Compare commits

..

No commits in common. "85e501b1090671b2d7429be430ecb4092374c25c" and "785c873eda0691a7fb9ae8c3f45ed84c7585b151" have entirely different histories.

21 changed files with 690 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

126
project/admin_menu.py Normal file
View File

@ -0,0 +1,126 @@
import tkinter as tk
from tkinter import messagebox, filedialog
from database import connect
import os
import shutil
class AdminPage(tk.Frame): # Ganti nama class jadi AdminPage
def __init__(self, parent, controller):
super().__init__(parent)
self.controller = controller
self.selected_image_path = None
# --- Header ---
top = tk.Frame(self, bg="#333")
top.pack(fill="x")
tk.Label(top, text="ADMIN DASHBOARD", font=("Arial", 16, "bold"), fg="white", bg="#333").pack(side="left", padx=10, pady=10)
tk.Button(top, text="Logout", bg="#ff6b6b", command=lambda: self.controller.show_frame("LoginPage")).pack(side="right", padx=10)
# --- Form Input (Kiri) ---
left_frame = tk.Frame(self, padx=10, pady=10)
left_frame.pack(side="left", fill="y")
tk.Label(left_frame, text="Nama Menu:").pack(anchor="w")
self.entry_nama = tk.Entry(left_frame, width=30)
self.entry_nama.pack(pady=5)
tk.Label(left_frame, text="Harga:").pack(anchor="w")
self.entry_harga = tk.Entry(left_frame, width=30)
self.entry_harga.pack(pady=5)
tk.Label(left_frame, text="Stok Awal:").pack(anchor="w")
self.entry_stok = tk.Entry(left_frame, width=30)
self.entry_stok.pack(pady=5)
tk.Label(left_frame, text="Gambar:").pack(anchor="w")
self.btn_img = tk.Button(left_frame, text="Pilih Gambar", command=self.browse_image)
self.btn_img.pack(pady=5, anchor="w")
self.lbl_img_path = tk.Label(left_frame, text="Belum ada gambar", fg="gray", font=("Arial", 8))
self.lbl_img_path.pack(anchor="w")
# Tombol Aksi
btn_box = tk.Frame(left_frame, pady=20)
btn_box.pack()
tk.Button(btn_box, text="TAMBAH", bg="#4CAF50", fg="white", command=self.add_menu).grid(row=0, column=0, padx=5)
tk.Button(btn_box, text="HAPUS", bg="#f44336", fg="white", command=self.delete_menu).grid(row=0, column=1, padx=5)
# --- Tabel Menu (Kanan) ---
right_frame = tk.Frame(self, padx=10, pady=10)
right_frame.pack(side="right", fill="both", expand=True)
tk.Label(right_frame, text="Daftar Menu Database:", font=("Arial", 10, "bold")).pack(anchor="w")
self.list_menu = tk.Listbox(right_frame)
self.list_menu.pack(fill="both", expand=True)
scrollbar = tk.Scrollbar(self.list_menu)
scrollbar.pack(side="right", fill="y")
self.list_menu.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=self.list_menu.yview)
def update_data(self):
self.list_menu.delete(0, tk.END)
self.data_menu = []
db = connect()
cur = db.cursor()
cur.execute("SELECT id, nama, harga, stok FROM menu")
rows = cur.fetchall()
db.close()
for row in rows:
self.data_menu.append(row)
self.list_menu.insert(tk.END, f"{row[1]} - Rp {int(row[2])} (Stok: {row[3]})")
def browse_image(self):
filename = filedialog.askopenfilename(title="Pilih Gambar", filetypes=[("Image Files", "*.png;*.jpg;*.jpeg")])
if filename:
self.selected_image_path = filename
self.lbl_img_path.config(text=os.path.basename(filename), fg="black")
def add_menu(self):
nama = self.entry_nama.get()
harga = self.entry_harga.get()
stok = self.entry_stok.get()
if not nama or not harga:
messagebox.showwarning("Warning", "Nama dan Harga wajib diisi!")
return
final_image_path = "default.png"
if self.selected_image_path:
if not os.path.exists("img"): os.makedirs("img")
nama_file_asli = os.path.basename(self.selected_image_path)
destinasi = os.path.join("img", nama_file_asli)
shutil.copy(self.selected_image_path, destinasi)
final_image_path = destinasi
db = connect()
cur = db.cursor()
try:
cur.execute("INSERT INTO menu (nama, harga, stok, gambar) VALUES (?, ?, ?, ?)",
(nama, harga, stok if stok else 0, final_image_path))
db.commit()
messagebox.showinfo("Sukses", "Menu berhasil ditambahkan!")
self.entry_nama.delete(0, tk.END)
self.entry_harga.delete(0, tk.END)
self.entry_stok.delete(0, tk.END)
self.update_data()
except Exception as e:
messagebox.showerror("Error", str(e))
finally:
db.close()
def delete_menu(self):
idx = self.list_menu.curselection()
if not idx:
messagebox.showwarning("Pilih", "Pilih menu dulu!")
return
id_menu = self.data_menu[idx[0]][0]
if messagebox.askyesno("Hapus", "Yakin hapus menu ini?"):
db = connect()
db.cursor().execute("DELETE FROM menu WHERE id=?", (id_menu,))
db.commit()
db.close()
self.update_data()

