Extends the app with friendly form-based management for Teams and Projects —
an alternative to using Django admin for routine maintenance.
New URLs (admin-only, all return 403 for non-admins):
- /teams/ · /teams/new/ · /teams/<id>/ · /teams/<id>/edit/
- /teams/report/ · /teams/report/csv/
- /projects/ + same 5 variants
Forms (core/forms.py):
- TeamForm — ModelForm with pay-schedule validation (both or neither field)
- ProjectForm — ModelForm with end_date >= start_date validation
- _supervisor_user_queryset() — admins + Work Logger group members
Views (core/views.py):
- 10 new views (5 per model: list, detail, edit, batch_report, batch_csv)
- _build_team_report_context() / _build_project_report_context() shared helpers
- All views gate on is_admin(user)
- Reuses existing get_pay_period() for Team detail Pay Schedule tab
Templates (core/templates/core/teams/ and projects/):
- list.html — filterable table with search
- detail.html — tabbed profile / workers / history / schedule
- edit.html — serves both /new/ and /edit/
- batch_report.html — lifetime aggregates per row, CSV download
UI integration:
- Resources dropdown added to top nav (admin-only, Teams + Projects)
- Manage All buttons added to Dashboard Manage Resources tabs (Teams, Projects)
No model changes, no migrations — purely additive.
CLAUDE.md updated with new routes and section describing the pattern.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1. Attendance form: Force start date to blank by clearing Django 5.x auto-fill
from model default (default=timezone.now). Added self.fields['date'].initial=None
in AttendanceLogForm.__init__().
2. History list view: When filtering by a specific worker, show only that
worker's name in the Workers column (not all workers on the log). Uses
filtered_worker_obj passed from the view.
3. History list view: Added Amount column (admin-only) showing daily cost.
When filtering by worker, shows that worker's daily_rate. When unfiltered,
shows total via new WorkLog.display_amount property (sum of all workers'
daily_rate, uses prefetch cache for efficiency).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Straight port from V2 adapted for V5 field names. Creates expense
receipts with dynamic line items, VAT calculation (Included/Excluded/
None at 15%), and emails HTML + PDF to Spark Receipt. Uses lazy
xhtml2pdf import to avoid crashing if not installed on server.
Files: forms.py (ExpenseReceiptForm + FormSet), views.py (create_receipt),
create_receipt.html, receipt_email.html, receipt_pdf.html, urls.py, base.html
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Attendance form: date range (start+end), Sat/Sun checkboxes, conflict
detection with Skip/Overwrite, supervisor auto-set, estimated cost card
- Work history: filter by worker/project/payment status, CSV export,
payment status badges (Paid/Unpaid)
- Supervisor dashboard: stat cards for projects, teams, workers count
- Forms: supervisor filtering (non-admins only see their projects/workers)
- Navbar: History link now works, cleaned up inline styles in base.html
- Management command: setup_groups creates Admin + Work Logger groups
- No model/migration changes — database is untouched
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>