docs(fusion_claims): add dashboard redesign spec
Action-oriented dashboard replacing the existing 4-panel HTML overview: posting-week banner with live countdown, 3 KPI tiles, 8 funder hotlinks, ADP + MOD workflow flag tiles, role-aware filtering, dark-mode aware SCSS. Spec captures all design decisions from the brainstorm session; ready to hand off to writing-plans. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1
fusion_claims/.gitignore
vendored
Normal file
1
fusion_claims/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.superpowers/
|
||||
@@ -0,0 +1,432 @@
|
||||
# Fusion Claims Dashboard — Design Spec
|
||||
|
||||
**Date:** 2026-05-21
|
||||
**Module:** `fusion_claims`
|
||||
**Status:** Design approved, ready for implementation plan
|
||||
**Replaces:** the existing 4-panel HTML-field dashboard at `models/dashboard.py` + `views/dashboard_views.xml`
|
||||
|
||||
---
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
Surface workflow flags, posting-week context, and per-funder hotlinks on a single dashboard so claims processors, sales reps, and managers can see at a glance what needs action today and how much money is in motion for the current ADP posting cycle.
|
||||
|
||||
The existing dashboard is a case-count overview. The new dashboard is action-oriented: "what's stuck, what's due this week, what should I be doing."
|
||||
|
||||
## 2. Audience and role behaviour
|
||||
|
||||
Single dashboard used by three personas, with auto-applied role filter:
|
||||
|
||||
- **Managers** (in `fusion_claims.group_fusion_claims_manager` or `sales_team.group_sale_manager`) — see all cases.
|
||||
- **Office staff** — same as managers (they are typically in the manager group already, per the module's security model).
|
||||
- **Sales reps** (only in `group_fusion_claims_user`) — see only SOs where `user_id = self.env.uid`.
|
||||
|
||||
A small "Showing your cases" hint appears above the workflow tiles when the role filter is active (driven by computed `is_manager`).
|
||||
|
||||
## 3. Scope
|
||||
|
||||
**In scope:**
|
||||
- Posting-period banner with live countdown to submission cutoff
|
||||
- 3 KPI tiles: Ready to Claim, Claimed This Period, Total AR (ADP-portion)
|
||||
- 8 quick-action hotlinks: + ADP, + MOD, + ODSP, + WSIB, + Insurance, + MDC, + Hardship, + Private
|
||||
- "Your Activities" list (top 10 of current user's `mail.activity`)
|
||||
- Two bottleneck callouts: Approved without POD, Submitted with no ADP response > 14 days
|
||||
- ADP Pre-Approval workflow tiles (4): Waiting App, App Received, Ready Submission, Needs Correction
|
||||
- ADP Post-Approval workflow tiles (4): Approved, Ready Delivery, Ready Billing, On Hold
|
||||
- MOD workflow tiles (5): Awaiting Funding, Funding Approved, PCA Received, Project Complete, POD Submitted
|
||||
- Other-funder count cards (6): ODSP, WSIB, Insurance, MDC, Hardship, ACSD
|
||||
- Light + dark theme support via compile-time SCSS branching
|
||||
|
||||
**Out of scope:**
|
||||
- Charts / time-series graphs
|
||||
- The existing 4 configurable HTML panels (removed)
|
||||
- A "Recent Cases" power-user view (deferred — separate spec if needed)
|
||||
- Auto-refresh on window focus (manual reload only)
|
||||
- Per-user personalisation beyond the role filter (no saved layouts/filters)
|
||||
- Push notifications, email digests (out of scope, handled elsewhere)
|
||||
|
||||
## 4. Architecture
|
||||
|
||||
### 4.1 Implementation pattern
|
||||
|
||||
**Hybrid: form-view shell + computed fields + small OWL widget for the live countdown.**
|
||||
|
||||
Server-rendered Bootstrap-grid form view sits on top of a TransientModel with ~36 computed fields. One OWL field-widget handles the live deadline countdown (ticks every 60 seconds, swaps colour as deadline approaches).
|
||||
|
||||
The TransientModel name `fusion.claims.dashboard` is **preserved** — existing menu/action records continue to resolve. The model's internals are rewritten; old fields are dropped.
|
||||
|
||||
### 4.2 Files
|
||||
|
||||
| File | Action | Purpose |
|
||||
|---|---|---|
|
||||
| `models/dashboard.py` | **Rewrite** | TransientModel with ~36 computed fields + role-filter helper + ~24 action methods |
|
||||
| `views/dashboard_views.xml` | **Rewrite** | Form view: banner → KPIs → quick-actions → 2-column grid |
|
||||
| `static/src/scss/_fc_dashboard_tokens.scss` | **New** | Colour palette tokens, compile-time `@if $o-webclient-color-scheme == dark` branch |
|
||||
| `static/src/scss/fc_dashboard.scss` | **New** | Layout + section styles, references tokens |
|
||||
| `static/src/js/fc_posting_countdown.js` | **New** | OWL field widget for live countdown (~60 lines) |
|
||||
| `static/src/xml/fc_posting_countdown.xml` | **New** | OWL template (~10 lines) |
|
||||
| `__manifest__.py` | **Edit** | Bump version (asset cache-bust), add SCSS to **both** `web.assets_backend` AND `web.assets_web_dark`, add JS+XML to backend |
|
||||
|
||||
### 4.3 Layout
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ BANNER: Posting Period: Mar 5 – 19 · [OWL: 3d to cutoff] │
|
||||
├──────────────────────────────────────────────────────────────┤
|
||||
│ KPI TILES (3-up): Ready | Claimed | Total AR │
|
||||
├──────────────────────────────────────────────────────────────┤
|
||||
│ QUICK ACTIONS: + ADP + MOD + ODSP + WSIB + Ins + ... │
|
||||
├────────────────────────┬─────────────────────────────────────┤
|
||||
│ LEFT COLUMN │ RIGHT COLUMN │
|
||||
│ Your Activities │ ADP Pre-Approval (4 tiles) │
|
||||
│ Bottlenecks │ ADP Post-Approval (4 tiles) │
|
||||
│ Other Funders (6) │ MOD (5 tiles) │
|
||||
└────────────────────────┴─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 4.4 Data flow
|
||||
|
||||
1. User clicks Dashboard menu.
|
||||
2. Existing `action_fusion_claims_dashboard` creates a fresh TransientModel record.
|
||||
3. Compute methods run (5 clusters — see §6).
|
||||
4. Form renders.
|
||||
5. OWL countdown widget tickets every 60 s, reading `submission_deadline_dt` from the rendered field, formatting it client-side.
|
||||
6. User clicks a tile → returns `ir.actions.act_window` opening a filtered `sale.order` list.
|
||||
7. User clicks a quick-action pill → returns `ir.actions.act_window` opening a fresh `sale.order` form with `default_x_fc_sale_type` in context.
|
||||
8. User clicks Refresh (form header button) → reloads the action.
|
||||
|
||||
## 5. Role filter
|
||||
|
||||
Central helper on `fusion.claims.dashboard`:
|
||||
|
||||
```python
|
||||
def _role_filter_domain(self):
|
||||
user = self.env.user
|
||||
if (user.has_group('fusion_claims.group_fusion_claims_manager')
|
||||
or user.has_group('sales_team.group_sale_manager')):
|
||||
return []
|
||||
return [('user_id', '=', user.id)]
|
||||
```
|
||||
|
||||
Every count/sum compute method prepends `_role_filter_domain()` to its domain. For `account.move` based counts (KPIs), the filter is applied through `x_fc_source_sale_order_id.user_id` (the linked SO's salesperson) because invoices don't have their own `user_id` to filter on in this module.
|
||||
|
||||
`is_manager` (Boolean computed) exposed for the view to optionally show a "Showing your cases" hint.
|
||||
|
||||
## 6. Field inventory (≈36 fields)
|
||||
|
||||
### 6.1 Header / banner
|
||||
|
||||
| Field | Type | Description |
|
||||
|---|---|---|
|
||||
| `posting_period_label` | Char | e.g. `"Mar 5 – Mar 19"` |
|
||||
| `posting_period_start` | Date | Start of current posting cycle |
|
||||
| `posting_period_end` | Date | Start of next cycle (exclusive) |
|
||||
| `submission_deadline_dt` | Datetime | Wed 18:00 of posting week, Toronto TZ |
|
||||
| `is_manager` | Boolean | Drives role-hint visibility |
|
||||
| `is_pre_first_posting` | Boolean | True if today < `adp_posting_base_date` |
|
||||
|
||||
Derived from helpers already on `adp.posting.schedule.mixin`. Dashboard `_inherit = ['adp.posting.schedule.mixin']`.
|
||||
|
||||
### 6.2 KPI tiles
|
||||
|
||||
| Field | Type | Source |
|
||||
|---|---|---|
|
||||
| `kpi_ready_amount` | Monetary | Sum of `account.move.amount_total` where `x_fc_adp_billing_status='waiting'` AND `adp_exported=False`, role-filtered via linked SO |
|
||||
| `kpi_ready_count` | Integer | Same filter, count |
|
||||
| `kpi_claimed_amount` | Monetary | Sum where `x_fc_adp_billing_status in ('submitted','resubmitted')` AND `adp_export_date >= posting_period_start` |
|
||||
| `kpi_claimed_count` | Integer | Same filter, count |
|
||||
| `kpi_ar_amount` | Monetary | Sum where `move_type='out_invoice'`, `state='posted'`, `payment_state in ('not_paid','partial')`, `x_fc_invoice_type='adp'` |
|
||||
| `kpi_ar_count` | Integer | Same filter, count |
|
||||
| `currency_id` | Many2one | Defaults to `company_id.currency_id` |
|
||||
|
||||
### 6.3 Activities (left column)
|
||||
|
||||
| Field | Type | Description |
|
||||
|---|---|---|
|
||||
| `my_activities_count` | Integer | `mail.activity` where `user_id=current_user` AND `res_model in ('sale.order','account.move','fusion.technician.task')` |
|
||||
| `my_activities_html` | Html | Top 10 ordered by `date_deadline asc`, links via `/odoo/<model>/<id>`, overdue rows tinted |
|
||||
|
||||
### 6.4 Bottlenecks (left column)
|
||||
|
||||
| Field | Type | Domain |
|
||||
|---|---|---|
|
||||
| `bottleneck_no_pod_count` | Integer | ADP cases `x_fc_adp_application_status in ('approved','approved_deduction')` AND `x_fc_proof_of_delivery=False` |
|
||||
| `bottleneck_no_response_count` | Integer | ADP cases `x_fc_adp_application_status in ('submitted','resubmitted')` AND `x_fc_claim_submission_date < today - 14 days` |
|
||||
|
||||
### 6.5 Other funders (left column)
|
||||
|
||||
Each is an Integer count of active (non-terminal) cases:
|
||||
|
||||
| Field | Domain |
|
||||
|---|---|
|
||||
| `count_odsp` | `x_fc_sale_type in ('odsp','adp_odsp')` excluding division-specific terminal states |
|
||||
| `count_wsib` | `x_fc_sale_type='wsib'` excluding `case_closed`, `cancelled`, `denied` |
|
||||
| `count_insurance` | `x_fc_sale_type='insurance'` excluding terminal states |
|
||||
| `count_mdc` | `x_fc_sale_type='muscular_dystrophy'` excluding terminal states |
|
||||
| `count_hardship` | `x_fc_sale_type='hardship'` excluding terminal states |
|
||||
| `count_acsd` | `x_fc_client_type='ACS'` excluding terminal states |
|
||||
|
||||
### 6.6 ADP Pre-Approval (right column, 4 tiles)
|
||||
|
||||
| Field | Status filter |
|
||||
|---|---|
|
||||
| `adp_waiting_app_count` | `x_fc_adp_application_status in ('waiting_for_application','assessment_completed')` |
|
||||
| `adp_app_received_count` | `x_fc_adp_application_status='application_received'` |
|
||||
| `adp_ready_submit_count` | `x_fc_adp_application_status='ready_submission'` |
|
||||
| `adp_needs_correction_count` | `x_fc_adp_application_status='needs_correction'` (rendered as urgent tile) |
|
||||
|
||||
`adp_waiting_app_count` and `adp_needs_correction_count` are styled `--urgent` (red tint).
|
||||
|
||||
### 6.7 ADP Post-Approval (right column, 4 tiles)
|
||||
|
||||
| Field | Status filter |
|
||||
|---|---|
|
||||
| `adp_approved_count` | `x_fc_adp_application_status in ('approved','approved_deduction')` |
|
||||
| `adp_ready_delivery_count` | `x_fc_adp_application_status='ready_delivery'` |
|
||||
| `adp_ready_bill_count` | `x_fc_adp_application_status='ready_bill'` |
|
||||
| `adp_on_hold_count` | `x_fc_adp_application_status='on_hold'` (rendered as urgent tile) |
|
||||
|
||||
### 6.8 MOD (right column, 5 tiles)
|
||||
|
||||
| Field | Status filter |
|
||||
|---|---|
|
||||
| `mod_awaiting_funding_count` | `x_fc_mod_status='awaiting_funding'` |
|
||||
| `mod_funding_approved_count` | `x_fc_mod_status='funding_approved'` |
|
||||
| `mod_pca_received_count` | `x_fc_mod_status='contract_received'` |
|
||||
| `mod_project_complete_count` | `x_fc_mod_status='project_complete'` |
|
||||
| `mod_pod_submitted_count` | `x_fc_mod_status='pod_submitted'` |
|
||||
|
||||
## 7. Compute method clustering
|
||||
|
||||
Five compute methods, each owning a logical section so an expensive query in one cluster doesn't recompute the rest:
|
||||
|
||||
| Method | Fields populated |
|
||||
|---|---|
|
||||
| `_compute_banner` | 6 banner fields |
|
||||
| `_compute_kpis` | 6 KPI fields + `currency_id` |
|
||||
| `_compute_activities` | 2 activity fields |
|
||||
| `_compute_workflow_counts` | 13 stage-tile fields (ADP + MOD) |
|
||||
| `_compute_secondary_counts` | 8 fields (bottlenecks + other funders) |
|
||||
|
||||
All compute methods are bound to non-stored `compute='_compute_*'` fields (no `@api.depends` since TransientModel records are throwaway — every dashboard open is a fresh record). Counts use `search_count()` not `search()` to avoid loading recordsets.
|
||||
|
||||
## 8. Action methods (~24)
|
||||
|
||||
### 8.1 `action_open_<bucket>` (~16)
|
||||
|
||||
Thin wrappers returning `ir.actions.act_window`. Where the module already has per-stage actions (e.g. `adp_claims_views.xml` defines `act_window_adp_ready_for_billing`), reuse them via `self.env.ref(...).read()[0]`. Otherwise build the action inline.
|
||||
|
||||
Examples:
|
||||
- `action_open_adp_waiting_app` — opens SO list filtered to `('x_fc_adp_application_status', 'in', ['waiting_for_application', 'assessment_completed'])`
|
||||
- `action_open_bottleneck_no_pod` — opens SO list filtered to approved-without-POD
|
||||
- `action_open_my_activities` — opens activity list filtered to current user
|
||||
|
||||
### 8.2 `action_create_<funder>_so` (8)
|
||||
|
||||
One per funder hotlink. Each opens a fresh `sale.order` form with `default_x_fc_sale_type` in context:
|
||||
|
||||
| Method | Context |
|
||||
|---|---|
|
||||
| `action_create_adp_so` | `{'default_x_fc_sale_type': 'adp'}` |
|
||||
| `action_create_mod_so` | `{'default_x_fc_sale_type': 'march_of_dimes'}` |
|
||||
| `action_create_odsp_so` | `{'default_x_fc_sale_type': 'odsp', 'default_x_fc_odsp_division': 'standard'}` |
|
||||
| `action_create_wsib_so` | `{'default_x_fc_sale_type': 'wsib'}` |
|
||||
| `action_create_insurance_so` | `{'default_x_fc_sale_type': 'insurance'}` |
|
||||
| `action_create_mdc_so` | `{'default_x_fc_sale_type': 'muscular_dystrophy'}` |
|
||||
| `action_create_hardship_so` | `{'default_x_fc_sale_type': 'hardship'}` |
|
||||
| `action_create_private_so` | `{'default_x_fc_sale_type': 'direct_private'}` |
|
||||
|
||||
User picks ODSP division on the SO form (we default to `standard`, they can change to `sa_mobility` or `ontario_works`).
|
||||
|
||||
## 9. Theming (SCSS structure)
|
||||
|
||||
### 9.1 File order
|
||||
|
||||
Tokens load **first** in each bundle. SCSS variables defined in `_fc_dashboard_tokens.scss` must be in scope when `fc_dashboard.scss` is compiled. Odoo concatenates SCSS within a bundle in registration order, so the manifest registration sequence is load-bearing — see §11.
|
||||
|
||||
### 9.2 `_fc_dashboard_tokens.scss`
|
||||
|
||||
Single source of truth. Define light values at top level, override with `!global` inside `@if $o-webclient-color-scheme == dark`. Token names use the `$_fc-*` convention (underscore prefix for "private" partials).
|
||||
|
||||
Light palette (22 tokens):
|
||||
|
||||
```
|
||||
page-bg: #f7f7f8 card-bg: #ffffff card-border: #d8dadd
|
||||
text: #2b2b2b text-muted: #6c7480
|
||||
|
||||
banner: linear-gradient(#eef2ff → #fce7f3) border: #c7d2fe text: #3730a3
|
||||
deadline-text: #b91c1c
|
||||
|
||||
kpi-bg: #f0f4ff kpi-border: #c7d2fe kpi-num: #1e3a8a
|
||||
|
||||
action-bg: #ecfdf5 action-border: #6ee7b7 action-text: #047857
|
||||
|
||||
tile-bg: #f3f4f6 tile-border: #e5e7eb tile-num: #111827
|
||||
|
||||
urgent-bg: #fee2e2 urgent-border: #fca5a5 urgent-num: #991b1b urgent-text: #7f1d1d
|
||||
|
||||
activity-bg: #fefce8 activity-border: #fde047
|
||||
bottleneck-bg: #fef2f2 bottleneck-border: #fecaca
|
||||
```
|
||||
|
||||
Dark palette overrides (cool blue monochrome banner per Round 3 selection):
|
||||
|
||||
```
|
||||
page-bg: #1a1d21 card-bg: #22262d card-border: #3a3f47
|
||||
text: #e5e7eb text-muted: #9ca3af
|
||||
|
||||
banner: linear-gradient(#1e293b → #1e3a5f) border: #3b82f6 text: #93c5fd
|
||||
deadline-text: #fca5a5
|
||||
|
||||
kpi-bg: #1e293b kpi-border: #334155 kpi-num: #93c5fd
|
||||
|
||||
action-bg: #064e3b action-border: #047857 action-text: #6ee7b7
|
||||
|
||||
tile-bg: #2d3138 tile-border: #3a3f47 tile-num: #f3f4f6
|
||||
|
||||
urgent-bg: #4a1414 urgent-border: #7f1d1d urgent-num: #fca5a5 urgent-text: #fecaca
|
||||
|
||||
activity-bg: #3a2e0a activity-border: #854d0e
|
||||
bottleneck-bg: #3a1414 bottleneck-border: #7f1d1d
|
||||
```
|
||||
|
||||
### 9.3 `fc_dashboard.scss`
|
||||
|
||||
Layout file. Re-exports each token as a CSS custom property scoped under `.o_fc_dashboard` so dev-tools can inspect/tweak live, then uses both the SCSS variable (for compile-time work like `darken()`) and the CSS variable (for runtime). Section classes:
|
||||
|
||||
- `.o_fc_banner` — gradient + border, flex-row with deadline countdown on the right
|
||||
- `.o_fc_kpi` (with `.o_fc_kpi__num`) — 3-up KPI tiles
|
||||
- `.o_fc_pill` — quick-action button pills
|
||||
- `.o_fc_activities`, `.o_fc_bottleneck` — left-column section backgrounds
|
||||
- `.o_fc_tile`, `.o_fc_tile--urgent` (with `.o_fc_tile__num`) — workflow stage tiles
|
||||
- `.o_fc_countdown--info` / `.o_fc_countdown--warning` / `.o_fc_countdown--danger` / `.o_fc_countdown--muted` — countdown widget colour levels (driven by OWL state)
|
||||
|
||||
### 9.4 Verification
|
||||
|
||||
After deploy, in `odoo-shell`:
|
||||
|
||||
```python
|
||||
env['ir.qweb']._get_asset_bundle('web.assets_backend').css() # light bundle URL
|
||||
env['ir.qweb']._get_asset_bundle('web.assets_web_dark').css() # dark bundle URL
|
||||
```
|
||||
|
||||
The two URLs must differ. If they're identical, the dark bundle didn't recompile — fix by deleting `ir.attachment` rows under `/web/assets/%` and restarting Odoo.
|
||||
|
||||
## 10. OWL countdown widget
|
||||
|
||||
### 10.1 Why a widget
|
||||
|
||||
The rest of the dashboard is fine being recomputed on page open — case counts move slowly. The countdown ("3 days 4 hours to cutoff") needs to tick without a page refresh, and its colour needs to shift as the deadline approaches (info → warning → danger).
|
||||
|
||||
### 10.2 Behaviour
|
||||
|
||||
- Registered as a field widget under the name `fc_posting_countdown`.
|
||||
- Reads `submission_deadline_dt` from `props.record.data`.
|
||||
- Ticks every 60 seconds via `setInterval`. Cleared on `onWillDestroy`.
|
||||
- Four levels with auto-shift:
|
||||
- `> 3 days remaining` → **info** (banner text colour)
|
||||
- `1–3 days` → **warning** (amber)
|
||||
- `< 24 hours` → **danger** (urgent-num colour)
|
||||
- `past deadline` → **muted** (text-muted colour), text reads "Cutoff passed"
|
||||
- Uses Luxon for date math (already loaded by Odoo).
|
||||
|
||||
### 10.3 Template
|
||||
|
||||
```xml
|
||||
<templates xml:space="preserve">
|
||||
<t t-name="fusion_claims.PostingCountdown" owl="1">
|
||||
<span t-att-class="'o_fc_countdown o_fc_countdown--' + state.level"
|
||||
t-esc="state.text"/>
|
||||
</t>
|
||||
</templates>
|
||||
```
|
||||
|
||||
### 10.4 Use in form view
|
||||
|
||||
```xml
|
||||
<field name="submission_deadline_dt"
|
||||
widget="fc_posting_countdown"
|
||||
nolabel="1"
|
||||
readonly="1"/>
|
||||
```
|
||||
|
||||
## 11. Manifest changes
|
||||
|
||||
```python
|
||||
'version': '<bump minor>', # e.g. 19.0.8.0.7 → 19.0.9.0.0 for asset cache-bust per CLAUDE.md §Asset Cache Busting
|
||||
|
||||
'data': [
|
||||
# ...existing entries (data files load order unchanged)...
|
||||
'views/dashboard_views.xml', # rewritten
|
||||
],
|
||||
|
||||
'assets': {
|
||||
'web.assets_backend': [
|
||||
# ...existing entries...
|
||||
'fusion_claims/static/src/scss/_fc_dashboard_tokens.scss', # tokens FIRST
|
||||
'fusion_claims/static/src/scss/fc_dashboard.scss',
|
||||
'fusion_claims/static/src/js/fc_posting_countdown.js',
|
||||
'fusion_claims/static/src/xml/fc_posting_countdown.xml',
|
||||
],
|
||||
'web.assets_web_dark': [
|
||||
'fusion_claims/static/src/scss/_fc_dashboard_tokens.scss',
|
||||
'fusion_claims/static/src/scss/fc_dashboard.scss',
|
||||
# No JS in dark bundle — Odoo loads JS once from backend.
|
||||
],
|
||||
},
|
||||
```
|
||||
|
||||
Token file is registered **before** layout file in **both** bundles. JS+XML only in backend.
|
||||
|
||||
## 12. Edge cases
|
||||
|
||||
### 12.1 Pre-first-posting
|
||||
|
||||
If today < `fusion_claims.adp_posting_base_date` (default 2026-01-23), `_get_current_posting_date()` returns the base date itself. Treatment:
|
||||
|
||||
- `posting_period_label` reads `"Posting starts Jan 23"`.
|
||||
- `submission_deadline_dt` set to first Wednesday at 18:00.
|
||||
- KPI tiles all show `$0 / 0` (no posting period to bill against yet).
|
||||
- `is_pre_first_posting=True` is exposed; view shows a one-line info note above the KPIs.
|
||||
|
||||
### 12.2 No invoices / empty system
|
||||
|
||||
All counts compute to 0. KPI tiles render `$0.00`. Activities section renders an empty-state message ("No activities assigned"). Bottleneck section hides itself when both counts are zero.
|
||||
|
||||
### 12.3 Sales rep with no assigned SOs
|
||||
|
||||
`_role_filter_domain()` returns `[('user_id', '=', user.id)]`. All counts → 0. The form still renders; "Showing your cases" hint plus an empty-state message ("You have no assigned cases").
|
||||
|
||||
### 12.4 Portal user accidentally clicks dashboard menu
|
||||
|
||||
The dashboard menu is already gated by `groups_id` on the existing menu item to `fusion_claims.group_fusion_claims_user` (internal users only). Confirm this is preserved in the rewritten `dashboard_views.xml`.
|
||||
|
||||
### 12.5 Currency mix
|
||||
|
||||
KPI sums assume a single company currency. `currency_id` defaults to `company_id.currency_id`. If invoices in another currency exist, they are summed in their own currency by Odoo's standard behaviour — out of scope to handle multi-currency for this dashboard. Document this limitation in the design note.
|
||||
|
||||
## 13. Decisions explicitly excluded
|
||||
|
||||
- **Auto-refresh on window focus** — considered, dropped to keep scope tight. Manual refresh via form header button is sufficient.
|
||||
- **The 4 configurable HTML panels from the existing dashboard** — removed entirely. If a "Recent Cases" view is needed later, that's a separate spec.
|
||||
- **Per-funder workflow tiles for ODSP / WSIB / Insurance / MDC / Hardship** — those funders get a count card only, not a row of stage tiles. Decision: keep the dashboard focused on the two highest-volume funders (ADP, MOD).
|
||||
- **Toggle between "My Cases" and "All Cases"** — group-based auto-filter only. Sales reps see their cases, managers see everything, no switch.
|
||||
|
||||
## 14. Acceptance criteria
|
||||
|
||||
1. Dashboard menu opens to a single page; old 4-panel UI gone.
|
||||
2. Banner shows current posting period and a live (ticking) countdown to Wed 6 PM cutoff.
|
||||
3. 3 KPI tiles render with correct dollar amounts for Ready / Claimed This Period / Total AR.
|
||||
4. 8 quick-action pills open a fresh SO form with the correct `x_fc_sale_type` pre-applied.
|
||||
5. All 17 workflow tiles show non-stale counts (verified by clicking a tile → resulting SO list count matches the tile number).
|
||||
6. Both bottleneck callouts compute and render; clicking opens the matching filtered SO list.
|
||||
7. Sales reps see only their own cases; managers see all.
|
||||
8. Light and dark themes render the dashboard without any invisible / low-contrast elements. Verified by:
|
||||
- Opening in light mode → no `display:none`-like artifacts, all text readable.
|
||||
- Switching to dark mode (user profile → Color Scheme → Dark → reload) → all colours shift to the dark palette, banner gradient is the cool blue monochrome.
|
||||
9. Asset bundles compile to distinct URLs in both themes (verified with the §9.4 snippet).
|
||||
10. No regression on existing dashboard menu item / action references — module loads cleanly, no XML resolution errors.
|
||||
|
||||
## 15. Open questions / non-decisions
|
||||
|
||||
None. All design choices are locked in. Implementation plan can proceed.
|
||||
Reference in New Issue
Block a user