Commit Graph

12 Commits

Author SHA1 Message Date
soroush.asadi 5596e8dbc5 chore(pos): fully remove the classic POS
CI/CD / CI · API (dotnet build + test) (push) Successful in 49s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 30s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m11s
CI/CD / CI · Admin Web (tsc) (push) Successful in 41s
CI/CD / CI · Website (tsc) (push) Successful in 47s
CI/CD / CI · Koja (tsc) (push) Successful in 50s
CI/CD / Deploy · all services (push) Successful in 2m52s
POS v2 has been the default at /pos for a while; this deletes the old classic
POS entirely:
- removed the /pos-classic route and all classic-only components
  (pos-screen, pos-pay-panel, pos-table-board, pos-queue-bar, pos-receipt-modal,
  pos-slip-modal, pos-receipt-print.css)
- relocated the two modules POS v2 still shared into the pos2 tree
  (lib/pos/submit-order → lib/pos2, components/pos/pos-customer-picker → pos2),
  so the components/pos and lib/pos folders are gone
- dropped the now-dead "نسخه کلاسیک" (classic version) button + RotateCcw import
  from the POS v2 header, and updated stale comments

POS v2 (/pos) is unchanged and fully self-contained. Typecheck clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 19:42:32 +03:30
soroush.asadi 46f962eb75 fix(pos): keep the receipt printable after paying an order
CI/CD / CI · API (dotnet build + test) (push) Successful in 56s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 31s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m10s
CI/CD / CI · Admin Web (tsc) (push) Successful in 39s
CI/CD / CI · Website (tsc) (push) Successful in 47s
CI/CD / CI · Koja (tsc) (push) Successful in 1m1s
CI/CD / Deploy · all services (push) Successful in 3m0s
Bug: confirming payment ran backToBoard() → clearSession(), wiping the cart's
activeOrderId, so the order vanished from the POS and the "print receipt" button
(which keys off activeOrderId) went dead — the only escape was a 4s toast.

