import { endpoints } from "./config.js"; import { t } from "./i18n.js"; import { trackEvent } from "./analytics.js"; import { requireFullAccess } from "./access.js"; import { buildBillRequestQueueMessage, buildWaiterCallQueueMessage, cacheOpenBills, ensureGuestActionAllowed, guestActionBlockedMessage, queueGuestAction, refreshGuestPendingActions, } from "./queue.js"; import { showToast } from "./toast.js"; import { getBillState, getHashParam, getTableParam, setBillState, } from "./state.js"; function sendApiSimulated(actionName, details) { console.log(`[SYMULACJA API] Akcja: ${actionName}`, details); // Przykładowe wysłanie docelowo: // if (window.socket && window.socket.readyState === WebSocket.OPEN) { // window.socket.send(JSON.stringify({ action: "sendUpstream", payload: { type: actionName, table: tableParam, ...details } })); // } } export async function callWaiter(type) { if (type !== "order") return; if (!(await ensureGuestActionAllowed("waiter_call"))) { return; } const queued = await queueGuestAction("waiter_call", buildWaiterCallQueueMessage(), { waiterType: "order", }); if (!queued.ok) { if (queued.reason === "pending") { showToast(guestActionBlockedMessage("waiter_call")); } else { showToast(t("waiter.toast_fail")); } return; } trackEvent("waiter_call_requested", { waiterType: "order" }); sendApiSimulated("CallWaiter_Order", { table: getTableParam() }); showToast(t("waiter.toast_ok")); } export function openWaiterDialog() { requireFullAccess("waiter", () => { openWaiterDialogInternal(); }); } export async function openWaiterDialogInternal() { if (!(await ensureGuestActionAllowed("waiter_call"))) { return; } document.getElementById("waiterModal").classList.add("active"); document.body.style.overflow = "hidden"; } export function closeWaiterDialog() { document.getElementById("waiterModal").classList.remove("active"); document.body.style.overflow = ""; } export async function confirmCallWaiter() { closeWaiterDialog(); await callWaiter("order"); } export async function proceedToBillPayment() { if (!(await ensureGuestActionAllowed("bill_request"))) { return; } goToStep("stepPayment"); } export function openBillDialog() { requireFullAccess("bill", () => { openBillDialogInternal(); }); } export async function openBillDialogInternal() { await refreshGuestPendingActions(); trackEvent("bill_dialog_opened"); setBillState({ payment: "", doc: "", nip: "", company: null, selectedBillId: null }); document.getElementById("billModal").classList.add("active"); document.body.style.overflow = "hidden"; // Zablokuj scroll tła document.getElementById("billLoading").classList.remove("hidden"); document.getElementById("billLoading").textContent = t("bill.loading"); document.getElementById("billListContainer").classList.add("hidden"); goToStep("stepBillList"); try { const res = await fetch(`${endpoints.bills}?h=${encodeURIComponent(getHashParam())}`); const result = await res.json(); if (result.status === "success" && result.data.length > 0) { const bills = result.data; cacheOpenBills(bills); if (bills.length === 1) { showBillReview(bills[0]); document.getElementById("btnBackToBills").style.display = "none"; } else { renderBillList(bills); document.getElementById("btnBackToBills").style.display = "block"; } } else { document.getElementById("billLoading").innerHTML = t("bill.loading_empty"); } } catch (err) { document.getElementById("billLoading").innerHTML = t("bill.loading_error"); } } function renderBillList(bills) { document.getElementById("billLoading").classList.add("hidden"); document.getElementById("billListContainer").classList.remove("hidden"); const container = document.getElementById("billListItems"); container.innerHTML = ""; bills.forEach((b) => { const div = document.createElement("div"); div.className = "option-card"; div.style.flexDirection = "row"; div.style.justifyContent = "space-between"; div.style.padding = "15px"; div.onclick = () => showBillReview(b); const numerFormat = b.numer ? `#${b.numer}` : t("bill.bill_fallback"); div.innerHTML = `
${numerFormat}
${b.opis}
${b.suma.toFixed(2)} PLN
`; container.appendChild(div); }); } export function goBackToBillList() { goToStep("stepBillList"); } export function showBillReview(bill) { const billState = getBillState(); billState.selectedBillId = bill.id; const content = document.getElementById("billReviewContent"); content.innerHTML = ""; bill.pozycje.forEach((p) => { const div = document.createElement("div"); div.style.display = "flex"; div.style.justifyContent = "space-between"; div.style.marginBottom = "8px"; div.style.borderBottom = "1px solid rgba(255,255,255,0.05)"; div.style.paddingBottom = "8px"; div.innerHTML = `
${p.nazwa}
${p.ilosc} x ${p.cena.toFixed(2)} PLN
${p.wartosc.toFixed(2)} PLN
`; content.appendChild(div); }); document.getElementById("billTotalAmount").textContent = bill.suma.toFixed(2) + " PLN"; goToStep("stepBillReview"); } export function closeBillDialog() { document.getElementById("billModal").classList.remove("active"); document.body.style.overflow = ""; // Odblokuj scroll tła } export function goToStep(stepId) { document.querySelectorAll(".step").forEach((el) => el.classList.remove("active")); document.getElementById(stepId).classList.add("active"); } export function selectPayment(method) { getBillState().payment = method; goToStep("stepDocument"); } export async function selectDocument(docType) { const billState = getBillState(); billState.doc = docType; if (docType === "paragon") { if (!(await ensureGuestActionAllowed("bill_request"))) { return; } const queued = await queueGuestAction("bill_request", buildBillRequestQueueMessage("paragon"), { payment: billState.payment || null, docType: "paragon", }); if (!queued.ok) { if (queued.reason === "pending") { showToast(guestActionBlockedMessage("bill_request")); } else { showToast(t("bill.toast_fail")); } return; } trackEvent("bill_request_sent", { docType: "paragon" }); closeBillDialog(); sendApiSimulated("CallWaiter_Bill", { table: getTableParam(), billId: billState.selectedBillId, payment: billState.payment, doc: "paragon", }); showToast(t("bill.toast_receipt")); } else { goToStep("stepNIP"); document.getElementById("nipInput").value = ""; setTimeout(() => document.getElementById("nipInput").focus(), 100); } } export async function fetchGUS() { const nip = document.getElementById("nipInput").value.replace(/[\s-]/g, ""); if (nip.length < 10) { alert(t("bill.nip_invalid")); return; } const btn = document.getElementById("btnGUS"); btn.textContent = t("bill.gus_searching"); btn.disabled = true; try { const response = await fetch(`${endpoints.gusLookup}?nip=${encodeURIComponent(nip)}`); const result = await response.json(); if (result.status && result.data) { const data = result.data; let fullStreet = data.street || ""; if (data.propertyNumber) fullStreet += " " + data.propertyNumber; if (data.apartmentNumber) fullStreet += "/" + data.apartmentNumber; const billState = getBillState(); billState.nip = nip; billState.company = { name: data.name, street: fullStreet.trim(), zip: data.zipCode, city: data.city, nip: data.nip, }; document.getElementById("cmpName").value = billState.company.name; document.getElementById("cmpStreet").value = billState.company.street; document.getElementById("cmpZip").value = billState.company.zip; document.getElementById("cmpCity").value = billState.company.city; document.getElementById("cmpNip").value = `${t("bill.queue_nip")} ${billState.company.nip}`; // reset do readonly document.getElementById("cmpName").readOnly = true; document.getElementById("cmpStreet").readOnly = true; document.getElementById("cmpZip").readOnly = true; document.getElementById("cmpCity").readOnly = true; document.getElementById("btnEditCompany").textContent = t("bill.edit_company"); goToStep("stepVerify"); } else { alert(t("bill.gus_fail")); } } catch (error) { console.error("Błąd pobierania danych z GUS:", error); alert(t("bill.gus_error")); } finally { btn.textContent = t("bill.gus"); btn.disabled = false; } } export function editCompanyData() { const n = document.getElementById("cmpName"); const s = document.getElementById("cmpStreet"); const z = document.getElementById("cmpZip"); const c = document.getElementById("cmpCity"); const btn = document.getElementById("btnEditCompany"); if (n.readOnly) { n.readOnly = false; s.readOnly = false; z.readOnly = false; c.readOnly = false; n.focus(); btn.textContent = t("bill.edit_done"); } else { n.readOnly = true; s.readOnly = true; z.readOnly = true; c.readOnly = true; btn.textContent = t("bill.edit_company"); } } export async function confirmInvoice() { const billState = getBillState(); billState.company.name = document.getElementById("cmpName").value; billState.company.street = document.getElementById("cmpStreet").value; billState.company.zip = document.getElementById("cmpZip").value; billState.company.city = document.getElementById("cmpCity").value; if (!(await ensureGuestActionAllowed("bill_request"))) { return; } const queued = await queueGuestAction("bill_request", buildBillRequestQueueMessage("faktura"), { payment: billState.payment || null, docType: "faktura", nip: billState.nip || null, company: billState.company || null, }); if (!queued.ok) { if (queued.reason === "pending") { showToast(guestActionBlockedMessage("bill_request")); } else { showToast(t("bill.toast_fail")); } return; } closeBillDialog(); trackEvent("bill_request_sent", { docType: "faktura" }); sendApiSimulated("CallWaiter_Bill", { table: getTableParam(), billId: billState.selectedBillId, payment: billState.payment, doc: "faktura", nip: billState.nip, company: billState.company, }); showToast(t("bill.toast_invoice")); }