Saltar a contenido

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

  1. app/Http/Livewire/Admin/Einvoice/Create.php - Línea ~1238
  2. app/Http/Livewire/Admin/Einvoice/CreateFast.php - Línea ~1042
  3. app/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

  1. Discrepancia Menor (≤0.2%): PaymentCalculationHelper ajusta proporcionalmente
  2. Discrepancia Mayor (>0.2%): Se toma el valor mayor como referencia
  3. Descuentos Adicionales: Los pagos por descuentos se incluyen en el cálculo
  4. 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

  1. Verificar facturación con descuentos múltiples
  2. Probar con diferentes formas de pago combinadas
  3. Validar escenarios con montos grandes y pequeños
  4. Confirmar compatibilidad con todos los PAC conectados