Waiter Tab
This commit is contained in:
parent
4ce205b3ae
commit
67bee18afd
@ -18,3 +18,8 @@ id,transaksi_id,menu_id,qty,harga_satuan,subtotal_item
|
||||
17,10,7,1,21000.0,21000.0
|
||||
18,11,3,1,30000.0,30000.0
|
||||
19,11,4,1,25000.0,25000.0
|
||||
20,12,7,1,21000.0,21000.0
|
||||
21,13,8,1,25000.0,25000.0
|
||||
22,13,2,1,25000.0,25000.0
|
||||
23,13,3,1,30000.0,30000.0
|
||||
24,14,10,1,20000.0,20000.0
|
||||
|
||||
|
@ -3,10 +3,11 @@ user_id,menu_id,order_count,last_ordered
|
||||
1,2,1,2025-12-13 20:12:35
|
||||
1,4,1,2025-12-13 20:12:35
|
||||
1,6,1,2025-12-13 20:12:35
|
||||
4,2,2,2025-12-14 10:03:04
|
||||
4,2,3,2025-12-14 21:14:46
|
||||
4,4,3,2025-12-14 10:35:35
|
||||
4,3,3,2025-12-14 10:35:35
|
||||
4,3,4,2025-12-14 21:14:46
|
||||
4,11,1,2025-12-14 01:44:46
|
||||
4,7,2,2025-12-14 10:03:04
|
||||
4,8,1,2025-12-14 09:50:02
|
||||
4,7,3,2025-12-14 21:12:55
|
||||
4,8,2,2025-12-14 21:14:46
|
||||
4,9,1,2025-12-14 09:50:02
|
||||
4,10,1,2025-12-14 21:43:51
|
||||
|
||||
|
351
main.py
351
main.py
@ -2827,9 +2827,8 @@ class App:
|
||||
def build_waiter_tab(self, parent, readonly=False):
|
||||
"""Tab untuk waiter mengelola pesanan
|
||||
|
||||
Args:
|
||||
parent: Parent frame
|
||||
readonly: Jika True, tombol aksi disabled (untuk admin monitoring)
|
||||
Status Flow yang Disederhanakan:
|
||||
pending → menunggu → selesai
|
||||
"""
|
||||
for w in parent.winfo_children():
|
||||
w.destroy()
|
||||
@ -2838,7 +2837,6 @@ class App:
|
||||
header = ttk.Frame(parent)
|
||||
header.pack(fill='x', padx=10, pady=6)
|
||||
|
||||
# ✅ UBAH JUDUL SESUAI MODE
|
||||
if readonly:
|
||||
ttk.Label(
|
||||
header,
|
||||
@ -2849,7 +2847,7 @@ class App:
|
||||
else:
|
||||
ttk.Label(
|
||||
header,
|
||||
text="Dashboard Waiter - Kelola Pesanan",
|
||||
text="🍽️ Dashboard Waiter - Kelola Pesanan",
|
||||
font=("Arial", 13, "bold")
|
||||
).pack(side='left')
|
||||
|
||||
@ -2865,8 +2863,7 @@ class App:
|
||||
ttk.Label(filter_frame, text="Filter Status:").pack(side='left', padx=6)
|
||||
ttk.Button(filter_frame, text="Semua", command=lambda: self.reload_waiter_orders(None), width=8).pack(side='left', padx=2)
|
||||
ttk.Button(filter_frame, text="Pending", command=lambda: self.reload_waiter_orders('pending'), width=8).pack(side='left', padx=2)
|
||||
ttk.Button(filter_frame, text="Menunggu", command=lambda: self.reload_waiter_orders('menunggu'), width=10).pack(side='left', padx=2)
|
||||
ttk.Button(filter_frame, text="Diproses", command=lambda: self.reload_waiter_orders('diproses'), width=8).pack(side='left', padx=2)
|
||||
ttk.Button(filter_frame, text="Diproses", command=lambda: self.reload_waiter_orders('menunggu'), width=10).pack(side='left', padx=2)
|
||||
ttk.Button(filter_frame, text="Selesai", command=lambda: self.reload_waiter_orders('selesai'), width=8).pack(side='left', padx=2)
|
||||
|
||||
# Treeview pesanan
|
||||
@ -2917,17 +2914,13 @@ class App:
|
||||
detail_scroll = ttk.Scrollbar(text_frame, orient='vertical', command=self.waiter_detail_text.yview)
|
||||
self.waiter_detail_text.configure(yscrollcommand=detail_scroll.set)
|
||||
|
||||
# PACK SCROLLBAR DULUAN
|
||||
detail_scroll.pack(side='right', fill='y')
|
||||
|
||||
# BARU TEXT AREA
|
||||
self.waiter_detail_text.pack(side='left', fill='both', expand=True)
|
||||
|
||||
# TOMBOL AKSI
|
||||
action_frame = ttk.LabelFrame(parent, text="🎯 Ubah Status Pesanan", padding=12)
|
||||
# TOMBOL AKSI - DENGAN STATE MANAGEMENT
|
||||
action_frame = ttk.LabelFrame(parent, text="🎯 Update Status Pesanan", padding=12)
|
||||
action_frame.pack(fill='x', padx=10, pady=8)
|
||||
|
||||
# ✅ JIKA READ-ONLY, TAMPILKAN WARNING & DISABLE TOMBOL
|
||||
if readonly:
|
||||
warning_label = ttk.Label(
|
||||
action_frame,
|
||||
@ -2937,48 +2930,83 @@ class App:
|
||||
foreground='red',
|
||||
justify='center'
|
||||
)
|
||||
warning_label.pack(pady=10)
|
||||
|
||||
warning_label.grid(row=2, column=0, columnspan=2, pady=10)
|
||||
# Grid untuk 2 tombol
|
||||
btn_frame = ttk.Frame(action_frame)
|
||||
btn_frame.pack(fill='x', pady=10)
|
||||
|
||||
# Grid 2x2 untuk 4 tombol
|
||||
btn1 = ttk.Button(
|
||||
action_frame,
|
||||
text="✅ Terima (Pending → Menunggu)",
|
||||
self.waiter_btn_terima = tk.Button(
|
||||
btn_frame,
|
||||
text="✅ Terima Pesanan (Pending → Diproses)",
|
||||
command=lambda: self.update_order_status('menunggu') if not readonly else None,
|
||||
width=35,
|
||||
state='disabled' if readonly else 'normal'
|
||||
font=("Arial", 10, "bold"),
|
||||
relief='raised',
|
||||
cursor='hand2',
|
||||
state='disabled' if readonly else 'normal',
|
||||
bg='#4CAF50',
|
||||
fg='white',
|
||||
activebackground='#45a049',
|
||||
padx=10,
|
||||
pady=10
|
||||
)
|
||||
btn1.grid(row=0, column=0, padx=4, pady=4, sticky='ew')
|
||||
self.waiter_btn_terima.pack(fill='x', padx=5, pady=5)
|
||||
|
||||
btn2 = ttk.Button(
|
||||
action_frame,
|
||||
text="🍳 Proses (Menunggu → Diproses)",
|
||||
command=lambda: self.update_order_status('diproses') if not readonly else None,
|
||||
width=35,
|
||||
state='disabled' if readonly else 'normal'
|
||||
)
|
||||
btn2.grid(row=0, column=1, padx=4, pady=4, sticky='ew')
|
||||
|
||||
btn3 = ttk.Button(
|
||||
action_frame,
|
||||
text="🍽️ Selesai (Diproses → Selesai)",
|
||||
self.waiter_btn_proses = tk.Button(
|
||||
btn_frame,
|
||||
text="🍳 Pesanan Siap Disajikan (Diproses → Selesai)",
|
||||
command=lambda: self.update_order_status('selesai') if not readonly else None,
|
||||
width=35,
|
||||
state='disabled' if readonly else 'normal'
|
||||
font=("Arial", 10, "bold"),
|
||||
relief='raised',
|
||||
cursor='hand2',
|
||||
state='disabled' if readonly else 'normal',
|
||||
bg='#2196F3',
|
||||
fg='white',
|
||||
activebackground='#0b7dda',
|
||||
padx=10,
|
||||
pady=10
|
||||
)
|
||||
btn3.grid(row=1, column=0, padx=4, pady=4, sticky='ew')
|
||||
self.waiter_btn_proses.pack(fill='x', padx=5, pady=5)
|
||||
|
||||
btn4 = ttk.Button(
|
||||
# ===== INFO BOX - STATUS FLOW =====
|
||||
info_box = tk.Frame(
|
||||
action_frame,
|
||||
text="💰 Dibayar (Selesai → Dibayar)",
|
||||
command=lambda: self.update_order_status('dibayar') if not readonly else None,
|
||||
width=35,
|
||||
state='disabled' if readonly else 'normal'
|
||||
bg='#E3F2FD',
|
||||
relief='solid',
|
||||
borderwidth=2,
|
||||
padx=15,
|
||||
pady=12
|
||||
)
|
||||
btn4.grid(row=1, column=1, padx=4, pady=4, sticky='ew')
|
||||
info_box.pack(fill='x', pady=10)
|
||||
|
||||
action_frame.columnconfigure(0, weight=1)
|
||||
action_frame.columnconfigure(1, weight=1)
|
||||
tk.Label(
|
||||
info_box,
|
||||
text="📌 ALUR STATUS PESANAN",
|
||||
font=("Arial", 10, "bold"),
|
||||
bg='#E3F2FD',
|
||||
fg='#1565C0'
|
||||
).pack(anchor='w', pady=(0, 8))
|
||||
|
||||
tk.Label(
|
||||
info_box,
|
||||
text="Pending (Baru) → Diproses (Sedang Disiapkan) → Selesai (Siap Disajikan)",
|
||||
font=("Arial", 9, "bold"),
|
||||
bg='#E3F2FD',
|
||||
fg='#0D47A1',
|
||||
wraplength=500,
|
||||
justify='center'
|
||||
).pack(anchor='w', pady=(0, 8))
|
||||
|
||||
tk.Label(
|
||||
info_box,
|
||||
text="💡 Tombol akan otomatis berubah warna sesuai status pesanan.\n"
|
||||
"Tombol berwarna cerah bisa diklik, yang abu-abu tidak.",
|
||||
font=("Arial", 8),
|
||||
bg='#E3F2FD',
|
||||
fg='#424242',
|
||||
justify='center',
|
||||
wraplength=500
|
||||
).pack(anchor='w')
|
||||
|
||||
# Load data
|
||||
self.reload_waiter_orders()
|
||||
@ -3062,7 +3090,10 @@ class App:
|
||||
self.waiter_detail_text.insert('1.0', detail_text)
|
||||
|
||||
def update_order_status(self, new_status):
|
||||
"""Update status pesanan yang dipilih"""
|
||||
"""Update status pesanan dengan visual feedback
|
||||
|
||||
Status Flow: pending → menunggu → selesai
|
||||
"""
|
||||
sel = self.waiter_tree.selection()
|
||||
if not sel:
|
||||
messagebox.showwarning("Pilih Pesanan", "Pilih pesanan terlebih dahulu")
|
||||
@ -3072,53 +3103,247 @@ class App:
|
||||
transaksi_id = item[0]
|
||||
current_status = item[4]
|
||||
|
||||
# Validasi flow status yang BENAR
|
||||
# Validasi flow status
|
||||
valid_transitions = {
|
||||
'pending': ['menunggu'],
|
||||
'menunggu': ['diproses'],
|
||||
'diproses': ['selesai'],
|
||||
'selesai': ['dibayar']
|
||||
'pending': ['menunggu'], # Pending → Diproses
|
||||
'menunggu': ['selesai'], # Diproses → Selesai
|
||||
'selesai': [] # Selesai = FINAL
|
||||
}
|
||||
|
||||
# Cek apakah current status valid
|
||||
# Cek current status valid
|
||||
if current_status not in valid_transitions:
|
||||
messagebox.showerror("Error", f"Status '{current_status}' sudah final, tidak bisa diubah lagi")
|
||||
messagebox.showerror(
|
||||
"Error",
|
||||
f"❌ Status '{current_status}' sudah final!\n\n"
|
||||
f"Pesanan ini sudah siap disajikan."
|
||||
)
|
||||
return
|
||||
|
||||
# Cek apakah new_status valid untuk current_status
|
||||
# Cek status sudah final
|
||||
if not valid_transitions[current_status]:
|
||||
messagebox.showerror(
|
||||
"Status Final",
|
||||
f"❌ Pesanan sudah mencapai status 'SELESAI'\n\n"
|
||||
f"Tidak ada lagi yang perlu dilakukan waiter."
|
||||
)
|
||||
return
|
||||
|
||||
# Cek new_status valid
|
||||
if new_status not in valid_transitions[current_status]:
|
||||
expected = ', '.join(valid_transitions[current_status])
|
||||
messagebox.showwarning("Status Tidak Valid",
|
||||
messagebox.showwarning(
|
||||
"Status Tidak Valid",
|
||||
f"❌ Tidak bisa ubah dari '{current_status}' ke '{new_status}'.\n\n"
|
||||
f"✅ Status yang benar setelah '{current_status}' adalah:\n"
|
||||
f" → {expected}")
|
||||
f" → {expected}"
|
||||
)
|
||||
return
|
||||
|
||||
# Mapping status untuk pesan
|
||||
status_messages = {
|
||||
'pending': 'Pesanan Baru',
|
||||
'menunggu': 'Sedang Disiapkan',
|
||||
'selesai': 'Siap Disajikan'
|
||||
}
|
||||
|
||||
current_msg = status_messages.get(current_status, current_status.upper())
|
||||
new_msg = status_messages.get(new_status, new_status.upper())
|
||||
|
||||
# Konfirmasi
|
||||
if not messagebox.askyesno("Konfirmasi",
|
||||
f"Ubah status pesanan #{transaksi_id}\n\n"
|
||||
f"Dari: {current_status.upper()}\n"
|
||||
f"Ke: {new_status.upper()}\n\n"
|
||||
f"Lanjutkan?"):
|
||||
confirm_msg = f"Ubah status pesanan #{transaksi_id}?\n\n"
|
||||
confirm_msg += f"Dari: {current_msg}\n"
|
||||
confirm_msg += f"Ke: {new_msg}\n\n"
|
||||
|
||||
if new_status == 'selesai':
|
||||
confirm_msg += "⚠️ Setelah ini, pesanan siap disajikan ke customer.\n"
|
||||
confirm_msg += "Customer dapat langsung diminta untuk bayar."
|
||||
elif new_status == 'menunggu':
|
||||
confirm_msg += "Pesanan akan dimasukkan ke daftar yang sedang disiapkan."
|
||||
|
||||
confirm_msg += "\n\nLanjutkan?"
|
||||
|
||||
if not messagebox.askyesno("Konfirmasi", confirm_msg):
|
||||
return
|
||||
|
||||
# Update status
|
||||
# Update status di database
|
||||
success = transaksi_update_status(transaksi_id, new_status)
|
||||
|
||||
if success:
|
||||
messagebox.showinfo("✅ Berhasil", f"Status berhasil diubah menjadi '{new_status.upper()}'")
|
||||
# Pesan sukses
|
||||
if new_status == 'menunggu':
|
||||
success_msg = (
|
||||
f"✅ Pesanan #{transaksi_id} sedang disiapkan.\n\n"
|
||||
f"Tim dapur: mulai siapkan pesanan ini!"
|
||||
)
|
||||
elif new_status == 'selesai':
|
||||
success_msg = (
|
||||
f"✅ Pesanan #{transaksi_id} siap disajikan!\n\n"
|
||||
f"Silakan bawa ke meja customer."
|
||||
)
|
||||
else:
|
||||
success_msg = f"✅ Status berhasil diubah menjadi '{new_status.upper()}'"
|
||||
|
||||
messagebox.showinfo("Berhasil", success_msg)
|
||||
|
||||
# ✅ RELOAD DAN UPDATE BUTTON STATE
|
||||
self.reload_waiter_orders()
|
||||
self.update_waiter_button_state()
|
||||
|
||||
# Auto select row yang sama
|
||||
for item_id in self.waiter_tree.get_children():
|
||||
if self.waiter_tree.item(item_id)['values'][0] == transaksi_id:
|
||||
self.waiter_tree.selection_set(item_id)
|
||||
self.waiter_tree.see(item_id)
|
||||
# Trigger event untuk reload detail
|
||||
self.on_waiter_select(None)
|
||||
break
|
||||
else:
|
||||
messagebox.showerror("❌ Gagal", "Gagal mengubah status pesanan")
|
||||
|
||||
def update_waiter_button_state(self):
|
||||
"""Update state tombol berdasarkan status pesanan yang dipilih
|
||||
|
||||
Logika:
|
||||
- Pending: Tombol TERIMA aktif, tombol PROSES disabled
|
||||
- Diproses: Tombol TERIMA disabled, tombol PROSES aktif
|
||||
- Selesai: Semua tombol disabled (pesanan sudah final)
|
||||
"""
|
||||
sel = self.waiter_tree.selection()
|
||||
|
||||
if not sel:
|
||||
# Tidak ada pesanan dipilih: semua disabled
|
||||
self.waiter_btn_terima.config(state='disabled', bg='#cccccc', fg='#666666')
|
||||
self.waiter_btn_proses.config(state='disabled', bg='#cccccc', fg='#666666')
|
||||
return
|
||||
|
||||
item = self.waiter_tree.item(sel)['values']
|
||||
current_status = item[4] # Status adalah field ke-4 (index 4)
|
||||
|
||||
# ===== LOGIC UNTUK SET STATE TOMBOL =====
|
||||
|
||||
if current_status == 'pending':
|
||||
# Status PENDING: Tombol TERIMA aktif, PROSES disabled
|
||||
|
||||
# Tombol TERIMA - AKTIF (Hijau)
|
||||
self.waiter_btn_terima.config(
|
||||
state='normal',
|
||||
bg='#4CAF50',
|
||||
fg='white',
|
||||
cursor='hand2',
|
||||
relief='raised',
|
||||
activebackground='#45a049'
|
||||
)
|
||||
|
||||
# Tombol PROSES - DISABLED (Gelap)
|
||||
self.waiter_btn_proses.config(
|
||||
state='disabled',
|
||||
bg='#A9A9A9',
|
||||
fg='#555555',
|
||||
cursor='arrow',
|
||||
relief='sunken'
|
||||
)
|
||||
|
||||
elif current_status == 'menunggu':
|
||||
# Status DIPROSES: Tombol TERIMA disabled, PROSES aktif
|
||||
|
||||
# Tombol TERIMA - DISABLED
|
||||
self.waiter_btn_terima.config(
|
||||
state='disabled',
|
||||
bg='#A9A9A9',
|
||||
fg='#555555',
|
||||
cursor='arrow',
|
||||
relief='sunken'
|
||||
)
|
||||
|
||||
# Tombol PROSES - AKTIF (Biru)
|
||||
self.waiter_btn_proses.config(
|
||||
state='normal',
|
||||
bg='#2196F3',
|
||||
fg='white',
|
||||
cursor='hand2',
|
||||
relief='raised',
|
||||
activebackground='#0b7dda'
|
||||
)
|
||||
|
||||
elif current_status == 'selesai':
|
||||
# Status SELESAI: Semua tombol DISABLED (FINAL STATE)
|
||||
|
||||
self.waiter_btn_terima.config(
|
||||
state='disabled',
|
||||
bg='#D3D3D3',
|
||||
fg='#777777',
|
||||
cursor='arrow',
|
||||
relief='sunken'
|
||||
)
|
||||
|
||||
self.waiter_btn_proses.config(
|
||||
state='disabled',
|
||||
bg='#D3D3D3',
|
||||
fg='#777777',
|
||||
cursor='arrow',
|
||||
relief='sunken'
|
||||
)
|
||||
|
||||
|
||||
# ========================================
|
||||
# ON WAITER SELECT - CALL UPDATE BUTTON STATE
|
||||
# ========================================
|
||||
|
||||
def on_waiter_select(self, event):
|
||||
"""Tampilkan detail pesanan + UPDATE BUTTON STATE"""
|
||||
sel = self.waiter_tree.selection()
|
||||
if not sel:
|
||||
return
|
||||
|
||||
item = self.waiter_tree.item(sel)['values']
|
||||
transaksi_id = item[0]
|
||||
|
||||
# Get detail transaksi
|
||||
transaksi_data = transaksi_get(transaksi_id)
|
||||
if not transaksi_data:
|
||||
return
|
||||
|
||||
tid, uid, meja, total, status, promo_code, subtotal, item_disc, promo_disc, tanggal = transaksi_data
|
||||
detail_items = detail_transaksi_list(transaksi_id)
|
||||
|
||||
# Format detail
|
||||
detail_text = f"═══════════════════════════════════════════════\n"
|
||||
detail_text += f"TRANSAKSI ID: {tid}\n"
|
||||
detail_text += f"═══════════════════════════════════════════════\n\n"
|
||||
detail_text += f"User ID : {uid}\n"
|
||||
detail_text += f"Nomor Meja : {meja}\n"
|
||||
detail_text += f"Status : {status.upper()}\n"
|
||||
detail_text += f"Tanggal : {tanggal}\n"
|
||||
detail_text += f"Kode Promo : {promo_code if promo_code else '-'}\n\n"
|
||||
|
||||
detail_text += f"───────────────────────────────────────────────\n"
|
||||
detail_text += f"ITEM PESANAN:\n"
|
||||
detail_text += f"───────────────────────────────────────────────\n"
|
||||
|
||||
for detail in detail_items:
|
||||
did, mid, qty, harga, subtotal_item = detail
|
||||
menu_data = menu_get(mid)
|
||||
if menu_data:
|
||||
_, nama, kategori, _, _, _, _, _ = menu_data
|
||||
detail_text += f"• {nama} ({kategori})\n"
|
||||
detail_text += f" {qty} x Rp {harga:,.0f} = Rp {subtotal_item:,.0f}\n\n"
|
||||
|
||||
detail_text += f"───────────────────────────────────────────────\n"
|
||||
detail_text += f"Subtotal : Rp {subtotal:,.0f}\n"
|
||||
detail_text += f"Diskon Item : Rp {item_disc:,.0f}\n"
|
||||
detail_text += f"Diskon Promo : Rp {promo_disc:,.0f}\n"
|
||||
detail_text += f"───────────────────────────────────────────────\n"
|
||||
detail_text += f"TOTAL BAYAR : Rp {total:,.0f}\n"
|
||||
detail_text += f"═══════════════════════════════════════════════\n"
|
||||
|
||||
# Tampilkan di text widget
|
||||
self.waiter_detail_text.delete('1.0', tk.END)
|
||||
self.waiter_detail_text.insert('1.0', detail_text)
|
||||
|
||||
# ✅ UPDATE BUTTON STATE SESUAI STATUS PESANAN
|
||||
self.update_waiter_button_state()
|
||||
|
||||
|
||||
|
||||
# Wilayah dikuasai Favorite
|
||||
|
||||
|
||||
|
||||
10
menu.csv
10
menu.csv
@ -1,13 +1,13 @@
|
||||
id,nama,kategori,harga,stok,foto,tersedia,item_discount_pct
|
||||
1,Americano,Minuman,20000.0,7,img/americano.jpg,1,0.0
|
||||
2,Latte,Minuman,25000.0,4,img/latte.jpg,1,10.0
|
||||
3,Banana Cake,Dessert,30000.0,8,img/banana_cake.jpg,1,4.0
|
||||
2,Latte,Minuman,25000.0,3,img/latte.jpg,1,10.0
|
||||
3,Banana Cake,Dessert,30000.0,7,img/banana_cake.jpg,1,4.0
|
||||
4,Nasi Goreng,Makanan,25000.0,9,img/nasi_goreng.jpg,1,0.0
|
||||
5,Nasi Kuning,Makanan,18000.0,7,img/Nasi-Kuning.jpg,1,5.0
|
||||
6,Strawberry Milkshake,Minuman,19000.0,5,img/strawberry_milkshake.jpg,1,0.0
|
||||
7,Coconut Matcha,Minuman,21000.0,12,img/coconut_matcha.jpg,1,5.0
|
||||
8,Beef Yakiniku,Makanan,25000.0,12,img/Beef-Yakiniku.jpg,1,4.0
|
||||
7,Coconut Matcha,Minuman,21000.0,11,img/coconut_matcha.jpg,1,5.0
|
||||
8,Beef Yakiniku,Makanan,25000.0,11,img/Beef-Yakiniku.jpg,1,4.0
|
||||
9,Osaka Curry,Makanan,30000.0,14,img/osaka_curry.jpg,1,10.0
|
||||
10,Choco Pudding,Dessert,20000.0,16,img/chocolate-pudding.jpg,1,8.0
|
||||
10,Choco Pudding,Dessert,20000.0,15,img/chocolate-pudding.jpg,1,8.0
|
||||
11,Totoro Dango,Dessert,18000.0,9,img/dango.jpg,1,4.0
|
||||
12,Cheese Cake,Dessert,32000.0,9,img/cheese-cake.jpg,1,6.0
|
||||
|
||||
|
@ -4,3 +4,6 @@ id,transaksi_id,metode_pembayaran,jumlah_bayar,status_pembayaran,tanggal_bayar,s
|
||||
3,9,qris,63855.0,sukses,2025-12-14 09:52:46,
|
||||
4,10,cash,25000.0,sukses,2025-12-14 10:05:01,
|
||||
5,11,ewallet-gopay,48420.0,sukses,2025-12-14 10:52:50,
|
||||
6,13,qris,75300.0,sukses,2025-12-14 21:17:59,
|
||||
7,12,cash,100000.0,sukses,2025-12-14 21:46:15,
|
||||
8,14,cash,100000.0,sukses,2025-12-14 21:46:20,
|
||||
|
||||
|
27
struk/STR-12-20251214_214615.txt
Normal file
27
struk/STR-12-20251214_214615.txt
Normal file
@ -0,0 +1,27 @@
|
||||
═════════════════════════════════════════
|
||||
TOTORO CAFE
|
||||
Jl. Raya Totoro No. 123, Surabaya
|
||||
Telp: 031-123456
|
||||
═════════════════════════════════════════
|
||||
|
||||
No. Struk : STR-12-20251214
|
||||
Tanggal : 14/12/2025 21:12
|
||||
Meja : 1
|
||||
Kasir : kasir
|
||||
Pembayaran : CASH
|
||||
─────────────────────────────────────────
|
||||
ITEM PESANAN:
|
||||
─────────────────────────────────────────
|
||||
Coconut Matcha
|
||||
1 x Rp 21,000 Rp 21,000
|
||||
─────────────────────────────────────────
|
||||
Subtotal : Rp 21,000
|
||||
Diskon Item : Rp 1,050
|
||||
─────────────────────────────────────────
|
||||
TOTAL BAYAR : Rp 19,950
|
||||
Bayar : Rp 100,000
|
||||
Kembalian : Rp 80,050
|
||||
═════════════════════════════════════════
|
||||
TERIMA KASIH ATAS KUNJUNGAN ANDA
|
||||
SAMPAI JUMPA LAGI!
|
||||
═════════════════════════════════════════
|
||||
29
struk/STR-13-20251214_211759.txt
Normal file
29
struk/STR-13-20251214_211759.txt
Normal file
@ -0,0 +1,29 @@
|
||||
═════════════════════════════════════════
|
||||
TOTORO CAFE
|
||||
Jl. Raya Totoro No. 123, Surabaya
|
||||
Telp: 031-123456
|
||||
═════════════════════════════════════════
|
||||
|
||||
No. Struk : STR-13-20251214
|
||||
Tanggal : 14/12/2025 21:14
|
||||
Meja : 2
|
||||
Kasir : kasir
|
||||
Pembayaran : QRIS
|
||||
─────────────────────────────────────────
|
||||
ITEM PESANAN:
|
||||
─────────────────────────────────────────
|
||||
Beef Yakiniku
|
||||
1 x Rp 25,000 Rp 25,000
|
||||
Latte
|
||||
1 x Rp 25,000 Rp 25,000
|
||||
Banana Cake
|
||||
1 x Rp 30,000 Rp 30,000
|
||||
─────────────────────────────────────────
|
||||
Subtotal : Rp 80,000
|
||||
Diskon Item : Rp 4,700
|
||||
─────────────────────────────────────────
|
||||
TOTAL BAYAR : Rp 75,300
|
||||
═════════════════════════════════════════
|
||||
TERIMA KASIH ATAS KUNJUNGAN ANDA
|
||||
SAMPAI JUMPA LAGI!
|
||||
═════════════════════════════════════════
|
||||
27
struk/STR-14-20251214_214620.txt
Normal file
27
struk/STR-14-20251214_214620.txt
Normal file
@ -0,0 +1,27 @@
|
||||
═════════════════════════════════════════
|
||||
TOTORO CAFE
|
||||
Jl. Raya Totoro No. 123, Surabaya
|
||||
Telp: 031-123456
|
||||
═════════════════════════════════════════
|
||||
|
||||
No. Struk : STR-14-20251214
|
||||
Tanggal : 14/12/2025 21:43
|
||||
Meja : 9
|
||||
Kasir : kasir
|
||||
Pembayaran : CASH
|
||||
─────────────────────────────────────────
|
||||
ITEM PESANAN:
|
||||
─────────────────────────────────────────
|
||||
Choco Pudding
|
||||
1 x Rp 20,000 Rp 20,000
|
||||
─────────────────────────────────────────
|
||||
Subtotal : Rp 20,000
|
||||
Diskon Item : Rp 1,600
|
||||
─────────────────────────────────────────
|
||||
TOTAL BAYAR : Rp 18,400
|
||||
Bayar : Rp 100,000
|
||||
Kembalian : Rp 81,600
|
||||
═════════════════════════════════════════
|
||||
TERIMA KASIH ATAS KUNJUNGAN ANDA
|
||||
SAMPAI JUMPA LAGI!
|
||||
═════════════════════════════════════════
|
||||
@ -10,3 +10,6 @@ id,user_id,nomor_meja,total,status,promo_code,subtotal,item_discount,promo_disco
|
||||
9,4,3,63855.0,dibayar,OPENING,76000.0,5050.0,7095.0,2025-12-14 09:50:02
|
||||
10,4,5,23347.5,dibayar,MERDEKA,46000.0,3550.0,19102.5,2025-12-14 10:03:04
|
||||
11,4,1,48420.0,dibayar,OPENING,55000.0,1200.0,5380.0,2025-12-14 10:35:35
|
||||
12,4,1,19950.0,dibayar,,21000.0,1050.0,0.0,2025-12-14 21:12:55
|
||||
13,4,2,75300.0,dibayar,,80000.0,4700.0,0.0,2025-12-14 21:14:46
|
||||
14,4,9,18400.0,dibayar,,20000.0,1600.0,0.0,2025-12-14 21:43:51
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user