fix(pago): valor $1,000.00 → 100000 en vez de 1000 causaba sin_coincidencia

preg_replace('/[^0-9]/', '', '1,000.00') = '100000' porque el .00 aporta 00.
Fix: primero quitar la parte decimal (/[.,]\d{1,2}$/) antes de limpiar separadores.
Aplicado en BancolombiaParser::normalizarValor() y como doble defensa en PagoValidadorService.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro
2026-07-18 17:05:16 +00:00
co-authored by Claude Sonnet 4.6
parent 595c75837f
commit 811b360939
2 changed files with 18 additions and 4 deletions
+14 -3
View File
@@ -142,11 +142,11 @@ class BancolombiaParser
}
/**
* Extrae el valor monetario como string limpio, ej: "1000.00"
* Extrae el valor monetario como entero limpio sin decimales (ej: "1000").
* $1,000.00 "1000" | $50.000,00 "50000"
*/
private static function extraerValor(string $text): string
{
// Patrones en orden de especificidad
$patterns = [
'/por\s+\$\s*([0-9][0-9.,]*)/iu',
'/valor[:\s]+\$?\s*([0-9][0-9.,]*)/iu',
@@ -156,12 +156,23 @@ class BancolombiaParser
];
foreach ($patterns as $pat) {
if (preg_match($pat, $text, $m)) {
return trim($m[1]);
return self::normalizarValor(trim($m[1]));
}
}
return '';
}
/**
* Convierte "1,000.00" o "1.000,00" a "1000" (entero limpio).
*/
private static function normalizarValor(string $raw): string
{
// Eliminar parte decimal: ,XX o .XX al final (pesos colombianos no tienen centavos reales)
$raw = preg_replace('/[.,]\d{1,2}$/', '', $raw);
// Eliminar separadores de miles (comas, puntos)
return preg_replace('/[^0-9]/', '', $raw);
}
/**
* Elimina completamente bloques <style>, <script>, <head> y luego
* convierte etiquetas estructurales en saltos de línea antes de strip_tags.
+4 -1
View File
@@ -56,7 +56,10 @@ class PagoValidadorService
Log::info("[PagoValidador] Correo #{$i} parseado: " . json_encode($datosCorreo));
// ── 1. Valor ────────────────────────────────────────────
$valorCorreo = (int) preg_replace('/[^0-9]/', '', (string) ($datosCorreo['valor'] ?? '0'));
// Normalizar: "1,000.00" → 1000 (strip decimals first, then non-digits)
$valorRaw = (string) ($datosCorreo['valor'] ?? '0');
$valorRaw = preg_replace('/[.,]\d{1,2}$/', '', $valorRaw); // quitar decimales
$valorCorreo = (int) preg_replace('/[^0-9]/', '', $valorRaw);
if ($valorIA <= 0 || $valorCorreo <= 0) {
Log::info("[PagoValidador] Correo #{$i}: valor inválido (ia={$valorIA} correo={$valorCorreo})");