Home » Knowledgebase » Here

MOQ (Minimal Order Quantities) are a ubiquitous form of ordering constraint in supply chain. An MOQ constraint indicates that a supplier won't accept a purchase order below a specified threshold typically expressed in units or in dollars. Frequently, multiple MOQ constraints coexist and must be satisfied together. The general MOQ problem consists of computing the (near) optimal purchase orders that both satisfy all the MOQ constraints while maximizing the economic returns associated to the units purchased.

The general MOQ problem is formalized as a

`moqsolv`

, the advanced numeric solver provided by Lokad to address the general MOQ problem.- a minimal quantity expressed in units per SKU, which typically reflects items that are too cheap to be sold individually.
- a minimal quantity expressed in dollars for the purchase order as a whole, which is frequently encountered when the supplier does not charge for the delivery.
- a minimal quantity expressed in units per
*category*of items, which is frequently found for products that are*made to order*with minimal size on production batches.

Dealing with one constraint at a time is usually reasonably straightforward in practice. However, as soon as multiple MOQ constraints need to be taken into account together at the same time, composing a purchase order that satisfies all those constraints becomes a lot harder.

- the
**items**which represent what can actually be purchased. Item quantities are frequently integral numbers; although there is no restriction here for them to be. - the
**ordered quantities**for every item (possibly zero) which represent a potential solution to the MOQ problem. - the
**rewards**associated to each extra unit for each item - basically what is obtained through the stockrwd function (stock reward), although using this function is not a requirement. - the
**costs**associated to the units to be acquired. The goal is indeed to maximize the reward for a given spending budget expressed in*costs*. Costs are typically expected to be flat per unit, but here we don't make assumptions; thus, price breaks may be taken into account. - the
**targets**which represent a way of specifying a stopping criteria which may not be the actual costs. This one is quite subtle, and covered in greater detail below.

The canonical stopping criteria while purchasing according to a

The concept of the

Ex: Frank the supply chain manager puts a target at 90% fill rate. The solving the MOQ problem consists of computing the smallest order - in costs - while *maximizing the rewards* that delivers a 90% fill rate. This order is NOT the smallest order possible to achieve the 90% fill rate - as this would be a pure fill-rate prioritization. Instead, it's the smallest order that, while prioritizing the rewards, is large enough to deliver a 90% fill rate. A pure fill-rate prioritization would have been a mistake because, unlike the stock reward, it does not take into account the cost associated to the generation of dead stock.

Let $I$ be the set of items being considered for ordering. Let $q_i$ with $i \in I$ the quantity to be ordered for the item $i$.

Then, we define a series of functions.

- Let $r_i(q)$ be the
*reward*when holding $q$ units of the item $i$. - Let $c_i(q)$ be the
*cost*when buying $q$ units of the item $i$. - Let $t_i(q)$ be the
*target*when holding $q$ units of the item $i$.

The reward function can return positive or negative values, however both the cost and target functions are strictly positive: $$\forall i, \forall q, c_i(q) > 0 \text{ and } t_i(q) >0$$ Let $M$ be the set of MOQ constraints. For each $m \in M$, we have $I_m$ the list of items that belongs to the constraint $m$ and $Q_m$ the minimal quantity that should be reached to satisfy the constraint. Let $m_i(q)$ the function that defines the contribution of the item $i$ to the MOQ constraint $m$ when $q$ units are purchased. The constraint $m$ is said to be satisfied if: $$\forall i \in I_m, q_i = 0 \text{ or } \sum_{i \in I_m}m_i(q_i) \geq Q_m$$ Thus, all MOQ constraints can be satisfied in two ways: either by reaching the MOQ threshold, or by having all item's quantities at zero.

Then, let $C$ be the maximal cost that can be afforded for the purchase order. We define $\textbf{q}_C=(q_i)_i$ the best purchase order as: $$\textbf{q}_C = \underset{q}{\operatorname{argmax}} \left\{ \sum_i r_i(q_i) \text{ with $m$ satisfied } \forall m\in M \right\}$$ The purchase order is the "best" in the sense that is maximizes the reward for a given budget. The solution $\textbf{q}_C$ is not unique, however, this consideration is rather theoretical because the MOQ problem is too hard for an exact resolution anyway. For the sake of simplicity, we proceed as if the solution was unique in the following.

