The pricing engine is the computational core of Acrylitec. It lives in two places: theDocumentation 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.
calcular_monto() instance method on the Cotizaciones model (called automatically on every save()), and the _calcular_monto() helper function in gestion/views.py (called by the AJAX endpoint to deliver real-time price previews to the browser). Both implement the same formula — the view helper additionally returns a full breakdown dict so the UI can display each cost component individually.
Formula Steps
The engine evaluates steps in order and short-circuits early if a fixed price is configured on the product.1. Fixed Price Check
Before any calculation, the engine checks whether the selected product carries aprecio_fijo:
precio_fijo is set, it is returned immediately as monto_total. Material cost, profit, and laser cost are all reported as 0.00. No further steps are executed.
2. Area Calculation
The piece dimensions (in centimetres) are converted to square metres:largo and ancho are coerced to Decimal from the raw POST values to guarantee precise arithmetic throughout the pipeline.
3. Tabulador Lookup
The engine queriesTabuladorCostos for an exact match on espesor_mm. If no matching row is found, factor_costo falls back to Decimal('0.00'):
4. Material Cost
The area (in m²) is multiplied by the tabulador factor (cost per m²) to produce the raw material cost:5. Profit Margin
The profit margin is applied as a percentage on top ofcosto_material. The default is 40 %:
porcentaje_utilidad may be customised per-product via Productos.porcentaje_utilidad or overridden per-quote via Cotizaciones.porcentaje_utilidad.
6. Laser Cost
The laser cutting cost is calculated by multiplying elapsed minutes by the current rate from the singletonConfiguracionPrecios:
_get_tarifa_laser() calls ConfiguracionPrecios.get_config().tarifa_laser_minuto, which defaults to 15.00 pesos per minute.
7. Total
The three cost components are summed and rounded to two decimal places usingROUND_HALF_UP:
Full Source Code
Below is the complete_calcular_monto() helper as it appears in gestion/views.py:
Return Value
When a fixed price does not apply,_calcular_monto() returns a dictionary with the following keys:
| Key | Type | Description |
|---|---|---|
area | Decimal | Raw area in cm² (largo × ancho) |
area_m2 | Decimal | Area converted to m² (area_cm2 / 10000) |
costo_material | Decimal | Material cost rounded to 2 decimal places |
utilidad | Decimal | Profit margin amount rounded to 2 decimal places |
costo_laser | Decimal | Laser cutting cost rounded to 2 decimal places |
monto_total | Decimal | Final total rounded to 2 decimal places via ROUND_HALF_UP |
costo_material, utilidad, and costo_laser are all Decimal('0.00'), and monto_total equals producto.precio_fijo.
Example Calculation
The following example walks through a typical keychain quote with no fixed price. Inputs:| Parameter | Value |
|---|---|
| Product | Llavero (no precio_fijo set) |
porcentaje_utilidad | 40 |
largo_pza | 10 cm |
ancho_pza | 5 cm |
espesor_mm | 3 mm |
factor_costo (from TabuladorCostos) | 850.0000 |
minutos_lazer | 5 |
tarifa_laser_minuto | 15.00 |
- Fixed price check —
precio_fijoisNone→ continue. - Area:
- Tabulador lookup — row for
espesor_mm = 3found;factor_costo = 850.0000. - Material cost:
- Profit margin:
- Laser cost:
- Total:
AJAX Calculation Endpoint
The quotation form callsPOST /ajax/calcular/ after any input change to display a live price preview without saving the quote. The view (calcular_precio_ajax) calls _calcular_monto() and returns the breakdown as JSON so the browser can populate each cost field individually.
For full request and response schema details, see the AJAX API Reference.