Alur Teknis Kasir

Daftar Isi

  1. Konfigurasi Fitur
  2. Status Flow Order
  3. Skenario A — Table Tracking Tidak Aktif
  4. Skenario B — Table Tracking Aktif
  5. Skenario C — Pesan Mandiri (Self-Order QR)
  6. Skenario D — Meja Bebas (Free Table)
  7. Skenario Khusus — Order Takeaway
  8. Halaman & Route POS
  9. Ringkasan Matriks Keputusan

Legenda Warna Diagram:

  • 🟡 Kuning — Order berstatus pending
  • 🔵 Biru — Order berstatus confirmed (di dapur)
  • 🟢 Hijau — Order berstatus ready atau completed
  • 🔴 Merah — Order dibatalkan (cancelled)

1. Konfigurasi Fitur

Pesan POS memiliki pengaturan di level tenant yang menentukan keseluruhan alur kasir:

Pengaturan Model Field Default Fungsi
Table Tracking enable_table_tracking true Order dikelola per meja; kasir wajib memilih meja sebelum bertransaksi
Kitchen Tracking enable_kitchen_tracking true Order dikirim ke dapur terlebih dahulu sebelum bisa dibayar
Pesan Mandiri enable_self_order false Customer scan QR di meja dan memesan langsung dari HP
Maks. Pesanan per Sesi QR self_order_max_orders 20 Batas jumlah pesanan yang diterima per sesi QR sebelum kadaluarsa
Masa Berlaku Sesi QR self_order_session_hours 12 Berapa jam QR link valid sejak dibuat (1–72 jam)

Catatan:

  • Semua pengaturan dapat diubah dari halaman Settings → POS.
  • Pesan Mandiri hanya dapat diaktifkan jika Table Tracking juga aktif.
  • Menonaktifkan Pesan Mandiri di tengah jalan tidak membatalkan sesi QR yang sedang berjalan — sesi lama tetap ada di database, tetapi pelanggan tidak bisa mengaksesnya (middleware menolak request).

2. Status Flow Order

stateDiagram-v2
    [*] --> pending: Order dibuat (tanpa kitchen tracking untuk dine_in tanpa table tracking)
    [*] --> confirmed: Order dibuat (kitchen tracking aktif atau table tracking aktif)
    [*] --> ready: Order dibuat (kitchen tracking tidak aktif)

    pending --> confirmed: Pembayaran lunas (order dikirim ke dapur)
    confirmed --> preparing: Dapur mulai memasak
    preparing --> ready: Makanan siap
    ready --> completed: Pembayaran selesai
    pending --> cancelled: Void order
    confirmed --> cancelled: Void order
    preparing --> cancelled: Void order
    ready --> cancelled: Void order

Status Payment (terpisah dari status order):

Status Keterangan
unpaid Belum ada pembayaran
paid Sudah lunas

Skenario A — Table Tracking Tidak Aktif

Ketika Table Tracking dinonaktifkan, kasir langsung masuk ke halaman transaksi tanpa melewati pemilihan meja. Order type default adalah takeaway.

A1. Kitchen Tracking Tidak Aktif

Konfigurasi:

  • enable_table_tracking = false
  • enable_kitchen_tracking = false

Status awal order yang dibuat: ready

flowchart TD
    A([Kasir Login]) --> B["/pos - Redirect otomatis ke halaman transaksi"]
    B --> C[POS Transaction /pos/transaction]
    C --> D{Order Type}
    D -->|Dine-In / Takeaway| E[Pilih & tambah produk ke keranjang]
    E --> F[Opsional: Aplikasi diskon, pilih customer]
    F --> G[Klik 'Complete Order']
    G --> H[(Database: Order dibuat status=ready payment=unpaid)]
    H --> I[Redirect ke Payment /pos/order/orderId/payment]
    I --> J[Pilih metode pembayaran, input nominal]
    J --> K[Finalize Payment]
    K --> L[(Database: Payment disimpan, Order=completed, Payment=paid)]
    L --> M[Struk /pos/receipt/orderId]
    M --> N[Kembali ke POS Transaction]

    style H fill:#f9a825,color:#000
    style L fill:#388e3c,color:#fff

Catatan penting:

  • Tidak ada proses dapur — order langsung ready begitu dibuat
  • Pembayaran dapat dilakukan segera setelah order dibuat
  • Tidak ada pemilihan meja

A2. Kitchen Tracking Aktif