Finally, let $T$ be a target minimum, we define $\textbf{q}^T$ with $$C^T = \underset{C}{\operatorname{min}} \left\{ \left(\sum_{q_i \in \textbf{q}_C} t_i(q_i) \right) \geq T \right\}$$ and $$\mathbf{q}^T = \textbf{q}_{C^T}$$ The solution $\mathbf{q}^T$ is built on top of $\textbf{q}_C$, that is, it's the smallest optimal (budget-wise) ROI-maximizing solution that is good enough to fulfill the target.

`moqsolv`

function in Envision`moqsolv`

and removes the need for messy numerical recipes while trying to cope with MOQ constraints. The function `moqsolv`

is intended to process a series of vectors associated to a table of type `Id(*)`

typically obtained by extending a vector of distributions through `extend.distrib()`

(see also the Algebra of Distributions). The function expects the following arguments:

`moqsolv(Id, Min, Reward, Cost, Target, threshold, g0, oq0, moq0, g1, oq1, moq1, ...)`

With:

`Id`

the item grouping column`Min`

the unit ordering column - as in`Grid.Min`

`Reward`

the reward for the line - as obtained through`stockrwd`

, the stock reward function`Cost`

the cost for the line - typically`PurchasePrice * Grid.Q`

`Target`

a target quantity - which can be equal to`Cost`

for a simple budget capping. By setting`Target == Cost`

, one is telling the solver to do a*budget*optimization (resp.`Target != Cost`

a*target*optimization).`threshold`

a scalar value acting as the threshold for the*target*. In case of a*budget*optimization, the target value is a upper bound on the cost associated to the solution. In case of a*target*optimization, the target value is a lower bound on the target associated to the solution. If the threshold value is negative, then the negative sign is interpreted as a Boolean flag to approach the (positive) target from*below*, instead of approaching the target from above. The sign of the threshold is only used to control the direction of the inequality, the threshold value is always interpreted as positive.`g0, oq0, moq0`

represents a triplet of vectors associated to each MOQ constraint (detailed in the following).

See also Prioritized ordering with ordering constraints- a tutorial that illustrates how the

`moqsolv`

function can be used to compose a purchase order that satisfies MOQ constraints.The function returns a

`bool`

vector where all lines eligible within the target are flagged as `true`

. The combination of all the lines at `true`

satisfies the MOQ constraints. The solver approximates the solution $\textbf{q}^T$ as defined in the previous section. As expected from the definition introduced in the previous section, the arguments `Cost`

, `Target`

and `threshold`

are expected to be strictly positive.Each MOQ constraint is defined by a three vectors:

`G`

the MOQ grouping, which can be equal to`Id`

in case of per-item MOQ`OQ`

the contribution of the line to the*order quantity*of the MOQ constraint.`MOQ`

the threshold that should be reached to satisfy the MOQ constraint.

The groups defined by

`G`

should define a partition of the item identifiers. The MOQ threshold is expected to be identical across all lines associated to the same `G`

value. All `OQ`

contribution values are expected to be strictly positive. The `MOQ`

values should be positive, but can be zero to reflect the Multiple MOQs can be specified by including multiple triplets. Envision supports up to 4 concurrent MOQ constraints.

- ABC analysis
- Backorders
- Container shipments
- Economic drivers
- Economic order quantity
- Fill Rate
- Financial impact of accuracy
- Inventory accuracy
- Inventory control
- Inventory costs (carrying costs)
- Inventory turnover
- Lead time
- Lead demand
- Min/Max Planning
- Minimal Order Quantities (MOQ)
- Multichannel Order Management
- Optimal service level formula
- Perpetual Inventory
- Phantom Inventory
- Prioritized Ordering
- Product life-cycle
- Quantitative supply chain
- Reorder point
- Replenishment
- Safety stock
- Service level
- Stock-keeping unit (SKU)
- Stock Reward Function

- Backtesting
- Continous Ranked Probability Score
- Data preparation
- Forecasting accuracy
- Forecasting methods
- Obfuscation
- Overfitting
- Pinball loss function
- Probabilistic forecasting
- Quantile regression
- Seasonality
- Time-series

- Supply Chain Antipatterns
- Devil's advocate
- The Non-Euclidian Horror
- The 100% service level
- The Jedi initiation

- Bundle Pricing
- Competitive Pricing
- Cost-Plus Pricing
- Decoy Pricing
- Long-term maintenance agreement pricing
- Long-term pricing strategies
- Odd Pricing
- Penetration Pricing
- Price Elasticity of Demand
- Price Skimming
- Repricing software (Repricer)
- Styling Prices for Retail