Lewati ke konten

Kasir dan keranjang (Retail)

Tab Kasir (apps/retail/src/app/(tabs)/index.tsx).

flowchart TD
  A["Buka tab Kasir"] --> B["Muat produk toko<br/>cache lalu segarkan"]
  B --> C{"Cari produk"}
  C -- "ketik nama atau barcode" --> D["Filter lokal"]
  D --> E["Ketuk produk"]
  E --> F["Tambah ke keranjang<br/>qty +1"]
  F --> G{"Pilih pelanggan?"}
  G -- "opsional" --> H["CustomerPicker"]
  G -- "lewati" --> I["Tekan Bayar"]
  H --> I
  I --> J["PayModal"]
  • Daftar produk dari GET /v1/store-products, di-cache di AsyncStorage (smash.retail.products.v2) sehingga tab tetap terbuka saat offline.
  • Layar menyegarkan daftar setiap kali mendapat fokus (useFocusEffect), mis. setelah produk ditambah dari tab Scan.
  • Keranjang adalah store global (src/lib/cart.ts, useSyncExternalStore) sehingga tab Scan dan Kasir berbagi keranjang. Isi keranjang bertahan setelah aplikasi ditutup.
  • Pencarian cocok pada nama, kategori, barcodeRaw, dan gtin14.
File Peran
src/lib/cart.ts store keranjang, cartActions.add/setQty/clear, checkout()
src/lib/products.ts hook useProducts (cache + refresh)
src/components/customer-picker.tsx pilih atau tambah pelanggan

checkout(confirm, { settings, cashier }) membuat payload (operationId, clientUuid, items, totalMinor, discountMinor, payments, customerId), menyusun struk, memasukkannya ke outbox, lalu mengosongkan keranjang. Hasilnya { outcome, receipt } dengan outcome.kind = synced, queued, atau failed.