Compare commits

...
16 Commits
Author SHA1 Message Date
5803025001 f349274710 Merge branch 'main' of https://git-eng.ukwms.ac.id/5803025001/Python-Menu 2025-12-16 15:31:17 +07:00
ofeleoprecio 4c8221971a fixing things 2025-12-16 15:31:14 +07:00
ofeleoprecio 5bd728b1bd fixing things 2025-12-16 15:24:08 +07:00
ofeleoprecio 9053434a83 add new 2025-12-16 15:14:12 +07:00
5803025001 e8edfe939f Merge branch 'main' of https://git-eng.ukwms.ac.id/5803025001/Python-Menu 2025-12-16 10:53:17 +07:00
5803025001 17bdf516b3 Merge branch 'main' of https://git-eng.ukwms.ac.id/5803025001/Python-Menu 2025-12-16 10:53:14 +07:00
ofeleoprecio 94e45a7aad Merge branch 'main' of https://git-eng.ukwms.ac.id/5803025001/Python-Menu 2025-12-16 10:29:03 +07:00
5803025001 54c14826c4 Merge branch 'main' of https://git-eng.ukwms.ac.id/5803025001/Python-Menu 2025-12-16 10:28:56 +07:00
5803025001 52233b09be Merge branch 'main' of https://git-eng.ukwms.ac.id/5803025001/Python-Menu 2025-12-15 09:16:19 +07:00
5803025001 3ab63e6327 Merge branch 'main' of https://git-eng.ukwms.ac.id/5803025001/Python-Menu 2025-12-15 09:16:17 +07:00
5803025001 e8bc7113d1 Merge branch 'main' of https://git-eng.ukwms.ac.id/5803025001/Python-Menu 2025-12-15 09:04:23 +07:00
5803025001 509715f629 Merge branch 'main' of https://git-eng.ukwms.ac.id/5803025001/Python-Menu 2025-12-15 09:04:20 +07:00
5803025001 c4b6e1fba9 Merge branch 'main' of https://git-eng.ukwms.ac.id/5803025001/Python-Menu 2025-12-15 08:55:06 +07:00
5803025001 e5c6da3417 Merge branch 'main' of https://git-eng.ukwms.ac.id/5803025001/Python-Menu 2025-12-15 08:55:02 +07:00
5803025001 92abbb95fa Merge branch 'main' of https://git-eng.ukwms.ac.id/5803025001/Python-Menu 2025-12-15 04:23:49 +07:00
5803025001 6e6218f2fa Merge branch 'main' of https://git-eng.ukwms.ac.id/5803025001/Python-Menu 2025-12-15 04:23:45 +07:00
8 changed files with 481 additions and 157 deletions
+1
View File
@@ -0,0 +1 @@
*.pyc
BIN
View File
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 308 KiB