74
project/database.py Normal file
View File

@ -0,0 +1,74 @@
import sqlite3
def connect():
return sqlite3.connect("cafe.db")
def setup_database():
db = connect()
cur = db.cursor()
# 1. Users
cur.execute("""
CREATE TABLE IF NOT EXISTS users(
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT,
password TEXT,
role TEXT
)
""")
# 2. Menu
cur.execute("""
CREATE TABLE IF NOT EXISTS menu(
id INTEGER PRIMARY KEY AUTOINCREMENT,
nama TEXT,
kategori TEXT,
harga REAL,
stok INTEGER,
gambar TEXT
)
""")
# 3. Transaksi (Header)
cur.execute("""
CREATE TABLE IF NOT EXISTS transaksi(
id INTEGER PRIMARY KEY AUTOINCREMENT,
nama_pelanggan TEXT,
meja_id INTEGER,
tanggal TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
total REAL,
metode_pembayaran TEXT,
status TEXT DEFAULT 'Pending'
)
""")
# Status Flow: 'Pending' (Dipesan) -> 'Served' (Diantar Waiter) -> 'Paid' (Dibayar di Kasir)
# 4. Detail Transaksi
cur.execute("""
CREATE TABLE IF NOT EXISTS detail_transaksi(
id INTEGER PRIMARY KEY AUTOINCREMENT,
transaksi_id INTEGER,
menu_id INTEGER,
jumlah INTEGER,
subtotal REAL
)
""")
# Seeding Data User Dummy
cur.execute("SELECT COUNT(*) FROM users")
if cur.fetchone()[0] == 0:
users = [
("admin","admin","admin"),
("kasir","kasir","kasir"),
("pembeli","pembeli","pembeli"),
("pemilik","pemilik","pemilik"),
("waiter","waiter","waiter")
]
cur.executemany("INSERT INTO users(username,password,role) VALUES (?,?,?)", users)
db.commit()
db.close()
print("Database Ready bos!")
if __name__ == "__main__":
setup_database()

49
project/isi_menu.py Normal file
View File

@ -0,0 +1,49 @@
import sqlite3
import os
# PERHATIKAN: Ini harus setup_database, BUKAN init_db
from database import setup_database
def isi_data_awal():
# 1. Pastikan database dan tabel sudah dibuat
setup_database()
db_name = "cafe.db"
# 2. Cek folder aset
# Pastikan kamu punya folder bernama 'aset' dan di dalamnya ada gambar-gambarnya
if not os.path.exists("aset"):
print("❌ WADUH! Folder 'aset' gak ketemu. Pastikan nama folder di kiri adalah 'aset'.")
return
conn = sqlite3.connect(db_name)
cur = conn.cursor()
print("♻️ Membersihkan data lama...")
cur.execute("DELETE FROM menu")
cur.execute("DELETE FROM sqlite_sequence WHERE name='menu'") # Reset ID jadi 1
# 3. Data Menu (Path gambar pakai 'aset/')
menus = [
("Ayam Goreng", "Makanan", 15000, 20, "aset/ayam_goreng.jpg"),
("Bakso Urat", "Makanan", 12000, 15, "aset/bakso.jpg"),
("Mie Ayam", "Makanan", 10000, 25, "aset/mie_ayam.jpg"),
("Es Teh Manis", "Minuman", 3000, 50, "aset/es_teh.jpg"),
("Jus Jeruk", "Minuman", 5000, 30, "aset/jus_jeruk.jpg"),
]
print("📥 Sedang mengisi data menu...")
try:
cur.executemany("""
INSERT INTO menu (nama, kategori, harga, stok, gambar)
VALUES (?, ?, ?, ?, ?)
""", menus)
conn.commit()
print("✅ MANTAP! Data menu berhasil masuk. Sekarang jalankan main.py!")
except Exception as e:
print(f"❌ Error: {e}")
finally:
conn.close()
if __name__ == "__main__":
isi_data_awal()

