repuve-backend-v1/app/Services/PadronEstatalService.php

238 lines
8.5 KiB
PHP

<?php
namespace App\Services;
use App\Exceptions\PadronEstatalException;
use Illuminate\Support\Facades\Log;
class PadronEstatalService
{
private string $soapUrl;
public function __construct()
{
$this->soapUrl = config('services.padron_estatal.url');
}
public function getVehiculoByNiv(string $niv): array
{
return $this->consultarPadron('niv', $niv);
}
public function getVehiculoByPlaca(string $placa): array
{
return $this->consultarPadron('placa', $placa);
}
public function getVehiculoByFolio(string $folio): array
{
return $this->consultarPadron('folio', $folio);
}
/**
* Consulta el padrón vehicular estatal
*/
private function consultarPadron(string $tipo, string $valor): array
{
$logger = Log::channel('padron_estatal');
// Construir el Data en formato JSON
$data = json_encode([
'tipo' => $tipo,
'valor' => $valor
]);
// Construir el cuerpo SOAP
$soapBody = <<<XML
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://mx/tgc/ConsultaPadronVehicular.wsdl">
<soapenv:Header/>
<soapenv:Body>
<wsdl:getVehiculosRepuve>
<Data>{$data}</Data>
</wsdl:getVehiculosRepuve>
</soapenv:Body>
</soapenv:Envelope>
XML;
$logger->info('Consulta al padrón estatal', [
'url' => $this->soapUrl,
'tipo' => $tipo,
'valor' => $valor,
]);
$logger->debug('SOAP request body', ['body' => $soapBody]);
// Configurar cURL
$ch = curl_init($this->soapUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $soapBody);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: text/xml; charset=utf-8',
'SOAPAction: ""',
'Content-Length: ' . strlen($soapBody)
]);
try {
// Ejecutar la petición
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlInfo = curl_getinfo($ch);
$error = curl_error($ch);
$logger->debug('Respuesta cURL', [
'http_code' => $httpCode,
'total_time' => $curlInfo['total_time'] ?? null,
'connect_time' => $curlInfo['connect_time'] ?? null,
'namelookup_time' => $curlInfo['namelookup_time'] ?? null,
'curl_error' => $error ?: null,
]);
if ($error) {
$logger->error('Error cURL al consultar padrón estatal', ['error' => $error]);
throw new PadronEstatalException("Error en la petición al padrón estatal: {$error}");
}
if ($httpCode !== 200) {
$logger->error('HTTP error al consultar padrón estatal', [
'http_code' => $httpCode,
'response' => $response,
]);
throw new PadronEstatalException("Error HTTP {$httpCode} al consultar padrón estatal");
}
$logger->debug('SOAP response body', ['body' => $response]);
// Parsear la respuesta
return $this->parsearRespuesta($response);
} finally {
unset($ch);
}
}
/**
* Parsea la respuesta del padrón estatal
*/
private function parsearRespuesta(string $soapResponse): array
{
$logger = Log::channel('padron_estatal');
// Extraer el contenido del tag
preg_match('/<result>(.*?)<\/result>/s', $soapResponse, $matches);
if (!isset($matches[1])) {
$logger->error('No se encontró tag <result> en la respuesta SOAP', ['response' => $soapResponse]);
throw new PadronEstatalException("No se pudo extraer el resultado del padrón estatal");
}
$jsonContent = trim($matches[1]);
// Decodificar el JSON
$result = json_decode($jsonContent, true);
if (json_last_error() !== JSON_ERROR_NONE) {
$logger->error('Error al decodificar JSON del padrón estatal', [
'json_error' => json_last_error_msg(),
'content' => $jsonContent,
]);
throw new PadronEstatalException("Error al decodificar JSON del padrón estatal: " . json_last_error_msg());
}
// La respuesta es un array con un objeto que tiene error y datos
if (!isset($result[0])) {
$logger->error('Formato de respuesta inesperado (sin índice 0)', ['result' => $result]);
throw new PadronEstatalException("Formato de respuesta inesperado del padrón estatal");
}
$data = $result[0];
// Verificar si hay error
if ($data['error'] !== 0) {
$logger->warning('El padrón estatal devolvió un código de error', [
'error_code' => $data['error'],
'data' => $data,
]);
throw new PadronEstatalException("Error en consulta al padrón estatal: código {$data['error']}");
}
// Verificar si hay datos
if (!isset($data['datos'][0])) {
$logger->warning('El padrón estatal no devolvió datos del vehículo', ['data' => $data]);
throw new PadronEstatalException("No se encontraron datos del vehículo en el padrón estatal");
}
$logger->info('Consulta al padrón estatal exitosa');
return $data['datos'][0];
}
/**
* Extrae los datos del vehículo del resultado
*/
public function extraerDatosVehiculo(array $datos): array
{
$fechaexpedicion = $datos['fechaexp'] ?? null;
return [
'placa' => $datos['placa'] ?? null,
'niv' => $datos['niv'] ?? null,
'marca' => $datos['marca'] ?? null,
'linea' => $datos['submarca'] ?? null,
'sublinea' => $datos['version'] ?? null,
'modelo' => $datos['modelo'] ?? null,
'color' => $datos['color'] ?? null,
'numero_motor' => $datos['motor'] ?? null,
'clase_veh' => $datos['clase_veh'] ?? null,
'tipo_servicio' => $datos['tipo_uso'] ?? null,
'rfv' => $datos['rfv'] ?? null,
'ofcexpedicion' => $datos['ofcexp'] ?? null,
'fechaexpedicion' => $fechaexpedicion,
'tipo_veh' => $datos['tipo_veh'] ?? null,
'numptas' => $datos['numptas'] ?? null,
'observac' => $datos['observac'] ?? null,
'cve_vehi' => $datos['cve_vehi'] ?? null,
'nrpv' => $datos['nrpv'] ?? null,
'tipo_mov' => $datos['tipo_mov'] ?? null,
];
}
/**
* Extrae los datos del propietario del resultado
*/
public function extraerDatosPropietario(array $datos): array
{
// Construir dirección completa
$addressParts = array_filter([
$datos['callep'] ?? null,
isset($datos['num_ext']) && $datos['num_ext'] ? "Num {$datos['num_ext']}" : null,
isset($datos['num_int']) && $datos['num_int'] ? "Int {$datos['num_int']}" : null,
$datos['colonia'] ?? null,
isset($datos['cp']) && $datos['cp'] ? "CP {$datos['cp']}" : null,
isset($datos['munic']) && $datos['munic'] ? "Mun {$datos['munic']}" : null,
isset($datos['ent_fed']) && $datos['ent_fed'] ? "Edo {$datos['ent_fed']}" : null,
]);
$address = implode(', ', $addressParts);
return [
'name' => $datos['nombre'] ?? null,
'paternal' => $datos['ap_paterno'] ?? null,
'maternal' => $datos['ap_materno'] ?? null,
'rfc' => $datos['rfc'] ?? null,
'curp' => $datos['curp'] ?? null,
'address' => $address,
'tipopers' => $datos['tipopers'] ?? null,
'pasaporte' => $datos['pasaporte'] ?? null,
'licencia' => $datos['licencia'] ?? null,
'ent_fed' => $datos['ent_fed'] ?? null,
'munic' => $datos['munic'] ?? null,
'callep' => $datos['callep'] ?? null,
'num_ext' => $datos['num_ext'] ?? null,
'num_int' => $datos['num_int'] ?? null,
'colonia' => $datos['colonia'] ?? null,
'cp' => $datos['cp'] ?? null,
];
}
}