feat: agregar logging y manejo de eliminación de archivos en PackageController y UpdateController

This commit is contained in:
Juan Felipe Zapata Moreno 2025-12-10 20:52:45 -06:00
parent 859596d858
commit 685ad3d3a8
3 changed files with 105 additions and 21 deletions

View File

@ -9,6 +9,7 @@
use App\Models\CatalogTagStatus; use App\Models\CatalogTagStatus;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Database\QueryException; use Illuminate\Database\QueryException;
use App\Models\Package; use App\Models\Package;
@ -20,14 +21,28 @@ class PackageController extends Controller
public function index(Request $request) public function index(Request $request)
{ {
try { 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.status:id,code,name',
'tags.vehicle:id,placa,niv', 'tags.vehicle:id,placa,niv',
'tags.module:id,name', 'tags.module:id,name',
'user:id,name,email' 'user:id,name,email'
]) ]);
->withCount('tags') } else {
->orderBy('id', 'ASC'); $packages->with('user:id,name,email');
}
$packages->withCount('tags')->orderBy('id', 'ASC');
if ($request->filled('lote') || $request->filled('lot')) { if ($request->filled('lote') || $request->filled('lot')) {
$loteValue = $request->input('lote') ?? $request->input('lot'); $loteValue = $request->input('lote') ?? $request->input('lot');
@ -39,8 +54,14 @@ public function index(Request $request)
$packages->where('box_number', 'LIKE', '%' . trim($cajaValue) . '%'); $packages->where('box_number', 'LIKE', '%' . trim($cajaValue) . '%');
} }
Log::info('PackageController@index - Ejecutando paginación');
$paginatedPackages = $packages->paginate(config('app.pagination')); $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 // Validación si no hay resultados
if ($paginatedPackages->isEmpty()) { if ($paginatedPackages->isEmpty()) {
return ApiResponse::NOT_FOUND->response([ return ApiResponse::NOT_FOUND->response([
@ -68,20 +89,26 @@ public function index(Request $request)
] : null, ] : null,
'estadisticas' => [ 'estadisticas' => [
'total' => $package->tags->count(), 'total' => $package->tags->count(),
'available' => $package->tags->where('status.code', 'available')->count(), 'available' => $package->tags->filter(function($tag) {
'assigned' => $package->tags->where('status.code', 'assigned')->count(), return $tag->status && $tag->status->code === 'available';
'cancelled' => $package->tags->where('status.code', 'cancelled')->count(), })->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) { 'tags' => $package->tags->map(function ($tag) {
return [ return [
'id' => $tag->id, 'id' => $tag->id,
'folio' => $tag->folio, 'folio' => $tag->folio,
'tag_number' => $tag->tag_number, 'tag_number' => $tag->tag_number,
'status' => [ 'status' => $tag->status ? [
'id' => $tag->status->id, 'id' => $tag->status->id,
'code' => $tag->status->code, 'code' => $tag->status->code,
'name' => $tag->status->name, 'name' => $tag->status->name,
], ] : null,
'vehicle' => $tag->vehicle ? [ 'vehicle' => $tag->vehicle ? [
'id' => $tag->vehicle->id, 'id' => $tag->vehicle->id,
'placa' => $tag->vehicle->placa, 'placa' => $tag->vehicle->placa,
@ -97,10 +124,19 @@ public function index(Request $request)
}); });
} }
Log::info('PackageController@index - Retornando respuesta exitosa');
return ApiResponse::OK->response([ return ApiResponse::OK->response([
'Paquetes' => $paginatedPackages, 'Paquetes' => $paginatedPackages,
]); ]);
} catch (\Exception $e) { } 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([ return ApiResponse::INTERNAL_ERROR->response([
'message' => 'Error al obtener los paquetes', 'message' => 'Error al obtener los paquetes',
'error' => $e->getMessage(), 'error' => $e->getMessage(),

View File

@ -845,7 +845,36 @@ public function updateData(VehicleUpdateRequest $request, $id)
// Procesar archivos // Procesar archivos
$uploadedFiles = []; $uploadedFiles = [];
$replacedFiles = []; $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')) { if ($request->hasFile('files')) {
$files = $request->file('files'); $files = $request->file('files');
$nameIds = $request->input('name_id', []); $nameIds = $request->input('name_id', []);
@ -913,7 +942,7 @@ public function updateData(VehicleUpdateRequest $request, $id)
} }
// Registrar el log de cambios si hubo actualizaciones // 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([ VehicleTagLog::create([
'vehicle_id' => $vehicle->id, 'vehicle_id' => $vehicle->id,
'tag_id' => $tag->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 // 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 // Recargar el vehículo y propietario con los datos actualizados
$vehicle->refresh(); $vehicle->refresh();
$owner->refresh(); $owner->refresh();
@ -976,14 +1005,14 @@ public function updateData(VehicleUpdateRequest $request, $id)
$record->load(['vehicle.owner', 'vehicle.tag', 'files', 'error']); $record->load(['vehicle.owner', 'vehicle.tag', 'files', 'error']);
$message = 'Expediente actualizado exitosamente'; $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.'; $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.'; $message = 'Datos del vehículo/propietario y archivos actualizados exitosamente.';
} elseif (($hasVehicleChanges || $hasOwnerChanges) && empty($uploadedFiles)) { } elseif (($hasVehicleChanges || $hasOwnerChanges) && empty($uploadedFiles) && empty($deletedFiles)) {
$message = 'Datos del vehículo/propietario actualizados exitosamente. No se subieron archivos.'; $message = 'Datos del vehículo/propietario actualizados exitosamente. No se modificaron archivos.';
} elseif (!$hasVehicleChanges && !$hasOwnerChanges && !empty($uploadedFiles)) { } elseif (!$hasVehicleChanges && !$hasOwnerChanges && (!empty($uploadedFiles) || !empty($deletedFiles))) {
$message = 'Archivos subidos exitosamente. No hubo cambios en los datos del vehículo/propietario.'; $message = 'Archivos modificados exitosamente. No hubo cambios en los datos del vehículo/propietario.';
} }
return ApiResponse::OK->response([ return ApiResponse::OK->response([
@ -993,9 +1022,11 @@ public function updateData(VehicleUpdateRequest $request, $id)
'vehicle_updated' => $hasVehicleChanges, 'vehicle_updated' => $hasVehicleChanges,
'owner_updated' => $hasOwnerChanges, 'owner_updated' => $hasOwnerChanges,
'files_uploaded' => count($uploadedFiles) > 0, 'files_uploaded' => count($uploadedFiles) > 0,
'files_deleted' => count($deletedFiles) > 0,
], ],
'record' => $record, 'record' => $record,
'uploaded_files' => $uploadedFiles, 'uploaded_files' => $uploadedFiles,
'deleted_files' => $deletedFiles,
'replaced_count' => count($replacedFiles), 'replaced_count' => count($replacedFiles),
'total_files' => File::where('record_id', $record->id)->count(), 'total_files' => File::where('record_id', $record->id)->count(),
]); ]);

View File

@ -12,17 +12,28 @@ class RepuveService
private string $baseUrl; private string $baseUrl;
private string $roboEndpoint; private string $roboEndpoint;
private string $inscripcionEndpoint; private string $inscripcionEndpoint;
private string $username; private ?string $username = null;
private string $password; private ?string $password = null;
private bool $credentialsLoaded = false;
public function __construct() public function __construct()
{ {
$this->baseUrl = config('services.repuve_federal.base_url'); $this->baseUrl = config('services.repuve_federal.base_url');
$this->roboEndpoint = config('services.repuve_federal.robo_endpoint'); $this->roboEndpoint = config('services.repuve_federal.robo_endpoint');
$this->inscripcionEndpoint = config('services.repuve_federal.inscripcion_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->loadCredentials();
$this->credentialsLoaded = true;
} }
/** /**
@ -59,6 +70,8 @@ private function loadCredentials(): void
public function consultarPadron(string $niv) public function consultarPadron(string $niv)
{ {
$this->asegurarCargaCredenciales();
$url = $this->baseUrl . $this->roboEndpoint; $url = $this->baseUrl . $this->roboEndpoint;
$arg2 = $niv . '|||||||'; $arg2 = $niv . '|||||||';
@ -207,6 +220,7 @@ private function parseVehicleResponse(string $soapResponse, string $niv)
public function verificarRobo(?string $niv = null, ?string $placa = null): array public function verificarRobo(?string $niv = null, ?string $placa = null): array
{ {
try { try {
$this->asegurarCargaCredenciales();
if (empty($niv) && empty($placa)) { if (empty($niv) && empty($placa)) {
logger()->warning('REPUVE verificarRobo: No se proporcionó NIV ni 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) public function consultarVehiculo(?string $niv = null, ?string $placa = null)
{ {
try { try {
$this->asegurarCargaCredenciales();
$url = $this->baseUrl . '/jaxws-consultarpv/ConsultaRpv'; $url = $this->baseUrl . '/jaxws-consultarpv/ConsultaRpv';
// Construir arg2: NIV|||||||| // Construir arg2: NIV||||||||
@ -426,9 +442,10 @@ public function consultarVehiculo(?string $niv = null, ?string $placa = null)
public function inscribirVehiculo(array $datos) public function inscribirVehiculo(array $datos)
{ {
$this->asegurarCargaCredenciales();
$url = $this->baseUrl . $this->inscripcionEndpoint; $url = $this->baseUrl . $this->inscripcionEndpoint;
// DATOS HARDCODEADOS
$arg2 = implode('|', [ $arg2 = implode('|', [
$datos['ent_fed'] ?? '', // 1. Entidad federativa $datos['ent_fed'] ?? '', // 1. Entidad federativa
$datos['ofcexp'] ?? '', // 2. Oficina expedición $datos['ofcexp'] ?? '', // 2. Oficina expedición