62
project/kasir.py Normal file
View File

@ -0,0 +1,62 @@
import tkinter as tk
from tkinter import messagebox
from database import connect
class KasirPage(tk.Frame):
def __init__(self, parent, controller):
super().__init__(parent)
self.controller = controller
# Header
top = tk.Frame(self, bg="#ddd")
top.pack(fill="x")
tk.Button(top, text="Logout", command=lambda: controller.show_frame("LoginPage")).pack(side="right", padx=10, pady=5)
tk.Label(top, text="KASIR - PEMBAYARAN", font=("Arial", 16, "bold"), bg="#ddd").pack(side="left", padx=10)
# List
tk.Label(self, text="Tagihan Belum Bayar (Status: Served):", font=("Arial", 11)).pack(pady=10)
self.order_list = tk.Listbox(self, width=80, height=15)
self.order_list.pack(pady=5)
tk.Button(self, text="Refresh Data", command=self.update_data).pack(pady=5)
tk.Button(self, text="💰 PROSES BAYAR & LUNAS", bg="#81C784", height=2, command=self.bayar).pack(fill="x", padx=20, pady=20)
def update_data(self):
self.order_list.delete(0, tk.END)
self.data_orders = []
db = connect()
cur = db.cursor()
# Kasir melihat yang sudah diantar (Served) tapi belum bayar
cur.execute("SELECT id, nama_pelanggan, meja_id, total FROM transaksi WHERE status='Served'")
self.data_orders = cur.fetchall()
db.close()
for item in self.data_orders:
self.order_list.insert(tk.END, f"ID Transaksi: {item[0]} | Meja {item[2]} | {item[1]} | Tagihan: Rp {int(item[3]):,}")
def bayar(self):
idx = self.order_list.curselection()
if not idx:
messagebox.showwarning("Pilih", "Pilih tagihan dulu!")
return
selected = self.data_orders[idx[0]]
trans_id = selected[0]
total = selected[3]
# Konfirmasi
if not messagebox.askyesno("Konfirmasi", f"Terima pembayaran sebesar Rp {int(total):,}?"):
return
db = connect()
cur = db.cursor()
# Update status jadi 'Paid'
cur.execute("UPDATE transaksi SET status='Paid', metode_pembayaran='CASH' WHERE id=?", (trans_id,))
db.commit()
db.close()
messagebox.showinfo("Lunas", "Transaksi Selesai & Lunas!")
self.update_data()

61
project/login.py Normal file
View File

@ -0,0 +1,61 @@
import tkinter as tk
from tkinter import messagebox
from database import connect
# Pastikan import ini sesuai
from admin_menu import AdminPage
from pembeli_menu import PembeliPage
from kasir import KasirPage
from pemilik import PemilikPage
from waiter_dashboard import WaiterPage
class LoginPage(tk.Frame):
def __init__(self, parent, controller):
super().__init__(parent)
self.controller = controller
tk.Label(self, text="LOGIN SYSTEM", font=("Arial", 20, "bold")).pack(pady=40)
frame_login = tk.Frame(self)
frame_login.pack()
tk.Label(frame_login, text="Username:").pack()
self.user = tk.Entry(frame_login)
self.user.pack(pady=5)
tk.Label(frame_login, text="Password:").pack()
self.passw = tk.Entry(frame_login, show="*")
self.passw.pack(pady=5)
tk.Button(frame_login, text="LOGIN", command=self.login, width=20, bg="#2196F3", fg="white").pack(pady=20)
def login(self):
u = self.user.get()
p = self.passw.get()
db = connect()
cur = db.cursor()
cur.execute("SELECT role FROM users WHERE username=? AND password=?", (u, p))
res = cur.fetchone()
db.close()
if not res:
messagebox.showerror("Gagal", "Username/Password salah!")
return
role = res[0]
# Reset input
self.user.delete(0, tk.END)
self.passw.delete(0, tk.END)
# Redirect sesuai Role
if role == "admin":
self.controller.show_frame("AdminPage")
elif role == "pembeli":
self.controller.show_frame("PembeliPage")
elif role == "kasir":
self.controller.show_frame("KasirPage")
elif role == "pemilik":
self.controller.show_frame("PemilikPage")
elif role == "waiter":
self.controller.show_frame("WaiterPage")

