Supplier invoice coding workbench¶
The Accountify AP workbench is an exception-first operational interface over Odoo. Accountify owns intake, structured extraction/OCR suggestions, work state, review, client requests, and audit. Odoo remains the system of record for vendors, draft bills, taxes, posting, payables, payments, and attachments.
Workflow boundary¶
| Capability | Odoo models | Write policy |
|---|---|---|
| Vendor match | res.partner |
Read; create only through approved new-vendor review |
| Draft vendor bill | account.move |
Create/write while move_type is supplier document and state = draft |
| Coding lines | account.move.line |
Create/write through invoice_line_ids commands on the draft bill |
| Journals/accounts/taxes | account.journal, account.account, account.tax |
Read same-company active configuration |
| Source file | ir.attachment |
Create/link to the bill; optional Documents integration |
| Posting | account.move, method action_post() |
Separate guarded action after review and readback |
| PO matching | purchase.order, purchase.order.line |
Prefer native purchase links and methods |
| Receipt matching | stock.picking, stock.move, stock.move.line |
Tenant capability; durable inventory operations |
Product flow¶
- A PDF, image, or structured e-invoice arrives through Accountify, email, Odoo Documents, Peppol, or another controlled source.
- Accountify creates an AP task and records source/checksum metadata.
- For a structured e-invoice, Accountify reads the authoritative XML fields and preserves the original structured artifact. For an unstructured document, OCR/AI extracts vendor, document type, dates, reference, currency, totals, taxes, payment terms, and line hints with confidence and reasons.
- Deterministic and historical rules suggest vendor, account, tax, analytic distribution, deferral/asset treatment, and duplicate risk.
- Staff reviews the document and coding in a split workbench.
- Accountify validates tenant, company, field combinations, policy, duplicate handling, and user role.
- Backend creates or updates an Odoo draft and attaches the source document with an idempotency key.
- A reviewer approves when policy requires it.
- A permitted user deliberately posts the bill after a fresh Odoo read and strict checks.
- Backend reads back Odoo state, totals, residual, duplicate indicators, and attachments before completing the task.
Structured e-invoice intake¶
The German B2B e-invoicing contract governs XRechnung, ZUGFeRD, and Peppol intake. Structured XML is the primary accounting-data source; a PDF rendering is for human review and cannot silently override it. OCR is not required merely to re-read values already present in valid structured data.
Inbound e-invoices must retain format/profile, structured-file hash, Odoo attachment identity, message UUID when available, supplier invoice ID/type, transport, and validation result. Invalid XML, unsupported profiles, structured/rendered differences, duplicate delivery, and correction relationships become explicit AP exceptions. Receipt creates a draft/work item; it never implies tax approval, posting, or payment authorization.
Accountify task API¶
| Endpoint | Purpose |
|---|---|
GET /ap/tasks |
Queue rows with client, source, vendor/amount guesses, confidence, risk, owner, SLA, task and Odoo states |
GET /ap/tasks/{id} |
Document, extraction, suggestions/reasons, coding, validation, Odoo IDs, audit, client thread |
PATCH /ap/tasks/{id}/coding |
Save staff coding; optionally create/update an Odoo draft; never post |
POST /ap/tasks/{id}/request-info |
Request missing/ambiguous information and move to waiting state |
POST /ap/tasks/{id}/submit-review |
Mark complete coding ready for reviewer/approval |
POST /ap/tasks/{id}/post |
Re-read, authorize, validate, call action_post(), then verify |
POST /ap/tasks/{id}/sync-odoo |
Recover from retry, timeout, or direct Odoo edits through readback |
Draft bill create contract¶
{
"vals_list": [
{
"move_type": "in_invoice",
"partner_id": 123,
"journal_id": 10,
"invoice_date": "2026-06-29",
"date": "2026-06-29",
"ref": "SUPPLIER-INV-10045",
"invoice_line_ids": [
[0, 0, {
"name": "Fulfillment services",
"quantity": 1,
"price_unit": 250.0,
"account_id": 456,
"tax_ids": [[6, 0, [789]]],
"analytic_distribution": {"321": 100}
}]
]
}
]
}
Call default_get first for company, currency, journal, date, and payment-term defaults under the same context as the intended create. Do not assume UI onchange behavior will run as it does in the browser. Send explicit validated values and re-read Odoo-computed totals.
Validation before draft save¶
- Tenant database, allowed company, vendor, journal, accounts, taxes, and currency are coherent.
- Document is a supplier invoice, credit note, paid receipt, or explicitly routed exception.
- Vendor creation, if needed, has passed policy and duplicate/vendor-master checks.
- Bill/document date is present and acceptable for accounting/tax policy.
- Supplier reference is present unless a documented policy permits omission.
- At least one invoice line has description, account, quantity/price (or supported amount representation), and valid taxes.
- Analytic/deferral/asset requirements are complete where client policy requires them.
- Source attachment exists unless explicitly waived.
- Duplicate checksum/vendor-reference/amount-date risk is resolved or overridden with reason.
Validation before posting¶
- The Odoo move still exists in
draftand itswrite_datematches the reviewed version. - Odoo totals, currency, vendor, dates, reference, taxes, and lines match the approved payload/readback hash.
- The task has no blocking warnings or unresolved client request.
- Reviewer/client approval thresholds and staff posting permission are satisfied.
- Duplicate warning is cleared or explicitly overridden.
- Lock-period and tax validation pass.
- The source document is attached.
- The idempotency key has not already produced a posted move.
Posting has legal and accounting consequences. A timeout after action_post() is an unknown outcome: read back by bill ID/idempotency context before retrying.
Task states¶
New -> Extracting -> To Code -> In Coding -> Needs Review -> Ready To Post -> Posted
Exception states: Duplicate Risk, Waiting For Client, Waiting For Approval, Blocked By Odoo, Failed Sync, and Archived/Rejected.
Each transition records actor, reason, before/after coding hash, Odoo operation, idempotency key, result, and readback state.
Suggestions and controls¶
Suggestions may use vendor history, VAT ID/IBAN/email/layout, reference and amount similarity, vendor defaults, fiscal position, tax country, past account/tax/analytic coding, payment linkage, and ecommerce-specific rules. Every suggestion must show confidence and reason, support accept/edit/reject, and record the decision. Suggestions never post silently.
Purchase and three-way matching¶
The current database has verified purchase.order, purchase.order.line, stock.picking, stock.move, and stock.move.line support. A controlled test confirmed the native flow:
- Confirm purchase order.
- Odoo creates incoming receipt.
- Validate received quantity.
- Odoo updates
qty_received. - On
purchase.order, call theaction_create_invoice()method. - Odoo creates a draft vendor bill linked through
purchase_line_id/purchase_order_id. - Odoo updates
qty_invoiced,qty_to_invoice, andinvoice_status.
Enable this per tenant only after verifying purchase_stock, warehouse, incoming picking type, stock location, Buy route, permissions, and a controlled PO-to-receipt-to-draft-bill smoke test. Store purchase_order_supported and three_way_match_supported separately.
Completed receipts are durable inventory history. Archive disposable products and use native return/reversal flows; do not hard-delete completed stock movements.
Edge cases¶
Cover duplicate/split/multi-document intake, wrong client, unreadable OCR, invalid or unsupported e-invoice XML, structured/rendered mismatch, repeated Peppol delivery, correction/credit-note chains, statement/quote instead of invoice, new/duplicate/renamed vendors, mixed VAT, reverse charge, import VAT/customs/freight, non-deductible VAT, assets, deferrals, deposits/retainers, credit notes, foreign currency, analytic requirements, ecommerce settlement invoices, fulfillment charges, advertising allocation, card receipts, employee reimbursements, direct Odoo edits, lock dates, permission changes, double-click/retry, timeout after create/post, and Odoo upgrades.
Testing evidence and rollout¶
- Draft AP smoke test: 17 passed, 0 failed, 0 warned; draft/vendor/attachment test data cleaned up; no bill posted.
- Studio automation smoke test: 11 passed, 0 failed, 0 warned.
- Final PO/receipt/draft-bill three-way test: 23 passed, 0 failed, 2 warnings; native receipt and purchase links verified; no bill posted.
- Completed test receipt remains as expected inventory history; the test product was archived.
Production posting, advanced assets, automated complex tax, and payment/reconciliation automation require separate controlled test plans.
Design basis¶
This guide is the sanitized, version-controlled implementation contract derived from the restricted Incoming Supplier Invoice Coding Workbench - Odoo Online Technical and UX Design dated June 26, 2026. The Drive source folder remains the record for the full design narrative and smoke-test details.