Odoo Sales Module · Contract & Pricing Control
Stop sales staff from quoting the wrong price and stop over-delivery from eating your margins, link every Sales Order to a governed contract with automatic lifecycle tracking.
Sales
Contract Management
Cron-Based Automation
More Than 150+ Brands
Most businesses that sell on long-term agreements, blanket orders, framework agreements, rate contracts, annual supply deals, run into the same problem in standard Odoo: once a price and quantity are negotiated, there's nothing stopping a salesperson from typing a different number on a Sales Order. There's no system-level link between "what we agreed" and "what we're invoicing."
A sales contract, in the way this module implements it, is a standalone record that captures the customer, the validity period, the agreed product lines, the locked unit prices, the committed quantities, and a configurable tolerance band for over, or under-delivery. Once that contract is confirmed and active, it becomes the single source of truth that every related Sales Order pulls from.
The Sales Contract Management module by Ahex Technologies adds a dedicated Sales → Contracts menu, ties directly into Sales Orders, Stock Pickings, and Invoicing, and runs a daily scheduled action that keeps every contract’s status, Draft, Active, Fulfilled, Expired, Closed, Cancelled, accurate without anyone having to update it by hand.
Configure custom tolerance margins per product line, so small real-world variances don't trigger false alarms.
Choose Block or Warn policies, hard-stop an order that breaches contract limits, or just flag it on Chatter.
A scheduled background action auto-activates draft contracts, and auto-expires or auto-closes active ones.
Selecting a contract on a Sales Order auto-populates lines, default quantities, and locks the negotiated unit price.
Delivered quantities update automatically as stock pickings are validated, with auto-closure checks built in.
One click generates a clean, print-ready QWeb Sales Contract report you can send straight to the customer.
Picture a typical blanket agreement: 1,000 units of a product at a fixed unit price, with a 10% under-tolerance and a 5% over-tolerance built in. Below is how that single contract governs every order against it, the same way a credit limit governs every invoice against a customer account.
| Event | Qty Ordered | Cumulative Delivered | Tolerance Band | Outcome |
|---|---|---|---|---|
| Contract Confirmed | — | 0 | 900 – 1,050 | Active |
| Sales Order #1 | +400 | 400 | 900 – 1,050 | Allowed |
| Sales Order #2 | +500 | 900 | 900 – 1,050 | Under-tolerance reached |
| Sales Order #3 (attempt) | +160 | 1,060 | 900 – 1,050 | Blocked — exceeds tolerance |
| Cron Engine (daily run) | — | 900 | 900 – 1,050 | Auto-marked Fulfilled / Closed |
This is the difference between hoping your sales team remembers the agreed terms and having Odoo enforce them automatically, at the moment of order confirmation, not after the fact during a reconciliation review.
This module solves a recurring problem for any business that sells on negotiated, recurring, or volume-based terms rather than one-off list-price orders. Here are the most common scenarios:
1 of 7
Running annual supply agreements with key accounts at fixed, pre-negotiated unit pricing.
2 of 7
Who need to stop sales reps from quoting off-contract prices to large or repeat customers.
3 of 7
From customers, where deliveries happen in multiple partial shipments over months.
4 of 7
Who need a single dashboard showing committed quantity, delivered quantity, and remaining balance per customer agreement.
5 of 7
With framework agreements that must auto-expire on a fixed end date.
6 of 7
Who need assurance that invoiced unit prices always match the originally signed contract, with full chatter-logged audit history.
7 of 7
In their commercial terms, common in raw materials, bulk goods, and industrial supply.
Think of it as a credit limit for quantity and price: every Sales Order linked to a contract is checked against what was actually agreed, not what someone remembers, or what’s convenient to type.
Go to Sales → Contracts → All Contracts, click New, select the customer, validity dates, over-quantity policy, and add product lines with target quantities, locked prices, and tolerances.
Click Confirm to move the contract from Draft to Active. Active contracts become selectable on Sales Orders immediately.
Open a standard Sales Order, pick the Customer, then select the matching active Sales Contract. Lines auto-populate with the pre-negotiated price and default quantity.
If the order exceeds quantity and tolerance, a Block policy raises a hard error while a Warn policy posts an alert to Chatter instead of stopping the sale.
As deliveries are validated, the contract's delivered quantity updates. Once the under-tolerance threshold is met, the daily cron engine marks the contract Fulfilled and Closed automatically.
Every action on a Sales Order or delivery has a predictable, auditable effect on the linked contract
Select
Contract on Sales Order → loads lines & locks price
Block
Warn
Validate
A daily scheduled cron engine independently sweeps all contracts: it auto-activates draft contracts that have reached their start date, and auto-expires or auto-closes active contracts that have passed their end date or hit the fulfilment threshold, so contract status is never stale, even if nobody opens the record.
Building contract enforcement logic in Odoo from scratch means designing a new contract model, writing constraints to lock prices on Sales Order lines, handling tolerance math against partial deliveries across multiple stock pickings, and building a reliable scheduled action for lifecycle transitions. For an experienced Odoo developer, this is realistically several days of work, plus testing edge cases around cancellations and partial fulfilment.
Get the Sales Contract Management module for Odoo and stop relying on memory or manual checks to enforce pricing, quantity, and tolerance terms.
According to Mavenvista, a mid-sized manufacturing unit in India could lose over ₹10 lakhs per day during downtime due to
Hyderabad-based IT services company strengthens its Odoo practice to help small and mid-sized businesses migrate from legacy accounting tools to
Are you a retailer or have a running e-commerce business that uses Shopify and Odoo to manage your online sales
Yes. Once a contract is selected on a Sales Order, the unit price for matching product lines is locked from the contract, removing manual price entry as a point of error or abuse.
That’s exactly what the over/under tolerance settings are for. You configure an acceptable margin per product line, so minor real-world variance is allowed without triggering a block or a warning.
No. Contracts with delivered quantities cannot be cancelled — this protects the integrity of the delivery and invoicing history. Cancellation is only available before any stock has moved against the contract.
Auto-closure depends on the delivered quantity reaching the configured under-tolerance percentage. If that threshold hasn’t been hit yet, the contract stays Active until the next cron run after fulfilment, or until its end date passes.
The product on the Sales Order line must match the contract line’s product exactly. A mismatched variant or substitute product will not inherit the locked price or count against contract quantities.
Forem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero et velit interdum, ac aliquet odio mattis. Class aptent taciti sociosqu ad litora
Know more ➞
Forem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero et velit interdum, ac aliquet odio mattis. Class aptent taciti sociosqu ad litora
Know more ➞
Forem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero et velit interdum, ac aliquet odio mattis. Class aptent taciti sociosqu ad litora
Know more ➞
DEVELOPERS
YEARS IN OPERATION
GLOBAL CLIENTS
Start your digital transformation journey now and revolutionize your business