UNPKG

listojs

Version:

a package for restaurant management

774 lines (717 loc) 30.1 kB
/* listo_guest.js 14.11.2019 5:14:31,91 */ /*-----------------------------------*/ /* guest.js */ module = "guest.js"; release = "none"; // functional parameters: let idtable = 0; let idwaiter = 0; let guestCount = 0; let loginState = parseInt(sessionStorage.getItem("customerLoginCheck"), 10); const mandatoryIds = ["box0", "box1", "box2", "box3", "orderForm", "main-content", "languageDiv", "idbill", "idwaiter", "idtable", "username", "userpass", "addProductText", "inputSelectRole", "waiterName", "tableName", "customerLoginCheck", "text1", "text28", "text30", "text33", "text47", "text72", "text92", "text603", "text714", "text741", "closeOrder", "confirmOrder", "startOrder", "openMenu", "showCart", "showStatus"]; // visual parameters: let scrollingCustomized = false; let productDetailsCustomized = false; let waiterName; let tableName; let scrollingDuration = 250; let shownCategoryLevel = 1; /* Include this for language-selection into a <script>-tag at top of every customer-theme: const updateGuestTexts = function () { showSubCategories(0, ""); showCart(); showDeliveryStatus(); setGuestTexts(); }; const languageSelect = { pre: "<div><span><p>", suf: "</p></span></div>", callback: updateGuestTexts, styleClass:"", targetDiv:"main-content", languages: [{ id: "en", name: "English" }, { id: "de", name: "Deutsch" }, { id: "it", name: "Italiano" }] }; */ function checkLayoutPermission() { apiCall_listorante_public_layouts(function (data) { let allowed = false; console.log("Check permission of use for theme-Id '" + themeID + "':"); for (let i = 0; i < data.count; i++) { let checkedID = parseInt(data.rows[i].s[0], 10); console.log((1 + i) + ": Customer has permission to use theme '" + checkedID + "': " + JSON.stringify(data.rows[i].s)); if (checkedID === parseInt(themeID, 10)) { console.log("Permission for theme '" + themeID + "' found."); allowed = true; //break; } } if (!allowed) { const txt = "Sorry! The customer with CID '" + customerID + "' is not allowed to use this theme..."; document.getElementsByTagName("body")[0].innerHTML = "<h1>" + txt + "</h1>"; console.error(txt); } }, function (err) { showHttpErrorMessage("main-content", err); }) } checkLayoutPermission(); function verifyMandatoryClass(id, className) { try { const classNameAttribute = document.getElementById(id).getAttribute("class"); if (!classNameAttribute) { console.error("Element with mandatory id '" + id + "' has no class-attribute (Requires '" + className + "')"); return false; } const coIdx = classNameAttribute.indexOf(className); if (coIdx < 0) { console.error("Element with mandatory id '" + id + "' is missing the mandatory class-attribute '" + className + "'"); return false; } } catch (err) { console.error("Element with mandatory id '" + id + "' is missing or not properly configured: " + err.message); return false; } return true; } function verifyTheme() { debug("Checking theme...", release); showRelease(module); let check; let check2; let check3; let ok = true; for (let id = 0; id < mandatoryIds.length; id++) { try { check = document.getElementById(mandatoryIds[id]).innerText; check2 = document.getElementById(mandatoryIds[id]).innerHTML; check3 = document.getElementById(mandatoryIds[id]).value; debug2(module, "Check-results", release, [mandatoryIds[id], check, check2, check3]); if (mandatoryIds[id] === "inputSelectRole") { if (parseInt(check, 10) !== 3) { console.error("ERROR: Mandatory element with id '" + mandatoryIds[id] + "' must have value 3."); ok = false; } } } catch (err) { ok = false; if (!check) { console.error("ERROR: Mandatory element with id '" + mandatoryIds[id] + "' is missing in index.html." + JSON.stringify(err)); } else { console.error("Unexpected error: " + JSON.stringify(err)); console.error("Mandatory element with id '" + mandatoryIds[id] + "' is probably missing in index.html."); } } } ok = ok && verifyMandatoryClass("closeOrder", "close-order") && verifyMandatoryClass("confirmOrder", "submit-order") && verifyMandatoryClass("startOrder", "start-order") && verifyMandatoryClass("openMenu", "get-products") && verifyMandatoryClass("showCart", "show-cart") && verifyMandatoryClass("showStatus", "show-deliverystatus"); if (!ok) { console.error("Errors in this theme were detected. It is not properly configured and must not be used."); } } verifyTheme(); function setLoginState(state) { /* * loginState: * 0/NaN : user is not logged in * 1 : user is logged in * 2 : there are items in the list * */ sessionStorage.setItem("customerLoginCheck", state); loginState = parseInt(sessionStorage.getItem("customerLoginCheck"), 10); } function scrollToCustomerBox(divBoxName) { if (scrollingCustomized && typeof guestScroll === "function") { guestScroll(divBoxName); } else { standardScroll(divBoxName); } }; function standardScroll(boxName) { $('html, body').animate({ scrollTop: $("#" + boxName).offset().top }, scrollingDuration); }; function setGuestTexts() { debug("Setting texts...", release); setElemText(1); setElemText(6); setElemText(12); setElemText(30); setElemText(33); setElemText(35); setElemText(47); setElemText(72); setElemText(92); setElemText(603); setElemText(714); setElemText(741); apiCall_listorante_public_settings("ADD_PRODUCT_TEXT_" + locale, function (data) { const addHtml = document.getElementById("addProductText").innerHTML; if (addHtml) { $("#addProductText").html(addHtml); debug("addProductText=" + addHtml.toString(), release); } else { const addTxt = document.getElementById("addProductText").innerText; if (addTxt > 3) { $("#addProductText").text(addTxt); debug("addProductText=" + addTxt, release); } else { try { $("#addProductText").text(data.rows[0].s[0]); } catch (err) { try { $("#addProductText").text(getTextById(740)); } catch (err2) { try { $("#addProductText").text("+++"); } catch (err3) { debug("#addProductText not found.", release, err, err2, err3); } } } } } }, function (err) { debug("Setting 'ADD_PRODUCT_TEXT_" + locale + "' could not be retrieved", release, err); $("#addProductText").text("+"); }); } apiCall_listorante_public_settings("SHOWCATLEV", function (data) { shownCategoryLevel = data.rows[0].s[0]; debug2(module, "shown category level", RELEASE, [shownCategoryLevel]); }, function (err) { debug2(module, "could not retrieve setting 'SHOWCATLEV'", [err]); }); setGuestTexts(); document.getElementById("username").hidden = true; function guest0_categories(category, categoryText, data) { let box0 = categoryHeader(); let errArray = []; let levelCount = 0; for (let i = 0; i < data.count; i++) { if (parseInt(data.rows[i].s[3], 10) <= parseInt(shownCategoryLevel, 10)) { levelCount++; } } for (let i = 0; i < data.count; i++) { try { if (parseInt(data.rows[i].s[3], 10) <= parseInt(shownCategoryLevel, 10)) { box0 += categoryItem(i, data.rows[i].s, levelCount); } } catch (err) { debug2("guest", "Erroneous value in row " + i + " of category-data.", release, [data.rows[i].s]); for (let j = 0; j < data.rows[i].s.length; j++) { try { errArray[j] = data.rows[i].s[j]; } catch (err2) { errArray[j] = ""; } } try { box0 += categoryItem(i, errArray, levelCount); } catch (err3) { debug2("guest", "Erroneous value in row " + i + " could not be replaced.", release, [err3]); } } } box0 += categoryBottom(); return box0; } ; function guest1_product(data) { let box1 = productsHeader(); let errArray = []; for (let i = 0; i < data.count; i++) { try { box1 += productItem(i, data.rows[i].s, data.count); } catch (err) { debug2("guest", "Erroneous value in row " + i + " of product-data.", release, [data.rows[i].s]); for (let j = 0; j < data.rows[i].s.length; j++) { try { errArray[j] = data.rows[i].s[j]; } catch (err2) { errArray[j] = ""; } } try { box1 += productItem(i, errArray, data.count); } catch (err3) { debug2("guest", "Erroneous value in row " + i + " could not be replaced.", release, [err3]); } } } box1 += productsBottom(); return box1; }; function guest2_cart(data) { let total = ""; let box2 = cartHeader(); let errArray = []; for (let i = 0; i < data.count; i++) { try { if (data.rows[i].s[1].trim().startsWith("TOTAL")) { total = data.rows[i].s; } else { box2 += cartItem(i, data.rows[i].s); } } catch (err) { debug2("guest", "Erroneous value in row " + i + " of cart-data.", release, [data.rows[i].s]); for (let j = 0; j < data.rows[i].s.length; j++) { try { errArray[j] = data.rows[i].s[j]; } catch (err2) { errArray[j] = ""; } } try { box2 += cartItem(i, errArray); } catch (err3) { debug2("guest", "Erroneous value in row " + i + " could not be replaced.", release, [err3]); } } } box2 += cartItem("", total); box2 += cartBottom(); return box2; }; function guest3_orderstatus(data) { let box3 = deliveryHeader(); let errArray = []; for (let i = 0; i < data.count; i++) { try { box3 += deliveryItem(i, data.rows[i].s); } catch (err) { debug2("guest", "Erroneous value in row " + i + " of delivery-status-data.", release, [data.rows[i].s]); for (let j = 0; j < data.rows[i].s.length; j++) { try { errArray[j] = data.rows[i].s[j]; } catch (err2) { errArray[j] = ""; } } try { box3 += orderStatusItem(i, errArray); } catch (err3) { debug2("guest", "Erroneous value in row " + i + " could not be replaced.", release, [err3]); } } } box3 += deliveryBottom(); return box3; }; function showSubCategories(category, categoryText) { // CALL-ID: listorante.Public.4 apiCall_listorante_public_category(category, function (data) { document.getElementById("box0").innerHTML = guest0_categories(category, categoryText, data); }, function (err) { showHttpErrorMessage("main-content", err); }); } function showProductsOfCategory(catid) { if (catid == 0) document.getElementById("box1").innerHTML = ""; //else document.getElementById("box0").hidden = false; document.getElementById("box1").hidden = false; apiCall_listorante_public_product(catid, function (data) { document.getElementById("box1").innerHTML = guest1_product(data); }, function (err) { showHttpErrorMessage("main-content", err); }); } function addproduct(idbillnumber, prodid, tablenumber, waiternumber) { apiCall_listorante_guest_addtoproductlist(idbillnumber, prodid, tablenumber, waiternumber, function (data) { debug("add to product list, data:", release, data); const qty = data[4].rows[0].s[1]; if (qty < 3) { $("#h3ID").remove(); const h3Tag = document.createElement("h3"); h3Tag.setAttribute("id", "h3ID"); const txt = getTextById(38) + qty; h3Tag.innerHTML = "<strong>" + txt + "</strong>"; $(this).append(h3Tag); $("#h3ID").fadeOut(7500); } }, function (err) { debug("addproduct debug: idbillnumber,idproduct,idtable,idwaiter", release, idbillnumber, prodid, tablenumber, waiternumber); showHttpErrorMessage("box1", err); scrollToCustomerBox("box1"); }); } function showProductDetails(idproduct) { if (productDetailsCustomized && typeof customized_ProductDetails === "function" ) { customized_ProductDetails(idproduct); } else { standard_productDetails(idproduct, "box1"); } } function standard_productDetails(idproduct, div) { apiCall_listorante_public_getproductattributes(idproduct, function (data) { let details = "<div>"; for (let i = 0; i < data.count; i++) { if (i == 0) { details += "<h3>" + data.rows[i].s[1] + "</h3>"; details += "<p>" + data.rows[i].s[4] + ":&nbsp;&nbsp;" + data.rows[i].s[5] + "</p>"; } else { details += "<p>" + data.rows[i].s[4] + ":&nbsp;&nbsp;" + data.rows[i].s[5] + "</p>"; } } details += "</div>"; document.getElementById(div).innerHTML = details; }, function (err) { showHttpErrorMessage("main-content", err); }); }; function deleteOrderFromList(idorder, idbillnumber) { apiCall_listorante_guest_delitem(idorder, function (data) { debug2("guest", "delete item", release, [idorder, idbillnumber, data]); showCart(idbillnumber); showDeliveryStatus(idbillnumber); }, function errHandling(err) { showHttpErrorMessage("box3", err); }); scrollToCustomerBox("box3"); } function showDeliveryStatus(idbill) { document.getElementById("box0").hidden = true; document.getElementById("box1").hidden = true; document.getElementById("box2").hidden = true; document.getElementById("box3").hidden = false; apiCall_listorante_guest_deliverystatus(idbill, function (data) { guest3_orderstatus(data); document.getElementById("box3").innerHTML = guest3_orderstatus(data); }, function (err) { showHttpErrorMessage("main-content", err); }); }; function showCart(bill) { document.getElementById("box0").hidden = true; document.getElementById("box1").hidden = true; document.getElementById("box3").hidden = true; document.getElementById("box2").hidden = false; apiCall_listorante_guest_showcart(bill, function (data) { guest2_cart(data); document.getElementById("box2").innerHTML = guest2_cart(data); }, function (err) { showHttpErrorMessage("main-content", err); }); }; function submitorder(bill) { apiCall_listorante_guest_sendorder(bill, function (data) { debug2("guest", "submit Order", "d16af_5", [data]); showDeliveryStatus(bill); }, function (err) { showHttpErrorMessage("main-content", err); }); }; function initializeOrders() { /* * loginState: * NaN : user is not logged in * 0 : user comes from login right now * 1 : user is logged in * 2 : there are items in the list * */ if (loginState === 0) { // Create a new bill number: apiCall_listorante_guest_getguesttable(function (data) { const thetableID = data.rows[0].s[0]; apiCall_listorante_guest_createbill(thetableID, function (data) { debug("Create new bill for customer", release, data); const newbill = data[4].rows[0].s[1]; document.getElementById("idbill").innerText = newbill; apiCall_listorante_guest_billinfo(newbill, function (data) { const release = RELEASE; debug("Info of bill " + newbill + ":", release, data); // Set loginState=1, so if page is refreshed, we still keep the // assigned values for idbill, waitername etc. setLoginState("1"); // Initialize values to be displayed: idwaiter = data.rows[0].s[0]; idtable = data.rows[0].s[1]; waiterName = data.rows[0].s[2]; guestCount = data.rows[0].s[3]; tableName = data.rows[0].s[4]; debug2(module, "intitialization", RELEASE, [data]); //Store the values: sessionStorage.setItem("idwaiter", idwaiter); sessionStorage.setItem("idtable", idtable); sessionStorage.setItem("waitername", waiterName); sessionStorage.setItem("tableName", tableName); sessionStorage.setItem("idbill", newbill); if (parseInt("" + customerID, 10) > 0) { sessionStorage.setItem("theCustomerID", customerID); } document.getElementById("idwaiter").innerText = idwaiter; document.getElementById("idtable").innerText = idtable; document.getElementById("waiterName").innerText = waiterName; document.getElementById("tableName").innerText = tableName; document.getElementById("idbill").innerText = newbill; document.getElementById("username").hidden = true; }, function (err) { setLoginState("") showHttpErrorMessage("box0", err); }); }, function (err) { setLoginState("") showHttpErrorMessage("box0", err); }); }, function (err) { setLoginState("") debug("Seems an error but this is OK: guest is not logged in yet", release, err); }); } else if (loginState > 0) { idwaiter = sessionStorage.getItem("idwaiter"); document.getElementById('idwaiter').innerText = idwaiter; idtable = sessionStorage.getItem("idtable"); document.getElementById('idtable').innerText = idtable; waiterName = sessionStorage.getItem("waiterName"); document.getElementById('waiterName').innerText = waiterName; tableName = sessionStorage.getItem("tableName"); document.getElementById('tableName').innerText = tableName; idbill = sessionStorage.getItem("idbill"); document.getElementById('idbill').innerText = idbill; } else {//customer has been logged out document.getElementById("idwaiter").innerText = ""; document.getElementById("idtable").innerText = ""; document.getElementById("waiterName").innerText = ""; document.getElementById("tableName").innerText = ""; document.getElementById("idbill").innerText = ""; setLoginState(""); } } function userLogout() { /* * loginState: * 0/NaN : user is not logged in * 1 : user is logged in * 2 : there are items in the list * */ debug2("guest", "loginState in userLogout()", "d16af_5", [loginState]); sessionStorage.removeItem("theCustomerID"); const logoutPath = getAPIServerPath() + customerID + "/1/logout"; const xhttp = new XMLHttpRequest(); xhttp.open("POST", logoutPath, true); xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xhttp.send("token=" + bearerCookie); xhttp.onreadystatechange = function () { debug2("guest", "logoutPath,xhttp,loginState,bearerCookie", "" + release, [logoutPath, xhttp, loginState, bearerCookie]); if (xhttp.readyState == 4) { if (xhttp.status >= 400) { debug2("guest", "ERROR: logout-status ", "" + release, [xhttp, loginState]); } else { window.open("../" + customerTheme + "/index.html?cust=" + customerID, "_self"); } } }; } // Display this only as soon as the user tries to order an item document.getElementById("userpass").style.visibility = "hidden"; initializeOrders(); showSubCategories(0, ""); /*-----------------------------------*/ /* guestevents.js */ release = "xxd16af_5"; module = "guestevents.js"; showRelease(module); document.getElementById("text1").hidden = true; document.getElementById("text741").hidden = true; jQuery(document).on('click', '.submit-order', function () { const bill = document.getElementById("idbill").innerText; document.getElementById("tableName").innerText = "//Delete this text. loginState = " + loginState; if (loginState && loginState === 2) { submitorder(bill); setLoginState("1"); document.getElementById("tableName").innerText = "//Change this text. 'Ordered items were submitted'. loginState = " + loginState; scrollToCustomerBox("box0"); document.getElementById("text1").hidden = true; document.getElementById("text741").hidden = true; } else if (loginState && loginState === 1) { document.getElementById("tableName").innerText = "//Change this text. 'No items in list'. loginState = " + loginState; scrollToCustomerBox("box0"); } else { document.getElementById("username").hidden = false; scrollToCustomerBox("username"); document.getElementById("tableName").innerText = "//TODO: change text. Order is not active yet. Please click on 'start order'. loginState = " + loginState; } }); jQuery(document).on('click', '.get-products', function () { const cat = $(this).attr('data-category'); const cattext = $(this).attr('data-categoryText'); debug("Category " + cat + " clicked (" + cattext + ")", release); document.getElementById("tableName").innerText = "//TODO delete this text. loginState = " + loginState; showSubCategories(cat, cattext); showProductsOfCategory(cat); scrollToCustomerBox("box0"); }); jQuery(document).on('click', '.add-product', function () { const prod = $(this).attr('data-product'); const bill = document.getElementById("idbill").innerText; const _idwaiter = document.getElementById("idwaiter").innerText; const _idtable = document.getElementById("idtable").innerText; debug('loginState: ' + loginState, release); debug('idbill: ' + bill, release); document.getElementById("tableName").innerText = "//TODO delete this text. loginState = " + loginState; /* * loginState: * NaN : user is not logged in * 0 : user comes from login, this should never occur here * 1 : user is logged in * 2 : there are items in the list * */ if (loginState && (loginState === 1 || loginState === 2)) { debug("Adding product with id " + prod + " and waiter " + _idwaiter + " and idtable " + _idtable, release, prod, _idwaiter, _idtable); addproduct(bill, prod, _idtable, _idwaiter); if (loginState === 1) { setLoginState("2"); } $("#h3ID").remove(); const h3Tag = document.createElement("h3"); h3Tag.setAttribute("id", "h3ID"); const txt = document.getElementById("addProductText").innerHTML; h3Tag.innerHTML = txt; $(this).append(h3Tag); $("#h3ID").fadeOut(2500); document.getElementById("text1").hidden = false; document.getElementById("text741").hidden = false; } else { const infoText = getTextById(739);// Text is "Order not yet opened. Please insert your table number first." document.getElementById("tableName").innerText = infoText + " [TODO delete this text part. LoginState = " + loginState + "]"; document.getElementById("username").hidden = false; scrollToCustomerBox("username"); } }); jQuery(document).on('click', '.delete-product', function () { // TODO change loginState to "1" if all products were ordered const idorder = $(this).attr('data-order'); const bill = document.getElementById("idbill").innerText; debug2("guestevent", "delete item", release, [idorder, bill]); deleteOrderFromList(idorder, bill); }); jQuery(document) .on( 'click', '.product-overview', function () { const idprod = $(this).attr('data-product'); showProductDetails(idprod); document.getElementById("main-content").innerText = "Create Product Overview"; }); jQuery(document) .on( 'click', '.show-cart', function () { const idbill = document.getElementById("idbill").innerText; showCart(idbill); scrollToCustomerBox("box2"); }); jQuery(document) .on( 'click', '.show-deliverystatus', function () { const idbill = document.getElementById("idbill").innerText; showDeliveryStatus(idbill); scrollToCustomerBox("box3"); }); jQuery(document).on( "click", ".send-notification", function () { const idnote = $(this).attr('data-notification'); const idwaiter = document.getElementById("idwaiter").innerText; apiCall_listorante_guest_sendnotification(idnote, idwaiter, function (data) { showNotifications(); }, function (err) { showHttpErrorMessage("main-content", err); }); }); jQuery(document).on('click', '.start-order', function (event) { /* * loginState: * 0/NaN : user is not logged in * 1 : user is logged in * 2 : there are items in the list * */ const userName = $('#username').val(); debug2("guestevents", "start new order", "d16af_5", ["userName:\n\t" + userName, "event:\n\t" + event, "loginState: " + loginState]); if (loginState && loginState === 2) { document.getElementById("tableName").innerText = "//TODO change text. There are still un-confirmed items. loginState = " + loginState; scrollToCustomerBox("orderForm"); } else if (loginState && loginState === 1) { document.getElementById("tableName").innerText = "//TODO change text. Order is already open. loginState = " + loginState; scrollToCustomerBox("box0"); } else { scrollToCustomerBox("username"); document.getElementById("username").hidden = false; setLoginState(""); if (userName && userName.length > 1) { apiCall_listorante_public_settings('GUESTPASS', function (data) { const passwordString = data.rows[0].s[0]; const pass = userName + passwordString; // login() will redirect to index.html with loginState 0 // initializeOrder sets the value to 1 if (passwordString) { setLoginState("0"); login(userName, pass, customerTheme); //after login, page will be redirected to index.html } else { document.getElementById("tableName").innerText = "//TODO delete text. Login failed. LoginState = " + loginState + " pass=" + pass; } }, function (err) { debug("ERROR:", release, err); }); } else { document.getElementById("tableName").innerText = "//TODO change text. Please insert a table-number. LoginState = " + loginState; } } }); jQuery(document).on('click', '.close-order', function (event) { /* * loginState: * NaN : user is not logged in * 0 : this value should never occur here * 1 : user is logged in * 2 : there are items in the list * */ debug2("guestevents", "close order", "d16af_5", ["event:\n\t" + event, "loginState: " + loginState]); if (loginState && loginState === 2) { scrollToCustomerBox("orderForm"); document.getElementById("tableName").innerText = "//TODO: change text. 'There are still items in list.'" + loginState; } else if (loginState && loginState === 1) { setLoginState(""); // userLogout() will redirect to index.html userLogout(); } else if (!loginState) { document.getElementById("username").hidden = false; scrollToCustomerBox("username"); document.getElementById("tableName").innerText = "//TODO: change text. Order is already closed." + loginState; } else { document.getElementById("tableName").innerText = "//TODO: delete text. Unexpected state:" + loginState; } }); /*---------------END OF LISTO_GUEST.JS--------------------*/