AWRA OpsHub Search

The Store That Empties Once a Year: Reorder Points, Dead Stock & Expiry

Reorder points assume stock is consumed steadily and replaced continuously. An input store buys once, sells for six weeks and then holds whatever is left for eleven months. Three alerts now watch that store, one of them shipped this month — and one number you type by hand decides whether any of them help.

Agribusiness & Cooperatives Washingtone Aura 14 min read

Almost every inventory feature ever built assumes a shop. Stock goes out at a rate, the rate is roughly stable, you watch a level and you top it up. An agricultural input store breaks all three assumptions at once: it buys a season's worth in one purchase, sells most of it in six weeks around the rains, and then sits on the remainder until the next long rains — by which time some of it has expired and all of it has cost you money to hold.

That is not a reason to avoid stock control. It is a reason to be precise about which of its parts help you and which will quietly mislead you, because a reorder point set for a shop is actively wrong in a store that buys once.

3
automatic stock alerts, all of them daily or faster
90
days idle before the dead-stock alert fires, by default
30/60/90
expiry horizons, with the value at risk in each
0
of them that read your demand forecast

The three alerts, and what each one actually watches

Start here, because these are the parts that do work without you thinking about them daily. All three run without anybody opening a page, which is the whole point — a report about stock that is not moving is a report nobody opens, precisely because nothing is happening.

Alert When it fires What it is blind to
Low stock The moment an item crosses to or below its reorder point, on any decrease path — plus a daily digest at 08:30 Whether you actually intend to reorder. In a store that buys once a season, crossing the line in week five is expected
Batch expiry Daily, for any batch expiring within 90 days, bucketed 30/60/90 with the value at risk — and only where stock is still on hand Batches with no expiry date typed. It cannot alert on a date nobody entered
Dead stock Daily, once an item has had no movement for the configured number of days — 90 by default, and 0 turns it off Whether the stillness is a problem. Out of season, most of your store is legitimately still

The low-stock alert is edge-triggered rather than scanned, which matters more than it sounds: it fires on the transaction that crosses the line, once, rather than nagging every hour while the level stays low. The dead-stock alert is the opposite by necessity — dead stock is defined by the absence of a movement, so there is no moment to hook and it has to be a scan. It stamps the item when it alerts and clears that stamp the next time the item moves, so a resurrected item that goes quiet again is alerted afresh.

The expiry alert has a switch, and until this batch you could not reach it

Expiry alerts were gated by an on/off setting and a cadence that existed in code and appeared on no screen — so the alert sent daily and there was no way to slow it to weekly or turn it off. It is now registered with the other notification settings alongside the low-stock alert, which is where anyone would look for it. The workflow event behind it fires regardless of the email preference, so you can automate on an expiring batch even with the mail muted.

Why the reorder point is the weak link

Everything above hangs off one figure, and the figure is stranger than it looks. The reorder point is a single number on the item — not seasonal, not per store, not per location. Two things can tell you what it ought to be: the Inventory Turnover & DIO report, which gives you turns and days-of-inventory per item over any range you pick, and the per-item demand forecast, which estimates units per day from movement history with outlier capping and a sensitivity setting. Both exist, and neither of those two writes anything back.

Something else does. A scheduled job runs at one o'clock every morning and recalculates the reorder point from its own usage figure — thirty days of recorded stock issues, divided by thirty, multiplied by the item's lead time, plus its safety stock — and writes the result over whatever was there. So the number you typed in March is not sitting there untouched. It is being replaced nightly, by an average taken over a window that, in a seasonal business, may be describing a completely different part of the year.

And there is a sharper edge to it. That usage figure counts documented issues — check-outs, issues against an invoice, procurement issues, adjustments. Stock rung up at a till is not one of them. An input store selling over the counter therefore looks, to the calculation, like a store with no usage at all — which produces an average of zero, a reorder point of zero, and a low-stock alert that can never fire because low stock means on-hand at or below the reorder point. It does not error. It goes quiet. Sort your item list by reorder point and a block of zeros against your fast movers is the whole diagnosis.

In a continuous business that is a mild limitation. In a seasonal one it produces a specific failure: you set the point in March when the store is full and demand is heavy, and it then fires all through the dry season on items you have deliberately run down and will not replace until the next purchase. Three weeks of that and everybody has learned to ignore the alert — which is expensive, because the one time it matters is when you run out of a fast-moving product mid-season.

