Skip to content

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:

  1. Vendors — get every vendor in the register, then commit
  2. Locations — every department / location, then commit
  3. 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):

  1. External ID — if the External ID (or id) column is filled on a row, Odoo looks up that external_id via env.ref(). Wins over business-key matching. Records the module created on first import are findable this way (Odoo auto-registers them under __import__.X).
  2. Business key — per object type:
  3. Equipment — by ref (gov asset no, enforced unique by roots_hemms_asset_master)
  4. Vendor — layered ladder:
    1. vat if present
    2. name + country_id if country present
    3. name alone (emits WARN with candidate IDs — see Vendor name-only collisions)
  5. 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:

  1. Open the error XLSX in Excel; sort by Field or filter by Severity.
  2. Fix the underlying issues in your source file (NOT the error file — it's a report, not an editable template).
  3. 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.