In this piece
Odoo BMD export: reconcile the batch before monthly handoff
A fictional export batch totals EUR 300.00. Two documents still carry the wrong amounts. The example below shows why the file and its grand total cannot prove a correct handoff.
Reconcile an Odoo-to-BMD handoff against the approved source documents, the exact export profile and the destination’s acceptance evidence. Compare identities and individual amounts before relying on totals. Keep credits, company boundaries and changed revisions visible. Confirm which records the receiving team accepted before closing the handoff.
Research checked: 5 November 2026. We inspected official Odoo documentation, BMD’s published interface-course outline and version-specific vendor material. We executed thirteen synthetic Python comparison cases. No Odoo export, BMD import, customer accounting data or finance approval was tested. The downloadable model is a normalized example, not a BMD file format.
What must an Odoo-to-BMD handoff prove?
An Odoo-to-BMD handoff must establish three separate things: the correct source population was selected, the export preserves its approved meaning, and the destination accepted the intended documents. Give each stage an identity and evidence. A completed download proves that a file exists; the receiving records establish what happened after that file arrived.
Ask the receiving team to define an accepted batch. Does it mean documents prepared for review or entries imported into a defined workspace? Record the agreed outcome. A shared “imported” status is ambiguous if the teams mean different things by it.
| Boundary | Evidence to retain | Question it answers |
|---|---|---|
| Approved source | Snapshot, company, period, document states and exclusions. | Which business documents should move? |
| Produced batch | Connector/profile revision, exact file identity and per-document comparison. | What meaning did this export carry? |
| Destination result | Import report, accepted/rejected document references and unresolved items. | Which intended records did the recipient accept? |
A batch can pass the export comparison while destination acceptance remains unknown. Keep that state visible, with evidence both teams can inspect.
Which connector and import profile are you validating?
Validate the exact combination of Odoo version, edition, installed connector revision and BMD receiving profile. Ask the owner to demonstrate a representative document through that combination. A product name alone cannot establish how the receiving system will interpret your records.
For example, MPI describes its BMD module for Odoo 19, with Enterprise Accounting, Austrian localization and configurable export columns. That is a version-specific vendor description. Confirm Odoo 20 support separately if that is your target.
Odoo’s 20.0 Austrian localization documentation covers accounting/report modules and SAF-T XML export. Those features do not establish the format required by your selected BMD import profile.
BMD’s standard-interface course outline separates master-data, balance and booking-file imports, and covers import errors and notices. The outline is not a complete field specification. Obtain the applicable profile and mapping requirements from the receiving owner before implementing a file layout.
Include credit documents and corrections in the demonstration, with their attachments if required. An ordinary invoice does not exercise those paths. Record any manual destination preparation needed to make the example work.
When hosting or API access determines the available integration path, use the existing Odoo integration architecture guide. The acceptance contract here remains useful whether a person delivers the approved file or an automated workflow transfers it.
What belongs in the monthly export contract?
The export contract should freeze the intended document population, its approved transformations and the evidence required at the destination. Name who may change those decisions. Bind approval to the source snapshot and batch revision; a later source edit or mapping change requires review.
| Decision | Specify before export | Evidence to inspect |
|---|---|---|
| Population | Company, posting period, allowed states and explicit exclusions. | Approved source references and extraction parameters. |
| Identity | Stable source key, revision and destination reference. | Each source document remains traceable through the handoff. |
| Amounts | Currency, net/tax/gross basis and agreed precision. | Individual values plus totals grouped by company and currency. |
| Mappings | Approved account, partner and tax interpretation for the selected profile. | Named mapping revision and responsible finance reviewer. |
| Credits and corrections | Document relationships and the receiving profile’s approved treatment. | A representative correction reaches the intended destination result. |
| Supporting documents | Required files, identity and authorized recipient access. | The right document is retrievable from the right business record. |
| Completion | What acceptance means and how partial or unknown results are resolved. | Destination evidence tied to this batch and its documents. |
Separate document date from the period used for this handoff. Decide how late arrivals and corrections enter a later batch, including who approves the treatment. The comparator checks the agreed rule. Finance must approve its accounting treatment.
Keep the source reference independently reviewable. If the same faulty transformation generates both the export and its expected values, the comparison can agree with the mistake. Check selected source documents directly against the approved mapping before trusting the aggregate control.
The separate invoice exception workflow owns unresolved intake decisions. An export should not conceal an unresolved source question by converting it into a plausible destination value.
Why can a correct total still hide wrong documents?
A correct total can hide wrong documents because opposite errors cancel when added together. Counts also discard identity. Compare each approved source document with its exported counterpart, then use grouped totals as an additional control. Our synthetic example keeps three documents and every amount total unchanged while two documents contain incorrect net and gross values.
| Document | Net | Tax | Gross |
|---|---|---|---|
| INV-001 | 100.00 | 20.00 | 120.00 |
| INV-002 | 200.00 | 40.00 | 240.00 |
| CR-001 | -50.00 | -10.00 | -60.00 |
| Total | 250.00 | 50.00 | 300.00 |
The negative credit is an example convention. These amounts do not prescribe a BMD sign convention or establish a valid tax treatment. The fictional mapping label DEMO-MAP-1 has no accounting authority.
Now change the first invoice to net EUR 101.00 and gross EUR 121.00. Change the second to net EUR 199.00 and gross EUR 239.00. Leave both tax values and the credit unchanged. Net remains EUR 250.00, tax EUR 50.00 and gross EUR 300.00. Each line still satisfies the example’s net-plus-tax arithmetic.
The document comparison finds four differences: net and gross on each of two invoices. Those differences block the candidate despite its matching totals. Keyed comparison still cannot validate the reference values themselves or prove a real accounting export.
What did the thirteen model cases demonstrate?
The thirteen executed cases demonstrate how a normalized comparison can distinguish source differences, a clean candidate without an import receipt, and an incomplete destination acknowledgment. The script uses invented JSON documents and Python’s standard library. It checks only those fixture rules, without parsing a BMD file or exercising either business application.
| Case | Observed decision | Meaning within the model |
|---|---|---|
| Unchanged batch with complete receipt | ACKNOWLEDGED_IN_MODEL | Reference, candidate and invented receipt agree. |
| No destination receipt | READY_FOR_IMPORT_REHEARSAL | The candidate reconciles; destination acceptance remains unproved. |
| Missing credit | BLOCKED | An expected document is absent. |
| Duplicate document | BLOCKED | A composite source identity occurs twice. |
| Offsetting document amounts | BLOCKED | Counts and totals match, but four amount fields differ. |
| Wrong company | BLOCKED | The candidate contains a document outside the approved identity scope. |
| Wrong posting period | BLOCKED | A document’s period differs from its approved source value. |
| Wrong currency | BLOCKED | The currency differs from the reference. |
| Missing mapping | BLOCKED | The required fictional mapping reference is empty. |
| Missing document reference | BLOCKED | The required supporting-document label is absent. |
| Changed import profile | BLOCKED | The candidate no longer identifies the reviewed profile. |
| Partial destination receipt | RECONCILIATION_REQUIRED | Not every intended document has an accepted destination reference. |
| Receipt for another payload | RECONCILIATION_REQUIRED | The receipt does not identify this candidate payload. |
Download the runnable comparison model and recorded results. Save the Python file and run:
python3 reconcile-export.pyAll thirteen expected decisions matched the local run. Money uses decimal arithmetic under the example’s exact-comparison policy. The payload hash covers normalized JSON, not an exported BMD file. In production, identify the actual file bytes and profile, then retain the destination’s real document evidence.
A nonempty attachment label cannot prove the recipient can retrieve the correct PDF. Inspect the actual file and its record association during native acceptance.
How should a partial import be recovered?
Recover a partial import by establishing which documents were accepted, rejected or left uncertain before deciding what to repeat. Use the destination report and record references, then agree the correction with the receiving owner. A failed batch-level message does not prove that every document failed, and a new filename does not make repeated documents new business events.
| Observed situation | Next action | Evidence before completion |
|---|---|---|
| No receiving evidence yet | Request the destination result and keep acceptance unresolved. | Identify whether any document was processed. |
| Some accepted, some rejected | Reconcile each disposition and agree how rejected documents will be corrected or resubmitted. | Accepted records are accounted for and the recovery creates no unapproved duplicate. |
| Import outcome is unknown after interruption | Inspect the receiving records before replay. | The proposed action follows the established result, not an assumption about the interruption. |
| Source or mapping changed after approval | Create an identified revision and repeat affected comparisons. | The current batch has current approval and a trace to the previous attempt. |
Do not assume that the destination supports a particular correction, reversal or selective replay mechanism. Demonstrate the agreed procedure on the actual profile with the receiving team. Retain the original attempt’s evidence when a corrected batch replaces it.
If n8n schedules or transfers the file, its execution history is useful transport evidence. The n8n retry and recovery guide explains why a retry needs a stable business identity and an understood target result. Here, the decisive evidence is the receiving document disposition.
Which checks should finance and engineering accept?
Engineering should demonstrate traceable selection, transformation, transfer and recovery. The authorized finance owner should approve the mapping and resulting accounting interpretation. Record those decisions separately. A clean comparison cannot supply finance approval. An approved template still needs its checks executed on the real system.
The proposed thirteen-control acceptance sheet starts with NOT_RUN execution and PENDING finance approval. Actual evidence and approver fields are empty. It covers the source population, credits, duplicates, amounts, company and period boundaries, currencies, mappings, documents, revisions, partial imports and final acknowledgment.
Run one ordinary batch and a deliberately incomplete receiving case in a protected environment. Include an approved credit example and an item that must remain on hold. Ask both teams to trace a document through the batch to its destination result from the retained evidence.
For a one-off system migration, use the broader Odoo migration acceptance framework. For recurring operation, keep each month’s evidence with its batch and unresolved items. Changes to the connector or receiving profile should trigger the relevant recheck before the next handoff.
The release QA checklist helps place these controls within the wider delivery decision. Define who investigates a missing acknowledgment and who can approve a corrected batch, so the procedure still works when its usual operator is absent.
What would we implement first?
We would implement one approved source population, one exact export profile and a receiving-team acknowledgment that names the resulting documents. Demonstrate an ordinary batch and a partial failure before automating the schedule. Expand the supported scope only after the finance and technical owners can explain the result and recover the exception from retained evidence.
For Wavect’s API integration service, bring a permitted sample export, its approved source records, the receiving profile and one difficult correction case. That gives the first delivery a concrete acceptance question: can both teams account for every intended document in this handoff?