Continuous store Single-season store

A reorder point

Genuinely useful — replenishment is continuous, so crossing the line means order more today

Low-stock alert

Reliable while the season runs; noise for the eleven months when you are not buying

Dead-stock alert

Cuts both ways. Out of season everything looks dead, so the threshold has to be set past your quiet period

Expiry alert

This is where the seasonal store lives. Chemicals and treated seed carry dates, and the value at risk is real money

Value-at-risk review

The number a seasonal business should manage against — what is on the shelf, what it cost, and how long it has left

Read your own store against this. If your business sits on the right, expiry and holding value are your controls and the reorder point is close to decoration — set it, but do not build your rhythm on it.

Setting the two thresholds for a seasonal store

You buy once a year and sell over six to ten weeks

Set the dead-stock threshold past your quiet period

A 90-day default will alert on almost every line in the store by the middle of the dry season. Push it beyond the gap between your selling windows — 200 days or more for a single-season store — so the alert means "this did not sell in a whole cycle", which is the thing you actually want to know.

You have two seasons, long rains and short rains

Leave the default, or shorten it

Ninety days roughly matches the interval between selling windows, so an item idle for that long genuinely missed a season. This is the case the default was designed for.

Nothing you hold has an expiry date

Turn dead-stock alerting up and stop there

With no expiry dates the expiry alert has nothing to work with — it cannot warn about a date nobody entered. Holding cost and obsolescence are then your only stock risks, and the dead-stock scan plus the aging report cover both.

You hold agrochemicals or treated seed

Capture the expiry date at receiving, without exception

This is the single highest-value data-entry habit in a seasonal input store. The batch carries the date, the alert reads it, and the value-at-risk figure comes out of the batch cost. Skip it at goods-in and no downstream control can recover it.

You want the store to stop selling something

Use a hold, not a note

Placing stock on hold — quarantined, damaged, expired, returned or inspection-pending — genuinely removes it from every allocation query, so it cannot be sold or issued. A sticker on the shelf and a note in the description do not.

What a season of holding actually costs

One input store, one year, four lines

Purchased in February for the long rains KES 3.4m
Sold by mid-May KES 2.6m
Left on the shelf on 1 June KES 0.8m
Of that, chemicals expiring before the next season KES 260,000
Flagged by the expiry alert at the 90-day horizon KES 260,000
Recovered by discounting into the short rains KES 190,000
Written off after expiry, disposal recorded KES 70,000
The alert did not save the stock — it bought ninety days to decide what to do with it 73% recovered

Illustrative. The point of the horizon is not the warning, it is the notice period. At 90 days you can discount, transfer to a busier branch or negotiate a return; at 30 you can discount; at zero you can only dispose. Everything the alert is worth is spent in the first bucket.

The four things that will not happen for you

Being exact about these prevents the specific disappointment of assuming an alert covers a case it does not.

  • Nothing expires stock automatically. The expired status exists and no job ever sets it. A batch past its date is still ordinary available stock, sellable and issuable, until a person places it on hold or disposes of it. The alert tells you; it does not act.
  • Nothing checks remaining shelf life at receiving. You cannot require, say, 75% of shelf life remaining on delivery and have goods-in warn or refuse. A drum with two months left is received exactly like one with two years.
  • There is no supplier return window, so "we can send it back until August" is knowledge that lives with a person rather than a date the system holds.
  • A hold is per stock row, not per batch. One batch spread across four locations takes four holds, and missing the fourth leaves that stock sellable. Check the batch's locations before you consider it frozen.

The expired status exists and nothing sets it. A batch past its date is ordinary sellable stock until a human intervenes — the alert is a notice, not a control.

What we do and do not do

Seasonal stock control — the straight answer

