Stock reservations in your ERP: how to stop selling the same item twice in an SME

· 9 min read · SilverData team

There are 40 units on hand. Rep A promises 30 to a customer in Poznań. An hour later Rep B promises 25 to a customer in Kraków. Both looked at the same report and both were right — at the moment they looked, the system showed 40. The problem: the ERP had no idea about the first promise when the second one hit it. Two days later, one of those customers gets an apology phone call.

This post is about why "stock on hand" in an ERP isn't enough to sell against, what separates a hard reservation from a soft one, and how a two-week project can put reservations in place so your reps stop lying to customers in good faith.

Why on-hand alone isn't enough

Almost every ERP used in Polish SMEs — Comarch Optima, Comarch ERP XL, enova365, Subiekt GT/nexo, Streamsoft — has a "stock on hand" field on each item. It shows what physically sits in the warehouse. It's accurate the moment something moves off a shelf or a delivery lands.

The problem: the sales process doesn't work on that timescale. Hours, days, sometimes weeks pass between a promise to a customer and the goods leaving the warehouse. During that window the same "on-hand" number is visible to every rep, the webshop, the warehouse manager and the purchasing team. Each of them sees the same number and makes decisions as if they were the only one using it.

That's fine when a company has two reps and one warehouse. It stops being fine the moment quotes, phone orders, the webshop, B2B EDI feeds and production (which also draws from the same stock) all run in parallel. Typical symptoms that a firm has outgrown the "one number for everyone" model:

Each of these has a cost. Not dramatic per incident, but daily — over a year it's a director's vacation eaten up by handling complaints that didn't need to happen.

Hard vs. soft reservations

The practical ERP vocabulary has two concepts worth separating before you touch any configuration.

A hard reservation locks a specific quantity in a specific warehouse against a specific order. When a rep confirms an order for customer X for 30 units, those 30 physically disappear from "available for sale" for everyone else. No discussion, no "we'll sort it out". The stock belongs to the document.

A soft reservation is a signal that someone intends to take the stock but hasn't confirmed. Typically: a quote sent to the customer, not yet accepted. A soft reservation always has an expiry date — after 7 days without confirmation, the block lifts and the stock returns to the sellable pool.

The core rule: every document in the sales process must have a clearly assigned reservation type. Quote = soft, confirmed sales order = hard, goods-issue note = actual dispatch (no longer a reservation — physical stock leaves).

In an SME ERP this is usually one checkbox on the document header and one date field for reservation validity. The rest is configuration: which document type creates which reservation by default, who can change what, and when the block lifts automatically.

Available stock isn't on-hand

The moment you enable reservations, the item record grows from one number to four, and the whole team has to learn to read them:

A rep never looks at "on hand". They look at "available to sell". The webshop pulls "available to sell" through the API, not "on hand". The warehouse manager looks at "on hand" and "reserved", because their concern is whether what should physically be there actually is.

This one change — teaching the team that you sell from "available", not from "on hand" — solves 80% of the double-selling problem. The rest is configuration of document types and the discipline of expiring soft reservations.

Configuration in a typical SME ERP

Illustrated on Comarch Optima and Comarch ERP XL because they're the most common in Polish 15-50 person companies. In enova365, Subiekt and Streamsoft the mechanism is very similar — only the field names differ.

Step 1 — turn on reservations for selected warehouses. In the warehouse settings, uncheck "ignore reservations". In a single-warehouse company that's one change. In one with a main warehouse and a retail one, it's usually worth keeping reservations only on the main one.

Step 2 — set default reservation types for documents. A confirmed sales order = hard reservation. A quote = soft reservation, 7 days. A pro-forma invoice = hard reservation until paid or until validity date (typically 3 days).

Step 3 — define who can lift reservations manually. A rep — only their own. A sales manager — anyone's. This needs to sit in permissions, otherwise everyone lifts everyone's and it's chaos.

Step 4 — a scheduled job to expire soft reservations. A daily background job or an ERP scheduler entry: "all quotes older than 7 days without an order → lift the reservation, email the rep".

Step 5 — visibility on the item record. On the item record, show a list of all reservations with document number, customer, quantity and expiry date. When a rep sees "30 units reserved on SO/2026/1234 for customer X until Sep 15", they know whether to call customer X and negotiate a shorter hold or go looking for stock elsewhere.

