Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/interezante456-pixel/Miercoles-Proyecto/llms.txt

Use this file to discover all available pages before exploring further.

The Ventas module is the core transactional engine of Tiendas Mi Cholo. Every sale creates a fully-audited record with auto-generated comprobante number, automatic IGV (18%) calculation, and real-time stock deduction for each line item. Roles ADMIN and VENDEDOR can register sales; only ADMIN may void them. All authenticated roles can read the sales list.

GET /api/ventas

List all sales recorded in the system, sorted by the default JPA fetch order. Accessible by all authenticated roles. GET http://localhost:8080/api/ventas

Authorization

Authorization
string
required
Bearer token — Authorization: Bearer <token>

Response 200 OK

id
Long
Internal database identifier for the sale.
numeroVenta
string
Auto-generated sale number in the format V-{year}-{sequence} (e.g. V-2024-0001).
tipoComprobante
string
Document type: BOLETA, FACTURA, or TICKET.
estado
string
Current sale status: PENDIENTE, COMPLETADA, or ANULADA.
subtotal
BigDecimal
Pre-tax subtotal amount, calculated from line items minus any discounts.
igv
BigDecimal
18% tax amount (subtotal × 0.18).
total
BigDecimal
Final amount charged (subtotal + igv).
observaciones
string
Optional free-text notes attached to the sale.
cliente
object
Embedded customer snapshot: id, nombres, apellidos, nroDoc.
usuario
object
Embedded user snapshot: id, nombre, apellido, username.
fechaVenta
string (ISO 8601)
Timestamp when the sale was persisted (@PrePersist).
Example response
[
  {
    "id": 1,
    "numeroVenta": "V-2024-0001",
    "tipoComprobante": "BOLETA",
    "estado": "COMPLETADA",
    "subtotal": 2711.86,
    "igv": 488.14,
    "total": 3200.00,
    "observaciones": null,
    "cliente": {
      "id": 1,
      "nombres": "Carlos Alberto",
      "apellidos": "Rodríguez Silva",
      "nroDoc": "12345678"
    },
    "usuario": {
      "id": 2,
      "nombre": "Luis",
      "apellido": "Mendoza",
      "username": "lmendoza"
    },
    "fechaVenta": "2024-01-15T14:30:00"
  }
]
cURL
curl -X GET http://localhost:8080/api/ventas \
  -H "Authorization: Bearer <token>"

GET /api/ventas/{id}

Retrieve a single sale by its database ID. Returns 404 if the sale does not exist. GET http://localhost:8080/api/ventas/{id}

Authorization

Authorization
string
required
Bearer token — Authorization: Bearer <token>

Path Parameters

id
Long
required
The internal ID of the sale to retrieve.

Response 200 OK

Returns the same sale object shape as GET /api/ventas.

Error Codes

StatusError
401 UnauthorizedToken missing, invalid, or expired.
404 Not Found"Venta no encontrada: {id}"
cURL
curl -X GET http://localhost:8080/api/ventas/1 \
  -H "Authorization: Bearer <token>"

POST /api/ventas

Register a new sale. The service resolves the authenticated user from the JWT, validates each line item’s stock availability, calculates subtotal/IGV/total, decrements stock for every product, and writes an Inventario SALIDA movement — all within a single database transaction. POST http://localhost:8080/api/ventas

Authorization

Authorization
string
required
Bearer token — requires ADMIN or VENDEDOR role.

Request Body

clienteId
Long
required
ID of the customer associated with this sale.
tipoComprobante
string
required
Comprobante type. Accepted values: BOLETA, FACTURA, TICKET.
observaciones
string
Optional free-text notes (e.g. payment terms, delivery instructions).
detalles
array
required
Line items array. Must contain at least one item (@NotEmpty).
IGV is always computed server-side at a fixed rate of 18%.
igv = subtotal × 0.18total = subtotal + igv
Do not send tax values in the request body; they will be ignored.

Response 200 OK

Returns the persisted Venta object including the auto-generated numeroVenta and computed subtotal, igv, and total.

Error Codes

StatusMeaning
400 Bad RequestValidation failure or insufficient stock (see example below).
401 UnauthorizedToken missing or invalid.
403 ForbiddenAuthenticated user does not have ADMIN or VENDEDOR role.
404 Not FoundclienteId or any productoId does not exist.
400 — Insufficient stock
{
  "timestamp": "2024-01-15T14:31:00",
  "status": 400,
  "error": "Stock insuficiente para: Laptop HP 15. Disponible: 0"
}
cURL — 2-item sale
curl -X POST http://localhost:8080/api/ventas \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "clienteId": 1,
    "tipoComprobante": "BOLETA",
    "observaciones": "Venta a crédito 30 días",
    "detalles": [
      {
        "productoId": 1,
        "cantidad": 1,
        "precioUnitario": 3200.00,
        "descuento": 0.00
      },
      {
        "productoId": 2,
        "cantidad": 3,
        "precioUnitario": 75.00,
        "descuento": 5.00
      }
    ]
  }'
Response — 200 OK
{
  "id": 7,
  "numeroVenta": "V-2024-0007",
  "tipoComprobante": "BOLETA",
  "estado": "COMPLETADA",
  "subtotal": 3413.75,
  "igv": 614.48,
  "total": 4028.23,
  "observaciones": "Venta a crédito 30 días",
  "cliente": {
    "id": 1,
    "nombres": "Carlos Alberto",
    "apellidos": "Rodríguez Silva",
    "nroDoc": "12345678"
  },
  "usuario": {
    "id": 2,
    "nombre": "Luis",
    "apellido": "Mendoza",
    "username": "lmendoza"
  },
  "fechaVenta": "2024-01-15T14:31:05"
}

PATCH /api/ventas/{id}/anular

Void an existing sale. The service restores stock for every line item and creates a corresponding Inventario ENTRADA movement (reversal). The sale record is never deleted — its estado is set to ANULADA. PATCH http://localhost:8080/api/ventas/{id}/anular

Authorization

Authorization
string
required
Bearer token — requires ADMIN role only.

Path Parameters

id
Long
required
ID of the sale to void.

Response 200 OK

Returns the updated Venta object with "estado": "ANULADA".
Once a sale is voided (ANULADA) it cannot be re-activated. Attempting to void an already-voided sale returns 400 Bad Request: "La venta ya está anulada". The sale record remains in the database for audit purposes, and the reversed stock movements are permanently logged in the inventory ledger.

Error Codes

StatusMeaning
400 Bad RequestSale is already in ANULADA state.
401 UnauthorizedToken missing or invalid.
403 ForbiddenUser does not have ADMIN role.
404 Not FoundSale ID does not exist.
cURL
curl -X PATCH http://localhost:8080/api/ventas/7/anular \
  -H "Authorization: Bearer <token>"
Response — 200 OK
{
  "id": 7,
  "numeroVenta": "V-2024-0007",
  "tipoComprobante": "BOLETA",
  "estado": "ANULADA",
  "subtotal": 3413.75,
  "igv": 614.48,
  "total": 4028.23,
  "observaciones": "Venta a crédito 30 días",
  "cliente": {
    "id": 1,
    "nombres": "Carlos Alberto",
    "apellidos": "Rodríguez Silva",
    "nroDoc": "12345678"
  },
  "usuario": {
    "id": 2,
    "nombre": "Luis",
    "apellido": "Mendoza",
    "username": "lmendoza"
  },
  "fechaVenta": "2024-01-15T14:31:05"
}

Build docs developers (and LLMs) love