diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index b622d85..2aa9d24 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/templates/core/payroll_dashboard.html b/core/templates/core/payroll_dashboard.html index fedc41e..d5191d4 100644 --- a/core/templates/core/payroll_dashboard.html +++ b/core/templates/core/payroll_dashboard.html @@ -65,7 +65,7 @@ -
+
Monthly Payroll Totals
@@ -83,6 +83,18 @@
+ + +
+
+
+
Overtime History
+
+ +
+
+
+
@@ -343,9 +362,51 @@ .cal-day--selected { background-color: rgba(13, 110, 253, 0.08) !important; box-shadow: inset 0 0 0 2px var(--bs-primary); } -{% if view_mode == 'calendar' %} -{% endif %} {% endblock %} \ No newline at end of file diff --git a/core/views.py b/core/views.py index cb7ca5d..91158f9 100644 --- a/core/views.py +++ b/core/views.py @@ -359,6 +359,21 @@ def work_log_list(request): total_amount = 0 combined_records = [] + # Prepare Chart Data (Overtime) - Admin only + ot_chart_labels = [] + ot_chart_data = [] + + if user_is_admin: + from django.db.models.functions import TruncMonth + ot_stats = adjustments.filter(type='OVERTIME') \ + .annotate(month=TruncMonth('date')) \ + .values('month') \ + .annotate(total=Sum('amount')) \ + .order_by('month') + + ot_chart_labels = [s['month'].strftime('%b %Y') for s in ot_stats] + ot_chart_data = [float(s['total']) for s in ot_stats] + # Process Logs for log in logs: record = { @@ -431,6 +446,8 @@ def work_log_list(request): 'selected_payment_status': payment_status, 'target_worker': target_worker, 'view_mode': view_mode, + 'ot_chart_labels': json.dumps(ot_chart_labels), + 'ot_chart_data': json.dumps(ot_chart_data), } if view_mode == 'calendar': @@ -777,6 +794,8 @@ def payroll_dashboard(request): all_project_names = list(Project.objects.values_list('name', flat=True).order_by('name')) project_monthly = {name: [] for name in all_project_names} + ot_history_totals = [] # Overtime history + for year, month in chart_months: chart_labels.append(f"{calendar.month_abbr[month]} {year}") @@ -789,6 +808,14 @@ def payroll_dashboard(request): date__gte=month_start, date__lte=month_end ).aggregate(total=Sum('amount'))['total'] or 0 chart_totals.append(float(month_paid)) + + # Overtime paid this month + ot_month_total = PayrollAdjustment.objects.filter( + type='OVERTIME', + date__gte=month_start, + date__lte=month_end + ).aggregate(total=Sum('amount'))['total'] or 0 + ot_history_totals.append(float(ot_month_total)) # Per-project labour cost this month (from work logs × day rates) month_logs = WorkLog.objects.filter( @@ -826,6 +853,7 @@ def payroll_dashboard(request): 'chart_totals_json': json.dumps(chart_totals), 'project_chart_json': json.dumps(project_chart_data), 'overtime_data_json': json.dumps(all_ot_data), + 'ot_history_json': json.dumps(ot_history_totals), } return render(request, 'core/payroll_dashboard.html', context)