| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Discuss (mail)
• Inventory (stock) • Invoicing (account) • Purchase (purchase) |
| Community Apps Dependencies | Show |
| Lines of code | 5792 |
| Technical Name |
eh_account_ap_automation |
| License | LGPL-3 |
| Website | https://www.erpheritage.com.au/ |
| Versions | 16.0 17.0 18.0 19.0 |
Vendor Bill Automation
Intake every vendor bill, run a genuine three-way match against the PO and goods receipt, and let a manager post the clean ones in one batch.
Why this module
Vendor Bill Automation
A real three-way match
Not field names that sound like a match. Each line is matched to its PO line, the received quantity is read from done stock moves, and price is compared in the bill currency after FX conversion. Over-receipt is flagged distinctly from a quantity mismatch.
Posting stays with a human
Matched-within-tolerance intakes are flagged ready to post; an accounting manager posts them, alone or as a selected batch, in one action. Posting is never automatic, and it re-checks duplicates at post time.
Yours to keep
LGPL-3 source on disk. The shipped regex parser makes no remote calls. The extractor interface is pluggable, so a partner OCR or line extractor can register without forking the suite. Free today, free at renewal, because there is no renewal.
Day in the life
100 vendor bills land Monday morning. Three of them are duplicates.
The mail intake drops every incoming bill into the inbox as its own record and resolves each sender to a vendor. The regex parser pulls the vendor reference and total from each. The duplicate detector checks (vendor, reference, total, date) against open intakes and already-posted bills, and flags two that arrived twice and one that posted last week. The three-way match against the open POs surfaces a quantity exception on a fourth bill where the receipt came up short. The bookkeeper resolves the four flagged cases, then the accounting manager selects the clean remainder and posts them in one batch. The duplicates need a manager override with a written reason; everything else just posts.
Edge cases
The cases most modules quietly ignore.
In the shipped code today, each one a place where a cheaper module silently does the wrong thing.
A bill raised in a different currency than the PO does not flag every line as a price exception. The PO unit price is converted into the bill currency at the bill date before the price-tolerance check runs.
A price line is only flagged when both the per-unit percent tolerance and the absolute line-amount tolerance are breached, so a trivial penny mismatch never blocks an otherwise clean bill from posting.
Invoiced quantity that exceeds the ordered PO quantity beyond the over-receipt percent is flagged distinctly as over-received, separate from a quantity-versus-received shortfall, so the two cases are never conflated.
A duplicate block can only be cleared by an accounting manager with a written reason, the override is posted to chatter, and posting re-runs the duplicate check at post time, not only at match time.
When more than one partner matches the sender address, the intake is created with no vendor rather than guessing, because a wrong vendor attribution on a bill is higher risk than the convenience of an auto-fill.
Re-running Parse will not clobber manually entered or previously extracted lines. If lines already exist on the intake, the parser returns early and leaves them untouched.
When an extracted line's quantity times unit price diverges from the reported line total by more than a cent, the framework trusts the line total and back-solves the unit price to minimise total drift.
Per-record try/except in the scheduled run means one un-parseable or un-matchable intake is logged and skipped, while the rest of the batch keeps moving.
What is inside
Built to do the job, end to end.
- Genuine three-way match. Per line: PO line by partner and product, received quantity from done stock moves, and price compared in the bill currency. Out-of-tolerance lines route the intake to the exception state with the deltas captured.
- Per-partner tolerance profiles. Quantity percent, price percent, absolute amount, and optional over-receipt percent. A default profile ships as install data and applies everywhere; vendors carry their own overrides.
- Duplicate detection. Checks (vendor, reference, total, date) against open intakes and posted bills. Override is manager-gated, reason-required, and audited; the check repeats at post time.
- Manager-gated posting. An accounting manager posts matched intakes individually or in a selected batch. Posting builds a standard in_invoice carrying the PO and supplier taxes, with full per-transition audit fields and chatter.
- Email intake and resolution. Inbound mail creates an intake from the message body and resolves the sender to a vendor. Ambiguous senders are left unattributed rather than guessed.
- Pluggable line extractor. The shipped regex parser makes no remote calls. A registry lets a partner package register its own OCR or line extractor without forking the suite; the bundled adapters ship as inert stubs.
- Scheduled advance with isolation. A cron runs every 15 minutes by default, promoting received intakes through parse and match with per-record try/except, so one bad record never halts the run.
Honest about the edges
What this does not do, so nothing surprises you.
- Posting is never automatic. Matched intakes are flagged ready and a manager posts them; there is no auto-post on match.
- The shipped regex parser extracts only the vendor reference and the total from the raw text. Vendor is resolved from the sender email or set manually, and due date and line items are entered by hand or via an optional extractor adapter. The parser records no confidence value.
- The bundled Claude, OpenAI and local extractor adapters are inert stubs. They ship no remote dependency and refuse live calls until a paid extension is installed.
- Override and transition history is captured via readonly audit fields (who, when, reason) and the standard Odoo chatter. This module ships no separate write or unlink locked log model.
- There is no integration with a separate approval module. The only gate on posting is the accounting-manager group check.
- There is no batch-payment-specific wiring. Posting creates a standard vendor bill that any AP batch-payment run can select, by virtue of standard posting only. No payment is scheduled on post.
Odoo three-way match, vendor bill automation Odoo, AP automation Odoo 19 Community, purchase order goods receipt invoice match, vendor bill tolerance profiles, duplicate invoice detection Odoo, accounts payable invoice intake, email to vendor bill Odoo, PO matching tolerance Odoo, vendor bill exception workflow
Languages
Available in 19 languages
The interface ships translated out of the box. Switch language in Odoo and the fields, menus, and messages follow.
Please log in to comment on this module