From 2c3410e7c79afc475b6eeef370364bb75f5f4ed3 Mon Sep 17 00:00:00 2001 From: Konrad du Plessis Date: Tue, 24 Mar 2026 22:32:05 +0200 Subject: [PATCH] Update CLAUDE.md with batch pay feature documentation - Add batch pay workflow docs (schedule vs pay-all modes, shared helper) - Add batch-pay preview and process endpoints to URL routes table - Update view count to 19 (~2000 lines) Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 7d3afd4..0b52857 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -26,7 +26,7 @@ core/ — Single main app: ALL business logic, models, views, forms, forms.py — AttendanceLogForm, PayrollAdjustmentForm, ExpenseReceiptForm + formset models.py — All 10 database models utils.py — render_to_pdf() helper (lazy xhtml2pdf import) - views.py — All 17 view functions (~1900 lines) + views.py — All 19 view functions (~2000 lines) management/commands/ — setup_groups, setup_test_data, import_production_data templates/ — base.html + 7 page templates + 2 email + 2 PDF + login ai/ — Flatlogic AI proxy client (not used in app logic) @@ -105,6 +105,7 @@ python manage.py check # System check - Split Payslip: Preview modal has checkboxes on work logs and adjustments (all checked by default). `process_payment()` accepts optional `selected_log_ids` / `selected_adj_ids` POST params to pay only selected items. Falls back to "pay all" if no IDs provided (backward compatible with the quick Pay button). - Team Pay Schedules: Teams have optional `pay_frequency` + `pay_start_date` fields. `get_pay_period(team)` calculates current period boundaries by stepping forward from the anchor date. The preview modal shows a "Split at Pay Date" button that auto-unchecks items outside the current pay period. `get_worker_active_team(worker)` returns the worker's first active team. - Pay period calculation: `pay_start_date` is an anchor (never needs updating). Weekly=7 days, Fortnightly=14 days, Monthly=calendar month stepping. Uses `calendar.monthrange()` for month-length edge cases (no `dateutil` dependency). +- Batch Pay: "Batch Pay" button on payroll dashboard opens a modal with two radio modes — **"Until Last Paydate"** (default, splits at last completed pay period per team schedule) and **"Pay All"** (includes all unpaid items regardless of date). Preview fetches from `batch_pay_preview` with `?mode=schedule|all`. Workers without team pay schedules are skipped in schedule mode but included in Pay All mode. `batch_pay` POST endpoint processes each worker in independent atomic transactions; emails are sent after all payments complete. Uses `_process_single_payment()` shared helper (same logic as individual `process_payment`). ## URL Routes | Path | View | Purpose | @@ -126,6 +127,8 @@ python manage.py check # System check | `/payroll/payslip//` | `payslip_detail` | Admin: view completed payslip | | `/receipts/create/` | `create_receipt` | Staff: expense receipt with line items | | `/import-data/` | `import_data` | Setup: run import command from browser | +| `/payroll/batch-pay/preview/` | `batch_pay_preview` | Admin: AJAX JSON batch pay preview (`?mode=schedule\|all`) | +| `/payroll/batch-pay/` | `batch_pay` | Admin: POST process batch payments for multiple workers | | `/run-migrate/` | `run_migrate` | Setup: run pending DB migrations from browser | ## Frontend Design Conventions