Konfigurasi:

  • enable_table_tracking = false
  • enable_kitchen_tracking = true

Status awal order yang dibuat:

  • dine_inpending (harus bayar dulu, baru dikirim ke dapur)
  • takeawayconfirmed (langsung dikirim ke dapur)
flowchart TD
    A([Kasir Login]) --> B["/pos - Redirect otomatis ke halaman transaksi"]
    B --> C[POS Transaction /pos/transaction]
    C --> D{Order Type}

    D -->|Dine-In| E1[Pilih & tambah produk]
    E1 --> F1[Klik 'Complete Order']
    F1 --> G1[(Order dibuat status=pending payment=unpaid)]
    G1 --> H1[Redirect ke Payment /pos/order/orderId/payment]
    H1 --> I1[Pilih metode & finalize]
    I1 --> J1[(Payment selesai, Order status=confirmed, dikirim ke Dapur)]
    J1 --> K1[Kitchen Board memproses]
    K1 --> L1[Status: preparing ke ready]
    L1 --> M[Struk / Receipt]

    D -->|Takeaway| E2[Pilih & tambah produk]
    E2 --> F2[Klik 'Complete Order']
    F2 --> G2[(Order dibuat status=confirmed, dikirim ke Dapur)]
    G2 --> H2[Kembali ke POS /pos - Kitchen akan memproses]
    H2 --> I2[Kitchen Board: confirmed ke preparing ke ready]
    I2 --> M

    M --> N[Kembali ke POS Transaction]

    style G1 fill:#f9a825,color:#000
    style J1 fill:#1565c0,color:#fff
    style G2 fill:#1565c0,color:#fff
    style L1 fill:#388e3c,color:#fff

Catatan penting:

  • Untuk dine_in: Kasir harus proses pembayaran terlebih dahulu agar order bisa dikirim ke dapur
  • Untuk takeaway: Order langsung dikirim ke dapur setelah dibuat
  • Setelah order ready, struk dapat dicetak

Skenario B — Table Tracking Aktif

Ketika Table Tracking diaktifkan, kasir masuk ke halaman overview meja. Kasir wajib memilih meja sebelum membuat order dine_in.

B1. Kitchen Tracking Tidak Aktif

Konfigurasi:

  • enable_table_tracking = true
  • enable_kitchen_tracking = false

Status awal order yang dibuat: ready

flowchart TD
    A([Kasir Login]) --> B["Table Overview /pos (Daftar semua meja)"]
    B --> C{Pilih Meja}
    C -->|Meja Tersedia| D[POS Transaction /pos/tables/tableId]
    C -->|Buat Takeaway| D2[POS Transaction /pos/transaction?orderType=takeaway]
    D --> E[Pilih & tambah produk ke keranjang]
    E --> F[Opsional: Diskon, customer, notes]
    F --> G[Klik 'Complete Order']
    G --> H[(Order dibuat status=ready table_id=tableId)]
    H --> I["Table Orders /pos/tables/tableId/orders"]
    I --> J{Aksi Kasir}

    J -->|Bayar 1 Order| K["Table Payment /pos/tables/tableId/payment"]
    J -->|Bayar Semua Sekaligus| L["Bulk Payment /pos/tables/tableId/bulk-payment"]
    J -->|Tambah Order Baru| D

    K --> M[Input Pembayaran, Finalize]
    L --> M

    M --> N[(Order=completed, Payment=paid, Meja dibebaskan jika kosong)]
    N --> O[Struk /pos/receipt]
    O --> P[Kembali ke Table Orders atau Table Overview]

    style H fill:#388e3c,color:#fff
    style N fill:#388e3c,color:#fff

Catatan penting:

  • Tanpa kitchen tracking, order langsung ready — tidak ada antrian dapur
  • Kasir bisa tambahkan beberapa order ke satu meja sebelum bayar
  • Bisa bayar per order atau sekaligus (bulk payment)
  • Meja otomatis dibebaskan jika semua order sudah paid/completed

B2. Kitchen Tracking Aktif

Konfigurasi:

  • enable_table_tracking = true
  • enable_kitchen_tracking = true

Status awal order yang dibuat: confirmed

Ini adalah skenario paling lengkap — melibatkan kasir, dapur (kitchen board), dan customer display.

