gigafibre-fsm/apps/ops/src/components
louispaulb 218f6fc7b1 feat(ops): Service Contract detail view + sub-delete redirects there
Contract termination is a fee-bearing, auditable workflow — it belongs
on the contract, not buried in a sub's delete dialog. Standard SaaS /
telecom practice: subs are an immutable event stream, contracts
orchestrate their lifecycle.

ServiceContractDetail.vue (new)
  • Status banner: contract type, dates, status — "Résilier" button
    when actionable, termination invoice link when already résilié.
  • Term progress bar: months_elapsed / duration_months with color
    ramp (primary → amber near end → positive when done).
  • Financial summary grid: mensualité, abonnement (clickable), devis,
    lieu, total avantages, résiduel, signature method & date.
  • Benefits detail table: per-row description, regular_price vs
    granted_price, économie, reconnu à date, et "À rembourser"
    (valeur résiduelle) — this is what the rep needs to see before
    deciding to break a contract.
  • Termination recap (only when status=Résilié): date, raison,
    penalty breakdown, link to the termination invoice.
  • "Résilier" action runs a 2-step dialog: first calls
    /contract/calculate-termination for the preview, then prompts for
    a reason (textarea, min 3 chars) before firing /contract/terminate.
    On success: cascade-cancels the linked sub (status=Annulé +
    end_date + cancellation_date — no hard delete), mutates the
    local doc so the modal refreshes in place, and emits
    contract-terminated so the parent page updates its sub + contract
    rows + drops an audit comment on the customer.

DetailModal
  • SECTION_MAP now routes Service Contract → ServiceContractDetail.
    Also added 'Service Subscription' → SubscriptionDetail (same
    template fits; was falling through to the generic grid).
  • Re-emits contract-terminated so the parent can listen.

ClientDetailPage
  • confirmDeleteSub: when a live contract references the sub, the
    dialog now simply redirects the rep to the contract modal
    ("Voir le contrat") instead of trying to do termination from
    the sub row. Terminal-state contracts (Résilié/Complété/Expiré)
    still get the inline link-scrub path so stale refs don't block
    a legit delete.
  • onContractTerminated: reflects the cascade locally — contract
    row → Résilié, sub row → Cancelled + end_date, audit Comment
    posted to the customer's notes feed.
2026-04-23 14:46:34 -04:00
..
customer feat: dispatch planning mode, offer pool, shared presets, recurrence selector 2026-04-08 22:44:18 -04:00
dispatch refactor: reduce token count, DRY code, consolidate docs 2026-04-13 08:39:58 -04:00
flow-editor docs: reorganize into architecture/features/reference/archive folders 2026-04-22 11:51:33 -04:00
shared feat(ops): Service Contract detail view + sub-delete redirects there 2026-04-23 14:46:34 -04:00