New AJAX endpoint (worker_lookup_ajax) returns a comprehensive financial report card for any active worker. Modal shows: amount payable, outstanding loans, paid this month/year, loans this year, recent activity, active loans table, current project + days, PPE sizing, drivers license, and notes. Worker names across all dashboard tabs are now clickable links that open the modal. Header button with searchable dropdown for quick access. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
6.1 KiB
Worker Lookup Modal — Implementation Plan
For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
Goal: Add a "Worker Lookup" modal to the payroll dashboard that shows a comprehensive financial report card for any active worker — payable amount, loans, recent payments, sizing, and notes.
Architecture: New AJAX endpoint (worker_lookup_ajax) returns JSON with all worker data. Modal HTML + JS in the dashboard template dynamically renders the data using safe DOM methods (textContent, createElement). Worker names across all dashboard tabs become clickable links that open the modal. A "Worker Lookup" button in the header lets you search any active worker.
Tech Stack: Django views (JSON), Bootstrap 5 modal, vanilla JavaScript (matching existing patterns)
Task 1: Add the AJAX backend endpoint
Files:
- Modify:
core/views.py(add new view afterpreview_payslipat ~line 2155) - Modify:
core/urls.py(add new URL pattern at ~line 54)
Step 1: Add URL pattern in core/urls.py
Add after the preview_payslip URL (line 51):
# Worker lookup — AJAX report card for a single worker (returns JSON)
path('payroll/worker-lookup/<int:worker_id>/', views.worker_lookup_ajax, name='worker_lookup_ajax'),
Step 2: Add worker_lookup_ajax view in core/views.py
Add after preview_payslip function (after line 2155). The view:
- Checks admin access (
is_admin) - Fetches the Worker object with all model fields (sizing, license, notes)
- Calculates Amount Payable:
- Unpaid WorkLogs x daily_rate (same logic as
preview_paysliplines 2069-2083) - Net pending adjustments (additive minus deductive)
- Unpaid WorkLogs x daily_rate (same logic as
- Outstanding Loans:
Loan.filter(worker=worker, active=True).aggregate(Sum('remaining_balance')) - Paid This Month:
PayrollRecord.filter(worker=worker, date__year=now.year, date__month=now.month).aggregate(Sum('amount_paid')) - Loans This Year:
Loan.filter(worker=worker, date__year=now.year).aggregate(Sum('principal_amount')) - Paid This Year:
PayrollRecord.filter(worker=worker, date__year=now.year).aggregate(Sum('amount_paid')) - Last Payslip:
PayrollRecord.filter(worker=worker).order_by('-date').first()-> date + amount - Last Loan Given:
Loan.filter(worker=worker).order_by('-date').first()-> date + amount + reason - Last Loan Repayment:
PayrollAdjustment.filter(worker=worker, type='Loan Repayment', payroll_record__isnull=False).order_by('-date').first()-> date + amount - Last Advance:
PayrollAdjustment.filter(worker=worker, type='Advance Payment', payroll_record__isnull=False).order_by('-date').first()-> date + amount - Active Loans list:
Loan.filter(worker=worker, active=True).order_by('-date')-> type, principal, balance, date, reason - Current Project: most recent WorkLog -> project name + count of logs on that project
- Team:
get_worker_active_team(worker)-> team name
Step 3: Verify imports
Ensure Sum is imported from django.db.models at the top of views.py. Check for existing from django.db.models import ... line and add Sum if missing.
Task 2: Add the modal HTML to the dashboard template
Files:
- Modify:
core/templates/core/payroll_dashboard.html
Step 1: Add "Worker Lookup" button in the page header (line 15)
Add a new button in the header button group, before Batch Pay.
Step 2: Add the Worker Lookup modal HTML
Add after the previewPayslipModal (after line ~783). The modal contains:
- Worker dropdown in header
- A body div (
#workerLookupBody) that gets populated by JS - Placeholder text as default content
Step 3: Pass active_workers_list from the view
In core/views.py, in the payroll_dashboard view, add to the context dict:
'active_workers_list': Worker.objects.filter(active=True).order_by('name'),
Task 3: Make worker names clickable across all tabs
Files:
- Modify:
core/templates/core/payroll_dashboard.html
Replace <strong>worker.name</strong> with clickable links using class worker-lookup-link and data-worker-id at:
- Pending Payments tab (line 268)
- Payment History tab (line 365)
- Loans & Advances tab (line 432)
Task 4: Add JavaScript to fetch data and render the modal
Files:
- Modify:
core/templates/core/payroll_dashboard.html(JS section at bottom)
Step 1: Add the loadWorkerLookup(workerId) function
This function:
- Shows a loading spinner in
#workerLookupBody - Fetches
/payroll/worker-lookup/<workerId>/via fetch API - Builds the report card using safe DOM methods (createElement, textContent — no innerHTML with user data)
- Renders sections: Identity, Quick Stats (4 cards), Recent Activity, Active Loans table, Paid This Year, Sizing & Info
Format currency as R X,XXX.XX using toLocaleString('en-ZA', {minimumFractionDigits: 2}).
Step 2: Add event listeners
- Worker Lookup button click -> open modal with empty dropdown
- Dropdown change -> call
loadWorkerLookup(selectedId) .worker-lookup-linkclick -> set dropdown value, load data, open modal
Task 5: Update CLAUDE.md
Files:
-
Modify:
CLAUDE.md -
Add Worker Lookup documentation to Development Workflow section
-
Add URL route to the URL Routes table
-
Update view count from "27 functions" to "28 functions"
Task 6: Test locally
- Start dev server:
run_dev.bat - Go to
/payroll/-> verify "Worker Lookup" button appears in header - Click "Worker Lookup" -> modal opens with dropdown -> select a worker -> report card loads
- Click a worker name in Pending Payments -> modal opens with that worker's data
- Click a worker name in Payment History -> same
- Click a worker name in Loans & Advances -> same
- Switch workers via dropdown while modal is open -> data refreshes
- Verify all sections render correctly:
- Quick stats show correct amounts
- Recent activity shows dates and amounts (or "None")
- Active loans table shows if worker has loans
- Sizing and notes display at bottom
- Verify existing functionality is unbroken:
- Preview payslip modal still works
- Quick adjust button still works
- Pay/Batch pay still works