Odoo ERP

Odoo Purchase Approval Workflows: RFQs, Limits, Matching

A practitioner's guide to building Odoo purchase approval workflows that actually hold: RFQ stages, approval thresholds, and three-way matching.

Ravi Shanker SinghFounder & Odoo ConsultantPublished 6 min read
Share
Odoo Purchase Approval Workflows: RFQs, Limits, Matching
On this page

Most finance teams discover their purchase approval gaps the hard way. A vendor bill posts for more than what was received. A large order goes out without anyone above the buyer seeing it. Getting Odoo purchase approval right is less about flipping a setting and more about deciding, deliberately, where the friction should sit between a request for quotation and a paid vendor bill.

This is the setup we walk through on most procurement engagements, whether the client runs a single warehouse or a multi-company group. Most of it needs only configuration, not custom code.

How the RFQ stage fits into Odoo purchase approval

An RFQ in Odoo is a purchase order in draft state. It is not yet a commitment, and that distinction matters more than most teams treat it. A common mistake is skipping the RFQ stage entirely and creating confirmed purchase orders straight away. That removes the one place where a buyer can compare vendor quotes side by side before money is committed.

We recommend keeping these steps distinct in the buyer's daily routine:

  • Create the RFQ from a purchase requisition, a reorder rule, or a manual need.
  • Send it to one or more vendors and log their quoted price and lead time.
  • Compare alternatives before confirming, especially for non-stock or capital purchases.
  • Confirm only after the comparison. Confirming converts the RFQ into a purchase order and triggers approval rules if a threshold applies.

Skipping comparison does not break anything in Odoo. It quietly turns the RFQ stage into paperwork rather than a control point.

Setting Odoo purchase approval thresholds without creating bottlenecks

Odoo's base purchase approval setting is a single value: orders above that amount need a user with purchase manager rights to confirm them. Below it, a buyer can confirm on their own. This is useful but blunt, and the blunt part is where most of our configuration work happens.

A few things we check before setting the number:

  1. Whether the threshold should differ by company, if the business runs multiple legal entities on one database.
  2. Whether certain product categories, such as capital equipment, services, or subcontracting, deserve a lower limit than routine stock replenishment.
  3. Who the approver actually is, and whether that person is available daily. A threshold with no backup approver just creates a queue.

A single global number is simple to explain to an auditor but often wrong for the business. Setting it too low turns every manager into a bottleneck for routine reorders. Setting it too high defeats the purpose of having a check at all. We generally start with a number pulled from twelve months of purchase order history, not a round figure someone picked at a meeting.

For organizations that need true multi-level approval, Odoo's purchase module already supports this natively. You can define multiple approval levels tied to job positions, with each approver assigned a minimum and maximum amount. A team lead might approve up to a set figure, a department head up to a higher one, and finance anything above that, all routed automatically by amount and category. No custom module is required to set this up, though mapping it correctly to your actual org chart takes real planning, and we often build this as part of broader Odoo customization work when the approval logic needs to interact with other modules.

A note on delegation

Approval rights in Odoo follow user groups and job positions, not just individuals. Granting someone manager-level access to approve one large order can also give them visibility into purchasing beyond that order, including prices negotiated by other buyers. This is a trade-off worth naming before granting that access as a quick fix during someone's vacation.

Three-way matching: order, receipt, bill

This is the control that actually prevents overpayment, and it depends on three documents lining up:

DocumentWhat it recordsWho creates it
Purchase orderAgreed quantity and priceBuyer
Receipt (incoming transfer)Quantity actually received into stockWarehouse
Vendor billAmount the vendor wants to be paidAccounting, from the vendor's invoice

Odoo compares these automatically when the billing control policy on the product or purchase order is set to bill on received quantities rather than ordered quantities. With that setting, a vendor bill cannot pull in more than what the receipt confirms. The bill lines show the received quantity as the default, not the ordered one. If a vendor invoices before the goods arrive, the bill stays at zero quantity until someone records the receipt. That is the intended friction point, not a bug.

Billing on ordered quantities instead removes that check entirely. Accounting can then post a bill the moment a purchase order is confirmed, regardless of what physically arrived. That setting exists for services and drop-ship scenarios where there is no separate receipt step, but using it for stockable goods defeats the point of three-way matching.

