From 5a144e282f1cf86316caf031c22502e6a930d87d Mon Sep 17 00:00:00 2001 From: Juan Felipe Zapata Moreno Date: Sun, 7 Dec 2025 17:16:39 -0600 Subject: [PATCH] =?UTF-8?q?refactor:=20renombrar=20ruta=20de=20actualizaci?= =?UTF-8?q?=C3=B3n=20de=20veh=C3=ADculo=20a=20'actualizar-informacion'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Repuve/UpdateController.php | 432 ++++++++---------- routes/api.php | 2 +- 2 files changed, 187 insertions(+), 247 deletions(-) diff --git a/app/Http/Controllers/Repuve/UpdateController.php b/app/Http/Controllers/Repuve/UpdateController.php index 3e268b0..5fcab4e 100644 --- a/app/Http/Controllers/Repuve/UpdateController.php +++ b/app/Http/Controllers/Repuve/UpdateController.php @@ -8,10 +8,10 @@ use Notsoweb\ApiResponse\Enums\ApiResponse; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Storage; -use Illuminate\Support\Facades\Cache; use App\Models\Record; use App\Models\File; use App\Models\Owner; +use App\Models\Vehicle; use App\Models\CatalogNameImg; use App\Models\VehicleTagLog; use App\Models\Tag; @@ -217,290 +217,218 @@ public function tagSubstitution(Request $request) } } - public function vehicleUpdate(VehicleUpdateRequest $request) + public function vehicleUpdate(Request $request) { try { - $folio = $request->input('folio'); - $tagNumber = $request->input('tag_number'); - $niv = $request->input('niv'); + $request->validate([ + 'placa' => 'required|string|max:20', + ], [ + 'placa.required' => 'La placa es requerida', + 'placa.string' => 'La placa debe ser texto', + 'placa.max' => 'La placa no puede exceder 20 caracteres', + ]); - /* $isStolen = $this->checkIfStolen($niv); + $placa = $request->input('placa'); - if ($isStolen) { - return ApiResponse::FORBIDDEN->response([ - 'niv' => $niv, - 'stolen' => true, - 'message' => 'El vehículo reporta robo. No se puede continuar con la actualización.', - ]); - } */ - - $record = Record::with(['vehicle.owner', 'vehicle.tag', 'files', 'error']) - ->where('folio', $folio) + $vehicle = Vehicle::with(['owner', 'tag.status']) + ->where('placa', $placa) ->first(); - if (!$record) { + if (!$vehicle) { return ApiResponse::NOT_FOUND->response([ - 'message' => 'No se encontró el expediente', - 'folio' => $folio, + 'message' => 'No se encontró un vehículo con esa placa en el sistema', + 'placa' => $placa, + ]); + } + + if (!$vehicle->owner) { + return ApiResponse::BAD_REQUEST->response([ + 'message' => 'El vehículo no tiene un propietario asociado', + 'placa' => $placa, + 'vehicle_id' => $vehicle->id, ]); } - $vehicle = $record->vehicle; $tag = $vehicle->tag; if (!$tag) { - return ApiResponse::NOT_FOUND->response([ - 'message' => 'El TAG no coincide con el registrado en el expediente', - 'tag_number' => $tagNumber, + return ApiResponse::BAD_REQUEST->response([ + 'message' => 'El vehículo no tiene un TAG asignado', + 'placa' => $placa, + 'vehicle_id' => $vehicle->id, ]); } - if ($vehicle->niv !== $niv) { + if (!$tag->isAssigned()) { return ApiResponse::BAD_REQUEST->response([ - 'message' => 'El NIV no coincide con el registrado en el expediente', + 'message' => 'El TAG del vehículo no está en estado activo', + 'placa' => $placa, + 'tag_status' => $tag->status->name, + 'tag_folio' => $tag->folio, + ]); + } + + $record = Record::where('vehicle_id', $vehicle->id)->first(); + + if (!$record) { + return ApiResponse::BAD_REQUEST->response([ + 'message' => 'El vehículo no tiene un expediente (record) asociado', + 'placa' => $placa, + 'vehicle_id' => $vehicle->id, + ]); + } + + try { + $datosCompletosRaw = $this->padronEstatalService->getVehiculoByPlaca($placa); + $vehicleDataEstatal = $this->padronEstatalService->extraerDatosVehiculo($datosCompletosRaw); + $ownerDataEstatal = $this->padronEstatalService->extraerDatosPropietario($datosCompletosRaw); + } catch (Exception $e) { + return ApiResponse::BAD_REQUEST->response([ + 'message' => 'Error al consultar el Padrón Estatal', + 'placa' => $placa, + 'error' => $e->getMessage(), + ]); + } + + $$nivEstatal = $vehicleDataEstatal['niv']; + $placaEstatal = $vehicleDataEstatal['placa']; + + if ($vehicle->niv !== $nivEstatal) { + return ApiResponse::BAD_REQUEST->response([ + 'message' => 'El NIV en el Padrón Estatal no coincide con el registrado en el sistema', + 'placa' => $placa, + 'niv_bd' => $vehicle->niv, + 'niv_padron' => $nivEstatal, + ]); + } + + // Validar también la placa + if (strtoupper($placa) !== strtoupper($placaEstatal)) { + return ApiResponse::BAD_REQUEST->response([ + 'message' => 'La placa retornada por el Padrón Estatal no coincide con la buscada', + 'placa_buscada' => $placa, + 'placa_padron' => $placaEstatal, + ]); + } + + /* $isStolen = $this->checkIfStolen($vehicle->niv, $placa); + + if ($isStolen) { + return ApiResponse::FORBIDDEN->response([ + 'message' => 'El vehículo reporta robo. No se puede continuar con la actualización', + 'placa' => $placa, + 'niv' => $vehicle->niv, + 'stolen' => true, + ]); + } */ + + $vehicleChangedFields = $this->detectVehicleChanges($vehicle, $vehicleDataEstatal); + $ownerChangedFields = $this->detectOwnerChanges($vehicle->owner, $ownerDataEstatal); + + $hasVehicleChanges = !empty($vehicleChangedFields); + $hasOwnerChanges = !empty($ownerChangedFields); + + if (!$hasVehicleChanges && !$hasOwnerChanges) { + return ApiResponse::OK->response([ + 'message' => 'No se detectaron cambios. Los datos ya están actualizados', + 'placa' => $placa, + 'cambios_hechos' => [ + 'vehicle_updated' => false, + 'owner_updated' => false, + 'owner_changed' => false, + ], ]); } DB::beginTransaction(); - $isManualUpdate = $request->has('vehicle') || $request->has('owner'); - $hasVehicleChanges = false; - $hasOwnerChanges = false; - $owner = $vehicle->owner; + $oldOwner = $vehicle->owner; + $ownerChanged = false; - if ($isManualUpdate) { - if ($request->has('vehicle')) { - $vehicleData = $request->input('vehicle', []); + if ($hasVehicleChanges) { + $vehicle->update($vehicleDataEstatal); + } - $allowedVehicleFields = [ - 'placa', - 'marca', - 'linea', - 'sublinea', - 'modelo', - 'color', - 'numero_motor', - 'clase_veh', - 'tipo_servicio', - 'rfv', - 'ofcexpedicion', - 'fechaexpedicion', - 'tipo_veh', - 'numptas', - 'observac', - 'cve_vehi', - 'nrpv', - 'tipo_mov' - ]; + if ($hasOwnerChanges) { + $newRfc = $ownerDataEstatal['rfc']; + $oldRfc = $vehicle->owner->rfc; - $vehicleData = array_filter( - array_intersect_key($vehicleData, array_flip($allowedVehicleFields)), - fn($value) => $value !== null && $value !== '' - ); - - if (!empty($vehicleData)) { - $vehicle->update($vehicleData); - $hasVehicleChanges = true; - } + if (!$newRfc) { + DB::rollBack(); + return ApiResponse::BAD_REQUEST->response([ + 'message' => 'El Padrón Estatal no retornó un RFC válido para el propietario', + 'placa' => $placa, + ]); } - if ($request->has('owner')) { - $ownerInput = $request->input('owner', []); - - $allowedOwnerFields = [ - 'name', - 'paternal', - 'maternal', - 'rfc', - 'curp', - 'address', - 'tipopers', - 'pasaporte', - 'licencia', - 'ent_fed', - 'munic', - 'callep', - 'num_ext', - 'num_int', - 'colonia', - 'cp', - 'telefono' - ]; - - $ownerData = array_filter( - array_intersect_key($ownerInput, array_flip($allowedOwnerFields)), - fn($value) => $value !== null && $value !== '' - ); - - if (!empty($ownerData)) { - // Si se cambió el RFC, buscar/crear otro propietario - if (isset($ownerData['rfc']) && $ownerData['rfc'] !== $owner->rfc) { - $owner = Owner::updateOrCreate( - ['rfc' => $ownerData['rfc']], - $ownerData - ); - $vehicle->update(['owner_id' => $owner->id]); - } else { - // Actualizar propietario existente - $owner->update($ownerData); - } - $hasOwnerChanges = true; - } - } - } else { - - // Intentar obtener datos del caché primero - $vehicleDataEstatal = Cache::get("update_vehicle_{$niv}"); - $ownerDataEstatal = Cache::get("update_owner_{$niv}"); - - // Si no hay - if (!$vehicleDataEstatal || !$ownerDataEstatal) { - $vehicleDataEstatal = $this->getVehicle($niv); - $ownerDataEstatal = $this->getOwner($niv); - } - - // Limpiar caché - Cache::forget("update_vehicle_{$niv}"); - Cache::forget("update_owner_{$niv}"); - - // Detectar si hay cambios - $hasVehicleChanges = $this->detectVehicleChanges($vehicle, $vehicleDataEstatal); - $hasOwnerChanges = $this->detectOwnerChanges($vehicle->owner, $ownerDataEstatal); - - // Actualizar vehículo solo si hay cambios - if ($hasVehicleChanges) { - $vehicle->update($vehicleDataEstatal); - } - - // Actualizar propietario solo si hay cambios - $owner = $vehicle->owner; - if ($hasOwnerChanges) { - $owner = Owner::updateOrCreate( - ['rfc' => $ownerDataEstatal['rfc']], + if ($oldRfc !== $newRfc) { + $newOwner = Owner::updateOrCreate( + ['rfc' => $newRfc], $ownerDataEstatal ); - $vehicle->update(['owner_id' => $owner->id]); + + $vehicle->update(['owner_id' => $newOwner->id]); + $ownerChanged = true; + } else { + $vehicle->owner->update($ownerDataEstatal); } } + VehicleTagLog::create([ + 'vehicle_id' => $vehicle->id, + 'tag_id' => $tag->id, + 'action_type' => 'actualizacion', + 'performed_by' => Auth::id(), + ]); - $uploadedFiles = []; - $replacedFiles = []; - - if ($request->hasFile('files')) { - $files = $request->file('files'); - $nameIds = $request->input('name_id', []); - - if (!empty($nameIds)) { - $validIds = CatalogNameImg::whereIn('id', $nameIds)->pluck('id')->toArray(); - if (count($validIds) !== count($nameIds)) { - DB::rollBack(); - return ApiResponse::BAD_REQUEST->response([ - 'message' => 'Algunos ids del catálogo de nombres no son válidos', - 'provided_id' => $nameIds, - 'valid_id' => $validIds, - ]); - } - } - - foreach ($files as $indx => $file) { - $nameId = $nameIds[$indx] ?? null; - - if ($nameId === null) { - DB::rollBack(); - return ApiResponse::BAD_REQUEST->response([ - 'message' => "Falta el nombre para el archivo, busca en el catálogo de nombres", - ]); - } - - $existingFile = File::where('record_id', $record->id) - ->where('name_id', $nameId) - ->first(); - - if ($existingFile) { - Storage::disk('public')->delete($existingFile->path); - - $replacedFiles[] = [ - 'id' => $existingFile->id, - 'name_id' => $nameId, - 'old_path' => $existingFile->path, - ]; - - $existingFile->delete(); - } - - // Obtener el nombre del catálogo para el nombre del archivo - $catalogName = CatalogNameImg::find($nameId); - $extension = $file->getClientOriginalExtension(); - $fileName = $catalogName->name . '_' . date('dmY_His') . '.' . $extension; - $path = $file->storeAs("records/{$record->folio}", $fileName, 'public'); - $md5 = md5_file($file->getRealPath()); - - $fileRecord = File::create([ - 'name_id' => $nameId, - 'path' => $path, - 'md5' => $md5, - 'record_id' => $record->id, - ]); - - $uploadedFiles[] = [ - 'id' => $fileRecord->id, - 'name' => $catalogName->name, - 'path' => $fileRecord->path, - 'url' => $fileRecord->url, - 'replaced' => $existingFile !== null, - ]; - } - } - - if ($hasVehicleChanges || $hasOwnerChanges || count($uploadedFiles) > 0) { - VehicleTagLog::create([ - 'vehicle_id' => $vehicle->id, - 'tag_id' => $tag->id, - 'action_type' => 'actualizacion', - 'performed_by' => Auth::id() - ]); - } - - // Solo enviar a REPUVE Nacional si hay cambios - if ($hasVehicleChanges || $hasOwnerChanges || count($uploadedFiles) > 0) { - // Preparar datos completos para REPUVE - $datosCompletos = $this->prepararDatosParaInscripcion($niv); - - // Enviar job - ProcessRepuveResponse::dispatch($record->id, $datosCompletos); - } + ProcessRepuveResponse::dispatch($record->id, $datosCompletosRaw); DB::commit(); - $message = 'Vehículo actualizado exitosamente'; - if (!$hasVehicleChanges && !$hasOwnerChanges && empty($uploadedFiles)) { - $message = 'No se detectaron cambios. Los datos ya estaban actualizados.'; - } elseif (($hasVehicleChanges || $hasOwnerChanges) && !empty($uploadedFiles)) { - $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.'; + $vehicle->refresh(); + $vehicle->load(['owner', 'tag.status']); + $record->load(['vehicle.owner', 'vehicle.tag', 'files']); + + $message = ''; + if ($ownerChanged) { + $message = 'Propietario del vehículo actualizado (cambio de dueño detectado)'; + } elseif ($hasVehicleChanges && $hasOwnerChanges) { + $message = 'Datos del vehículo y propietario actualizados exitosamente'; + } elseif ($hasVehicleChanges) { + $message = 'Datos del vehículo actualizados exitosamente'; + } elseif ($hasOwnerChanges) { + $message = 'Datos del propietario actualizados exitosamente'; } return ApiResponse::OK->response([ 'message' => $message, - 'has_error' => false, - 'changes_made' => [ + 'placa' => $placa, + 'cambios_hechos' => [ 'vehicle_updated' => $hasVehicleChanges, 'owner_updated' => $hasOwnerChanges, - 'files_uploaded' => count($uploadedFiles) > 0, + 'owner_changed' => $ownerChanged, ], + 'campos_cambiados' => [ + 'vehicle' => $vehicleChangedFields, + 'owner' => $ownerChangedFields, + ], + 'info_propietario' => $ownerChanged ? [ + 'old_owner' => [ + 'id' => $oldOwner->id, + 'rfc' => $oldOwner->rfc, + 'full_name' => $oldOwner->full_name, + ], + 'nuevo_propietario' => [ + 'id' => $vehicle->owner->id, + 'rfc' => $vehicle->owner->rfc, + 'full_name' => $vehicle->owner->full_name, + ], + ] : null, 'record' => $record, - 'vehicle' => $vehicle, - 'owner' => $owner, - 'files' => $record->files, - 'uploaded_files' => $uploadedFiles, - 'replaced_count' => count($replacedFiles), - 'total_files' => File::where('record_id', $record->id)->count(), ]); } catch (Exception $e) { + DB::rollBack(); + return ApiResponse::INTERNAL_ERROR->response([ 'message' => 'Error al actualizar el vehículo', 'error' => $e->getMessage(), @@ -556,8 +484,10 @@ private function prepararDatosParaInscripcion(string $niv): array ]; } - private function detectVehicleChanges($vehicle, array $vehicleDataEstatal): bool + private function detectVehicleChanges($vehicle, array $vehicleDataEstatal) { + $changedFields = []; + $fieldsToCompare = [ 'placa', 'marca', @@ -583,15 +513,21 @@ private function detectVehicleChanges($vehicle, array $vehicleDataEstatal): bool $estatalValue = $vehicleDataEstatal[$field] ?? null; if (strval($bdValue) !== strval($estatalValue)) { - return true; + $changedFields[] = [ + 'field' => $field, + 'old_value' => $bdValue, + 'new_value' => $estatalValue, + ]; } } - return false; + return $changedFields; } - private function detectOwnerChanges($owner, array $ownerDataEstatal): bool + private function detectOwnerChanges($owner, array $ownerDataEstatal) { + $changedFields = []; + $fieldsToCompare = [ 'name', 'paternal', @@ -616,11 +552,15 @@ private function detectOwnerChanges($owner, array $ownerDataEstatal): bool $estatalValue = $ownerDataEstatal[$field] ?? null; if (strval($bdValue) !== strval($estatalValue)) { - return true; + $changedFields[] = [ + 'field' => $field, + 'old_value' => $bdValue, + 'new_value' => $estatalValue, + ]; } } - return false; + return $changedFields; } private function getVehicle(string $niv): array @@ -887,7 +827,7 @@ public function updateData(VehicleUpdateRequest $request, $id) return ApiResponse::OK->response([ 'message' => $message, 'has_error' => false, - 'changes_made' => [ + 'cambios_hechos' => [ 'vehicle_updated' => $hasVehicleChanges, 'owner_updated' => $hasOwnerChanges, 'files_uploaded' => count($uploadedFiles) > 0, diff --git a/routes/api.php b/routes/api.php index 18891fb..7fc5123 100644 --- a/routes/api.php +++ b/routes/api.php @@ -48,7 +48,7 @@ //Rutas de Actualización Route::post('sustitucion', [UpdateController::class, 'tagSubstitution']); - Route::post('actualizar', [UpdateController::class, 'vehicleUpdate']); + Route::post('actualizar-informacion', [UpdateController::class, 'vehicleUpdate']); Route::post('actualizar-expediente/{id}', [UpdateController::class, 'updateData']); Route::post('/repuve/resend/{id}', [UpdateController::class, 'resendToRepuve']);