# Fox Fitt LabourPay ## Coding Style - Always add clear section header comments using the format: # === SECTION NAME === - 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 ## Project Overview Django payroll management system for Fox Fitt 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. ## Tech Stack - Django 5.x, Python 3.11, MariaDB - Bootstrap 5 with Material Design-inspired styling, vanilla JavaScript - PDF generation for payslips and receipts - SMTP email integration for automated document delivery - Apache reverse proxy with systemd service management ## Project Structure - `config/` — Django project settings, URLs, WSGI/ASGI entrypoints - `core/` — Single main app containing ALL business logic, models, views, forms, templates, and migrations - `ai/` — Local AI API integration module - `media/workers/ids/` — Worker ID photo uploads - `static/` — Source static files (custom CSS) - `staticfiles/` — Collected static assets (Bootstrap, Popper.js, admin) ## Key Business Rules - All business logic lives in the `core/` app — do not create additional apps - Workers have a `day_rate` calculated automatically from monthly salary / 20 working days - PIN authentication (4-digit) exists alongside password auth for quick field access - Supervisors can only see their assigned projects and teams - Admins have full access to payroll, adjustments, and resource management - WorkLog is the central attendance record — links workers to projects on specific dates - Attendance logging includes conflict detection to prevent double-logging - Loans have automated repayment deductions during payroll processing - Cascading deletes use SET_NULL for supervisors to preserve historical data ## Key Models - **UserProfile** — extends User with PIN and is_admin flag - **Project** — work sites/contracts with supervisor assignments - **Worker** — profiles with salary, day_rate, employment details - **Team** — groups of workers under a supervisor - **WorkLog** — daily attendance records (worker + project + date) - **PayrollRecord** — completed payments linked to WorkLog entries - **PayrollAdjustment** — bonuses, deductions, overtime, loan repayments - **Loan** — worker advances with balance tracking - **ExpenseReceipt / ExpenseLineItem** — business expense records ## Commands - `python manage.py runserver 0.0.0.0:8000` — run dev server - `python manage.py migrate` — apply database migrations - `python manage.py collectstatic` — collect static files for production - `python manage.py setup_groups` — configure permission groups - `python manage.py update_permission_names` — update permission display names - `python manage.py check` — system check (ignore staticfiles warnings about missing `assets/` and `node_modules/` dirs — pre-existing, harmless) ## Development Workflow - Active development branch: `ai-dev` (PR target: `master`) - Admin check in views: `is_admin(request.user)` helper (imported at top of views.py) - "Unpaid" adjustment = `payroll_record__isnull=True` (no linked PayrollRecord) - POST-only mutation views pattern: check `request.method != 'POST'` → redirect, then process - Template UI pattern: Bootstrap 5 modals with dynamic JS wiring, data-* attributes on clickable elements ## PayrollAdjustment Type Handling - **BONUS / DEDUCTION** — standalone, no linked objects - **LOAN** — links to `Loan` model via `adj.loan` FK; editing syncs loan amount/balance/reason; deleting cascades to Loan + unpaid repayments (blocked if paid repayments exist) - **OVERTIME** — links to `WorkLog` via `adj.work_log` FK; deleting removes worker from `work_log.overtime_paid_to` M2M (un-prices the OT) - **LOAN_REPAYMENT** — links to `Loan` via `adj.loan` FK; loan balance only changes during payment processing ## Frontend Design Conventions - **CSS variables** defined in `static/css/custom.css` `:root` — always use `var(--name)` instead of hardcoding hex values - `--primary-dark: #0f172a` (navbar), `--primary-color: #1e293b` (headers), `--accent-color: #10b981` (CTAs, brand green), `--text-main: #334155`, `--bg-color: #f1f5f9` - **Icon library**: Font Awesome 6 only (`fas fa-*`). Do NOT use Bootstrap Icons (`bi bi-*`) - **CTA buttons**: `btn-accent` (green) for all primary page-level actions. `btn-primary` (Bootstrap blue) for modal Save/Submit buttons only - **Page titles**: `{% block title %}Page Name | Fox Fitt{% endblock %}` — always use ` | ` separator, always "Fox Fitt" (never "LabourFlow") - **Fonts**: Inter (body) + Poppins (headings) loaded once in base.html. Do not add `@import` in custom.css - **Cards**: `shadow-sm` everywhere, never `shadow-lg`. Table headers use `table-light` class, never `bg-light` on `` - **Email/PDF payslips**: Worker name must be the dominant element — do NOT add prominent Fox Fitt branding (Spark reads the vendor name from the document) ## Recent Work (Feb 2026) ### Completed This Session 1. **Mobile responsiveness review & fixes** — 17 issues found and fixed across all templates (card hover on touch, calendar compact view, form columns, chart heights, button stacking, heading sizes) 2. **Design consistency review** — 25 issues identified across branding, colours, fonts, icons, buttons, cards, spacing, and tables 3. **Branding fixes** — Replaced all "LabourFlow" → "Fox Fitt", standardized title separators to ` | ` 4. **Font cleanup** — Removed duplicate Inter import from custom.css, removed duplicate inline body font rule from base.html, consolidated Google Fonts loading into single base.html link 5. **Icon standardization** — Replaced all 13 Bootstrap Icon usages with Font Awesome equivalents, removed Bootstrap Icons CDN 6. **Colour variable standardization** — Added `--primary-dark` CSS variable, replaced all inline hex colours with CSS variables 7. **Shadow & table standardization** — All cards use `shadow-sm`, all theads use `table-light`, payslip tables changed from `table-bordered` to `table-hover` 8. **Button consistency** — All page-level CTA buttons use `btn-accent`, login button inline override removed ### Completed in Prior Sessions - Edit & Delete unpaid payroll adjustments feature - Advance Payment feature (plan written, not yet implemented) - Section header comments added to all core/ files - Bug/security fixes (mutable default args, queryset evaluation, timezone-aware dates, XSS protection, etc.) - Performance optimizations (database indexes, select_related/prefetch_related, aggregate queries) ### Remaining from Design Review (Not Yet Fixed) - **#10**: Unify stat card styles between index.html (glassmorphism `.stat-card`) and payroll_dashboard (tinted `bg-X bg-opacity-10`) - **#16**: Inconsistent card header patterns across pages - **#18**: Create_receipt has dark primary-color card header while others don't - **#19**: Inconsistent page top spacing (some use `dashboard-header` + negative margin, some use `py-5`, some use `mt-5`) - **#22**: Footer is very basic — could use brand accent - **#23**: No loading/spinner states on form submissions - **#25**: Plain text empty states — could use icons ### Pending Feature Work - **Advance Payment feature** — Full plan exists at `.claude/plans/cozy-twirling-rainbow.md`. Allows partial advance payments against earned wages with standalone payslip generation. Ready for implementation. ## Important Context - Read APP_DOCUMENTATION.md for detailed workflows (attendance, payroll, expenses) - Environment variables loaded from `../.env` - The owner (Konrad) is not a developer — explain changes clearly and avoid unnecessary complexity - This system handles real payroll for 14 field workers — accuracy is critical