Spaces:
Running
Running
| const scriptURL = "https://api.sheetbest.com/sheets/67a68e64-dca9-4eea-99b7-0431c5786cf6"; | |
| const menu = [ | |
| { | |
| section: "เมนูข้าวต้ม", | |
| items: [ | |
| { name: "ข้าวต้มปลา (ปลาช่อน)", price: 59 }, | |
| { name: "ข้าวต้มปลา (ปลากระพง)", price: 79 }, | |
| { name: "ข้าวต้มปลาแห้ง (ปลาช่อน)", price: 59 }, | |
| { name: "ข้าวต้มปลาแห้ง (ปลากระพง)", price: 79 }, | |
| { name: "ข้าวต้มกุ้ง", price: 79 }, | |
| { name: "ข้าวต้มปลาหมึก", price: 59 }, | |
| { name: "ข้าวต้มทะเล", price: 99 } | |
| ] | |
| }, | |
| { | |
| section: "เมนูอาหารไทย", | |
| items: [ | |
| { name: "ผัดฉ่าปลา (ปลาช่อน)", price: 69 }, | |
| { name: "ผัดฉ่าปลา (ปลากระพง)", price: 89 }, | |
| { name: "ผัดขี้เมาปลา (ปลาช่อน)", price: 69 }, | |
| { name: "ผัดขี้เมาปลา (ปลากระพง)", price: 89 }, | |
| { name: "ต้มยำเนื้อปลา (ปลาช่อน)", price: 69 }, | |
| { name: "ต้มยำเนื้อปลา (ปลากระพง)", price: 89 }, | |
| { name: "ต้มยำหัวปลา", price: 89 }, | |
| { name: "ต้มยำทะเล", price: 109 }, | |
| { name: "ต้มยำกุ้ง", price: 99 }, | |
| { name: "เกาเหลาปลา (ปลาช่อน)", price: 79 }, | |
| { name: "เกาเหลาปลา (ปลากระพง)", price: 99 }, | |
| { name: "เกาเหลาทะเล", price: 109 }, | |
| { name: "ลวกจิ้มปลา (ปลาช่อน)", price: 79 }, | |
| { name: "ลวกจิ้มปลา (ปลากระพง)", price: 99 }, | |
| { name: "รวมทะเลลวกจิ้ม", price: 129 }, | |
| { name: "ยำรวมทะเล", price: 109 }, | |
| { name: "ยำแมงกะพรุน", price: 69 }, | |
| { name: "แมงกะพรุนน้ำมันงา", price: 59 } | |
| ] | |
| }, | |
| { | |
| section: "ของทอด", | |
| items: [ | |
| { name: "แหนมกระดูกอ่อนหมู", price: 69 }, | |
| { name: "ปีกไก่ทอด", price: 79 }, | |
| { name: "คางกุ้งทอด", price: 59 }, | |
| { name: "เฟรนซ์ฟรายส์", price: 59 }, | |
| { name: "ไข่เจียว", price: 20 } | |
| ] | |
| }, | |
| { | |
| section: "เครื่องดื่ม/อื่นๆ", | |
| items: [ | |
| { name: "ข้าวสวย", price: 10 }, | |
| { name: "น้ำเปล่า", price: 10 }, | |
| { name: "น้ำอัดลม", price: 15 }, | |
| { name: "น้ำอัดลม ขวดใหญ่", price: 40 }, | |
| { name: "น้ำแข็ง", price: 25 }, | |
| { name: "โซดา", price: 20 } | |
| ] | |
| } | |
| ]; | |
| function renderMenuDropdown() { | |
| const select = document.getElementById("add-menu"); | |
| let html = `<option value="">เลือกเมนู</option>`; | |
| menu.forEach(section => { | |
| section.items.forEach(item => { | |
| html += `<option value="${item.name}">${item.name} (${item.price} ฿)</option>`; | |
| }); | |
| }); | |
| select.innerHTML = html; | |
| } | |
| // ฟังก์ชันสำคัญ: เอาเฉพาะรายการ unpaid ล่าสุด (ที่ไม่มี deleted/paid ทับ) ต่อเมนู | |
| function getLatestUnpaidOrders(data, tableNum) { | |
| const rows = data.filter(i => String(i.table).trim() === String(tableNum)); | |
| // เก็บสถานะล่าสุดของแต่ละเมนู | |
| const latest = {}; | |
| rows.forEach((row, idx) => { | |
| latest[row.menu] = { ...row, idx }; // ทับของเก่า, แถวท้ายสุดจะถูกใช้ | |
| }); | |
| return Object.values(latest).filter(r => (r.status ?? "unpaid") === "unpaid"); | |
| } | |
| // แสดงออเดอร์ | |
| async function loadOrder() { | |
| const table = document.getElementById("table").value; | |
| const res = await fetch(`${scriptURL}?table=${table}`); | |
| const data = await res.json(); | |
| const orders = getLatestUnpaidOrders(data, table); | |
| let html = ""; | |
| let sum = 0; | |
| if (orders.length === 0) { | |
| html = "<div style='color:#bbb'>ไม่มีออเดอร์ที่ยังไม่เช็กบิล</div>"; | |
| document.getElementById("checkout-btn").style.display = "none"; | |
| } else { | |
| orders.forEach(item => { | |
| const qty = Number(item.qty) || 1; | |
| const price = Number(item.price) || 0; | |
| html += `<div class="order-item"> | |
| <span>${item.menu} x${qty}</span> | |
| <span>${price * qty} ฿</span> | |
| <button onclick="removeOrder('${item.menu}')">ลบ</button> | |
| </div>`; | |
| sum += price * qty; | |
| }); | |
| document.getElementById("checkout-btn").style.display = "inline-block"; | |
| } | |
| document.getElementById("order-list").innerHTML = html; | |
| document.getElementById("total").textContent = sum ? `รวมทั้งหมด ${sum} ฿` : ""; | |
| } | |
| // เพิ่มออเดอร์ (POST status=unpaid) | |
| async function addOrder() { | |
| const table = document.getElementById("table").value; | |
| const menuName = document.getElementById("add-menu").value; | |
| const qty = parseInt(document.getElementById("add-qty").value, 10) || 1; | |
| let price = 0; | |
| menu.forEach(section => { | |
| section.items.forEach(item => { if(item.name === menuName) price = item.price; }); | |
| }); | |
| if (!menuName || !qty) return alert("กรุณาเลือกเมนูและจำนวน"); | |
| const now = new Date().toISOString().split(".")[0] + "Z"; | |
| for (let i = 0; i < qty; i++) { | |
| const order = { | |
| table: table, | |
| menu: menuName, | |
| price: price, | |
| qty: 1, | |
| note: "[เพิ่มโดยแอดมิน]", | |
| timestamp: now, | |
| status: "unpaid" | |
| }; | |
| await fetch(scriptURL, { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify(order), | |
| }); | |
| } | |
| alert("เพิ่มรายการสำเร็จ"); | |
| loadOrder(); | |
| } | |
| // ลบเมนู = POST status=deleted | |
| async function removeOrder(menuName) { | |
| const table = document.getElementById("table").value; | |
| if (!confirm(`ต้องการลบเมนู "${menuName}" ออกจากโต๊ะ ${table} ?`)) return; | |
| const now = new Date().toISOString().split(".")[0] + "Z"; | |
| const order = { | |
| table: table, | |
| menu: menuName, | |
| price: 0, | |
| qty: 1, | |
| note: "[ลบโดยแอดมิน]", | |
| timestamp: now, | |
| status: "deleted" | |
| }; | |
| await fetch(scriptURL, { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify(order), | |
| }); | |
| alert("ลบเมนูสำเร็จ"); | |
| loadOrder(); | |
| } | |
| // เช็กบิล = POST status=paid สำหรับทุกเมนู unpaid ที่ยังไม่ถูกเช็กบิล/ลบ | |
| async function checkout() { | |
| const table = document.getElementById("table").value; | |
| const res = await fetch(`${scriptURL}?table=${table}`); | |
| const data = await res.json(); | |
| const unpaidOrders = getLatestUnpaidOrders(data, table); | |
| const now = new Date().toISOString().split(".")[0] + "Z"; | |
| for (const order of unpaidOrders) { | |
| const paidOrder = { | |
| table: order.table, | |
| menu: order.menu, | |
| price: order.price, | |
| qty: order.qty, | |
| note: "[เช็กบิล]", | |
| timestamp: now, | |
| status: "paid" | |
| }; | |
| await fetch(scriptURL, { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify(paidOrder), | |
| }); | |
| } | |
| alert("เช็กบิลเรียบร้อย!"); | |
| loadOrder(); | |
| } | |
| renderMenuDropdown(); | |
| loadOrder(); | |