-
Notifications
You must be signed in to change notification settings - Fork 134
Pharmacy Batch Management and Expiry Tracking
HMIS tracks every pharmacy stock unit at the batch level from the moment of goods receipt through to dispensing, transfer, adjustment, or disposal. Each batch carries a batch number, manufacture date, expiry date, and purchase cost. The system enforces FIFO/FEFO (First In First Out / First Expired First Out) at the point of dispensing — the oldest or soonest-expiring batch is automatically selected — minimising expired stock write-offs. Wastage (discards, expired disposals) is recorded with category and reason, maintaining a complete chain of custody for every unit received.
| Function | Menu Path |
|---|---|
| GRN (batch entry) | Main Menu → Pharmacy → Procurement → GRN |
| Bin Card (batch-wise) | Main Menu → Pharmacy → Reports → Bin Card (Batch) |
| Stock by Batch | Main Menu → Pharmacy → Reports → Department Stock by Batch |
| Expiry Report | Main Menu → Pharmacy → Reports → Expiry Tracking |
| Adjustment (expiry correction) | Main Menu → Pharmacy → Stock → Adjustment |
| Wastage / Disposal | Main Menu → Pharmacy → Stock → Disposal |
| Physical Stock Take | Main Menu → Pharmacy → Stock → Stock Take |
When a GRN is entered, each drug line creates or updates an ItemBatch record:
| Field | Description |
|---|---|
| Batch Number | Supplier/manufacturer batch/lot number |
| Date of Manufacture (DOF) | Manufacturing date — used for FIFO ordering |
| Date of Expiry (DOE) | Expiry date — used for FEFO ordering and expiry alerts |
| Purchase Cost | Unit cost at time of receipt |
| Quantity Received | Units received in this batch |
| Supplier / GRN Reference | Links batch to the purchase document |
| Store | Pharmacy store where batch was received |
Multiple batches of the same drug can coexist in the same store. The Stock entity holds the current quantity per item per batch per store.
HMIS applies FEFO (First Expired First Out) as the primary selection rule at the point of dispensing:
- When a pharmacist adds a drug to a sale or issue, the system queries all available batches of that item in the dispensing store.
- Batches are ordered by expiry date ascending (soonest to expire first).
- The soonest-expiring batch with available stock is automatically selected.
- If that batch has insufficient quantity, the next batch fills the remainder.
- The pharmacist can see the batch details and can override the selection if clinically required (with the override recorded for audit).
This automatic selection eliminates manual batch picking errors and reduces expired stock write-offs.
The system generates expiry alerts for batches approaching their expiry date:
- Pre-expiry warning: configurable number of days before expiry (e.g., 90 days, 30 days).
- Alerts appear on the pharmacy dashboard and in the expiry report.
- Pharmacy staff can take action: return to supplier, transfer to a higher-consumption store, or plan for timely use before expiry.
The Bin Card report shows the complete movement history for a specific item and batch:
- Opening balance
- Each GRN, issue, transfer, return, and adjustment with date and quantity
- Closing balance
- Purchase cost per movement
Available at:
-
Item level: all batches combined (
bin_card.xhtml) -
Batch level: single batch movements (
bin_card_batch.xhtml) -
DTO-optimised: fast query version (
bin_card_dto.xhtml)
When stock must be discarded (expired, damaged, contaminated):
- Navigate to Disposal under Stock Management.
- Select the item and batch to discard.
- Enter the quantity to discard.
- Select a Discard Category from the configured list (e.g., Expired, Damaged, Quality Rejection).
- Enter a reason / authoriser reference.
- Submit for approval.
- On approval, stock is decremented and a disposal record is created in the stock history.
DiscardCategory is configurable by the pharmacy administrator.
If a batch record contains an error (wrong expiry date, wrong cost, wrong quantity from GRN), a Stock Adjustment is used:
| Adjustment Type | Purpose |
|---|---|
| Expiry Date Correction | Correct DOE recorded at GRN |
| Rate Adjustment (Retail) | Correct retail price on existing stock |
| Rate Adjustment (Wholesale) | Correct wholesale price |
| Quantity Adjustment | Correct physical quantity discrepancy |
All adjustments require supervisor approval before taking effect. The AdjustmentBillItem entity records the before/after values for full audit trail.
- Generate stock count sheet: system prints expected quantities per batch per item.
- Physical count: staff count physical units on shelves.
- Enter actual counts: quantities entered against each batch.
- Variance report: system shows differences (surplus / shortage) per batch.
- Adjustment bill generated: variances become an adjustment transaction.
- Approval: supervisor approves; stock is reconciled to physical count.
Before and after stock take reports (pharmacy_report_before_stock_taking.xhtml, pharmacy_report_after_stock_taking.xhtml) allow comparison for the same snapshot date.
StockHistory records a snapshot of stock levels at configurable intervals:
- Supports multilevel reporting: per department, per institution, total.
- Used for period-end stock valuation reports.
-
StockHistoryArchivestores older snapshots to keep the active history table performant.
| Item | Detail |
|---|---|
| Batch entity | com.divudi.core.entity.pharmacy.ItemBatch |
| Stock entity | com.divudi.core.entity.pharmacy.Stock |
| Stock history |
StockHistory, StockHistoryArchive
|
| Adjustment entity | AdjustmentBillItem |
| Discard category | DiscardCategory |
| FEFO query | Batch ordered by DOE ascending in dispense queries |
| Bin card pages |
bin_card.xhtml, bin_card_batch.xhtml, bin_card_dto.xhtml
|
| Stock take services |
StockTakeApprovalService, StockTakePersistService, StockCountGenerationService
|
| Related | Pharmacy Pack Transactions and Ward Stock, Pharmacy Dispensing Workflows |