baseUrl = config('services.vehiculos_externos.base_url'); $this->loginEndpoint = config('services.vehiculos_externos.login_endpoint'); $this->vehiculosEndpoint = config('services.vehiculos_externos.vehiculos_endpoint'); $this->email = config('services.vehiculos_externos.email'); $this->password = config('services.vehiculos_externos.password'); $this->tokenTtl = config('services.vehiculos_externos.token_ttl', 3600); } /** * Consultar vehículo por tag_number, placa o VIN * */ public function consultarVehiculoPorTag(?string $criterio = null) { try { // Validar que se proporcionó algún criterio de búsqueda if (empty($criterio)) { Log::warning('ConsultaRepuveConstancia: No se proporcionó criterio de búsqueda'); return null; } // Obtener token de autenticación $token = $this->obtenerToken(); if (!$token) { Log::error('ConsultaRepuveConstancia: No se pudo obtener token de autenticación'); return null; } $url = $this->baseUrl . $this->vehiculosEndpoint; Log::info('ConsultaRepuveConstancia: Consultando', [ 'url' => $url, 'criterio' => $criterio ]); $headers = [ 'Authorization' => 'Bearer ' . $token, 'Accept' => 'application/json', ]; // Intentar buscar por tag_number primero $response = Http::withHeaders($headers)->timeout(30)->get($url, [ 'tag_number' => $criterio ]); if ($response->successful()) { $data = $response->json(); if ( isset($data['status']) && $data['status'] === 'success' && isset($data['data']['records']['data']) && !empty($data['data']['records']['data']) ) { $vehiculoEncontrado = $data['data']['records']['data'][0]; return $this->transformarDatosVehiculo($vehiculoEncontrado); } } // Intentar búsqueda por placa SOLO si el anterior NO encontró nada $response = Http::withHeaders($headers)->timeout(30)->get($url, [ 'placa' => $criterio ]); if ($response->successful()) { $data = $response->json(); if ( isset($data['status']) && $data['status'] === 'success' && isset($data['data']['records']['data']) && !empty($data['data']['records']['data']) ) { $vehiculoEncontrado = $data['data']['records']['data'][0]; return $this->transformarDatosVehiculo($vehiculoEncontrado); } } // Intentar búsqueda por VIN SOLO si los anteriores NO encontraron nada $response = Http::withHeaders($headers)->timeout(30)->get($url, [ 'vin' => $criterio ]); if (!$response->successful()) { Log::error('ConsultaRepuveConstancia: Error en petición HTTP', [ 'status' => $response->status(), 'body' => $response->body() ]); return null; } $data = $response->json(); // Validar estructura de respuesta y que haya datos if ( !isset($data['status']) || $data['status'] !== 'success' || !isset($data['data']['records']['data']) || empty($data['data']['records']['data']) ) { Log::info('ConsultaRepuveConstancia: Vehículo no encontrado en ningún criterio', [ 'criterio' => $criterio ]); return null; } $vehiculoEncontrado = $data['data']['records']['data'][0]; return $this->transformarDatosVehiculo($vehiculoEncontrado); } catch (Exception $e) { Log::error('ConsultaRepuveConstancia: Error al consultar vehículo', [ 'criterio' => $criterio, 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); return null; } } /** * Obtener token JWT */ private function obtenerToken() { $cacheKey = 'vehiculos_externos_jwt_token'; // Intentar obtener token de caché $token = Cache::get($cacheKey); if ($token) { return $token; } // Si no está en caché, autenticar try { $url = $this->baseUrl . $this->loginEndpoint; Log::info('ConsultaRepuveConstancia: Autenticando', [ 'url' => $url, 'email' => $this->email ]); $response = Http::timeout(30)->post($url, [ 'email' => $this->email, 'password' => $this->password, ]); if (!$response->successful()) { Log::error('ConsultaRepuveConstancia: Error al autenticar', [ 'status' => $response->status(), 'body' => $response->body() ]); return null; } $data = $response->json(); // Validar estructura de respuesta if (!isset($data['status']) || $data['status'] !== 'success' || !isset($data['data']['token'])) { Log::error('ConsultaRepuveConstancia: Respuesta de login inválida', [ 'response' => $data ]); return null; } $token = $data['data']['token']; // Guardar en caché (hora por defecto) Cache::put($cacheKey, $token, $this->tokenTtl); Log::info('ConsultaRepuveConstancia: Token obtenido y guardado en caché'); return $token; } catch (Exception $e) { Log::error('ConsultaRepuveConstancia: Excepción al obtener token', [ 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); return null; } } /** * Transformar datos del vehículo al formato esperado */ private function transformarDatosVehiculo(array $record) { $vehiculo = $record['vehicle']; $tag = $vehiculo['tag'] ?? []; $owner = $vehiculo['owner'] ?? []; return [ 'tag_number' => $tag['tag_number'] ?? null, 'folio_tag' => $tag['folio'] ?? null, 'vin' => $vehiculo['niv'] ?? null, 'placa' => $vehiculo['placa'] ?? null, 'marca' => $vehiculo['marca'] ?? null, 'modelo' => $vehiculo['modelo'] ?? null, 'linea' => $vehiculo['linea'] ?? null, 'sublinea' => $vehiculo['sublinea'] ?? null, 'color' => $vehiculo['color'] ?? null, 'numero_motor' => $vehiculo['numero_motor'] ?? null, 'clase_veh' => $vehiculo['clase_veh'] ?? null, 'tipo_servicio' => $vehiculo['tipo_servicio'] ?? null, 'rfv' => $vehiculo['rfv'] ?? null, 'nrpv' => $vehiculo['nrpv'] ?? null, 'reporte_robo' => $vehiculo['reporte_robo'] ?? false, 'propietario' => [ 'id' => $owner['id'] ?? null, 'nombre_completo' => $owner['full_name'] ?? null, 'rfc' => $owner['rfc'] ?? null, 'curp' => $owner['curp'] ?? null, 'telefono' => $owner['telefono'] ?? null, 'direccion' => $owner['address'] ?? null, ], 'tag_status' => $tag['status']['name'] ?? null, ]; } /** * Limpiar token de caché (útil para forzar re-autenticación) */ public function limpiarToken() { Cache::forget('vehiculos_externos_jwt_token'); Log::info('ConsultaRepuveConstancia: Token eliminado de caché'); } }