Skip to content

Service Contracts

The Service Contracts module (roots_hemms_service_contracts) lets the BME team capture every warranty, MA, and vendor agreement in one place, then auto-link the active contract to every new corrective request so technicians know — at the moment they open a ticket — whether the vendor will cover the work or the hospital pays.

Key features

1. One record per vendor agreement

Each contract is a hemms.service.contract with a running reference (SC/2026/00001) covering one or many equipment, one vendor, a contract type (Warranty / Extended Warranty / MA / Spare-only / Labor-only), start and end dates, and an optional SLA tier.

2. Per-kind coverage scope

Inside every contract, a Coverage tab lets you mark each maintenance.kind as Included (within scope) and Billable to Hospital (parts billed separately even on a covered job). Q3.5 reads those two booleans to set roots_is_billable_to_hospital on every new request.

When a technician opens a corrective request on covered equipment, the form auto-fills roots_service_contract_id with the equipment's most recent active contract — and a coverage banner above the title spells out the consequence:

  • ✅ Covered by SC/2026/00003 (GE Healthcare) — vendor pays
  • ✅ Covered by SC/2026/00003 (GE Healthcare) — hospital billable
  • ⚠ Covered by SC/2026/00003 but kind not in coverage — hospital pays
  • ⚠ Out of contract — hospital pays

The technician can manually override the picked contract; the compute will not clobber the override on subsequent edits.

4. Renewal alert before expiry

A daily cron promotes contracts draft → active → expired based on dates, then fires a mail.activity on the Responsible user for any active contract whose end date is within roots_renewal_alert_days (default 60). The single-threshold default matches plan D7 — multi-stage (90/60/30/7) is on the Q4 roadmap.

5. SLA tier display

Every contract carries a roots_sla_tier (bronze / silver / gold / platinum) plus a free-form roots_sla_response_hours. Q3 displays these on the form and list views; SLA-breach detection compares request.create_date to first_response_date and is the Q4 vendor scorecard hook.

6. Bilingual everywhere

Contract title, contract type, and search all support roots_name_th so Thai-language users can find a contract by its TH label.

7. Three stat-button drilldowns

  • Vendor partner form → "X Service Contracts"
  • Equipment form → "X Contracts" + Under Warranty badge in header
  • Contract form → "Equipment" + "Requests" stat buttons

Module architecture

Layer 3 — roots_hemms_service_contracts (this module)
Layer 2 — maintenance_partner (OCA)            ← vendor link on equipment
Layer 2 — roots_hemms_pm                       ← maintenance.kind vocabulary
Layer 2 — roots_hemms_asset_master             ← equipment master with brand/model
Layer 1 — maintenance + mail (Odoo base)

A deliberate non-dependency: we do not vendor OCA maintenance_equipment_contract. That module is ~25 lines on top of OCA contract (recurring invoicing) which depends on account — hospitals track warranty/MA coverage and SLA tiers, not recurring invoices. The lean Layer 3 model mirrors the m2m equipment ↔ contract field shape without the invoicing baggage. See plan §2 (D1) for the rationale and revisit conditions.

Where to next

  • Get Started — create your first contract in 10 minutes
  • Configuration — contract types, sequence, SLA, ACL
  • Workflows — drafting, activating, renewing, cancelling
  • Reporting — filters, drilldown, KPIs to monitor