In most small and mid-sized trading and manufacturing companies, the customer ranking is built by revenue. That's the simplest — and most misleading — number you can put on a slide. The "top" customer by revenue can easily be number twenty by profit, and nobody sees it, because no single report in the ERP shows it.
We worked with a regional power-tool wholesaler (45 people, one warehouse, Comarch Optima with an in-house billing add-on). The owner had lived for years with the belief that five biggest customers kept the company alive. Once we spent three weeks loading real per-unit costs onto sales invoices — shipping (split by route), twelve months of returns and complaints, unreturned reusable packaging, sales rep hours spent on custom orders, even accounting time explaining offsets — one of that "top five" turned out to be running a roughly 40 000 PLN loss a year. Not small. And the other four weren't nearly as rosy as the revenue ranking suggested.
Why write this up? Because it's one of those things: trivial to compute once you know how, and nobody in the company has time to do it. And the difference at year-end is bigger than most "cost optimisation" programmes put together.
Why revenue lies
Revenue tells you how much a customer left with you. It doesn't tell you how much you kept. Between the two sits a whole factory of invisible costs: discounts, purchase cost, freight margin, returns, complaints, payment terms (and the financing behind them), staff hours spent servicing orders, reusable packaging losses, collection costs.
A typical SME wholesaler has all of this scattered across five records:
- Sales invoices and credit notes in Optima or enova365.
- Complaints in a separate Excel file on the warehouse manager's computer.
- Courier route summaries in yet another file at the logistics coordinator.
- Balances and interest notes at the bookkeeper.
- Sales rep hours — nowhere.
Until this comes together in one place, "customer profitability" is a slogan, not a number.
What to actually count
There's no point pretending you run a corporate controlling function. The goal is different: enough accuracy to make a decision. Six to eight cost components are usually enough:
- Purchase cost of the goods — ideally a weighted average of the last N purchases, not the last recorded price.
- Discounts and promotions attributed to a specific customer (not just the invoice discount, but also "one free per N" campaigns).
- Shipping cost — if you deliver yourselves, cost-per-km times the route; if a courier, the real rate after rebates.
- Returns and complaints from the last twelve months attributed to the customer.
- Service cost — sales rep time, bookkeeper time (average rate × estimated hours per month).
- Trade credit cost — if the customer pays after 60 days and you finance yourself via factoring at 8% a year, that isn't free.
- Reusable packaging (pallets, containers, kegs) — if the customer regularly doesn't return them, that's a real cost line.
Anything more granular than that is academic, not useful. You don't need textbook activity-based costing — you need numbers close enough to reality to stop being wrong in a sales conversation.
How to build it in the ERP
The sequence that works for our clients:
- Define the model. On paper, before anyone touches the system. Which components, from which tables, at what frequency (monthly/quarterly). Do not mix periods — averaging annual and monthly data is the fastest route to nonsense.
- Fill the ERP gaps first. In Optima there are usually three missing pieces: shipping cost tied to a specific WZ document, real purchase cost in cost of goods sold (often taken from the price list, not the actual purchase), and a "complaint cost" field on returns. Without those, the report will always be lame.
- Export it as one report. Do not try to do this "live" in the ERP GUI. Build a SQL report (or view) on a database copy that returns one row per customer per period with all eight columns. One hour of developer time, two days a month of bookkeeper time.
- Plug it into Power BI, Metabase or plain Excel. Do not pick the "trendy" tool — pick the one the owner actually opens. If the owner only opens Excel, the report goes into Excel.
- Show two views. First: ranking by direct profit (margin minus variable costs). Second: a 2×2 map — revenue vs. profitability. That second chart is why you're doing all of this in the first place.
The whole project for a mid-sized wholesaler is typically 3–5 working days on our side and about the same in-house effort tidying up data. Monthly refresh: half a day.
What to do with the result
This is the part many owners flinch from: the hard sales conversation with a customer who runs at a loss. In a small company the customer is often a friendly phone number.
Practically sensible options before you "cut" anyone:
- Raise the discount threshold. A customer used to a 12% rebate at old volumes might get 8% and stay — if the competition offers less.
- Change delivery terms. Self-pickup or paid delivery below a threshold. That move alone often lifts the customer out of the red.
- Shorten payment terms. From 60 to 30 days. If the customer refuses, you learn how much they need you.
- Move service to a cheaper channel. A B2B web shop, email, one "C-customer" rep instead of a dedicated relationship manager.
At the wholesaler above, after the analysis the owner picked only the three biggest loss-making customers, changed their discount and payment terms, and — after a polite conversation — parted ways with one. Two stayed on the new terms, one walked. Net after a year: about 380 000 PLN of additional gross margin. No layoffs, no scrimping on toilet paper, no "IT optimisation".
It's one of the few things in a company where a decent report pays for itself in months.
Revenue tells you who buys from you. Profit tells you who works for you. It's worth knowing which is which.