diff --git a/core/admin.py b/core/admin.py index f92bff2..39d913d 100644 --- a/core/admin.py +++ b/core/admin.py @@ -18,7 +18,9 @@ class UserAdmin(BaseUserAdmin): 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 + def get_queryset(self, request): + return super().get_queryset(request).prefetch_related('groups') + fieldsets = ( (None, {'fields': ('username', 'password')}), ('Personal info', {'fields': ('first_name', 'last_name', 'email')}), @@ -63,6 +65,9 @@ class ProjectAdmin(admin.ModelAdmin): list_filter = ('is_active',) filter_horizontal = ('supervisors',) + def get_queryset(self, request): + return super().get_queryset(request).prefetch_related('supervisors') + def get_supervisors(self, obj): return ', '.join(u.username for u in obj.supervisors.all()) or '-' get_supervisors.short_description = 'Supervisors' diff --git a/core/context_processors.py b/core/context_processors.py index 4ac3a71..f198dd4 100644 --- a/core/context_processors.py +++ b/core/context_processors.py @@ -1,6 +1,9 @@ import os import time +# Computed once at module load — changes per server restart/deploy +_DEPLOYMENT_TIMESTAMP = int(time.time()) + # === TEMPLATE CONTEXT PROCESSORS === @@ -11,6 +14,5 @@ def project_context(request): return { "project_description": os.getenv("PROJECT_DESCRIPTION", ""), "project_image_url": os.getenv("PROJECT_IMAGE_URL", ""), - # Used for cache-busting static assets - "deployment_timestamp": int(time.time()), + "deployment_timestamp": _DEPLOYMENT_TIMESTAMP, } diff --git a/core/migrations/0017_alter_payrolladjustment_date_and_more.py b/core/migrations/0017_alter_payrolladjustment_date_and_more.py new file mode 100644 index 0000000..1cb9d4e --- /dev/null +++ b/core/migrations/0017_alter_payrolladjustment_date_and_more.py @@ -0,0 +1,34 @@ +# Generated by Django 5.2.7 on 2026-02-19 22:25 + +import django.utils.timezone +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0016_alter_payrolladjustment_type'), + ] + + operations = [ + migrations.AlterField( + model_name='payrolladjustment', + name='date', + field=models.DateField(db_index=True, default=django.utils.timezone.now), + ), + migrations.AlterField( + model_name='payrolladjustment', + name='type', + field=models.CharField(choices=[('BONUS', 'Bonus'), ('OVERTIME', 'Overtime'), ('DEDUCTION', 'Deduction'), ('LOAN_REPAYMENT', 'Loan Repayment'), ('LOAN', 'New Loan'), ('ADVANCE', 'Advance Payment')], db_index=True, default='DEDUCTION', max_length=20), + ), + migrations.AlterField( + model_name='payrollrecord', + name='date', + field=models.DateField(db_index=True, default=django.utils.timezone.now), + ), + migrations.AlterField( + model_name='worklog', + name='date', + field=models.DateField(db_index=True), + ), + ] diff --git a/core/models.py b/core/models.py index 87efb54..2c3fedf 100644 --- a/core/models.py +++ b/core/models.py @@ -95,7 +95,7 @@ class WorkLog(models.Model): (Decimal('1.0'), 'Full Day'), ] - date = models.DateField() + date = models.DateField(db_index=True) project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name='logs') team = models.ForeignKey(Team, on_delete=models.SET_NULL, null=True, blank=True, related_name='work_logs') workers = models.ManyToManyField(Worker, related_name='work_logs') @@ -117,7 +117,7 @@ class WorkLog(models.Model): class PayrollRecord(models.Model): worker = models.ForeignKey(Worker, on_delete=models.CASCADE, related_name='payroll_records') - date = models.DateField(default=timezone.now) + date = models.DateField(default=timezone.now, db_index=True) amount = models.DecimalField(max_digits=10, decimal_places=2) work_logs = models.ManyToManyField(WorkLog, related_name='paid_in') created_at = models.DateTimeField(auto_now_add=True) @@ -171,9 +171,9 @@ class PayrollAdjustment(models.Model): work_log = models.ForeignKey(WorkLog, on_delete=models.SET_NULL, null=True, blank=True, related_name='adjustments') amount = models.DecimalField(max_digits=10, decimal_places=2, help_text="Positive adds to pay, negative subtracts (except for Loan Repayment which is auto-handled)") - date = models.DateField(default=timezone.now) + date = models.DateField(default=timezone.now, db_index=True) description = models.CharField(max_length=255) - type = models.CharField(max_length=20, choices=ADJUSTMENT_TYPES, default='DEDUCTION') + type = models.CharField(max_length=20, choices=ADJUSTMENT_TYPES, default='DEDUCTION', db_index=True) class Meta: verbose_name = "Payroll Adjustment"