Inventory System maintains a complete, immutable ledger of every stock change through theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/juadariasmar/inventory_project/llms.txt
Use this file to discover all available pages before exploring further.
Movimiento model. Whether stock increases because a purchase order arrived, decreases because a sale was processed, or is adjusted manually by a warehouse operator, a movement record is always created. This gives you a traceable history of every unit that has entered or left your inventory.
Movimiento model
Each movement record captures:| Field | Type | Description |
|---|---|---|
id | Int | Auto-incremented primary key |
tipo | entrada | salida | Direction of the stock change |
cantidad | Int | Number of units moved (always a positive integer) |
productoId | Int | FK to the affected Producto |
ventaId | Int? | FK to the originating Venta, if applicable |
ordenCompraId | Int? | FK to the originating OrdenCompra, if applicable |
notas | String? | Optional free-text note describing the reason |
empresaId | String | Tenant isolation key |
creadoEn | DateTime | UTC timestamp of the movement |
ventaId and ordenCompraId are mutually exclusive in practice: a movement is either linked to a sale, to a purchase order receipt, or to neither (manual adjustment).Automatic movement creation
The system creates movements automatically in two situations:Sale confirmed
When
POST /api/ventas is called, VentasService.registrarVenta runs inside a database transaction. For every product in the sale it creates a Movimiento of type salida linked to the new Venta via ventaId, and decrements Producto.cantidad by the sold quantity. The movement note is set to "Venta #<id>".Purchase order received
When
POST /api/ordenes-compra/[id]/recibir is called, OrdenesCompraService.recibir runs a transaction that iterates over every OrdenCompraItem. For each item it creates a Movimiento of type entrada linked to the order via ordenCompraId, and increments Producto.cantidad. The note is set to "Orden de compra #<id>".SELECT … FOR UPDATE) on the affected Producto rows to prevent race conditions under concurrent requests.
Manual movements
Operators with theREGISTRAR_MOVIMIENTOS permission (or REALIZAR_VENTAS for exits) can record ad-hoc adjustments via POST /api/movimientos:
tipois exactly"entrada"or"salida".cantidadis a positive integer (fractional values are rejected).- For exits, the available stock after subtracting active quote reservations is sufficient.
Movimiento including the updated Producto snapshot.
Filtering and pagination
GET /api/movimientos supports cursor-based pagination:
| Query parameter | Description |
|---|---|
cursor | ID of the last record from the previous page |
limite | Page size (default 50, maximum 100) |
nextCursor as cursor in the next request to load the following page. When nextCursor is null there are no more records.
Bulk delete
To delete multiple movement records at once:Relationship to analytics
EveryMovimiento is included in the analytics calculations performed by src/lib/analisis.ts:
obtenerResumenMovimientos— aggregates daily entry and exit counts over the last 30 days for theGraficoMovimientoschart.obtenerAltaRotacion— sums exit movements per product to identify the top-10 highest-rotation items.obtenerStockPorAgotarse— computes the average daily consumption from exit movements to project when each product will run out.