Service Contracts: Reporting¶
The module ships with four dedicated menus, eight search filters, five group-by axes, and three stat-button drilldowns. This page covers the most common reporting patterns.
Four dedicated lenses¶
:menuselection:Maintenance --> Service Contracts:
| Menu | Default filter | Best for |
|---|---|---|
| All Contracts | none — grouped by State | quarterly review, audit |
| Active | state=active | "what's running right now" |
| Expiring Soon (≤90d) | state=active AND date_end <= today+90 | procurement queue |
| Expired | state=expired | renewal post-mortem, gap analysis |
Each lens has its own ir.actions.act_window so you can bookmark the URL or pin it to a user's home dashboard.
Search filters¶
In any list view, click the search bar and scroll to Filters:
| Filter | Domain | Use case |
|---|---|---|
| My Contracts | user_id = uid | personal queue |
| Active | state = active | currently running |
| Draft | state = draft | not started, pending negotiation |
| Expired | state = expired | historical, off-contract analysis |
| Expiring Soon (≤90d) | state = active AND date_end <= today + 90d | procurement planning |
| Under Warranty | contract_type_id.code in ('warranty', 'ext_warranty') | finance vs vendor split |
| Gold / Platinum SLA | roots_sla_tier in ('gold', 'platinum') | high-priority watch |
| Not Yet Alerted | roots_renewal_alerted = False AND state = active | identify cron gaps |
Group-by axes¶
| Group | What you see |
|---|---|
| State (default on All) | counts per state, quick health pulse |
| Vendor | concentration risk, top-3 vendors |
| Contract Type | warranty vs MA mix |
| SLA Tier | bronze ↔ platinum distribution |
| End Date (by Month) | the next-12-month renewal calendar |
Combine filters and group-bys for views like "Gold-tier contracts expiring this quarter, grouped by vendor" — useful for vendor renewal negotiations.
Bilingual search¶
The search box on the contract list searches reference + name + roots_name_th simultaneously. A user typing สัญญา MA เครื่อง MRI will get the contract whose Thai name matches — without having to remember the English title or reference.
The same search is wired on hemms.contract.type (via the bilingual _compute_display_name) so the type picker on a contract form works with Thai or English input.
Drilldown stat buttons¶
Three stat-button paths let you cross-navigate the contract ↔ equipment ↔ vendor trio in one click:
From the vendor partner form¶
:menuselection:Contacts --> [vendor] → Service Contracts stat button → opens a list of contracts where partner_id = this vendor.
- Visible only when the vendor has at least one contract (the button is hidden via
invisible="roots_service_contract_count == 0") - Useful for vendor reviews, "what do we buy from this firm?"
From the equipment form¶
:menuselection:Maintenance --> Equipment --> [equipment] → Contracts stat button → opens contracts where equipment_ids includes this equipment.
The equipment header also shows two read-only badges:
- Under Warranty — True when the active contract's type code is
warrantyorext_warranty - Active Contract (hidden, used by the request auto-link) — available in form for technicians who toggle developer mode
From the contract form¶
Inside a contract, two stat buttons sit at the top:
- Equipment — opens the equipment list filtered to this contract's
equipment_ids - Requests — opens
maintenance.requestrecords whereroots_service_contract_id = this contract. Useful for vendor SLA review, billing reconciliation, and post-renewal "did we get value?" analysis
Renewal activity tracking¶
Every renewal alert is a mail.activity on the contract owner (user_id). To see all open renewal alerts across the firm:
- Activities → :menuselection:
Filters --> Document Model --> HEMMS Service Contract - Filter by Summary containing "Renewal due"
Or click the bell icon in the top-right corner of Odoo to see your own queue.
KPIs to monitor¶
A small set of metrics tells the BME manager whether the contract portfolio is healthy:
| KPI | Where to find it | Healthy range |
|---|---|---|
| Contract coverage ratio | (active contracts × avg equipment) ÷ total equipment | > 70 % on red-tier equipment |
| Expiring-soon backlog | "Expiring Soon" lens row count | < 10 % of active contracts |
| Not-yet-alerted active | "Not Yet Alerted" filter row count | should be 0 except for 60-day-fresh contracts |
| Stale draft contracts | filter state=draft AND date_start <= today | should be 0 — cron should promote within 24h |
| Vendor concentration | group-by Vendor, top-1 share | < 50 % to avoid single-vendor lock-in |
| SLA tier mix on red equipment | filter red equipment + group-by SLA tier | gold + platinum > 80 % on critical |
Exporting for finance¶
Contract records support standard Odoo export (Action → Export):
- Fields commonly needed:
reference,name,partner_id.name,contract_type_id.name,date_start,date_end,state,roots_sla_tier,equipment_count,request_count - Coverage lines export separately from
hemms.service.contract.coverage.line; export withcontract_id.referenceas the join key
For PDF audit packs, attach signed contract PDFs to the mail.thread chatter and combine via the Q4 e-Signature module's roots_hemms_signature PDF stamp (when bridged to contracts in a future quarter).
Audit-trail / chatter¶
Every contract has a full mail.thread + mail.activity.mixin chatter on the form. Tracked fields (changes logged automatically):
name,reference,partner_id,contract_type_iddate_start,date_endstate(every transition)user_id(handoff between BME staff)roots_sla_tier
For HA Thailand surveys and JCI audits, the chatter is the immutable record of who changed what and when — the surveyor's first question on any flagged contract.