ADD: Implementar reporte de robo en vehículos y actualizar lógica de consulta

This commit is contained in:
Juan Felipe Zapata Moreno 2025-12-06 11:51:34 -06:00
parent 118f5ef868
commit 74dedc32df
4 changed files with 219 additions and 2 deletions

View File

@ -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([

View File

@ -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()

View File

@ -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 = <<<XML
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://consultaRpv.org/wsdl">
<soapenv:Header/>
<soapenv:Body>
<wsdl:doConsRPV>
<arg0>{$this->username}</arg0>
<arg1>{$this->password}</arg1>
<arg2>{$arg2}</arg2>
</wsdl:doConsRPV>
</soapenv:Body>
</soapenv:Envelope>
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,
];
}
}
}

View File

@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('vehicle', function (Blueprint $table) {
$table->boolean('reporte_robo')->default(false)->after('placa');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('vehicle', function (Blueprint $table) {
$table->dropColumn('reporte_robo');
});
}
};