refactor(src): replace hardcoded role checks with is_admin attribute

Simplify permission logic by using the unified `is_admin` flag instead of duplicated role list checks.
This commit is contained in:
sankalp committed 2026-06-28 19:16:54 +05:45
1 parent 5db8cfc63e
commit 6a343efc0a
18 files changed
+269 -123

No files matched your search

+98 -34
View File
@@ -184,40 +184,49 @@ class Command(BaseCommand):
# ── Demo Users ─────────────────────────────────────────────────────── # ── Demo Users ───────────────────────────────────────────────────────
users = [] users = []
for i in range(1, 10): dev_roles = [
"backend_developer",
"frontend_developer",
"ui_ux_designer",
"qa",
"tester",
"devops",
"data_analyst",
"product_owner",
"scrum_master",
]
for role_name in dev_roles:
user, _ = User.objects.get_or_create( user, _ = User.objects.get_or_create(
username=f"user{i}", username=role_name,
defaults={ defaults={
"email": f"user{i}@mail.com", "email": f"{role_name}@mail.com",
"first_name": f"Developer{i}", "first_name": role_name.replace("_", " ").title(),
"last_name": "User", "last_name": "User",
"role": "member", "role": role_name,
}, },
) )
user.set_password("user123") user.set_password("user123")
if user.role != "member": if user.role != role_name:
user.role = "member" user.role = role_name
user.save() user.save()
users.append(user) users.append(user)
# Additional specific roles # Manager user
roles = ["Manager", "Designer", "Tester", "DevOps"] manager_role = "manager"
for r_name in roles: user, _ = User.objects.get_or_create(
u_role = "manager" if r_name == "Manager" else "member" username="manager",
user, _ = User.objects.get_or_create( defaults={
username=r_name.lower(), "email": "manager@mail.com",
defaults={ "first_name": "Manager",
"email": f"{r_name.lower()}@mail.com", "last_name": "Staff",
"first_name": r_name, "role": manager_role,
"last_name": "Staff", },
"role": u_role, )
}, user.set_password("user123")
) if user.role != manager_role:
user.set_password("user123") user.role = manager_role
if user.role != u_role: user.save()
user.role = u_role users.append(user)
user.save()
users.append(user)
all_users = [admin] + users all_users = [admin] + users
self.stdout.write(f" ✓ {len(all_users)} users ready") self.stdout.write(f" ✓ {len(all_users)} users ready")
@@ -256,6 +265,14 @@ class Command(BaseCommand):
"Shopping Cart", "Shopping Cart",
"Payment Gateway", "Payment Gateway",
], ],
"statuses": [
("Backlog", "#6B7280", False),
("Todo", "#3B82F6", False),
("In Progress", "#F59E0B", False),
("In Review", "#8B5CF6", False),
("Staging", "#06B6D4", False),
("Done", "#10B981", True),
],
}, },
{ {
"name": "Org Website", "name": "Org Website",
@@ -268,6 +285,14 @@ class Command(BaseCommand):
"Services Section", "Services Section",
"Contact & Forms", "Contact & Forms",
], ],
"statuses": [
("Draft", "#6B7280", False),
("Copy Review", "#3B82F6", False),
("Design Review", "#8B5CF6", False),
("Development", "#F59E0B", False),
("Client Review", "#EC4899", False),
("Published", "#10B981", True),
],
}, },
{ {
"name": "Health Homeservice Website", "name": "Health Homeservice Website",
@@ -280,6 +305,14 @@ class Command(BaseCommand):
"Booking System", "Booking System",
"Telehealth Video", "Telehealth Video",
], ],
"statuses": [
("Registration", "#6B7280", False),
("Triage", "#3B82F6", False),
("Provider Assigned", "#F59E0B", False),
("In Service", "#8B5CF6", False),
("Follow-up", "#EC4899", False),
("Completed", "#10B981", True),
],
}, },
{ {
"name": "Consultancy Website", "name": "Consultancy Website",
@@ -292,6 +325,14 @@ class Command(BaseCommand):
"Scheduling Integration", "Scheduling Integration",
"Client Testimonials", "Client Testimonials",
], ],
"statuses": [
("Lead", "#6B7280", False),
("Discovery", "#3B82F6", False),
("Proposal", "#F59E0B", False),
("Negotiation", "#EC4899", False),
("Active", "#8B5CF6", False),
("Closed", "#10B981", True),
],
}, },
{ {
"name": "School Website with Student Management", "name": "School Website with Student Management",
@@ -304,6 +345,13 @@ class Command(BaseCommand):
"Grading & Attendance", "Grading & Attendance",
"Public Admissions Page", "Public Admissions Page",
], ],
"statuses": [
("Enrollment", "#6B7280", False),
("Records Pending", "#3B82F6", False),
("Active", "#10B981", False),
("Graduating", "#F59E0B", False),
("Alumni", "#8B5CF6", True),
],
}, },
{ {
"name": "Human Resource Management Website", "name": "Human Resource Management Website",
@@ -316,6 +364,14 @@ class Command(BaseCommand):
"Leave Management", "Leave Management",
"Performance Reviews", "Performance Reviews",
], ],
"statuses": [
("Application", "#6B7280", False),
("Screening", "#3B82F6", False),
("Interview", "#F59E0B", False),
("Onboarding", "#8B5CF6", False),
("Active", "#10B981", False),
("Offboarding", "#EF4444", True),
],
}, },
{ {
"name": "Staff Location Tracking Application", "name": "Staff Location Tracking Application",
@@ -328,6 +384,14 @@ class Command(BaseCommand):
"Mobile App Core", "Mobile App Core",
"Reporting & Analytics", "Reporting & Analytics",
], ],
"statuses": [
("Logged", "#6B7280", False),
("Dispatched", "#3B82F6", False),
("En Route", "#F59E0B", False),
("On Site", "#8B5CF6", False),
("Returning", "#06B6D4", False),
("Completed", "#10B981", True),
],
}, },
{ {
"name": "Ecommerce App", "name": "Ecommerce App",
@@ -340,6 +404,14 @@ class Command(BaseCommand):
"Push Notifications", "Push Notifications",
"Mobile Checkout", "Mobile Checkout",
], ],
"statuses": [
("Backlog", "#6B7280", False),
("Design", "#8B5CF6", False),
("Development", "#F59E0B", False),
("QA", "#EC4899", False),
("Beta Review", "#06B6D4", False),
("Published", "#10B981", True),
],
}, },
] ]
@@ -378,15 +450,7 @@ class Command(BaseCommand):
# ── Statuses ──────────────────────────────────────────────────── # ── Statuses ────────────────────────────────────────────────────
statuses = [] statuses = []
for i, (name, color, completed) in enumerate( for i, (name, color, completed) in enumerate(pd["statuses"]):
[
("Backlog", "#6B7280", False),
("Todo", "#3B82F6", False),
("In Progress", "#F59E0B", False),
("In Review", "#8B5CF6", False),
("Done", "#10B981", True),
]
):
st, _ = TicketStatus.objects.get_or_create( st, _ = TicketStatus.objects.get_or_create(
project=proj, project=proj,
name=name, name=name,
@@ -49,3 +49,21 @@ class Command(BaseCommand):
admin.role = "superadmin" admin.role = "superadmin"
admin.save() admin.save()
self.stdout.write(" -> superuser 'admin' already exists (role verified)") self.stdout.write(" -> superuser 'admin' already exists (role verified)")
if not User.objects.filter(username="manager").exists():
mgr = User.objects.create_user(
username="manager",
email="manager@dewakoding.com",
password="admin123",
first_name="Project",
last_name="Manager",
)
mgr.role = "manager"
mgr.save()
self.stdout.write(" -> manager created: manager / admin123")
else:
mgr = User.objects.get(username="manager")
if mgr.role != "manager":
mgr.role = "manager"
mgr.save()
self.stdout.write(" -> manager 'manager' already exists (role verified)")
+34 -3
View File
@@ -1,15 +1,46 @@
from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import AbstractUser
from django.db import models from django.db import models
ADMIN_ROLES = ("superadmin", "manager")
DEVELOPER_ROLES = (
"backend_developer",
"frontend_developer",
"ui_ux_designer",
"qa",
"tester",
"devops",
"data_analyst",
"product_owner",
"scrum_master",
)
class User(AbstractUser): class User(AbstractUser):
ROLE_CHOICES = ( ROLE_CHOICES = (
("superadmin", "Superadmin"), ("superadmin", "Superadmin"),
("manager", "Manager"), ("manager", "Manager"),
("member", "Member"), ("backend_developer", "Backend Developer"),
("guest", "Guest"), ("frontend_developer", "Frontend Developer"),
("ui_ux_designer", "UI/UX Designer"),
("qa", "QA"),
("tester", "Tester"),
("devops", "DevOps"),
("data_analyst", "Data Analyst"),
("product_owner", "Product Owner"),
("scrum_master", "Scrum Master"),
) )
role = models.CharField(max_length=20, choices=ROLE_CHOICES, default="member") role = models.CharField(
max_length=30, choices=ROLE_CHOICES, default="backend_developer"
)
@property
def is_admin(self):
return self.role in ADMIN_ROLES
@property
def is_developer(self):
return not self.is_admin
google_id = models.CharField(max_length=255, blank=True, null=True, unique=True) google_id = models.CharField(max_length=255, blank=True, null=True, unique=True)
profile_image = models.ImageField(upload_to="profiles/", blank=True, null=True) profile_image = models.ImageField(upload_to="profiles/", blank=True, null=True)
receive_deadline_emails = models.BooleanField( receive_deadline_emails = models.BooleanField(
+10 -3
View File
@@ -18,9 +18,6 @@ from src.tickets.models import (
User = get_user_model() User = get_user_model()
DEFAULT_STATUS_NAMES = ["Backlog", "Todo", "In Progress", "In Review", "Done"]
DEFAULT_STATUS_COLORS = ["#6B7280", "#3B82F6", "#F59E0B", "#8B5CF6", "#10B981"]
@require_http_methods(["POST"]) @require_http_methods(["POST"])
def board_create_ticket(request, project_id): def board_create_ticket(request, project_id):
@@ -101,6 +98,16 @@ def move_ticket(request, project_id, ticket_id):
) )
status = get_object_or_404(TicketStatus, pk=status_id, project_id=project_id) status = get_object_or_404(TicketStatus, pk=status_id, project_id=project_id)
if not request.user.is_admin and status.is_completed:
return JsonResponse(
{
"success": False,
"error": "Members cannot move tickets to completed statuses.",
},
status=403,
)
ticket.status = status ticket.status = status
ticket.save(update_fields=["status", "updated_at"]) ticket.save(update_fields=["status", "updated_at"])
+9 -27
View File
@@ -16,33 +16,10 @@ from src.tickets.models import (
User = get_user_model() User = get_user_model()
DEFAULT_STATUS_NAMES = ["Backlog", "Todo", "In Progress", "In Review", "Done"]
DEFAULT_STATUS_COLORS = ["#6B7280", "#3B82F6", "#F59E0B", "#8B5CF6", "#10B981"]
def _ensure_default_statuses(project):
# Auto-migrate legacy 'Review' to 'In Review' if it exists
review_status = TicketStatus.objects.filter(project=project, name="Review").first()
if review_status:
in_review_status, created = TicketStatus.objects.get_or_create(
project=project,
name="In Review",
defaults={"color": "#8B5CF6", "sort_order": 3},
)
Ticket.objects.filter(status=review_status).update(status=in_review_status)
review_status.delete()
for i, name in enumerate(DEFAULT_STATUS_NAMES):
TicketStatus.objects.get_or_create(
project=project,
name=name,
defaults={"color": DEFAULT_STATUS_COLORS[i], "sort_order": i},
)
def project_board(request, project_id=None): def project_board(request, project_id=None):
projects = Project.objects.all() projects = Project.objects.all()
if request.user.role == "member": if not request.user.is_admin:
projects = projects.filter(members=request.user) projects = projects.filter(members=request.user)
projects = projects.annotate( projects = projects.annotate(
member_count=Count("members", distinct=True), member_count=Count("members", distinct=True),
@@ -68,7 +45,6 @@ def project_board(request, project_id=None):
), ),
pk=project_id, pk=project_id,
) )
_ensure_default_statuses(selected_project)
project_members = selected_project.project_members.select_related("user").all() project_members = selected_project.project_members.select_related("user").all()
statuses = TicketStatus.objects.filter(project=selected_project).order_by( statuses = TicketStatus.objects.filter(project=selected_project).order_by(
"sort_order" "sort_order"
@@ -120,10 +96,12 @@ def project_board(request, project_id=None):
} }
) )
can_move = request.user.role in ["superadmin", "manager"] or ( is_admin = request.user.is_admin
can_move = is_admin or (
selected_project selected_project
and selected_project.members.filter(id=request.user.id).exists() and selected_project.members.filter(id=request.user.id).exists()
) )
can_move_to_completed = is_admin
priorities = TicketPriority.objects.all() priorities = TicketPriority.objects.all()
epics = Epic.objects.filter(project=selected_project) if selected_project else [] epics = Epic.objects.filter(project=selected_project) if selected_project else []
@@ -174,12 +152,14 @@ def project_board(request, project_id=None):
"selected_project_id": project_id, "selected_project_id": project_id,
"selected_project": selected_project, "selected_project": selected_project,
"project_members": project_members, "project_members": project_members,
"is_admin": is_admin,
"columns": columns, "columns": columns,
"priorities": priorities, "priorities": priorities,
"epics": epics, "epics": epics,
"sort": sort, "sort": sort,
"search": search, "search": search,
"can_move": can_move, "can_move": can_move,
"can_move_to_completed": can_move_to_completed,
"today": date.today(), "today": date.today(),
"project_users": project_users, "project_users": project_users,
"project_users_json": json.dumps(project_users), "project_users_json": json.dumps(project_users),
@@ -200,7 +180,6 @@ def project_board(request, project_id=None):
@require_http_methods(["GET"]) @require_http_methods(["GET"])
def board_data(request, project_id): def board_data(request, project_id):
project = get_object_or_404(Project, pk=project_id) project = get_object_or_404(Project, pk=project_id)
_ensure_default_statuses(project)
statuses = TicketStatus.objects.filter(project=project).order_by("sort_order") statuses = TicketStatus.objects.filter(project=project).order_by("sort_order")
tickets = ( tickets = (
Ticket.objects.filter(project=project) Ticket.objects.filter(project=project)
@@ -236,6 +215,8 @@ def board_data(request, project_id):
priorities = TicketPriority.objects.all() priorities = TicketPriority.objects.all()
epics = Epic.objects.filter(project=project) epics = Epic.objects.filter(project=project)
user_can_move_to_completed = request.user.is_admin
return render( return render(
request, request,
"projects/partials/board_columns.html", "projects/partials/board_columns.html",
@@ -246,5 +227,6 @@ def board_data(request, project_id):
"epics": epics, "epics": epics,
"sort": sort, "sort": sort,
"today": date.today(), "today": date.today(),
"user_can_move_to_completed": user_can_move_to_completed,
}, },
) )
-3
View File
@@ -14,9 +14,6 @@ from src.tickets.models import (
User = get_user_model() User = get_user_model()
DEFAULT_STATUS_NAMES = ["Backlog", "Todo", "In Progress", "In Review", "Done"]
DEFAULT_STATUS_COLORS = ["#6B7280", "#3B82F6", "#F59E0B", "#8B5CF6", "#10B981"]
@require_http_methods(["POST"]) @require_http_methods(["POST"])
def export_board_tickets(request, project_id): def export_board_tickets(request, project_id):
+1 -1
View File
@@ -30,7 +30,7 @@ def site_stats(request):
User = get_user_model() User = get_user_model()
total_users = User.objects.filter(is_active=True).count() total_users = User.objects.filter(is_active=True).count()
if request.user.is_authenticated and request.user.role == "member": if request.user.is_authenticated and not request.user.is_admin:
total_tickets = Ticket.objects.filter(assignees=request.user).count() total_tickets = Ticket.objects.filter(assignees=request.user).count()
else: else:
total_tickets = Ticket.objects.count() total_tickets = Ticket.objects.count()
+1 -1
View File
@@ -77,7 +77,7 @@ def projects_list(request):
) )
projects = Project.objects.annotate() projects = Project.objects.annotate()
if request.user.role == "member": if not request.user.is_admin:
projects = projects.filter(members=request.user) projects = projects.filter(members=request.user)
projects = projects.annotate( projects = projects.annotate(
member_count=Count("members", distinct=True), member_count=Count("members", distinct=True),
+1 -1
View File
@@ -81,7 +81,7 @@ def tickets_list(request):
"status", "priority", "project", "created_by", "epic" "status", "priority", "project", "created_by", "epic"
).prefetch_related("assignees") ).prefetch_related("assignees")
if request.user.role == "member": if not request.user.is_admin:
tickets = tickets.filter(assignees=request.user) tickets = tickets.filter(assignees=request.user)
# Search across name, uuid, project name, assignee name, creator name, epic name # Search across name, uuid, project name, assignee name, creator name, epic name
+2 -2
View File
@@ -141,7 +141,7 @@ def epic_delete(request, epic_id):
def epics_overview(request, project_id=None): def epics_overview(request, project_id=None):
projects = Project.objects.all() projects = Project.objects.all()
if request.user.role == "member": if not request.user.is_admin:
projects = projects.filter(members=request.user) projects = projects.filter(members=request.user)
projects = projects.annotate( projects = projects.annotate(
ticket_count=Count("tickets"), ticket_count=Count("tickets"),
@@ -154,7 +154,7 @@ def epics_overview(request, project_id=None):
if project_id: if project_id:
selected_project = get_object_or_404(Project, pk=project_id) selected_project = get_object_or_404(Project, pk=project_id)
if ( if (
request.user.role == "member" not request.user.is_admin
and not selected_project.members.filter(id=request.user.id).exists() and not selected_project.members.filter(id=request.user.id).exists()
): ):
from django.contrib import messages from django.contrib import messages
+3 -3
View File
@@ -283,7 +283,7 @@ def ticket_priorities(request):
@require_http_methods(["POST"]) @require_http_methods(["POST"])
def ticket_priority_add(request): def ticket_priority_add(request):
if request.user.role == "member": if not request.user.is_admin:
messages.error(request, "Permission denied.") messages.error(request, "Permission denied.")
return redirect("ticket-priorities") return redirect("ticket-priorities")
name = request.POST.get("name", "").strip() name = request.POST.get("name", "").strip()
@@ -298,7 +298,7 @@ def ticket_priority_add(request):
@require_http_methods(["POST"]) @require_http_methods(["POST"])
def ticket_priority_edit(request, priority_id): def ticket_priority_edit(request, priority_id):
if request.user.role == "member": if not request.user.is_admin:
messages.error(request, "Permission denied.") messages.error(request, "Permission denied.")
return redirect("ticket-priorities") return redirect("ticket-priorities")
priority = get_object_or_404(TicketPriority, pk=priority_id) priority = get_object_or_404(TicketPriority, pk=priority_id)
@@ -316,7 +316,7 @@ def ticket_priority_edit(request, priority_id):
@require_http_methods(["POST"]) @require_http_methods(["POST"])
def ticket_priority_delete(request, priority_id): def ticket_priority_delete(request, priority_id):
if request.user.role == "member": if not request.user.is_admin:
messages.error(request, "Permission denied.") messages.error(request, "Permission denied.")
return redirect("ticket-priorities") return redirect("ticket-priorities")
priority = get_object_or_404(TicketPriority, pk=priority_id) priority = get_object_or_404(TicketPriority, pk=priority_id)
+4 -21
View File
@@ -16,7 +16,6 @@ from src.projects.models import Project, ProjectMember
from src.tickets.models import ( from src.tickets.models import (
Ticket, Ticket,
TicketPriority, TicketPriority,
TicketStatus,
) )
User = get_user_model() User = get_user_model()
@@ -48,7 +47,7 @@ COLOR_PALETTE = [
@require_http_methods(["GET", "POST"]) @require_http_methods(["GET", "POST"])
def project_create(request): def project_create(request):
if request.user.role == "member": if not request.user.is_admin:
from django.contrib import messages from django.contrib import messages
from django.shortcuts import redirect from django.shortcuts import redirect
@@ -88,23 +87,6 @@ def project_create(request):
except User.DoesNotExist: except User.DoesNotExist:
pass pass
if request.POST.get("use_default_statuses") == "1":
default_statuses = ["Backlog", "Todo", "In Progress", "In Review", "Done"]
for i, sname in enumerate(default_statuses):
TicketStatus.objects.create(
project=project,
name=sname,
sort_order=i,
is_completed=(sname == "Done"),
color={
"Backlog": "#6B7280",
"Todo": "#3B82F6",
"In Progress": "#F59E0B",
"In Review": "#8B5CF6",
"Done": "#10B981",
}.get(sname, "#6B7280"),
)
messages.success(request, f"Project '{project.name}' created successfully.") messages.success(request, f"Project '{project.name}' created successfully.")
if request.POST.get("create_another") == "1": if request.POST.get("create_another") == "1":
@@ -308,6 +290,7 @@ def project_detail(request, project_id):
"pinned_display": pinned_display, "pinned_display": pinned_display,
"today": today, "today": today,
"external_access": external_access, "external_access": external_access,
"is_admin": request.user.is_admin,
}, },
) )
@@ -498,7 +481,7 @@ def project_edit(request, project_id):
@require_http_methods(["POST"]) @require_http_methods(["POST"])
def project_delete(request, project_id): def project_delete(request, project_id):
if request.user.role == "member": if not request.user.is_admin:
from django.contrib import messages from django.contrib import messages
from django.shortcuts import redirect from django.shortcuts import redirect
@@ -529,7 +512,7 @@ def project_timeline(request):
projects_qs = Project.objects.filter( projects_qs = Project.objects.filter(
start_date__isnull=False, end_date__isnull=False start_date__isnull=False, end_date__isnull=False
) )
if request.user.role == "member": if not request.user.is_admin:
projects_qs = projects_qs.filter(members=request.user) projects_qs = projects_qs.filter(members=request.user)
projects_qs = projects_qs.order_by("start_date") projects_qs = projects_qs.order_by("start_date")
+2 -2
View File
@@ -52,7 +52,7 @@ COLOR_PALETTE = [
def ticket_timeline(request, project_id=None): def ticket_timeline(request, project_id=None):
projects = Project.objects.all() projects = Project.objects.all()
if request.user.role == "member": if not request.user.is_admin:
projects = projects.filter(members=request.user) projects = projects.filter(members=request.user)
projects = projects.annotate( projects = projects.annotate(
ticket_count=Count("tickets"), ticket_count=Count("tickets"),
@@ -482,7 +482,7 @@ def tickets_export(request):
tickets = Ticket.objects.select_related( tickets = Ticket.objects.select_related(
"project", "status", "priority", "created_by", "epic" "project", "status", "priority", "created_by", "epic"
) )
if request.user.role == "member": if not request.user.is_admin:
tickets = tickets.filter(assignees=request.user) tickets = tickets.filter(assignees=request.user)
tickets = ( tickets = (
tickets.select_related("status", "priority", "project", "created_by", "epic") tickets.select_related("status", "priority", "project", "created_by", "epic")
+77 -13
View File
@@ -107,12 +107,31 @@ def users_list(request):
"has_created": has_created, "has_created": has_created,
"role": role, "role": role,
"unverified": unverified, "unverified": unverified,
"roles": ["superadmin", "manager", "member", "guest"], "roles": [
"superadmin",
"manager",
"backend_developer",
"frontend_developer",
"ui_ux_designer",
"qa",
"tester",
"devops",
"data_analyst",
"product_owner",
"scrum_master",
],
"roles_label": { "roles_label": {
"superadmin": "Superadmin", "superadmin": "Superadmin",
"manager": "Manager", "manager": "Manager",
"member": "Member", "backend_developer": "Backend Developer",
"guest": "Guest", "frontend_developer": "Frontend Developer",
"ui_ux_designer": "UI/UX Designer",
"qa": "QA",
"tester": "Tester",
"devops": "DevOps",
"data_analyst": "Data Analyst",
"product_owner": "Product Owner",
"scrum_master": "Scrum Master",
}, },
"per_page": per_page, "per_page": per_page,
"columns": columns, "columns": columns,
@@ -157,7 +176,7 @@ def user_create(request):
user = form.save() user = form.save()
user.is_active = True user.is_active = True
if request.user.role == "superadmin": if request.user.role == "superadmin":
role = request.POST.get("role", "member") role = request.POST.get("role", "backend_developer")
user.role = role user.role = role
user.save() user.save()
messages.success( messages.success(
@@ -173,12 +192,31 @@ def user_create(request):
"users/form.html", "users/form.html",
{ {
"form": form, "form": form,
"roles": ["superadmin", "manager", "member", "guest"], "roles": [
"superadmin",
"manager",
"backend_developer",
"frontend_developer",
"ui_ux_designer",
"qa",
"tester",
"devops",
"data_analyst",
"product_owner",
"scrum_master",
],
"roles_label": { "roles_label": {
"superadmin": "Superadmin", "superadmin": "Superadmin",
"manager": "Manager", "manager": "Manager",
"member": "Member", "backend_developer": "Backend Developer",
"guest": "Guest", "frontend_developer": "Frontend Developer",
"ui_ux_designer": "UI/UX Designer",
"qa": "QA",
"tester": "Tester",
"devops": "DevOps",
"data_analyst": "Data Analyst",
"product_owner": "Product Owner",
"scrum_master": "Scrum Master",
}, },
"can_change_role": request.user.role == "superadmin", "can_change_role": request.user.role == "superadmin",
}, },
@@ -204,8 +242,15 @@ def user_detail(request, user_id):
"roles_label": { "roles_label": {
"superadmin": "Superadmin", "superadmin": "Superadmin",
"manager": "Manager", "manager": "Manager",
"member": "Member", "backend_developer": "Backend Developer",
"guest": "Guest", "frontend_developer": "Frontend Developer",
"ui_ux_designer": "UI/UX Designer",
"qa": "QA",
"tester": "Tester",
"devops": "DevOps",
"data_analyst": "Data Analyst",
"product_owner": "Product Owner",
"scrum_master": "Scrum Master",
}, },
"projects_count": project_count, "projects_count": project_count,
"assigned_count": assigned_count, "assigned_count": assigned_count,
@@ -254,7 +299,7 @@ def user_edit(request, user_id):
if form.is_valid(): if form.is_valid():
user_obj = form.save() user_obj = form.save()
if request.user.role == "superadmin": if request.user.role == "superadmin":
role = request.POST.get("role", "member") role = request.POST.get("role", "backend_developer")
user_obj.role = role user_obj.role = role
user_obj.save() user_obj.save()
messages.success( messages.success(
@@ -301,12 +346,31 @@ def user_edit(request, user_id):
"editing": True, "editing": True,
"user_obj": user_obj, "user_obj": user_obj,
"current_role": current_role, "current_role": current_role,
"roles": ["superadmin", "manager", "member", "guest"], "roles": [
"superadmin",
"manager",
"backend_developer",
"frontend_developer",
"ui_ux_designer",
"qa",
"tester",
"devops",
"data_analyst",
"product_owner",
"scrum_master",
],
"roles_label": { "roles_label": {
"superadmin": "Superadmin", "superadmin": "Superadmin",
"manager": "Manager", "manager": "Manager",
"member": "Member", "backend_developer": "Backend Developer",
"guest": "Guest", "frontend_developer": "Frontend Developer",
"ui_ux_designer": "UI/UX Designer",
"qa": "QA",
"tester": "Tester",
"devops": "DevOps",
"data_analyst": "Data Analyst",
"product_owner": "Product Owner",
"scrum_master": "Scrum Master",
}, },
"can_change_role": request.user.role == "superadmin", "can_change_role": request.user.role == "superadmin",
"user_memberships": proj_page, "user_memberships": proj_page,
+2 -2
View File
@@ -13,7 +13,7 @@ User = get_user_model()
@require_http_methods(["GET"]) @require_http_methods(["GET"])
def recent_activity(request): def recent_activity(request):
user = request.user user = request.user
is_super = user.role in ["superadmin", "manager"] is_super = user.is_admin
qs = TicketHistory.objects.select_related( qs = TicketHistory.objects.select_related(
"ticket", "user", "status", "ticket__project" "ticket", "user", "status", "ticket__project"
@@ -37,7 +37,7 @@ def recent_activity(request):
@require_http_methods(["GET"]) @require_http_methods(["GET"])
def recent_activity_all(request): def recent_activity_all(request):
user = request.user user = request.user
is_super = user.role in ["superadmin", "manager"] is_super = user.is_admin
qs = TicketHistory.objects.select_related( qs = TicketHistory.objects.select_related(
"ticket", "user", "status", "ticket__project" "ticket", "user", "status", "ticket__project"
+3 -3
View File
@@ -17,7 +17,7 @@ User = get_user_model()
@require_http_methods(["GET"]) @require_http_methods(["GET"])
def tickets_per_project_chart(request): def tickets_per_project_chart(request):
user = request.user user = request.user
is_super = user.role in ["superadmin", "manager"] is_super = user.is_admin
qs = Project.objects.annotate(count=Count("tickets")).order_by("name") qs = Project.objects.annotate(count=Count("tickets")).order_by("name")
if not is_super: if not is_super:
@@ -53,7 +53,7 @@ def tickets_per_project_chart(request):
@require_http_methods(["GET"]) @require_http_methods(["GET"])
def user_statistics_data(request): def user_statistics_data(request):
user = request.user user = request.user
is_super = user.role in ["superadmin", "manager"] is_super = user.is_admin
users_qs = User.objects.annotate( users_qs = User.objects.annotate(
project_count=Count("projects", distinct=True), project_count=Count("projects", distinct=True),
@@ -80,7 +80,7 @@ def user_statistics_chart(request):
@require_http_methods(["GET"]) @require_http_methods(["GET"])
def monthly_trend_chart(request): def monthly_trend_chart(request):
user = request.user user = request.user
is_super = user.role in ["superadmin", "manager"] is_super = user.is_admin
earliest = Ticket.objects.all() earliest = Ticket.objects.all()
if not is_super: if not is_super:
+2 -2
View File
@@ -21,7 +21,7 @@ def dashboard(request):
days=now.weekday() days=now.weekday()
) )
is_super = user.role in ["superadmin", "manager"] is_super = user.is_admin
if is_super: if is_super:
total_projects = Project.objects.count() total_projects = Project.objects.count()
@@ -204,7 +204,7 @@ def stats_cards(request):
days=now.weekday() days=now.weekday()
) )
is_super = user.role in ["superadmin", "manager"] is_super = user.is_admin
if is_super: if is_super:
total_projects = Project.objects.count() total_projects = Project.objects.count()
+2 -2
View File
@@ -13,10 +13,10 @@ User = get_user_model()
def project_timeline_widget(request): def project_timeline_widget(request):
filter_type = request.GET.get("filter", "pinned") filter_type = request.GET.get("filter", "pinned")
user = request.user user = request.user
is_super = user.role in ["superadmin", "manager"] is_super = user.is_admin
qs = Project.objects.filter(start_date__isnull=False, end_date__isnull=False) qs = Project.objects.filter(start_date__isnull=False, end_date__isnull=False)
if request.user.role == "member": if not request.user.is_admin:
qs = qs.filter(members=request.user) qs = qs.filter(members=request.user)
if not is_super: if not is_super:
qs = qs.filter(members=user) qs = qs.filter(members=user)