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:
143
backend/app/Http/Controllers/BalanzaController.php
Normal file
143
backend/app/Http/Controllers/BalanzaController.php
Normal file
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Balanza;
|
||||
use App\Models\Cliente;
|
||||
use App\Services\Parsers\DetectorFormato;
|
||||
use App\Services\ClasificadorCuentas;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class BalanzaController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
private DetectorFormato $detector,
|
||||
private ClasificadorCuentas $clasificador,
|
||||
) {}
|
||||
|
||||
public function index(Request $request, Cliente $cliente): JsonResponse
|
||||
{
|
||||
if (!$request->user()->canAccessCliente($cliente->id)) {
|
||||
return response()->json(['message' => 'No autorizado'], 403);
|
||||
}
|
||||
|
||||
$balanzas = $cliente->balanzas()
|
||||
->orderByDesc('periodo_fin')
|
||||
->get();
|
||||
|
||||
return response()->json($balanzas);
|
||||
}
|
||||
|
||||
public function store(Request $request, Cliente $cliente): JsonResponse
|
||||
{
|
||||
if (!$request->user()->canAccessCliente($cliente->id)) {
|
||||
return response()->json(['message' => 'No autorizado'], 403);
|
||||
}
|
||||
|
||||
$request->validate([
|
||||
'archivo' => 'required|file|mimes:pdf,xlsx,xls,csv|max:10240',
|
||||
'periodo_inicio' => 'required|date',
|
||||
'periodo_fin' => 'required|date|after_or_equal:periodo_inicio',
|
||||
]);
|
||||
|
||||
$file = $request->file('archivo');
|
||||
$path = $file->store('balanzas/' . $cliente->id, 'local');
|
||||
|
||||
$balanza = Balanza::create([
|
||||
'cliente_id' => $cliente->id,
|
||||
'periodo_inicio' => $request->periodo_inicio,
|
||||
'periodo_fin' => $request->periodo_fin,
|
||||
'archivo_original' => $path,
|
||||
'sistema_origen' => 'pendiente',
|
||||
'status' => 'pendiente',
|
||||
]);
|
||||
|
||||
// Procesar archivo en background o inmediatamente
|
||||
try {
|
||||
$this->procesarBalanza($balanza, $path);
|
||||
} catch (\Exception $e) {
|
||||
$balanza->update([
|
||||
'status' => 'error',
|
||||
'error_mensaje' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
|
||||
return response()->json($balanza, 201);
|
||||
}
|
||||
|
||||
public function show(Request $request, Balanza $balanza): JsonResponse
|
||||
{
|
||||
if (!$request->user()->canAccessCliente($balanza->cliente_id)) {
|
||||
return response()->json(['message' => 'No autorizado'], 403);
|
||||
}
|
||||
|
||||
return response()->json($balanza->load(['cuentas', 'cliente']));
|
||||
}
|
||||
|
||||
public function cuentas(Request $request, Balanza $balanza): JsonResponse
|
||||
{
|
||||
if (!$request->user()->canAccessCliente($balanza->cliente_id)) {
|
||||
return response()->json(['message' => 'No autorizado'], 403);
|
||||
}
|
||||
|
||||
$cuentas = $balanza->cuentas()
|
||||
->with(['categoriaContable', 'reporteContable', 'cuentaPadre'])
|
||||
->orderBy('codigo')
|
||||
->get();
|
||||
|
||||
return response()->json($cuentas);
|
||||
}
|
||||
|
||||
public function updateExclusiones(Request $request, Balanza $balanza): JsonResponse
|
||||
{
|
||||
if (!$request->user()->canAccessCliente($balanza->cliente_id)) {
|
||||
return response()->json(['message' => 'No autorizado'], 403);
|
||||
}
|
||||
|
||||
$request->validate([
|
||||
'exclusiones' => 'required|array',
|
||||
'exclusiones.*' => 'integer|exists:cuentas,id',
|
||||
]);
|
||||
|
||||
// Marcar todas como incluidas primero
|
||||
$balanza->cuentas()->update(['excluida' => false]);
|
||||
|
||||
// Marcar las seleccionadas como excluidas
|
||||
$balanza->cuentas()
|
||||
->whereIn('id', $request->exclusiones)
|
||||
->update(['excluida' => true]);
|
||||
|
||||
// Recalcular saldos de cuentas padre
|
||||
$cuentasPadre = $balanza->cuentasPadre()->get();
|
||||
foreach ($cuentasPadre as $cuentaPadre) {
|
||||
$cuentaPadre->recalcularSaldoDesdeHijos();
|
||||
}
|
||||
|
||||
return response()->json(['message' => 'Exclusiones actualizadas']);
|
||||
}
|
||||
|
||||
private function procesarBalanza(Balanza $balanza, string $path): void
|
||||
{
|
||||
$balanza->update(['status' => 'procesando']);
|
||||
|
||||
$fullPath = Storage::disk('local')->path($path);
|
||||
|
||||
// Detectar sistema origen
|
||||
$resultado = $this->detector->detectar($fullPath);
|
||||
$balanza->update(['sistema_origen' => $resultado['sistema']]);
|
||||
|
||||
// Parsear y guardar cuentas
|
||||
$cuentas = $resultado['parser']->parsear($fullPath);
|
||||
|
||||
foreach ($cuentas as $cuentaData) {
|
||||
$balanza->cuentas()->create($cuentaData);
|
||||
}
|
||||
|
||||
// Clasificar cuentas
|
||||
$this->clasificador->clasificar($balanza);
|
||||
|
||||
$balanza->update(['status' => 'completado']);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user