From b4c3109c29a3e11a1473902d85d17dc48e086934 Mon Sep 17 00:00:00 2001 From: Konrad du Plessis Date: Wed, 22 Apr 2026 13:43:13 +0200 Subject: [PATCH] Add URL routes + stubs for work log payroll cross-link Routes /history// and /history//payroll/ajax/ to stub views. Both admin-gated; no data yet. Sets up the surface for Tasks 2-4. Co-Authored-By: Claude Opus 4.7 (1M context) --- core/urls.py | 7 +++++++ core/views.py | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/core/urls.py b/core/urls.py index c71f20d..29c860d 100644 --- a/core/urls.py +++ b/core/urls.py @@ -18,6 +18,13 @@ urlpatterns = [ # CSV export — downloads filtered work logs as a spreadsheet path('history/export/', views.export_work_log_csv, name='export_work_log_csv'), + # === WORK LOG PAYROLL CROSS-LINK (admin-only) === + # Click a historic work log -> see who got paid and who didn't. + # AJAX endpoint returns JSON (the modal builds its own DOM safely); + # detail view renders the same data as a shareable full page. + path('history//', views.work_log_payroll_detail, name='work_log_payroll_detail'), + path('history//payroll/ajax/', views.work_log_payroll_ajax, name='work_log_payroll_ajax'), + # CSV export — downloads all worker data (admin only) path('workers/export/', views.export_workers_csv, name='export_workers_csv'), diff --git a/core/views.py b/core/views.py index dcc4358..12a6cc5 100644 --- a/core/views.py +++ b/core/views.py @@ -720,6 +720,44 @@ def work_history(request): return render(request, 'core/work_history.html', context) +# ============================================================================= +# === WORK LOG PAYROLL CROSS-LINK === +# From any historic work log, see which workers got paid, which didn't, and +# (for paid ones) which payslip it was. Admin-only; supervisors never see +# payroll data. Two endpoints share one helper so the modal and the full +# page can never drift apart. +# ============================================================================= + +def _build_work_log_payroll_context(log): + """Return a context dict describing the payroll status of a work log. + + Used by both the AJAX modal endpoint and the full-page detail view so + they always show identical data. See Task 2 for the full implementation. + """ + # Stub — implemented in Task 2 + return {'log': log} + + +@login_required +def work_log_payroll_ajax(request, log_id): + """Return JSON describing the payroll status of a work log.""" + # Stub — implemented in Task 3 + if not is_admin(request.user): + return JsonResponse({'error': 'Not authorized'}, status=403) + get_object_or_404(WorkLog, id=log_id) + return JsonResponse({'stub': True}) + + +@login_required +def work_log_payroll_detail(request, log_id): + """Render the full payroll-status page for a single work log.""" + # Stub — implemented in Task 4 + if not is_admin(request.user): + return HttpResponseForbidden("Admin access required.") + log = get_object_or_404(WorkLog, id=log_id) + return HttpResponse(f"

stub for log {log.id}

") + + # === CSV EXPORT === # Downloads the filtered work log history as a CSV file. # Uses the same filters as the work_history page.