- Laravel 11 backend with API REST - React 18 + TypeScript + Vite frontend - Multi-parser architecture for accounting systems (CONTPAQi, Aspel, SAP) - 27+ financial metrics calculation - PDF report generation with Browsershot - Complete documentation (10 documents) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
6.0 KiB
6.0 KiB
7. Parsers de Balanzas
Arquitectura
Upload archivo
│
▼
┌─────────────────┐
│ DetectorFormato │ ← Detecta el sistema origen
└────────┬────────┘
│
▼
┌─────────────────┐
│ Parser Específico│
│ - ContpaqiParser│
│ - GenericoParser│
│ - (futuro: Aspel)│
└────────┬────────┘
│
▼
┌─────────────────┐
│ Formato Standard│ ← Estructura normalizada
└────────┬────────┘
│
▼
┌─────────────────┐
│ ClasificadorCtas│ ← Aplica reglas de mapeo
└─────────────────┘
Interface ParserInterface
Todos los parsers deben implementar:
interface ParserInterface
{
/**
* Parsea archivo y retorna array de cuentas normalizadas
*/
public function parsear(string $filePath): array;
/**
* Verifica si puede manejar el archivo
*/
public function puedeManej(string $filePath): bool;
/**
* Retorna identificador del sistema
*/
public function getSistema(): string;
}
Estructura de cuenta normalizada:
[
'codigo' => '001-100-000',
'nombre' => 'ACTIVO CIRCULANTE',
'nivel' => 1,
'saldo_inicial_deudor' => 1500000.00,
'saldo_inicial_acreedor' => 0.00,
'cargos' => 500000.00,
'abonos' => 200000.00,
'saldo_final_deudor' => 1800000.00,
'saldo_final_acreedor' => 0.00,
'es_cuenta_padre' => true,
'cuenta_padre_codigo' => null, // opcional
]
DetectorFormato
Detecta automáticamente el sistema origen del archivo.
class DetectorFormato
{
private array $parsers = [
new ContpaqiParser(),
// new AspelParser(),
// new SapParser(),
new GenericoParser(), // Fallback
];
public function detectar(string $filePath): array
{
foreach ($this->parsers as $parser) {
if ($parser->puedeManej($filePath)) {
return [
'sistema' => $parser->getSistema(),
'parser' => $parser,
];
}
}
throw new Exception('Formato no reconocido');
}
}
ContpaqiParser
Parser para balanzas de CONTPAQi.
Detección
Busca patrones característicos en el PDF:
- Texto "CONTPAQ" o "CONTPAQi"
- Patrón de códigos:
\d{3}-\d{3}-\d{3} - Encabezados típicos: "Saldo Inicial", "Debe", "Haber"
Formato de código CONTPAQi
XXX-XXX-XXX
│ │ │
│ │ └── Detalle (000 = padre)
│ └────── Subcuenta (000 = padre)
└────────── Mayor
Ejemplos:
001-100-000→ Nivel 1 (Mayor: Activo Circulante)101-000-000→ Nivel 2 (Subcuenta: Caja)101-001-000→ Nivel 3 (Detalle)
Reglas de mapeo CONTPAQi
| Cuenta Padre | Rango Hijos | Categoría |
|---|---|---|
| 001-100-000 | 101-000-000 a 154-999-999 | Activos Circulantes |
| 001-200-000 | 155-000-000 a 199-999-999 | Activos No Circulantes |
| 002-100-000 | 200-000-000 a 209-999-999 | Pasivo Circulante |
| 002-200-000 | 210-000-000 a 220-999-999 | Pasivo No Circulante |
| 30X-XXX-XXX | - | Capital Social |
| 310-XXX-XXX | - | Pérdidas Anteriores |
| 311-XXX-XXX | - | Utilidades Anteriores |
| 40X-XXX-XXX | - | Ingresos |
| 5XX-XXX-XXX | - | Gastos Operativos |
| 6XX-XXX-XXX | - | Otros Gastos |
| 7XX-XXX-XXX | - | Gastos Financieros |
GenericoParser
Parser para archivos Excel/CSV genéricos.
Formatos soportados
.xlsx- Excel 2007+.xls- Excel 97-2003.csv- Valores separados por coma/punto y coma
Detección de columnas
Busca headers similares a:
| Campo | Aliases aceptados |
|---|---|
| codigo | codigo, cuenta, code, account, cta, numero |
| nombre | nombre, descripcion, name, description, concepto |
| saldo_inicial_deudor | saldo_inicial_deudor, inicial_debe, opening_debit |
| cargos | cargos, debe, debit, debits, movs_deudor |
| abonos | abonos, haber, credit, credits, movs_acreedor |
| saldo_final_deudor | saldo_final_deudor, final_debe, closing_debit |
Detección de delimitador CSV
Detecta automáticamente: ,, ;, \t, |
Agregar Nuevo Parser
- Crear clase en
app/Services/Parsers/:
<?php
namespace App\Services\Parsers;
class AspelParser implements ParserInterface
{
public function getSistema(): string
{
return 'aspel';
}
public function puedeManej(string $filePath): bool
{
// Lógica de detección para Aspel
$text = file_get_contents($filePath);
return str_contains(strtoupper($text), 'ASPEL');
}
public function parsear(string $filePath): array
{
// Lógica de parsing
$cuentas = [];
// ... extraer datos ...
return $cuentas;
}
}
- Registrar en DetectorFormato:
// En DetectorFormato::__construct()
$this->parsers = [
new ContpaqiParser(),
new AspelParser(), // ← Agregar antes de GenericoParser
new GenericoParser(),
];
- Agregar reglas de mapeo en seeder:
// Crear nuevo seeder: ReglasMapeeoAspelSeeder.php
ReglaMapeo::create([
'sistema_origen' => 'aspel',
'patron_regex' => '/^1\d{3}/',
'reporte_contable_id' => $balance->id,
'categoria_contable_id' => $activosCirc->id,
'prioridad' => 10,
]);
ClasificadorCuentas
Aplica reglas de mapeo a las cuentas importadas.
Proceso:
- Buscar mapeo específico del cliente
- Si no existe, buscar regla del sistema
- Si no existe regla, marcar para revisión
Detección de anomalías:
- Cuentas 45X (normalmente pasivo) usadas como gasto
- Cuentas 8XX-9XX (cuentas de orden)
- Códigos sin regla de mapeo
// Ejemplo de nota de revisión automática
"Código 45X normalmente es pasivo pero podría ser gasto. Verificar clasificación."