Shift Management
Shift Management tracks a cashier's till from the moment they declare an opening float to the moment they count and close the drawer, so every rupee that goes in or out during a shift is accounted for.
Overview
A "shift" begins when a cashier opens the till with a declared opening cash float and ends when they close it and count the actual cash in the drawer. In between, the system silently tracks every sale, payment method and any cash removed from the drawer.
This page always shows the state of the currently selected store + terminal combination. If no shift is open on that terminal, you see an "Open Shift" prompt; once one is open, you see live totals, quick actions and a payment-method breakdown.
Because this is a till-based workflow, it is scoped per terminal — a shop with three checkout counters runs three independent shifts side by side, each with its own float, sales and expected cash.
Before You Start
- A Store and Terminal must be selected (from the header dropdowns) before this page can load or open a shift.
- Requires the
billingfeature at theAdvancedplan tier or above — on lower tiers this menu item does not appear in the sidebar at all. - Only one shift can be open per terminal at a time; you must close the current shift before a new one can be opened on the same terminal.
Step-by-Step Guide
1 Open a shift at the start of the day
Every cashier should open a shift before ringing up the first sale so cash reconciliation is accurate at closing time.
- If no shift is active, click Open Shift on the empty-state card.
- Enter the Opening Float — the cash you are starting the drawer with (e.g. change for the day).
- Optionally add a note (e.g. "Counted by Rajesh, 2x ₹500 short due to no change available").
- Click Open. The page switches to the live shift view with four stat cards: Shift Duration, Total Sales, Transactions, and Expected Cash.
2 Record a cash drop mid-shift
Use a cash drop whenever cash is removed from the drawer before closing — for a bank deposit, a safe deposit, or paying out an expense — so the "Expected Cash" figure stays accurate.
- Click Record Cash Drop under Actions.
- Enter the Amount removed from the drawer.
- Choose a Reason: Safe Deposit, Bank Deposit, Payout, or Other.
- Add optional notes, then submit. The drop is immediately reflected in the shift's expected cash calculation.
3 Generate an X report mid-shift
- Click Generate X Report at any time during an open shift.
- An X report is a read-only snapshot of sales so far — it does not close or reset the shift, so you can pull one any number of times during the day (e.g. for a manager spot-check).
4 Close the shift and generate a Z report
Closing a shift is a one-way action — once closed, a new shift must be opened for further sales on that terminal.
- Click Close Shift.
- Physically count the cash in the drawer and enter it as Actual Cash Count.
- The dialog shows an Over (green) or Short (red) amount — the difference between what you counted and the system's Expected Cash.
- If there is a variance, use Close Notes to explain it (e.g. "₹40 short — customer given wrong change").
- Click Close & Generate Z Report. The Z report is the final, permanent summary of the shift and cannot be edited afterward.
Every Field & Button, Explained
| Field / Button | What it does |
|---|---|
Opening Float | Cash amount the drawer starts with when the shift opens; required before a shift can be opened. |
Shift Duration | Live-updating hours and minutes since the shift was opened. |
Total Sales | Sum of all sales rung up on this terminal during the current open shift. |
Transactions | Count of completed sales during the current shift. |
Expected Cash | Opening float + cash sales − any recorded cash drops; this is what the drawer should physically contain at any moment. |
Record Cash Drop | Opens a dialog to log cash removed from the drawer mid-shift, with Amount, Reason (Safe Deposit / Bank Deposit / Payout / Other) and Notes. |
Generate X Report | Produces a non-destructive, repeatable snapshot report of the shift's sales so far — does not close the shift. |
Close Shift | Opens the closing dialog where you enter the counted cash and permanently end the shift with a Z report. |
Actual Cash Count | The cash you physically counted in the drawer at close time — compared against Expected Cash to compute over/short. |
Over / Short indicator | Live-calculated difference (Actual − Expected) shown in green (over) or red (short) as soon as you type an actual cash amount. |
Close Notes | Free-text explanation for any cash variance found at closing — useful for later audits. |
Payment Breakdown | Four cards showing Cash, Card, UPI and Other sales totals collected during the current shift. |
Refresh | Re-fetches the active shift's live totals without closing or reopening it. |
Tips & Best Practices
- Have every cashier open their own shift at the start of their till time — this keeps the over/short reconciliation attributable to a specific person rather than the whole day.
- Pull an X report before a shift-change handover so the outgoing cashier and incoming cashier can agree on the numbers before the drawer changes hands.
- Always write a Close Note when there is a variance, even a small one — a pattern of small shortages over weeks is much easier to spot with notes attached.
Troubleshooting & FAQ
I can't open a new shift on this terminal.
The "Expected Cash" figure looks wrong.
Can I edit or reopen a shift after closing it?
Why don't I see this page in the sidebar?
🧑💻 Developer Notes
Source component(s):
frontend-app/packages/pos-react-lib/src/pages/ShiftManagementPage.jsx
Backend endpoints used:
GET /shifts/active?terminalId=&storeId=POST /shifts/openPOST /shifts/:id/cash-dropPOST /shifts/:id/closeGET /shifts/:id/x-report
Related tables (db-core repositories):
Shift (best-effort — shift open/close, opening float, expected/actual cash)ShiftCashDrop (best-effort)
Redux slices:
auth (selectedStoreId, selectedTerminalId, user)
Feature flag key: billing (requires advanced plan tier or above)
A 404 from GET /shifts/active is treated as "no active shift" rather than an error. Cash-drop and close amounts are parsed with parseFloat client-side before being posted; server-side validation of the shift totals happens in the shifts controller.