Análisis de Discrepancias en Cálculo de Pagos - Facturación Electrónica
Problema Identificado
En el sistema de facturación electrónica, se presentaba una discrepancia de 1 centavo en el cálculo del vuelto debido a diferencias entre el total esperado (dVTot
) y el total recibido (dTotRec
).
Ejemplo del Problema:
// Datos originales del usuario:
$gTot = [
'dVTot' => 20.33, // Total esperado
'dTotRec' => 20.32, // Total recibido
'dVuelto' => 0.01 // Vuelto no deseado
];
Análisis de las Fuentes de Discrepancia
1. Cálculo de $dVTot
(Total Esperado)
$dVTot = $this->filterVar($this->numberFormat(($dVTotItems + $dTotAcar + $dTotSeg)), FILTER_VALIDATE_FLOAT);
- Se calcula basado en la suma de items, acarreos y seguros
- Puede tener precisión diferente debido a redondeos acumulativos
2. Cálculo de $dTotRec
(Total Recibido Inicial)
$dTotRec = array_sum(array_column($payments, 'dVlrCuota'));
- Se calcula sumando los valores de todos los pagos
- Puede diferir de
$dVTot
por errores de redondeo
3. Determinación de $maxTotal
$maxTotal = $this->numberFormat(max([$dTotRec, $dVTot]), 2);
- Se toma el mayor valor entre
$dTotRec
y$dVTot
- Este se convierte en el valor de referencia para el ajuste
Solución Implementada
Problema Principal
El PaymentCalculationHelper
ajustaba correctamente los pagos para sumar exactamente $maxTotal
, pero $dVTot
no se sincronizaba con este valor ajustado.
Solución: Sincronización de $dVTot
// Procesar pagos con suma exacta garantizada al $maxTotal
$payments = PaymentCalculationHelper::processPaymentsWithExactTotal($payments, $maxTotal, 2);
// Aplicar formateo de decimales consistente
$payments = PaymentCalculationHelper::formatPaymentValuesForDisplay($payments, 2);
// Recalcular el total después del procesamiento
$dTotRec = PaymentCalculationHelper::calculateNormalizedTotal($payments, 2);
// CLAVE: Sincronizar dVTot con el maxTotal para evitar discrepancias
$dVTot = $maxTotal;
$dVuelto = $this->numberFormat(abs($dTotRec - $dVTot), 2);
Archivos Modificados
app/Http/Livewire/Admin/Einvoice/Create.php
- Línea ~1238app/Http/Livewire/Admin/Einvoice/CreateFast.php
- Línea ~1042app/Http/Livewire/Admin/Einvoice/CreateFastJob.php
- Línea ~1302
Resultado Esperado
Después de la corrección:
// Datos después del ajuste:
$gTot = [
'dVTot' => 20.33, // Sincronizado con maxTotal
'dTotRec' => 20.33, // Ajustado por PaymentCalculationHelper
'dVuelto' => 0.00 // Sin vuelto no deseado
];
Casos de Uso Cubiertos
- Discrepancia Menor (≤0.2%): PaymentCalculationHelper ajusta proporcionalmente
- Discrepancia Mayor (>0.2%): Se toma el valor mayor como referencia
- Descuentos Adicionales: Los pagos por descuentos se incluyen en el cálculo
- Múltiples Formas de Pago: Todos los tipos de pago se normalizan consistentemente
Beneficios de la Solución
- Eliminación de vueltos no deseados: No más centavos de diferencia
- Consistencia en facturación: Mismo comportamiento en todos los módulos
- Compatibilidad con PAC: Los totales coinciden exactamente
- Mantenimiento de precisión: Se respeta la tolerancia del 0.2%
Consideraciones Técnicas
- La sincronización de
$dVTot = $maxTotal
ocurre DESPUÉS del procesamiento del PaymentCalculationHelper - Se mantiene la lógica existente de determinación del valor de referencia (
max([$dTotRec, $dVTot])
) - La precisión se mantiene en 2 decimales para cumplir con estándares fiscales
- El formateo consistente evita problemas de presentación de decimales
Testing Recomendado
- Verificar facturación con descuentos múltiples
- Probar con diferentes formas de pago combinadas
- Validar escenarios con montos grandes y pequeños
- Confirmar compatibilidad con todos los PAC conectados