diff --git a/app/Http/Controllers/Repuve/InscriptionController.php b/app/Http/Controllers/Repuve/InscriptionController.php index c529ae3..c1a62d5 100644 --- a/app/Http/Controllers/Repuve/InscriptionController.php +++ b/app/Http/Controllers/Repuve/InscriptionController.php @@ -463,6 +463,22 @@ public function stolen(Request $request) $resultado = $this->repuveService->verificarRobo($vin, $placa); $isStolen = $resultado['is_robado'] ?? false; + $vehicle = Vehicle::where(function ($query) use ($vin, $placa) { + if ($vin) { + $query->orWhere('niv', $vin); + } + if ($placa) { + $query->orWhere('placa', $placa); + } + })->first(); + + $actualizar = false; + if ($vehicle) { + $vehicle->reporte_robo = $isStolen; + $vehicle->save(); + $actualizar = true; + } + return ApiResponse::OK->response([ 'vin' => $vin ?: null, 'placa' => $placa ?: null, @@ -472,7 +488,9 @@ public function stolen(Request $request) ? 'El vehículo tiene reporte de robo en REPUVE.' : 'El vehículo no tiene reporte de robo.', 'fecha' => now()->toDateTimeString(), - 'detalle_repuve' => $resultado, + 'detalle_robo' => $resultado, + 'existe_registro_BD' => $vehicle ? true : false, + 'actualizado_reporte_robo' => $actualizar, ]); } catch (\Exception $e) { return ApiResponse::INTERNAL_ERROR->response([ diff --git a/app/Models/Vehicle.php b/app/Models/Vehicle.php index 80d38e4..e526c9f 100644 --- a/app/Models/Vehicle.php +++ b/app/Models/Vehicle.php @@ -32,10 +32,12 @@ class Vehicle extends Model 'nrpv', 'tipo_mov', 'owner_id', + 'reporte_robo', ]; protected $casts = [ 'fechaexpedicion' => 'date', + 'reporte_robo' => 'boolean', ]; public function owner() diff --git a/app/Services/RepuveService.php b/app/Services/RepuveService.php index ff46358..44fcb86 100644 --- a/app/Services/RepuveService.php +++ b/app/Services/RepuveService.php @@ -242,7 +242,6 @@ public function verificarRobo(?string $niv = null, ?string $placa = null): array // Retornar el array completo con toda la información return $resultado; - } catch (Exception $e) { logger()->error('REPUVE verificarRobo: Excepción capturada', [ 'niv' => $niv, @@ -257,6 +256,94 @@ public function verificarRobo(?string $niv = null, ?string $placa = null): array } } + public function consultarVehiculo(?string $niv = null, ?string $placa = null) + { + try { + $url = $this->baseUrl . '/jaxws-consultarpv/ConsultaRpv'; + + // Construir arg2: NIV|PLACA||||||| + $arg2 = ($niv ?? '') . '|' . ($placa ?? '') . str_repeat('|', 7); + + $soapBody = << + + + + {$this->username} + {$this->password} + {$arg2} + + + + XML; + + $ch = curl_init($url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $soapBody); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Content-Type: text/xml; charset=utf-8', + 'SOAPAction: "doConsRPV"', + 'Content-Length: ' . strlen($soapBody), + ]); + + $response = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $error = curl_error($ch); + curl_close($ch); + + if ($error) { + logger()->error('REPUVE consultarVehiculo: Error de conexión', [ + 'error' => $error, + 'niv' => $niv, + 'placa' => $placa, + ]); + return [ + 'success' => false, + 'has_error' => true, + 'error_message' => 'Error de conexión con el servicio REPUVE', + ]; + } + + if ($httpCode !== 200) { + logger()->error('REPUVE consultarVehiculo: HTTP error', [ + 'http_code' => $httpCode, + 'niv' => $niv, + 'placa' => $placa, + ]); + return [ + 'success' => false, + 'has_error' => true, + 'error_message' => "Error HTTP {$httpCode} del servicio REPUVE", + ]; + } + + // Parsear respuesta + $resultado = $this->parseConsultarVehiculoResponse($response); + + if ($resultado['has_error'] ?? false) { + logger()->warning('REPUVE consultarVehiculo: Error al parsear', [ + 'niv' => $niv, + 'placa' => $placa, + 'error' => $resultado['error_message'] ?? 'Desconocido', + ]); + } + + return $resultado; + } catch (Exception $e) { + logger()->error('REPUVE consultarVehiculo: Excepción', [ + 'niv' => $niv, + 'placa' => $placa, + 'exception' => $e->getMessage(), + ]); + return [ + 'success' => false, + 'has_error' => true, + 'error_message' => 'Excepción: ' . $e->getMessage(), + ]; + } + } + public function inscribirVehiculo(array $datos) { $url = $this->baseUrl . $this->inscripcionEndpoint; @@ -555,4 +642,86 @@ private function parseRoboResponse(string $soapResponse, string $valor): array 'raw_response' => $contenido, ]; } + + public function parseConsultarVehiculoResponse(string $xmlResponse): array + { + try { + $xml = simplexml_load_string($xmlResponse); + + if ($xml === false) { + return [ + 'success' => false, + 'has_error' => true, + 'error_message' => 'Error al parsear XML', + 'raw_response' => $xmlResponse, + ]; + } + + $xml->registerXPathNamespace('ns2', 'http://consultaRpv.org/wsdl'); + $return = $xml->xpath('//ns2:doConsRPVResponse/return'); + + if (empty($return)) { + return [ + 'success' => false, + 'has_error' => true, + 'error_message' => 'No se encontró elemento return en la respuesta', + 'raw_response' => $xmlResponse, + ]; + } + $contenido = trim((string)$return[0]); + + // Verificar si la respuesta es OK + if (!str_starts_with($contenido, 'OK:')) { + return [ + 'success' => false, + 'has_error' => true, + 'error_message' => $contenido, + 'raw_response' => $xmlResponse, + ]; + } + + // Remover "OK:" del inicio + $data = substr($contenido, 3); + + // Separar por | + $campos = explode('|', $data); + + return [ + 'success' => true, + 'has_error' => false, + 'entidad_federativa' => $campos[0] ?? null, + 'oficina' => $campos[1] ?? null, + 'folio_tarjeta' => $campos[2] ?? null, + 'niv' => $campos[3] ?? null, + 'fecha_expedicion' => $campos[4] ?? null, + 'hora_expedicion' => $campos[5] ?? null, + 'procedencia' => $campos[6] ?? null, + 'origen' => $campos[7] ?? null, + 'clave_vehicular' => $campos[8] ?? null, + 'fecha_emplacado' => $campos[9] ?? null, + 'municipio' => $campos[10] ?? null, + 'serie' => $campos[11] ?? null, + 'placa' => $campos[12] ?? null, + 'tipo_vehiculo' => $campos[13] ?? null, + 'modelo' => $campos[14] ?? null, + 'color' => $campos[15] ?? null, + 'version' => $campos[16] ?? null, + 'entidad_placas' => $campos[17] ?? null, + 'marca' => $campos[18] ?? null, + 'linea' => $campos[19] ?? null, + 'uso' => $campos[20] ?? null, + 'clase' => $campos[21] ?? null, + 'estatus' => $campos[22] ?? null, + 'observaciones' => $campos[23] ?? null, + 'raw_response' => $contenido, + ]; + } catch (Exception $e) { + return [ + 'success' => false, + 'has_error' => true, + 'error_message' => 'Excepción al parsear: ' . $e->getMessage(), + 'raw_response' => $xmlResponse, + ]; + } + } } diff --git a/database/migrations/2025_12_06_112122_add_reporte_robo_to_vehicle.php b/database/migrations/2025_12_06_112122_add_reporte_robo_to_vehicle.php new file mode 100644 index 0000000..3471fa2 --- /dev/null +++ b/database/migrations/2025_12_06_112122_add_reporte_robo_to_vehicle.php @@ -0,0 +1,28 @@ +boolean('reporte_robo')->default(false)->after('placa'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('vehicle', function (Blueprint $table) { + $table->dropColumn('reporte_robo'); + }); + } +};