A limitation worth knowing: Odoo's matching compares quantities, and price variance between the PO and the bill does not block posting by default. A vendor can bill a different unit price than what was quoted, and Odoo will only show a warning on the bill rather than stop it. Catching price drift still requires someone on the accounting side to actually read that warning, or a reconciliation policy that reviews variance reports periodically.

Building the audit trail that survives a review

Every state change on a purchase order and every posted bill carries a timestamp and a user, visible in the chatter log on the record. That is useful but passive. Nobody reviews chatter logs unless something has already gone wrong. The audit trail that holds up under a real review is built from a few additional habits:

  • Require a reason in the internal notes field when an order is confirmed above the normal threshold through an approved exception.
  • Keep the vendor bill's journal items reconciled against the receipt date, not just the bill date, so lead-time disputes can be traced.
  • Lock accounting periods at month-end close so a bill cannot be backdated into a closed period without an explicit reversal.
  • Run a vendor price variance report at least monthly if price matching is not enforced at posting time.

None of these are exotic. They are closer to accounting hygiene than Odoo configuration. But the configuration is what makes the hygiene possible or impossible.

When native Odoo purchase approval settings still fall short

The built-in multi-level approval by job position covers most hierarchies. It does not, by itself, handle split approval by cost center, routing specific vendors through extra review, or multi-currency thresholds that convert at a live rate. These narrower gaps are where we typically add targeted server actions or automated rules rather than a full custom module, since the base purchase workflow already does the heavy lifting. If you are planning this as part of a wider rollout, our Odoo implementation services page covers how we sequence procurement controls alongside inventory and accounting go-live.

One more honest caveat: tightening purchase approval controls always adds steps for buyers, and the people doing the buying will feel that before the people who requested the controls do. We recommend testing the threshold and matching policy on a slice of live purchase orders for two to three weeks before rolling it out company-wide, so the friction gets tuned rather than imposed all at once.

If procurement sits inside a broader ERP rollout that also touches inventory valuation by industry and vendor onboarding, it is worth reviewing approval rules again once go-live settles. Real purchase volume will surface edge cases that design-phase estimates miss. For sector-specific procurement patterns, our industry-specific Odoo customization work often starts with exactly this kind of review.

Share

Frequently asked questions

What triggers an approval step in Odoo purchase orders?

By default Odoo asks for a manager review once a request for quotation crosses a value you set in Purchase settings. Below that line a buyer can confirm the order directly. We usually set the threshold per company or per purchase category rather than one number for everyone.

Does Odoo support multi-level approval for large purchase orders?

Yes. Odoo's purchase module natively supports multiple approval levels tied to job positions, each with its own minimum and maximum amount. This builds a dynamic approval route, such as team lead then department head then finance, without custom development, though the levels still need careful configuration to match your actual org chart.

What is three-way matching and why does it matter?

Three-way matching compares the purchase order quantity and price, the receipt quantity actually recorded in stock, and the vendor bill. Odoo blocks or flags a bill when the billed quantity exceeds what was received, which catches both billing errors and early or inflated invoices.

Can we require a receipt before a vendor bill is allowed?

Yes, by setting the billing control policy on the purchase order or product to bill on received quantities instead of ordered quantities. This forces the sequence of order, then receipt, then bill, which is the core of the audit trail.

Does raising the approval threshold reduce fraud risk?

No, a higher threshold reduces review workload but widens the range of spend that goes through without a second set of eyes. We recommend pairing any threshold increase with tighter vendor bill matching controls so the trade-off is deliberate, not accidental.

Sources

About the author

Ravi Shanker Singh

Founder & Odoo Consultant

Founder of Tech After Me and Odoo consultant. Ravi implements, customizes and supports Odoo ERP and builds web, mobile and data products for companies in Thailand, the USA and India, working from Bangkok, New York and Delhi NCR.

More from this author

Keep reading

Put what you read into practice

The team writing these guides is the same team that ships them. Tell us what you are working on.

Get new articles in your inbox

Get new articles in your inbox

Odoo guides and IT news that matter to your business. At most one email a week.