Project

General

Profile

Actions

Bug #692

open
MN MN

Batch Expiring First Not Always Picked for Billing or Dispensing

Bug #692: Batch Expiring First Not Always Picked for Billing or Dispensing

Added by Medha N. 13 days ago. Updated 4 days ago.

Status:
Feedback
Priority:
Normal
Assignee:
Target version:
-
Start date:
10/30/2026
Due date:
% Done:

0%

Estimated time:
Resolved By:

Description

When billing or dispensing a drug that has multiple batches in stock, the batch expiring first should be picked/billed against first (FEFO — First-Expiry-First-Out), so that older stock is used up before newer stock. This has been reported as not happening — the earliest-expiring batch is not getting used first.

Impact
If the earliest-expiring batch is genuinely not prioritised, near-expiry stock can sit unused while later-expiring stock gets sold or dispensed instead, so the near-expiry stock eventually expires on the shelf. This causes direct financial loss (write-offs), unnecessary wastage, and for Schedule drugs, potential compliance/traceability concerns around dispensing from the wrong batch.

Environment
Reported as happening in production. Also checked live in the test environment (Vetri Vivega Medical Center, vvmc.test.clinq.health), Pharmacy > Counter Sale, on 02 Nov 2026.

Steps to Reproduce
No specific steps are available for the production report yet (no drug name, batch numbers, or bill number given).

In the test environment, tried: 1. Find a drug with two or more non-quarantined, non-expired batches at different expiry dates in the same store (e.g., Amoxicillin 500mg: batch GLN4455 expiring 12 Sep 2028, and batch “wert” expiring 23 Oct 2036, both in Main Store). 2. Go to Pharmacy > Counter Sale > New Counter Sale and add that drug. 3. Check which batch the line item is billed against.

Expected
Expected: When billing or dispensing a drug with multiple batches in stock, the system should bill/dispense against the batch with the earliest expiry date among batches that are actually eligible (not expired, not on quarantine/hold).

AM Updated by Arya M. 11 days ago Actions #1

  • Assignee set to SK -

RH Updated by Roshni Harish. 10 days ago · Edited Actions #2

  • Subject changed from Batches: earliest expiry should go out first to Batch Expiring First Not Always Picked for Billing or Dispensing
  • Description updated (diff)

This symptom has been reported in production, but no specifics are available yet (no drug, batch, or bill number given), and as i cannot access the production to verify it directly. Since this exact stock-not-decrementing bug reproduces the same symptom in the test environment, it’s the likely explanation — but treat it as unconfirmed for production until either this fix is verified live, or someone gets specifics (drug, batch numbers/expiry dates, bill number) from whoever reported it.

S- Updated by SK - 4 days ago Actions #3

  • Status changed from New to Feedback
  • Assignee changed from SK - to Medha N.

Checked the current FEFO batch-selection code against origin/dev (fetched fresh) across every path that picks a batch: StockAllocator.cs:76 (FefoStockAllocator, used for Generate Bill pricing), CounterSaleService.cs:376 (Counter Sale Complete draw), DispenseService.cs:347 (prescription dispense draw) and :476 (substitute-batch fallback), DrugStockService.cs/.Paged.cs (stock-preview/batch drawer feed), and the portal's own allocate-fefo.ts (kept in parity with the C# allocator via AllocationParityTests.cs). All of them sort OrderBy(ExpiryDate).ThenBy(Id) - correct FEFO, no nulls possible (Stock.ExpiryDate is non-nullable). No existing commit is tagged #692, so if this was ever broken it isn't broken in the current code - it looks like it was fixed as a side effect of the Counter Sale batch/pricing work already done for Bug #99 / #689 / #674 / #714, not by a dedicated change.

One by-design behavior that could look like this from the UI: both Counter Sale and Dispense let a pharmacist's explicitly-selected batch lead the draw ahead of strict expiry order ("the pharmacist already has that pack in hand") - this is intentional and tested, not a bug. But your repro steps (add the drug to a New Counter Sale, no manual batch override mentioned) shouldn't hit that path, so this doesn't fully explain what you saw.

Most likely explanation: vvmc.test.clinq.health on 02 Nov 2026 was running a build that predated one of the fixes above. Could you re-test the exact repro (Amoxicillin 500mg, batch GLN4455 vs "wert") on the current test deploy and confirm which batch gets billed? If it still picks the wrong one, please also capture the bill number/line so we can check the actual DB row rather than code alone. For the production report, drug name + batch numbers + bill number would help pin down whether it's the same root cause or something else entirely.

Actions

Also available in: PDF Atom