There's a tempting design where close_quote returns 409 Conflict if any line lacks stock. Clean. Safe. Wrong.
The appeal is obvious: never promise what you can't deliver. Every line on a closed quote is backed by physical inventory. The system is conservative, the warehouse is happy, and nothing ever goes negative. But this design has a hidden assumption built into it β that inventory is static and that the commercial team doesn't know things the system doesn't. Both assumptions are false.
Why it's wrong Sales happens before warehousing catches up. A commercial person closes a quote Friday evening; the receipt of inbound stock is Tuesday. The quote is legitimate, the customer is paying, the team knows the product is on the way. Blocking the close forces a rescheduling dance that creates more problems than it solves.
The real-world consequence of strict stock enforcement at close time is that commercial teams build workarounds. They create 'dummy' products to absorb the reservation. They close the quote in a test environment and email the PDF. They write the order on paper and enter it when stock arrives. Each workaround is worse than the problem β it creates shadow inventory, untracked commitments, and a parallel system that the real system can't see.
The Quotery answer
POST /api/quotes/{id}/close/ never 409s on availability. It always succeeds, reserves what's there, and returns a shortages array with every underprovisioned product. The frontend renders a clear banner; the commercial person acts with information, not errors.
The shortages array is the key. It's not just a boolean 'insufficient stock' flag β it's a structured list of exactly which products are short and by how much. The frontend renders this as an amber banner: '3 products have insufficient available stock. Total shortfall: 47 units across 2 suppliers.' The commercial person can click through to see each product, its current available quantity, the reserved quantity, and the gap. They can then decide: proceed and place a purchase order, split the quote into what's available now and what's backordered, or call the customer and adjust.
Where we DO enforce
Delivery is different. A delivery note that would drive on_hand negative IS rejected at post time. You can reserve what doesn't exist; you cannot ship what doesn't exist. That's where the constraint belongs β one step later, one transition further along.
This is the critical distinction. Reservation is a promise; delivery is a fulfillment. Promises can be made against future inventory. Fulfillment can only happen against physical inventory. By placing the hard constraint at delivery rather than at quoting, we give the commercial team flexibility without letting the warehouse ship product it doesn't have. The two operations have different invariants because they serve different purposes. The system enforces each at the right point.
