05/08 Phase 4

This commit is contained in:
2026-05-08 10:15:40 -04:00
parent 959f54ed84
commit bf9b54f6b5
26 changed files with 1509 additions and 42 deletions
+24 -2
View File
@@ -731,8 +731,23 @@ WantedBy=multi-user.target
- [ ] Gift cards (issuance with unique code; POS redemption; balance tracking; expiry)
- [ ] End-of-day reconciliation (Close Day flow; cash count entry; variance calculation; `daily_reconciliations` record)
### Phase 4 — Tenant Operations Modules
- [ ] Staff management (profiles, job type, system role, location assignments, schedules)
### Phase 4 — Tenant Operations Modules ✅ COMPLETE
- [x] Pay structure per staff (hourly_rate, salary_amount, guarantee_amount, commission_rate, commission_enabled, pay_period — editable via staff form)
- [x] Pay period calculation engine (app/tenant/pay_periods/routes.py): hourly × hours, salary fixed, guarantee = max(guarantee, commission); results written to staff_pay_periods
- [x] Pay period approval workflow (draft → approved → paid; tenant_admin only)
- [x] Inventory (CRUD, reorder alerts, manual adjustment log; tenant_feature_required("inventory"))
- [x] Automatic inventory deduction on POS product sale (matched by SKU or name; InventoryLog entry created)
- [x] Appointment reminder engine (APScheduler job every 5 min; sends 24h + 2h email reminders; status=pending|sent|failed|cancelled)
- [x] Appointment reminders scheduled on appointment create (24h + 2h ahead)
- [x] Customer review request engine (APScheduler job every 10 min; delay per tenant setting; smart routing ≥4 stars shows platform links; one send enforced by review_request_sent_at)
- [x] app/scheduler_jobs.py — send_appointment_reminders(), send_review_requests()
- [x] Scheduler init in create_tenant_app() with SCHEDULER_API_ENABLED=False
- [x] pay_periods_bp + inventory_bp registered in tenant factory
- [x] Nav links wired: inventory → inventory.index, pay_periods → pay_periods.index
- [x] Both template trees in sync: 73 files each
- [x] Full validation passed: 6 imports OK, 0 missing templates, 0 illegal Jinja2, 0 broken extends
### Phase 4 — Staff management (profiles, job type, system role, location assignments, schedules) (profiles, job type, system role, location assignments, schedules)
- [ ] Pay structure setup per staff member (pay type, rates, pay period, commission toggle)
- [ ] Commission tracking (per transaction, period summary; respects `commission_enabled` flag per staff)
- [ ] Working hours / clockings (clock-in at login or manual; clock-out; total hours computed per period)
@@ -949,6 +964,13 @@ Every fix must be validated by a programmatic test (import test, render test, or
**Rule 10 — Pack files when more than 5 files are changed.**
When a fix touches more than 5 files, compress them into a ZIP for delivery. Always include only the changed files — not the entire project.
**Rule 11 — Never call Python builtins or stdlib objects inside Jinja2 `{{ }}` expressions.**
Jinja2 does not have access to Python's standard library or builtins such as `set()`, `dict()`, `list()`, `int()`, `float()`, `str()`, `len()`, `sorted()`, `enumerate()`, `zip()`, `timedelta`, `datetime`, `date`. Any computation involving these must be done in the route and passed as a named template variable. Violations produce `UndefinedError` in production. Examples of what NOT to do: `(assigned_ids or set())`, `(view_date - timedelta(days=1))`. Correct approach: compute `prev_date = view_date - timedelta(days=1)` in the route and pass `prev_date=prev_date` to `render_template`.
**Rule 12 — Always pass every variable a template references, on every code path.**
Every `render_template` call for a given template must supply the same set of variables — including early-return error paths. If the template uses `assigned_ids`, every `render_template("...form.html", ...)` call in that view must include `assigned_ids=...`. Missing variables on error-return paths produce `UndefinedError` only when that path is hit, making them hard to catch in testing.
When a fix touches more than 5 files, compress them into a ZIP for delivery. Always include only the changed files — not the entire project.
---
## Phase 1 — Implementation Notes