Workflows¶
Object order: vendors → locations → equipment¶
Equipment rows reference vendors (by name) and departments (by complete_name). If you import equipment FIRST, every row whose vendor or department doesn't yet exist will FAIL with a clear "Vendor X not found — run vendor import first" reason.
Recommended sequence on a fresh hospital:
- Vendors — get every vendor in the register, then commit
- Locations — every department / location, then commit
- Equipment — once vendors and locations resolve, equipment rows go OK
The 1-hour preview-cache TTL is intentionally long enough that you can prepare all three files in advance, import vendors, then move to locations, etc., all in the same session.
Re-import with corrections¶
The mass-import flow is fully idempotent — re-uploading the same file (or a corrected version of it) upserts existing records rather than creating duplicates.
Matching priority (per plan D5 / D6):
- External ID — if the
External ID(orid) column is filled on a row, Odoo looks up that external_id viaenv.ref(). Wins over business-key matching. Records the module created on first import are findable this way (Odoo auto-registers them under__import__.X). - Business key — per object type:
- Equipment — by
ref(gov asset no, enforced unique byroots_hemms_asset_master) - Vendor — layered ladder:
vatif presentname+country_idif country presentnamealone (emits WARN with candidate IDs — see Vendor name-only collisions)
- Location — by computed
complete_name
The Step 2 preview's Match column shows which row will be created vs upsert #X so you can verify before commit.
Deleting a batch¶
Open the batch record (Maintenance → Configuration → Mass-Import Batches) and click 🗑 Delete Batch. The action checks all of:
| Guard | Who can bypass |
|---|---|
Batch state must be committed | Nobody — uncommitted batches have nothing to delete |
| Within 7 days of commit | Equipment managers can force past this |
No maintenance.request (PM event) references tagged equipment | Equipment managers can force past this — but unlink will cascade-orphan the PM events |
No hemms.service.contract (Q3) references tagged equipment or vendor | Equipment managers can force past this |
| For location batches: no equipment references the tagged department | Equipment managers can force past this |
When blocked, the Delete Audit section on the batch form shows the specific reason (e.g., "3 maintenance request(s) reference equipment in this batch — resolve or archive them before deleting."). The batch stays in committed state — nothing is unlinked.
On a clean delete, every tagged record is unlinked via roots_hemms_import_batch_id lookup, the batch transitions to deleted state, deleted_at / deleted_by_id get stamped, and the chatter posts an audit line.
Error XLSX recovery¶
When a dry-run produces FAIL rows, the ⬇ Download Error XLSX button on the batch form (visible whenever row_count_fail > 0) returns a single-sheet workbook:
| Row | Verdict | Field | Severity | Message | Raw Value |
|---|---|---|---|---|---|
| 17 | fail | partner_id/name | fail | Vendor 'Acme XYZ' not found — run vendor import first. | Acme XYZ |
| 42 | fail | ref | fail | Equipment Ref. No. (ref) is required | (blank) |
| 88 | fail | (business_key) | fail | Duplicate row in this file — business key ('equipment', 'A-0042') already used by an earlier row. |
Workflow:
- Open the error XLSX in Excel; sort by
Fieldor filter bySeverity. - Fix the underlying issues in your source file (NOT the error file — it's a report, not an editable template).
- Re-upload the corrected source file into a new batch. The previously-committed OK rows will upsert (no duplicates); the formerly-FAIL rows now succeed.
The error XLSX always reflects the LAST dry-run. If you re-run the dry-run on the same batch (e.g., after the system was patched), the error XLSX updates accordingly.
Vendor name-only collisions¶
Layer C of the vendor matching ladder (name alone) emits a WARN verdict. There are two flavors:
| Scenario | Behavior |
|---|---|
Exactly one existing res.partner with that name | Upsert into it; WARN message says "Matched on name only — consider adding VAT or country to disambiguate future re-imports." |
Multiple existing res.partner records share that name | Upsert into the first (lowest id) deterministically; WARN message lists ALL candidate ids and recommends the post-import dedupe path |
WARN rows still commit (they don't block the batch). Post-import, the recommended cleanup is Odoo's standard Contacts → Merge Wizard — or, more frequently, just edit your source file to add VAT or country to the colliding rows and re-import.
This is the deliberate trade-off documented in plan §9 — onboarding ease beats strict uniqueness for the typical hospital migration.
Splitting a large register across files¶
The 5,000-row cap (plan D10, config-driven) is the safe boundary for transaction-commit time. Larger registers split naturally:
- File 1 — rows 1–5,000
- File 2 — rows 5,001–10,000
- ...
Upload them sequentially in the same session. The 1-hour preview TTL keeps each batch's verdict cache warm long enough to do realistic chunked imports without re-uploading anything.
Each chunk becomes its own batch (own audit trail, own import_batch_id tag on records). To "undo" all chunks at once, delete each batch — they're independent.