- 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>
120 lines
3.8 KiB
PHP
120 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Balanza;
|
|
use App\Models\Cuenta;
|
|
use App\Models\ReglaMapeo;
|
|
use App\Models\MapeoCuenta;
|
|
|
|
class ClasificadorCuentas
|
|
{
|
|
/**
|
|
* Clasifica todas las cuentas de una balanza según las reglas de mapeo
|
|
*/
|
|
public function clasificar(Balanza $balanza): void
|
|
{
|
|
$cuentas = $balanza->cuentas()->get();
|
|
$sistemaOrigen = $balanza->sistema_origen;
|
|
$clienteId = $balanza->cliente_id;
|
|
|
|
// Obtener reglas ordenadas por prioridad
|
|
$reglas = ReglaMapeo::where('sistema_origen', $sistemaOrigen)
|
|
->where('activo', true)
|
|
->orderByDesc('prioridad')
|
|
->get();
|
|
|
|
// Obtener mapeos específicos del cliente
|
|
$mapeosCliente = MapeoCuenta::where('cliente_id', $clienteId)->get();
|
|
|
|
foreach ($cuentas as $cuenta) {
|
|
$this->clasificarCuenta($cuenta, $reglas, $mapeosCliente);
|
|
}
|
|
|
|
// Establecer relaciones padre-hijo en base de datos
|
|
$this->establecerRelacionesPadreHijo($balanza);
|
|
}
|
|
|
|
private function clasificarCuenta(Cuenta $cuenta, $reglas, $mapeosCliente): void
|
|
{
|
|
// Primero buscar en mapeos específicos del cliente
|
|
foreach ($mapeosCliente as $mapeo) {
|
|
if ($this->coincidePatron($cuenta->codigo, $mapeo->codigo_patron)) {
|
|
$cuenta->update([
|
|
'categoria_contable_id' => $mapeo->categoria_contable_id,
|
|
'reporte_contable_id' => $mapeo->categoriaContable->reporte_contable_id,
|
|
'requiere_revision' => false,
|
|
]);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Buscar en reglas del sistema
|
|
foreach ($reglas as $regla) {
|
|
if ($regla->coincideCon($cuenta->codigo)) {
|
|
$cuenta->update([
|
|
'categoria_contable_id' => $regla->categoria_contable_id,
|
|
'reporte_contable_id' => $regla->reporte_contable_id,
|
|
'requiere_revision' => false,
|
|
]);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// No se encontró regla - marcar para revisión
|
|
$this->marcarParaRevision($cuenta);
|
|
}
|
|
|
|
private function coincidePatron(string $codigo, string $patron): bool
|
|
{
|
|
// El patrón puede ser exacto o con wildcards (*)
|
|
$regex = '/^' . str_replace(['*', '-'], ['.*', '\-'], $patron) . '$/';
|
|
return (bool) preg_match($regex, $codigo);
|
|
}
|
|
|
|
private function marcarParaRevision(Cuenta $cuenta): void
|
|
{
|
|
$nota = $this->generarNotaRevision($cuenta);
|
|
|
|
$cuenta->update([
|
|
'requiere_revision' => true,
|
|
'nota_revision' => $nota,
|
|
]);
|
|
}
|
|
|
|
private function generarNotaRevision(Cuenta $cuenta): string
|
|
{
|
|
$codigo = $cuenta->codigo;
|
|
$notas = [];
|
|
|
|
// Detectar posibles anomalías basadas en el código
|
|
if (preg_match('/^45[0-9]-/', $codigo)) {
|
|
$notas[] = 'Código 45X normalmente es pasivo pero podría ser gasto. Verificar clasificación.';
|
|
}
|
|
|
|
if (preg_match('/^[89][0-9]{2}-/', $codigo)) {
|
|
$notas[] = 'Cuenta de orden o especial. Verificar si debe incluirse en estados financieros.';
|
|
}
|
|
|
|
if (empty($notas)) {
|
|
$notas[] = 'No se encontró regla de mapeo para este código. Asignar clasificación manualmente.';
|
|
}
|
|
|
|
return implode(' ', $notas);
|
|
}
|
|
|
|
private function establecerRelacionesPadreHijo(Balanza $balanza): void
|
|
{
|
|
$cuentas = $balanza->cuentas()->get()->keyBy('codigo');
|
|
|
|
foreach ($cuentas as $cuenta) {
|
|
if (isset($cuenta->cuenta_padre_codigo)) {
|
|
$padre = $cuentas->get($cuenta->cuenta_padre_codigo);
|
|
if ($padre) {
|
|
$cuenta->update(['cuenta_padre_id' => $padre->id]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|