44
project/main.py Normal file
View File

@ -0,0 +1,44 @@
import tkinter as tk
from database import setup_database
# Import class yang sudah kita benerin namanya
from login import LoginPage
from admin_menu import AdminPage
from pembeli_menu import PembeliPage
from kasir import KasirPage
from pemilik import PemilikPage
from waiter_dashboard import WaiterPage
class CafeApp(tk.Tk):
def __init__(self):
super().__init__()
self.title("Sistem Manajemen Kafe Python")
self.geometry("1000x700")
setup_database() # Auto bikin tabel
self.container = tk.Frame(self)
self.container.pack(side="top", fill="both", expand=True)
self.container.grid_rowconfigure(0, weight=1)
self.container.grid_columnconfigure(0, weight=1)
self.frames = {}
# Loop semua halaman
for F in (LoginPage, AdminPage, PembeliPage, KasirPage, PemilikPage, WaiterPage):
page_name = F.__name__
frame = F(parent=self.container, controller=self)
self.frames[page_name] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("LoginPage")
def show_frame(self, page_name):
frame = self.frames[page_name]
if hasattr(frame, "update_data"):
frame.update_data()
frame.tkraise()
if __name__ == "__main__":
app = CafeApp()
app.mainloop()

169
project/pembeli_menu.py Normal file
View File

