Skip to main content

El problema

El DESGLOSE DE VENTA del Corte Z (#ORDER_SUBTOTAL#, #ORDER_TAXES#, #ORDER_TOTAL#) actualmente se calcula tomando lo que caja capturó como pago y dividiéndolo entre 1.16 para “obtener” el subtotal.

Por qué está mal

Si el cajero teclea un monto incorrecto al cobrar, el DESGLOSE DE VENTA queda mal — y ese dato incorrecto es el que llega a Restaurantero Pro, afectando el P&L, Food Cost y EBITDA del dashboard del dueño.
Además de errores del cajero, hay otros problemas estructurales:
ProblemaConsecuencia
Cancelaciones y voids no se descuentanVentas infladas — productos cancelados aparecen como vendidos
Descuentos pueden no reflejarseEl total reportado no coincide con lo que realmente pagó el cliente
IVA calculado como 16% fijo en todoProductos con IVA 0% (alimentos básicos) quedan mal calculados
Datos incorrectos a Restaurantero ProP&L, Food Cost % y EBITDA del dashboard quedan mal

La fuente de verdad correcta

El DESGLOSE DE VENTA debe calcularse desde OrderTicketLine con status open — las líneas que realmente se ordenaron, sirvieron y cobraron correctamente.
El método getOrderTicketLines($model, 'open') ya existe en el código y filtra exactamente lo correcto — solo líneas con status open, excluyendo automáticamente canceled y voided. Solo hay que usarlo para calcular el subtotal de ventas.
El modelo OrderTicketLine ya tiene los accessors correctos listos para usar:
AccessorQué representa
$line->netSubtotalSubtotal de la línea menos descuento aplicado
$line->taxIVA calculado correctamente por línea (respeta IVA 0%)
$line->totalMonto final neto de la línea (con descuentos, sin cancelados)

El fix

Archivo a modificar:
Solo hay que reemplazar 3 métodos. Todo lo demás queda igual.

Método 1 — getOrderSubtotal (línea ~277)

Método 2 — getOrderTaxes (línea ~284)

Método 3 — getOrderTotal (línea ~291)


Qué cambia y qué no cambia

Campo del Corte ZAntesDespués
#ORDER_SUBTOTAL#Pagos ÷ 1.16Suma de netSubtotal/1.16 por línea pagada
#ORDER_TAXES#Subtotal × 16% fijoSuma de IVA real por línea
#ORDER_TOTAL#Subtotal + IVA estimadoSuma de total real por línea
#PAYMENT_CASH_TOTAL#Sin cambioSin cambio
#PAYMENT_CARD_TOTAL_WITHOUT_TIP#Sin cambioSin cambio
#BALANCE_CHECK#Sin cambioSin cambio
#CASH_SHORTAGE#Sin cambioSin cambio
#THEORETICAL_FINAL_CASH#Sin cambioSin cambio
Los campos de efectivo, tarjeta, faltante/sobrante y saldo siguen viniendo de los pagos — eso es correcto y no debe cambiar. Solo cambian los 3 campos del DESGLOSE DE VENTA.

Impacto en Restaurantero Pro

Con este fix, cuando RC envíe el POST /api/v1/ingest/sales al cerrar el Corte Z, Restaurantero Pro recibirá los valores correctos:
  • total_sales_cents = venta real neta (con descuentos, sin cancelados, sin voided)
  • total_sales_no_iva_cents = venta real sin IVA calculada por línea
  • Food Cost % correcto en el dashboard del dueño
  • P&L correcto
  • EBITDA correcto

Prompt para Cursor


Cómo verificar que el fix funcionó

Después del cambio, en el siguiente Corte Z verifica:
  1. #ORDER_TOTAL# coincide con la suma de todos los tickets cerrados del período
  2. Si hubo una cancelación de $500, ese monto NO aparece en #ORDER_TOTAL#
  3. Si hubo un descuento del 20% en una mesa, el total refleja el precio con descuento
  4. #PAYMENT_CASH_TOTAL# y #PAYMENT_CARD_TOTAL_WITHOUT_TIP# no cambiaron
  5. El cash_shortage (faltante/sobrante) sigue calculándose correctamente

Restaurant Controller — Fix Corte Z
Mayo 2026 · Confidencial