A pharmacy checkout screen can look like ordinary retail software: search, scan, quantity, total. The difficult part is the meaning of the stock behind that screen.
A medicine name does not uniquely describe a saleable item. Strength, dosage form, pack size, batch, expiry and the unit being sold all matter. These are useful domain-model questions for developers building inventory systems, even before choosing a framework.
We work on RunMyPharmacy, pharmacy software for medical stores in Pakistan. This article explains a design approach for the domain. The schema and calculations below are illustrative, rather than a description of every detail of our production implementation.
1. Separate product identity from physical stock
A product record describes what the item is. A batch record describes a particular lot of that item. Putting expiry only on the product record loses information as soon as a second delivery has a different expiry date.
An illustrative model:
Product
id
name
strength
dosage_form
pack_description
barcode
Batch
id
product_id
batch_number
expiry_date
stock_status
StockMovement
id
batch_id
quantity_in_base_units
movement_type
source_document_id
created_at
The exact fields will depend on the business and applicable requirements. The key separation is that two batches can belong to the same product while having different stock status and expiry dates.
2. Make unit conversions explicit
Suppose a hypothetical carton contains ten strips. Receiving three cartons should add thirty strips if a strip is the chosen base unit. Selling two strips should subtract two, not two cartons.
received_base_units = purchase_quantity × base_units_per_purchase_unit
3 cartons × 10 strips per carton = 30 strips
30 strips − 2 strips sold = 28 strips remaining
That example is about recording units, not permission to split or dispense a particular product. Supported sale units must follow the product and the store's authorised process.
Show the unit beside every quantity. Validate conversions at setup, receiving and checkout. A perfect-looking quantity field is dangerous when its unit is implicit.
3. A barcode is a lookup aid
Scanning should identify a candidate product quickly. It should not erase the need to display exact identity or resolve the relevant batch.
Useful interface details include visible strength and dosage form, clear pack information, an explicit unit selector and a readable unavailable state. Avoid silently accepting a loosely matched product when the exact barcode is unknown.
In a rehearsal, try two similar-looking products and a barcode that is not in the catalogue. Observe whether a staff member can understand the result and refer uncertainty appropriately.
4. Keep stock status visible
A returned product, a questionable delivery or an expired batch should not be indistinguishable from saleable stock. Match the physical handling process with a system status and appropriate permissions.
A status change should record who made the decision and why. Creating a refund or supplier credit does not, by itself, establish that the physical item can be sold again. The authorised professional and quality process must determine that.
For developers, this means availability should be a domain decision rather than a simple sum of every quantity in the database.
5. Preserve the movement history
Receiving, selling, returning and adjusting stock are different events. An unexplained edit to a current-balance field makes discrepancies difficult to investigate.
Keep a reference to the originating document and a reason for adjustments. Treat a supplier order and an actual receipt separately: an order for twenty units is not evidence that twenty arrived.
On the server, design sale and stock updates so a partial failure does not leave an invoice completed with its stock movement missing. Duplicate submissions and concurrent attempts to sell the last available unit deserve deliberate handling. These are engineering concerns to test, not capabilities to assume from a responsive checkout UI.
6. Test workflows with consequences
Useful scenarios include:
- Two deliveries of the same product with different batches and expiry dates.
- A purchase unit that differs from the sale unit.
- A short delivery that leaves part of the order outstanding.
- A return awaiting assessment rather than automatic release.
- A duplicate checkout submission.
- Two sessions attempting to sell the final available unit.
- A stock adjustment that needs an explanation and approval.
These tests challenge the business model rather than merely confirming that a button calls a function.
Connect the model to the real workflow
A stock system succeeds when the recorded identity, unit, batch and status match what staff handle at the counter. Review those decisions with the people responsible for receiving and authorised professional work.
For the owner-facing side of these questions, our opening-stock guide includes a downloadable planning worksheet, and the pharmacy software guide explains how billing, purchasing and inventory fit together.
What stock-model edge case has caused the most trouble in a system you have built?
Prepared with AI assistance and reviewed against the product's public materials. Examples are illustrative.
Top comments (0)