= 2; } catch (\Exception $e) { return false; } } public function parsear(string $filePath): array { $text = Pdf::getText($filePath); $lineas = explode("\n", $text); $cuentas = []; foreach ($lineas as $linea) { $cuenta = $this->parsearLinea($linea); if ($cuenta) { $cuentas[] = $cuenta; } } // Establecer relaciones padre-hijo $this->establecerJerarquia($cuentas); return $cuentas; } private function parsearLinea(string $linea): ?array { // Patrón para líneas de cuenta CONTPAQi // Formato típico: "001-100-000 ACTIVO CIRCULANTE 1,234.56 0.00 500.00 200.00 1,534.56 0.00" $patron = '/^(\d{3}-\d{3}-\d{3})\s+(.+?)\s+([\d,]+\.?\d*)\s+([\d,]+\.?\d*)\s+([\d,]+\.?\d*)\s+([\d,]+\.?\d*)\s+([\d,]+\.?\d*)\s+([\d,]+\.?\d*)$/'; if (!preg_match($patron, trim($linea), $matches)) { return null; } $codigo = $matches[1]; $nombre = trim($matches[2]); // Determinar nivel basado en el código $nivel = $this->determinarNivel($codigo); // Determinar si es cuenta padre (termina en -000-000 o -XXX-000) $esCuentaPadre = preg_match('/-000-000$/', $codigo) || preg_match('/-\d{3}-000$/', $codigo); return [ 'codigo' => $codigo, 'nombre' => $nombre, 'nivel' => $nivel, 'saldo_inicial_deudor' => $this->parsearNumero($matches[3]), 'saldo_inicial_acreedor' => $this->parsearNumero($matches[4]), 'cargos' => $this->parsearNumero($matches[5]), 'abonos' => $this->parsearNumero($matches[6]), 'saldo_final_deudor' => $this->parsearNumero($matches[7]), 'saldo_final_acreedor' => $this->parsearNumero($matches[8]), 'es_cuenta_padre' => $esCuentaPadre, ]; } private function determinarNivel(string $codigo): int { // En CONTPAQi el nivel se puede inferir del patrón de código // XXX-000-000 = Nivel 1 (cuenta mayor) // XXX-XXX-000 = Nivel 2 (subcuenta) // XXX-XXX-XXX = Nivel 3 (detalle) if (preg_match('/-000-000$/', $codigo)) { return 1; } if (preg_match('/-\d{3}-000$/', $codigo)) { return 2; } return 3; } private function parsearNumero(string $valor): float { // Remover comas y convertir a float return (float) str_replace(',', '', $valor); } private function establecerJerarquia(array &$cuentas): void { // Crear índice por código $indice = []; foreach ($cuentas as $i => $cuenta) { $indice[$cuenta['codigo']] = $i; } // Establecer padres basado en el código foreach ($cuentas as $i => &$cuenta) { $codigo = $cuenta['codigo']; $partes = explode('-', $codigo); // Buscar cuenta padre if ($partes[2] !== '000') { // Buscar padre de nivel 2 (XXX-XXX-000) $codigoPadre = $partes[0] . '-' . $partes[1] . '-000'; if (isset($indice[$codigoPadre])) { $cuenta['cuenta_padre_codigo'] = $codigoPadre; } } elseif ($partes[1] !== '000') { // Buscar padre de nivel 1 (XXX-000-000) $codigoPadre = $partes[0] . '-000-000'; if (isset($indice[$codigoPadre])) { $cuenta['cuenta_padre_codigo'] = $codigoPadre; } } } } }