DB to CSV

This commit is contained in:
Bluwww 2025-12-03 15:42:08 +07:00
parent b1f67c9a3f
commit 388d55be6a
4 changed files with 384 additions and 249 deletions

619
main.py
View File

@ -6,102 +6,134 @@
- owner / owner123 (role pemilik) - owner / owner123 (role pemilik)
""" """
import sqlite3
import os import os
import csv
import tkinter as tk import tkinter as tk
from tkinter import ttk, messagebox, filedialog from tkinter import ttk, messagebox, filedialog
from PIL import Image, ImageTk from PIL import Image, ImageTk
DB_PATH = "cafe_person1.db" USERS_CSV = "users.csv"
MENU_CSV = "menu.csv"
PROMO_CSV = "promo.csv"
IMG_PREVIEW_SIZE = (120, 80) IMG_PREVIEW_SIZE = (120, 80)
def ensure_file(path, fieldnames):
if not os.path.exists(path):
with open(path, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
def read_all(path):
# Baguan Database (ati ati) if not os.path.exists(path):
return []
with open(path, newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
return list(reader)
def init_db(): def write_all(path, fieldnames, rows):
conn = sqlite3.connect(DB_PATH) with open(path, "w", newline="", encoding="utf-8") as f:
c = conn.cursor() writer = csv.DictWriter(f, fieldnames=fieldnames)
c.execute(""" writer.writeheader()
CREATE TABLE IF NOT EXISTS users ( writer.writerows(rows)
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE,
password TEXT,
role TEXT
)
""")
c.execute("""
CREATE TABLE IF NOT EXISTS menu (
id INTEGER PRIMARY KEY AUTOINCREMENT,
nama TEXT NOT NULL,
kategori TEXT,
harga REAL NOT NULL,
stok INTEGER DEFAULT 0,
foto TEXT,
tersedia INTEGER DEFAULT 1,
item_discount_pct REAL DEFAULT 0 -- per item discount percent (like 10 for 10%)
)
""")
c.execute("""
CREATE TABLE IF NOT EXISTS promo (
code TEXT PRIMARY KEY,
type TEXT CHECK(type IN ('percent','fixed')),
value REAL,
min_total REAL DEFAULT 0
)
""")
conn.commit()
seed_defaults(conn)
return conn
def seed_defaults(conn):
c = conn.cursor() def next_int_id(rows, id_field="id"):
defaults = [ max_id = 0
('admin','admin123','admin'), for r in rows:
('kasir','kasir123','kasir'),
('waiter','waiter123','waiter'),
('user','user123','pembeli'),
('owner','owner123','pemilik'),
]
for u,p,r in defaults:
try: try:
c.execute("INSERT INTO users (username,password,role) VALUES (?,?,?)", (u,p,r)) v = int(r.get(id_field, 0) or 0)
except sqlite3.IntegrityError: if v > max_id:
pass max_id = v
sample = [ except:
('Americano','Minuman',20000,10,None,1,0), continue
('Latte','Minuman',25000,5,None,1,10), return str(max_id + 1)
('Banana Cake','Dessert',30000,2,None,1,0),
('Nasi Goreng','Makanan',35000,0,None,0,0),
]
for name,kategori,harga,stok,foto,tersedia,disc in sample: def init_db_csv():
c.execute("SELECT id FROM menu WHERE nama=?", (name,)) ensure_file(USERS_CSV, ["id", "username", "password", "role"])
if c.fetchone() is None: ensure_file(MENU_CSV, ["id", "nama", "kategori", "harga", "stok", "foto", "tersedia", "item_discount_pct"])
c.execute("""INSERT INTO menu (nama,kategori,harga,stok,foto,tersedia,item_discount_pct) ensure_file(PROMO_CSV, ["code", "type", "value", "min_total"])
VALUES (?,?,?,?,?,?,?)""", (name,kategori,harga,stok,foto,tersedia,disc))
promos = [ seed_defaults()
('CAFE10','percent',10,0),
('HEMAT5000','fixed',5000,20000),
]
for code,ptype,val,min_total in promos:
try:
c.execute("INSERT INTO promo (code,type,value,min_total) VALUES (?,?,?,?)", (code,ptype,val,min_total))
except sqlite3.IntegrityError: # buat masukin data/sample ke database csv
pass
conn.commit() def seed_defaults():
users = read_all(USERS_CSV)
if not users:
defaults = [
('admin','admin123','admin'),
('kasir','kasir123','kasir'),
('waiter','waiter123','waiter'),
('user','user123','pembeli'),
('owner','owner123','pemilik'),
]
rows = []
for i,(u,p,r) in enumerate(defaults, start=1):
rows.append({"id": str(i), "username": u, "password": p, "role": r})
write_all(USERS_CSV, ["id","username","password","role"], rows)
menu_rows = read_all(MENU_CSV)
if not menu_rows:
sample = [
('Americano','Minuman',20000,10,None,1,0),
('Latte','Minuman',25000,5,None,1,10),
('Banana Cake','Dessert',30000,2,None,1,0),
('Nasi Goreng','Makanan',35000,0,None,0,0),
]
rows = []
for i,(name,kategori,harga,stok,foto,tersedia,disc) in enumerate(sample, start=1):
rows.append({
"id": str(i),
"nama": name,
"kategori": kategori,
"harga": str(harga),
"stok": str(stok),
"foto": foto or "",
"tersedia": str(tersedia),
"item_discount_pct": str(disc)
})
write_all(MENU_CSV, ["id","nama","kategori","harga","stok","foto","tersedia","item_discount_pct"], rows)
promo_rows = read_all(PROMO_CSV)
if not promo_rows:
promos = [
('PARDEDE','percent',10,0),
('BOTAK','fixed',5000,20000),
]
rows = []
for code,ptype,val,min_total in promos:
rows.append({
"code": code,
"type": ptype,
"value": str(val),
"min_total": str(min_total)
})
write_all(PROMO_CSV, ["code","type","value","min_total"], rows)
def authenticate(username, password): def authenticate(username, password):
conn = sqlite3.connect(DB_PATH) rows = read_all(USERS_CSV)
c = conn.cursor() for r in rows:
c.execute("SELECT id,username,role FROM users WHERE username=? AND password=?", (username,password)) if r.get("username") == username and r.get("password") == password:
r = c.fetchone() return {'id': int(r.get("id")), 'username': r.get("username"), 'role': r.get("role")}
conn.close()
if r:
return {'id':r[0],'username':r[1],'role':r[2]}
return None return None
@ -110,170 +142,291 @@ def authenticate(username, password):
# Bagian Menu wel
# Wilayah dikuasai Menu
def menu_add(nama, kategori, harga, stok, foto, item_discount_pct=0): def menu_add(nama, kategori, harga, stok, foto, item_discount_pct=0):
conn = sqlite3.connect(DB_PATH) rows = read_all(MENU_CSV)
c = conn.cursor() new_id = next_int_id(rows, "id")
tersedia = 1 if stok>0 else 0 tersedia = "1" if int(stok) > 0 else "0"
c.execute("""INSERT INTO menu (nama,kategori,harga,stok,foto,tersedia,item_discount_pct) rows.append({
VALUES (?,?,?,?,?,?,?)""", (nama,kategori,harga,stok,foto,tersedia,item_discount_pct)) "id": new_id,
conn.commit() "nama": nama,
conn.close() "kategori": kategori,
"harga": str(float(harga)),
"stok": str(int(stok)),
"foto": foto or "",
"tersedia": tersedia,
"item_discount_pct": str(float(item_discount_pct))
})
write_all(MENU_CSV, ["id","nama","kategori","harga","stok","foto","tersedia","item_discount_pct"], rows)
def menu_update(menu_id, nama, kategori, harga, stok, foto, item_discount_pct=0): def menu_update(menu_id, nama, kategori, harga, stok, foto, item_discount_pct=0):
conn = sqlite3.connect(DB_PATH) rows = read_all(MENU_CSV)
c = conn.cursor() found = False
tersedia = 1 if stok>0 else 0 for r in rows:
c.execute("""UPDATE menu SET nama=?,kategori=?,harga=?,stok=?,foto=?,tersedia=?,item_discount_pct=? if r.get("id") == str(menu_id):
WHERE id=?""", (nama,kategori,harga,stok,foto,tersedia,item_discount_pct, menu_id)) r["nama"] = nama
conn.commit() r["kategori"] = kategori
conn.close() r["harga"] = str(float(harga))
r["stok"] = str(int(stok))
r["foto"] = foto or ""
r["tersedia"] = "1" if int(stok) > 0 else "0"
r["item_discount_pct"] = str(float(item_discount_pct))
found = True
break
if found:
write_all(MENU_CSV, ["id","nama","kategori","harga","stok","foto","tersedia","item_discount_pct"], rows)
else:
raise ValueError("Menu id tidak ditemukan")
def menu_delete(menu_id): def menu_delete(menu_id):
conn = sqlite3.connect(DB_PATH) rows = read_all(MENU_CSV)
c = conn.cursor() newrows = [r for r in rows if r.get("id") != str(menu_id)]
c.execute("DELETE FROM menu WHERE id=?", (menu_id,)) write_all(MENU_CSV, ["id","nama","kategori","harga","stok","foto","tersedia","item_discount_pct"], newrows)
conn.commit()
conn.close()
def menu_list(kategori=None, available_only=False, search_text=None): def menu_list(kategori=None, available_only=False, search_text=None):
conn = sqlite3.connect(DB_PATH) rows = read_all(MENU_CSV)
c = conn.cursor() out = []
q = "SELECT id,nama,kategori,harga,stok,foto,tersedia,item_discount_pct FROM menu" for r in rows:
conditions = [] if kategori and r.get("kategori") != kategori:
params = [] continue
if kategori: if available_only and r.get("tersedia") != "1":
conditions.append("kategori=?") continue
params.append(kategori) if search_text:
if available_only: s = search_text.lower()
conditions.append("tersedia=1") if s not in (r.get("nama","").lower() or "") and s not in (r.get("kategori","").lower() or ""):
if search_text: continue
conditions.append("(nama LIKE ? OR kategori LIKE ?)") try:
params += [f"%{search_text}%", f"%{search_text}%"] mid = int(r.get("id") or 0)
if conditions: except:
q += " WHERE " + " AND ".join(conditions) mid = r.get("id")
q += " ORDER BY id ASC" try:
c.execute(q, params) harga = float(r.get("harga") or 0.0)
rows = c.fetchall() except:
conn.close() harga = 0.0
return rows try:
stok = int(float(r.get("stok") or 0))
except:
stok = 0
foto = r.get("foto") or None
tersedia = 1 if r.get("tersedia") == "1" else 0
try:
item_disc = float(r.get("item_discount_pct") or 0.0)
except:
item_disc = 0.0
out.append((mid, r.get("nama"), r.get("kategori"), harga, stok, foto, tersedia, item_disc))
out.sort(key=lambda x: int(x[0]))
return out
def menu_get(menu_id): def menu_get(menu_id):
conn = sqlite3.connect(DB_PATH) rows = read_all(MENU_CSV)
c = conn.cursor() for r in rows:
c.execute("SELECT id,nama,kategori,harga,stok,foto,tersedia,item_discount_pct FROM menu WHERE id=?", (menu_id,)) if r.get("id") == str(menu_id):
r = c.fetchone() try:
conn.close() mid = int(r.get("id") or 0)
return r except:
mid = r.get("id")
try:
harga = float(r.get("harga") or 0.0)
except:
harga = 0.0
try:
stok = int(float(r.get("stok") or 0))
except:
stok = 0
foto = r.get("foto") or None
tersedia = 1 if r.get("tersedia") == "1" else 0
try:
item_disc = float(r.get("item_discount_pct") or 0.0)
except:
item_disc = 0.0
return (mid, r.get("nama"), r.get("kategori"), harga, stok, foto, tersedia, item_disc)
return None
def menu_decrease_stock(menu_id, qty): def menu_decrease_stock(menu_id, qty):
conn = sqlite3.connect(DB_PATH) rows = read_all(MENU_CSV)
c = conn.cursor() found = False
c.execute("SELECT stok FROM menu WHERE id=?", (menu_id,)) for r in rows:
r = c.fetchone() if r.get("id") == str(menu_id):
if not r: found = True
conn.close() try:
stok = int(float(r.get("stok") or 0))
except:
stok = 0
if stok < qty:
return False, "Stok tidak cukup"
newstok = stok - qty
r["stok"] = str(newstok)
r["tersedia"] = "1" if newstok > 0 else "0"
break
if not found:
return False, "Menu tidak ditemukan" return False, "Menu tidak ditemukan"
stok = r[0] write_all(MENU_CSV, ["id","nama","kategori","harga","stok","foto","tersedia","item_discount_pct"], rows)
if stok < qty:
conn.close()
return False, "Stok tidak cukup"
newstok = stok - qty
tersedia = 1 if newstok>0 else 0
c.execute("UPDATE menu SET stok=?, tersedia=? WHERE id=?", (newstok, tersedia, menu_id))
conn.commit()
conn.close()
return True, newstok return True, newstok
# Bagian Promooo
# Reza balap liar
# wilayah dikuasai promo
def promo_add(code, ptype, value, min_total=0): def promo_add(code, ptype, value, min_total=0):
conn = sqlite3.connect(DB_PATH) rows = read_all(PROMO_CSV)
c = conn.cursor() for r in rows:
c.execute("INSERT INTO promo (code,type,value,min_total) VALUES (?,?,?,?)", (code,ptype,value,min_total)) if r.get("code") == code:
conn.commit() raise ValueError("Kode promo sudah ada")
conn.close() rows.append({
"code": code,
"type": ptype,
"value": str(float(value)),
"min_total": str(float(min_total))
})
write_all(PROMO_CSV, ["code","type","value","min_total"], rows)
def promo_update(code, ptype, value, min_total=0): def promo_update(code, ptype, value, min_total=0):
conn = sqlite3.connect(DB_PATH) rows = read_all(PROMO_CSV)
c = conn.cursor() found = False
c.execute("UPDATE promo SET type=?, value=?, min_total=? WHERE code=?", (ptype,value,min_total,code)) for r in rows:
conn.commit() if r.get("code") == code:
conn.close() r["type"] = ptype
r["value"] = str(float(value))
r["min_total"] = str(float(min_total))
found = True
break
if not found:
raise ValueError("Promo tidak ditemukan")
write_all(PROMO_CSV, ["code","type","value","min_total"], rows)
def promo_delete(code): def promo_delete(code):
conn = sqlite3.connect(DB_PATH) rows = read_all(PROMO_CSV)
c = conn.cursor() newrows = [r for r in rows if r.get("code") != code]
c.execute("DELETE FROM promo WHERE code=?", (code,)) write_all(PROMO_CSV, ["code","type","value","min_total"], newrows)
conn.commit()
conn.close()
def promo_list(): def promo_list():
conn = sqlite3.connect(DB_PATH) rows = read_all(PROMO_CSV)
c = conn.cursor() out = []
c.execute("SELECT code,type,value,min_total FROM promo ORDER BY code") for r in rows:
rows = c.fetchall() try:
conn.close() val = float(r.get("value") or 0.0)
return rows except:
val = 0.0
try:
mt = float(r.get("min_total") or 0.0)
except:
mt = 0.0
out.append((r.get("code"), r.get("type"), val, mt))
out.sort(key=lambda x: x[0] or "")
return out
def promo_get(code): def promo_get(code):
conn = sqlite3.connect(DB_PATH) rows = read_all(PROMO_CSV)
c = conn.cursor() for r in rows:
c.execute("SELECT code,type,value,min_total FROM promo WHERE code=?", (code,)) if r.get("code") == code:
r = c.fetchone() try:
conn.close() val = float(r.get("value") or 0.0)
return r except:
val = 0.0
try:
mt = float(r.get("min_total") or 0.0)
except:
mt = 0.0
return (r.get("code"), r.get("type"), val, mt)
return None
# 19 juta lapangan badmin
# Buat logika diskon + promok
def apply_discounts_and_promo(cart_items, promo_code=None): def apply_discounts_and_promo(cart_items, promo_code=None):
"""
cart_items: list of dicts: [{'menu_id':..,'qty':..}, ...]
returns breakdown: subtotal, item_discount_total, promo_code, promo_discount, total
- uses item_discount_pct from menu table
- promo_code can be percent or fixed, with min_total
"""
conn = sqlite3.connect(DB_PATH)
c = conn.cursor()
subtotal = 0.0 subtotal = 0.0
item_discount_total = 0.0 item_discount_total = 0.0
menu_rows = read_all(MENU_CSV)
menu_dict = {r["id"]: r for r in menu_rows}
for it in cart_items: for it in cart_items:
c.execute("SELECT harga,item_discount_pct FROM menu WHERE id=?", (it['menu_id'],)) mid = str(it.get('menu_id'))
r = c.fetchone() r = menu_dict.get(mid)
if not r: if not r:
continue continue
price, item_disc_pct = r try:
qty = it.get('qty',1) price = float(r.get("harga") or 0.0)
except:
price = 0.0
try:
item_disc_pct = float(r.get("item_discount_pct") or 0.0)
except:
item_disc_pct = 0.0
qty = int(it.get('qty', 1))
line = price * qty line = price * qty
subtotal += line subtotal += line
if item_disc_pct and item_disc_pct > 0: if item_disc_pct and item_disc_pct > 0:
item_discount_total += (price * qty) * (item_disc_pct/100.0) item_discount_total += (price * qty) * (item_disc_pct / 100.0)
promo_discount = 0.0 promo_discount = 0.0
promo_applied = None promo_applied = None
if promo_code: if promo_code:
c.execute("SELECT type,value,min_total FROM promo WHERE code=?", (promo_code,)) p = promo_get(promo_code)
row = c.fetchone() if p:
if row: _, ptype, val, min_total = p
ptype, val, min_total = row if subtotal >= (min_total or 0.0):
if subtotal >= min_total:
if ptype == 'percent': if ptype == 'percent':
promo_discount = (subtotal - item_discount_total) * (val/100.0) promo_discount = (subtotal - item_discount_total) * (val / 100.0)
else: else:
promo_discount = val promo_discount = val
promo_applied = promo_code promo_applied = promo_code
total = subtotal - item_discount_total - promo_discount total = subtotal - item_discount_total - promo_discount
if total < 0: if total < 0:
total = 0.0 total = 0.0
conn.close()
return { return {
'subtotal': round(subtotal,2), 'subtotal': round(subtotal, 2),
'item_discount': round(item_discount_total,2), 'item_discount': round(item_discount_total, 2),
'promo_code': promo_applied, 'promo_code': promo_applied,
'promo_discount': round(promo_discount,2), 'promo_discount': round(promo_discount, 2),
'total': round(total,2) 'total': round(total, 2)
} }
@ -281,16 +434,25 @@ def apply_discounts_and_promo(cart_items, promo_code=None):
# wilayah UI (universitas indonesia)
# Wilayah dikuasai UI
class App: class App:
def __init__(self, root): def __init__(self, root):
self.root = root self.root = root
self.root.title("Cafe Totoro") self.root.title("Cafe Totoro Mania")
self.session = None self.session = None
self.img_cache = {} self.img_cache = {}
self.setup_ui() self.setup_ui()
def setup_ui(self): def setup_ui(self):
@ -298,18 +460,13 @@ class App:
self.root.resizable(False, False) self.root.resizable(False, False)
self.login_frame() self.login_frame()
# windah batubara
# tampilan login dan logout
def login_frame(self): def login_frame(self):
for w in self.root.winfo_children(): for w in self.root.winfo_children():
w.destroy() w.destroy()
frame = ttk.Frame(self.root, padding=20) frame = ttk.Frame(self.root, padding=20)
frame.pack(expand=True) frame.pack(expand=True)
ttk.Label(frame, text="LOGIN", font=("Arial", 24)).grid(row=0, column=0, columnspan=2, pady=10) ttk.Label(frame, text="Login kak", font=("Arial", 24)).grid(row=0, column=0, columnspan=2, pady=10)
ttk.Label(frame, text="Username:").grid(row=1, column=0, sticky='e', pady=5) ttk.Label(frame, text="Username:").grid(row=1, column=0, sticky='e', pady=5)
self.username_var = tk.StringVar() self.username_var = tk.StringVar()
@ -335,17 +492,11 @@ class App:
messagebox.showinfo("Sukses", f"Login berhasil sebagai {user['role']}") messagebox.showinfo("Sukses", f"Login berhasil sebagai {user['role']}")
self.dashboard_frame() self.dashboard_frame()
def logout(self): def logout(self):
self.session = None self.session = None
self.img_cache.clear() self.img_cache.clear()
self.login_frame() self.login_frame()
# tampilan dashboard untuk admin dah ngantuk we
def dashboard_frame(self): def dashboard_frame(self):
for w in self.root.winfo_children(): for w in self.root.winfo_children():
w.destroy() w.destroy()
@ -372,13 +523,6 @@ class App:
self.build_menu_manage_tab(self.tab_menu_manage) self.build_menu_manage_tab(self.tab_menu_manage)
self.build_promo_tab(self.tab_promo) self.build_promo_tab(self.tab_promo)
# Bagian Search dan Filter
def build_menu_view_tab(self, parent): def build_menu_view_tab(self, parent):
for w in parent.winfo_children(): for w in parent.winfo_children():
w.destroy() w.destroy()
@ -404,14 +548,6 @@ class App:
self.view_tree.pack(fill='both', expand=True) self.view_tree.pack(fill='both', expand=True)
self.view_tree.bind("<<TreeviewSelect>>", self.on_view_select) self.view_tree.bind("<<TreeviewSelect>>", self.on_view_select)
# Preview Image
ttk.Label(right, text="Preview Item", font=("Arial", 12, "bold")).pack(pady=6) ttk.Label(right, text="Preview Item", font=("Arial", 12, "bold")).pack(pady=6)
self.preview_label = ttk.Label(right, text="Pilih menu di kiri") self.preview_label = ttk.Label(right, text="Pilih menu di kiri")
self.preview_label.pack() self.preview_label.pack()
@ -460,15 +596,6 @@ class App:
else: else:
self.preview_img_label.config(image='') self.preview_img_label.config(image='')
# bagian menu manage khusus admin
def build_menu_manage_tab(self, parent): def build_menu_manage_tab(self, parent):
for w in parent.winfo_children(): for w in parent.winfo_children():
w.destroy() w.destroy()
@ -588,16 +715,6 @@ class App:
if p: if p:
var.set(p) var.set(p)
# Promo manage Khusus Admin
def build_promo_tab(self, parent): def build_promo_tab(self, parent):
for w in parent.winfo_children(): for w in parent.winfo_children():
w.destroy() w.destroy()
@ -671,12 +788,11 @@ class App:
messagebox.showinfo("Sukses", "Promo ditambahkan") messagebox.showinfo("Sukses", "Promo ditambahkan")
w.destroy() w.destroy()
self.reload_promo_table() self.reload_promo_table()
except sqlite3.IntegrityError: except Exception as e:
messagebox.showerror("Error", "Kode promo sudah ada") messagebox.showerror("Error", f"Kode promo sudah ada atau error: {e}")
ttk.Button(frm, text="Simpan", command=save).grid(row=4, column=1, pady=12) ttk.Button(frm, text="Simpan", command=save).grid(row=4, column=1, pady=12)
def open_edit_promo(self): def open_edit_promo(self):
sel = self.promo_tree.selection() sel = self.promo_tree.selection()
if not sel: if not sel:
@ -736,7 +852,6 @@ class App:
ttk.Button(frm, text="Update", command=save).grid(row=4, column=1, pady=12) ttk.Button(frm, text="Update", command=save).grid(row=4, column=1, pady=12)
def delete_selected_promo(self): def delete_selected_promo(self):
sel = self.promo_tree.selection() sel = self.promo_tree.selection()
if not sel: if not sel:
@ -750,10 +865,16 @@ class App:
# Done
if __name__ == "__main__": if __name__ == "__main__":
init_conn = init_db() init_db_csv()
init_conn.close()
root = tk.Tk() root = tk.Tk()
app = App(root) app = App(root)
root.mainloop() root.mainloop()