Step 6 — integrations with the webshop and EDI. If your webshop pulls stock through an API, switch it to available stock. If you push catalogs to retail chains via EDI, make sure the INVRPT files carry available, not on-hand. Otherwise the chain orders what you've already blocked for someone else.

A real example

An 18-person distributor of plumbing supplies near Łódź. Comarch ERP XL, bought 6 years ago, warehouse module configured on defaults — reservations never enabled during the rollout because "it's complicated". Sales through 5 reps in the office, a B2B webshop and EDI feeds to two wholesale chains. 2,400 SKUs, 300-400 daily line items on documents.

Why they called: the sales manager tallied complaints for the first half of the year — 84 "promised, didn't deliver" cases, including 11 lost customers who moved to a competitor. The owner did the math on lost margin: roughly PLN 340,000 a year, plus the load on accounting and logistics from correcting invoices.

What we did in 3 weeks:

  1. Sales process audit — 2 days with the sales manager, one rep and the warehouse manager. We mapped 6 sales channels (phone, email, B2B webshop, EDI, field reps, over-the-counter retail). Key finding: field reps were "reserving" stock by SMS to the office, the office scribbled it into Outlook — none of it existed in the ERP.
  2. Enable reservations on the main warehouse — one config change in Comarch ERP XL, but we had to walk through 32 open orders from the last 6 weeks and issue retroactive reservations so the available stock wasn't out of balance.
  3. Reservation types on documents — quote = soft 5 days, confirmed order = hard, pro-forma = hard 3 days. A daily job at 6 a.m. expires overdue soft ones and emails the rep the list of "here's what expired on you yesterday".
  4. Webshop API change — the shop used to show customers on-hand stock. We switched the API query to available (on-hand − hard reservations + purchase orders arriving within 7 days). A few customers noticed and asked why "suddenly there's less"; the answer was "because we don't sell what we don't have anymore".
  5. EDI file change — the INVRPT file for the two chains got a different view on the same product, delivering available, not on-hand. The chains didn't notice the format change, but they stopped ordering stock that was already reserved.
  6. A mobile view for field reps — a small add-on giving B2B webshop access from a phone. Instead of the SMS-to-office loop, a rep sitting with a customer creates a quote that generates a soft reservation straight into the ERP.
  7. New rep dashboard — "my active reservations" with expiry dates, so each rep manages their own before the timer runs out, not after.

Result after 3 months: "promised, didn't deliver" complaints dropped from 14-16 a month to 2-3. Those 2-3 are mostly supplier delays, not double-selling. Reps stopped calling the warehouse before quotes — the warehouse manager reckoned it saved him around 40 hours a month. Two lost chains came back within a quarter, because a rep called them with something concrete: "we now have a reliable available-stock feed in EDI, your order won't be wasted".

Project cost: about PLN 18,000 — 3 days of audit, 4 days of Comarch ERP XL configuration, 2 days on the API integration for the webshop and the EDI file, 1 day training the reps and warehouse manager, and a mobile view for field reps built on the existing B2B portal (we didn't build a new one — just a mobile view). Payback: two months, counting recovered customers and freed-up warehouse manager time.

Traps worth watching for

A handful of things that can derail a reservations project:

When it isn't worth it

Reservations only pay off past a certain scale. If a company has two reps, one warehouse, sells on a same-day cycle and has virtually no forward-looking open orders — adding reservations is over-engineering. A shared spreadsheet of "promised this week" and a 5-minute daily sales huddle is enough.

Reservations start to pay off when:

Below those thresholds, reservations are admin overhead with no clear payoff. Above them, not having reservations costs more than putting them in.

What next

Reservations in an ERP look like a technical change but are mostly a change in how a company thinks about warehouse stock. "How much do I have" stops being enough — the team has to learn to ask "how much is available for a new sale". That's a question a properly configured ERP answers in a second and a hand-run warehouse never answers at all.

If your reps phone the warehouse before every quote, or "promised, didn't deliver" complaints come back every week — half an hour of conversation is usually enough to tell whether reservations are what your company is missing.

A rep who phones the warehouse before every quote isn't being polite. They're doing it because the ERP report is lying to them — and it's lying because nobody turned on reservations.

← Back to blog