with('deviceModules.module', 'deviceModules.user'); if ($request->filled('serie')) { $devices->where('serie', 'LIKE', '%' . $request->input('serie') . '%'); } if ($request->filled('brand')) { $devices->where('brand', 'LIKE', '%' . $request->input('brand') . '%'); } return ApiResponse::OK->response([ 'devices' => $devices->paginate(config('app.pagination')), ]); } catch (\Exception $e) { return ApiResponse::INTERNAL_ERROR->response([ 'message' => 'Error al obtener la lista de dispositivos.', 'error' => $e->getMessage(), ]); } } public function store(DeviceStoreRequest $request) { try { DB::beginTransaction(); // 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), ]); // Asignar módulo y usuarios usando el modelo DeviceModule $userIds = $request->input('user_id', []); if (!empty($userIds)) { // Si hay usuarios, crear un registro por cada usuario foreach ($userIds as $userId) { DeviceModule::create([ 'device_id' => $device->id, 'module_id' => $request->module_id, 'user_id' => $userId, 'status' => true, ]); } } else { // Si no hay usuarios, crear solo la relación device-module DeviceModule::create([ 'device_id' => $device->id, 'module_id' => $request->module_id, 'user_id' => null, 'status' => true, ]); } DB::commit(); $device->load('deviceModules.module'); return ApiResponse::CREATED->response([ 'message' => 'Dispositivo creado exitosamente.', 'device' => [ 'id' => $device->id, 'brand' => $device->brand, 'serie' => $device->serie, 'status' => $device->status, 'module' => $device->deviceModules->first()?->module, ], ]); } catch (\Exception $e) { DB::rollBack(); return ApiResponse::INTERNAL_ERROR->response([ 'message' => 'Error al crear el dispositivo.', 'error' => $e->getMessage(), ]); } } public function show($id) { try { $device = Device::with('deviceModules.module', 'deviceModules.user')->findOrFail($id); return ApiResponse::OK->response([ 'device' => $device, ]); } catch (ModelNotFoundException $e) { return ApiResponse::NOT_FOUND->response([ 'message' => 'Dispositivo no encontrado.', ]); } catch (\Exception $e) { return ApiResponse::INTERNAL_ERROR->response([ 'message' => 'Error al obtener el dispositivo.', 'error' => $e->getMessage(), ]); } } public function update(DeviceUpdateRequest $request, $id) { try { DB::beginTransaction(); $device = Device::findOrFail($id); // Validar unicidad solo si los valores cambiaron if ($request->filled('serie') && $request->serie !== $device->serie) { if (Device::where('serie', $request->serie)->exists()) { DB::rollBack(); return ApiResponse::UNPROCESSABLE_CONTENT->response([ 'serie' => ['El número de serie ya está en uso.'], ]); } } if ($request->filled('mac_address') && $request->mac_address !== $device->mac_address) { if (Device::where('mac_address', $request->mac_address)->exists()) { DB::rollBack(); return ApiResponse::UNPROCESSABLE_CONTENT->response([ 'mac_address' => ['La dirección MAC ya está registrada.'], ]); } } $device->update($request->only(['brand', 'serie', 'mac_address', 'status'])); DeviceModule::where('device_id', $device->id)->delete(); $userIds = $request->input('user_id', []); if (!empty($userIds)) { foreach ($userIds as $userId) { DeviceModule::create([ 'device_id' => $device->id, 'module_id' => $request->module_id, 'user_id' => $userId, 'status' => true, ]); } } else { DeviceModule::create([ 'device_id' => $device->id, 'module_id' => $request->module_id, 'user_id' => null, 'status' => true, ]); } DB::commit(); $device->load(['deviceModules.module', 'deviceModules.user']); return ApiResponse::OK->response([ 'message' => 'Dispositivo actualizado exitosamente.', 'device' => [ 'id' => $device->id, 'brand' => $device->brand, 'serie' => $device->serie, 'mac_address' => $device->mac_address, 'status' => $device->status, 'module' => $device->deviceModules->first()?->module, 'authorized_users' => $device->deviceModules ->filter(fn($dm) => $dm->user !== null) ->map(fn($dm) => [ 'id' => $dm->user->id, 'name' => $dm->user->full_name, 'username' => $dm->user->username, ]) ->unique('id') ->values(), ], ]); } catch (ModelNotFoundException $e) { return ApiResponse::NOT_FOUND->response([ 'message' => 'Dispositivo no encontrado.', ]); } catch (\Exception $e) { DB::rollBack(); return ApiResponse::INTERNAL_ERROR->response([ 'message' => 'Error al actualizar el dispositivo.', 'error' => $e->getMessage(), ]); } } public function destroy($id) { try { DB::beginTransaction(); $device = Device::findOrFail($id); $device->delete(); DB::commit(); return ApiResponse::OK->response([ 'message' => 'Dispositivo eliminado exitosamente.', ]); } catch (ModelNotFoundException $e) { DB::rollBack(); return ApiResponse::NOT_FOUND->response([ 'message' => 'Dispositivo no encontrado.', ]); } catch (\Exception $e) { DB::rollBack(); return ApiResponse::INTERNAL_ERROR->response([ 'message' => 'Error al eliminar el dispositivo.', 'error' => $e->getMessage(), ]); } } /** * Cambiar solo el status de un dispositivo */ public function toggleStatus(int $id) { try { $device = Device::findOrFail($id); DB::beginTransaction(); $newStatus = !$device->status; $device->update([ 'status' => $newStatus, ]); DB::commit(); $device->refresh(); return ApiResponse::OK->response([ 'message' => $device->status ? 'Dispositivo activado exitosamente' : 'Dispositivo desactivado exitosamente', 'device' => [ 'id' => $device->id, 'brand' => $device->brand, 'serie' => $device->serie, 'mac_address' => $device->mac_address, 'status' => $device->status ? 'Activo' : 'Inactivo', 'updated_at' => $device->updated_at->format('Y-m-d H:i:s'), ], ]); } catch (ModelNotFoundException $e) { return ApiResponse::NOT_FOUND->response([ 'message' => 'Dispositivo no encontrado', ]); } catch (\Exception $e) { DB::rollBack(); Log::error('Error al cambiar status del módulo: ' . $e->getMessage(), [ 'module_id' => $id, 'trace' => $e->getTraceAsString() ]); return ApiResponse::INTERNAL_ERROR->response([ 'message' => 'Error al cambiar status del módulo', 'error' => $e->getMessage(), ]); } } }