Documentation Index
Fetch the complete documentation index at: https://mintlify.com/interezante456-pixel/nuevo-proyecto-viernes/llms.txt
Use this file to discover all available pages before exploring further.
VentaController and DetalleVentaController together manage the complete sales lifecycle in Tienda Mi Cholo. VentaController handles sale headers — browsing the sales list, creating new sales with full client resolution and voucher auto-numbering, viewing a sale’s detail page, deleting a sale with stock restoration, and a live product-search endpoint used by the sale form. DetalleVentaController manages individual line items on an existing sale: adding a new line (with stock validation and total recalculation) and removing a line (with stock restoration and total recalculation). Both controllers carry [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)] and require an authenticated user via [Authorize] at the class level; individual actions narrow access further with role-based [Authorize(Roles = "...")] attributes.
VentaController
GET /Venta/Lista
Returns all sales ordered byFechaVenta descending, each with its related Cliente record eagerly loaded, and passes the list to the Lista view.
Authorization: Any authenticated user (all roles).
GET /Venta/Nueva
Loads the new-sale form. PopulatesViewBag.Clientes with every client whose ID_Cliente is not 1 (i.e., all non-default clients) so the cashier can optionally select an existing customer.
Authorization: Administrador, Gerente, Cajero.
Client ID 1 is the reserved Público General default client. It is excluded from the dropdown because it is selected automatically when no client name is provided on the POST.
POST /Venta/Nueva
Creates a new sale inside a database transaction. Resolves or creates the appropriate client record depending ontipoComprobante, auto-generates a correlative voucher number, decrements product stock for each line item, and persists the Venta together with its DetalleVenta collection in a single SaveChangesAsync call.
Authorization: Administrador, Gerente, Cajero. Decorated with [ValidateAntiForgeryToken] — the form must include a valid anti-forgery token or the request is rejected with a 400 Bad Request.
Array of product IDs to include in the sale. Must not be empty and must have the same length as
cantidades and precios.Quantity for each product, parallel to
productoIds. Each value must be greater than zero and must not exceed the product’s current Stock.Unit price for each product, parallel to
productoIds. Used directly to compute Subtotal = cantidad × precio.Either
"Boleta" or "Factura". Determines both the voucher prefix (B001- / F001-) and the client-resolution logic.Full name (Boleta) or Razón Social (Factura) of the customer. Optional for Boleta; required for Factura.
DNI (Boleta) or RUC (Factura). For Factura, must be exactly 11 digits and start with
10 or 20. Ignored for Boleta unless a name was supplied.Mobile number. For Factura, must be 9 digits, start with
9, and must not be all-identical digits. Ignored for Boleta.TempData["Success"] with the voucher number and redirects to GET /Venta/Lista.
On validation failure: Rolls back the transaction, sets TempData["Error"], restores form state via ViewBag (including a JSON-serialized cart for JavaScript re-hydration), and returns the Nueva view.
GET /Venta/BuscarProductos?q=
Live search endpoint consumed by the new-sale form’s product typeahead. Returns a JSON array of matching active products that have stock available. Authorization: Any authenticated user (all roles).Search term matched against
NombreProducto using a SQL LIKE/Contains. Returns an empty array when blank or whitespace.Estado = true and Stock > 0, limited to 20 records.
Response shape:
GET /Venta/Detalle/
Returns the full sale record for display: theVenta header with its Cliente, and all DetalleVenta line items each with their associated Producto.
Authorization: Any authenticated user (all roles).
Primary key (
ID_Venta) of the sale to display.GET /Venta/Eliminar/
Permanently deletes a sale after restoring the stock for every product that appeared in it. Removes all associatedDetalleVenta rows first, then removes the Venta header, and redirects to the sales list.
Authorization: Administrador, Gerente.
Primary key (
ID_Venta) of the sale to delete.DetalleVentaController
POST /DetalleVenta/Nuevo
Adds a single line item to an existing sale. Fetches the product to validate stock and resolve the current unit price, computes the subtotal, decrements stock, persists the newDetalleVenta, then recalculates and saves Venta.MontoTotal.
Authorization: Administrador, Gerente, Cajero.
Model-bound
DetalleVenta object. The required fields are:Venta_ID— the parent sale.Producto_ID— the product to add.Cantidad— units to add; must be greater than zero and not exceed current stock.
PrecioUnitario and Subtotal are overwritten by the server from the product record regardless of what is submitted.If
Cantidad ≤ 0, the action silently redirects back to GET /Venta/Detalle/{id} without adding a line. If Cantidad > producto.Stock, it redirects with TempData["Error"] set.Venta.MontoTotal is recalculated as the sum of all remaining DetalleVenta.Subtotal values for that sale:
GET /Venta/Detalle/{Venta_ID}.
GET /DetalleVenta/Eliminar/
Removes a single line item from a sale. Restores the product’s stock by adding the line’sCantidad back, deletes the DetalleVenta record, then recalculates and saves Venta.MontoTotal.
Authorization: Administrador, Gerente, Cajero.
Primary key (
ID_DetalleVenta) of the line item to remove.Venta.MontoTotal is recalculated the same way as in the Nuevo action:
GET /Venta/Detalle/{Venta_ID}.