Home/Blog
Guides

Running an online specialty coffee brand: inventory by roast date, subscriptions and accounting

The store sells the coffee. Roast dates, batch cost and monthly subscriptions are not run from the store dashboard. This guide is about where they are run from.

Running an online specialty coffee brand: inventory by roast date, subscriptions and accounting
In short
  1. An online-only roaster is the simplest shape in coffee: one location, national shipping, some subscription revenue, no branches and no wholesale.
  2. Freshness is the constraint that makes it different. Roast date is a stock attribute, not a note on a label.
  3. The store dashboard holds the sale. It does not hold roast date, roast loss, batch cost or a subscription as recurring revenue.
  4. Picking oldest first is the single change that stops you shipping a fresh bag while older stock quietly ages out.
  5. A small roaster selling a few hundred bags a month usually does not need any of this yet, and that is a fair answer.

The model, in one paragraph

Green beans in, roast to order or to a forecast, pack, ship nationally, and take some of the revenue as a monthly subscription. No branches, no wholesale accounts, no counter. It is the simplest of the coffee models, which makes it the right place to start, and the one where the gap between what the store dashboard does and what the business needs is easiest to see. If you are still deciding whether the question applies to you at all, does your store need an ERP covers it from the start.

What the store dashboard does not hold

Your storefront is good at selling coffee. It records that a customer bought a 250g bag of a named coffee, took the payment, and produced a shipping label. Four things it does not hold, and all four matter more in coffee than in most categories.

Roast date as a property of the stock. Not a line on the label, but an attribute the system can sort and pick by.

Cost from green to roasted. The bag you ship is lighter than the beans you bought, and the difference has to land somewhere.

A subscription as recurring revenue, rather than the same customer placing a similar order twelve times.

Returns on something perishable, where the question is not only whether to refund but whether the bag can go back into sellable stock at all.

Inventory by roast date

This is the section that matters most, and it is the one thing a general stock count cannot do for you.

Each roast becomes a lot, carrying its own roast date. Odoo's expiry tracking then gives that lot up to four dates: a best before date, an end of life date, an alert date that warns you in advance, and a removal date, which is the one the picking rule reads. Set the freshness window you sell to, say thirty days from roast, and the removal date follows from the roast date automatically.

Then switch the removal strategy to first expiry, first out. From that point the system picks the lot closest to its limit rather than whatever is nearest the door. That one setting is the difference between a warehouse that rotates itself and one that quietly ages out its oldest stock while shipping the freshest bag to a customer who would not have minded either way.

What a merchant sees looks like this.

LotRoastedWindow usedBagsStatus
R-090124 days ago24 of 30 days8Near limit
R-091012 days ago12 of 30 days28Next
R-09184 days ago4 of 30 days48Freshest

Three lots of the same coffee, 84 bags in total, sold on a thirty day window. R-0901 ships first because it has six days left, and the alert date is what tells you that in time to do something about it, whether that is prioritising it, bundling it, or putting it in subscription boxes going out this week. Without lots, those 84 bags are one number and the decision is invisible. Odoo's inventory application is where this lives.

From order to invoice

The full path for a single bag, once the store and the system are connected.

  1. Store order. Customer, items and payment.
  2. Into the system. A sales order is created and stock is reserved.
  3. Roast batch. The lot number and roast date are recorded against what was produced.
  4. Packing. The oldest lot is picked first.
  5. Courier. Shipment raised and the tracking number attached.
  6. E-invoice. Issued and reported to ZATCA from the same record.

Nobody retypes anything at any step, and the lot number stays attached from the roast to the invoice, which is what makes a quality complaint traceable to a batch rather than to a guess.

Batch cost, from green to roasted

This is where most roasters are quietly wrong, and it is arithmetic rather than accounting.

Take an illustrative example. You buy a 60kg green lot. Roasting drives off moisture, so at a typical loss of around 16 percent you are left with roughly 50kg of roasted coffee, which is about 201 bags at 250g. The cost that belongs on one bag is its share of the green lot, plus the roast, plus packaging and labour, divided across 201 bags rather than across the 240 bags the green weight would have suggested.

Cost from the green weight and every bag is understated by the loss. Do it from the roasted weight, per lot, and the margin you read is the margin you have. If roast batches are tracked as production, manufacturing is what carries the bill of materials and the loss.

Subscriptions

A monthly subscription is not twelve orders. It is one agreement that generates a delivery and an invoice on a schedule, and the distinction shows up in your numbers immediately: recurring revenue you can forecast, churn you can see, and a roast plan you can build against next month's committed volume rather than last month's guess.

Odoo's subscriptions application holds the agreement and raises the recurring invoice. Whether the subscriber manages their own plan from the storefront depends on how the store and the system are connected, and that is worth settling during setup rather than after the first renewal.

What you actually need to switch on

Less than most people expect. Sales, inventory with lot and expiry tracking, accounting, and purchasing for green buying. Add manufacturing only if you want roast batches tracked as production with a bill of materials and a recorded loss. Add subscriptions when subscription revenue is material rather than experimental.

If your store is on one of the Saudi platforms, the connection itself is covered separately: connecting a Salla store and connecting a Zid store each set out what moves and how the setup runs.

FAQ

Frequently asked questions

What is the best system for a specialty coffee shop selling online?

The one that holds roast date as a stock attribute, costs a bag from roasted weight rather than green weight, and treats a subscription as recurring revenue. Those three are what separate coffee from general retail. Everything else a storefront and an accounting tool can already handle between them.

How do I manage coffee stock by roast date?

Track each roast as a lot carrying its roast date, set the freshness window you sell to so the removal date is calculated from it, and switch the picking rule to first expiry, first out. The system then picks the lot closest to its limit automatically, and an alert date warns you before a lot reaches it.

How do I work out the cost of a kilo of roasted coffee?

Divide the lot's cost by the roasted weight, not the green weight. Roasting drives off moisture, commonly around 15 to 18 percent, so a 60kg green lot yields roughly 50kg roasted. Costing from the green figure understates every bag by the loss, and the error compounds across the year.

How do I account for monthly coffee subscriptions?

As one recurring agreement that generates a scheduled delivery and an invoice each period, rather than as a series of separate orders. That gives you forecastable recurring revenue, visible churn, and a roast plan built on committed volume. It also stops the same subscriber appearing as twelve unrelated customers in your reports.

Does a small roaster actually need this?

Often not, and it is worth saying plainly. If you roast once a week, sell a few hundred bags a month from one location and can name your slowest-moving lot from memory, a storefront and a good accounting tool are enough. The case appears when lots outnumber what you can hold in your head, or when subscriptions and wholesale start pulling against the same stock.

What happens to a returned bag of coffee?

The refund is the easy part. The real question is whether the bag can go back into sellable stock, and for a perishable product opened or not, the answer is usually no. Recording the return against its original lot keeps your stock figure honest and shows you whether returns cluster on a particular roast, which is the more useful signal.

Can the system issue ZATCA e-invoices for online coffee orders?

Yes. Once a synced order becomes an invoice, e-invoicing runs through Odoo's Saudi localisation, so the compliant invoice comes out of the same record that holds the order, the lot and the payment. Check your own wave and integration deadline on the ZATCA e-invoicing pages.

How long does setting this up take, and what does it cost?

Both depend on scope: how many applications, how clean your product and supplier data is, and whether roast batches are tracked as production. For an online-only roaster the setup is at the simpler end, because there are no branches and no wholesale pricing to model. A scoped quote after a discovery session is the only honest number.

Keep reading

Related articles

Ready to run your business on one system?

Free consultation. Meet the team and get a clear roadmap in one call.

Book your consultation