250 lines
7.9 KiB
PHP
250 lines
7.9 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Vehicle;
|
|
use App\Models\Detection;
|
|
use Illuminate\Support\Facades\Redis;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class VehicleService
|
|
{
|
|
public function __construct(
|
|
private ConsultaEstatalService $consultaEstatal,
|
|
private ReporteRoboService $reporteRobo,
|
|
private ConsultaRepuveConstancia $consultaRepuveCons
|
|
) {}
|
|
|
|
public function procesarDeteccion(string $epc, ?int $arcoId = null): array
|
|
{
|
|
$key = "vehiculo:robado:{$epc}";
|
|
|
|
// Verificar si está en Redis
|
|
$enRedis = Redis::get($key);
|
|
|
|
if ($enRedis) {
|
|
// Ya está marcado como robado, verificar si sigue así
|
|
$resultado = $this->verificarVehiculoRobado($epc, $arcoId, json_decode($enRedis, true));
|
|
$this->registrarDeteccion($epc, $resultado);
|
|
return $resultado;
|
|
}
|
|
|
|
// No está en Redis, consultar servicios
|
|
$resultado = $this->consultarNuevoVehiculo($epc, $arcoId);
|
|
$this->registrarDeteccion($epc, $resultado);
|
|
return $resultado;
|
|
}
|
|
|
|
private function consultarNuevoVehiculo(string $epc, ?int $arcoId): array
|
|
{
|
|
// Consultar padrón estatal
|
|
$datosEstatal = $this->consultaEstatal->consultarPorEpc($epc);
|
|
|
|
if (!$datosEstatal || !$datosEstatal['vin']) {
|
|
return [
|
|
'success' => false,
|
|
'message' => 'No se encontró información del vehículo'
|
|
];
|
|
}
|
|
|
|
// Consultar REPUVE
|
|
$reporteRobo = $this->reporteRobo->consultarPorVin(
|
|
$datosEstatal['vin'],
|
|
$datosEstatal['placa']
|
|
);
|
|
|
|
if ($reporteRobo['tiene_reporte']) {
|
|
// Está robado → Guardar en Redis
|
|
$this->guardarEnRedis($epc, $datosEstatal, $reporteRobo['datos']);
|
|
|
|
Log::warning('¡VEHÍCULO ROBADO DETECTADO!', [
|
|
'epc' => $epc,
|
|
'vin' => $datosEstatal['vin'],
|
|
'placa' => $datosEstatal['placa']
|
|
]);
|
|
|
|
return [
|
|
'success' => true,
|
|
'tiene_reporte_robo' => true,
|
|
'estado' => 'ROBADO',
|
|
'accion' => 'GUARDADO_EN_REDIS',
|
|
'vehiculo' => array_merge($datosEstatal, $reporteRobo['datos'])
|
|
];
|
|
}
|
|
|
|
// No está robado, no hacer nada
|
|
return [
|
|
'success' => true,
|
|
'tiene_reporte_robo' => false,
|
|
'estado' => 'LIBRE',
|
|
'vehiculo' => $datosEstatal
|
|
];
|
|
}
|
|
|
|
private function verificarVehiculoRobado(string $epc, ?int $arcoId, array $datosRedis): array
|
|
{
|
|
// Consultar REPUVE para verificar estado actual
|
|
$reporteRobo = $this->reporteRobo->consultarPorVin(
|
|
$datosRedis['vin'],
|
|
$datosRedis['placa']
|
|
);
|
|
|
|
if (!$reporteRobo['tiene_reporte']) {
|
|
// No tiene reporte robo
|
|
$this->registrarRecuperacion($epc, $arcoId, $datosRedis);
|
|
|
|
Log::info('¡VEHÍCULO RECUPERADO!', [
|
|
'epc' => $epc,
|
|
'vin' => $datosRedis['vin'],
|
|
'placa' => $datosRedis['placa']
|
|
]);
|
|
|
|
return [
|
|
'success' => true,
|
|
'tiene_reporte_robo' => false,
|
|
'estado' => 'RECUPERADO',
|
|
'accion' => 'GUARDADO_EN_MYSQL_Y_ELIMINADO_DE_REDIS',
|
|
'vehiculo' => $datosRedis
|
|
];
|
|
}
|
|
|
|
// Sigue robado → Actualizar contador en Redis
|
|
$this->actualizarDeteccionRedis($epc, $datosRedis);
|
|
|
|
Log::warning('Vehículo robado detectado nuevamente', [
|
|
'epc' => $epc,
|
|
'detecciones' => $datosRedis['detecciones'] + 1
|
|
]);
|
|
|
|
return [
|
|
'success' => true,
|
|
'tiene_reporte_robo' => true,
|
|
'estado' => 'ROBADO',
|
|
'accion' => 'ACTUALIZADO_EN_REDIS',
|
|
'vehiculo' => $datosRedis
|
|
];
|
|
}
|
|
|
|
private function guardarEnRedis(string $epc, array $datosEstatal, array $datosRobo)
|
|
{
|
|
$key = "vehiculo:robado:{$epc}";
|
|
|
|
$datos = [
|
|
'epc' => $epc,
|
|
'vin' => $datosEstatal['vin'],
|
|
'placa' => $datosEstatal['placa'],
|
|
'fecha_robo' => $datosRobo['fecha_robo'] ?? null,
|
|
'autoridad' => $datosRobo['autoridad'] ?? null,
|
|
'acta' => $datosRobo['acta'] ?? null,
|
|
'denunciante' => $datosRobo['denunciante'] ?? null,
|
|
'fecha_acta' => $datosRobo['fecha_acta'] ?? null,
|
|
'primera_deteccion' => now()->toIso8601String(),
|
|
'ultima_deteccion' => now()->toIso8601String(),
|
|
'detecciones' => 1
|
|
];
|
|
|
|
Redis::set($key, json_encode($datos));
|
|
}
|
|
|
|
private function actualizarDeteccionRedis(string $epc, array $datosActuales)
|
|
{
|
|
$key = "vehiculo:robado:{$epc}";
|
|
|
|
$datosActuales['ultima_deteccion'] = now()->toIso8601String();
|
|
$datosActuales['detecciones'] = ($datosActuales['detecciones'] ?? 0) + 1;
|
|
|
|
Redis::set($key, json_encode($datosActuales));
|
|
}
|
|
|
|
private function registrarRecuperacion(string $epc, ?int $arcoId, array $datosRedis)
|
|
{
|
|
// Guardar en MySQL
|
|
Vehicle::create([
|
|
'epc' => $epc,
|
|
'vin' => $datosRedis['vin'],
|
|
'placa' => $datosRedis['placa'],
|
|
'fecha_robo' => $datosRedis['fecha_robo'],
|
|
'autoridad_robo' => $datosRedis['autoridad'],
|
|
'acta_robo' => $datosRedis['acta'],
|
|
'denunciante' => $datosRedis['denunciante'],
|
|
'fecha_recuperacion' => now(),
|
|
'fecha_acta' => $datosRedis['fecha_acta'] ?? null,
|
|
'datos_robo_original' => $datosRedis
|
|
]);
|
|
|
|
// Eliminar de Redis
|
|
Redis::del("vehiculo:robado:{$epc}");
|
|
}
|
|
|
|
public function listarVehiculosRobados(): array
|
|
{
|
|
$keys = Redis::keys('vehiculo:robado:*');
|
|
$vehiculos = [];
|
|
|
|
foreach ($keys as $key) {
|
|
$datos = Redis::get($key);
|
|
if ($datos) {
|
|
$vehiculos[] = json_decode($datos, true);
|
|
}
|
|
}
|
|
|
|
return $vehiculos;
|
|
}
|
|
|
|
private function registrarDeteccion(string $epc, array $resultado)
|
|
{
|
|
if (!$resultado['success'] || !isset($resultado['vehiculo'])) {
|
|
return;
|
|
}
|
|
|
|
$vehiculo = $resultado['vehiculo'];
|
|
|
|
Detection::create([
|
|
'epc' => $epc,
|
|
'vin' => $vehiculo['vin'] ?? null,
|
|
'placa' => $vehiculo['placa'] ?? null,
|
|
'marca' => $vehiculo['marca'] ?? null,
|
|
'modelo' => $vehiculo['modelo'] ?? null,
|
|
'color' => $vehiculo['color'] ?? null,
|
|
'fecha_deteccion' => now()
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Consultar vehículo por tag_id
|
|
*/
|
|
public function consultarVehiculoPorTag(?string $epc = null, ?string $tagId = null)
|
|
{
|
|
try {
|
|
// Validar que se proporcionó tag_id
|
|
if (empty($tagId)) {
|
|
Log::warning('VehicleService: No se proporcionó tag_id');
|
|
return null;
|
|
}
|
|
$vehiculoExterno = $this->consultaRepuveCons->consultarVehiculoPorTag($tagId);
|
|
|
|
if ($vehiculoExterno) {
|
|
Log::info('VehicleService: Vehículo encontrado', [
|
|
'tag_id' => $vehiculoExterno['tag_id'] ?? null,
|
|
'tag_number' => $vehiculoExterno['tag_number'] ?? null,
|
|
'vin' => $vehiculoExterno['vin'] ?? null
|
|
]);
|
|
} else {
|
|
Log::info('VehicleService: Vehículo no encontrado', [
|
|
'tag_id' => $tagId
|
|
]);
|
|
}
|
|
|
|
return $vehiculoExterno;
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('VehicleService: Error en consulta', [
|
|
'tag_id' => $tagId,
|
|
'error' => $e->getMessage(),
|
|
'trace' => $e->getTraceAsString()
|
|
]);
|
|
return null;
|
|
}
|
|
}
|
|
}
|