5
menu.csv Normal file
View File

@ -0,0 +1,5 @@
id,nama,kategori,harga,stok,foto,tersedia,item_discount_pct
1,Americano,Minuman,20000,10,,1,0
2,Latte,Minuman,25000,5,,1,10
3,Banana Cake,Dessert,30000,2,,1,0
4,Nasi Goreng,Makanan,35000,0,,0,0
1 id nama kategori harga stok foto tersedia item_discount_pct
2 1 Americano Minuman 20000 10 1 0
3 2 Latte Minuman 25000 5 1 10
4 3 Banana Cake Dessert 30000 2 1 0
5 4 Nasi Goreng Makanan 35000 0 0 0

3
promo.csv Normal file
View File

@ -0,0 +1,3 @@
code,type,value,min_total
PARDEDE,percent,10,0
BOTAK,fixed,5000,20000
1 code type value min_total
2 PARDEDE percent 10 0
3 BOTAK fixed 5000 20000

6
users.csv Normal file
View File

@ -0,0 +1,6 @@
id,username,password,role
1,admin,admin123,admin
2,kasir,kasir123,kasir
3,waiter,waiter123,waiter
4,user,user123,pembeli
5,owner,owner123,pemilik
1 id username password role
2 1 admin admin123 admin
3 2 kasir kasir123 kasir
4 3 waiter waiter123 waiter
5 4 user user123 pembeli
6 5 owner owner123 pemilik