WIP listar devices y creación agregado
This commit is contained in:
parent
c4935d5298
commit
2fc21be5a2
@ -1,41 +1,67 @@
|
|||||||
<?php namespace App\Http\Controllers\Repuve;
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Repuve;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Notsoweb\ApiResponse\Enums\ApiResponse;
|
use Notsoweb\ApiResponse\Enums\ApiResponse;
|
||||||
|
use App\Http\Requests\Repuve\DeviceStoreRequest;
|
||||||
use App\Models\Device;
|
use App\Models\Device;
|
||||||
|
use App\Models\DeviceModule;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class DeviceController extends Controller
|
class DeviceController extends Controller
|
||||||
{
|
{
|
||||||
public function index(Request $request)
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
try{
|
try {
|
||||||
$query = Device::query('devices');
|
$query = Device::query();
|
||||||
|
|
||||||
if (!$request->filled('serie') && !$request->filled('brand')){
|
if (!$request->filled('serie') && !$request->filled('brand')) {
|
||||||
return ApiResponse::BAD_REQUEST->response([
|
return ApiResponse::BAD_REQUEST->response([
|
||||||
'message' => 'Debe proporcionar al menos uno de los siguientes parámetros: serie o marca.'
|
'message' => 'Debe proporcionar al menos uno de los siguientes parámetros: serie o marca.'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request->filled('serie')){
|
if ($request->filled('serie')) {
|
||||||
$query->where('serie', 'LIKE', '%' . $request->input('serie') . '%');
|
$query->where('serie', 'LIKE', '%' . $request->input('serie') . '%');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request->filled('brand')){
|
if ($request->filled('brand')) {
|
||||||
$query->where('brand', 'LIKE', '%' . $request->input('brand') . '%');
|
$query->where('brand', 'LIKE', '%' . $request->input('brand') . '%');
|
||||||
}
|
}
|
||||||
|
|
||||||
$perPage = $request->input('per_page', 10);
|
$query->with('deviceModules.module', 'deviceModules.user');
|
||||||
|
|
||||||
|
$perPage = $request->input('per_page', 15);
|
||||||
$devices = $query->paginate($perPage);
|
$devices = $query->paginate($perPage);
|
||||||
|
|
||||||
return ApiResponse::OK->response([
|
return ApiResponse::OK->response([
|
||||||
'devices' => $devices->map(function ($devices){
|
'devices' => $devices->map(function ($device) {
|
||||||
|
$module = $device->deviceModules->first()?->module;
|
||||||
|
$authorizedUsers = $device->deviceModules
|
||||||
|
->filter(fn($dm) => $dm->user !== null)
|
||||||
|
->map(function ($deviceModule) {
|
||||||
return [
|
return [
|
||||||
'id' => $devices->id,
|
'id' => $deviceModule->user->id,
|
||||||
'brand' => $devices->brand,
|
'name' => $deviceModule->user->full_name,
|
||||||
'serie' => $devices->serie,
|
'email' => $deviceModule->user->email,
|
||||||
'status' => $devices->status,
|
];
|
||||||
|
})
|
||||||
|
->unique('id')
|
||||||
|
->values();
|
||||||
|
|
||||||
|
return [
|
||||||
|
'id' => $device->id,
|
||||||
|
'brand' => $device->brand,
|
||||||
|
'serie' => $device->serie,
|
||||||
|
'mac_address' => $device->mac_address,
|
||||||
|
'status' => $device->status ? 'activo' : 'inactivo',
|
||||||
|
'module' => $module ? [
|
||||||
|
'id' => $module->id,
|
||||||
|
'name' => $module->name,
|
||||||
|
] : null,
|
||||||
|
'authorized_users' => $authorizedUsers,
|
||||||
];
|
];
|
||||||
}),
|
}),
|
||||||
'pagination' => [
|
'pagination' => [
|
||||||
@ -47,11 +73,58 @@ public function index(Request $request)
|
|||||||
'to' => $devices->lastItem(),
|
'to' => $devices->lastItem(),
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
} catch(\Exception $e){
|
} catch (\Exception $e) {
|
||||||
return ApiResponse::INTERNAL_ERROR->response([
|
return ApiResponse::INTERNAL_ERROR->response([
|
||||||
'message' => 'Error al obtener la lista de dispositivos.',
|
'message' => 'Error al obtener la lista de dispositivos.',
|
||||||
'error' => $e->getMessage(),
|
'error' => $e->getMessage(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function store(DeviceStoreRequest $request)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
DB::beginTransaction();
|
||||||
|
|
||||||
|
// 1. Crear el dispositivo
|
||||||
|
$device = Device::create([
|
||||||
|
'brand' => $request->input('brand'),
|
||||||
|
'serie' => $request->input('serie'),
|
||||||
|
'mac_address' => $request->input('mac_address'),
|
||||||
|
'status' => $request->input('status', true),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 2. Asignar módulo y usuarios usando el modelo DeviceModule
|
||||||
|
$userIds = $request->input('user_id');
|
||||||
|
|
||||||
|
foreach ($userIds as $userId) {
|
||||||
|
DeviceModule::create([
|
||||||
|
'device_id' => $device->id,
|
||||||
|
'module_id' => $request->module_id,
|
||||||
|
'user_id' => $userId,
|
||||||
|
'status' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
|
||||||
|
$device->load('modules');
|
||||||
|
|
||||||
|
return ApiResponse::CREATED->response([
|
||||||
|
'message' => 'Dispositivo creado exitosamente.',
|
||||||
|
'device' => [
|
||||||
|
'id' => $device->id,
|
||||||
|
'brand' => $device->brand,
|
||||||
|
'serie' => $device->serie,
|
||||||
|
'status' => $device->status,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
DB::rollBack();
|
||||||
|
return ApiResponse::INTERNAL_ERROR->response([
|
||||||
|
'message' => 'Error al crear el dispositivo.',
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -137,11 +137,6 @@ public function store(ModuleStoreRequest $request)
|
|||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
Log::error('Error al crear módulo: ' . $e->getMessage(), [
|
|
||||||
'request' => $request->all(),
|
|
||||||
'trace' => $e->getTraceAsString()
|
|
||||||
]);
|
|
||||||
|
|
||||||
return ApiResponse::INTERNAL_ERROR->response([
|
return ApiResponse::INTERNAL_ERROR->response([
|
||||||
'message' => 'Error al crear módulo',
|
'message' => 'Error al crear módulo',
|
||||||
'error' => $e->getMessage(),
|
'error' => $e->getMessage(),
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
<?php
|
<?php namespace App\Http\Requests\Repuve;
|
||||||
|
|
||||||
namespace App\Http\Requests\Repuve;
|
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
class ModuleStoreRequest extends FormRequest
|
class DeviceStoreRequest extends FormRequest
|
||||||
{
|
{
|
||||||
public function authorize(): bool
|
public function authorize(): bool
|
||||||
{
|
{
|
||||||
@ -14,10 +12,13 @@ public function authorize(): bool
|
|||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'brand' => 'required|string|max:255',
|
'brand' => ['required', 'string', 'max:255'],
|
||||||
'serie' => 'required|string|unique:devices,serie|max:255',
|
'serie' => ['required', 'string', 'unique:devices,serie', 'max:255'],
|
||||||
'module_id' => 'required|exists:modules,id',
|
'mac_address' => ['required', 'string', 'unique:devices,mac_address', 'regex:/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/'],
|
||||||
'status' => 'nullable|boolean',
|
'module_id' => ['required', 'exists:modules,id'],
|
||||||
|
'user_id' => ['required', 'array', 'min:1'],
|
||||||
|
'user_id.*' => ['exists:users,id'],
|
||||||
|
'status' => ['nullable', 'boolean'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,7 +27,13 @@ public function messages(): array
|
|||||||
return [
|
return [
|
||||||
'brand.required' => 'La marca del dispositivo es requerida',
|
'brand.required' => 'La marca del dispositivo es requerida',
|
||||||
'serie.required' => 'El número de serie del dispositivo es requerido',
|
'serie.required' => 'El número de serie del dispositivo es requerido',
|
||||||
|
'serie.unique' => 'El número de serie ya está registrado',
|
||||||
|
'mac_address.required' => 'La dirección MAC es requerida',
|
||||||
|
'mac_address.unique' => 'La dirección MAC ya está registrada',
|
||||||
|
'mac_address.regex' => 'La dirección MAC debe tener un formato válido (Ej: 00:1B:44:11:3A:B7)',
|
||||||
'module_id.required' => 'El módulo asignado es requerido',
|
'module_id.required' => 'El módulo asignado es requerido',
|
||||||
|
'user_id.required' => 'Debe seleccionar al menos un usuario autorizado',
|
||||||
|
'user_id.array' => 'Los usuarios autorizados deben ser un array',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
class ModuleStoreRequest extends FormRequest
|
class DeviceUpdateRequest extends FormRequest
|
||||||
{
|
{
|
||||||
public function authorize(): bool
|
public function authorize(): bool
|
||||||
{
|
{
|
||||||
@ -14,10 +14,13 @@ public function authorize(): bool
|
|||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'brand' => 'sometimes|string|max:255',
|
'brand' => ['required', 'string', 'max:255'],
|
||||||
'serie' => 'sometimes|string|unique:devices,serie,{id}|max:255',
|
'serie' => ['required', 'string', 'unique:devices,serie', 'max:255'],
|
||||||
'module_id' => 'sometimes|exists:modules,id',
|
'mac_address' => ['required', 'string', 'unique:devices,mac_address', 'max:15'],
|
||||||
'status' => 'nullable|boolean',
|
'module_id' => ['required', 'exists:modules,id'],
|
||||||
|
'user_id' => ['required', 'array', 'min:1'],
|
||||||
|
'user_id.*' => ['exists:users,id'],
|
||||||
|
'status' => ['nullable', 'boolean'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,7 @@ class Device extends Model
|
|||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'brand',
|
'brand',
|
||||||
'serie',
|
'serie',
|
||||||
|
'mac_address',
|
||||||
'status',
|
'status',
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -24,7 +25,7 @@ protected function casts(): array
|
|||||||
|
|
||||||
public function modules()
|
public function modules()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Module::class, 'device_module')
|
return $this->belongsToMany(Module::class, 'device_module')
|
||||||
->withPivot('status')
|
->withPivot('status')
|
||||||
->withTimestamps();
|
->withTimestamps();
|
||||||
}
|
}
|
||||||
@ -36,7 +37,7 @@ public function deviceModules()
|
|||||||
|
|
||||||
public function activeModules()
|
public function activeModules()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Module::class, 'device_module')
|
return $this->belongsToMany(Module::class, 'device_module')
|
||||||
->wherePivot('status', true)
|
->wherePivot('status', true)
|
||||||
->withPivot('status')
|
->withPivot('status')
|
||||||
->withTimestamps();
|
->withTimestamps();
|
||||||
|
|||||||
@ -14,6 +14,7 @@ class DeviceModule extends Model
|
|||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'device_id',
|
'device_id',
|
||||||
'module_id',
|
'module_id',
|
||||||
|
'user_id',
|
||||||
'status',
|
'status',
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -33,4 +34,9 @@ public function module()
|
|||||||
{
|
{
|
||||||
return $this->belongsTo(Module::class);
|
return $this->belongsTo(Module::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function user()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,6 +30,7 @@ public function definition(): array
|
|||||||
return [
|
return [
|
||||||
'brand' => fake()->randomElement($brands),
|
'brand' => fake()->randomElement($brands),
|
||||||
'serie' => strtoupper(fake()->bothify('??##')) . '-' . $year . '-' . $randomNumber,
|
'serie' => strtoupper(fake()->bothify('??##')) . '-' . $year . '-' . $randomNumber,
|
||||||
|
'mac_address' => fake()->macAddress(),
|
||||||
'status' => fake()->boolean(85), // 85% activos
|
'status' => fake()->boolean(85), // 85% activos
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@ public function up(): void
|
|||||||
$table->id();
|
$table->id();
|
||||||
$table->string('brand');
|
$table->string('brand');
|
||||||
$table->string('serie')->unique();
|
$table->string('serie')->unique();
|
||||||
|
$table->string('mac_address')->unique();
|
||||||
$table->boolean('status')->default(true);
|
$table->boolean('status')->default(true);
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -15,10 +15,11 @@ public function up(): void
|
|||||||
$table->id();
|
$table->id();
|
||||||
$table->foreignId('device_id')->constrained('devices')->cascadeOnDelete();
|
$table->foreignId('device_id')->constrained('devices')->cascadeOnDelete();
|
||||||
$table->foreignId('module_id')->constrained('modules')->cascadeOnDelete();
|
$table->foreignId('module_id')->constrained('modules')->cascadeOnDelete();
|
||||||
|
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
|
||||||
$table->boolean('status')->default(true);
|
$table->boolean('status')->default(true);
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
|
|
||||||
$table->unique(['device_id', 'module_id']);
|
$table->unique(['device_id', 'module_id', 'user_id']);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,41 +17,49 @@ public function run(): void
|
|||||||
[
|
[
|
||||||
'brand' => 'estatal',
|
'brand' => 'estatal',
|
||||||
'serie' => 'ZB01-2024-001234',
|
'serie' => 'ZB01-2024-001234',
|
||||||
|
'mac_address' => '00:1B:44:11:3A:B7',
|
||||||
'status' => true,
|
'status' => true,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'brand' => 'estatal',
|
'brand' => 'estatal',
|
||||||
'serie' => 'ZB01-2024-001235',
|
'serie' => 'ZB01-2024-001235',
|
||||||
|
'mac_address' => '00:1B:44:11:3A:B8',
|
||||||
'status' => true,
|
'status' => true,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'brand' => 'estatal',
|
'brand' => 'estatal',
|
||||||
'serie' => 'HW02-2024-002456',
|
'serie' => 'HW02-2024-002456',
|
||||||
|
'mac_address' => '00:1B:44:11:3A:B9',
|
||||||
'status' => true,
|
'status' => true,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'brand' => 'estatal',
|
'brand' => 'estatal',
|
||||||
'serie' => 'HW02-2024-002457',
|
'serie' => 'HW02-2024-002457',
|
||||||
|
'mac_address' => '00:1B:44:11:3A:BA',
|
||||||
'status' => true,
|
'status' => true,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'brand' => 'nacional',
|
'brand' => 'nacional',
|
||||||
'serie' => 'DL03-2023-003678',
|
'serie' => 'DL03-2023-003678',
|
||||||
|
'mac_address' => '00:1B:44:11:3A:BB',
|
||||||
'status' => true,
|
'status' => true,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'brand' => 'nacional',
|
'brand' => 'nacional',
|
||||||
'serie' => 'IP04-2024-004890',
|
'serie' => 'IP04-2024-004890',
|
||||||
|
'mac_address' => '00:1B:44:11:3A:BC',
|
||||||
'status' => true,
|
'status' => true,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'brand' => 'nacional',
|
'brand' => 'nacional',
|
||||||
'serie' => 'MT05-2023-005123',
|
'serie' => 'MT05-2023-005123',
|
||||||
|
'mac_address' => '00:1B:44:11:3A:BD',
|
||||||
'status' => true,
|
'status' => true,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'brand' => 'nacional',
|
'brand' => 'nacional',
|
||||||
'serie' => 'TM06-2024-006345',
|
'serie' => 'TM06-2024-006345',
|
||||||
|
'mac_address' => '00:1B:44:11:3A:BE',
|
||||||
'status' => false, // Dispositivo inactivo
|
'status' => false, // Dispositivo inactivo
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
@ -55,6 +55,7 @@
|
|||||||
|
|
||||||
//Rutas de dispositivos
|
//Rutas de dispositivos
|
||||||
Route::get('/devices', [DeviceController::class, 'index']);
|
Route::get('/devices', [DeviceController::class, 'index']);
|
||||||
|
Route::post('/devices-create', [DeviceController::class, 'store']);
|
||||||
});
|
});
|
||||||
|
|
||||||
/** Rutas públicas */
|
/** Rutas públicas */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user