- Dashboard: Outstanding Payments, Paid This Month, Active Loans cards - Dashboard: This Week summary, Recent Activity, Quick Actions, Manage Resources - Dashboard: Active/Inactive/All filter for resources - Payroll: Preview payslip modal (no DB/email side effects) - Payroll: Multi-select workers in adjustment modal - History: Team column + direct team FK on WorkLog - History: Shift+click multi-date selection on calendar - Permissions: Replaced PIN system with Django groups (Admin, Work Logger) - Permissions: Renamed Supervisor to Work Logger throughout - Nav: Hide financial links (Payroll) from non-admin users - Admin: Enhanced Django admin with group management - New migrations: 0011 (remove pin/is_admin), 0012 (add team to WorkLog) - New management command: setup_groups Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
102 lines
3.8 KiB
Python
102 lines
3.8 KiB
Python
from django.contrib import admin
|
|
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
|
from django.contrib.auth.models import User
|
|
from django.db import models
|
|
from .models import Worker, Project, Team, WorkLog, UserProfile
|
|
|
|
|
|
# Inline UserProfile on User admin
|
|
class UserProfileInline(admin.StackedInline):
|
|
model = UserProfile
|
|
can_delete = False
|
|
verbose_name_plural = 'Profile'
|
|
|
|
|
|
# Customise the User admin to show groups prominently
|
|
class UserAdmin(BaseUserAdmin):
|
|
inlines = [UserProfileInline]
|
|
list_display = ('username', 'first_name', 'last_name', 'is_staff', 'get_groups')
|
|
list_filter = ('is_staff', 'is_superuser', 'is_active', 'groups')
|
|
|
|
# Reorder fieldsets so Groups appears near the top
|
|
fieldsets = (
|
|
(None, {'fields': ('username', 'password')}),
|
|
('Personal info', {'fields': ('first_name', 'last_name', 'email')}),
|
|
('Role & Groups', {
|
|
'description': 'Assign user to "Admin" or "Work Logger" group to set permissions automatically.',
|
|
'fields': ('is_active', 'is_staff', 'groups'),
|
|
}),
|
|
('Individual Permissions', {
|
|
'classes': ('collapse',),
|
|
'description': 'Fine-tune permissions beyond what the group provides. Usually not needed.',
|
|
'fields': ('is_superuser', 'user_permissions'),
|
|
}),
|
|
('Important dates', {
|
|
'classes': ('collapse',),
|
|
'fields': ('last_login', 'date_joined'),
|
|
}),
|
|
)
|
|
|
|
def get_groups(self, obj):
|
|
return ', '.join(g.name for g in obj.groups.all()) or '-'
|
|
get_groups.short_description = 'Groups'
|
|
|
|
|
|
# Re-register User with our custom admin
|
|
admin.site.unregister(User)
|
|
admin.site.register(User, UserAdmin)
|
|
|
|
|
|
@admin.register(Worker)
|
|
class WorkerAdmin(admin.ModelAdmin):
|
|
list_display = ('name', 'id_no', 'phone_no', 'monthly_salary', 'date_of_employment', 'projects_worked_on_count')
|
|
search_fields = ('name', 'id_no')
|
|
readonly_fields = ('projects_worked_on_count',)
|
|
|
|
|
|
@admin.register(Project)
|
|
class ProjectAdmin(admin.ModelAdmin):
|
|
list_display = ('name', 'get_supervisors', 'is_active', 'created_at')
|
|
list_filter = ('is_active',)
|
|
filter_horizontal = ('supervisors',)
|
|
|
|
def get_supervisors(self, obj):
|
|
return ', '.join(u.username for u in obj.supervisors.all()) or '-'
|
|
get_supervisors.short_description = 'Supervisors'
|
|
|
|
def formfield_for_manytomany(self, db_field, request, **kwargs):
|
|
if db_field.name == 'supervisors':
|
|
# Only show users who are staff or in Work Logger/Admin group
|
|
kwargs['queryset'] = User.objects.filter(
|
|
models.Q(is_staff=True) |
|
|
models.Q(groups__name__in=['Admin', 'Work Logger'])
|
|
).distinct().order_by('username')
|
|
return super().formfield_for_manytomany(db_field, request, **kwargs)
|
|
|
|
|
|
@admin.register(Team)
|
|
class TeamAdmin(admin.ModelAdmin):
|
|
list_display = ('name', 'supervisor', 'worker_count', 'is_active', 'created_at')
|
|
list_filter = ('is_active', 'supervisor')
|
|
filter_horizontal = ('workers',)
|
|
|
|
def worker_count(self, obj):
|
|
return obj.workers.count()
|
|
worker_count.short_description = 'Workers'
|
|
|
|
def formfield_for_foreignkey(self, db_field, request, **kwargs):
|
|
if db_field.name == 'supervisor':
|
|
# Only show users who are staff or in Work Logger/Admin group
|
|
kwargs['queryset'] = User.objects.filter(
|
|
models.Q(is_staff=True) |
|
|
models.Q(groups__name__in=['Admin', 'Work Logger'])
|
|
).distinct().order_by('username')
|
|
return super().formfield_for_foreignkey(db_field, request, **kwargs)
|
|
|
|
|
|
@admin.register(WorkLog)
|
|
class WorkLogAdmin(admin.ModelAdmin):
|
|
list_display = ('date', 'project', 'supervisor')
|
|
list_filter = ('date', 'project', 'supervisor')
|
|
filter_horizontal = ('workers',)
|