diff --git a/civicfix/core/__pycache__/models.cpython-313.pyc b/civicfix/core/__pycache__/models.cpython-313.pyc index df7f7df..10f13c8 100644 Binary files a/civicfix/core/__pycache__/models.cpython-313.pyc and b/civicfix/core/__pycache__/models.cpython-313.pyc differ diff --git a/civicfix/core/__pycache__/views.cpython-313.pyc b/civicfix/core/__pycache__/views.cpython-313.pyc index 348638f..bbaf288 100644 Binary files a/civicfix/core/__pycache__/views.cpython-313.pyc and b/civicfix/core/__pycache__/views.cpython-313.pyc differ diff --git a/civicfix/core/migrations/0006_remove_department_users_department_admin.py b/civicfix/core/migrations/0006_remove_department_users_department_admin.py new file mode 100644 index 0000000..90852f5 --- /dev/null +++ b/civicfix/core/migrations/0006_remove_department_users_department_admin.py @@ -0,0 +1,24 @@ +# Generated by Django 5.2.5 on 2025-08-25 07:20 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0005_department_users'), + ] + + operations = [ + migrations.RemoveField( + model_name='department', + name='users', + ), + migrations.AddField( + model_name='department', + name='admin', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='admin_of_department', to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/civicfix/core/migrations/0007_department_users.py b/civicfix/core/migrations/0007_department_users.py new file mode 100644 index 0000000..30a4b8f --- /dev/null +++ b/civicfix/core/migrations/0007_department_users.py @@ -0,0 +1,19 @@ +# Generated by Django 5.2.5 on 2025-08-25 07:24 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0006_remove_department_users_department_admin'), + ] + + operations = [ + migrations.AddField( + model_name='department', + name='users', + field=models.ManyToManyField(blank=True, related_name='departments', to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/civicfix/core/migrations/__pycache__/0006_remove_department_users_department_admin.cpython-313.pyc b/civicfix/core/migrations/__pycache__/0006_remove_department_users_department_admin.cpython-313.pyc new file mode 100644 index 0000000..61da016 Binary files /dev/null and b/civicfix/core/migrations/__pycache__/0006_remove_department_users_department_admin.cpython-313.pyc differ diff --git a/civicfix/core/migrations/__pycache__/0007_department_users.cpython-313.pyc b/civicfix/core/migrations/__pycache__/0007_department_users.cpython-313.pyc new file mode 100644 index 0000000..aae0a5d Binary files /dev/null and b/civicfix/core/migrations/__pycache__/0007_department_users.cpython-313.pyc differ diff --git a/civicfix/core/models.py b/civicfix/core/models.py index ecaa146..de722af 100644 --- a/civicfix/core/models.py +++ b/civicfix/core/models.py @@ -1,5 +1,6 @@ from django.contrib.auth.models import AbstractUser from django.core.validators import FileExtensionValidator +from django.conf import settings from django.db import models class User(AbstractUser): @@ -98,15 +99,24 @@ class Department(models.Model): description = models.TextField(blank=True, null=True) created_at = models.DateTimeField(auto_now_add=True) + # Each department can have many users users = models.ManyToManyField( - User, + settings.AUTH_USER_MODEL, related_name="departments", - blank=True, - limit_choices_to={'is_staff': True} + blank=True + ) + + # One admin per department + admin = models.OneToOneField( + settings.AUTH_USER_MODEL, + on_delete=models.SET_NULL, + related_name="admin_of_department", + null=True, + blank=True ) class Meta: ordering = ["name"] def __str__(self): - return self.name.name + return self.name \ No newline at end of file diff --git a/civicfix/core/templates/department/department_detail.html b/civicfix/core/templates/department/department_detail.html index be81bfd..a6f5211 100644 --- a/civicfix/core/templates/department/department_detail.html +++ b/civicfix/core/templates/department/department_detail.html @@ -8,12 +8,30 @@
+
Department Users
{% if users %} @@ -21,10 +39,24 @@

No users registered in this department yet.

{% endif %} + + {% if department.admin %} +
+ {% csrf_token %} + + +
+ {% endif %} +
+ +
Register New User for {{ department.name }}
{% csrf_token %} +
diff --git a/civicfix/core/views.py b/civicfix/core/views.py index 86c0ad0..6a8ecac 100644 --- a/civicfix/core/views.py +++ b/civicfix/core/views.py @@ -3,6 +3,7 @@ from django.contrib.auth import authenticate, login from django.contrib.auth.decorators import login_required, user_passes_test from django.contrib.auth.forms import AuthenticationForm from django.contrib.auth.hashers import make_password +from django.db import IntegrityError from django.db.models import Exists, OuterRef from django.http import JsonResponse from django.shortcuts import render, redirect, get_object_or_404 @@ -196,15 +197,13 @@ def add_comment(request, pk, parent_id=None): return redirect("issue_detail", pk=pk) def superadmin_check(user): - return user.is_superuser - + return user.is_superuser @login_required @user_passes_test(superadmin_check) def superadmin_dashboard(request): return render(request, "dashboard/superadmin_dashboard.html") - @login_required @user_passes_test(superadmin_check) def manage_departments(request): @@ -228,19 +227,41 @@ def department_detail(request, pk): users = department.users.all() if request.method == "POST": - username = request.POST.get("username") - email = request.POST.get("email") - password = request.POST.get("password") + # ---- Create user ---- + if "create_user" in request.POST: + username = request.POST.get("username", "").strip() + email = request.POST.get("email", "").strip() + password = request.POST.get("password", "").strip() + if username and password: + try: + user = User.objects.create_user( + username=username, + email=email, + password=password + ) + user.is_staff = True + user.save() + department.users.add(user) + messages.success(request, f"User '{username}' created and added to department.") + except IntegrityError: + messages.error(request, "Username already exists.") - if username and password: - user = User.objects.create( - username=username, - email=email, - password=make_password(password), # hash the password - is_staff=True # mark as staff - ) - department.users.add(user) - return redirect("department_detail", pk=department.id) + # ---- Assign admin ---- + elif "assign_admin" in request.POST: + user_id = request.POST.get("admin_user_id") + if user_id: + user = get_object_or_404(User, id=user_id) + department.admin = user + department.save() + messages.success(request, f"{user.username} is now the admin of {department.name}.") + + # ---- Remove admin ---- + elif "remove_admin" in request.POST: + department.admin = None + department.save() + messages.info(request, "Department admin removed.") + + return redirect("department_detail", pk=department.id) return render(request, "department/department_detail.html", { "department": department,