Merge branch 'main' of https://git-eng.ukwms.ac.id/5803025001/Python-Menu
This commit is contained in:
commit
2d2669361d
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.
@ -4,27 +4,21 @@ from database import connect
|
|||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
# GANTI NAMA CLASS JADI AdminPage
|
class AdminPage(tk.Frame): # Ganti nama class jadi AdminPage
|
||||||
class AdminPage(tk.Frame):
|
|
||||||
def __init__(self, parent, controller):
|
def __init__(self, parent, controller):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.selected_image_path = None
|
self.selected_image_path = None
|
||||||
self.data_menu = []
|
|
||||||
|
|
||||||
# --- Header ---
|
# --- Header ---
|
||||||
top = tk.Frame(self, bg="#333")
|
top = tk.Frame(self, bg="#333")
|
||||||
top.pack(fill="x")
|
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.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: controller.show_frame("LoginPage")).pack(side="right", padx=10)
|
tk.Button(top, text="Logout", bg="#ff6b6b", command=lambda: self.controller.show_frame("LoginPage")).pack(side="right", padx=10)
|
||||||
|
|
||||||
# --- Layout Kiri (Form) & Kanan (Tabel) ---
|
# --- Form Input (Kiri) ---
|
||||||
main_content = tk.Frame(self)
|
left_frame = tk.Frame(self, padx=10, pady=10)
|
||||||
main_content.pack(fill="both", expand=True, padx=10, pady=10)
|
left_frame.pack(side="left", fill="y")
|
||||||
|
|
||||||
# --- KIRI ---
|
|
||||||
left_frame = tk.Frame(main_content)
|
|
||||||
left_frame.pack(side="left", fill="y", padx=10)
|
|
||||||
|
|
||||||
tk.Label(left_frame, text="Nama Menu:").pack(anchor="w")
|
tk.Label(left_frame, text="Nama Menu:").pack(anchor="w")
|
||||||
self.entry_nama = tk.Entry(left_frame, width=30)
|
self.entry_nama = tk.Entry(left_frame, width=30)
|
||||||
@ -36,7 +30,6 @@ class AdminPage(tk.Frame):
|
|||||||
|
|
||||||
tk.Label(left_frame, text="Stok Awal:").pack(anchor="w")
|
tk.Label(left_frame, text="Stok Awal:").pack(anchor="w")
|
||||||
self.entry_stok = tk.Entry(left_frame, width=30)
|
self.entry_stok = tk.Entry(left_frame, width=30)
|
||||||
self.entry_stok.insert(0, "100") # Default stok
|
|
||||||
self.entry_stok.pack(pady=5)
|
self.entry_stok.pack(pady=5)
|
||||||
|
|
||||||
tk.Label(left_frame, text="Gambar:").pack(anchor="w")
|
tk.Label(left_frame, text="Gambar:").pack(anchor="w")
|
||||||
@ -45,16 +38,17 @@ class AdminPage(tk.Frame):
|
|||||||
self.lbl_img_path = tk.Label(left_frame, text="Belum ada gambar", fg="gray", font=("Arial", 8))
|
self.lbl_img_path = tk.Label(left_frame, text="Belum ada gambar", fg="gray", font=("Arial", 8))
|
||||||
self.lbl_img_path.pack(anchor="w")
|
self.lbl_img_path.pack(anchor="w")
|
||||||
|
|
||||||
|
# Tombol Aksi
|
||||||
btn_box = tk.Frame(left_frame, pady=20)
|
btn_box = tk.Frame(left_frame, pady=20)
|
||||||
btn_box.pack()
|
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="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)
|
tk.Button(btn_box, text="HAPUS", bg="#f44336", fg="white", command=self.delete_menu).grid(row=0, column=1, padx=5)
|
||||||
|
|
||||||
# --- KANAN ---
|
# --- Tabel Menu (Kanan) ---
|
||||||
right_frame = tk.Frame(main_content)
|
right_frame = tk.Frame(self, padx=10, pady=10)
|
||||||
right_frame.pack(side="right", fill="both", expand=True)
|
right_frame.pack(side="right", fill="both", expand=True)
|
||||||
|
|
||||||
tk.Label(right_frame, text="Daftar Menu:", font=("Arial", 10, "bold")).pack(anchor="w")
|
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 = tk.Listbox(right_frame)
|
||||||
self.list_menu.pack(fill="both", expand=True)
|
self.list_menu.pack(fill="both", expand=True)
|
||||||
@ -79,7 +73,7 @@ class AdminPage(tk.Frame):
|
|||||||
self.list_menu.insert(tk.END, f"{row[1]} - Rp {int(row[2])} (Stok: {row[3]})")
|
self.list_menu.insert(tk.END, f"{row[1]} - Rp {int(row[2])} (Stok: {row[3]})")
|
||||||
|
|
||||||
def browse_image(self):
|
def browse_image(self):
|
||||||
filename = filedialog.askopenfilename(title="Pilih Gambar", filetypes=[("Images", "*.png;*.jpg;*.jpeg")])
|
filename = filedialog.askopenfilename(title="Pilih Gambar", filetypes=[("Image Files", "*.png;*.jpg;*.jpeg")])
|
||||||
if filename:
|
if filename:
|
||||||
self.selected_image_path = filename
|
self.selected_image_path = filename
|
||||||
self.lbl_img_path.config(text=os.path.basename(filename), fg="black")
|
self.lbl_img_path.config(text=os.path.basename(filename), fg="black")
|
||||||
@ -96,20 +90,21 @@ class AdminPage(tk.Frame):
|
|||||||
final_image_path = "default.png"
|
final_image_path = "default.png"
|
||||||
if self.selected_image_path:
|
if self.selected_image_path:
|
||||||
if not os.path.exists("img"): os.makedirs("img")
|
if not os.path.exists("img"): os.makedirs("img")
|
||||||
destinasi = os.path.join("img", os.path.basename(self.selected_image_path))
|
nama_file_asli = os.path.basename(self.selected_image_path)
|
||||||
try:
|
destinasi = os.path.join("img", nama_file_asli)
|
||||||
shutil.copy(self.selected_image_path, destinasi)
|
shutil.copy(self.selected_image_path, destinasi)
|
||||||
final_image_path = destinasi
|
final_image_path = destinasi
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
db = connect()
|
db = connect()
|
||||||
cur = db.cursor()
|
cur = db.cursor()
|
||||||
try:
|
try:
|
||||||
cur.execute("INSERT INTO menu (nama, harga, stok, gambar) VALUES (?, ?, ?, ?)",
|
cur.execute("INSERT INTO menu (nama, harga, stok, gambar) VALUES (?, ?, ?, ?)",
|
||||||
(nama, harga, stok, final_image_path))
|
(nama, harga, stok if stok else 0, final_image_path))
|
||||||
db.commit()
|
db.commit()
|
||||||
messagebox.showinfo("Sukses", "Menu berhasil ditambahkan!")
|
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()
|
self.update_data()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
messagebox.showerror("Error", str(e))
|
messagebox.showerror("Error", str(e))
|
||||||
@ -118,12 +113,14 @@ class AdminPage(tk.Frame):
|
|||||||
|
|
||||||
def delete_menu(self):
|
def delete_menu(self):
|
||||||
idx = self.list_menu.curselection()
|
idx = self.list_menu.curselection()
|
||||||
if not idx: return
|
if not idx:
|
||||||
|
messagebox.showwarning("Pilih", "Pilih menu dulu!")
|
||||||
|
return
|
||||||
|
|
||||||
selected = self.data_menu[idx[0]]
|
id_menu = self.data_menu[idx[0]][0]
|
||||||
if messagebox.askyesno("Hapus", f"Hapus {selected[1]}?"):
|
if messagebox.askyesno("Hapus", "Yakin hapus menu ini?"):
|
||||||
db = connect()
|
db = connect()
|
||||||
db.cursor().execute("DELETE FROM menu WHERE id=?", (selected[0],))
|
db.cursor().execute("DELETE FROM menu WHERE id=?", (id_menu,))
|
||||||
db.commit()
|
db.commit()
|
||||||
db.close()
|
db.close()
|
||||||
self.update_data()
|
self.update_data()
|
||||||
@ -1,4 +1,3 @@
|
|||||||
# File: database.py
|
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
|
||||||
def connect():
|
def connect():
|
||||||
@ -30,7 +29,7 @@ def setup_database():
|
|||||||
)
|
)
|
||||||
""")
|
""")
|
||||||
|
|
||||||
# 3. Transaksi
|
# 3. Transaksi (Header)
|
||||||
cur.execute("""
|
cur.execute("""
|
||||||
CREATE TABLE IF NOT EXISTS transaksi(
|
CREATE TABLE IF NOT EXISTS transaksi(
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
@ -42,6 +41,7 @@ def setup_database():
|
|||||||
status TEXT DEFAULT 'Pending'
|
status TEXT DEFAULT 'Pending'
|
||||||
)
|
)
|
||||||
""")
|
""")
|
||||||
|
# Status Flow: 'Pending' (Dipesan) -> 'Served' (Diantar Waiter) -> 'Paid' (Dibayar di Kasir)
|
||||||
|
|
||||||
# 4. Detail Transaksi
|
# 4. Detail Transaksi
|
||||||
cur.execute("""
|
cur.execute("""
|
||||||
@ -54,7 +54,7 @@ def setup_database():
|
|||||||
)
|
)
|
||||||
""")
|
""")
|
||||||
|
|
||||||
# Seeding User (Kalau kosong diisi default)
|
# Seeding Data User Dummy
|
||||||
cur.execute("SELECT COUNT(*) FROM users")
|
cur.execute("SELECT COUNT(*) FROM users")
|
||||||
if cur.fetchone()[0] == 0:
|
if cur.fetchone()[0] == 0:
|
||||||
users = [
|
users = [
|
||||||
@ -68,7 +68,7 @@ def setup_database():
|
|||||||
|
|
||||||
db.commit()
|
db.commit()
|
||||||
db.close()
|
db.close()
|
||||||
print("Database Ready!")
|
print("Database Ready bos!")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
setup_database()
|
setup_database()
|
||||||
@ -1,32 +1,49 @@
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
|
import os
|
||||||
|
# PERHATIKAN: Ini harus setup_database, BUKAN init_db
|
||||||
|
from database import setup_database
|
||||||
|
|
||||||
def isi_data_awal():
|
def isi_data_awal():
|
||||||
conn = sqlite3.connect("cafe.db")
|
# 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()
|
cur = conn.cursor()
|
||||||
|
|
||||||
# Hapus data lama biar gak dobel (opsional, biar bersih)
|
print("♻️ Membersihkan data lama...")
|
||||||
cur.execute("DELETE FROM menu")
|
cur.execute("DELETE FROM menu")
|
||||||
|
cur.execute("DELETE FROM sqlite_sequence WHERE name='menu'") # Reset ID jadi 1
|
||||||
|
|
||||||
# Data Menu (Sesuaikan nama file gambar dengan yang ada di folder aset kamu)
|
# 3. Data Menu (Path gambar pakai 'aset/')
|
||||||
menus = [
|
menus = [
|
||||||
# (Nama, Kategori, Harga, Stok, Nama File Gambar)
|
("Ayam Goreng", "Makanan", 15000, 20, "aset/ayam_goreng.jpg"),
|
||||||
("Ayam Goreng", "Makanan", 15000, 20, "ayam_goreng.jpg"),
|
("Bakso Urat", "Makanan", 12000, 15, "aset/bakso.jpg"),
|
||||||
("Bakso Urat", "Makanan", 12000, 15, "bakso.jpg"),
|
("Mie Ayam", "Makanan", 10000, 25, "aset/mie_ayam.jpg"),
|
||||||
("Mie Ayam", "Makanan", 10000, 25, "mie_ayam.jpg"),
|
("Es Teh Manis", "Minuman", 3000, 50, "aset/es_teh.jpg"),
|
||||||
("Es Teh Manis", "Minuman", 3000, 50, "es_teh.jpg"),
|
("Jus Jeruk", "Minuman", 5000, 30, "aset/jus_jeruk.jpg"),
|
||||||
("Jus Jeruk", "Minuman", 5000, 30, "jus_jeruk.jpg"),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
print("Sedang mengisi data menu...")
|
print("📥 Sedang mengisi data menu...")
|
||||||
|
|
||||||
|
try:
|
||||||
cur.executemany("""
|
cur.executemany("""
|
||||||
INSERT INTO menu (nama, kategori, harga, stok, gambar)
|
INSERT INTO menu (nama, kategori, harga, stok, gambar)
|
||||||
VALUES (?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?)
|
||||||
""", menus)
|
""", menus)
|
||||||
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
print("✅ MANTAP! Data menu berhasil masuk. Sekarang jalankan main.py!")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Error: {e}")
|
||||||
|
finally:
|
||||||
conn.close()
|
conn.close()
|
||||||
print("✅ Berhasil! Data menu sudah masuk database.")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
isi_data_awal()
|
isi_data_awal()
|
||||||
@ -13,13 +13,13 @@ class KasirPage(tk.Frame):
|
|||||||
tk.Button(top, text="Logout", command=lambda: controller.show_frame("LoginPage")).pack(side="right", padx=10, pady=5)
|
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)
|
tk.Label(top, text="KASIR - PEMBAYARAN", font=("Arial", 16, "bold"), bg="#ddd").pack(side="left", padx=10)
|
||||||
|
|
||||||
# List Order
|
# List
|
||||||
tk.Label(self, text="Tagihan Belum Lunas (Status: Served):", font=("Arial", 11)).pack(pady=10)
|
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, font=("Arial", 10))
|
self.order_list = tk.Listbox(self, width=80, height=15)
|
||||||
self.order_list.pack(pady=5)
|
self.order_list.pack(pady=5)
|
||||||
|
|
||||||
tk.Button(self, text="Refresh Data", command=self.update_data).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=50, pady=20)
|
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):
|
def update_data(self):
|
||||||
self.order_list.delete(0, tk.END)
|
self.order_list.delete(0, tk.END)
|
||||||
@ -27,32 +27,33 @@ class KasirPage(tk.Frame):
|
|||||||
|
|
||||||
db = connect()
|
db = connect()
|
||||||
cur = db.cursor()
|
cur = db.cursor()
|
||||||
# Kasir melihat yang statusnya Served
|
# Kasir melihat yang sudah diantar (Served) tapi belum bayar
|
||||||
cur.execute("SELECT id, nama_pelanggan, meja_id, total FROM transaksi WHERE status='Served'")
|
cur.execute("SELECT id, nama_pelanggan, meja_id, total FROM transaksi WHERE status='Served'")
|
||||||
self.data_orders = cur.fetchall()
|
self.data_orders = cur.fetchall()
|
||||||
db.close()
|
db.close()
|
||||||
|
|
||||||
for item in self.data_orders:
|
for item in self.data_orders:
|
||||||
self.order_list.insert(tk.END, f"ID: {item[0]} | Meja {item[2]} | {item[1]} | Tagihan: Rp {int(item[3])}")
|
self.order_list.insert(tk.END, f"ID Transaksi: {item[0]} | Meja {item[2]} | {item[1]} | Tagihan: Rp {int(item[3]):,}")
|
||||||
|
|
||||||
def bayar(self):
|
def bayar(self):
|
||||||
idx = self.order_list.curselection()
|
idx = self.order_list.curselection()
|
||||||
if not idx:
|
if not idx:
|
||||||
messagebox.showwarning("Pilih", "Pilih tagihan yang mau dibayar!")
|
messagebox.showwarning("Pilih", "Pilih tagihan dulu!")
|
||||||
return
|
return
|
||||||
|
|
||||||
selected = self.data_orders[idx[0]]
|
selected = self.data_orders[idx[0]]
|
||||||
transaksi_id = selected[0]
|
trans_id = selected[0]
|
||||||
nama = selected[1]
|
|
||||||
total = selected[3]
|
total = selected[3]
|
||||||
|
|
||||||
confirm = messagebox.askyesno("Konfirmasi", f"Terima pembayaran Rp {int(total)} dari {nama}?")
|
# Konfirmasi
|
||||||
if confirm:
|
if not messagebox.askyesno("Konfirmasi", f"Terima pembayaran sebesar Rp {int(total):,}?"):
|
||||||
|
return
|
||||||
|
|
||||||
db = connect()
|
db = connect()
|
||||||
cur = db.cursor()
|
cur = db.cursor()
|
||||||
|
|
||||||
# Update status jadi 'Paid' dan metode pembayaran (misal Cash default)
|
# Update status jadi 'Paid'
|
||||||
cur.execute("UPDATE transaksi SET status='Paid', metode_pembayaran='Cash' WHERE id=?", (transaksi_id,))
|
cur.execute("UPDATE transaksi SET status='Paid', metode_pembayaran='CASH' WHERE id=?", (trans_id,))
|
||||||
|
|
||||||
db.commit()
|
db.commit()
|
||||||
db.close()
|
db.close()
|
||||||
|
|||||||
@ -2,52 +2,57 @@ import tkinter as tk
|
|||||||
from tkinter import messagebox
|
from tkinter import messagebox
|
||||||
from database import connect
|
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):
|
class LoginPage(tk.Frame):
|
||||||
def __init__(self, parent, controller):
|
def __init__(self, parent, controller):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
|
|
||||||
# Center Content
|
tk.Label(self, text="LOGIN SYSTEM", font=("Arial", 20, "bold")).pack(pady=40)
|
||||||
center_frame = tk.Frame(self)
|
|
||||||
center_frame.place(relx=0.5, rely=0.5, anchor="center")
|
|
||||||
|
|
||||||
tk.Label(center_frame, text="LOGIN CAFE", font=("Arial", 20, "bold")).pack(pady=20)
|
frame_login = tk.Frame(self)
|
||||||
|
frame_login.pack()
|
||||||
|
|
||||||
tk.Label(center_frame, text="Username").pack(anchor="w")
|
tk.Label(frame_login, text="Username:").pack()
|
||||||
self.user = tk.Entry(center_frame, width=30)
|
self.user = tk.Entry(frame_login)
|
||||||
self.user.pack(pady=5)
|
self.user.pack(pady=5)
|
||||||
|
|
||||||
tk.Label(center_frame, text="Password").pack(anchor="w")
|
tk.Label(frame_login, text="Password:").pack()
|
||||||
self.passw = tk.Entry(center_frame, show="*", width=30)
|
self.passw = tk.Entry(frame_login, show="*")
|
||||||
self.passw.pack(pady=5)
|
self.passw.pack(pady=5)
|
||||||
|
|
||||||
tk.Button(center_frame, text="Login", bg="#4CAF50", fg="white", width=20, command=self.login).pack(pady=20)
|
tk.Button(frame_login, text="LOGIN", command=self.login, width=20, bg="#2196F3", fg="white").pack(pady=20)
|
||||||
|
|
||||||
def login(self):
|
def login(self):
|
||||||
username = self.user.get()
|
u = self.user.get()
|
||||||
password = self.passw.get()
|
p = self.passw.get()
|
||||||
|
|
||||||
db = connect()
|
db = connect()
|
||||||
cur = db.cursor()
|
cur = db.cursor()
|
||||||
cur.execute("SELECT role FROM users WHERE username=? AND password=?", (username, password))
|
cur.execute("SELECT role FROM users WHERE username=? AND password=?", (u, p))
|
||||||
res = cur.fetchone()
|
res = cur.fetchone()
|
||||||
db.close()
|
db.close()
|
||||||
|
|
||||||
if not res:
|
if not res:
|
||||||
messagebox.showerror("Error", "Username/Password salah!")
|
messagebox.showerror("Gagal", "Username/Password salah!")
|
||||||
return
|
return
|
||||||
|
|
||||||
role = res[0]
|
role = res[0]
|
||||||
|
|
||||||
# Reset input
|
# Reset input
|
||||||
self.user.delete(0, tk.END)
|
self.user.delete(0, tk.END)
|
||||||
self.passw.delete(0, tk.END)
|
self.passw.delete(0, tk.END)
|
||||||
|
|
||||||
# Arahkan sesuai Role (Nama Class harus sama dengan di main.py)
|
# Redirect sesuai Role
|
||||||
if role == "admin":
|
if role == "admin":
|
||||||
self.controller.show_frame("AdminPage")
|
self.controller.show_frame("AdminPage")
|
||||||
elif role == "pembeli":
|
elif role == "pembeli":
|
||||||
self.controller.show_frame("PembeliMenu")
|
self.controller.show_frame("PembeliPage")
|
||||||
elif role == "kasir":
|
elif role == "kasir":
|
||||||
self.controller.show_frame("KasirPage")
|
self.controller.show_frame("KasirPage")
|
||||||
elif role == "pemilik":
|
elif role == "pemilik":
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from database import setup_database
|
from database import setup_database
|
||||||
|
|
||||||
# Pastikan nama file dan nama class sesuai
|
# Import class yang sudah kita benerin namanya
|
||||||
from login import LoginPage
|
from login import LoginPage
|
||||||
from admin_menu import AdminPage # Class diganti jadi AdminPage di file admin_menu
|
from admin_menu import AdminPage
|
||||||
from pembeli_menu import PembeliMenu # Class tetap PembeliMenu
|
from pembeli_menu import PembeliPage
|
||||||
from kasir import KasirPage
|
from kasir import KasirPage
|
||||||
from pemilik import PemilikPage
|
from pemilik import PemilikPage
|
||||||
from waiter_dashboard import WaiterPage
|
from waiter_dashboard import WaiterPage
|
||||||
@ -12,10 +12,10 @@ from waiter_dashboard import WaiterPage
|
|||||||
class CafeApp(tk.Tk):
|
class CafeApp(tk.Tk):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.title("Sistem Manajemen Kafe")
|
self.title("Sistem Manajemen Kafe Python")
|
||||||
self.geometry("1000x700")
|
self.geometry("1000x700")
|
||||||
|
|
||||||
setup_database()
|
setup_database() # Auto bikin tabel
|
||||||
|
|
||||||
self.container = tk.Frame(self)
|
self.container = tk.Frame(self)
|
||||||
self.container.pack(side="top", fill="both", expand=True)
|
self.container.pack(side="top", fill="both", expand=True)
|
||||||
@ -24,8 +24,8 @@ class CafeApp(tk.Tk):
|
|||||||
|
|
||||||
self.frames = {}
|
self.frames = {}
|
||||||
|
|
||||||
# Loop semua class halaman
|
# Loop semua halaman
|
||||||
for F in (LoginPage, AdminPage, PembeliMenu, KasirPage, PemilikPage, WaiterPage):
|
for F in (LoginPage, AdminPage, PembeliPage, KasirPage, PemilikPage, WaiterPage):
|
||||||
page_name = F.__name__
|
page_name = F.__name__
|
||||||
frame = F(parent=self.container, controller=self)
|
frame = F(parent=self.container, controller=self)
|
||||||
self.frames[page_name] = frame
|
self.frames[page_name] = frame
|
||||||
|
|||||||
@ -1,177 +1,169 @@
|
|||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import messagebox, simpledialog
|
from tkinter import messagebox, ttk
|
||||||
from PIL import Image, ImageTk
|
|
||||||
import os
|
|
||||||
from database import connect
|
from database import connect
|
||||||
|
|
||||||
class PembeliMenu(tk.Frame):
|
class PembeliPage(tk.Frame): # Ganti nama class jadi PembeliPage
|
||||||
def __init__(self, parent, controller):
|
def __init__(self, parent, controller):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.keranjang = [] # List untuk simpan belanjaan sementara
|
self.cart = {}
|
||||||
self.image_refs = [] # Supaya gambar tidak hilang
|
self.nama_pelanggan = ""
|
||||||
|
self.no_meja = ""
|
||||||
|
|
||||||
# --- Layout Utama: Kiri (Menu) & Kanan (Keranjang) ---
|
self.login_frame = tk.Frame(self)
|
||||||
|
self.menu_frame = tk.Frame(self)
|
||||||
|
self.show_login_ui()
|
||||||
|
|
||||||
# 1. Frame Kiri (Daftar Menu)
|
# --- UI 1: LOGIN PEMBELI ---
|
||||||
self.left_frame = tk.Frame(self)
|
def show_login_ui(self):
|
||||||
self.left_frame.pack(side="left", fill="both", expand=True)
|
self.menu_frame.pack_forget()
|
||||||
|
self.login_frame.pack(fill="both", expand=True)
|
||||||
|
|
||||||
# Header Kiri
|
for w in self.login_frame.winfo_children(): w.destroy()
|
||||||
header = tk.Frame(self.left_frame, bg="#2c3e50", height=50)
|
|
||||||
header.pack(fill="x")
|
|
||||||
tk.Label(header, text="DAFTAR MENU", font=("Arial", 14, "bold"), fg="white", bg="#2c3e50").pack(pady=10)
|
|
||||||
|
|
||||||
# Canvas untuk Scroll Menu
|
tk.Label(self.login_frame, text="SELAMAT DATANG", font=("Arial", 20, "bold")).pack(pady=50)
|
||||||
self.canvas = tk.Canvas(self.left_frame)
|
|
||||||
self.scrollbar = tk.Scrollbar(self.left_frame, orient="vertical", command=self.canvas.yview)
|
|
||||||
self.scrollable_frame = tk.Frame(self.canvas)
|
|
||||||
|
|
||||||
self.scrollable_frame.bind("<Configure>", lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all")))
|
box = tk.Frame(self.login_frame, bd=2, relief="groove", padx=20, pady=20)
|
||||||
self.canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
|
box.pack()
|
||||||
self.canvas.configure(yscrollcommand=self.scrollbar.set)
|
|
||||||
|
|
||||||
self.canvas.pack(side="left", fill="both", expand=True)
|
tk.Label(box, text="Nama Anda:").pack(anchor="w")
|
||||||
self.scrollbar.pack(side="right", fill="y")
|
self.entry_nama = tk.Entry(box, width=30)
|
||||||
|
self.entry_nama.pack(pady=5)
|
||||||
|
|
||||||
# 2. Frame Kanan (Keranjang Belanja)
|
tk.Label(box, text="Nomor Meja:").pack(anchor="w")
|
||||||
self.right_frame = tk.Frame(self, bg="#ecf0f1", width=300)
|
self.combo_meja = ttk.Combobox(box, values=[str(i) for i in range(1, 21)], state="readonly")
|
||||||
self.right_frame.pack(side="right", fill="y")
|
self.combo_meja.current(0)
|
||||||
self.right_frame.pack_propagate(False) # Agar lebar tetap 300px
|
self.combo_meja.pack(pady=5)
|
||||||
|
|
||||||
tk.Label(self.right_frame, text="KERANJANG SAYA", font=("Arial", 12, "bold"), bg="#bdc3c7", pady=10).pack(fill="x")
|
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)
|
||||||
|
|
||||||
# Listbox Keranjang
|
def validate_login(self):
|
||||||
self.cart_listbox = tk.Listbox(self.right_frame, font=("Arial", 10))
|
if not self.entry_nama.get():
|
||||||
self.cart_listbox.pack(fill="both", expand=True, padx=10, pady=10)
|
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()
|
||||||
|
|
||||||
# Label Total Harga
|
# --- UI 2: MENU MAKANAN ---
|
||||||
self.total_label = tk.Label(self.right_frame, text="Total: Rp 0", font=("Arial", 14, "bold"), bg="#ecf0f1", fg="#e74c3c")
|
def show_menu_ui(self):
|
||||||
self.total_label.pack(pady=10)
|
self.login_frame.pack_forget()
|
||||||
|
self.menu_frame.pack(fill="both", expand=True)
|
||||||
|
|
||||||
# Tombol Aksi
|
# Bersihkan frame lama biar gak numpuk
|
||||||
tk.Button(self.right_frame, text="Hapus Item Terpilih", bg="#e67e22", fg="white", command=self.hapus_item).pack(fill="x", padx=10, pady=5)
|
for w in self.menu_frame.winfo_children(): w.destroy()
|
||||||
tk.Button(self.right_frame, text="CHECKOUT / BAYAR", bg="#27ae60", fg="white", font=("Arial", 10, "bold"), height=2, command=self.checkout).pack(fill="x", padx=10, pady=20)
|
|
||||||
tk.Button(self.right_frame, text="Kembali / Logout", command=lambda: controller.show_frame("LoginPage")).pack(pady=5)
|
|
||||||
|
|
||||||
def update_data(self):
|
# Header
|
||||||
"""Dipanggil saat halaman dibuka"""
|
top = tk.Frame(self.menu_frame, bg="#eee", pady=10)
|
||||||
self.load_menu()
|
top.pack(fill="x")
|
||||||
self.keranjang = [] # Reset keranjang tiap login baru
|
tk.Label(top, text=f"👤 {self.nama_pelanggan} | Meja {self.no_meja}", font=("Arial", 12)).pack(side="left", padx=20)
|
||||||
self.update_keranjang_ui()
|
tk.Button(top, text="Keluar", bg="#ff6b6b", fg="white", command=self.logout).pack(side="right", padx=20)
|
||||||
|
|
||||||
def load_menu(self):
|
content = tk.Frame(self.menu_frame)
|
||||||
# Bersihkan area menu
|
content.pack(fill="both", expand=True, padx=10, pady=10)
|
||||||
for widget in self.scrollable_frame.winfo_children():
|
|
||||||
widget.destroy()
|
# Kiri: Daftar Menu
|
||||||
self.image_refs.clear()
|
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()
|
db = connect()
|
||||||
cur = db.cursor()
|
cur = db.cursor()
|
||||||
cur.execute("SELECT * FROM menu")
|
cur.execute("SELECT id, nama, harga, stok FROM menu WHERE stok > 0")
|
||||||
items = cur.fetchall()
|
items = cur.fetchall()
|
||||||
db.close()
|
db.close()
|
||||||
|
|
||||||
columns = 3
|
row, col = 0, 0
|
||||||
for index, item in enumerate(items):
|
for item in items:
|
||||||
self.create_card(item, index, columns)
|
m_id, nama, harga, stok = item
|
||||||
|
card = tk.Frame(self.scroll_frame, bd=2, relief="ridge", padx=5, pady=5)
|
||||||
def create_card(self, item, index, columns):
|
|
||||||
id_menu, nama, kategori, harga, stok, file_gambar = item
|
|
||||||
row = index // columns
|
|
||||||
col = index % columns
|
|
||||||
|
|
||||||
card = tk.Frame(self.scrollable_frame, bd=2, relief="groove", bg="white")
|
|
||||||
card.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
|
card.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
|
||||||
|
|
||||||
# Load Gambar
|
tk.Label(card, text=nama, font=("Arial", 10, "bold")).pack()
|
||||||
path = os.path.join("aset", file_gambar)
|
tk.Label(card, text=f"Rp {int(harga):,}", fg="green").pack()
|
||||||
try:
|
tk.Button(card, text="Tambah +", command=lambda i=m_id, n=nama, h=harga: self.add_to_cart(i, n, h)).pack(pady=2)
|
||||||
img = Image.open(path).resize((120, 80), Image.Resampling.LANCZOS)
|
|
||||||
photo = ImageTk.PhotoImage(img)
|
|
||||||
self.image_refs.append(photo)
|
|
||||||
tk.Label(card, image=photo, bg="white").pack(pady=5)
|
|
||||||
except:
|
|
||||||
tk.Label(card, text="[No Image]", bg="#eee", height=4).pack(pady=5)
|
|
||||||
|
|
||||||
tk.Label(card, text=nama, font=("Arial", 10, "bold"), bg="white").pack()
|
col += 1
|
||||||
tk.Label(card, text=f"Rp {int(harga):,}", fg="green", bg="white").pack()
|
if col > 2:
|
||||||
|
col = 0
|
||||||
|
row += 1
|
||||||
|
|
||||||
# Tombol Tambah
|
def add_to_cart(self, m_id, nama, harga):
|
||||||
state = "normal" if stok > 0 else "disabled"
|
if m_id in self.cart:
|
||||||
text_btn = "Tambah" if stok > 0 else "Habis"
|
self.cart[m_id]['qty'] += 1
|
||||||
tk.Button(card, text=text_btn, bg="#3498db", fg="white", state=state,
|
else:
|
||||||
command=lambda: self.tambah_ke_keranjang(item)).pack(pady=5, padx=5, fill="x")
|
self.cart[m_id] = {'nama': nama, 'harga': harga, 'qty': 1}
|
||||||
|
self.refresh_cart()
|
||||||
|
|
||||||
def tambah_ke_keranjang(self, item):
|
def refresh_cart(self):
|
||||||
# item = (id, nama, kategori, harga, stok, gambar)
|
self.cart_list.delete(0, tk.END)
|
||||||
self.keranjang.append(item)
|
|
||||||
self.update_keranjang_ui()
|
|
||||||
|
|
||||||
def update_keranjang_ui(self):
|
|
||||||
self.cart_listbox.delete(0, tk.END)
|
|
||||||
total = 0
|
total = 0
|
||||||
for item in self.keranjang:
|
for m_id, item in self.cart.items():
|
||||||
nama = item[1]
|
sub = item['harga'] * item['qty']
|
||||||
harga = item[3]
|
total += sub
|
||||||
self.cart_listbox.insert(tk.END, f"{nama} - Rp {int(harga):,}")
|
self.cart_list.insert(tk.END, f"{item['qty']}x {item['nama']} = {sub:,}")
|
||||||
total += harga
|
self.lbl_total.config(text=f"Total: Rp {int(total):,}")
|
||||||
|
|
||||||
self.total_label.config(text=f"Total: Rp {int(total):,}")
|
|
||||||
|
|
||||||
def hapus_item(self):
|
|
||||||
selected = self.cart_listbox.curselection()
|
|
||||||
if not selected:
|
|
||||||
return
|
|
||||||
index = selected[0]
|
|
||||||
del self.keranjang[index]
|
|
||||||
self.update_keranjang_ui()
|
|
||||||
|
|
||||||
def checkout(self):
|
def checkout(self):
|
||||||
if not self.keranjang:
|
if not self.cart: return
|
||||||
messagebox.showwarning("Kosong", "Keranjang masih kosong!")
|
|
||||||
return
|
|
||||||
|
|
||||||
nama_pelanggan = simpledialog.askstring("Input", "Masukkan Nama Pelanggan:")
|
total_val = int(self.lbl_total.cget("text").replace("Total: Rp ","").replace(",",""))
|
||||||
if not nama_pelanggan: return
|
|
||||||
|
|
||||||
total_harga = sum(item[3] for item in self.keranjang)
|
|
||||||
|
|
||||||
# Simpan ke Database
|
|
||||||
db = connect()
|
db = connect()
|
||||||
cur = db.cursor()
|
cur = db.cursor()
|
||||||
|
|
||||||
try:
|
# Simpan ke tabel TRANSAKSI (Bukan orders)
|
||||||
# 1. Simpan Transaksi Utama
|
cur.execute("INSERT INTO transaksi (nama_pelanggan, meja_id, total, status) VALUES (?, ?, ?, 'Pending')",
|
||||||
cur.execute("""
|
(self.nama_pelanggan, self.no_meja, total_val))
|
||||||
INSERT INTO transaksi (nama_pelanggan, total, status)
|
trans_id = cur.lastrowid
|
||||||
VALUES (?, ?, 'Pending')
|
|
||||||
""", (nama_pelanggan, total_harga))
|
|
||||||
transaksi_id = cur.lastrowid
|
|
||||||
|
|
||||||
# 2. Simpan Detail Transaksi (Looping item di keranjang)
|
# Simpan Detail
|
||||||
for item in self.keranjang:
|
for m_id, item in self.cart.items():
|
||||||
menu_id = item[0]
|
sub = item['harga'] * item['qty']
|
||||||
harga = item[3]
|
cur.execute("INSERT INTO detail_transaksi (transaksi_id, menu_id, jumlah, subtotal) VALUES (?,?,?,?)",
|
||||||
# Masukkan ke detail
|
(trans_id, m_id, item['qty'], sub))
|
||||||
cur.execute("""
|
# Kurangi Stok
|
||||||
INSERT INTO detail_transaksi (transaksi_id, menu_id, jumlah, subtotal)
|
cur.execute("UPDATE menu SET stok = stok - ? WHERE id=?", (item['qty'], m_id))
|
||||||
VALUES (?, ?, 1, ?)
|
|
||||||
""", (transaksi_id, menu_id, harga))
|
|
||||||
|
|
||||||
# Kurangi Stok Menu
|
|
||||||
cur.execute("UPDATE menu SET stok = stok - 1 WHERE id = ?", (menu_id,))
|
|
||||||
|
|
||||||
db.commit()
|
db.commit()
|
||||||
messagebox.showinfo("Berhasil", "Pesanan berhasil dibuat! Silakan bayar di kasir.")
|
|
||||||
|
|
||||||
# Reset
|
|
||||||
self.keranjang = []
|
|
||||||
self.update_keranjang_ui()
|
|
||||||
self.load_menu() # Reload menu untuk update stok visual
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
db.rollback()
|
|
||||||
messagebox.showerror("Error", f"Gagal Checkout: {e}")
|
|
||||||
finally:
|
|
||||||
db.close()
|
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()
|
||||||
@ -1,43 +1,36 @@
|
|||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from database import connect
|
from database import connect
|
||||||
|
|
||||||
class PemilikPage(tk.Frame):
|
class PemilikPage(tk.Frame): # HARUS inherit tk.Frame
|
||||||
def __init__(self, parent, controller):
|
def __init__(self, parent, controller):
|
||||||
super().__init__(parent)
|
super().__init__(parent) # Init parent class
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
|
|
||||||
# --- PERBAIKAN: Baris self.pack() sudah DIHAPUS ---
|
tk.Label(self, text="LAPORAN PENJUALAN (OWNER)", font=("Arial", 18, "bold")).pack(pady=20)
|
||||||
# Kita tidak boleh packing diri sendiri karena main.py sudah mengatur posisi kita pakai Grid.
|
|
||||||
|
|
||||||
# Judul Halaman
|
self.box = tk.Frame(self, bd=2, relief="groove", padx=40, pady=40)
|
||||||
tk.Label(self, text="LAPORAN PENJUALAN", font=("Arial", 18, "bold")).pack(pady=20)
|
self.box.pack()
|
||||||
|
|
||||||
# Label Total
|
# Label Total
|
||||||
self.total_lbl = tk.Label(self, text="Total Pendapatan: Rp 0", font=("Arial", 20, "bold"), fg="green")
|
self.total_lbl = tk.Label(self.box, text="Total Pendapatan: Rp 0", font=("Arial", 20, "bold"), fg="green")
|
||||||
self.total_lbl.pack(pady=20)
|
self.total_lbl.pack(pady=10)
|
||||||
|
|
||||||
tk.Label(self, text="(Menghitung semua transaksi berstatus 'Paid')", fg="gray").pack()
|
self.count_lbl = tk.Label(self.box, text="Jumlah Transaksi: 0", font=("Arial", 12))
|
||||||
|
self.count_lbl.pack(pady=5)
|
||||||
|
|
||||||
# Tombol-tombol
|
tk.Button(self, text="Refresh Laporan", bg="#cfe2ff", command=self.update_data).pack(pady=10)
|
||||||
tk.Button(self, text="Refresh Laporan", bg="#cfe2ff", command=self.load).pack(pady=10)
|
tk.Button(self, text="Logout", bg="#f9e79f", command=lambda: controller.show_frame("LoginPage")).pack(pady=5)
|
||||||
tk.Button(self, text="Logout", bg="#f9e79f", command=lambda: controller.show_frame("LoginPage")).pack(pady=10)
|
|
||||||
|
|
||||||
def update_data(self):
|
def update_data(self):
|
||||||
"""Dipanggil otomatis saat halaman dibuka"""
|
|
||||||
self.load()
|
|
||||||
|
|
||||||
def load(self):
|
|
||||||
"""Ambil data total penjualan dari database"""
|
|
||||||
db = connect()
|
db = connect()
|
||||||
cur = db.cursor()
|
cur = db.cursor()
|
||||||
|
# Hitung total dari transaksi yang statusnya 'Paid'
|
||||||
# Hitung sum total dari transaksi yang sudah Paid (Lunas)
|
cur.execute("SELECT SUM(total), COUNT(id) FROM transaksi WHERE status='Paid'")
|
||||||
cur.execute("SELECT SUM(total) FROM transaksi WHERE status='Paid'")
|
res = cur.fetchone()
|
||||||
result = cur.fetchone()[0]
|
|
||||||
|
|
||||||
# Kalau belum ada penjualan, set 0
|
|
||||||
total = result if result else 0
|
|
||||||
db.close()
|
db.close()
|
||||||
|
|
||||||
# Update tampilan
|
total_duit = res[0] if res[0] else 0
|
||||||
self.total_lbl.config(text=f"Total Pendapatan: Rp {int(total):,}")
|
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}")
|
||||||
@ -13,16 +13,16 @@ class WaiterPage(tk.Frame):
|
|||||||
tk.Label(top, text="WAITER DASHBOARD", font=("Arial", 16, "bold"), bg="#FF9800", fg="white").pack(side="left", padx=10, pady=10)
|
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)
|
tk.Button(top, text="Logout", command=lambda: controller.show_frame("LoginPage")).pack(side="right", padx=10)
|
||||||
|
|
||||||
# List Pesanan
|
# Content
|
||||||
tk.Label(self, text="Pesanan Status: PENDING (Perlu Diantar)", font=("Arial", 12, "bold")).pack(pady=10)
|
tk.Label(self, text="Pesanan Pending (Perlu Diantar):", font=("Arial", 12)).pack(pady=10)
|
||||||
|
|
||||||
self.list_orders = tk.Listbox(self, width=80, height=15, font=("Arial", 10))
|
self.list_orders = tk.Listbox(self, width=80, height=15)
|
||||||
self.list_orders.pack(pady=5)
|
self.list_orders.pack(pady=5)
|
||||||
|
|
||||||
btn_frame = tk.Frame(self)
|
btn_frame = tk.Frame(self)
|
||||||
btn_frame.pack(pady=10)
|
btn_frame.pack(pady=10)
|
||||||
|
|
||||||
tk.Button(btn_frame, text="Refresh Data", command=self.update_data).pack(side="left", padx=5)
|
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)
|
tk.Button(btn_frame, text="✅ Selesai Diantar (Served)", bg="#81C784", command=self.mark_served).pack(side="left", padx=5)
|
||||||
|
|
||||||
def update_data(self):
|
def update_data(self):
|
||||||
@ -31,14 +31,14 @@ class WaiterPage(tk.Frame):
|
|||||||
|
|
||||||
db = connect()
|
db = connect()
|
||||||
cur = db.cursor()
|
cur = db.cursor()
|
||||||
# Ambil Transaksi yang statusnya Pending
|
# Ambil transaksi yang statusnya 'Pending'
|
||||||
cur.execute("SELECT id, nama_pelanggan, meja_id, total FROM transaksi WHERE status='Pending'")
|
cur.execute("SELECT id, nama_pelanggan, meja_id, total FROM transaksi WHERE status='Pending'")
|
||||||
self.data_orders = cur.fetchall()
|
self.data_orders = cur.fetchall()
|
||||||
db.close()
|
db.close()
|
||||||
|
|
||||||
for item in self.data_orders:
|
for item in self.data_orders:
|
||||||
# item: (id, nama, meja, total)
|
# item = (id, nama, meja, total)
|
||||||
self.list_orders.insert(tk.END, f"ID Transaksi: {item[0]} | Meja: {item[2]} | A.N: {item[1]} | Total: Rp {int(item[3])}")
|
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):
|
def mark_served(self):
|
||||||
idx = self.list_orders.curselection()
|
idx = self.list_orders.curselection()
|
||||||
@ -46,15 +46,14 @@ class WaiterPage(tk.Frame):
|
|||||||
messagebox.showwarning("Pilih", "Pilih pesanan dulu!")
|
messagebox.showwarning("Pilih", "Pilih pesanan dulu!")
|
||||||
return
|
return
|
||||||
|
|
||||||
selected = self.data_orders[idx[0]]
|
trans_id = self.data_orders[idx[0]][0]
|
||||||
transaksi_id = selected[0]
|
|
||||||
|
|
||||||
db = connect()
|
db = connect()
|
||||||
cur = db.cursor()
|
cur = db.cursor()
|
||||||
# Update Status Transaksi jadi Served
|
# Update status jadi 'Served' biar muncul di Kasir
|
||||||
cur.execute("UPDATE transaksi SET status='Served' WHERE id=?", (transaksi_id,))
|
cur.execute("UPDATE transaksi SET status='Served' WHERE id=?", (trans_id,))
|
||||||
db.commit()
|
db.commit()
|
||||||
db.close()
|
db.close()
|
||||||
|
|
||||||
messagebox.showinfo("Sukses", "Pesanan Meja selesai dilayani!")
|
messagebox.showinfo("Sukses", "Pesanan Meja ini sudah dilayani!")
|
||||||
self.update_data()
|
self.update_data()
|
||||||
Loading…
x
Reference in New Issue
Block a user