Skip to content
PharmaFlow Knowledgebase
Esc
↑↓navigate↵open⌘Jpreview
On this page

Sessions and Parked Sales

Open cash sessions, take breaks, declare tender, close with a Z-report, and park carts.

You track each cashier shift with apps/server/src/features/sessions/route.ts, validated by apps/server/src/features/sessions/schemas.ts, and you park interrupted carts with apps/server/src/features/parked/route.ts.

Log in first

Sessions and parked carts belong to you and your branch, so log in and keep the token for every call.

TOKEN=$(curl -s -X POST http://localhost:8000/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"admin@demo.pharmaflow","password":"Demo@1234"}' | python3 -c "import sys,json; print(json.load(sys.stdin)['token'])")

Open and check your session

You open with POST /sessions/open and an opening_float, and if you already have one open the server returns it instead of creating a duplicate. New sales automatically attach to your open session id.

curl -X POST http://localhost:8000/api/v1/sessions/open \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"opening_float": 200}'
curl http://localhost:8000/api/v1/sessions/current -H "Authorization: Bearer $TOKEN"

You review past shifts with GET /sessions/history, which returns your closed sessions newest first with revenue, VAT, and break minutes.

Take a break

You pause with POST /sessions/break/start and resume with POST /sessions/break/end. Ending the break adds the elapsed whole minutes to break_minutes, and closing while on break finalizes the open break first.

curl -X POST http://localhost:8000/api/v1/sessions/break/start \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"reason":"Lunch"}'
curl -X POST http://localhost:8000/api/v1/sessions/break/end \
  -H "Authorization: Bearer $TOKEN"

Declare tender and read the verdict

You count the drawer and post POST /sessions/tender with declared_cash. The server computes expected cash as opening float plus cash sales minus cash refunds, then returns OVERAGE, SHORTAGE, or BALANCED with the difference.

curl -X POST http://localhost:8000/api/v1/sessions/tender \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"declared_cash": 1250.5, "notes":"End of morning count"}'

You list the last ten declarations with GET /sessions/tender/history before you close.

Close and print the Z-report

You close with POST /sessions/close, which aggregates sale count, revenue, VAT, and a per-method payment breakdown onto the session row. Then you fetch the printable report and the itemized sales list.

curl -X POST http://localhost:8000/api/v1/sessions/close -H "Authorization: Bearer $TOKEN"
curl http://localhost:8000/api/v1/sessions/SESSION_ID/z-report -H "Authorization: Bearer $TOKEN"
curl http://localhost:8000/api/v1/sessions/SESSION_ID/sales -H "Authorization: Bearer $TOKEN"

Park, recall, or void a cart

You park an interrupted cart with POST /parked, list your own PARKED carts, then recall one back to the register or void it when the customer walks away. Recall and void only work on your own parked rows.

curl -X POST http://localhost:8000/api/v1/parked \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"cart":[{"medicine_id":"MED-001","quantity":1,"unit_price":12.5}]}'
curl http://localhost:8000/api/v1/parked -H "Authorization: Bearer $TOKEN"
curl -X POST http://localhost:8000/api/v1/parked/PARKED_ID/recall -H "Authorization: Bearer $TOKEN"
curl -X POST http://localhost:8000/api/v1/parked/PARKED_ID/void -H "Authorization: Bearer $TOKEN"

Next steps

Ring the recalled cart in /sales/selling-at-the-counter, validate a parting coupon in /sales/coupons-and-discounts, and process any same-day comeback in /sales/returns-and-credit-notes.

Last updated on October 20, 2026