What AWRA OpsHub does today

  • Low-stock alerting in real time, fired on the movement that crosses the reorder point, plus a daily digest — one chokepoint covering check-outs, sales, transfers and adjustments.
  • Batch expiry alerting, daily, bucketed at 30/60/90 days with an expired bucket and the value at risk, and limited to batches with stock still on hand.
  • A Batch Expiry (FEFO) report with a selectable window, and a Dead Stock & Aging report behind the dead-stock alert.
  • Dead-stock alerting, with the idle threshold configurable per organization, 0 to disable, and a stamp that clears when the item next moves so it cannot nag.
  • Enforced holds — quarantined, inspection-pending, damaged, expired, returned — filtered out of every allocation query, with quantity, reason and acting user recorded on hold, release and disposal.
  • Batch cost carried through landed cost, so the value-at-risk figures are your real cost rather than a list price.
  • An Inventory Turnover & DIO report over any date range, per item and overall, with non-movers flagged and CSV/PDF export — and a per-item demand forecast giving units per day from movement history, with outlier capping and a sensitivity setting.

More we can add to your workspace

  • Over-the-counter sales in the nightly reorder-point calculation. It reads documented issues today — check-outs, invoice issues, procurement, adjustments — so a store selling at a till shows zero usage, and a zero reorder point is an alert with nothing to fire on. This is the one that matters most.
  • A pinned figure and a seasonal profile. The nightly recalculation overwrites the stored number unconditionally, so a figure a person chose deliberately needs somewhere to be held — and one thirty-day average currently serves a business with a six-week selling window.
  • A par level per store or per location. One reorder point serves the item everywhere it is held.
  • Automatic expiry on stock. Past-date batches held or flagged on the date, rather than waiting for a person to act on them.
  • A shelf-life policy at receiving and no supplier return window.
  • A temperature or sensor integration, so a cold-chain breach on treated seed or veterinary stock is invisible.
  • A seasonal buying plan. A purchase calendar and a season entity, so the one big annual purchase is more than an ordinary set of purchase orders.

The pattern is worth seeing: the alerting layer is genuinely complete and automatic, and the inputs it depends on are split. Expiry dates and batch numbers are typed at goods-in and stay as typed — that is data-entry discipline. The reorder point is not: it is recalculated nightly, from a usage figure that may or may not include the way your store actually sells. Knowing which of your inputs are yours and which are the system's is what turns three good alerts into three useful ones.

More we can add to your workspace

Anything above that you need, we can build for you

Everything listed above as something we can add describes what ships in the standard product today — it is a starting point, not a limit on what AWRA OpsHub can do for your organisation. Kenya's eTIMS integration and its maintained payroll engine are both in the product because clients needed them and commissioned them; neither appeared by itself, and the same door is open for whatever you just read about. One qualification so this is worth what it claims: a small number of things on this blog we deliberately leave to a specialist rather than build — a statutory ledger we will not sign our name to, a rule that would decide a tax question for you, a clinical or member-funds record that belongs in a regulated system — and where that is true the post says so in those words. Everything else is a scope, a timeline and a price.

The operational work, which is what most commissions actually are

An extra approval stage in a chain that does not match the standard one, a custom field set on employees or assets that only your sector needs, an expiry that has to block an order rather than send an email, a report your board asks for in a shape nothing produces, or a scanner or weighbridge feeding the goods-in door. These are the commissions we are asked for most often and the smallest ones we quote — and unlike a revenue-authority pipeline, none of them waits on a regulator.

The module-shaped additions, which are the ones readers ask for most often

A price list with real discount authority, a customer-facing quotation that expires, a bill of materials or recipe costing, a staff advance that is issued, acquitted and chased, a member or unit ledger, a matching rule that holds a payment. Each of these is a build rather than a setting, and each has been quoted before — a bigger piece of work than a custom field, with a written spec and a date instead of a roadmap slide.

The report, document or pack nothing currently produces

The board pack in the shape your board actually asks for, a donor or funder layout, an invoice or receipt template carrying what your regulator or your customer expects, a dataset the report builder cannot reach yet. Usually the fastest thing on this list to deliver, because the data is already in the system.

Systems, rails and hardware you already run

The accounting package, CRM, online store, core banking or custom database you intend to keep — connected through our API so a fact is entered once and appears everywhere it is needed. Plus the physical edge: a scanner, a scale, a weighbridge or a till peripheral feeding the door it belongs to.

How it works: you describe the requirement, we return a written scope, timeline and cost, and once agreed it is built into your environment and maintained as part of the product. Nothing here waits on a regulator or a published specification, which is why operational builds are the ones we quote fastest. Tell us the requirement that would otherwise rule us out — that is a better first conversation than a demo.

