Initial commit: Horux Strategy Platform
- 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>
This commit is contained in:
253
docs/07-parsers.md
Normal file
253
docs/07-parsers.md
Normal file
@@ -0,0 +1,253 @@
|
||||
# 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:
|
||||
|
||||
```php
|
||||
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:
|
||||
|
||||
```php
|
||||
[
|
||||
'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.
|
||||
|
||||
```php
|
||||
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
|
||||
|
||||
1. **Crear clase** en `app/Services/Parsers/`:
|
||||
|
||||
```php
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. **Registrar en DetectorFormato**:
|
||||
|
||||
```php
|
||||
// En DetectorFormato::__construct()
|
||||
$this->parsers = [
|
||||
new ContpaqiParser(),
|
||||
new AspelParser(), // ← Agregar antes de GenericoParser
|
||||
new GenericoParser(),
|
||||
];
|
||||
```
|
||||
|
||||
3. **Agregar reglas de mapeo** en seeder:
|
||||
|
||||
```php
|
||||
// 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:
|
||||
1. Buscar mapeo específico del cliente
|
||||
2. Si no existe, buscar regla del sistema
|
||||
3. 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
|
||||
|
||||
```php
|
||||
// Ejemplo de nota de revisión automática
|
||||
"Código 45X normalmente es pasivo pero podría ser gasto. Verificar clasificación."
|
||||
```
|
||||
Reference in New Issue
Block a user