How Does a Three-Way Match Work in Odoo Purchase?

A three-way match checks that the purchase order, the goods receipt and the vendor bill agree on quantity and price before you pay. In Odoo, the purchase order and the receipt are linked automatically, and you control how strictly the bill is compared to them with the Bill Control setting on each product.
This article explains the three documents, where Odoo compares them, and how to set it up so a bill cannot slip through for goods that never arrived. It applies to Odoo 18 and 19.
What is a three-way match?
It is a control used in purchasing. Before the company pays a supplier, three documents have to tell the same story:
- The purchase order: what you agreed to buy, at what quantity and price.
- The goods receipt: what physically arrived in the warehouse.
- The vendor bill: what the supplier is asking you to pay.
If the bill says 100 units and the receipt says 80, someone has to look at it before payment. That is the whole point. A two-way match only compares the order and the bill. The third document, the receipt, is what protects you from paying for goods that did not arrive.
Which Odoo documents map to the three?
- Purchase order: Purchase app, a confirmed order (state Purchase Order, not a quotation).
- Receipt: Inventory app, the receipt created from the confirmed order. It is linked to the order, and the received quantity is written back to the order line.
- Vendor bill: Accounting, created from the purchase order with the Create Bill button, or from a bill you enter or import.
On the purchase order line you will see three quantity columns that matter here: Quantity (ordered), Received and Billed. Those three columns are the match, shown in one place. When Received and Billed differ, the order has something left to resolve.
How does Odoo decide how many units you can bill?
The rule is the Bill Control policy on the product (on the product form, Purchase tab). It has two values:
- On ordered quantities: you can bill the full ordered quantity as soon as the order is confirmed, before anything is received.
- On received quantities: you can only bill what has been received so far.
On received quantities is the setting that gives you a real three-way match. When a user clicks Create Bill on an order with 80 of 100 units received, Odoo proposes a bill for 80. The other 20 become billable when the next receipt is validated.
If you use a default for many products, set it once on the product category or in your data import rather than editing products one by one. Check how your Odoo version and the products you import handle this field before you rely on a default.
How do you set it up?
A short checklist for a consultant:
- Make sure the Inventory and Purchase apps are both installed, so receipts exist and are linked to orders.
- Set the products you buy as storable goods that are tracked in Inventory. Services and consumables you do not receive will not have a receipt to match against.
- Set Bill Control to On received quantities on those products.
- Agree with the client who enters vendor bills and who validates receipts. The match only works if receipts are validated on the day the goods arrive.
- Test with one order that is received in two parts.
What does the match look like in a worked example?
A furniture distributor orders 100 office chairs at 45.00 each from a supplier. The order total is 4,500.00.
Step 1. The buyer confirms the purchase order. Ordered: 100. Received: 0. Billed: 0.
Step 2. The first truck arrives with 80 chairs. The warehouse validates the receipt for 80 and does not create a backorder for the missing 20 yet, or creates one, depending on how the team wants to track them. The order now shows Received: 80.
Step 3. The supplier sends a bill for 100 chairs, 4,500.00. The accountant clicks Create Bill on the order. With Bill Control on received quantities, Odoo proposes 80 chairs, 3,600.00.
Step 4. The accountant compares the draft bill to the supplier document. The supplier document shows 100. The difference is 20 chairs, 900.00. The accountant does not post the full bill. They either ask the supplier for a corrected bill for 80, or hold the bill until the second truck is received.
Step 5. The second truck arrives with 20 chairs. The receipt is validated, Received becomes 100, and the remaining 20 can now be billed. The bill is posted and paid.
Notice what the system did and what a person did. Odoo showed the received quantity and limited the proposed bill. The decision to hold the supplier's bill was made by the accountant.
What about price differences?
Quantity is only half of the match. The unit price on the bill should equal the unit price on the order. If the supplier bills 47.00 instead of 45.00, the draft bill built from the order will carry 45.00, and a bill entered by hand or imported may carry 47.00. The accountant should compare the price column to the order before posting, and ask the buyer whether the new price was agreed.
If the company values stock in real time, a price difference also has accounting consequences, so involve the finance lead on how price differences should be booked.
What are common mistakes when setting this up?
- Leaving Bill Control on ordered quantities on goods, then wondering why bills can be created before receipt.
- Receipts that are validated late, so the Received column is behind reality and valid bills look too high.
- Entering vendor bills from scratch instead of from the order, which bypasses the proposed quantity and the link between bill and order.
- Forgetting that services have no receipt. For those, the control is the approval of the person who ordered the service.
How do you practice this?
The fastest way to learn a three-way match is to do one: confirm an order, receive part of it, create the bill and watch the proposed quantity change. Repeat it with Bill Control set to each value and compare the results.
Praxio has Purchase and Inventory practice items, and hands-on Simulations that open a real Odoo 19 database with a client brief, so you can practice this workflow end to end. You can see all of them at https://www.praxio.pro/app/practice/simulations. Praxio is free while it is in beta.
Ready to start practicing?
Take the free Consultant Readiness Assessment and find out where you stand across five consulting dimensions.
Take the Free Assessment →