Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/YonAnn99/Acrylitec/llms.txt

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

Acrylitec supports two sales flows. The primary flow is the POS (Point of Sale) interface at /pedidos/nuevo/, which accepts a multi-item cart, calculates subtotals client-side, and persists the order as a single Ventas record with one DetalleVenta row per line item. A legacy quote-based flow (linking a Ventas record to an existing Cotizaciones record via id_cotizacion) is also retained for backward compatibility with orders created before the POS system was introduced.

POS Order Flow

1

Open the new order form

Navigate to /pedidos/nuevo/. The page is accessible to all authenticated users and renders the Punto de Venta (POS) interface.
2

Select or create a client

Choose an existing client from the searchable Select2 dropdown. If the client is not yet registered, click Nuevo cliente to open a modal form. Submitting the modal calls the AJAX endpoint POST /ajax/crear-cliente/ in the background, which creates a Clientes record and returns the new id_cliente and nombre so the dropdown can be updated immediately without a page reload.Once the first cart item is added, the client selector is locked to prevent accidental changes.
3

Configure each line item

For each item in the order, fill in:
  • Producto and Material from the respective Select2 dropdowns
  • Cantidad (quantity, minimum 1)
  • Largo (cm) and Ancho (cm) — piece dimensions
  • Espesor (mm) — acrylic thickness, selected from the TabuladorCostos entries
  • Min. Láser — laser cutting minutes (optional, defaults to 0)
  • Utilidad (%) — profit margin for this line item (defaults to 40)
The right-hand Calculadora del renglón panel updates in real time using the same formula as the quotation form. The tarifa_laser_minuto value is injected into the page from ConfiguracionPrecios via the template context.
4

Add the item to the cart

Click Agregar al Carrito. The line item — including its computed subtotal — is appended to the in-memory carrito array and displayed in the Resumen del Pedido table. The grand total updates automatically.
5

Set payment and delivery details

In the Cobro y Confirmación section, enter:
  • Monto abonado ($) — advance payment received (pre-filled with the grand total; edit as needed)
  • Estatus inicial — starting status for the order (see Sales Statuses below)
  • Fecha de entrega — optional promised delivery date
6

Submit the order

Click Registrar Pedido Completo. The browser serialises the cart as a JSON payload and sends it via fetch to POST /pedidos/nuevo/ with the Content-Type: application/json header.
7

Server-side processing

The nuevo_pedido view detects the JSON content type and performs the following in sequence:
  1. Creates a Ventas record linked to the selected client, with the provided monto_abonado, estatus, and optional fecha_entrega.
  2. For each item in the carrito array, creates a DetalleVenta record storing the product, material, dimensions, laser minutes, and subtotal.
  3. Decrements Materiales.stock_actual by the item’s cantidad for each material used.
  4. Checks whether any material’s stock_actual has dropped to or below stock_minimo.
  5. Returns a JSON response with ok: true, the new venta_id, and any alertas_stock entries.
On success the browser redirects to /ventas/<venta_id>/.

Sales Statuses

Every Ventas record carries an estatus field with one of four choices defined in the model:
ValueLabelMeaning
pendientePendienteDefault state — order received but not yet started
en_produccionEn producciónThe acrylic pieces are actively being cut or processed
pagadaPagadaFull payment has been received; counts as revenue in dashboard and sales KPIs
entregadaEntregadaOrder has been physically delivered to the client; counts as revenue in dashboard and sales KPIs

Updating Order Status

To change the estatus or set a delivery date, submit a standard HTML POST form to:
POST /ventas/<pk>/estatus/
The request body must include the estatus field (one of the four values above). Optionally include fecha_entrega (ISO date string YYYY-MM-DD) to record or update the promised delivery date. The view validates the status value and saves the changes, then redirects back to /ventas/<pk>/. The order detail page (/ventas/<pk>/) also renders a four-step visual progress bar — Pendiente → En producción → Pagada → Entregada — that highlights the current stage.

Managing Advance Payments

Each Ventas record stores a monto_abonado field representing the amount already paid by the client. The remaining balance is computed on the fly by the saldo_restante property:
# For legacy quote-based orders (id_cotizacion is set):
saldo_restante = self.id_cotizacion.monto_total - self.monto_abonado

# For POS orders (cart-based, id_cotizacion is None):
saldo_restante = sum(detalle.subtotal for detalle in self.detalles.all()) - self.monto_abonado
To update the advance payment amount, submit a POST to:
POST /ventas/<pk>/abono/
Include monto_abonado in the request body with the new cumulative total paid. The view saves the value and redirects to the order detail page, where the updated saldo_restante is displayed immediately.

Viewing the Sales List

The full sales history is available at /ventas/. In addition to the paginated table of all orders, the page header shows five summary KPI cards computed by the lista_ventas view:
KPIDescription
Total ventasCount of all Ventas records
Ingresos totalesSum of order totals where estatus is pagada or entregada
PendientesCount of orders with estatus = pendiente
En producciónCount of orders with estatus = en_produccion
EntregadasCount of orders with estatus = entregada
Each row in the table shows the order ID (VTA-XXXX), date, client name, product name, total amount, amount paid, current status badge, and a Ver link to the detail view.

Low Stock Alerts

After each DetalleVenta is saved, the server checks whether the consumed material’s stock_actual has dropped to or below its configured stock_minimo. If so, the material is added to the alertas_stock list in the JSON response:
{
  "ok": true,
  "venta_id": 42,
  "alertas_stock": [
    { "nombre": "Acrílico Transparente 3mm", "actual": 2, "minimo": 5 }
  ]
}
The browser displays these alerts in a confirmation dialog before redirecting to the order detail page, allowing staff to reorder stock promptly.

DetalleVenta Line Items

The DetalleVenta model (db_table = 'detalle_venta') stores one row per cart item and links back to its parent order via a CASCADE foreign key. Its fields are:
FieldTypeDescription
id_detalleAutoField (PK)Auto-generated primary key
id_ventaFK → VentasParent sale (deletes children on cascade)
id_productoFK → ProductosProduct for this line item
id_materialFK → MaterialesMaterial used for this line item
cantidadIntegerFieldNumber of pieces (default 1)
largo_pzaDecimalFieldPiece length in centimetres
ancho_pzaDecimalFieldPiece width in centimetres
espesor_mmDecimalFieldThickness in millimetres
minutos_lazerIntegerFieldLaser cutting minutes (default 0)
subtotalDecimalFieldPre-calculated line total sent from the client

Build docs developers (and LLMs) love