diff --git a/app/Http/Controllers/Admin/RoleController.php b/app/Http/Controllers/Admin/RoleController.php index 80b05c6..ddfe86b 100644 --- a/app/Http/Controllers/Admin/RoleController.php +++ b/app/Http/Controllers/Admin/RoleController.php @@ -14,9 +14,9 @@ /** * Roles del sistema - * + * * @author Moisés Cortés C. - * + * * @version 1.0.0 */ class RoleController extends Controller @@ -97,4 +97,23 @@ public function updatePermissions(Role $role, Request $request) return ApiResponse::OK->response(); } + + /** + * Obtener todos los roles + */ + public function listAll() + { + try { + $roles = Role::orderBy('name')->get(['id', 'name']); + + return ApiResponse::OK->response([ + 'roles' => $roles, + ]); + + } catch (\Exception $e) { + return ApiResponse::INTERNAL_ERROR->response([ + 'message' => 'Error al obtener roles', + ]); + } + } } diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index c95d8b0..8f79c55 100644 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -15,11 +15,11 @@ /** * Controlador de usuarios - * + * * Permite la administración de los usuarios en general. - * + * * @author Moisés Cortés C - * + * * @version 1.0.0 */ class UserController extends Controller @@ -34,7 +34,21 @@ public function index() QuerySupport::queryByKeys($users, ['name', 'email']); return ApiResponse::OK->response([ - 'models' => $users->paginate(config('app.pagination')) + 'models' => $users->paginate(config('app.pagination')), + 'data' => $users->paginate(config('app.pagination'))->map(function($user) { + return [ + 'id' => $user->id, + 'name' => $user->full_name, + 'username' => $user->name, // username corto + 'email' => $user->email, + 'module' => $user->module ? [ + 'id' => $user->module->id, + 'name' => $user->module->name, + ] : null, + 'roles' => $user->roles->pluck('name')->toArray(), + 'status' => $user->deleted_at ? 'De Baja' : 'Activo', + ]; + }), ]); } @@ -49,7 +63,10 @@ public function store(UserStoreRequest $request) $user->roles()->sync($request->roles); } - return ApiResponse::OK->response(); + return ApiResponse::OK->response([ + 'message' => 'Usuario actualizado exitosamente', + 'user' => $user->load(['module', 'roles']), + ]); } /** @@ -69,7 +86,14 @@ public function update(UserUpdateRequest $request, User $user) { $user->update($request->all()); - return ApiResponse::OK->response(); + if ($request->has('roles')) { + $user->roles()->sync($request->roles); + } + + return ApiResponse::OK->response([ + 'message' => 'Usuario actualizado exitosamente', + 'user' => $user->load(['module', 'roles']), + ]); } /** @@ -152,7 +176,7 @@ public function activity(UserActivityRequest $request, User $user) } return ApiResponse::OK->response([ - 'models' => + 'models' => $model->orderBy('created_at', 'desc') ->paginate(config('app.pagination')) ]); diff --git a/app/Http/Controllers/Repuve/ModuleController.php b/app/Http/Controllers/Repuve/ModuleController.php index b39c83b..0e4715e 100644 --- a/app/Http/Controllers/Repuve/ModuleController.php +++ b/app/Http/Controllers/Repuve/ModuleController.php @@ -6,6 +6,7 @@ use App\Http\Requests\Repuve\ModuleStoreRequest; use App\Http\Requests\Repuve\ModuleUpdateRequest; use App\Models\Module; +use App\Models\User; use Illuminate\Database\Eloquent\Model; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; @@ -21,7 +22,7 @@ class ModuleController extends Controller public function index(Request $request) { try { - $query = Module::query(); + $query = Module::query('responsible')->withCount(['packages']); // Validar que se envíe al menos un parámetro de búsqueda if (!$request->filled('name') && !$request->filled('municipality')) { @@ -57,6 +58,11 @@ public function index(Request $request) return [ 'id' => $module->id, 'name' => $module->name, + 'responsible' => $module->responsible ? [ + 'id' => $module->responsible->id, + 'name' => $module->responsible->full_name, + 'email' => $module->responsible->email, + ] : null, 'municipality' => $module->municipality, 'address' => $module->address, 'colony' => $module->colony, @@ -103,6 +109,7 @@ public function store(ModuleStoreRequest $request) // Crear el módulo $module = Module::create([ 'name' => $request->input('name'), + 'responsible_id' => $request->input('responsible_id'), 'municipality' => $request->input('municipality'), 'address' => $request->input('address'), 'colony' => $request->input('colony'), @@ -120,6 +127,7 @@ public function store(ModuleStoreRequest $request) 'id' => $module->id, 'name' => $module->name, 'municipality' => $module->municipality, + 'responsible_id' => $module->responsible_id, 'address' => $module->address, 'colony' => $module->colony, 'cp' => $module->cp, @@ -158,6 +166,7 @@ public function update(ModuleUpdateRequest $request, int $id) // Actualizar solo los campos que vienen en el request $module->update($request->only([ 'name', + 'responsible_id', 'municipality', 'address', 'colony', @@ -174,6 +183,7 @@ public function update(ModuleUpdateRequest $request, int $id) 'module' => [ 'id' => $module->id, 'name' => $module->name, + 'responsible_id' => $module->responsible_id, 'municipality' => $module->municipality, 'address' => $module->address, 'colony' => $module->colony, @@ -252,4 +262,57 @@ public function toggleStatus(int $id) ]); } } + + public function getAvailableUsers() + { + try { + $users = User::select('id', 'name', 'paternal', 'maternal', 'email') + ->orderBy('name') + ->get(); + + return ApiResponse::OK->response([ + 'users' => $users->map(function ($user) { + return [ + 'id' => $user->id, + 'name' => $user->full_name, + 'email' => $user->email, + ]; + }), + ]); + + } catch (\Exception $e) { + Log::error('Error al obtener usuarios: ' . $e->getMessage()); + + return ApiResponse::INTERNAL_ERROR->response([ + 'message' => 'Error al obtener lista de usuarios', + 'error' => $e->getMessage(), + ]); + } + } + + /** + * Obtener lista simplificada de módulos para dropdown + */ + public function listForDropdown() + { + try { + $modules = Module::where('status', true) // Solo activos + ->orderBy('name') + ->get(['id', 'name', 'municipality']); + + return ApiResponse::OK->response([ + 'modules' => $modules->map(fn($m) => [ + 'id' => $m->id, + 'name' => $m->name, + 'municipality' => $m->municipality, + 'label' => "{$m->name} - {$m->municipality}", // Para mostrar en dropdown + ]), + ]); + + } catch (\Exception $e) { + return ApiResponse::INTERNAL_ERROR->response([ + 'message' => 'Error al obtener módulos', + ]); + } + } } diff --git a/app/Models/Module.php b/app/Models/Module.php index fbd9292..560aaa2 100644 --- a/app/Models/Module.php +++ b/app/Models/Module.php @@ -11,6 +11,7 @@ class Module extends Model protected $fillable = [ 'name', + 'responsible_id', 'municipality', 'address', 'colony', @@ -53,4 +54,9 @@ public function packages() { return $this->hasMany(Package::class); } + + public function responsible() + { + return $this->belongsTo(User::class, 'responsible_id'); + } } diff --git a/app/Models/User.php b/app/Models/User.php index 9cdaf9d..3653914 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -19,9 +19,9 @@ /** * Modelo de usuario - * + * * @author Moisés Cortés C. - * + * * @version 1.0.0 */ #[ObservedBy([UserObserver::class])] @@ -46,6 +46,7 @@ class User extends Authenticatable 'phone', 'password', 'profile_photo_path', + 'module_id' ]; /** @@ -127,4 +128,9 @@ public function resetPasswords() { return $this->hasMany(ResetPassword::class); } + + public function module() + { + return $this->belongsTo(Module::class); + } } diff --git a/database/migrations/2025_10_22_215552_add_responsible_id_to_modules_table.php b/database/migrations/2025_10_22_215552_add_responsible_id_to_modules_table.php new file mode 100644 index 0000000..2646489 --- /dev/null +++ b/database/migrations/2025_10_22_215552_add_responsible_id_to_modules_table.php @@ -0,0 +1,33 @@ +foreignId('responsible_id') + ->nullable() + ->after('name') + ->constrained('users') + ->nullOnDelete(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('modules', function (Blueprint $table) { + $table->dropForeign(['responsible_id']); + $table->dropColumn('responsible_id'); + }); + } +}; diff --git a/database/migrations/2025_10_22_224432_add_module_id_to_users_table.php b/database/migrations/2025_10_22_224432_add_module_id_to_users_table.php new file mode 100644 index 0000000..728c7dd --- /dev/null +++ b/database/migrations/2025_10_22_224432_add_module_id_to_users_table.php @@ -0,0 +1,32 @@ +foreignId('module_id') + ->nullable() + ->after('email') + ->constrained('modules') + ->nullOnDelete(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + // + }); + } +}; diff --git a/routes/api.php b/routes/api.php index b759837..999cd59 100644 --- a/routes/api.php +++ b/routes/api.php @@ -5,6 +5,7 @@ use App\Http\Controllers\Repuve\CancellationController; use App\Http\Controllers\Repuve\InscriptionController; use App\Http\Controllers\Repuve\UpdateController; +use App\Http\Controllers\Admin\RoleController; /** * Rutas del núcleo de la aplicación. @@ -43,6 +44,13 @@ Route::post('/moduleCreate', [ModuleController::class, 'store']); Route::put('/moduleUpdate/{id}', [ModuleController::class, 'update']); Route::patch('/moduleStatus/{id}', [ModuleController::class, 'toggleStatus']); + Route::get('/moduleUsers', [ModuleController::class, 'getAvailableUsers']); + + //Ruta para listar modulos para usuarios + Route::get('/modulesDropdown', [ModuleController::class, 'listForDropdown']); + + // Rutas de roles, mostrar roles para asignar a usuarios + Route::get('/admin/roles-all', [RoleController::class, 'listAll']); }); /** Rutas públicas */