Cálculos (Facturación)
Moneda canónica: CRC. Al vender en otra moneda, los precios (que viven en CRC) se convierten con el tipo de cambio. El total autoritativo lo calcula el servidor (calculo.ts); la UI muestra una previsualización con la misma lógica.
Tarifas de IVA
Código (codigoTarifaIVA) | Tarifa |
|---|---|
08 | 13 % |
04 | 4 % |
03 | 2 % |
02 | 1 % |
09 | 0.5 % |
01 / exento | 0 % |
Cálculo por línea
base = cantidad × precioUnitario − descuento
tarifa = (exento || noSujeto) ? 0 : TARIFA[codigoTarifaIVA]
IVA_línea = base × (tarifa / 100)Exoneración (reduce el IVA)
Cuando el cliente tiene un documento de exoneración vigente que cubre el CABYS de la línea:
IVA_línea = max(0, IVA_línea − base × (tarifaExonerada / 100))tarifaExonerada=porcentajeExoneracionque devuelve Hacienda (validado en/api/facturacion/exoneracion).- Se auto-rellena por línea (
camposExoAuto/exoParaCabys) si el CABYS está en la lista cubierta del documento y no está vencido; editable por línea. - Los CABYS cubiertos viven en un sub-doc del cliente:
receptores/{id}/exo/cabys(se cargan on-demand). - No aplica en exportación (FEE 09).
Régimen MAG (agropecuario)
El MAG no exonera: fija el IVA de la línea en 1 % (codigoTarifaIVA = "02").
- Disponible por línea si el cliente tiene MAG vigente (
activoMAGy no vencido). - Mutuamente excluyente con la exoneración. No aplica a productos exentos.
IVA devuelto (salud + tarjeta)
Servicios de salud (tarifa 4 %, CABYS que no empieza en 64 = aviación) pagados con tarjeta → su IVA se devuelve:
ivaDevuelto = (medioPago == "02") ? Σ IVA_línea(salud 4%) : 0No aplica a líneas MAG ni exoneradas.
Otros impuestos / otros cargos
- Otros impuestos por línea (ISC, IUC…):
oiMontoobase × oiTarifa%. - Otros cargos (nivel comprobante): p.ej. el cargo 06 (servicio 10 %) se calcula automático = 10 % del subtotal de las líneas.
Total del comprobante
total = subtotal + IVA + otrosImpuestos + otrosCargos − ivaDevueltosubtotal = Σ base de líneas. En la previsualización del POS, el total mostrado se redondea a 2 decimales (evita el “céntimo fantasma” del botón Exacto y el vuelto).
Cantidades fraccionables vs. enteras
Cada producto define permiteFracciones:
- Fraccionables (kg, g, L, mL, m, cm, h…): aceptan decimales (ej.
0.250), normalizados a 3 decimales. - Enteras (Unid, Sp, Otros): entero, mínimo 1 (se redondea con
Math.round, piso 1).
Reglas de aplicación:
- POS: usa el flag guardado del producto. La cantidad inicial al agregar =
1, o el disponible si es fraccionable y queda< 1(ej.0.2 kg); topada al stock; si te pasás, avisa. - Nueva factura: el flag se deriva de la unidad de la línea (
unidadFraccionable), así no se desincroniza al cambiar la unidad; valida contra el stock del producto. - La
Cantidaddel XML de Hacienda esxs:decimal→ las fracciones llegan correctas a la factura, a las NC/ND y al descuento de inventario.
Topes en notas (NC/ND)
- NC: la cantidad a acreditar ≤
saldoCantde la línea (cantidad original − créditos previos). El monto ≤ saldo restante (montoSaldo). - ND: la cantidad ≤
cantidadOrigen(cantidad original de la factura). Las NC previas no reducen ese tope. - No fraccionables: en NC/ND también se exige entero ≥ 1.
Redondeos y precisión
- Total mostrado/cobrado → 2 decimales.
- Cantidades fraccionables →
parseFloat(n.toFixed(3)). - IVA exonerado → piso
0(nunca negativo). - Inventario optimista en cache local con
Math.max(0, …)(evita stock negativo visual).