diff --git a/CLAUDE.md b/CLAUDE.md index bb2cb42..d1d3e14 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -5,6 +5,8 @@ - Add plain English comments explaining what complex logic does - The project owner is not a programmer — comments should be understandable by a non-technical person - When creating or editing code, maintain the existing comment structure +- **Django template comments `{# ... #}` are SINGLE-LINE only.** Multi-line blocks need `{% comment %}...{% endcomment %}`. A `{#` on line N with no closing `#}` on the same line renders the whole block as literal text onto the page (and silently — no error). This bit us 4× during the Adjustments feature. Also: the literal tokens `{#` and `#}` cannot appear inside a `{% comment %}` block — they'll be parsed as a nested comment marker. Rephrase meta-notes about comment syntax OUTSIDE the block. +- **Duplicate `id=""` attributes cause silent bugs.** `document.getElementById()` returns only the FIRST match in DOM order, so adding a second element with an existing id silently steals the handler from the original. Grep the template before assigning any new id (caught `adjSelectAll` collision in Task 6 — header checkbox stole the Add-Adjustment modal's Select-All handler). ## Project Overview Django payroll management system for FoxFitt Construction, a civil works contractor specializing in solar farm foundation installations. Manages field worker attendance, payroll processing, employee loans, and business expenses for solar farm projects. @@ -29,12 +31,13 @@ core/ — Single main app: ALL business logic, models, views, forms, views.py — All view functions (~52 functions, ~3,800 lines) — dashboard, attendance, payroll, reports, worker/team/project CRUD forms.py — All form classes + validators (WorkerForm, TeamForm, ProjectForm, AttendanceLogForm, PayrollAdjustmentForm, ExpenseReceiptForm, WorkerCertificate/WarningFormSet, 5MB file validator) admin.py — Django admin registrations for all core models + WorkerCertificate/Warning inlines on Worker - templatetags/ — format_tags.py (money filter for ZAR formatting) + templatetags/ — format_tags.py: `money` (ZAR), `money_abs` (signed callers), `type_slug` (type→CSS class), `url_replace` (swap one query-param), `dictlookup` management/commands/ — setup_groups, setup_test_data, import_production_data templates/ base.html — App shell (topbar + mobile menu + bottom tab bar) core/ — Page templates: index, attendance_log, work_history, payroll_dashboard, - report, create_receipt, payslip, login, _report_config_modal (partial) + report, create_receipt, payslip, login + Partials: _adjustment_row.html (shared row for flat + grouped Adjustments tab) core/workers/ — 4 templates: list, detail, edit, batch_report core/teams/ — 4 templates: list, detail, edit, batch_report core/projects/— 4 templates: list, detail, edit, batch_report @@ -66,6 +69,8 @@ sessions; grep `core/models.py` before using any field you haven't used before: - `PayrollAdjustment.description` — NOT `reason` - `log.adjustments_by_work_log` (reverse accessor for PayrollAdjustment.work_log FK) — NOT `payrolladjustment_set` (the FK has `related_name` set) - `log.overtime_amount` (DecimalField, default 0.00) — NOT `log.overtime` +- `PayrollRecord.amount_paid` (DecimalField) + `PayrollRecord.work_logs` (M2M reverse) — NOT `total_amount` / `days_worked` (easy to guess wrong when writing test fixtures) +- `Loan.principal_amount` — NOT `principal`. `Loan.save()` auto-sets `remaining_balance = principal_amount` on create, so tests rarely need to pass both. ## Key Business Rules - All business logic lives in the `core/` app — do not create additional Django apps @@ -149,6 +154,10 @@ USE_SQLITE=true DJANGO_DEBUG=true python manage.py test core.tests -v 2 - Worker Management UI: A friendlier alternative to `/admin/core/worker/`. Reachable via the "Resources" topbar dropdown → Workers (admin-only). Pages: `/workers/` (list with search + status filter), `/workers//` (detail with Profile/Certifications/Warnings/History tabs), `/workers//edit/` or `/workers/new/` (single-page form with sections for Personal & Pay, PPE, Documents, Driver's License, plus inline formsets for certifications and warnings). Uses `WorkerForm`, `WorkerCertificateFormSet`, `WorkerWarningFormSet` from `core/forms.py`. The "+ Add Certification" / "+ Add Warning" buttons clone a `