arcos-backend/app/Services/VehicleService.php

188 lines
5.8 KiB
PHP

<?php
namespace App\Services;
use App\Models\Vehicle;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Log;
class VehicleService
{
public function __construct(
private ConsultaEstatalService $consultaEstatal,
private ReporteRoboService $reporteRobo
) {}
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í
return $this->verificarVehiculoRobado($epc, $arcoId, json_decode($enRedis, true));
}
// No está en Redis, consultar servicios
return $this->consultarNuevoVehiculo($epc, $arcoId);
}
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): void
{
$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): void
{
$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): void
{
// 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;
}
}