# W1-POS — Blind shift close · handover to main treasury · shift-account receipt [FIN] (full-stack, POS + Clinic Z print)

Migration timestamp range: `2026_11_25_600001…600099`. Read `_COMMON.md` first. Look at `design/client-msg-2.png` (the client's «حساب الوردية» receipt, captioned «إيصال التحويل من الخزنة الفرعية الرئيسية»: shift no., user, open date/time, close date/time, opening balance, shift sales, sales returns, amount received, visa, amount after deducting sales, shortage/overage). [FIN] — Fable reviews your diff.

Client: «الفكرة هنا إنه مش عايز يعرف المستخدم معاه كام إلا بعد التحويل؛ لما يحوّل مثلاً 10000 والخزنة فيها 11000 فمش هيبان له الفرق إلا بعد التحويل فعلاً».

Today:
- POS shift: `Modules/POS/routes/api.php:26-30` (`sessions/active`, `POST sessions`, `PUT sessions/{id}/close`); `pos_sessions` (opening/closing/expected balance, times; migration `2026_02_28_600004…:11-30`); summary (sales, returns, by-method takings/refunds, expected cash, variance) at `POSSessionController.php:534-597`; BE returns `expected_cash` to the cashier in `active()`/`show()` (:331, :574); variance never posted (:289-292); `pos_sessions` has no cash box (`POSReceivingAccountResolver.php:48`). FE `features/pos/.../session-close-dialog.component.{ts,html}`: shows total sales + per-method took/paid-out before counting (html:100-138) and reveals expected + difference per row as soon as a number is typed (html:171-189). Thermal print `features/pos/services/pos-receipt.service.ts:479` called on close (`session-close-dialog.component.ts:392,423`), reprint `pos-reports.component.ts:172`.
- Clinic already does it right: `Clinic/app/Actions/CloseCashierSession.php:43-76,140-161` (`handover_petty_cash_id` / `handover_amount` → JE `ClinicCashierHandover`, `JournalEntryType.php:114-116`), `CashierSessionResource.php:12-29` hides `expected_cash` while open, FE `clinic/cashier/cashier-collect.component.ts:350,847,856-893,900-913` (no prefill, variance only in a toast after close), Z print `clinic/cashier/shift-report/shift-report.component.ts:165`. Generic cash transfer `POST accounting/transfers`.

Build (POS — mirror the Clinic design, reuse code where sensible):
1. Setting `pos.session.blind_close` (default **true**). When on: `active()`/`show()`/summary for an OPEN session hide expected cash, per-method expected and any total that lets the cashier derive it (sales totals by method) from users lacking new permission `pos.sessions.view_expected` (grant to POS supervisor/manager/admin + bridge migration). Close dialog: cashier enters counted cash per denomination/total and visa/card total slips (as the dialog does now) WITHOUT seeing expected or differences; after submit the result screen shows expected vs counted vs difference (عجز/زيادة) per method.
2. Handover («التحويل للخزنة الرئيسية»): close takes `handover_account_id` (main treasury / cash box — list the company's cash accounts/petty-cash boxes the same way the Clinic close does) + `handover_amount` (default = counted cash minus the float to keep, configurable `pos.session.keep_float` default 0). Posts a JE (new type `POSCashierHandover`) Dr main treasury / Cr the POS session's receiving cash account (via `POSReceivingAccountResolver`) for the handover amount — only when the company posts POS to GL the way POS sales post (follow the existing POS GL switch). Over/short: post the cash difference to a cash over/short account (new default account «عجز وزيادة الخزينة» in POS default accounts) Dr/Cr receiving cash account, behind setting `pos.session.post_variance` (default true when POS GL is on). Reversal if a closed session is reopened (if reopen exists).
3. Receipt «حساب الوردية» (80mm): shift no., cashier, open date/time, close date/time, opening balance, shift sales, sales returns, cash received (counted), visa/cards, amount after deducting sales (as the client's slip: received − sales), handover amount + target treasury, shortage/overage (shown only after close), signature lines; caption «إيصال تحويل من الخزنة الفرعية إلى الرئيسية» when a handover was made. Same for reprint.
4. Clinic Z print: make `shift-report.component.ts` print contain the same lines (sales/returns/visa/handover/variance) — check what's missing and align; keep Clinic BE as is unless a field is missing from its resource.
5. LIS cashier shift shows expected openly (`features/lis/cashier-shift…component.ts:53`) — apply the same blind rule there if it's a small change via the same permission concept (`lis.cashier.view_expected` or reuse); if large, note it and skip.

Acceptance + tests: blind on → cashier API responses for an open session contain no expected figures; supervisor sees them; close with handover posts balanced JE (handover + variance) and the receipt prints all lines; blind off → old behaviour. Pest per path.