@ -0,0 +1,169 @@
import tkinter as tk
from tkinter import messagebox, ttk
from database import connect
class PembeliPage(tk.Frame): # Ganti nama class jadi PembeliPage
def __init__(self, parent, controller):
super().__init__(parent)
self.controller = controller
self.cart = {}
self.nama_pelanggan = ""
self.no_meja = ""
self.login_frame = tk.Frame(self)
self.menu_frame = tk.Frame(self)
self.show_login_ui()
# --- UI 1: LOGIN PEMBELI ---
def show_login_ui(self):
self.menu_frame.pack_forget()
self.login_frame.pack(fill="both", expand=True)
for w in self.login_frame.winfo_children(): w.destroy()
tk.Label(self.login_frame, text="SELAMAT DATANG", font=("Arial", 20, "bold")).pack(pady=50)
box = tk.Frame(self.login_frame, bd=2, relief="groove", padx=20, pady=20)
box.pack()
tk.Label(box, text="Nama Anda:").pack(anchor="w")
self.entry_nama = tk.Entry(box, width=30)
self.entry_nama.pack(pady=5)
tk.Label(box, text="Nomor Meja:").pack(anchor="w")
self.combo_meja = ttk.Combobox(box, values=[str(i) for i in range(1, 21)], state="readonly")
self.combo_meja.current(0)
self.combo_meja.pack(pady=5)
tk.Button(box, text="MULAI PESAN", bg="#4CAF50", fg="white", command=self.validate_login).pack(pady=20, fill="x")
tk.Button(self.login_frame, text="Kembali", command=lambda: self.controller.show_frame("LoginPage")).pack(pady=10)
def validate_login(self):
if not self.entry_nama.get():
messagebox.showwarning("Oops", "Nama wajib diisi!")
return
self.nama_pelanggan = self.entry_nama.get()
self.no_meja = self.combo_meja.get()
self.show_menu_ui()
# --- UI 2: MENU MAKANAN ---
def show_menu_ui(self):
self.login_frame.pack_forget()
self.menu_frame.pack(fill="both", expand=True)
# Bersihkan frame lama biar gak numpuk
for w in self.menu_frame.winfo_children(): w.destroy()
# Header
top = tk.Frame(self.menu_frame, bg="#eee", pady=10)
top.pack(fill="x")
tk.Label(top, text=f"👤 {self.nama_pelanggan} | Meja {self.no_meja}", font=("Arial", 12)).pack(side="left", padx=20)
tk.Button(top, text="Keluar", bg="#ff6b6b", fg="white", command=self.logout).pack(side="right", padx=20)
content = tk.Frame(self.menu_frame)
content.pack(fill="both", expand=True, padx=10, pady=10)
# Kiri: Daftar Menu
left_frame = tk.LabelFrame(content, text=" Menu Tersedia ")
left_frame.pack(side="left", fill="both", expand=True)
canvas = tk.Canvas(left_frame)
scrollbar = tk.Scrollbar(left_frame, orient="vertical", command=canvas.yview)
self.scroll_frame = tk.Frame(canvas)
self.scroll_frame.bind("<Configure>", lambda e: canvas.configure(scrollregion=canvas.bbox("all")))
canvas.create_window((0, 0), window=self.scroll_frame, anchor="nw")
canvas.configure(yscrollcommand=scrollbar.set)
canvas.pack(side="left", fill="both", expand=True)
scrollbar.pack(side="right", fill="y")
# Kanan: Keranjang
right_frame = tk.LabelFrame(content, text=" Keranjang ")
right_frame.pack(side="right", fill="both", width=300, padx=5)
self.cart_list = tk.Listbox(right_frame)
self.cart_list.pack(fill="both", expand=True, padx=5, pady=5)
self.lbl_total = tk.Label(right_frame, text="Total: Rp 0", font=("Arial", 14, "bold"), fg="red")
self.lbl_total.pack(pady=5)
tk.Button(right_frame, text="PESAN SEKARANG", bg="green", fg="white", height=2, command=self.checkout).pack(fill="x", padx=5, pady=5)
self.load_menu_items()
def load_menu_items(self):
for w in self.scroll_frame.winfo_children(): w.destroy()
db = connect()
cur = db.cursor()
cur.execute("SELECT id, nama, harga, stok FROM menu WHERE stok > 0")
items = cur.fetchall()
db.close()
row, col = 0, 0
for item in items:
m_id, nama, harga, stok = item
card = tk.Frame(self.scroll_frame, bd=2, relief="ridge", padx=5, pady=5)
card.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
tk.Label(card, text=nama, font=("Arial", 10, "bold")).pack()
tk.Label(card, text=f"Rp {int(harga):,}", fg="green").pack()
tk.Button(card, text="Tambah +", command=lambda i=m_id, n=nama, h=harga: self.add_to_cart(i, n, h)).pack(pady=2)
col += 1
if col > 2:
col = 0
row += 1
def add_to_cart(self, m_id, nama, harga):
if m_id in self.cart:
self.cart[m_id]['qty'] += 1
else:
self.cart[m_id] = {'nama': nama, 'harga': harga, 'qty': 1}
self.refresh_cart()
def refresh_cart(self):
self.cart_list.delete(0, tk.END)
total = 0
for m_id, item in self.cart.items():
sub = item['harga'] * item['qty']
total += sub
self.cart_list.insert(tk.END, f"{item['qty']}x {item['nama']} = {sub:,}")
self.lbl_total.config(text=f"Total: Rp {int(total):,}")
def checkout(self):
if not self.cart: return
total_val = int(self.lbl_total.cget("text").replace("Total: Rp ","").replace(",",""))
db = connect()
cur = db.cursor()
# Simpan ke tabel TRANSAKSI (Bukan orders)
cur.execute("INSERT INTO transaksi (nama_pelanggan, meja_id, total, status) VALUES (?, ?, ?, 'Pending')",
(self.nama_pelanggan, self.no_meja, total_val))
trans_id = cur.lastrowid
# Simpan Detail
for m_id, item in self.cart.items():
sub = item['harga'] * item['qty']
cur.execute("INSERT INTO detail_transaksi (transaksi_id, menu_id, jumlah, subtotal) VALUES (?,?,?,?)",
(trans_id, m_id, item['qty'], sub))
# Kurangi Stok
cur.execute("UPDATE menu SET stok = stok - ? WHERE id=?", (item['qty'], m_id))
db.commit()
db.close()
messagebox.showinfo("Sukses", "Pesanan terkirim! Mohon tunggu.")
self.cart = {}
self.refresh_cart()
self.load_menu_items()
def logout(self):
self.cart = {}
self.show_login_ui()
def update_data(self):
self.show_login_ui()

