Skip to main content

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.

The Sales module in Tienda Mi Cholo S.A.C. is the central hub for every transaction processed at the point of sale. It provides a chronological record of every completed sale, displays client and receipt information at a glance, and enforces role-based permissions so that only authorized staff can create or delete transactions. All authenticated users — Administradores, Gerentes, Cajeros, and read-only staff — can browse the sales history, while more sensitive operations such as creating a new sale or annulling an existing one are restricted to specific roles.

Sales List

The sales history is available at /Venta/Lista and is accessible to every authenticated user. Records are returned sorted by FechaVenta in descending order, so the most recent sale always appears at the top of the table. Each row eagerly loads its related Cliente record so client names are displayed without a second request.
ColumnSource fieldNotes
IDVenta.ID_VentaAuto-incremented primary key
ComprobanteVenta.TipoComprobanteColor-coded badge: emerald for Boleta, blue for Factura
Nro. ComprobanteVenta.NumeroComprobanteAuto-generated correlative, e.g. B001-00000001
ClienteVenta.Cliente.Nombres + ApellidosLoaded via Include(v => v.Cliente)
FechaVenta.FechaVentaFormatted dd/MM/yyyy HH:mm
TotalVenta.MontoTotalDisplayed as S/ #,##0.00; recalculated automatically
Acciones“Ver” (all roles) · “Anular” (Administrador, Gerente only)
The controller query that populates this view is:
List<Venta> lista = await _context.Ventas
    .Include(v => v.Cliente)
    .OrderByDescending(v => v.FechaVenta)
    .ToListAsync();

Receipt Types

Every sale is tied to exactly one of two receipt types. The type is chosen on the new-sale screen and determines which client fields are required, as well as the voucher-number prefix that is generated.
A Boleta de Venta is the standard consumer receipt. Client identification is entirely optional: if the cashier leaves the client name blank, the system automatically assigns the sale to the built-in Público General record (document 00000000, TipoDocumento = DNI).When a name is provided, the system first searches for an existing Cliente with TipoDocumento = DNI matching that name. If none is found, a new client record is created with an auto-generated 8-digit DNI.Voucher number format: B001-XXXXXXXXThe eight trailing digits are a zero-padded correlative that increments independently from the Factura series. For example, the first boleta ever issued is numbered B001-00000001.
FieldRequired?Notes
Nombre del ClienteOptionalLeave blank for Público General

Deleting a Sale

Deleting (annulling) a sale is a permanent action. There is no soft-delete or recycle bin. Once confirmed, the sale record and all of its line items are removed from the database and all associated product stock is fully restored. This action cannot be undone.
Only users with the Administrador or Gerente role can see and use the “Anular” button in the sales list. The deletion endpoint is:
GET /Venta/Eliminar/{id}
When a sale is deleted, the controller iterates over every DetalleVenta line belonging to that sale and adds the stored Cantidad back to the corresponding product’s Stock:
foreach (var detalle in venta.Detalles)
{
    var producto = await _context.Productos
        .FirstAsync(p => p.ID_Producto == detalle.Producto_ID);
    producto.Stock += detalle.Cantidad;
    _context.Productos.Update(producto);
}

_context.DetalleVentas.RemoveRange(venta.Detalles);
_context.Ventas.Remove(venta);
await _context.SaveChangesAsync();
After deletion the user is redirected back to the sales list and the voucher number that was in use is not reused — the correlative continues from where it left off for future sales.

Sale Totals

The MontoTotal field on a Venta record is never entered manually. It is always computed as the arithmetic sum of all DetalleVenta.Subtotal values that belong to that sale:
MontoTotal = Σ (DetalleVenta.Subtotal)
           = Σ (Cantidad × PrecioUnitario)
This recalculation happens automatically in two scenarios:
  1. When a new sale is created — the total is computed during the transaction before the Venta record is persisted.
  2. When a line item is added or removed from an existing saleDetalleVentaController recalculates and saves the total immediately after every change.
Because MontoTotal is always derived from the stored line items, it stays consistent even if a cashier modifies quantities or removes products from a sale that is still open.

Register a New Sale

Step-by-step walkthrough of the POS interface: search products, build a cart, choose a receipt type, and finalize the transaction.

Sale Detail View

Understand what is displayed on the sale detail page, including line items, price snapshots, and client information.

Build docs developers (and LLMs) love