input('folio'); // Simular consulta de robo $isStolen = $this->checkIfStolen($folio); // Si está robado, detener el flujo if ($isStolen) { return ApiResponse::FORBIDDEN->response([ 'folio' => $folio, 'stolen' => true, 'message' => 'El vehículo reporta robo. No se puede continuar con la inscripción.', ]); } // Iniciar transacción DB::beginTransaction(); // Obtener datos del vehículo y propietario $vehicleData = $this->getVehicle(); $ownerData = $this->getOwner(); //Crear propietario $owner = Owner::updateOrCreate( ['rfc' => $ownerData['rfc']], [ 'name' => $ownerData['name'], 'paternal' => $ownerData['paternal'], 'maternal' => $ownerData['maternal'], 'curp' => $ownerData['curp'], 'address' => $ownerData['address'], ] ); //Crear o actualizar vehículo $vehicle = Vehicle::updateOrCreate( ['placa' => $vehicleData['PLACA']], [ 'anio_placa' => $vehicleData['ANIO_PLACA'], 'placa' => $vehicleData['PLACA'], 'numero_serie' => $vehicleData['NO_SERIE'], 'rfc' => $vehicleData['RFC'], 'folio' => $vehicleData['FOLIO'], 'vigencia' => $vehicleData['VIGENCIA'], 'fecha_impresion' => $vehicleData['FECHA_IMPRESION'], 'qr_hash' => $vehicleData['QR_HASH'], 'valido' => $vehicleData['VALIDO'], 'foliotemp' => $vehicleData['FOLIOTEMP'], 'nombre' => $vehicleData['NOMBRE'], 'nombre2' => $vehicleData['NOMBRE2'], 'municipio' => $vehicleData['MUNICIPIO'], 'localidad' => $vehicleData['LOCALIDAD'], 'calle' => $vehicleData['CALLE'], 'calle2' => $vehicleData['CALLE2'], 'tipo' => $vehicleData['TIPO'], 'tipo_servicio' => $vehicleData['TIPO_SERVICIO'], 'marca' => $vehicleData['MARCA'], 'linea' => $vehicleData['LINEA'], 'sublinea' => $vehicleData['SUBLINEA'], 'modelo' => $vehicleData['MODELO'], 'numero_motor' => $vehicleData['NUMERO_MOTOR'], 'descripcion_origen' => $vehicleData['DESCRIPCION_ORIGEN'], 'color' => $vehicleData['COLOR'], 'codigo_postal' => $vehicleData['CODIGO_POSTAL'], 'serie_folio' => $vehicleData['SERIE_FOLIO'], 'sfolio' => $vehicleData['SFOLIO'], 'nrpv' => $vehicleData['NUMERO_SERIE'], 'owner_id' => $owner->id, ] ); //Crear registro (expediente) $record = Record::create([ 'folio' => $folio, 'vehicle_id' => $vehicle->id, 'user_id' => auth()->id() ?? null, ]); //Procesar y guardar archivos si existen $uploadedFiles = []; if ($request->hasFile('files')) { $files = $request->file('files'); $fileNames = $request->input('names', []); foreach ($files as $index => $file) { // Generar nombre único $fileName = time() . '_' . $index . '_' . $file->getClientOriginalName(); // Guardar archivos $path = $file->storeAs('records', $fileName, 'public'); // Calcular MD5 $md5 = md5_file($file->getRealPath()); // Crear registro en BD $fileRecord = File::create([ 'name' => $fileNames[$index] ?? "Archivo " . ($index + 1), 'path' => $path, 'md5' => $md5, 'record_id' => $record->id, ]); $uploadedFiles[] = [ 'id' => $fileRecord->id, 'name' => $fileRecord->name, 'path' => $fileRecord->path, 'url' => $fileRecord->url, ]; } } // Confirmar transacción DB::commit(); // Responder con éxito return ApiResponse::OK->response([ 'folio' => $folio, 'stolen' => false, 'message' => 'Vehículo inscrito exitosamente', 'record' => [ 'id' => $record->id, 'folio' => $record->folio, 'vehicle_id' => $vehicle->id, 'user_id' => $record->user_id, 'created_at' => $record->created_at->toDateTimeString(), ], 'vehicle' => [ 'id' => $vehicle->id, 'placa' => $vehicle->placa, 'numero_serie' => $vehicle->numero_serie, 'marca' => $vehicle->marca, 'modelo' => $vehicle->modelo, 'color' => $vehicle->color, ], 'owner' => [ 'id' => $owner->id, 'full_name' => $owner->full_name, 'rfc' => $owner->rfc, ], 'files' => $uploadedFiles, 'total_files' => count($uploadedFiles), ]); } catch (\Exception $e) { // Revertir transacción en caso de error DB::rollBack(); // Log del error Log::error('Error en inscripcionVehiculo: ' . $e->getMessage(), [ 'folio' => $folio ?? null, 'trace' => $e->getTraceAsString() ]); return ApiResponse::BAD_REQUEST->response([ 'message' => 'Error al procesar la inscripción del vehículo', 'error' => $e->getMessage(), ]); } } private function checkIfStolen(string $folio): bool { // Aquí api servicio de REPUVE // simulamos con random return (bool) rand(0, 1); } public function consultaExpediente(Request $request) { $request->validate([ 'folio' => 'required|string', ]); $folio = $request->input('folio'); // Cargar record con todas sus relaciones $record = Record::where('folio', $folio) ->with(['vehicle.owner', 'files', 'user']) ->first(); if (!$record) { return ApiResponse::NOT_FOUND->response([ 'message' => 'No se encontró ningún expediente con el folio proporcionado.' ]); } return ApiResponse::OK->response([ 'record' => [ 'id' => $record->id, 'folio' => $record->folio, 'vehicle' => $record->vehicle, 'owner' => $record->vehicle->owner, 'files' => $record->files, 'user' => $record->user, 'created_at' => $record->created_at->toDateTimeString(), ] ]); } private function getVehicle(): array { return [ "ANIO_PLACA" => "2020", "PLACA" => "WNU700B", "NO_SERIE" => "LSGHD52H0ND032457", "RFC" => "GME111116GJA", "FOLIO" => "3962243", "VIGENCIA" => "2025", "FECHA_IMPRESION" => "10-01-2025", "QR_HASH" => "Vu5TF4kYsbbltzjDdGQyenKfZoIk2wro34a5Gkh9JVh0CFxfPlrd92YEWK21JF.nLjQNyzKmqRvWYuPiS.kU7A--", "VALIDO" => true, "FOLIOTEMP" => false, "NOMBRE" => "GOLSYSTEMS DE MEXICO S DE RL DE CV", "NOMBRE2" => "GOLS*MS DXICOE RL*CV", "MUNICIPIO" => "CENTRO", "LOCALIDAD" => "VILLAHERMOSA", "CALLE" => "C BUGAMBILIAS 118 ", "CALLE2" => "C BU*ILIA*18 ", "TIPO" => "SEDAN", "TIPO_SERVICIO" => "PARTICULAR", "MARCA" => "CHEVROLET G.M.C.", "LINEA" => "AVEO", "SUBLINEA" => "PAQ. \"A\" LS", "MODELO" => 2022, "NUMERO_SERIE" => "LSGHD52H0ND032457", "NUMERO_MOTOR" => "H. EN WUHANLL,SGM", "DESCRIPCION_ORIGEN" => "IMPORTADO", "COLOR" => "BLANCO", "CODIGO_POSTAL" => "86179", "SERIE_FOLIO" => "D3962243", "SFOLIO" => "3962243" ]; } private function getOwner(): array { return [ 'name' => 'Nicolas', 'paternal' => 'Hernandez', 'maternal' => 'Castillo', 'rfc' => 'HECN660509HTCRSC01', 'curp' => 'HECN660509HTCRSC01', 'address' => 'Fracc Pomoca, Calle Armadillo MZ9 LT28', ]; } }