flowchart TD
    A([Kasir Login]) --> B["Table Overview /pos (Daftar meja dengan status order)"]
    B --> C{Pilih meja}

    C -->|Meja kosong / aktif| D["POS Transaction /pos/tables/tableId"]
    D --> E[Pilih produk, tambah ke cart]
    E --> F[Opsional: Diskon, customer, notes]
    F --> G[Klik 'Complete Order']
    G --> H[(Order dibuat: status=confirmed, Print job dikirim ke Dapur)]

    H --> I["Table Orders /pos/tables/tableId/orders"]

    subgraph KITCHEN["Proses Dapur (Paralel)"]
        K1["Kitchen Board /pos/kitchen Status: confirmed"]
        K1 -->|Klik 'Start Preparing'| K2[Status: preparing]
        K2 -->|Klik 'Mark Ready'| K3[Status: ready]
    end

    H -.->|Kitchen Board memproses| KITCHEN

    I --> J{Aksi Kasir}
    J -->|Tambah order lagi ke meja| D
    J -->|Lihat detail order| J1["Table Order Show /pos/tables/tableId/orders/orderId"]
    J -->|Void order| J2[Order dibatalkan, Stok dikembalikan]

    K3 --> M{Order siap disajikan}
    M -->|Kasir proses pembayaran| N["Table Payment /pos/tables/tableId/payment"]
    M -->|Bulk Payment| NB["Bulk Payment /pos/tables/tableId/bulk-payment"]

    N --> O[Input metode & nominal, Finalize]
    NB --> O

    O --> P[(Payment disimpan, Order=completed, Meja dibebaskan jika kosong)]
    P --> Q[Struk /pos/receipt]
    Q --> R[Kembali ke Table Overview]

    style H fill:#1565c0,color:#fff
    style K3 fill:#388e3c,color:#fff
    style P fill:#388e3c,color:#fff
    style J2 fill:#c62828,color:#fff

Alur lengkap step-by-step:

Langkah Pelaku Aksi Status Order
1 Kasir Login ke POS
2 Kasir Pilih meja di Table Overview
3 Kasir Tambah produk ke cart
4 Kasir Klik "Complete Order" confirmed
5 Sistem Print job dikirim ke dapur confirmed
6 Dapur Klik "Start Preparing" di Kitchen Board preparing
7 Dapur Klik "Mark Ready" ready
8 Kasir Proses pembayaran di Table Payment ready
9 Kasir Finalize Payment completed / paid
10 Sistem Cetak struk, meja dibebaskan


Skenario C — Pesan Mandiri (Self-Order QR)

Fitur Pesan Mandiri memungkinkan pelanggan untuk memindai QR code di meja dan memesan langsung dari smartphone mereka tanpa perlu memanggil kasir.

Syarat aktif:

  • enable_table_tracking = true
  • enable_self_order = true

C1. Alur Kasir — Membuka Meja dengan QR

Kasir membuka sesi QR untuk meja, mencetak QR ke printer thermal, lalu meletakkan struk di meja agar customer bisa scan.

flowchart TD
    A([Kasir Login]) --> B["Table Overview /pos"]
    B --> C{Status Meja}

    C -->|Meja Tersedia| D["Klik 'Buka Meja dengan QR'"]
    C -->|Meja Terisi & ada sesi aktif| D2["Klik 'Lihat / Print QR'"]

    D --> E["Sistem: Buat TableQrSession baru (token unik, expires_at, max_orders)"]
    E --> F["Modal QR terbuka — QR code tampil di layar"]
    D2 --> F

    F --> G{Aksi Kasir}
    G -->|Print QR| H["Buat PrintJob (job_type=qr) — ESC/POS ke printer thermal"]
    G -->|Regenerate QR| I["Sesi lama ditutup, sesi baru dibuat, URL berubah"]
    G -->|Tutup Modal| J["Meja berstatus occupied — Customer bisa scan QR"]

    H --> J

    style E fill:#1565c0,color:#fff
    style H fill:#388e3c,color:#fff
    style I fill:#f9a825,color:#000

Catatan penting:

  • Setiap klik "Buka Meja dengan QR" atau "Regenerate" menghasilkan token baru — URL lama langsung tidak valid.
  • Struk QR yang dicetak ke thermal printer berisi: nama bisnis, nomor meja, QR code, dan instruksi singkat.
  • Sesi QR menyimpan konfigurasi max_orders dan expires_at dari pengaturan tenant pada saat sesi dibuat — mengubah pengaturan global tidak mempengaruhi sesi yang sedang berjalan.

C2. Alur Customer — Scan QR & Pesan

