Compare commits

..

2 Commits

16 changed files with 450 additions and 0 deletions

BIN
cafe.db Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

40
project/admin_menu.py Normal file
View File

@ -0,0 +1,40 @@
import tkinter as tk
from database import connect
from tkinter import messagebox
class AdminMenu:
def __init__(self, root):
self.root = root
self.frame = tk.Frame(root)
self.frame.pack()
tk.Label(
self.frame,
text="ADMIN - KELOLA MENU",
font=("Arial", 18, "bold")
).pack(pady=10)
self.nama = tk.Entry(self.frame)
self.harga = tk.Entry(self.frame)
self.gambar = tk.Entry(self.frame)
for label, entry in [
("Nama Menu", self.nama),
("Harga", self.harga),
("Path Gambar", self.gambar)
]:
tk.Label(self.frame, text=label).pack()
entry.pack()
tk.Button(self.frame, text="Tambah Menu", command=self.tambah).pack(pady=5)
def tambah(self):
db = connect()
cur = db.cursor()
cur.execute(
"INSERT INTO menu(nama,harga,gambar) VALUES (?,?,?)",
(self.nama.get(), self.harga.get(), self.gambar.get())
)
db.commit()
db.close()
messagebox.showinfo("Sukses", "Menu berhasil ditambahkan")

59
project/database.py Normal file
View File

@ -0,0 +1,59 @@
import sqlite3
def connect():
return sqlite3.connect("cafe.db")
def setup_database():
db = connect()
cur = db.cursor()
cur.execute("""
CREATE TABLE IF NOT EXISTS users(
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT,
password TEXT,
role TEXT
)
""")
cur.execute("""
CREATE TABLE IF NOT EXISTS menu(
id INTEGER PRIMARY KEY AUTOINCREMENT,
nama TEXT,
harga REAL,
gambar TEXT
)
""")
cur.execute("""
CREATE TABLE IF NOT EXISTS orders(
id INTEGER PRIMARY KEY AUTOINCREMENT,
nama TEXT,
harga REAL
)
""")
cur.execute("""
CREATE TABLE IF NOT EXISTS pembayaran(
id INTEGER PRIMARY KEY AUTOINCREMENT,
order_id INTEGER,
total REAL
)
""")
cur.execute("SELECT COUNT(*) FROM users")
if cur.fetchone()[0] == 0:
users = [
("admin","admin","admin"),
("kasir","kasir","kasir"),
("pembeli","pembeli","pembeli"),
("pemilik","pemilik","pemilik"),
("waiter","waiter","waiter")
]
cur.executemany(
"INSERT INTO users(username,password,role) VALUES (?,?,?)",
users
)
db.commit()
db.close()

76
project/kasir.py Normal file
View File

@ -0,0 +1,76 @@
import tkinter as tk
from tkinter import messagebox
from database import connect
class KasirPage:
def __init__(self, parent, controller):
self.parent = parent
self.controller = controller
self.frame = tk.Frame(parent)
self.frame.pack(fill="both", expand=True)
tk.Label(self.frame, text="KASIR PAGE", font=("Arial", 18, "bold")).pack(pady=10)
# Tombol Logout
tk.Button(self.frame, text="Logout", bg="#f9e79f", command=self.logout).pack(pady=5)
# Listbox untuk menampilkan order
tk.Label(self.frame, text="Daftar Order:", font=("Arial", 12, "bold")).pack(pady=5)
self.listbox = tk.Listbox(self.frame, width=50, height=10)
self.listbox.pack(pady=5)
# Tombol bayar
tk.Button(self.frame, text="Bayar", bg="#d1e7dd", command=self.bayar).pack(pady=5)
self.load_orders() # Load order dari database saat awal
def load_orders(self):
self.listbox.delete(0, tk.END)
db = connect()
cur = db.cursor()
cur.execute("SELECT id, nama, harga FROM orders")
self.data = cur.fetchall()
db.close()
for order in self.data:
self.listbox.insert(tk.END, f"ID {order[0]}: {order[1]} - Rp {order[2]:,}")
def bayar(self):
idx = self.listbox.curselection()
if not idx:
messagebox.showwarning("Pilih Order", "Pilih order yang ingin dibayar!")
return
order = self.data[idx[0]]
order_id, nama, total = order
# Simpan pembayaran di database (opsional, bisa buat tabel pembayaran)
db = connect()
cur = db.cursor()
cur.execute("INSERT INTO pembayaran VALUES (NULL, ?, ?)", (order_id, total))
cur.execute("DELETE FROM orders WHERE id=?", (order_id,))
db.commit()
db.close()
# Tampilkan struk
self.tampil_struk(order_id, nama, total)
# Update listbox
self.load_orders()
def tampil_struk(self, order_id, nama, total):
win = tk.Toplevel(self.frame)
win.title("Struk Pembayaran")
tk.Label(win, text="STRUK PEMBAYARAN", font=("Arial",14,"bold")).pack(pady=5)
tk.Label(win, text=f"Order ID : {order_id}").pack()
tk.Label(win, text=f"Nama Menu: {nama}").pack()
tk.Label(win, text=f"Total : Rp {total:,}").pack()
tk.Label(win, text="Terima kasih 🙏").pack(pady=10)
tk.Button(win, text="Tutup", command=win.destroy).pack(pady=5)
def logout(self):
self.frame.destroy()
from main import LoginScreen
LoginScreen(self.parent)

