Compare commits

...
8 Commits
6 changed files with 189 additions and 38 deletions
+1
View File
@@ -0,0 +1 @@
*.pyc
BIN
View File
Binary file not shown.
+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
) )
""") """)
+139 -23
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,15 +179,41 @@ 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)
elif metode == "E-Wallet": elif metode == "E-Wallet":
self.konfirmasi_ewallet(t_id, meja, total) self.konfirmasi_ewallet(t_id, meja, total)
else:
self.selesaikan_pembayaran(t_id, meja, total, metode) 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 (CLOSE WINDOW = LUNAS) # QRIS (CLOSE WINDOW = LUNAS)
@@ -188,25 +284,48 @@ Lanjutkan pembayaran?
if confirm: if confirm:
self.selesaikan_pembayaran(t_id, meja, total, "E-Wallet") self.selesaikan_pembayaran(t_id, meja, total, "E-Wallet")
# ===================== def selesaikan_pembayaran(self, t_id, meja, total, metode, uang=None, kembalian=None):
# FINAL PEMBAYARAN
# =====================
def selesaikan_pembayaran(self, t_id, meja, total, metode):
db = connect() db = connect()
cur = db.cursor() cur = db.cursor()
cur.execute( try:
cur.execute(
"""
UPDATE transaksi
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 (?, ?, ?, ?, ?)
""" """
UPDATE transaksi
SET status='Lunas', data_transaksi = (tanggal_sekarang, total, meja, "Lunas", metode)
tanggal = DATETIME('now') cur.execute(sql_query, data_transaksi)
WHERE id=? db.commit()
""",
(t_id,)
)
db.commit() # Tambahkan print debug untuk konfirmasi
db.close() 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",
@@ -215,7 +334,7 @@ Lanjutkan pembayaran?
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 🙏
@@ -224,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
+47 -14
View File
@@ -5,6 +5,8 @@ import sqlite3
import datetime import datetime
import os import os
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# ================= DATABASE CONNECT ================= # ================= DATABASE CONNECT =================
def connect(): def connect():
return sqlite3.connect("cafe.db") return sqlite3.connect("cafe.db")
@@ -124,17 +126,26 @@ class PembeliMenu:
card.grid_propagate(False) card.grid_propagate(False)
try: try:
filename = os.path.basename(gambar) if gambar else None if not gambar:
img_path = os.path.join("aset", filename) if filename else None raise ValueError("gambar kosong")
if img_path and os.path.exists(img_path):
img = Image.open(img_path).resize((140, 90)) # gambar dari DB sudah mengandung 'aset/...'
photo = ImageTk.PhotoImage(img) img_path = os.path.join(BASE_DIR, gambar)
self.images.append(photo)
tk.Label(card, image=photo).pack(pady=5) if not os.path.exists(img_path):
else: raise FileNotFoundError(img_path)
tk.Label(card, text="[No Image]", height=6).pack()
except Exception: img = Image.open(img_path)
tk.Label(card, text="Error Img", height=6).pack() 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=nama, font=("Arial", 10, "bold"), wraplength=160).pack()
tk.Label(card, text=f"Rp {harga:,.0f}").pack(pady=2) tk.Label(card, text=f"Rp {harga:,.0f}").pack(pady=2)
@@ -172,24 +183,46 @@ class PembeliMenu:
total += item['subtotal'] total += item['subtotal']
self.total_lbl.config(text=f"Total: Rp {total:,.0f}") self.total_lbl.config(text=f"Total: Rp {total:,.0f}")
# ================= CHECKOUT =================
def checkout(self): def checkout(self):
if not self.entry_nama.get() or not self.cart: if not self.entry_nama.get() or not self.cart:
messagebox.showwarning("Error", "Data belum lengkap") messagebox.showwarning("Error", "Data belum lengkap")
return return
total = 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()
cur.execute("INSERT INTO transaksi (tanggal, total, meja_id, status) VALUES (?, ?, ?, ?)",
(tanggal, total, self.combo_meja.get(), "Pending")) # 1️⃣ Simpan transaksi
cur.execute("""
INSERT INTO transaksi (tanggal, total, meja_id, status)
VALUES (?, ?, ?, ?)
""", (tanggal, total, self.combo_meja.get(), "Pending"))
transaksi_id = cur.lastrowid # 🔥 AMBIL ID TRANSAKSI
# 2️⃣ Simpan detail menu
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", "Pesanan berhasil dikirim") messagebox.showinfo("Berhasil", "Pesanan berhasil dikirim")
self.cart.clear() self.cart.clear()
self.refresh_cart() self.refresh_cart()
def logout(self): def logout(self):
self.frame.destroy() self.frame.destroy()