Setelah kasir mencetak QR dan meletakkannya di meja, pelanggan dapat memindai dan memesan langsung.

flowchart TD
    A([Customer Scan QR]) --> B["Buka URL /order/TENANTCODE/qr/TOKEN"]
    B --> C{Validasi Middleware}

    C -->|Tidak valid / kadaluarsa| D["Halaman QR Expired (customer.qr-expired)"]
    C -->|Valid| E["CustomerMenu /order/TENANTCODE/qr/TOKEN"]

    E --> F["Lihat menu (kategori & produk)"]
    F --> G["Pilih produk, pilih addon, atur qty"]
    G --> H["Tambah ke keranjang"]
    H --> I{Mau pesan lagi?}
    I -->|Ya| F
    I -->|Tidak| J["Klik Pesan Sekarang"]

    J --> K{Cek duplikat order}
    K -->|Sama dengan order terakhir| L["Modal konfirmasi duplikat"]
    K -->|Order berbeda| N["Validasi stok & produk"]
    L -->|Konfirmasi| N
    L -->|Batal| J

    N --> O{Validasi lolos?}
    O -->|Stok habis / produk tidak aktif| P["Pesan error, update cart"]
    O -->|Lolos| Q{Rate limit 30 detik}
    Q -->|Terlalu cepat| R["Pesan: Tunggu 30 detik sebelum pesan lagi"]
    Q -->|OK| S["CustomerOrderService::createOrder() — order_source=mobile_customer"]

    S --> T["Redirect ke halaman status order"]
    T --> U["Status order live — poll 4 detik"]

    style D fill:#c62828,color:#fff
    style S fill:#388e3c,color:#fff
    style L fill:#f9a825,color:#000
    style R fill:#f9a825,color:#000

Alur step-by-step pelanggan:

Langkah Aksi Keterangan
1 Scan QR di meja Buka URL unik di browser HP
2 Lihat menu Tampil kategori, produk, harga, dan foto
3 Pilih produk Bisa tambah addon dan atur kuantitas
4 Klik "Pesan Sekarang" Validasi cart dan stok dilakukan
5 (jika duplikat) Konfirmasi jika identik dengan order terakhir
6 Order dibuat order_source = mobile_customer, status = confirmed (jika kitchen tracking ON) atau ready
7 Lihat status Halaman status otomatis refresh setiap 4 detik
8 Selesai makan Kasir proses pembayaran seperti biasa dari sisi POS

C3. Proteksi & Validasi Sesi QR

Sistem menerapkan beberapa lapis perlindungan untuk mencegah penyalahgunaan:

Proteksi Mekanisme Keterangan
Token unik TableQrSession.token (hex acak 32 byte) Setiap sesi memiliki URL yang berbeda — tidak bisa ditebak
Kadaluarsa waktu expires_at QR otomatis tidak valid setelah durasi yang dikonfigurasi
Batas pesanan max_orders / order_count Setelah N pesanan, sesi dikunci
Status sesi active / expired / closed Sesi ditutup otomatis saat meja dibebaskan
Fitur aktif enable_self_order di tenant Middleware menolak jika fitur dinonaktifkan
Rate limiting Cache (30 detik per sesi) Mencegah spam order dari pelanggan yang sama
Deteksi duplikat Bandingkan cart dengan order terakhir Konfirmasi diminta jika identik
Validasi stok Saat submit order Produk tidak aktif / stok habis ditolak

Kapan sesi QR ditutup otomatis?

  • Kasir klik "Regenerate QR" → sesi lama langsung closed
  • Meja dibebaskan (semua order paid/cancelled) → PosOrderService::releaseTableIfFree() menutup semua sesi aktif di meja tersebut
  • expires_at sudah lewat → middleware otomatis mengubah status menjadi expired dan menampilkan halaman kadaluarsa

Skenario D — Meja Bebas (Free Table)

Fitur Meja Bebas memungkinkan kasir membuat meja sementara di luar daftar meja permanen — berguna untuk meja tambahan, ruang VIP dadakan, atau area outdoor yang tidak terdaftar.

Syarat aktif: enable_table_tracking = true

Perbedaan utama dengan meja reguler:

  • Meja bersifat sementara (is_temporary = true) dan tidak disimpan permanen — otomatis dihapus (forceDelete) saat semua order selesai.
  • Nama meja ditentukan bebas oleh kasir (maks. 50 karakter), misalnya Teras 1, VIP, Outdoor 2.
  • Status langsung occupied saat pertama kali dibuat.
  • Di tampilan Table Overview, card meja bebas memiliki border dashed amber dan badge SEMENTARA.
  • Jika Pesan Mandiri aktif, meja bebas juga mendukung QR self-order seperti meja reguler.