Tell us what your operation needs

The rhythm that fits a seasonal store

  • At goods-in: batch number and expiry date on every dated line, no exceptions, before the delivery is signed for.
  • Once, before the season: safety stock set on the lines you cannot be caught without — it is the one part of the reorder point the nightly recalculation adds rather than replaces — and the dead-stock threshold set past your quiet period.
  • Weekly in season: the low-stock digest read and acted on, because in season it means what it says.
  • Monthly out of season: the expiry horizon report, working the 90-day bucket first — that is where the options are.
  • At season end: the dead stock and aging report read line by line, and a decision recorded for each line rather than a plan to think about it.

Our take

For a store that buys once a year, expiry and holding value are the controls that matter and the reorder point is the one most likely to mislead you. Push the dead-stock threshold past your quiet period so the alert means something, capture expiry dates at goods-in without exception, and work the 90-day bucket rather than the 30 — the entire value of an expiry alert is the notice period it buys, and it is spent by the time the date arrives.

See stock alerting and batch expiry

Real-time low-stock triggers, a daily 30/60/90 expiry horizon with value at risk, dead-stock scanning you set the threshold for, and holds that genuinely stop issue.

Explore inventory management

Frequently asked questions

Does anything warn us before stock expires?

Yes. A daily scan alerts on any batch expiring within 90 days, bucketed at 30, 60 and 90 days with an expired bucket, and each bucket carries the value at risk computed from batch cost. It only alerts on batches with stock still on hand, because an alert about stock that is not there is how an alert gets muted. It also fires a workflow event per scan, so you can automate a response — raise a task, notify the storekeeper, start a supplier return — even if the email is switched off.

Will expired stock stop being sold automatically?

No, and this is the most important limitation to plan around. The expired status exists and no job sets it, so a batch past its expiry date remains ordinary available stock — sellable and issuable — until a person places it on hold or disposes of it. Holds are genuinely enforced once applied: held stock is filtered out of every allocation query. So the alert tells you and a human acts. Build that step into somebody's week.

How should we set a reorder point in a business that buys once a year?

Read it off the numbers that already exist, then type it — because nothing writes it for you. The Inventory Turnover & DIO report gives turns and days of inventory per item over any range, and the per-item demand forecast estimates units per day from movement history. Neither feeds the reorder point, so the loop is manual and worth doing once a season for your fast-moving lines only. There is no seasonal profile, so accept that whatever you type will over-fire out of season, and manage the quiet months on expiry and holding value instead.

What does the dead-stock alert do, and what should the threshold be?

A daily scan flags items with no movement for the number of days you configure — 90 by default, and 0 disables it entirely. It stamps the item when it alerts so it cannot re-alert daily, and clears that stamp the next time the item moves. For a single-season business, push the threshold past the gap between your selling windows, or the whole store will be flagged every dry season and the alert will be ignored when it matters.

Can we require a minimum remaining shelf life on deliveries?

No. There is no shelf-life policy at receiving, so goods-in cannot warn or refuse when a delivery arrives with too little life left, and there is no supplier return window held anywhere. Both are contract terms you enforce by inspecting the dates at the door — which is why capturing the expiry date at goods-in matters so much: it is the only moment the information is in front of somebody.

If a batch is bad, can we freeze it everywhere at once?

Not in one action. A hold applies to a stock row — an item at a location — so a batch spread across four locations takes four holds, and the one you miss stays sellable. Check the batch's locations from the traceability view before you treat it as frozen. What does work properly is the hold itself: held stock cannot be allocated, sold or issued, and the hold records quantity, reason and who applied it.

Are these alerts on by default, and can we turn them down?

Low-stock and expiry alerting are on by default, and the cadence can be set to daily, weekly, monthly or a custom interval per organization. The expiry alert's switch and cadence were missing from the notification settings screen until this batch — they existed in code and no page could reach them — so it is now listed beside the low-stock alert. Dead-stock alerting is on with a 90-day default and switches off by setting the threshold to 0.

Help Center

Need a quick answer while you read?

Run inventory, procurement, assets, sales, and field work with approved AWRA guidance for setup, migration, integrations, security, pricing, and support.

Search all approved AWRA public help articles.

Open Help Center