36
project/pemilik.py Normal file
View File

@ -0,0 +1,36 @@
import tkinter as tk
from database import connect
class PemilikPage(tk.Frame): # HARUS inherit tk.Frame
def __init__(self, parent, controller):
super().__init__(parent) # Init parent class
self.controller = controller
tk.Label(self, text="LAPORAN PENJUALAN (OWNER)", font=("Arial", 18, "bold")).pack(pady=20)
self.box = tk.Frame(self, bd=2, relief="groove", padx=40, pady=40)
self.box.pack()
# Label Total
self.total_lbl = tk.Label(self.box, text="Total Pendapatan: Rp 0", font=("Arial", 20, "bold"), fg="green")
self.total_lbl.pack(pady=10)
self.count_lbl = tk.Label(self.box, text="Jumlah Transaksi: 0", font=("Arial", 12))
self.count_lbl.pack(pady=5)
tk.Button(self, text="Refresh Laporan", bg="#cfe2ff", command=self.update_data).pack(pady=10)
tk.Button(self, text="Logout", bg="#f9e79f", command=lambda: controller.show_frame("LoginPage")).pack(pady=5)
def update_data(self):
db = connect()
cur = db.cursor()
# Hitung total dari transaksi yang statusnya 'Paid'
cur.execute("SELECT SUM(total), COUNT(id) FROM transaksi WHERE status='Paid'")
res = cur.fetchone()
db.close()
total_duit = res[0] if res[0] else 0
total_transaksi = res[1] if res[1] else 0
self.total_lbl.config(text=f"Total Pendapatan: Rp {int(total_duit):,}")
self.count_lbl.config(text=f"Jumlah Transaksi Sukses: {total_transaksi}")

10
project/project.css Normal file
View File

@ -0,0 +1,10 @@
project/
main.py
database.py
pembeli_menu.py
kasir_page.py
pemilik_page.py
mie ayam.webp
mie kuah.webp
es teh.webp
jus jeruk.webp

View File

@ -0,0 +1,59 @@
import tkinter as tk
from tkinter import messagebox
from database import connect
class WaiterPage(tk.Frame):
def __init__(self, parent, controller):
super().__init__(parent)
self.controller = controller
# Header
top = tk.Frame(self, bg="#FF9800")
top.pack(fill="x")
tk.Label(top, text="WAITER DASHBOARD", font=("Arial", 16, "bold"), bg="#FF9800", fg="white").pack(side="left", padx=10, pady=10)
tk.Button(top, text="Logout", command=lambda: controller.show_frame("LoginPage")).pack(side="right", padx=10)
# Content
tk.Label(self, text="Pesanan Pending (Perlu Diantar):", font=("Arial", 12)).pack(pady=10)
self.list_orders = tk.Listbox(self, width=80, height=15)
self.list_orders.pack(pady=5)
btn_frame = tk.Frame(self)
btn_frame.pack(pady=10)
tk.Button(btn_frame, text="Refresh", command=self.update_data).pack(side="left", padx=5)
tk.Button(btn_frame, text="✅ Selesai Diantar (Served)", bg="#81C784", command=self.mark_served).pack(side="left", padx=5)
def update_data(self):
self.list_orders.delete(0, tk.END)
self.data_orders = []
db = connect()
cur = db.cursor()
# Ambil transaksi yang statusnya 'Pending'
cur.execute("SELECT id, nama_pelanggan, meja_id, total FROM transaksi WHERE status='Pending'")
self.data_orders = cur.fetchall()
db.close()
for item in self.data_orders:
# item = (id, nama, meja, total)
self.list_orders.insert(tk.END, f"ID: {item[0]} | Meja: {item[2]} | A.N: {item[1]} | Total: Rp {int(item[3]):,}")
def mark_served(self):
idx = self.list_orders.curselection()
if not idx:
messagebox.showwarning("Pilih", "Pilih pesanan dulu!")
return
trans_id = self.data_orders[idx[0]][0]
db = connect()
cur = db.cursor()
# Update status jadi 'Served' biar muncul di Kasir
cur.execute("UPDATE transaksi SET status='Served' WHERE id=?", (trans_id,))
db.commit()
db.close()
messagebox.showinfo("Sukses", "Pesanan Meja ini sudah dilayani!")
self.update_data()