flowchart TD
    A([Kasir di Table Overview]) -->|"Klik '+ Meja Bebas'"| B["Modal: Input nama meja"]
    B -->|"Ketik nama, klik Buat Meja"| C{Validasi}
    C -->|"Nama kosong / >50 karakter"| B
    C -->|"Nama duplikat"| B
    C -->|"Lolos"| D["INSERT: is_temporary=true, status=occupied"]
    D --> E["Redirect ke POS Transaction /pos/tables/tableId"]
    E --> F["Kasir tambah order seperti biasa"]
    F --> G{Semua order paid/cancelled?}
    G -->|Ya| H["releaseTableIfFree() — forceDelete() meja"]
    G -->|Tidak| F
    I([Kasir klik 'Tutup Meja Bebas']) -->|Tidak ada order aktif| H
    I -->|Masih ada order aktif| J["Ditolak: selesaikan order terlebih dahulu"]
    style D fill:#f59e0b,color:#000
    style H fill:#c62828,color:#fff
    style J fill:#f9a825,color:#000

Alur step-by-step:

Langkah Pelaku Aksi
1 Kasir Klik "+ Meja Bebas" di Table Overview
2 Kasir Ketik nama meja di modal, klik "Buat Meja"
3 Sistem Buat RestaurantTable dengan is_temporary=true, status=occupied
4 Sistem Redirect ke POS Transaction meja baru
5 Kasir Tambah order, proses pembayaran seperti meja biasa
6a Sistem Jika semua order selesai → forceDelete() otomatis
6b Kasir Atau klik "Tutup Meja Bebas" di card (hanya jika tidak ada order aktif)

Catatan penting:

  • Meja bebas tidak muncul di Settings — tidak bisa diubah menjadi permanen.
  • Nama meja tidak boleh sama dengan meja lain yang sedang aktif di tenant yang sama.
  • Saat meja dihapus, semua sesi QR aktif untuk meja tersebut juga otomatis ditutup.
  • Jika Pesan Mandiri aktif, kasir dapat membuka sesi QR untuk meja bebas dan customer bisa self-order seperti biasa.

Skenario Khusus — Order Takeaway

T1. Takeaway Standalone (Tanpa Meja)

Order takeaway yang tidak terhubung ke meja manapun.

Cara akses:

  • Jika table tracking OFF: otomatis tersedia di /pos/transaction
  • Jika table tracking ON: kasir bisa pilih order type takeaway di POS Transaction tanpa memilih meja
flowchart TD
    A[POS Transaction] --> B{Kitchen Tracking?}

    B -->|Kitchen Tracking OFF| C[(Order dibuat status=ready table_id=null)]
    C --> D[Redirect ke Payment /pos/order/orderId/payment]
    D --> E[Proses Bayar]
    E --> F[Struk]

    B -->|Kitchen Tracking ON| G[(Order dibuat status=confirmed table_id=null)]
    G --> H[Kembali ke POS, Kitchen Board memproses]
    H --> I[Kitchen: confirmed ke preparing ke ready]
    I --> F

    style C fill:#388e3c,color:#fff
    style G fill:#1565c0,color:#fff

T2. Takeaway Join Bill (Digabung ke Meja)

Order takeaway yang digabungkan dengan order di meja — berguna untuk pelanggan yang bersamaan memesan untuk dibawa pulang bersama group dine-in.

Cara akses: Dari Table Overview → pilih meja → di POS Transaction, ganti order type ke takeaway (tableId tetap ada di URL)

flowchart TD
    A["Table Overview /pos"] --> B["Pilih Meja"]
    B --> C["POS Transaction /pos/tables/tableId"]
    C --> D["Ganti order type ke Takeaway"]
    D --> E[Tambah produk ke cart]
    E --> F[Klik 'Complete Order']
    F --> G{Kitchen Tracking?}

    G -->|Kitchen Tracking ON| H[(Order dibuat type=takeaway table_id=tableId status=confirmed Join order group meja)]
    H --> I["Redirect ke Table Orders /pos/tables/tableId/orders"]
    I --> J[Kasir bisa bayar bersama order dine-in lainnya via Bulk Payment]

    G -->|Kitchen Tracking OFF| K[(Order dibuat type=takeaway table_id=tableId status=ready)]
    K --> I

    style H fill:#1565c0,color:#fff
    style K fill:#388e3c,color:#fff