+2 -1
View File
@@ -47,7 +47,8 @@ def setup_database():
tanggal TEXT, tanggal TEXT,
total REAL, total REAL,
meja_id INTEGER, meja_id INTEGER,
status TEXT status TEXT,
metode TEXT
) )
""") """)
+170 -22
View File
@@ -1,11 +1,10 @@
import tkinter as tk import tkinter as tk
from tkinter import messagebox from tkinter import messagebox
from database import connect from database import connect
from datetime import datetime
import qrcode import qrcode
from PIL import ImageTk from PIL import ImageTk
class KasirPage: class KasirPage:
def __init__(self, parent, controller=None): def __init__(self, parent, controller=None):
self.parent = parent self.parent = parent
@@ -61,6 +60,56 @@ class KasirPage:
"Cash", "QRIS", "E-Wallet" "Cash", "QRIS", "E-Wallet"
).pack(side=tk.LEFT, padx=5) ).pack(side=tk.LEFT, padx=5)
# =====================
# INPUT CASH
# =====================
cash_frame = tk.Frame(self.frame)
cash_frame.pack(pady=5)
tk.Label(cash_frame, text="Uang Diterima (Cash):").pack(side=tk.LEFT)
self.uang_entry = tk.Entry(cash_frame, width=15)
self.uang_entry.pack(side=tk.LEFT, padx=5)
# =====================
# HITUNG KEMBALIAN
# =====================
def hitung_kembalian(event=None):
try:
# 1. Ambil transaksi yang sedang dipilih (Total tagihan)
idx = self.listbox.curselection()
if idx:
teks_item = self.listbox.get(idx).split(" ")
total = int(teks_item[len(teks_item)-1].replace(",",""))
uang_diterima = int(self.uang_entry.get())
# 3. Hitung dan update label
kembalian = uang_diterima - total
self.kembalian_label.config(text=f"Rp {kembalian:,.0f}")
except ValueError:
# Jika input bukan angka atau kosong, atur kembalian jadi 0
self.kembalian_label.config(text="Rp 0")
except IndexError:
# Jika transaksi tidak dipilih
self.kembalian_label.config(text="Rp 0")
self.uang_entry.bind("<KeyRelease>", hitung_kembalian)
# =====================
# UANG KEMBALIAN (BARU)
# =====================
kembalian_frame = tk.Frame(self.frame)
kembalian_frame.pack(pady=5)
tk.Label(kembalian_frame, text="Uang Kembalian:").pack(side=tk.LEFT)
# ⭐️ Label untuk menampilkan kembalian
self.kembalian_label = tk.Label(kembalian_frame, text="Rp 0")
self.kembalian_label.pack(side=tk.LEFT, padx=5)
# ===================== # =====================
# BUTTON BAYAR # BUTTON BAYAR
# ===================== # =====================
@@ -94,12 +143,33 @@ class KasirPage:
for row in rows: for row in rows:
t_id, meja, total = row t_id, meja, total = row
self.listbox.insert( self.listbox.insert(
tk.END, tk.END,
f"Meja {meja} | ID {t_id} | Total Rp {total:,.0f}" f"Meja {meja} | ID {t_id} | Total Rp {total:,.0f}"
) )
# 🔽 AMBIL DETAIL MENU
db = connect()
cur = db.cursor()
cur.execute("""
SELECT menu_nama, jumlah
FROM detail_transaksi
WHERE transaksi_id=?
""", (t_id,))
items = cur.fetchall()
db.close()
for nama, qty in items:
self.listbox.insert(
tk.END,
f" • {nama} x{qty}"
)
self.listbox.insert(tk.END, "-" * 50)
self.transaksi_data.append(row) self.transaksi_data.append(row)
# ===================== # =====================
# BAYAR # BAYAR
# ===================== # =====================
@@ -109,16 +179,44 @@ class KasirPage:
messagebox.showwarning("Pilih", "Pilih tagihan yang akan dibayar!") messagebox.showwarning("Pilih", "Pilih tagihan yang akan dibayar!")
return return
t_id, meja, total = self.transaksi_data[idx[0]] idx = self.listbox.curselection()
if idx:
teks_item = self.listbox.get(idx).split(" ")
total = int(teks_item[len(teks_item)-1].replace(",",""))
meja = int(teks_item[1])
t_id = int(teks_item[4])
metode = self.metode.get() metode = self.metode.get()
if metode == "QRIS": if metode == "QRIS":
self.tampilkan_qr(t_id, meja, total) self.tampilkan_qr(t_id, meja, total)
else:
self.selesaikan_pembayaran(t_id, meja, total, metode) elif metode == "E-Wallet":
self.konfirmasi_ewallet(t_id, meja, total)
else: # CASH
try:
uang = int(self.uang_entry.get())
except:
messagebox.showwarning("Error", "Masukkan uang cash!")
return
if uang < total:
messagebox.showwarning(
"Kurang",
f"Uang kurang!\nTotal: Rp {total:,.0f}"
)
return
kembalian = uang - total
self.selesaikan_pembayaran(
t_id, meja, total, metode,
uang, kembalian
)
# ===================== # =====================
# QRIS # QRIS (CLOSE WINDOW = LUNAS)
# ===================== # =====================
def tampilkan_qr(self, t_id, meja, total): def tampilkan_qr(self, t_id, meja, total):
win = tk.Toplevel(self.frame) win = tk.Toplevel(self.frame)
@@ -152,29 +250,82 @@ Total: {total}
font=("Arial", 11) font=("Arial", 11)
).pack(pady=5) ).pack(pady=5)
def selesai_qris():
self.selesaikan_pembayaran(t_id, meja, total, "QRIS")
win.destroy()
# ❌ WINDOW DITUTUP = TRANSAKSI BERHASIL
win.protocol("WM_DELETE_WINDOW", selesai_qris)
tk.Button( tk.Button(
win, win,
text="Konfirmasi Pembayaran", text="Konfirmasi Pembayaran",
bg="#d1e7dd", bg="#d1e7dd",
width=25, width=25,
command=lambda: [ command=selesai_qris
self.selesaikan_pembayaran(t_id, meja, total, "QRIS"),
win.destroy()
]
).pack(pady=15) ).pack(pady=15)
# ===================== # =====================
# FINAL PEMBAYARAN # E-WALLET
# ===================== # =====================
def selesaikan_pembayaran(self, t_id, meja, total, metode): def konfirmasi_ewallet(self, t_id, meja, total):
confirm = messagebox.askyesno(
"E-Wallet Payment",
f"""
Bayar menggunakan E-Wallet?
Meja : {meja}
Total : Rp {total:,.0f}
Lanjutkan pembayaran?
"""
)
if confirm:
self.selesaikan_pembayaran(t_id, meja, total, "E-Wallet")
def selesaikan_pembayaran(self, t_id, meja, total, metode, uang=None, kembalian=None):
db = connect() db = connect()
cur = db.cursor() cur = db.cursor()
cur.execute(
"UPDATE transaksi SET status='Lunas' WHERE id=?", try:
(t_id,) cur.execute(
) """
db.commit() UPDATE transaksi
db.close() SET status='Lunas',
tanggal = DATETIME('now')
WHERE id=?
""",
(t_id,)
)
db.commit() # ⭐️ PASTIKAN COMMIT DILAKUKAN
tanggal_sekarang = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
sql_query = """
INSERT INTO transaksi (tanggal, total, meja_id, status, metode)
VALUES (?, ?, ?, ?, ?)
"""
data_transaksi = (tanggal_sekarang, total, meja, "Lunas", metode)
cur.execute(sql_query, data_transaksi)
db.commit()
# Tambahkan print debug untuk konfirmasi
print(f"DEBUG: Transaksi ID {t_id} berhasil diupdate menjadi Lunas.")
except Exception as e:
# Jika ada error database
print(f"ERROR: Gagal update status transaksi: {e}")
messagebox.showerror("DB Error", "Gagal memperbarui status transaksi.")
finally:
db.close()
struk_tambahan = ""
if metode == "Cash" and uang is not None and kembalian is not None:
struk_tambahan = f"""
Uang Diterima: Rp {uang:,.0f}
Kembalian : Rp {kembalian:,.0f}"""
messagebox.showinfo( messagebox.showinfo(
"Struk Pembayaran", "Struk Pembayaran",
@@ -183,7 +334,7 @@ Total: {total}
ID Transaksi : {t_id} ID Transaksi : {t_id}
Meja : {meja} Meja : {meja}
Total : Rp {total:,.0f} Total : Rp {total:,.0f}
Metode : {metode} Metode : {metode}{struk_tambahan}
Status : Lunas Status : Lunas
==================== ====================
Terima kasih 🙏 Terima kasih 🙏
@@ -192,9 +343,6 @@ Terima kasih 🙏
self.load_tagihan() self.load_tagihan()
# =====================
# LOGOUT
# =====================
def logout(self): def logout(self):
self.frame.destroy() self.frame.destroy()
from main import LoginScreen from main import LoginScreen
View File
+141 -109
View File
@@ -1,10 +1,17 @@
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
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# ================= 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 +21,26 @@ 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) header = tk.Frame(self.frame)
header.pack(fill="x", padx=20, pady=10)
# --- INPUT DATA PELANGGAN --- tk.Label(
header,
text="SELAMAT DATANG",
font=("Arial", 18, "bold")
).pack(side="left")
tk.Button(
header,
text="⬅ Kembali",
bg="#f8d7da",
font=("Arial", 10, "bold"),
command=self.logout
).pack(side="right")
# ================= 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 +48,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 +107,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 +118,122 @@ 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): if not gambar:
img = Image.open(gambar).resize((100, 80)) raise ValueError("gambar kosong")
photo = ImageTk.PhotoImage(img)
self.images.append(photo)
tk.Label(f, image=photo).pack()
else:
tk.Label(f, text="[No Image]").pack()
except:
tk.Label(f, text="Error Img").pack()
tk.Label(f, text=nama, font=("Arial",10,"bold")).pack() # gambar dari DB sudah mengandung 'aset/...'
tk.Label(f, text=f"Rp {harga:,.0f}").pack() img_path = os.path.join(BASE_DIR, gambar)
tk.Button(f, text="Tambah", bg="#cfe2ff", command=lambda n=nama, h=harga: self.add_to_cart(n, h)).pack(pady=2)
if not os.path.exists(img_path):
raise FileNotFoundError(img_path)
img = Image.open(img_path)
img = img.resize((140, 90), Image.Resampling.LANCZOS)
photo = ImageTk.PhotoImage(img)
self.images.append(photo)
tk.Label(card, image=photo).pack(pady=5)
except Exception as e:
print("IMG ERROR:", e)
tk.Label(card, text="No Image", height=6).pack()
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): 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)
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)
else: else:
self.cart.pop(index) item['subtotal'] = item['qty'] * item['harga_satuan']
self.refresh_cart() 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}")
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
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 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") 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})" # 1️⃣ Simpan transaksi
cur.execute("""
INSERT INTO transaksi (tanggal, total, meja_id, status)
VALUES (?, ?, ?, ?)
""", (tanggal, total, self.combo_meja.get(), "Pending"))
cur.execute("INSERT INTO transaksi (tanggal, total, meja_id, status) VALUES (?, ?, ?, ?)", transaksi_id = cur.lastrowid # 🔥 AMBIL ID TRANSAKSI
(tanggal_custom, total_belanja, meja, "Pending"))
transaksi_id = cur.lastrowid
# 2️⃣ Simpan detail menu
for item in self.cart: for item in self.cart:
cur.execute("INSERT INTO detail_transaksi (transaksi_id, menu_nama, harga, jumlah, subtotal) VALUES (?, ?, ?, ?, ?)", cur.execute("""
(transaksi_id, item['nama'], item['harga_satuan'], item['qty'], item['subtotal'])) 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): def logout(self):
self.frame.destroy() self.frame.destroy()
from main import LoginScreen from main import LoginScreen
LoginScreen(self.parent) LoginScreen(self.parent)
# ================= RUN =================
if __name__ == '__main__':
root = tk.Tk()
root.title("Sistem Cafe Python")
root.geometry("1200x700")
PembeliMenu(root)
root.mainloop()
+157 -15
View File
@@ -1,40 +1,182 @@
import tkinter as tk import tkinter as tk
from tkinter import messagebox
from database import connect from database import connect
import matplotlib.pyplot as plt
class PemilikPage: class PemilikPage:
def __init__(self, parent, controller): def __init__(self, parent, controller=None):
self.parent = parent self.parent = parent
self.controller = controller self.controller = controller
self.frame = tk.Frame(parent) self.frame = tk.Frame(parent)
self.frame.pack(fill="both", expand=True) self.frame.pack(fill="both", expand=True)
tk.Label(self.frame, text="LAPORAN PENJUALAN", font=("Arial", 18, "bold")).pack(pady=10) # =====================
# JUDUL
# =====================
tk.Label(
self.frame,
text="LAPORAN PENJUALAN",
font=("Arial", 18, "bold")
).pack(pady=10)
# Label untuk total penjualan # =====================
self.total_lbl = tk.Label(self.frame, text="Total Penjualan: Rp 0", font=("Arial", 14, "bold")) # FILTER PERIODE
self.total_lbl.pack(pady=5) # =====================
filter_frame = tk.Frame(self.frame)
filter_frame.pack(pady=5)
# Tombol Refresh tk.Label(filter_frame, text="Periode:").pack(side=tk.LEFT)
tk.Button(self.frame, text="Refresh", bg="#cfe2ff", command=self.load).pack(pady=5)
# Tombol Logout self.filter_var = tk.StringVar(value="Harian")
tk.Button(self.frame, text="Logout", bg="#f9e79f", command=self.logout).pack(pady=5) tk.OptionMenu(
filter_frame,
self.filter_var,
"Harian", "Mingguan", "Bulanan"
).pack(side=tk.LEFT, padx=5)
tk.Button(
filter_frame,
text="Refresh",
bg="#cfe2ff",
command=self.load
).pack(side=tk.LEFT, padx=10)
# =====================
# TOTAL
# =====================
self.total_lbl = tk.Label(
self.frame,
text="Total (Harian): Rp 0",
font=("Arial", 14, "bold")
)
self.total_lbl.pack(pady=10)
# =====================
# GRAFIK
# =====================
tk.Button(
self.frame,
text="Tampilkan Grafik",
bg="#d1e7dd",
width=20,
command=self.show_graph
).pack(pady=5)
# =====================
# LOGOUT
# =====================
tk.Button(
self.frame,
text="Logout",
bg="#f9e79f",
command=self.logout
).pack(pady=5)
# Load data awal
self.load() self.load()
# =====================
# LOAD TOTAL (SUM ASLI)
# =====================
def load(self): def load(self):
db = connect() db = connect()
cur = db.cursor() cur = db.cursor()
# Jumlahkan semua total pembayaran dari tabel pembayaran periode = self.filter_var.get()
cur.execute("SELECT SUM(total) FROM pembayaran")
total = cur.fetchone()[0] or 0 if periode == "Harian":
cur.execute("""
SELECT COALESCE(SUM(total), 0)
FROM transaksi
WHERE status='Lunas'
AND datetime(tanggal) >= datetime('now','-1 day')
""")
elif periode == "Mingguan":
cur.execute("""
SELECT COALESCE(SUM(total), 0)
FROM transaksi
WHERE status='Lunas'
AND datetime(tanggal) >= datetime('now','-7 day')
""")
else: # Bulanan
cur.execute("""
SELECT COALESCE(SUM(total), 0)
FROM transaksi
WHERE status='Lunas'
AND strftime('%Y-%m', tanggal) = strftime('%Y-%m','now')
""")
total = cur.fetchone()[0]
db.close() db.close()
self.total_lbl.config(text=f"Total Penjualan: Rp {total:,}") self.total_lbl.config(
text=f"Total ({periode}): Rp {total:,.0f}"
)
# =====================
# GRAFIK (SUM SESUAI TOTAL)
# =====================
def show_graph(self):
plt.close('all')
db = connect()
cur = db.cursor()
periode = self.filter_var.get()
if periode == "Harian":
cur.execute("""
SELECT strftime('%H:%M', tanggal), SUM(total)
FROM transaksi
WHERE status='Lunas'
AND datetime(tanggal) >= datetime('now','-1 day')
GROUP BY strftime('%H', tanggal)
ORDER BY tanggal
""")
elif periode == "Mingguan":
cur.execute("""
SELECT date(tanggal), SUM(total)
FROM transaksi
WHERE status='Lunas'
AND datetime(tanggal) >= datetime('now','-7 day')
GROUP BY date(tanggal)
ORDER BY date(tanggal)
""")
else:
cur.execute("""
SELECT strftime('%Y-%m', tanggal), SUM(total)
FROM transaksi
WHERE status='Lunas'
GROUP BY strftime('%Y-%m', tanggal)
ORDER BY strftime('%Y-%m', tanggal)
""")
data = cur.fetchall()
db.close()
if not data:
messagebox.showinfo("Info", "Belum ada data penjualan")
return
labels = [d[0] for d in data]
totals = [d[1] for d in data]
plt.figure()
plt.plot(labels, totals, marker='o')
plt.title(f"Grafik Penjualan ({periode})")
plt.xlabel("Periode")
plt.ylabel("Total Penjualan")
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
# =====================
# LOGOUT
# =====================
def logout(self): def logout(self):
self.frame.destroy() self.frame.destroy()
from main import LoginScreen from main import LoginScreen
LoginScreen(self.parent) LoginScreen(self.parent)