309 lines
11 KiB
PHP
309 lines
11 KiB
PHP
<?php namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Vehicle;
|
|
use App\Services\VehicleService;
|
|
use App\Services\ConsultaEstatalService;
|
|
use App\Services\ReporteRoboService;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Redis;
|
|
use Illuminate\Support\Facades\Validator;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class VehicleController extends Controller
|
|
{
|
|
public function __construct(
|
|
private VehicleService $vehicleService,
|
|
private ConsultaEstatalService $consultaEstatal,
|
|
private ReporteRoboService $reporteRobo
|
|
) {}
|
|
|
|
/**
|
|
* Consultar y registrar vehículo por PLACA o VIN
|
|
*/
|
|
public function consultarVehiculo(Request $request): JsonResponse
|
|
{
|
|
$validator = Validator::make($request->all(), [
|
|
'placa' => 'required_without:vin|string|nullable',
|
|
'vin' => 'required_without:placa|string|nullable',
|
|
], [
|
|
'placa.required_without' => 'Debe proporcionar al menos placa o VIN',
|
|
'vin.required_without' => 'Debe proporcionar al menos placa o VIN',
|
|
]);
|
|
|
|
if ($validator->fails()) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Datos inválidos',
|
|
'errors' => $validator->errors()
|
|
], 422);
|
|
}
|
|
|
|
try {
|
|
$placa = $request->placa;
|
|
$vin = $request->vin;
|
|
|
|
// Consultar padrón estatal (obtener datos completos del vehículo)
|
|
Log::info('Consultando padrón estatal', ['placa' => $placa, 'vin' => $vin]);
|
|
|
|
// Si viene VIN, usar VIN, si no usar placa
|
|
$criterio = $vin ?: $placa;
|
|
$datosEstatal = $this->consultaEstatal->consultarPorEpc($criterio);
|
|
|
|
if (!$datosEstatal || (!$datosEstatal['vin'] && !$datosEstatal['placa'])) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'No se encontró información del vehículo en el padrón estatal'
|
|
], 404);
|
|
}
|
|
|
|
// Obtener VIN y Placa completos
|
|
$vinCompleto = $datosEstatal['vin'] ?: $vin;
|
|
$placaCompleta = $datosEstatal['placa'] ?: $placa;
|
|
|
|
Log::info('Datos del padrón estatal obtenidos', [
|
|
'vin' => $vinCompleto,
|
|
'placa' => $placaCompleta
|
|
]);
|
|
|
|
// Consultar REPUVE
|
|
$reporteRobo = $this->reporteRobo->consultarPorVin($vinCompleto, $placaCompleta);
|
|
|
|
$tieneReporte = $reporteRobo['tiene_reporte'] ?? false;
|
|
|
|
// Si tiene reporte de robo → Guardar en Redis
|
|
if ($tieneReporte) {
|
|
$epc = 'MANUAL_' . ($vinCompleto ?: $placaCompleta);
|
|
|
|
$this->guardarEnRedis($epc, $datosEstatal, $reporteRobo['datos']);
|
|
|
|
Log::warning('¡VEHÍCULO CON REPORTE DE ROBO REGISTRADO!', [
|
|
'vin' => $vinCompleto,
|
|
'placa' => $placaCompleta,
|
|
'autoridad' => $reporteRobo['datos']['autoridad'] ?? null
|
|
]);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'tiene_reporte_robo' => true,
|
|
'message' => '¡ALERTA! El vehículo tiene reporte de robo',
|
|
'vehiculo' => [
|
|
'vin' => $vinCompleto,
|
|
'placa' => $placaCompleta,
|
|
],
|
|
'reporte_robo' => $reporteRobo['datos']
|
|
]);
|
|
}
|
|
|
|
// No tiene reporte de robo
|
|
Log::info('Vehículo consultado sin reporte de robo', [
|
|
'vin' => $vinCompleto,
|
|
'placa' => $placaCompleta
|
|
]);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'tiene_reporte_robo' => false,
|
|
'message' => 'Vehículo sin reporte de robo',
|
|
'vehiculo' => [
|
|
'vin' => $vinCompleto,
|
|
'placa' => $placaCompleta,
|
|
]
|
|
]);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('Error al consultar vehículo', [
|
|
'placa' => $request->placa,
|
|
'vin' => $request->vin,
|
|
'error' => $e->getMessage()
|
|
]);
|
|
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Error al consultar vehículo',
|
|
'error' => $e->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Guardar vehículo robado en Redis
|
|
*/
|
|
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' => 0,
|
|
'origen' => 'CONSULTA_MANUAL'
|
|
];
|
|
|
|
Redis::set($key, json_encode($datos));
|
|
}
|
|
|
|
/**
|
|
* Dar de baja (registrar como recuperado) un vehículo por PLACA o VIN
|
|
*/
|
|
public function recuperarVehiculo(Request $request): JsonResponse
|
|
{
|
|
$validator = Validator::make($request->all(), [
|
|
'placa' => 'required_without:vin|string|nullable',
|
|
'vin' => 'required_without:placa|string|nullable',
|
|
], [
|
|
'placa.required_without' => 'Debe proporcionar al menos placa o VIN',
|
|
'vin.required_without' => 'Debe proporcionar al menos placa o VIN',
|
|
]);
|
|
|
|
if ($validator->fails()) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Datos inválidos',
|
|
'errors' => $validator->errors()
|
|
], 422);
|
|
}
|
|
|
|
try {
|
|
$placa = $request->placa;
|
|
$vin = $request->vin;
|
|
|
|
Log::info('Buscando vehículo robado para recuperar', ['placa' => $placa, 'vin' => $vin]);
|
|
|
|
// 1. Buscar en Redis (vehículos robados activos)
|
|
$vehiculoEncontrado = $this->buscarEnRedis($vin, $placa);
|
|
|
|
if (!$vehiculoEncontrado) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'El vehículo no se encuentra en la lista de robados activos'
|
|
], 404);
|
|
}
|
|
|
|
$datosRedis = $vehiculoEncontrado['datos'];
|
|
$epc = $vehiculoEncontrado['epc'];
|
|
|
|
Log::info('Vehículo encontrado en Redis', [
|
|
'epc' => $epc,
|
|
'vin' => $datosRedis['vin'],
|
|
'placa' => $datosRedis['placa']
|
|
]);
|
|
|
|
// 2. Guardar en MySQL como recuperado
|
|
$vehiculoRecuperado = 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_acta' => $datosRedis['fecha_acta'] ?? null,
|
|
'fecha_recuperacion' => now(),
|
|
'datos_robo_original' => $datosRedis
|
|
]);
|
|
|
|
// 3. Eliminar de Redis
|
|
Redis::del("vehiculo:robado:{$epc}");
|
|
|
|
Log::info('Vehículo registrado como recuperado', [
|
|
'id' => $vehiculoRecuperado->id,
|
|
'vin' => $vehiculoRecuperado->vin,
|
|
'placa' => $vehiculoRecuperado->placa
|
|
]);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Vehículo registrado como recuperado exitosamente',
|
|
'vehiculo' => [
|
|
'id' => $vehiculoRecuperado->id,
|
|
'epc' => $vehiculoRecuperado->epc,
|
|
'vin' => $vehiculoRecuperado->vin,
|
|
'placa' => $vehiculoRecuperado->placa,
|
|
'fecha_robo' => $vehiculoRecuperado->fecha_robo,
|
|
'fecha_recuperacion' => $vehiculoRecuperado->fecha_recuperacion,
|
|
'autoridad_robo' => $vehiculoRecuperado->autoridad_robo,
|
|
'acta_robo' => $vehiculoRecuperado->acta_robo,
|
|
]
|
|
]);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('Error al recuperar vehículo', [
|
|
'placa' => $request->placa,
|
|
'vin' => $request->vin,
|
|
'error' => $e->getMessage()
|
|
]);
|
|
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Error al registrar vehículo como recuperado',
|
|
'error' => $e->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Buscar vehículo en Redis por VIN o Placa
|
|
*/
|
|
private function buscarEnRedis(?string $vin, ?string $placa): ?array
|
|
{
|
|
$keys = Redis::keys('vehiculo:robado:*');
|
|
|
|
foreach ($keys as $key) {
|
|
$datos = Redis::get($key);
|
|
if (!$datos) {
|
|
continue;
|
|
}
|
|
|
|
$vehiculo = json_decode($datos, true);
|
|
|
|
// Buscar por VIN o Placa
|
|
if (($vin && $vehiculo['vin'] === $vin) || ($placa && $vehiculo['placa'] === $placa)) {
|
|
// Extraer el EPC del key
|
|
$epc = str_replace('vehiculo:robado:', '', $key);
|
|
|
|
return [
|
|
'epc' => $epc,
|
|
'datos' => $vehiculo
|
|
];
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Listar todos los vehículos robados activos
|
|
* GET /api/vehicles/robados
|
|
*/
|
|
public function listarRobados(): JsonResponse
|
|
{
|
|
try {
|
|
$vehiculos = $this->vehicleService->listarVehiculosRobados();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'total' => count($vehiculos),
|
|
'vehiculos' => $vehiculos
|
|
]);
|
|
|
|
} catch (\Exception $e) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Error al listar vehículos robados',
|
|
'error' => $e->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
}
|