8. Halaman & Route POS

Route POS (Kasir)

Route Name URL Komponen Keterangan
pos /pos TableOverview Overview semua meja (redirect ke transaction jika table tracking OFF)
pos.transaction /pos/transaction PosTransaction Transaksi tanpa meja
pos.tables.show /pos/tables/{tableId} PosTransaction Transaksi dengan meja
pos.tables.orders /pos/tables/{tableId}/orders PosTableOrders Daftar order di meja
pos.tables.orders.show /pos/tables/{tableId}/orders/{orderId} PosTableOrderShow Detail & void order
pos.tables.payment /pos/tables/{tableId}/payment PosTablePayment Pembayaran per order
pos.tables.bulk-payment /pos/tables/{tableId}/bulk-payment PosBulkPayment Pembayaran semua order sekaligus
pos.order.payment /pos/order/{orderId}/payment PosTablePayment Pembayaran order tanpa meja
pos.receipt /pos/receipt/{orderId?} PosReceipt Struk transaksi
pos.kitchen /pos/kitchen KitchenBoard Monitor dapur

Route Customer Pesan Mandiri

Route ini dilindungi middleware qr.session yang memvalidasi token dan status sesi QR.

Route Name URL Komponen Keterangan
customer.qr.menu /order/{tenantCode}/qr/{token} CustomerMenu Halaman menu & keranjang untuk pelanggan
customer.qr.status /order/{tenantCode}/qr/{token}/status/{orderId} CustomerOrderStatus Status order pelanggan setelah pesan
(fallback) (expired/invalid token) customer.qr-expired Halaman informatif ketika QR tidak valid

9. Ringkasan Matriks Keputusan

Entry Point Kasir

Table Tracking Kitchen Tracking Entry Point (/pos)
OFF OFF PosTransaction (langsung transaksi)
OFF ON PosTransaction (langsung transaksi)
ON OFF TableOverview (pilih meja dulu)
ON ON TableOverview (pilih meja dulu)

Status Order Saat Dibuat

Order Type Table Tracking Kitchen Tracking Status Awal Redirect Setelah Submit
dine_in OFF OFF ready /pos/order/{id}/payment
dine_in OFF ON pending /pos/order/{id}/payment → bayar dulu → kitchen
dine_in ON OFF ready /pos/tables/{id}/orders
dine_in ON ON confirmed /pos/tables/{id}/orders → kitchen memproses
takeaway OFF OFF ready /pos/order/{id}/payment
takeaway OFF ON confirmed /pos (kembali ke POS)
takeaway ON OFF ready /pos/tables/{id}/orders (join bill)
takeaway ON ON confirmed /pos/tables/{id}/orders (join bill + kitchen)

Alur Pembayaran

Skenario Halaman Payment Catatan
Tanpa meja PosTablePayment via /pos/order/{id}/payment Single order
Dengan meja, 1 order PosTablePayment via /pos/tables/{id}/payment Single order
Dengan meja, multi order PosBulkPayment via /pos/tables/{id}/bulk-payment Bayar semua sekaligus dengan diskon yang bisa diaplikasi ke semua order

Kapan Meja Dibebaskan?

Meja otomatis dibebaskan (status kembali tersedia) ketika semua order di meja tersebut sudah berstatus completed dengan payment_status = paid, atau semua order berstatus cancelled.

Saat meja dibebaskan, semua sesi QR aktif untuk meja tersebut juga otomatis ditutup (status = closed).

Khusus Meja Bebas (is_temporary = true): alih-alih status kembali ke available, meja langsung dihapus permanen (forceDelete()). Meja bebas juga bisa ditutup manual oleh kasir dari card Table Overview selama tidak ada order aktif.

Status Order dari Pesan Mandiri

Order yang dibuat melalui Pesan Mandiri mengikuti aturan yang sama dengan order kasir berdasarkan konfigurasi Kitchen Tracking tenant:

Kitchen Tracking order_source Status Awal Alur Selanjutnya
OFF mobile_customer ready Kasir langsung bisa proses pembayaran
ON mobile_customer confirmed Dapur memproses → preparingready → kasir bayar

Order dari Pesan Mandiri muncul di Table Orders (/pos/tables/{tableId}/orders) seperti order biasa — kasir bisa lihat, void, dan proses pembayarannya secara normal.