diff --git a/project/kasir.py b/project/kasir.py index 52ce2a5..b159a7d 100644 --- a/project/kasir.py +++ b/project/kasir.py @@ -114,11 +114,13 @@ class KasirPage: if metode == "QRIS": self.tampilkan_qr(t_id, meja, total) + elif metode == "E-Wallet": + self.konfirmasi_ewallet(t_id, meja, total) else: self.selesaikan_pembayaran(t_id, meja, total, metode) # ===================== - # QRIS + # QRIS (CLOSE WINDOW = LUNAS) # ===================== def tampilkan_qr(self, t_id, meja, total): win = tk.Toplevel(self.frame) @@ -152,27 +154,57 @@ Total: {total} font=("Arial", 11) ).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( win, text="Konfirmasi Pembayaran", bg="#d1e7dd", width=25, - command=lambda: [ - self.selesaikan_pembayaran(t_id, meja, total, "QRIS"), - win.destroy() - ] + command=selesai_qris ).pack(pady=15) + # ===================== + # E-WALLET + # ===================== + 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") + # ===================== # FINAL PEMBAYARAN # ===================== def selesaikan_pembayaran(self, t_id, meja, total, metode): db = connect() cur = db.cursor() + cur.execute( - "UPDATE transaksi SET status='Lunas' WHERE id=?", + """ + UPDATE transaksi + SET status='Lunas', + tanggal = DATETIME('now') + WHERE id=? + """, (t_id,) ) + db.commit() db.close() diff --git a/project/pemilik.py b/project/pemilik.py index 7d1007c..700cf7d 100644 --- a/project/pemilik.py +++ b/project/pemilik.py @@ -1,40 +1,182 @@ import tkinter as tk +from tkinter import messagebox from database import connect +import matplotlib.pyplot as plt + class PemilikPage: - def __init__(self, parent, controller): + def __init__(self, parent, controller=None): self.parent = parent self.controller = controller + self.frame = tk.Frame(parent) 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")) - self.total_lbl.pack(pady=5) + # ===================== + # FILTER PERIODE + # ===================== + filter_frame = tk.Frame(self.frame) + filter_frame.pack(pady=5) - # Tombol Refresh - tk.Button(self.frame, text="Refresh", bg="#cfe2ff", command=self.load).pack(pady=5) + tk.Label(filter_frame, text="Periode:").pack(side=tk.LEFT) - # Tombol Logout - tk.Button(self.frame, text="Logout", bg="#f9e79f", command=self.logout).pack(pady=5) + self.filter_var = tk.StringVar(value="Harian") + 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() + # ===================== + # LOAD TOTAL (SUM ASLI) + # ===================== def load(self): db = connect() cur = db.cursor() - # Jumlahkan semua total pembayaran dari tabel pembayaran - cur.execute("SELECT SUM(total) FROM pembayaran") - total = cur.fetchone()[0] or 0 + periode = self.filter_var.get() + + 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() - 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): self.frame.destroy() from main import LoginScreen LoginScreen(self.parent) -