Migrates Enterprise account_followup per-partner state to Fusion fields:
- res.partner.followup_status -> fusion_followup_status (action_due/no_action)
- res.partner.payment_next_action_date -> fusion_followup_paused_until
(when future-dated; sets status to 'paused')
- res.partner.followup_line_id -> fusion_followup_last_level_id
(resolved by name match against migrated levels)
Wired into fusion.migration.wizard.action_run_migration after the
existing _followup_bootstrap_step. Idempotent: skips partners whose
Fusion state is already non-default. Defensive against missing
Enterprise fields (each field probed individually before use).
Closes the per-partner state migration gap that was blocking
Enterprise account_followup uninstall.
Made-with: Cursor
V19 removed the 'rpc' service from the registry. All 4 fusion services
(bank_reconciliation, reports, assets, followup) declared dependencies:
['rpc', ...] and accessed services.rpc in their constructor. At runtime
this caused:
Error: Some services could not be started: fusion_bank_reconciliation,
fusion_reports, fusion_assets, fusion_followup. Missing dependencies: rpc
\u2014 which prevented the entire OWL backend from booting (blank screen).
Fix per V19 docs:
- Add 'import { rpc } from "@web/core/network/rpc";'
- Set 'this.rpc = rpc;' in constructor (instead of services.rpc)
- Remove 'rpc' from dependencies list
This is the workspace CLAUDE.md guidance Phase 4's subagent flagged
but didn't act on for backward consistency. V19 actually removed the
service entirely, so the consistency choice was wrong \u2014 fixing now.
All call sites still use this.rpc(...) so no per-method changes needed.
Bundle rebuilt clean; backend boots correctly.
Made-with: Cursor
- test_create_minimal/negative_delay used sequence=1, which now collides
with the seeded Friendly Reminder level. Use sequences 901/902.
- migration backfill: search by name (not raw seq) for idempotency,
allocate sequence as max(existing)+1 to avoid both seed clashes and
within-batch collisions when Enterprise has duplicate sequence values.
Made-with: Cursor
- fusion.followup.cron AbstractModel with two handlers
- cron_fusion_followup_daily_scan: walks every overdue partner and
delegates to engine.send_followup_email
- cron_fusion_followup_risk_refresh: weekly refresh of
fusion_followup_risk_score / risk_band on res.partner
- V19 ir.cron records (no numbercall field)
- 2 smoke tests added (80 total)
Made-with: Cursor
- Switch FUSION_MODEL to fusion.followup.engine so adapter mode
selection matches the new module
- Add list_overdue() with fusion/enterprise/community variants
- Re-route send_followup_via_fusion to engine.send_followup_email
- 4 new TransactionCase tests (73 total)
Existing aging / overdue_invoices adapter methods continue to fall
back to the community implementation.
Made-with: Cursor
End-to-end flows over a real posted receivable line: aging discovery,
level resolution, send-with-cache reuse, pause+force override, and
audit history growth. Adds ignore_pause kwarg to compute_followup_level
so force=True in send_followup_email reaches level resolution.
Made-with: Cursor
The orchestrator AbstractModel for follow-up lifecycle.
get_overdue_for_partner, compute_followup_level, send_followup_email,
escalate_to_next_level, pause_followup, reset_followup, snapshot_followup_history.
All controllers, AI tools, wizards, cron must route through these
methods; no direct ORM writes to fusion.followup.run from anywhere else.
Made-with: Cursor