46
project/login.py Normal file
View File

@ -0,0 +1,46 @@
import tkinter as tk
from tkinter import messagebox
from database import connect
from admin_menu import AdminMenu
from pembeli_menu import PembeliMenu
from kasir import KasirPage
from pemilik import PemilikPage
class LoginPage:
def __init__(self, root):
self.root = root
self.frame = tk.Frame(root)
self.frame.pack(expand=True)
tk.Label(self.frame, text="LOGIN CAFE", font=("Arial",20,"bold")).pack(pady=10)
self.user = tk.Entry(self.frame)
self.passw = tk.Entry(self.frame, show="*")
self.user.pack()
self.passw.pack()
tk.Button(self.frame, text="Login", command=self.login).pack(pady=5)
def login(self):
db = connect()
cur = db.cursor()
cur.execute("SELECT role FROM users WHERE username=? AND password=?",
(self.user.get(), self.passw.get()))
res = cur.fetchone()
db.close()
if not res:
messagebox.showerror("Error","Login gagal")
return
self.frame.destroy()
role = res[0]
if role=="admin":
AdminMenu(self.root)
elif role=="pembeli":
PembeliMenu(self.root)
elif role=="kasir":
KasirPage(self.root)
elif role=="pemilik":
PemilikPage(self.root)

71
project/main.py Normal file
View File

@ -0,0 +1,71 @@
import tkinter as tk
from database import setup_database, connect
from pembeli_menu import PembeliMenu
from kasir import KasirPage
from pemilik import PemilikPage
from admin_menu import AdminMenu
from waiter_dashboard import WaiterDashboard
from tkinter import messagebox
# --- Login Screen ---
class LoginScreen:
def __init__(self, root):
self.root = root
self.frame = tk.Frame(root)
self.frame.pack(fill="both", expand=True)
tk.Label(self.frame,text="LOGIN SISTEM CAFE", font=("Arial",18,"bold")).pack(pady=20)
tk.Label(self.frame,text="Username").pack()
self.username_entry = tk.Entry(self.frame)
self.username_entry.pack()
tk.Label(self.frame,text="Password").pack()
self.password_entry = tk.Entry(self.frame, show="*")
self.password_entry.pack(pady=5)
tk.Button(self.frame,text="Login", bg="#cfe2ff", command=self.login).pack(pady=10)
def login(self):
username = self.username_entry.get()
password = self.password_entry.get()
db = connect()
cur = db.cursor()
cur.execute("SELECT role FROM users WHERE username=? AND password=?", (username,password))
result = cur.fetchone()
db.close()
if result:
role = result[0]
self.frame.destroy()
if role=="pembeli":
PembeliMenu(self.root)
elif role=="kasir":
KasirPage(self.root, self.root)
elif role=="pemilik":
PemilikPage(self.root, self.root)
elif role == "admin":
AdminMenu(self.root)
elif role == "waiter":
WaiterDashboard(self.root)
else:
messagebox.showerror("Error","Role tidak dikenali")
else:
messagebox.showerror("Error","Username / Password salah")
# --- App ---
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Sistem Cafe")
self.geometry("700x600")
# --- Run Program ---
if __name__=="__main__":
setup_database()
app = App()
LoginScreen(app)
app.mainloop()

91
project/pembeli_menu.py Normal file
View File