Fix: capture the just-paid order id in local state (survives the session clear)
and show a persistent payment-success sheet with a "چاپ فاکتور" button so the
cashier can print/reprint the customer receipt, then "سفارش جدید" to continue.
Shared printReceiptById() backs both the in-order button and the success sheet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 19:14:01 +03:30
soroush.asadi 6184c83fa7 feat(pos): print customer receipt from the POS page
CI/CD / CI · API (dotnet build + test) (push) Successful in 44s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 32s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m12s
CI/CD / CI · Admin Web (tsc) (push) Successful in 39s
CI/CD / CI · Website (tsc) (push) Successful in 48s
CI/CD / CI · Koja (tsc) (push) Successful in 51s
CI/CD / Deploy · all services (push) Successful in 3m0s
POS v2 auto-printed the receipt on full payment but had no manual button. Adds a
"چاپ فاکتور" (print receipt) action in the order panel that prints/reprints the
active saved order's customer receipt, plus a "print receipt" action on the
payment-success toast. Replaces the dead disabled "hold" placeholder button.
Backend print endpoint unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 14:18:20 +03:30
soroush.asadi 0c2ded4070 feat(pos): set a per-item note on each cart line in POS v2
CI/CD / CI · API (dotnet build + test) (push) Successful in 43s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 32s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m13s
CI/CD / CI · Admin Web (tsc) (push) Successful in 40s
CI/CD / CI · Website (tsc) (push) Successful in 48s
CI/CD / CI · Koja (tsc) (push) Successful in 52s
CI/CD / Deploy · all services (push) Successful in 3m9s
The cart store, order payload (create + add-items + offline), KDS ticket and
receipt already supported per-item notes — but POS v2 had no way to enter one.
Adds a note button on each cart line that toggles an inline input (e.g. "no
sugar"); the note shows highlighted when set and rides along to the kitchen/bar
ticket. No backend change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 14:05:00 +03:30
soroush.asadi 2cff5051ac feat(rbac): gate pages and action buttons in the UI by permission
CI/CD / CI · API (dotnet build + test) (push) Successful in 39s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 28s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m8s
CI/CD / CI · Admin Web (tsc) (push) Successful in 37s
CI/CD / CI · Website (tsc) (push) Successful in 46s
CI/CD / CI · Koja (tsc) (push) Successful in 49s
CI/CD / Deploy · all services (push) Successful in 2m45s
Nav already hides pages a role can't view (NAV_REQUIRED_PERMISSION). This wraps
the sensitive/CRUD action controls in <Can permission> so users only see what
they can do (server still enforces):

- POS/orders: void → VoidOrder, cancel → VoidOrder, transfer → EditOrder,
  pay/split → HandlePayments
- menu/inventory/coupons/customers/reservations/expenses/taxes/branches:
  add/edit/delete buttons → the matching Create/Edit/Delete permission
- reports CSV export → ExportReports; SMS send → SendSms, settings → ManageSmsSettings
- home dashboard: revenue/orders KPI queries gated on ViewReports so non-report
  roles don't 403 on the landing page

(Refund/discount/comp/cash-drawer have no UI control yet — no buttons to gate.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 05:58:56 +03:30
soroush.asadi 82145b0d21 feat(pos2): add dashboard exit button to POS board header
CI/CD / CI · API (dotnet build + test) (push) Failing after 3m19s
CI/CD / CI · Admin API (dotnet build) (push) Failing after 3m19s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m5s
CI/CD / CI · Admin Web (tsc) (push) Successful in 37s
CI/CD / CI · Website (tsc) (push) Successful in 44s
CI/CD / CI · Koja (tsc) (push) Successful in 48s
CI/CD / Deploy · all services (push) Has been cancelled
POS runs in the (fullscreen) layout which strips the sidebar.
Adds a Home → داشبورد button at the top-left of the table board so
users can navigate back to the dashboard without being stuck.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 07:23:14 +03:30
soroush.asadi 59486cdf24 fix(pos2): wait for branch before fetching menu + add left category sidebar
CI/CD / CI · API (dotnet build + test) (push) Failing after 3m20s
CI/CD / CI · Admin API (dotnet build) (push) Failing after 3m19s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m5s
CI/CD / CI · Admin Web (tsc) (push) Successful in 41s
CI/CD / CI · Website (tsc) (push) Successful in 44s
CI/CD / CI · Koja (tsc) (push) Successful in 52s
CI/CD / Deploy · all services (push) Has been cancelled
Race fix: orderBranchId now returns `undefined` (not null) while the /branches
query is in flight. usePos2Menu treats undefined as "not yet determined" and
skips the fetch, preventing getBranchMenu(cafeId, null) → empty array.
Once branchesFetched=true, orderBranchId resolves to the correct branchId
(or null for café-wide fallback).

Layout: desktop order screen now shows a left vertical category sidebar
(116 px, md+) instead of horizontal chips, giving the classic POS sidebar
feel. Horizontal chips kept for mobile (<md). Menu grid columns adjusted.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 07:10:03 +03:30
soroush.asadi f02f78a97c fix(pos): POS v2 menu empty — resolve a valid branch like classic POS
CI/CD / CI · API (dotnet build + test) (push) Successful in 42s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 31s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m6s
CI/CD / CI · Admin Web (tsc) (push) Successful in 38s
CI/CD / CI · Website (tsc) (push) Successful in 45s
CI/CD / CI · Koja (tsc) (push) Successful in 49s
CI/CD / Deploy · all services (push) Successful in 2m37s
The menu/tables are branch-scoped. v2 used the raw stored branchId, which is
null or stale for users who never opened the classic POS (it has no branch
picker), so getBranchMenu returned an empty menu. Now v2 fetches /branches,
auto-selects the first valid branch (self-healing the stored id), and loads the
branch menu + tables + order submission against that resolved branch — matching
the classic POS exactly. Also adds a visible "menu failed to load / retry"
state instead of a silent empty grid.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 06:17:37 +03:30
soroush.asadi 7c35984096 feat(pos): default the pay sheet to Card
CI/CD / CI · API (dotnet build + test) (push) Successful in 40s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 31s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m6s
CI/CD / CI · Admin Web (tsc) (push) Successful in 37s
CI/CD / CI · Website (tsc) (push) Successful in 44s
CI/CD / CI · Koja (tsc) (push) Successful in 48s
CI/CD / Deploy · all services (push) Successful in 2m42s
Card is now the pre-selected payment method (and split rows default to Card),
matching Iran's card-dominant payments. Card already sits first in the selector.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 05:38:13 +03:30
soroush.asadi bf0ca68fa6 feat(pos): show Card first in pay sheet, keep Cash as default
CI/CD / CI · API (dotnet build + test) (push) Successful in 43s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 31s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m6s
CI/CD / CI · Admin Web (tsc) (push) Has been cancelled
CI/CD / CI · Website (tsc) (push) Has been cancelled
CI/CD / CI · Koja (tsc) (push) Has been cancelled
CI/CD / Deploy · all services (push) Has been cancelled
Reorder the payment method tabs to کارت / نقدی / تقسیم (Card first, most common
in Iran) while keeping Cash as the pre-selected default method.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 05:32:26 +03:30
soroush.asadi 6778c32028 feat(pos): POS v2 feature parity + promote to default /pos
CI/CD / CI · API (dotnet build + test) (push) Successful in 45s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 32s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m7s
CI/CD / CI · Admin Web (tsc) (push) Successful in 38s
CI/CD / CI · Website (tsc) (push) Successful in 45s
CI/CD / CI · Koja (tsc) (push) Successful in 49s
CI/CD / Deploy · all services (push) Successful in 2m46s
Completes the four POS v2 roadmap items:

1. Real split payments — split tab records N separate payment rows (equal split,
   last row takes the remainder), each row toggles Cash/Card; posts payments[].
2. Card-terminal push — confirmPay sums Card amounts and calls requestPosPayment
   (POS device) before recording; surfaces POS_DEVICE_* errors.
3. Customer + coupons + loyalty — reuses PosCustomerPicker (attach/search/create)
   and validates coupons via /coupons/validate (discount in totals). Pay sheet
   offers loyalty redemption (1 point = 100 toman) when a customer is attached.
4. Promote to default — /pos now renders POS v2 (full-screen, café-themed); the
   classic terminal moves to /pos-classic with its sidebar+topbar chrome. The
   "نسخه کلاسیک" link points there.

Order submission already carried customerId/guestName/guestPhone/couponId via the
shared cart store, so customer + coupon flow straight through send + pay.
tsc --noEmit clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 05:16:52 +03:30
soroush.asadi 75a0a1c834 feat(pos): wire POS v2 to live data (board, orders, payments)
CI/CD / CI · API (dotnet build + test) (push) Successful in 43s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 32s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m5s
CI/CD / CI · Admin Web (tsc) (push) Successful in 37s
CI/CD / CI · Website (tsc) (push) Successful in 45s
CI/CD / CI · Koja (tsc) (push) Successful in 49s
CI/CD / Deploy · all services (push) Successful in 2m42s
POS v2 is now a real, working point of sale at /[locale]/pos2 (was a static
mock). It reuses the existing data layer so it shares the React Query cache and
offline pipeline with the classic POS:

- Table board ← fetchCafeTableBoard (Free/Busy/Reserved/Cleaning, live totals,
  guest-QR badge); polls every 15s. Open a free table to start an order; open a
  busy table to hydrate its existing order (GET order → cart hydrateFromOrder).
- Order screen ← real branch/café menu + categories, bound to useCartStore
  (add/qty/remove). Send via submitOrderToApi (online + offline outbox) then
  re-hydrate; "ارسال (n)" shows the pending (unsynced) line count.
- Pay sheet ← POST /orders/{id}/payments. Cash (numpad + change), Card, and a
  Split helper (records the full amount; split is cashier guidance for now).
- Online/offline badge, loading/empty states, toasts, busy overlay, and a
  "نسخه کلاسیک" link back to /pos.

The static design mock stays at /[locale]/pos2-preview (dev-only, 404 in prod).
tsc --noEmit clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 00:16:37 +03:30