Dashboard waiter

This commit is contained in:
Jevinca Marvella 2025-12-08 16:41:02 +07:00
parent 5f8f54e8d2
commit 85c2f3158c
2 changed files with 208 additions and 3 deletions

205
main.py
View File

@ -698,9 +698,12 @@ class App:
self.tab_menu_view = ttk.Frame(main)
self.tab_promo = ttk.Frame(main)
self.tab_order = ttk.Frame(main)
self.tab_waiter = ttk.Frame(main)
main.add(self.tab_order, text="Order Menu")
main.add(self.tab_menu_view, text="Menu - View")
if self.session['role'] in ['waiter', 'admin']:
main.add(self.tab_waiter, text="Waiter - Pesanan")
if self.session['role'] == 'admin':
main.add(self.tab_menu_manage, text="Menu - Manage")
main.add(self.tab_promo, text="Promo - Manage")
@ -709,6 +712,8 @@ class App:
self.build_menu_view_tab(self.tab_menu_view)
self.build_order_tab(self.tab_order)
if self.session['role'] in ['waiter', 'admin']:
self.build_waiter_tab(self.tab_waiter)
if self.session['role'] == 'admin':
self.build_menu_manage_tab(self.tab_menu_manage)
self.build_promo_tab(self.tab_promo)
@ -1408,6 +1413,206 @@ class App:
# Wilayah dikuasai Waiter
def build_waiter_tab(self, parent):
"""Tab untuk waiter mengelola pesanan"""
for w in parent.winfo_children():
w.destroy()
# Header
header = ttk.Frame(parent)
header.pack(fill='x', padx=10, pady=8)
ttk.Label(header, text="Dashboard Waiter - Kelola Pesanan", font=("Arial", 14, "bold")).pack(side='left')
ttk.Button(header, text="🔄 Refresh", command=self.reload_waiter_orders).pack(side='right', padx=6)
# Filter status
filter_frame = ttk.Frame(parent)
filter_frame.pack(fill='x', padx=10, pady=6)
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)).pack(side='left', padx=3)
ttk.Button(filter_frame, text="Pending", command=lambda: self.reload_waiter_orders('pending')).pack(side='left', padx=3)
ttk.Button(filter_frame, text="Menunggu", command=lambda: self.reload_waiter_orders('menunggu')).pack(side='left', padx=3)
ttk.Button(filter_frame, text="Diproses", command=lambda: self.reload_waiter_orders('diproses')).pack(side='left', padx=3)
ttk.Button(filter_frame, text="Selesai", command=lambda: self.reload_waiter_orders('selesai')).pack(side='left', padx=3)
# Treeview pesanan
cols = ("ID", "User ID", "No.Meja", "Total", "Status", "Promo", "Tanggal")
self.waiter_tree = ttk.Treeview(parent, columns=cols, show='headings', height=12)
self.waiter_tree.heading("ID", text="ID")
self.waiter_tree.heading("User ID", text="User ID")
self.waiter_tree.heading("No.Meja", text="No.Meja")
self.waiter_tree.heading("Total", text="Total")
self.waiter_tree.heading("Status", text="Status")
self.waiter_tree.heading("Promo", text="Promo")
self.waiter_tree.heading("Tanggal", text="Tanggal")
self.waiter_tree.column("ID", width=40)
self.waiter_tree.column("User ID", width=60)
self.waiter_tree.column("No.Meja", width=70)
self.waiter_tree.column("Total", width=100)
self.waiter_tree.column("Status", width=90)
self.waiter_tree.column("Promo", width=80)
self.waiter_tree.column("Tanggal", width=140)
self.waiter_tree.pack(fill='both', expand=True, padx=10, pady=6)
# Detail pesanan (muncul saat pilih row)
detail_frame = ttk.LabelFrame(parent, text="Detail Pesanan", padding=10)
detail_frame.pack(fill='x', padx=10, pady=6)
self.waiter_detail_text = tk.Text(detail_frame, height=8, width=80)
self.waiter_detail_text.pack(fill='both', expand=True)
# Bind event saat pilih pesanan
self.waiter_tree.bind("<<TreeviewSelect>>", self.on_waiter_select)
# Tombol aksi
action_frame = ttk.Frame(parent)
action_frame.pack(pady=10)
ttk.Button(action_frame, text="✅ Terima Pesanan (Pending → Menunggu)",
command=lambda: self.update_order_status('menunggu'),
width=35).pack(pady=3)
ttk.Button(action_frame, text="🍳 Proses Pesanan (Menunggu → Diproses)",
command=lambda: self.update_order_status('diproses'),
width=35).pack(pady=3)
ttk.Button(action_frame, text="🍽️ Selesai Disajikan (Diproses → Selesai)",
command=lambda: self.update_order_status('selesai'),
width=35).pack(pady=3)
ttk.Button(action_frame, text="💰 Selesai Dilayani (Selesai → Dibayar)",
command=lambda: self.update_order_status('dibayar'),
width=35).pack(pady=3)
# Load data
self.reload_waiter_orders()
def reload_waiter_orders(self, status_filter=None):
"""Load pesanan untuk waiter"""
# Clear tree
for r in self.waiter_tree.get_children():
self.waiter_tree.delete(r)
# Get transaksi
if status_filter:
orders = transaksi_list(status=status_filter)
else:
# Tampilkan semua kecuali yang sudah dibayar
all_orders = transaksi_list()
orders = [o for o in all_orders if o[4] != 'dibayar']
# Insert ke tree
for order in orders:
tid, uid, meja, total, status, promo_code, tanggal = order
promo_display = promo_code if promo_code else "-"
self.waiter_tree.insert("", tk.END, values=(
tid, uid, meja, f"Rp {total:,.0f}", status, promo_display, tanggal
))
def on_waiter_select(self, event):
"""Tampilkan detail pesanan saat dipilih"""
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
# Get detail items
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
# Get nama menu
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)
def update_order_status(self, new_status):
"""Update status pesanan yang dipilih"""
sel = self.waiter_tree.selection()
if not sel:
messagebox.showwarning("Pilih Pesanan", "Pilih pesanan terlebih dahulu")
return
item = self.waiter_tree.item(sel)['values']
transaksi_id = item[0]
current_status = item[4]
# Validasi flow status
valid_transitions = {
'pending': ['menunggu'],
'menunggu': ['diproses'],
'diproses': ['selesai'],
'selesai': ['dibayar']
}
if current_status not in valid_transitions:
messagebox.showerror("Error", f"Status '{current_status}' tidak bisa diubah lagi")
return
if new_status not in valid_transitions[current_status]:
messagebox.showwarning("Invalid",
f"Tidak bisa ubah dari '{current_status}' ke '{new_status}'.\n"
f"Status berikutnya: {', '.join(valid_transitions[current_status])}")
return
# Konfirmasi
if not messagebox.askyesno("Konfirmasi",
f"Ubah status pesanan #{transaksi_id}\n"
f"dari '{current_status}' ke '{new_status}'?"):
return
# Update status
success = transaksi_update_status(transaksi_id, new_status)
if success:
messagebox.showinfo("Sukses", f"Status diubah menjadi '{new_status}'")
self.reload_waiter_orders()
else:
messagebox.showerror("Error", "Gagal update status")

View File

@ -1,5 +1,5 @@
id,nama,kategori,harga,stok,foto,tersedia,item_discount_pct
1,Americano,Minuman,20000,10,,1,0
2,Latte,Minuman,25000,2,,1,10
3,Banana Cake,Dessert,30000,1,,1,0
1,Americano,Minuman,20000,8,,1,0
2,Latte,Minuman,25000,1,,1,10
3,Banana Cake,Dessert,30000,0,,0,0
4,Nasi Goreng,Makanan,35000,0,,0,0

1 id nama kategori harga stok foto tersedia item_discount_pct
2 1 Americano Minuman 20000 10 8 1 0
3 2 Latte Minuman 25000 2 1 1 10
4 3 Banana Cake Dessert 30000 1 0 1 0 0
5 4 Nasi Goreng Makanan 35000 0 0 0