A 6-branch pharmacy chain in Nagpur ran three different off-the-shelf billing tools across 14 months and abandoned all three. The reasons were always the same: Schedule-H drug compliance the software couldn't enforce, batch-and-expiry tracking that broke at branch transfers, and stock counts that disagreed between branches by Friday. We built them a custom inventory-plus-billing app in 9 weeks. This is the build-versus-buy story, the QA we ran, and the specific failures that made "buy" the wrong answer.
The Answer in 60 Words
Off-the-shelf pharmacy software failed this chain on three hard requirements: enforcing Schedule-H prescription capture at the point of sale, tracking batch and expiry through inter-branch transfers, and keeping stock consistent across six locations in near real time. Generic retail billing tools treat medicine like any SKU. We built a custom app on Next.js and PostgreSQL in 9 weeks. Expired-stock dispenses dropped to zero in the first 90 days.
Why This Matters Now
Indian pharmacies sit under the Drugs and Cosmetics Act, and Schedule-H and H1 drugs legally require a valid prescription record at sale. Drug inspectors check batch-wise records and expiry handling. A generic POS that lets a cashier sell a Schedule-H drug without logging the prescriber isn't just inconvenient — it's a compliance exposure. As chains add branches, the "spreadsheet per branch" approach collapses: stock you think is in Branch 2 was actually transferred to Branch 5 on Tuesday, and now you've sold air. The trigger for this client was a near-miss expiry incident that a manager caught by hand.
The Client (Specific Details)
Why Each Off-the-Shelf Tool Failed
Build vs Buy: The Honest Comparison
We don't default to "build." For most retail, off-the-shelf wins. Here's the actual decision table we walked the owner through.
| Dimension | Off-the-shelf | Custom build |
|---|---|---|
| Upfront cost | Low or no setup fee | One-time build |
| Monthly cost | Subscriptions per branch | Hosting only, all branches |
| Schedule-H enforcement | Partial or none | Built to the exact rule |
| Batch + expiry (FEFO) | Per-product at best | Per-batch, enforced at sale |
| Multi-branch live stock | Tool-dependent | Single ledger, real time |
| Time to value | Days | 9 weeks |
| You own the data | No | Yes |
How We Built It (The Methodology)
We started by sitting at the busiest branch's counter for two days. That's where we learned the cashier scans, then asks for the prescription, then bills — so the prescriber field had to slot into that exact rhythm or it'd get skipped. We modelled the stock ledger as an append-only log of movements (receipt, sale, transfer, return, write-off) rather than a mutable "current quantity" — so any branch's stock is a sum, and you can never get a mystery number you can't explain.
What We Built
The QA That Mattered (Manvi's Notes)
As Manvi, who led QA on this build, the riskiest area was never the happy path — it was the edges. We wrote test cases for the ugly cases first: a sale that fails mid-transaction (does stock get decremented anyway?), a transfer approved twice, an expiry-blocked drug sold via override, a return of a batch that's since expired. Each got an automated test plus a manual run on a real device at a real counter. Pharmacy software that's only tested on the happy path will quietly corrupt stock within a week.
Common Mistakes (When Custom Goes Wrong)
Symptom: "Stock numbers drift after a few weeks." Cause: mutable quantity field updated by multiple code paths. Fix: model stock as an append-only movement ledger; current quantity is always a sum, never a stored mutable value.
Symptom: "Cashiers skip the prescription field." Cause: it's optional in the UI. Fix: enforce it server-side for Schedule-H drugs — the save fails without it.
Symptom: "Expiry alerts are ignored." Cause: a flat list of 400 near-expiry items. Fix: rank by rupee value at risk, so the manager sees the high-value batch before the cheap strip.
Symptom: "Inter-branch transfers double-count." Cause: non-atomic move (deduct here, add there, in two steps). Fix: a single transaction that moves the units, or it doesn't happen at all.
When Not to Build a Custom Pharmacy App
If you run a single branch and a pharmacy SaaS already does batch-expiry and Schedule-H capture, buy it — a 9-week custom build is overkill. If you're under ₹3 crore turnover and not adding branches, the subscription math favours off-the-shelf for years. Custom earns its cost when compliance rules are strict, branches are multiplying, and no product on the market enforces your exact workflow. We told this client "buy" would've been our first recommendation — except they'd already proven it failed three times.
Outcome
In the first 90 days post-launch: zero expired-stock dispenses, Friday stock reconciliation went from a half-day accountant task to a glance at one dashboard, and the owner cancelled three software subscriptions. We saw a similar "one system replaces a tangle of tools" payoff building Radiant Finance's pipeline, and the same multi-branch inventory discipline shows up in our FMCG multi-vendor marketplace build. For the diagnostics-sector cousin of this project, see our write-up on a 9-branch pathology lab app.
Build-vs-buy checklist for pharmacy software
- Does it enforce Schedule-H prescription capture server-side?
- Is expiry tracked per batch, not per product?
- Does the sale screen default to FEFO and block near-expiry batches?
- Is stock a single live ledger across all branches?
- Are inter-branch transfers atomic?
- Is billing GST-ready with per-branch sequential numbering?
- Do you own and can you export your data?
A Note on the Stack
We built on Next.js (Pages Router) with a PostgreSQL backend, deployed on a single mid-tier cloud box for all six branches. We didn't reach for microservices — six branches and 31 staff do not need them, and they'd have tripled the ops burden. Our web development team ships most SMB line-of-business apps as a well-structured monolith for exactly this reason: it's the cheapest thing to run and the easiest thing to debug at 9 pm when a counter's down.
FAQ
Why did off-the-shelf pharmacy software fail this chain?
Three specific gaps: no Schedule-H prescription enforcement at the point of sale, expiry tracked per product instead of per batch, and no live stock view across six branches. Each tool failed at least one of these, and no single product solved all three.
What does per-batch expiry tracking actually require?
Every unit must carry its own batch ID and expiry date through receipt, sale, transfer, and return. The sale screen defaults to first-expiry-first-out and blocks batches near expiry. Per-product tracking collapses two batches with different dates into one number, which breaks safe dispensing.
How long did the custom build take?
Nine weeks from kickoff to go-live, against a 10-week fixed scope. That included two days shadowing a live counter, building the stock ledger and billing, GST compliance, the owner dashboard, and a full UAT cycle with hand-counted stock reconciliation.
When should a pharmacy buy instead of build?
A single branch under about ₹3 crore turnover, where an existing pharmacy SaaS already handles batch-expiry and Schedule-H capture, should buy. The subscription cost stays below a custom build's payback for years. Build wins when compliance is strict, branches multiply, and no product enforces your exact rules.
How do you keep stock consistent across branches?
We model stock as an append-only ledger of movements rather than a mutable quantity. Any branch's stock is the sum of its movements, so a number is always explainable. Inter-branch transfers move units in a single atomic transaction, which removes double-counting.
What did the chain save after launch?
Zero expired-stock dispenses in the first 90 days, Friday reconciliation reduced from a half-day accounting task to a dashboard glance, and three cancelled software subscriptions.
What stack did you build it on?
Next.js with a PostgreSQL backend on a single cloud server for all six branches — a structured monolith, not microservices. At six branches and 31 staff, a monolith is cheaper to run and faster to debug than a distributed setup.
Off-the-Shelf Not Cutting It for Your Multi-Branch Business?
We build custom inventory, billing, and compliance apps for Indian SMBs with 3–15 branches. Fixed-scope, typically 8–12 weeks. We'll tell you honestly if buying beats building. First call is with the engineer who'd lead it.
Book a 20-min Call
