From 685ad3d3a805cea45f3cccc679eaba5ee09a707b Mon Sep 17 00:00:00 2001 From: Juan Felipe Zapata Moreno Date: Wed, 10 Dec 2025 20:52:45 -0600 Subject: [PATCH] =?UTF-8?q?feat:=20agregar=20logging=20y=20manejo=20de=20e?= =?UTF-8?q?liminaci=C3=B3n=20de=20archivos=20en=20PackageController=20y=20?= =?UTF-8?q?UpdateController?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Repuve/PackageController.php | 54 +++++++++++++++---- .../Controllers/Repuve/UpdateController.php | 47 +++++++++++++--- app/Services/RepuveService.php | 25 +++++++-- 3 files changed, 105 insertions(+), 21 deletions(-) diff --git a/app/Http/Controllers/Repuve/PackageController.php b/app/Http/Controllers/Repuve/PackageController.php index b2b51b6..ab8d9c3 100644 --- a/app/Http/Controllers/Repuve/PackageController.php +++ b/app/Http/Controllers/Repuve/PackageController.php @@ -9,6 +9,7 @@ use App\Models\CatalogTagStatus; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Log; use Illuminate\Http\Request; use Illuminate\Database\QueryException; use App\Models\Package; @@ -20,14 +21,28 @@ class PackageController extends Controller public function index(Request $request) { try { - $packages = Package::with([ + Log::info('PackageController@index - Iniciando consulta de paquetes', [ + 'filters' => $request->all() + ]); + + // Si NO hay filtro de caja, no cargar las relaciones de tags para optimizar + $shouldLoadTags = $request->filled('caja') || $request->filled('box_number'); + + $packages = Package::query(); + + if ($shouldLoadTags) { + $packages->with([ + 'tags:id,folio,tag_number,package_id,status_id,vehicle_id,module_id', 'tags.status:id,code,name', 'tags.vehicle:id,placa,niv', 'tags.module:id,name', 'user:id,name,email' - ]) - ->withCount('tags') - ->orderBy('id', 'ASC'); + ]); + } else { + $packages->with('user:id,name,email'); + } + + $packages->withCount('tags')->orderBy('id', 'ASC'); if ($request->filled('lote') || $request->filled('lot')) { $loteValue = $request->input('lote') ?? $request->input('lot'); @@ -39,8 +54,14 @@ public function index(Request $request) $packages->where('box_number', 'LIKE', '%' . trim($cajaValue) . '%'); } + Log::info('PackageController@index - Ejecutando paginación'); $paginatedPackages = $packages->paginate(config('app.pagination')); + Log::info('PackageController@index - Paginación completada', [ + 'total' => $paginatedPackages->total(), + 'count' => $paginatedPackages->count() + ]); + // Validación si no hay resultados if ($paginatedPackages->isEmpty()) { return ApiResponse::NOT_FOUND->response([ @@ -68,20 +89,26 @@ public function index(Request $request) ] : null, 'estadisticas' => [ 'total' => $package->tags->count(), - 'available' => $package->tags->where('status.code', 'available')->count(), - 'assigned' => $package->tags->where('status.code', 'assigned')->count(), - 'cancelled' => $package->tags->where('status.code', 'cancelled')->count(), + 'available' => $package->tags->filter(function($tag) { + return $tag->status && $tag->status->code === 'available'; + })->count(), + 'assigned' => $package->tags->filter(function($tag) { + return $tag->status && $tag->status->code === 'assigned'; + })->count(), + 'cancelled' => $package->tags->filter(function($tag) { + return $tag->status && $tag->status->code === 'cancelled'; + })->count(), ], 'tags' => $package->tags->map(function ($tag) { return [ 'id' => $tag->id, 'folio' => $tag->folio, 'tag_number' => $tag->tag_number, - 'status' => [ + 'status' => $tag->status ? [ 'id' => $tag->status->id, 'code' => $tag->status->code, 'name' => $tag->status->name, - ], + ] : null, 'vehicle' => $tag->vehicle ? [ 'id' => $tag->vehicle->id, 'placa' => $tag->vehicle->placa, @@ -97,10 +124,19 @@ public function index(Request $request) }); } + Log::info('PackageController@index - Retornando respuesta exitosa'); + return ApiResponse::OK->response([ 'Paquetes' => $paginatedPackages, ]); } catch (\Exception $e) { + Log::error('PackageController@index - Error capturado', [ + 'message' => $e->getMessage(), + 'file' => $e->getFile(), + 'line' => $e->getLine(), + 'trace' => $e->getTraceAsString() + ]); + return ApiResponse::INTERNAL_ERROR->response([ 'message' => 'Error al obtener los paquetes', 'error' => $e->getMessage(), diff --git a/app/Http/Controllers/Repuve/UpdateController.php b/app/Http/Controllers/Repuve/UpdateController.php index 6152c46..322a842 100644 --- a/app/Http/Controllers/Repuve/UpdateController.php +++ b/app/Http/Controllers/Repuve/UpdateController.php @@ -845,7 +845,36 @@ public function updateData(VehicleUpdateRequest $request, $id) // Procesar archivos $uploadedFiles = []; $replacedFiles = []; + $deletedFiles = []; + // Manejar eliminación de archivos + if ($request->has('delete_files')) { + $filesToDelete = $request->input('delete_files', []); + + foreach ($filesToDelete as $fileId) { + $fileToDelete = File::where('id', $fileId) + ->where('record_id', $record->id) + ->first(); + + if ($fileToDelete) { + // Eliminar archivo físico + if (Storage::disk('public')->exists($fileToDelete->path)) { + Storage::disk('public')->delete($fileToDelete->path); + } + + $deletedFiles[] = [ + 'id' => $fileToDelete->id, + 'name_id' => $fileToDelete->name_id, + 'name' => $fileToDelete->catalogName->name ?? 'Desconocido', + 'path' => $fileToDelete->path, + ]; + + $fileToDelete->delete(); + } + } + } + + // Manejar carga/reemplazo de archivos if ($request->hasFile('files')) { $files = $request->file('files'); $nameIds = $request->input('name_id', []); @@ -913,7 +942,7 @@ public function updateData(VehicleUpdateRequest $request, $id) } // Registrar el log de cambios si hubo actualizaciones - if ($hasVehicleChanges || $hasOwnerChanges || count($uploadedFiles) > 0) { + if ($hasVehicleChanges || $hasOwnerChanges || count($uploadedFiles) > 0 || count($deletedFiles) > 0) { VehicleTagLog::create([ 'vehicle_id' => $vehicle->id, 'tag_id' => $tag->id, @@ -923,7 +952,7 @@ public function updateData(VehicleUpdateRequest $request, $id) } // datos para REPUVE Nacional usando datos actuales de la BD - if ($hasVehicleChanges || $hasOwnerChanges || count($uploadedFiles) > 0) { + if ($hasVehicleChanges || $hasOwnerChanges || count($uploadedFiles) > 0 || count($deletedFiles) > 0) { // Recargar el vehículo y propietario con los datos actualizados $vehicle->refresh(); $owner->refresh(); @@ -976,14 +1005,14 @@ public function updateData(VehicleUpdateRequest $request, $id) $record->load(['vehicle.owner', 'vehicle.tag', 'files', 'error']); $message = 'Expediente actualizado exitosamente'; - if (!$hasVehicleChanges && !$hasOwnerChanges && empty($uploadedFiles)) { + if (!$hasVehicleChanges && !$hasOwnerChanges && empty($uploadedFiles) && empty($deletedFiles)) { $message = 'No se detectaron cambios. Los datos ya estaban actualizados.'; - } elseif (($hasVehicleChanges || $hasOwnerChanges) && !empty($uploadedFiles)) { + } elseif (($hasVehicleChanges || $hasOwnerChanges) && (!empty($uploadedFiles) || !empty($deletedFiles))) { $message = 'Datos del vehículo/propietario y archivos actualizados exitosamente.'; - } elseif (($hasVehicleChanges || $hasOwnerChanges) && empty($uploadedFiles)) { - $message = 'Datos del vehículo/propietario actualizados exitosamente. No se subieron archivos.'; - } elseif (!$hasVehicleChanges && !$hasOwnerChanges && !empty($uploadedFiles)) { - $message = 'Archivos subidos exitosamente. No hubo cambios en los datos del vehículo/propietario.'; + } elseif (($hasVehicleChanges || $hasOwnerChanges) && empty($uploadedFiles) && empty($deletedFiles)) { + $message = 'Datos del vehículo/propietario actualizados exitosamente. No se modificaron archivos.'; + } elseif (!$hasVehicleChanges && !$hasOwnerChanges && (!empty($uploadedFiles) || !empty($deletedFiles))) { + $message = 'Archivos modificados exitosamente. No hubo cambios en los datos del vehículo/propietario.'; } return ApiResponse::OK->response([ @@ -993,9 +1022,11 @@ public function updateData(VehicleUpdateRequest $request, $id) 'vehicle_updated' => $hasVehicleChanges, 'owner_updated' => $hasOwnerChanges, 'files_uploaded' => count($uploadedFiles) > 0, + 'files_deleted' => count($deletedFiles) > 0, ], 'record' => $record, 'uploaded_files' => $uploadedFiles, + 'deleted_files' => $deletedFiles, 'replaced_count' => count($replacedFiles), 'total_files' => File::where('record_id', $record->id)->count(), ]); diff --git a/app/Services/RepuveService.php b/app/Services/RepuveService.php index cbf84a7..1fb57f6 100644 --- a/app/Services/RepuveService.php +++ b/app/Services/RepuveService.php @@ -12,17 +12,28 @@ class RepuveService private string $baseUrl; private string $roboEndpoint; private string $inscripcionEndpoint; - private string $username; - private string $password; + private ?string $username = null; + private ?string $password = null; + private bool $credentialsLoaded = false; public function __construct() { $this->baseUrl = config('services.repuve_federal.base_url'); $this->roboEndpoint = config('services.repuve_federal.robo_endpoint'); $this->inscripcionEndpoint = config('services.repuve_federal.inscripcion_endpoint'); + } + + /** + * Asegurar que las credenciales estén cargadas (lazy loading) + */ + private function asegurarCargaCredenciales(): void + { + if ($this->credentialsLoaded) { + return; // Ya están cargadas + } - // Cargar credenciales desde BD (encriptadas) $this->loadCredentials(); + $this->credentialsLoaded = true; } /** @@ -59,6 +70,8 @@ private function loadCredentials(): void public function consultarPadron(string $niv) { + $this->asegurarCargaCredenciales(); + $url = $this->baseUrl . $this->roboEndpoint; $arg2 = $niv . '|||||||'; @@ -207,6 +220,7 @@ private function parseVehicleResponse(string $soapResponse, string $niv) public function verificarRobo(?string $niv = null, ?string $placa = null): array { try { + $this->asegurarCargaCredenciales(); if (empty($niv) && empty($placa)) { logger()->warning('REPUVE verificarRobo: No se proporcionó NIV ni PLACA'); @@ -330,6 +344,8 @@ public function verificarRobo(?string $niv = null, ?string $placa = null): array public function consultarVehiculo(?string $niv = null, ?string $placa = null) { try { + $this->asegurarCargaCredenciales(); + $url = $this->baseUrl . '/jaxws-consultarpv/ConsultaRpv'; // Construir arg2: NIV|||||||| @@ -426,9 +442,10 @@ public function consultarVehiculo(?string $niv = null, ?string $placa = null) public function inscribirVehiculo(array $datos) { + $this->asegurarCargaCredenciales(); + $url = $this->baseUrl . $this->inscripcionEndpoint; - // DATOS HARDCODEADOS $arg2 = implode('|', [ $datos['ent_fed'] ?? '', // 1. Entidad federativa $datos['ofcexp'] ?? '', // 2. Oficina expedición