This commit is contained in:
Nathan 2025-12-15 04:23:49 +07:00
commit e5c6da3417
2 changed files with 103 additions and 122 deletions

BIN
project/aset/es_krim.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 KiB

View File

@ -1,10 +1,15 @@
import tkinter as tk import tkinter as tk
from tkinter import messagebox, ttk from tkinter import messagebox, ttk
from PIL import Image, ImageTk from PIL import Image, ImageTk
from database import connect import sqlite3
import datetime import datetime
import os import os
# ================= DATABASE CONNECT =================
def connect():
return sqlite3.connect("cafe.db")
# ================= PEMBELI MENU =================
class PembeliMenu: class PembeliMenu:
def __init__(self, parent): def __init__(self, parent):
self.parent = parent self.parent = parent
@ -14,10 +19,14 @@ class PembeliMenu:
self.cart = [] self.cart = []
self.images = [] self.images = []
# --- Header --- # ================= HEADER =================
tk.Label(self.frame, text="SELAMAT DATANG", font=("Arial", 18, "bold")).pack(pady=10) tk.Label(
self.frame,
text="SELAMAT DATANG",
font=("Arial", 18, "bold")
).pack(pady=10)
# --- INPUT DATA PELANGGAN --- # ================= INPUT DATA =================
info_frame = tk.Frame(self.frame, bd=2, relief="groove", padx=10, pady=10) info_frame = tk.Frame(self.frame, bd=2, relief="groove", padx=10, pady=10)
info_frame.pack(pady=5) info_frame.pack(pady=5)
@ -25,38 +34,56 @@ class PembeliMenu:
self.entry_nama = tk.Entry(info_frame) self.entry_nama = tk.Entry(info_frame)
self.entry_nama.grid(row=0, column=1, padx=5) self.entry_nama.grid(row=0, column=1, padx=5)
# --- LOGIKA MEJA ---
tk.Label(info_frame, text="Pilih Meja:").grid(row=0, column=2, sticky="e") tk.Label(info_frame, text="Pilih Meja:").grid(row=0, column=2, sticky="e")
self.meja_var = tk.StringVar() self.meja_var = tk.StringVar()
self.combo_meja = ttk.Combobox(info_frame, textvariable=self.meja_var, state="readonly", width=5) self.combo_meja = ttk.Combobox(
info_frame,
textvariable=self.meja_var,
state="readonly",
width=5
)
self.combo_meja.grid(row=0, column=3, padx=5) self.combo_meja.grid(row=0, column=3, padx=5)
tk.Button(info_frame, text="🔄", command=self.refresh_available_tables, bd=1).grid(row=0, column=4, padx=2) tk.Button(info_frame, text="🔄", command=self.refresh_available_tables).grid(row=0, column=4, padx=2)
self.refresh_available_tables() self.refresh_available_tables()
# Tombol Kembali # ================= CONTENT 2 KOLOM =================
tk.Button(self.frame, text="Kembali ke Utama", bg="#f9e79f", command=self.logout).pack(pady=5) content = tk.Frame(self.frame)
content.pack(fill="both", expand=True, padx=20, pady=10)
# --- Area Menu --- content.grid_columnconfigure(0, weight=3)
self.menu_frame = tk.Frame(self.frame) content.grid_columnconfigure(1, weight=1)
self.menu_frame.pack(pady=10, fill="both", expand=True)
# ================= MENU (KIRI) =================
self.menu_frame = tk.Frame(content)
self.menu_frame.grid(row=0, column=0, sticky="nw")
self.load_menu() self.load_menu()
# --- Keranjang Belanja --- # ================= KERANJANG (KANAN) =================
tk.Label(self.frame, text="Keranjang Pesanan:", font=("Arial", 10, "bold")).pack() cart_frame = tk.LabelFrame(
content,
text="Keranjang Pesanan",
font=("Arial", 11, "bold"),
padx=10,
pady=10
)
cart_frame.grid(row=0, column=1, sticky="ne")
self.listbox = tk.Listbox(self.frame, width=60, height=8, font=("Courier", 10)) self.listbox = tk.Listbox(cart_frame, width=35, height=10, font=("Courier", 10))
self.listbox.pack() self.listbox.pack(pady=5)
tk.Button(self.frame, text=" Kurangi / Hapus Item", fg="red", font=("Arial", 9), command=self.kurangi_item_cart).pack(pady=2) tk.Button(cart_frame, text=" Kurangi / Hapus Item", fg="red",
command=self.kurangi_item_cart).pack(pady=5)
self.total_lbl = tk.Label(self.frame, text="Total: Rp 0", font=("Arial", 12, "bold")) self.total_lbl = tk.Label(cart_frame, text="Total: Rp 0",
font=("Arial", 12, "bold"))
self.total_lbl.pack(pady=5) self.total_lbl.pack(pady=5)
tk.Button(self.frame, text="✅ KIRIM PESANAN", bg="#d1e7dd", font=("Arial", 11, "bold"), command=self.checkout).pack(pady=10) tk.Button(cart_frame, text="✅ KIRIM PESANAN", bg="#d1e7dd",
font=("Arial", 11, "bold"), command=self.checkout).pack(pady=10)
# ================= MEJA =================
def refresh_available_tables(self): def refresh_available_tables(self):
total_meja = [str(i) for i in range(1, 11)] total_meja = [str(i) for i in range(1, 11)]
db = connect() db = connect()
@ -66,14 +93,10 @@ class PembeliMenu:
db.close() db.close()
tersedia = [m for m in total_meja if m not in terisi] tersedia = [m for m in total_meja if m not in terisi]
self.combo_meja['values'] = tersedia if tersedia else ["Penuh"]
self.combo_meja.set(tersedia[0] if tersedia else "Penuh")
if not tersedia: # ================= MENU =================
self.combo_meja['values'] = ["Penuh"]
self.combo_meja.set("Penuh")
else:
self.combo_meja['values'] = tersedia
self.combo_meja.current(0)
def load_menu(self): def load_menu(self):
db = connect() db = connect()
cur = db.cursor() cur = db.cursor()
@ -81,127 +104,85 @@ class PembeliMenu:
data = cur.fetchall() data = cur.fetchall()
db.close() db.close()
row_frame = None columns = 4
for i, (nama, harga, gambar) in enumerate(data): for i, (nama, harga, gambar) in enumerate(data):
if i % 3 == 0: row, col = divmod(i, columns)
row_frame = tk.Frame(self.menu_frame) card = tk.Frame(self.menu_frame, width=180, height=220, bd=2, relief="ridge")
row_frame.pack() card.grid(row=row, column=col, padx=10, pady=10)
card.grid_propagate(False)
f = tk.Frame(row_frame, bd=2, relief="ridge", padx=5, pady=5)
f.pack(side=tk.LEFT, padx=5)
try: try:
if os.path.exists(gambar): filename = os.path.basename(gambar) if gambar else None
img = Image.open(gambar).resize((100, 80)) img_path = os.path.join("aset", filename) if filename else None
if img_path and os.path.exists(img_path):
img = Image.open(img_path).resize((140, 90))
photo = ImageTk.PhotoImage(img) photo = ImageTk.PhotoImage(img)
self.images.append(photo) self.images.append(photo)
tk.Label(f, image=photo).pack() tk.Label(card, image=photo).pack(pady=5)
else: else:
tk.Label(f, text="[No Image]").pack() tk.Label(card, text="[No Image]", height=6).pack()
except: except Exception:
tk.Label(f, text="Error Img").pack() tk.Label(card, text="Error Img", height=6).pack()
tk.Label(f, text=nama, font=("Arial",10,"bold")).pack() tk.Label(card, text=nama, font=("Arial", 10, "bold"), wraplength=160).pack()
tk.Label(f, text=f"Rp {harga:,.0f}").pack() tk.Label(card, text=f"Rp {harga:,.0f}").pack(pady=2)
tk.Button(f, text="Tambah", bg="#cfe2ff", command=lambda n=nama, h=harga: self.add_to_cart(n, h)).pack(pady=2)
tk.Button(card, text="Tambah", bg="#cfe2ff",
command=lambda n=nama, h=harga: self.add_to_cart(n, h)).pack(pady=5)
# ================= CART =================
def add_to_cart(self, nama, harga): def add_to_cart(self, nama, harga):
item_found = False
for item in self.cart: for item in self.cart:
if item['nama'] == nama: if item['nama'] == nama:
item['qty'] += 1 item['qty'] += 1
item['subtotal'] = item['qty'] * harga item['subtotal'] = item['qty'] * harga
item_found = True self.refresh_cart()
break return
self.cart.append({'nama': nama, 'harga_satuan': harga, 'qty': 1, 'subtotal': harga})
if not item_found:
self.cart.append({
'nama': nama,
'harga_satuan': harga,
'qty': 1,
'subtotal': harga
})
self.refresh_cart() self.refresh_cart()
def kurangi_item_cart(self): def kurangi_item_cart(self):
idx = self.listbox.curselection() if not self.listbox.curselection(): return
if not idx: idx = self.listbox.curselection()[0]
messagebox.showwarning("Peringatan", "Pilih menu yang mau dikurangi!") item = self.cart[idx]
return
index = idx[0]
item = self.cart[index]
# Kurangi jumlah
item['qty'] -= 1 item['qty'] -= 1
if item['qty'] <= 0:
if item['qty'] > 0: self.cart.pop(idx)
else:
item['subtotal'] = item['qty'] * item['harga_satuan'] item['subtotal'] = item['qty'] * item['harga_satuan']
self.refresh_cart() self.refresh_cart()
# AUTO-SELECT: Pilih kembali item yang sama
self.listbox.selection_set(index)
self.listbox.activate(index)
else:
self.cart.pop(index)
self.refresh_cart()
# AUTO-SELECT (Opsional): Pilih item yang menggantikan posisinya (jika ada)
if index < self.listbox.size():
self.listbox.selection_set(index)
self.listbox.activate(index)
def refresh_cart(self): def refresh_cart(self):
self.listbox.delete(0, tk.END) self.listbox.delete(0, tk.END)
total_belanja = 0 total = 0
for item in self.cart: for item in self.cart:
display_text = f"{item['nama']} (x{item['qty']}) - Rp {item['subtotal']:,.0f}" self.listbox.insert(tk.END, f"{item['nama']} (x{item['qty']}) - Rp {item['subtotal']:,.0f}")
self.listbox.insert(tk.END, display_text) total += item['subtotal']
total_belanja += item['subtotal'] self.total_lbl.config(text=f"Total: Rp {total:,.0f}")
self.total_lbl.config(text=f"Total: Rp {total_belanja:,.0f}")
# ================= CHECKOUT =================
def checkout(self): def checkout(self):
nama_pemesan = self.entry_nama.get() if not self.entry_nama.get() or not self.cart:
meja = self.combo_meja.get() messagebox.showwarning("Error", "Data belum lengkap")
if not nama_pemesan:
messagebox.showwarning("Data Kurang", "Mohon isi Nama Anda!")
return return
if not meja or meja == "Penuh": total = sum(item['subtotal'] for item in self.cart)
messagebox.showwarning("Penuh", "Mohon maaf, meja penuh atau belum dipilih.")
return
if not self.cart:
messagebox.showwarning("Kosong", "Pilih menu dulu!")
return
total_belanja = sum(item['subtotal'] for item in self.cart)
tanggal = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") tanggal = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
db = connect() db = connect()
cur = db.cursor() cur = db.cursor()
tanggal_custom = f"{tanggal} ({nama_pemesan})"
cur.execute("INSERT INTO transaksi (tanggal, total, meja_id, status) VALUES (?, ?, ?, ?)", cur.execute("INSERT INTO transaksi (tanggal, total, meja_id, status) VALUES (?, ?, ?, ?)",
(tanggal_custom, total_belanja, meja, "Pending")) (tanggal, total, self.combo_meja.get(), "Pending"))
transaksi_id = cur.lastrowid
for item in self.cart:
cur.execute("INSERT INTO detail_transaksi (transaksi_id, menu_nama, harga, jumlah, subtotal) VALUES (?, ?, ?, ?, ?)",
(transaksi_id, item['nama'], item['harga_satuan'], item['qty'], item['subtotal']))
db.commit() db.commit()
db.close() db.close()
messagebox.showinfo("Berhasil", f"Pesanan a.n {nama_pemesan} berhasil dikirim!") messagebox.showinfo("Berhasil", "Pesanan berhasil dikirim")
self.cart.clear() self.cart.clear()
self.refresh_cart() self.refresh_cart()
self.entry_nama.delete(0, tk.END)
self.refresh_available_tables()
def logout(self): # ================= RUN =================
self.frame.destroy() if __name__ == '__main__':
from main import LoginScreen root = tk.Tk()
LoginScreen(self.parent) root.title("Sistem Cafe Python")
root.geometry("1200x700")
PembeliMenu(root)
root.mainloop()