diff --git a/project/aset/es_krim.jpg b/project/aset/es_krim.jpg new file mode 100644 index 0000000..8efd080 Binary files /dev/null and b/project/aset/es_krim.jpg differ diff --git a/project/pembeli_menu.py b/project/pembeli_menu.py index 6dcad05..5962dda 100644 --- a/project/pembeli_menu.py +++ b/project/pembeli_menu.py @@ -1,23 +1,32 @@ import tkinter as tk from tkinter import messagebox, ttk from PIL import Image, ImageTk -from database import connect +import sqlite3 import datetime import os +# ================= DATABASE CONNECT ================= +def connect(): + return sqlite3.connect("cafe.db") + +# ================= PEMBELI MENU ================= class PembeliMenu: def __init__(self, parent): self.parent = parent self.frame = tk.Frame(parent) self.frame.pack(fill="both", expand=True) - - self.cart = [] - self.images = [] - # --- Header --- - tk.Label(self.frame, text="SELAMAT DATANG", font=("Arial", 18, "bold")).pack(pady=10) - - # --- INPUT DATA PELANGGAN --- + self.cart = [] + self.images = [] + + # ================= HEADER ================= + tk.Label( + self.frame, + text="SELAMAT DATANG", + font=("Arial", 18, "bold") + ).pack(pady=10) + + # ================= INPUT DATA ================= info_frame = tk.Frame(self.frame, bd=2, relief="groove", padx=10, pady=10) info_frame.pack(pady=5) @@ -25,38 +34,56 @@ class PembeliMenu: self.entry_nama = tk.Entry(info_frame) 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") - 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) - - 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() - # Tombol Kembali - tk.Button(self.frame, text="Kembali ke Utama", bg="#f9e79f", command=self.logout).pack(pady=5) + # ================= CONTENT 2 KOLOM ================= + content = tk.Frame(self.frame) + content.pack(fill="both", expand=True, padx=20, pady=10) - # --- Area Menu --- - self.menu_frame = tk.Frame(self.frame) - self.menu_frame.pack(pady=10, fill="both", expand=True) + content.grid_columnconfigure(0, weight=3) + content.grid_columnconfigure(1, weight=1) + + # ================= MENU (KIRI) ================= + self.menu_frame = tk.Frame(content) + self.menu_frame.grid(row=0, column=0, sticky="nw") self.load_menu() - # --- Keranjang Belanja --- - tk.Label(self.frame, text="Keranjang Pesanan:", font=("Arial", 10, "bold")).pack() - - self.listbox = tk.Listbox(self.frame, width=60, height=8, font=("Courier", 10)) - self.listbox.pack() + # ================= KERANJANG (KANAN) ================= + 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") - tk.Button(self.frame, text="➖ Kurangi / Hapus Item", fg="red", font=("Arial", 9), command=self.kurangi_item_cart).pack(pady=2) + self.listbox = tk.Listbox(cart_frame, width=35, height=10, font=("Courier", 10)) + self.listbox.pack(pady=5) - self.total_lbl = tk.Label(self.frame, text="Total: Rp 0", font=("Arial", 12, "bold")) + tk.Button(cart_frame, text="➖ Kurangi / Hapus Item", fg="red", + command=self.kurangi_item_cart).pack(pady=5) + + self.total_lbl = tk.Label(cart_frame, text="Total: Rp 0", + font=("Arial", 12, "bold")) 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): total_meja = [str(i) for i in range(1, 11)] db = connect() @@ -66,14 +93,10 @@ class PembeliMenu: db.close() 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: - self.combo_meja['values'] = ["Penuh"] - self.combo_meja.set("Penuh") - else: - self.combo_meja['values'] = tersedia - self.combo_meja.current(0) - + # ================= MENU ================= def load_menu(self): db = connect() cur = db.cursor() @@ -81,127 +104,85 @@ class PembeliMenu: data = cur.fetchall() db.close() - row_frame = None + columns = 4 for i, (nama, harga, gambar) in enumerate(data): - if i % 3 == 0: - row_frame = tk.Frame(self.menu_frame) - row_frame.pack() - - f = tk.Frame(row_frame, bd=2, relief="ridge", padx=5, pady=5) - f.pack(side=tk.LEFT, padx=5) + row, col = divmod(i, columns) + card = tk.Frame(self.menu_frame, width=180, height=220, bd=2, relief="ridge") + card.grid(row=row, column=col, padx=10, pady=10) + card.grid_propagate(False) try: - if os.path.exists(gambar): - img = Image.open(gambar).resize((100, 80)) + filename = os.path.basename(gambar) if gambar else None + 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) self.images.append(photo) - tk.Label(f, image=photo).pack() + tk.Label(card, image=photo).pack(pady=5) else: - tk.Label(f, text="[No Image]").pack() - except: - tk.Label(f, text="Error Img").pack() + tk.Label(card, text="[No Image]", height=6).pack() + except Exception: + tk.Label(card, text="Error Img", height=6).pack() - tk.Label(f, text=nama, font=("Arial",10,"bold")).pack() - tk.Label(f, text=f"Rp {harga:,.0f}").pack() - tk.Button(f, text="Tambah", bg="#cfe2ff", command=lambda n=nama, h=harga: self.add_to_cart(n, h)).pack(pady=2) + tk.Label(card, text=nama, font=("Arial", 10, "bold"), wraplength=160).pack() + tk.Label(card, text=f"Rp {harga:,.0f}").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): - item_found = False for item in self.cart: if item['nama'] == nama: item['qty'] += 1 item['subtotal'] = item['qty'] * harga - item_found = True - break - - if not item_found: - self.cart.append({ - 'nama': nama, - 'harga_satuan': harga, - 'qty': 1, - 'subtotal': harga - }) - + self.refresh_cart() + return + self.cart.append({'nama': nama, 'harga_satuan': harga, 'qty': 1, 'subtotal': harga}) self.refresh_cart() def kurangi_item_cart(self): - idx = self.listbox.curselection() - if not idx: - messagebox.showwarning("Peringatan", "Pilih menu yang mau dikurangi!") - return - - index = idx[0] - item = self.cart[index] - - # Kurangi jumlah + if not self.listbox.curselection(): return + idx = self.listbox.curselection()[0] + item = self.cart[idx] item['qty'] -= 1 - - if item['qty'] > 0: - item['subtotal'] = item['qty'] * item['harga_satuan'] - self.refresh_cart() - # AUTO-SELECT: Pilih kembali item yang sama - self.listbox.selection_set(index) - self.listbox.activate(index) + if item['qty'] <= 0: + self.cart.pop(idx) 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) + item['subtotal'] = item['qty'] * item['harga_satuan'] + self.refresh_cart() def refresh_cart(self): self.listbox.delete(0, tk.END) - total_belanja = 0 - + total = 0 for item in self.cart: - display_text = f"{item['nama']} (x{item['qty']}) - Rp {item['subtotal']:,.0f}" - self.listbox.insert(tk.END, display_text) - total_belanja += item['subtotal'] - - self.total_lbl.config(text=f"Total: Rp {total_belanja:,.0f}") + self.listbox.insert(tk.END, f"{item['nama']} (x{item['qty']}) - Rp {item['subtotal']:,.0f}") + total += item['subtotal'] + self.total_lbl.config(text=f"Total: Rp {total:,.0f}") + # ================= CHECKOUT ================= def checkout(self): - nama_pemesan = self.entry_nama.get() - meja = self.combo_meja.get() - - if not nama_pemesan: - messagebox.showwarning("Data Kurang", "Mohon isi Nama Anda!") + if not self.entry_nama.get() or not self.cart: + messagebox.showwarning("Error", "Data belum lengkap") return - if not meja or meja == "Penuh": - 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) + total = sum(item['subtotal'] for item in self.cart) tanggal = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") db = connect() cur = db.cursor() - - tanggal_custom = f"{tanggal} ({nama_pemesan})" - cur.execute("INSERT INTO transaksi (tanggal, total, meja_id, status) VALUES (?, ?, ?, ?)", - (tanggal_custom, total_belanja, meja, "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'])) - + (tanggal, total, self.combo_meja.get(), "Pending")) db.commit() db.close() - messagebox.showinfo("Berhasil", f"Pesanan a.n {nama_pemesan} berhasil dikirim!") + messagebox.showinfo("Berhasil", "Pesanan berhasil dikirim") self.cart.clear() self.refresh_cart() - self.entry_nama.delete(0, tk.END) - self.refresh_available_tables() - def logout(self): - self.frame.destroy() - from main import LoginScreen - LoginScreen(self.parent) \ No newline at end of file +# ================= RUN ================= +if __name__ == '__main__': + root = tk.Tk() + root.title("Sistem Cafe Python") + root.geometry("1200x700") + PembeliMenu(root) + root.mainloop() \ No newline at end of file