The quote lifecycle
A quote has a life of its own before it becomes an order. This article describes that life as a state machine — what each state means, who may move it, and what is frozen the moment you press send.
The scenario
A maintenance buyer at a machine builder needs 500 metres of hydraulic hose in
DN 12, delivered to two sites, plus 40 fittings. Your catalogue prices all of
it. They still ask for a quote, because their purchasing policy requires two
written offers above €5,000, and because they want the delivery split written
down.
Your Innendienst prices it: hose at €4.80 instead of the €5.60 scale price, fittings at list, freight quoted separately. The quote goes out on a Tuesday, valid four weeks. On Thursday the buyer asks whether 600 metres changes the number. It does. You send a second version. Eleven days later their ERP raises a purchase order against version 2.
That whole sequence — from the request to the purchase order — is the quote lifecycle. Every state below exists because somebody in that story needed it.
The states
| State | Means | Moved by |
|---|---|---|
requested | A buyer has asked. Nothing is priced yet. | The buyer, from the storefront — or a rep recording a phone call |
draft | Someone is working on it. Editable. Not visible to the buyer. | Your Innendienst |
pending_approval | The discount or the value exceeds what the author may grant alone. | The author submits; an approver decides |
sent | The offer is out. Prices are frozen. Not editable. | Whoever holds the send permission |
accepted | The buyer said yes. | The buyer on the storefront, or a rep recording an emailed acceptance |
declined | The buyer said no, with a reason. | The buyer, or a rep recording the loss |
expired | valid_until passed with no answer. | Nobody. The clock. |
cancelled | Withdrawn by you. | Your Innendienst |
converted | An order now exists for it. | The system, on conversion |
Four of these are terminal: declined, expired, cancelled and converted.
The rest can still move.
requested is not draft. A request is the buyer's text — quantities, a
delivery date, a free-text note, sometimes an attached parts list. A draft is
your answer to it. Keeping them apart is what lets you measure response time,
and what stops a half-priced answer from ever reaching a buyer.The two transitions that matter
Everything else is bookkeeping. These two are the ones that change what the platform is allowed to do.
draft → sent freezes the prices
A quote in draft shows live prices. Open it tomorrow and the numbers may have
moved, because they are being resolved the same way every other price in the
platform is resolved — see
How pricing works.
The moment you send, that stops. Each line stores the unit price that was resolved for it, the quantity rung it came from, the currency, the net/gross basis and the tax rate — and never resolves again. A quote is a snapshot, not a live view.
This is not a convenience. It is the difference between an offer and a price indication. A buyer who receives a written quote and finds a different number on the order confirmation has been given a reason to phone rather than click, and that is the failure mode the whole platform is built to avoid.
accepted → converted creates an order
Acceptance is a commercial fact. Conversion is a system event, and it is
separate on purpose: the order it creates is subject to the same approval rules
as any other order. A buyer with orders.request but not orders.create
accepts a quote and gets an order in pending, awaiting their own approver —
see Quotes, approvals and negotiation
for the two doors into that state.
What "frozen" actually covers
Freezing a unit price is the obvious part. A quote that can be argued about later is one where these were not frozen:
| Frozen on send | Why it has to be |
|---|---|
| Unit price per line | The offer |
| The quantity rung it came from | So a partial acceptance at a lower quantity is visibly a different price |
| Currency | A CHF quote does not become a EUR quote because the buyer's market changed |
| Net or gross basis | Otherwise the same figure means two things — see Currencies and tax |
| Tax rate and tax class | The gross total on the PDF must still be re-derivable in March |
| Rounding mode and precision | Two systems rounding differently produce a two-cent argument on a €40,000 quote |
| Freight and surcharges | The quoted pallet price is part of the offer |
A quoted line records enough to be re-computed from its own contents. If you cannot reproduce the total on a sent quote from the quote itself, without asking the price engine anything, the snapshot is incomplete.
Validity and expiry
valid_until is a timestamp, not a date. It is evaluated in the tenant's time
zone, and a quote valid "until 30 April" expires at the end of 30 April local
time — not at midnight UTC, which for a German tenant in summer is two hours
early and has cost people deals.
Expiry is passive. Nothing is deleted, no price is recalculated, and the buyer can still open the document. What changes is that the accept action is gone. An expired quote cannot be converted, because the prices in it were an offer for a period that has ended.
Set a default validity in Quote settings and override it per quote. Thirty days is a common default in the Mittelstand. Choose it deliberately: a validity longer than your own purchase-price stability is a promise you may not be able to keep, and one shorter than the buyer's own approval cycle guarantees expiry.
What converts, and what does not
Acceptance can be partial. The buyer takes the hose and not the fittings. Two honest ways to model that, and you must pick one as policy:
- All or nothing. The quote is one commercial package; partial acceptance is a counter-offer, and it becomes a new version. Correct where the price depended on the whole basket.
- Line-level acceptance. The buyer accepts lines individually. The order
carries the accepted lines; the rest of the quote closes as
declined.
The second is friendlier and the first is safer. If you gave a bundle discount because of the total volume, line-level acceptance hands the discount away with none of the volume behind it.
How this works in the Revenue Cloud
Quotes live on Sales › Quotes. The grid shows the number, the account, the value, the state, the version and the days left to expiry — sorted by expiry, so the top of the list is the follow-up list. Requests arrive on Sales › Quotes › Requests and stay there until somebody drafts from them.
A quote number comes from a number range of the same shape as your order numbers
(prefix, padding, counter, step), configured on Configuration › Number ranges.
Give quotes their own range — AN-000412 next to SO-000198 tells everyone
which document they are holding.
Next
- Quotes, contracts and framework agreements — the three things that all mean "agreed price".
- Handle a quote request — the daily task this lifecycle describes.