docs(fusion_maintenance): correct backfill for lifts (no serials) after live sizing
Live sizing on Westin: stair lifts ~254 customers / porch-VPL ~30 / lift chairs ~41, but lift serial coverage ~0 (12/416 stairlift lines). The serial-as-unit-key approach (valid for ADP wheelchairs) fails for lifts. Backfill now splits into two regimes: serial dedup for wheelchairs; partner+base-product+sale-line dedup for lifts with accessory-line exclusion via the per-product maintainable flag. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -81,8 +81,13 @@ Source: [`fusion_repairs/models/maintenance_contract.py`](../../../fusion_repair
|
||||
- ADP‑side base ≈ **138 serial‑tracked units / ~136 customers** (walkers 68, wheelchairs 45, power
|
||||
bases 7, scooters 4, +14 no‑device‑type). Funders: adp 109, direct_private 13, adp_odsp 10,
|
||||
march_of_dimes 7. Deliveries 2022‑10 → 2026‑05.
|
||||
- **Lifts are NOT in the ADP data** (private‑pay) — their count must be sized from lift‑category
|
||||
sale lines at implementation time (see §15).
|
||||
- **Lifts (sized 2026‑06‑02; name‑based, approximate)** — a LARGE base in Westin's Odoo: stair lifts
|
||||
~254 customers (416 lines incl. accessories), porch/VPL ~30 customers (75 lines), lift chairs ~41
|
||||
customers (47 lines) — real products (Access BDD, Handicare, Serenity VPL, Pride VivaLift). **But lift
|
||||
serial coverage is ~0** (12/416 stairlift lines, 0 VPL, 2 lift‑chair). So the serial‑as‑unit‑key
|
||||
approach that works for ADP wheelchairs **does NOT work for lifts** — lifts must be keyed by
|
||||
(partner + base‑unit product + sale line), excluding accessory lines (curves, rails, remotes, charging
|
||||
stations, rentals). This splits the backfill into two regimes (§6.2).
|
||||
- Two backfill data gaps: 14 units have no device_type (need product/manual category); non‑ADP units
|
||||
lack `x_fc_adp_delivery_date` (need an invoice/order‑date fallback anchor).
|
||||
|
||||
@@ -152,12 +157,14 @@ method; fix + wire it). For each confirmed line whose product/category has
|
||||
|
||||
### 6.2 Path B — backfill existing install base (one‑time wizard, idempotent)
|
||||
`fusion.repair.maintenance.backfill.wizard`:
|
||||
- **Scan** historical `sale.order.line` for products whose category is maintenance‑enabled **and**
|
||||
that have a serial **and** were delivered. Two sources:
|
||||
- **Lifts / repairs‑side** equipment — lift categories (`lift_elevating` etc.).
|
||||
- **Wheelchairs / power chairs** — via the `fusion_claims` serial/`device_type` data (soft dep,
|
||||
guarded). Map ADP `device_type` → maintenance category.
|
||||
- **Dedup** strictly by serial (one active contract per unit).
|
||||
- **Scan** historical `sale.order.line` for products whose category/product is maintenance‑enabled and
|
||||
were delivered. **Two unit‑identity regimes**, because lifts carry no serials (§3.3):
|
||||
- **Serial‑tracked** (ADP wheelchairs/power chairs, via the `fusion_claims` serial/`device_type` data
|
||||
— soft dep, guarded; map ADP `device_type` → maintenance category): require a serial, **dedup by serial**.
|
||||
- **Non‑serial** (lifts — stair/porch/VPL/lift‑chair): do **NOT** require a serial. One contract per
|
||||
**base‑unit line**, **dedup by (partner + maintainable product + source sale line)**. The per‑product
|
||||
`x_fc_maintenance_enabled` flag is what includes base units and **excludes accessory lines** (curves,
|
||||
rails, remotes, charging stations, rentals) — only the lift itself gets a contract, not its add‑ons.
|
||||
- **Stagger** the first `next_due_date` across a configurable window (e.g. spread overdue units over
|
||||
N weeks) so years of equipment don't all email on day one.
|
||||
- **Dry‑run first**: produce a report (counts by category, # new vs already‑enrolled, # skipped for
|
||||
@@ -249,7 +256,7 @@ old link stays valid across cycles). Old token → friendly "link expired" page.
|
||||
`fusion_tasks` over Enterprise `appointment` — the **entire feature is Community‑testable** on
|
||||
`odoo-modsdev`. `TransactionCase` coverage:
|
||||
- Contract spawn on `sale.order` confirm (enabled vs disabled category; quantity; idempotency).
|
||||
- Backfill wizard: dedup by serial, stagger, dry‑run produces no records, anchor fallback.
|
||||
- Backfill wizard: **two‑regime dedup** (serial for wheelchairs; partner+product+line for lifts), accessory‑line exclusion, stagger, dry‑run produces no records, anchor fallback.
|
||||
- Booking: slot list comes from real gaps; confirm creates task+repair+visit; **double‑book guard**;
|
||||
no‑slot fallback.
|
||||
- Roll‑forward on completion: dates advance, band reset, **token regenerated**, visit → done.
|
||||
@@ -274,8 +281,10 @@ old link stays valid across cycles). Old token → friendly "link expired" page.
|
||||
hours source) and whether they already account for travel windows.
|
||||
- The visit‑report wizard's current fields/flow before extending it with the checklist.
|
||||
- The inspection‑certificate issue API (how M1 creates a certificate) for the lift link.
|
||||
- **Size the lift install base** on Westin (lift‑category sale lines with serials) — not yet counted;
|
||||
needed to set expectations and the backfill stagger window.
|
||||
- **Lift base sized** (§3.3): ~254 stairlift + ~30 porch/VPL + ~41 lift‑chair customers, but ~0 serials.
|
||||
Still to verify: which exact products are **base units vs accessories** (so `x_fc_maintenance_enabled`
|
||||
lands on base units only), plus the lift interval/fee per category. Lift products aren't yet tagged
|
||||
with `fusion_repairs` categories on Westin (module not deployed there) — categorization is a deploy step.
|
||||
- `fusion_claims` device_type → maintenance‑category mapping table for the wheelchair backfill.
|
||||
|
||||
## 16. Build sequence (for the implementation plan)
|
||||
|
||||
Reference in New Issue
Block a user