@ -0,0 +1,91 @@
import tkinter as tk
from PIL import Image, ImageTk
from database import connect
from tkinter import messagebox
class PembeliMenu:
def __init__(self, parent):
self.parent = parent
self.frame = tk.Frame(parent)
self.frame.pack(fill="both", expand=True)
self.cart = [] # Simpan tuple (nama, harga)
self.images = [] # Simpan reference gambar agar tidak dihapus GC
# --- Judul Halaman ---
tk.Label(self.frame, text="MENU PEMBELI", font=("Arial", 18, "bold")).pack(pady=10)
# --- Tombol Logout ---
tk.Button(self.frame, text="Logout", bg="#f9e79f", command=self.logout).pack(pady=5)
# --- Frame Menu ---
self.menu_frame = tk.Frame(self.frame)
self.menu_frame.pack(pady=10)
self.load_menu() # Load menu dari database
# --- Daftar Pesanan ---
tk.Label(self.frame, text="Daftar Pesanan:", font=("Arial", 12, "bold")).pack(pady=5)
self.listbox = tk.Listbox(self.frame, width=50, height=6)
self.listbox.pack()
# --- Total ---
self.total_lbl = tk.Label(self.frame, text="Total: Rp 0", font=("Arial", 12, "bold"))
self.total_lbl.pack(pady=5)
# --- Tombol Checkout ---
tk.Button(self.frame, text="Checkout", bg="#d1e7dd", command=self.checkout).pack(pady=5)
def load_menu(self):
db = connect()
cur = db.cursor()
cur.execute("SELECT nama, harga, gambar FROM menu")
data = cur.fetchall()
db.close()
for i, (nama, harga, gambar) in enumerate(data):
f = tk.Frame(self.menu_frame, bd=2, relief="ridge")
f.grid(row=i//3, column=i%3, padx=10, pady=10)
try:
img = Image.open(gambar).resize((120, 90))
photo = ImageTk.PhotoImage(img)
self.images.append(photo)
tk.Label(f, image=photo).pack()
except FileNotFoundError:
tk.Label(f, text="No Image").pack()
tk.Label(f, text=nama).pack()
tk.Label(f, text=f"Rp {harga:,}").pack()
tk.Button(f, text="Pesan", bg="#cfe2ff",
command=lambda n=nama, h=harga: self.add(n, h)).pack(pady=3)
def add(self, nama, harga):
self.cart.append((nama, harga))
self.listbox.insert(tk.END, f"{nama} - Rp {harga:,}")
total = sum(h for _, h in self.cart)
self.total_lbl.config(text=f"Total: Rp {total:,}")
def checkout(self):
if not self.cart:
messagebox.showwarning("Pesan Kosong", "Belum ada pesanan!")
return
db = connect()
cur = db.cursor()
for nama, harga in self.cart:
cur.execute("INSERT INTO orders VALUES (NULL, ?, ?)", (nama, harga))
db.commit()
db.close()
messagebox.showinfo("Sukses", "Pesanan dikirim ke kasir")
self.cart.clear()
self.listbox.delete(0, tk.END)
self.total_lbl.config(text="Total: Rp 0")
def logout(self):
self.frame.destroy()
from main import LoginScreen
LoginScreen(self.parent)

40
project/pemilik.py Normal file
View File

@ -0,0 +1,40 @@
import tkinter as tk
from database import connect
class PemilikPage:
def __init__(self, parent, controller):
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)
# 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)
# Tombol Refresh
tk.Button(self.frame, text="Refresh", bg="#cfe2ff", command=self.load).pack(pady=5)
# Tombol Logout
tk.Button(self.frame, text="Logout", bg="#f9e79f", command=self.logout).pack(pady=5)
# Load data awal
self.load()
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
db.close()
self.total_lbl.config(text=f"Total Penjualan: Rp {total:,}")
def logout(self):
self.frame.destroy()
from main import LoginScreen
LoginScreen(self.parent)

10
project/project.css Normal file
View File

@ -0,0 +1,10 @@
project/
main.py
database.py
pembeli_menu.py
kasir_page.py
pemilik_page.py
mie ayam.webp
mie kuah.webp
es teh.webp
jus jeruk.webp

View File

@ -0,0 +1,17 @@
import tkinter as tk
class WaiterDashboard:
def __init__(self, parent):
self.parent = parent
self.frame = tk.Frame(parent)
self.frame.pack(fill="both", expand=True)
tk.Label(self.frame, text="WAITER", font=("Arial", 20, "bold")).pack(pady=20)
tk.Label(self.frame, text="(Input pesanan manual)").pack()
tk.Button(self.frame, text="Logout", command=self.logout).pack(pady=10)
def logout(self):
self.frame.destroy()
from main import LoginScreen
LoginScreen(self.parent)