guide

Cross-Branch Pharmacy Transfers: A Workflow Walkthrough

How to move stock between hospital sites without losing lot accuracy, expiry data, or auditable paper trail — a nine-state workflow you can borrow.

By CareHubOS team

Most multi-site hospital pharmacies move stock between branches at some point. One site over-ordered. Another site has an unexpected surge. A clinical lead at Branch A is leaving and the supply they specifically requested is no longer needed.

What looks like a simple operational problem — pick stock here, ship it there — turns into a mess if you don't model it carefully. This walkthrough covers the nine-state workflow CareHubOS uses, and why each state exists.

What can go wrong without a workflow

Three classic failure modes:

  1. Phantom stock. Branch A's records say they have 200 units; Branch B's records say they have 50; in reality, half of A's 200 was already loaded onto a truck heading to B. Both branches are wrong.

  2. Lot identity loss. Stock leaves Branch A with a recorded expiry of 2026-09-15. It arrives at Branch B and gets logged as a fresh batch — losing the expiry, losing the manufacturer's lot number, losing the chain of custody.

  3. Unaccountable shrinkage. Someone walks stock out the door of Branch A. The supervisor "remembers" approving it. Three months later it doesn't reconcile and there's no paper trail.

A workflow that has to be enforced by the system, not by goodwill, fixes all three.

The nine states

A stock transfer in CareHubOS goes through up to nine states. Each transition records who did it, when, and why. Cancellations and rejections are first-class — you can't accidentally lose a request by leaving it in limbo.

1. REQUESTED

Branch B's pharmacy lead asks for stock from Branch A. The request lists the medications and quantities they need. At this point, no stock has moved and no inventory has changed.

The request lives in Branch A's "incoming transfer requests" queue, so the lead at Branch A sees it next time they open the screen.

2. APPROVED

Branch A's lead reviews the request. They can approve as-is or modify quantities (we don't have 200 of that one, you can have 150). On approval, the system reserves the stock at Branch A — it stays on the shelf but is no longer available for normal dispensing. The reservation is recorded as a StockReservation row.

This is the state that fixes the phantom-stock problem. The moment a transfer is approved, the source branch's available quantity drops. Their dispensing queue can't accidentally dispense it.

3. RESERVED

A confirmation state. The lead at Branch A has approved; the system has reserved. Both branches can now see the same source of truth. This state exists for a sometimes-surprising reason: it lets a separate role (a logistics coordinator, say) take over from the approver without losing the audit trail of who did each step.

4. PACKED

A staff member physically picks the stock from the shelf and packs it for transit. The system records which lot and which expiry was packed, so when the receiving branch unpacks they can reconcile. The source branch's OnHand quantity drops; the reservation is consumed; the stock is now in transit.

5. SHIPPED

The packed transfer leaves the source branch. Optional carrier / waybill information is recorded.

6. IN_TRANSIT

A long-running state for transfers between distant sites. Useful as a holding bucket — the operational view at both branches says "this is on its way, do not double-order."

7. RECEIVED

The packed transfer arrives at the destination branch. A receiving clerk opens the package and confirms each item against the manifest.

This is where lot cloning happens. Each lot that arrives at Branch B is recorded as a new lot row at Branch B, copying the expiry date and manufacturer lot number from the source. The original lot at Branch A is closed.

We deliberately don't share a lot row between branches. The receiving branch needs its own lot identity so it can be the subject of its own audit log, its own FEFO calculation, its own future transfer. The shared piece is the metadata (expiry, manufacturer batch), not the row.

8. CONFIRMED

A second pair of eyes confirms the receipt. In high-value or controlled-substance transfers, the receiving clerk and a witness both sign off. This state is optional for low-value transfers but mandatory for narcotics.

9. CLOSED

Final state. The transfer is closed in the audit trail. No further changes possible. Reports against the transfer use this row as the canonical record.

Where it can branch off

Two alternative paths:

  • REJECTED — at the APPROVED step. The source branch declines the request (we can't spare the stock right now). No reservation is created; the request closes with the reason recorded.
  • CANCELLED — at any state before SHIPPED. Either branch can cancel; reservations are released; the audit trail shows who cancelled when and why.

After SHIPPED, you can't cancel — the stock is physically gone. You can only RECEIVE and then return as a separate transfer.

Why nine states feels like a lot

It does feel like a lot. The simpler version — REQUEST, APPROVE, SHIP, RECEIVE — works fine for paper. The reason for the extra states is that each transition is an event with its own audit log. A four-state workflow means four events; a nine-state workflow means nine. When something goes wrong six weeks later and someone asks "when did this go off the rails," more events means a sharper diagnosis.

You also don't have to use every state. For a same-day intra-city transfer, RESERVED → PACKED → SHIPPED → RECEIVED → CONFIRMED can happen within minutes. For an inter-regional transfer with a long truck ride, IN_TRANSIT is a useful holding state that prevents over-ordering.

Things this workflow doesn't (yet) solve

  • External transfers. Moving stock to a facility that isn't part of your group is a different workflow — different consent, different billing, different paperwork. Don't shoehorn it into the same flow.
  • Returns to supplier. A defective lot going back to the manufacturer isn't a transfer; it's a return. Separate entity, separate workflow.
  • Cross-currency / cross-jurisdiction transfers. If your group operates across currency or regulatory boundaries, the financial reconciliation needs to be more careful than a simple stock move.

The takeaway

Cross-branch stock transfer is one of those operations where the engineering effort is far better invested in the workflow than in fancy logistics integration. Get the states right, get the audit trail right, get the lot cloning right — and the operational result is a pharmacy team that trusts the system because the system doesn't lose stock.

If you're evaluating hospital pharmacy software for a multi-branch group: ask to see a cross-branch transfer in real time. If the answer involves "you can mark stock as out at one branch and in at another," that's a four-state hack. If the answer involves an explicit workflow with auditable transitions, you're looking at something that will actually hold up.

Want to see this in your branches?

A 30-minute walkthrough tailored to your group's size and module mix.

Book a demo