arcos-backend/app/Http/Controllers/Api/ArcoController.php
Juan Felipe Zapata Moreno 04c5cc2dfa fix: robados
2026-01-08 16:10:16 -06:00

224 lines
6.3 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\Arco;
use App\Services\VehicleService;
use Illuminate\Http\Request;
use Notsoweb\ApiResponse\Enums\ApiResponse;
/**
* Controlador para gestión de Arcos
*/
class ArcoController extends Controller
{
public function __construct(
private VehicleService $vehicleService
) {}
/**
* Listar todos los arcos
* GET /api/arcos
*/
public function index(Request $request)
{
$query = Arco::query();
// Filtro por estado activo
if ($request->has('activo')) {
$query->where('activo', $request->boolean('activo'));
}
// Filtro por IP
if ($request->has('ip')) {
$query->where('ip_address', 'like', '%' . $request->ip . '%');
}
$arcos = $query->orderBy('created_at', 'desc')->get();
// Agregar token desencriptado a cada arco
$arcos->each(function($arco) {
$arco->api_token_plain = $arco->obtenerTokenDesencriptado();
});
return ApiResponse::OK->response([
'arcos' => $arcos,
]);
}
/**
* Crear un nuevo arco
* POST /api/arcos
*/
public function store(Request $request)
{
$validated = $request->validate([
'nombre' => 'required|string|max:255',
'ip_address' => 'required|ip|unique:arcos,ip_address',
'ubicacion' => 'nullable|string|max:255',
'descripcion' => 'nullable|string',
'antena_1' => 'nullable|string',
'antena_2' => 'nullable|string',
'antena_3' => 'nullable|string',
'antena_4' => 'nullable|string',
'activo' => 'boolean'
]);
$arco = Arco::create($validated);
// Obtener el token en texto plano para mostrárselo al usuario
$plainToken = $arco->obtenerTokenDesencriptado();
return ApiResponse::CREATED->response([
'message' => 'Arco creado exitosamente',
'arco' => $arco,
'api_token' => $plainToken // Token en texto plano para que el arco lo use
]);
}
/**
* Mostrar un arco específico
* GET /api/arcos/{id}
*/
public function show(Arco $arco)
{
return ApiResponse::OK->response([
'arco' => $arco
]);
}
/**
* Actualizar un arco
* PUT/PATCH /api/arcos/{id}
*/
public function update(Request $request, int $id)
{
$arco = Arco::find($id);
if (!$arco) {
return ApiResponse::NOT_FOUND->response([
'message' => 'Arco no encontrado'
]);
}
$validated = $request->validate([
'nombre' => 'sometimes|required|string|max:255',
'ip_address' => 'sometimes|required|ip|unique:arcos,ip_address,' . $id,
'ubicacion' => 'nullable|string|max:255',
'descripcion' => 'nullable|string',
'antena_1' => 'nullable|string',
'antena_2' => 'nullable|string',
'antena_3' => 'nullable|string',
'antena_4' => 'nullable|string'
]);
$arco->update($validated);
return ApiResponse::OK->response([
'message' => 'Arco actualizado exitosamente',
'arco' => $arco
]);
}
/**
* Eliminar un arco
* DELETE /api/arcos/{id}
*/
public function destroy(int $id)
{
$arco = Arco::find($id);
if (!$arco) {
return ApiResponse::NOT_FOUND->response([
'message' => 'Arco no encontrado'
]);
}
$arco->delete();
return ApiResponse::OK->response([
'message' => 'Arco eliminado exitosamente'
]);
}
/**
* Activar/Desactivar un arco
* PATCH /api/arcos/{id}/toggle-estado
*/
public function toggleEstado(int $id)
{
$arco = Arco::find($id);
if (!$arco) {
return ApiResponse::NOT_FOUND->response([
'message' => 'Arco no encontrado'
]);
}
$arco->activo = !$arco->activo;
$arco->save();
return ApiResponse::OK->response([
'message' => $arco->activo ? 'Arco activado' : 'Arco desactivado',
'arco' => $arco
]);
}
/**
* Listar detecciones del día de un arco específico
* GET /api/arcos/{id}/detecciones/dia
*/
public function deteccionesDelDia(Request $request, int $id)
{
$arco = Arco::find($id);
if (!$arco) {
return ApiResponse::NOT_FOUND->response([
'success' => false,
'message' => 'Arco no encontrado'
]);
}
$fecha = $request->input('fecha'); // Formato: Y-m-d (opcional)
if ($fecha && !preg_match('/^\d{4}-\d{2}-\d{2}$/', $fecha)) {
return ApiResponse::BAD_REQUEST->response([
'success' => false,
'message' => 'Formato de fecha inválido. Use YYYY-MM-DD'
]);
}
try {
$detecciones = $this->vehicleService->listarDeteccionesDelDiaPorArco($id, $fecha);
// Filtrar solo VIN, placa, antena y si es robado
$deteccionesFiltradas = array_map(function($deteccion) {
return [
'vin' => $deteccion['vin'] ?? null,
'placa' => $deteccion['placa'] ?? null,
'antena' => $deteccion['antena'] ?? null,
'robado' => $deteccion['tiene_reporte_robo'] ?? false,
];
}, $detecciones);
return ApiResponse::OK->response([
'success' => true,
'arco' => [
'id' => $arco->id,
'nombre' => $arco->nombre,
'ubicacion' => $arco->ubicacion,
],
'fecha' => $fecha ?? now()->format('Y-m-d'),
'total' => count($deteccionesFiltradas),
'detecciones' => $deteccionesFiltradas
]);
} catch (\Exception $e) {
return ApiResponse::INTERNAL_ERROR->response([
'success' => false,
'message' => 'Error al obtener detecciones del arco',
'error' => $e->getMessage()
]);
}
}
}