Order Management for Wholesale Distributors
Wholesale distribution moves serious volume on thin margins, and it runs on rules that no retail or e-commerce tool assumes: the same SKU sells at a different price to every account, orders come in by the case rather than the each, and you almost never ship the whole order on the first pass. U.S. merchant wholesalers did over eleven trillion dollars in sales in a single year, and every dollar of it flows through customer-specific pricing, credit terms, and partial shipments. This guide walks through the order management system a distributor actually needs, and how to stand it up as a running, hosted app on ybuild, served on your own domain.
The problem
- Every account has its own negotiated pricing. A retail till knows one price per SKU, but you run contract prices, volume breaks, and customer tiers, so the price on a line is really a function of who is buying, what, how much, and when.
- You buy, stock, and ship in different units. A product lives on the shelf as eaches but sells by the case of 24 and moves by the pallet, and a build that stores one number cannot tell whether "order 3" means three eaches or three cases.
- You rarely fill the whole order. Something is always short, so you ship what you have and backorder the rest, while a naive system assumes full fulfillment and either over-deducts stock or quietly drops the unfilled demand.
- You sell on terms, not on cash. Accounts pay Net 30 against a credit limit, you invoice for what actually shipped, and one order released past a customer's limit is money you may never see.
What you’d build
A B2B customer record that carries an assigned price list or tier, payment terms, a credit limit, an open AR balance, ship-to addresses, and a sales rep. When you start an order for that account, the entry screen loads their price list automatically, so every line prices at their negotiated rate instead of list. It ships live and hosted on ybuild from the first build.
An order screen where you enter lines in whichever unit you like, case or each, and the system converts to the base unit using the case pack, enforces minimum-order and case-only rules, checks available-to-promise, allocates what is on hand, and splits any shortfall into a backorder line so the rest of the order can ship today.
A fulfillment flow that turns a released order into a warehouse pick list, captures the quantity actually picked, confirms the shipment with a packing slip, deducts only what shipped from inventory, and generates the invoice for the shipped quantity with the customer's terms and a due date, all on your live ybuild app.
The data model
A day in the system
- Morning: a rep or a customer places an order. You pick the account, and the entry screen loads that account's price list, so every line prices at their negotiated rate rather than list price.
- You enter lines by the case, "3 cases of SKU 4247," and the system converts to eaches using the case pack, checks any minimum-order and case-only rules, and shows the extended price at their contract number.
- The order checks the customer's credit limit against their open AR balance. If it would push them over, the order lands on credit hold instead of releasing to the warehouse.
- On release, what is on hand allocates to the order; whatever is short splits automatically into a backorder line, so one out-of-stock item does not hold up everything else.
- The warehouse works a pick list grouped by bin location. The picker confirms quantities, which may be less than ordered, and any short pick flows back onto the backorder line.
- Ship confirm generates the packing slip, deducts only the shipped quantity from inventory, and creates the invoice for what actually went out, stamped with the customer's terms and a due date.
- Backordered lines stay open on the order. When the replenishment purchase order arrives, they surface on a fill-backorders queue and ship as a second shipment, invoiced separately.
- End of day, the AR aging and open-order reports show who is past terms, which orders sit on credit hold, and how much stock is committed against incoming replenishment.
Where AI trips up
- Pricing off the product record instead of the customer's price list. In wholesale the price is a function of customer, SKU, quantity, and date: contract prices, tier breaks, and promos all coexist. Store one price per SKU and you quietly overcharge some accounts and undercharge others, and every invoice dispute traces straight back to it.
- Modeling quantity in a single unit. You buy, stock, sell, and ship in different units, each, inner pack, case, and pallet. If the schema does not store a base unit and a case pack and convert between them, someone orders "3" meaning three cases and you ship three eaches, or the reverse.
- Assuming full fulfillment. Retail deducts the whole order at checkout; wholesale ships partial and backorders the rest. If an order line cannot carry qty_ordered, qty_shipped, and qty_backordered as three separate numbers, backorders disappear and you either over-deduct inventory or lose the unfilled demand entirely.
- Invoicing on order instead of on shipment. You bill for what shipped, not what was ordered, or the customer is invoiced for backordered goods they never received. The invoice has to be generated at ship confirm off shipped quantities, with terms and a due date, not at order entry.
- Skipping credit control and allocation. Releasing an order that blows past a customer's credit limit, or promising the same stock to two orders because nothing allocates on hand, are the two ways a wholesale system loses money silently. Available-to-promise is on-hand minus already-allocated, and credit hold has to be a real order status the warehouse cannot pick against.
- The pricing spine: customers assigned to price lists, and an order screen that resolves each line off that customer's list with case-pack quantities. Everything else is worthless if the price is wrong.
- Order-to-ship with partial fulfillment: enter an order, allocate on-hand stock, split shortfalls to backorder, ship-confirm, and generate the invoice on the shipped quantity.
- Credit control: a credit-limit and open-AR check that puts an order on hold instead of releasing it to the floor.
- A full general ledger and accounts payable. Export invoices to your accountant or QuickBooks instead of rebuilding accounting inside the app.
- EDI feeds and a self-service customer portal. Start with your team entering orders, and add electronic ordering once the core flow is solid.
- Route planning, freight rate-shopping, and warehouse automation. v1 confirms shipments and prints packing slips; leave TMS and WMS integrations for later.
FAQ
How do I give each customer their own pricing?
Assign every account to a price list or tier, and store customer-specific unit prices, with quantity breaks, in price_list_items. The order screen then resolves the price from the customer's list, the SKU, the quantity, and the date, so a contract account and a brand-new account can order the same SKU and each sees their own number. List price on the product is only the fallback when no list entry applies.
We sell by the case but stock by the each. How does that work?
Each product carries a base unit and a case pack, say 24. You order and price in whichever unit you choose, and the system converts to the base unit for inventory. Ordering 3 cases allocates 72 eaches, and minimum-order and case-only rules are enforced at entry so nobody orders half a case.
What happens when I cannot fill the whole order?
The line splits. The available quantity allocates and ships now, and the shortfall becomes a backorder line that stays open on the order. When your replenishment arrives it surfaces on a fill-backorders queue and ships as a second shipment, invoiced separately, so you never promise stock you do not physically have.
When does the customer actually get invoiced?
At ship confirm, for what actually shipped, not at order entry. The invoice picks up the customer's payment terms, such as Net 30, and a due date, and posts to their AR balance. Backordered goods are invoiced only when they ship, so a customer is never billed for something still sitting in your warehouse.
How do I stop shipping to an account that has not paid?
The order checks the customer's credit limit against their open AR balance. An order that would push them over lands on credit hold, a real status the warehouse cannot pick against, until someone reviews and releases it. That one check is what separates a real wholesale system from a glorified order pad.
Sources
- U.S. Census Bureau: 2022 Annual Wholesale Trade Survey — Official government data showing U.S. merchant wholesalers had sales of $11,382.3 billion in 2022, the scale of the distribution channel this app serves.
- U.S. Bureau of Labor Statistics: Wholesale Trade (NAICS 42) — The official Industry at a Glance profile for the wholesale trade sector, covering merchant wholesalers of durable and nondurable goods.
- NetSuite: Minimum Order Quantity (MOQ) Formula, Tips, and Benefits — A practical guide to how MOQ and case-quantity rules work and why they belong at the order-entry stage in a distribution business.
Describe it, go live on your own domain in one pass — hosted, full-stack, no server. Free to start.