ordersprinter/webapp/waiterdesktop.php

2713 lines
86 KiB
PHP
Raw Normal View History

2020-11-19 23:00:09 +01:00
<html>
<head>
<title>Ansicht Kellner</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="author" content="Stefan Pichel">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v={VERSION}">
<link rel="stylesheet" href="css/ospage.css" />
<link rel="stylesheet" href="css/tablepanel.css" />
<link rel="stylesheet" href="css/productpanel.css" />
<link rel="stylesheet" href="css/grouppanel.css" />
<link rel="stylesheet" href="css/groupitem.css" />
<link rel="stylesheet" href="css/ordereditem.css" />
<link rel="stylesheet" href="css/roompanel.css" />
<link rel="stylesheet" href="css/extraspanel.css" />
<link rel="stylesheet" href="css/actpanel.css" />
<link rel="stylesheet" href="css/paypanel.css" />
<link rel="stylesheet" href="php/3rdparty/jqueryui1-12-0/jquery-ui.min.css" />
<script src="php/3rdparty/jquery-2.2.4.min.js"></script>
<script src="php/3rdparty/jqueryui1-12-0/jquery-ui.min.js"></script>
<script src="elements/grouping.js"></script>
<script src="utilities.js"></script>
<script src="receiptutils.js"></script>
<script>
function sendNewOrders(doPrint) {
var tableid = getTableid();
if (neworders.length != 0) {
var data = {
tableid: tableid,
prods: neworders,
print: (doPrint ? 1 : 0),
payprinttype: "s"
};
// REM* this request must be sync!!! --> Otherwise the change from order to paydesk with pay button shows an empty table maybe
doAjax("POST", "php/contenthandler.php?module=queue&command=addProductListToQueue", data, handleSentNewOrders, "Fehler bei Produktversand",false);
} else {
alert("Es sind keine Produkte ausgewählt worden.");
}
}
function handleSentNewOrders(answer) {
if (answer.status != "OK") {
alert("Es ist ein Fehler beim Versenden der Bestellung aufgetreten");
} else {
neworders = [];
requestRoomInformation();
//showTablesForRoomIndex();
clearProductsSelection();
requestProdInformation();
requestOrderedInformation();
$("#search").val("");
displayPanels();
}
}
function getTableid() {
if (selectedroomindex !== null) {
if (selectedroomindex < 0) {
// REM* togo
return 0;
} else {
if (selectedtableindex !== null) {
var theTable = roominfo.roomstables[selectedroomindex].tables[selectedtableindex];
return theTable.id;
} else {
return 0;
}
}
}
}
function enableSendButton() {
// $("#sendNewOrders").removeClass("inputwhite");
// $("#sendNewOrders").removeClass("inputgreen");
// $("#sendNewOrders").addClass("inputgreen");
}
function disableSendButton() {
// $("#sendNewOrders").removeClass("inputwhite");
// $("#sendNewOrders").removeClass("inputgreen");
// $("#sendNewOrders").addClass("inputwhite");
}
function bindRightButtons() {
$("#sendNewOrders").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
sendNewOrders(false);
});
$("#paydeskbtn").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
if (neworders.length > 0) {
if (waitergopayprint == 1) {
sendNewOrders(true);
} else {
sendNewOrders(false);
}
}
goPayDesk();
});
//
$("#workbtn").off("click").on("click", function (e) {
if (neworders.length > 0) {
sendNewOrders(true);
}
});
$("#goorderbtn").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
goOrderDesk();
});
$("#mainmenudlg").dialog(
{autoOpen: false,
modal: true,
});
// $("#mainmenudlg").dialog(
// {autoOpen: false,
// modal: true,
// height: 580,
// position:{my:"right top",at:"right+100 top+100", of:"body"},
// buttons: {
// Abbrechen: function() {$(this).dialog("close"); }
// }
// });
}function requestRoomInformation() {
doAjax("GET", "php/contenthandler.php?module=roomtables&command=showAllRooms", null, insertRoomInfo, null,true);
}
function insertRoomInfo(roomanswer) {
roominfo = roomanswer;
showRooms();
}
function showRooms() {
var allRooms = roominfo.roomstables;
var txt = "";
$.each(allRooms, function (i, aRoom) {
if (selectedroomindex === i) {
txt += '<div id="room_' + i + '" class="roomitemselected">' + aRoom.name + '</div>';
} else {
txt += '<div id="room_' + i + '" class="roomitem">' + aRoom.name + '</div>';
}
});
var takeawayprice = roominfo.takeawayprice.replace(".", decpoint) + " " + currency;
if (takeawayprice != "") {
takeawayprice = '<div class="roomtogoaccounted">' + takeawayprice + '</div>';
}
if (selectedroomindex < 0) {
txt += '<div id="room_-1" class="roomitemselected roomtogo">';
txt += '<div class="roomname">Zum Mitnehmen</div>';
txt += takeawayprice;
txt += '</div>';
} else {
txt += '<div id="room_-1" class="roomitem roomtogo">';
txt += '<div class="roomname">Zum Mitnehmen</div>';
txt += takeawayprice;
txt += '</div>';
}
$("#roompanel").html(txt);
$("#tablepanelcontent").html("");
showRoomTableTextInfo();
showTablesForRoomIndex();
bindingRoom();
}
function bindingRoom() {
$(".roomitem").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
var newRoom = parseInt(this.id.split('_')[1]);
if (panelMode == "waiter") {
if (neworders.length > 0) {
$( "#unsentorderdlg" ).dialog({
autoOpen: false,
modal: true,
height: 400,
buttons: {
Nein: function() {$(this).dialog("close"); },
Ja: function() {$(this).dialog("close"); discardChangeRoom(newRoom); }
},
});
$("#unsentorderdlg").dialog("open");
} else {
changeRoom(newRoom);
if (selectedroomindex == "-1") {
// REM* togo
startProductDisplay();
}
}
} else {
// REM* paydesk
changeRoom(newRoom);
goPayDesk();
}
});
}
function discardChangeRoom(newRoom) {
neworders = [];
groupedNewOrders = null;
showNewOrders();
changeRoom(newRoom);
}
function changeRoom(newRoom) {
clearProductsSelection();
// disableSendButton();
selectedtableindex = null;
selectedroomindex = newRoom;
showRooms();
//showTablesForRoomIndex();
}
function showRoomTableTextInfo() {
var txt = "Keine Auswahl";
if (selectedroomindex !== null) {
if (selectedroomindex < 0) {
txt = "Zum Mitnehmen";
} else {
txt = "Raum: " + roominfo.roomstables[selectedroomindex].name;
if (selectedtableindex !== null) {
var theTable = roominfo.roomstables[selectedroomindex].tables[selectedtableindex];
txt += " - Tisch: " + theTable.name;
}
}
}
$("#location").html(txt);
}
function showTablesForRoomIndex() {
if ((selectedroomindex >= 0) && (selectedroomindex !== null)) {
var tables = roominfo.roomstables[selectedroomindex].tables;
var txt = "";
$.each(tables, function (i, aTable) {
if ((selectedtableindex != null) && (tables[selectedtableindex].id == aTable.id)) {
txt += '<div id="table_' + i + '" class="tableelement tableitemselected">';
} else {
// REM* a non.selected table:
txt += '<div id="table_' + i + '" class="tableelement tableitem">';
}
txt += ' <header class="tablename">' + aTable.name + '</header>';
var price = aTable.pricesum;
if (price != 0.00) {
var priceTxt = price.replace(".", decpoint) + " " + currency;
txt += '<div class="tableopen">' + priceTxt + '</div>';
}
txt += '</div>';
});
$("#tablepanelcontent").html(txt);
} else {
$("#tablepanelcontent").html("");
}
bindingTable();
}
function bindingTable() {
$(".tableitem").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
var newTable = parseInt(this.id.split('_')[1]);
if (panelMode == "waiter") {
if (neworders.length > 0) {
$( "#unsentorderdlg" ).dialog({
autoOpen: false,
modal: true,
height: 400,
buttons: {
Nein: function() {$(this).dialog("close"); },
Ja: function() {$(this).dialog("close"); discardChangeTable(newTable); }
}
});
$("#unsentorderdlg").dialog("open");
} else {
changeTable(newTable);
startProductDisplay();
}
} else {
// REM* paydesk mode
changeTable(newTable);
goPayDesk();
}
});
}
function discardChangeTable(newTable) {
neworders = [];
groupedNewOrders = null;
showNewOrders();
changeTable(newTable);
}
function changeTable(newTable) {
selectedtableindex = newTable;
showRoomTableTextInfo();
showTablesForRoomIndex();
}
function startProductDisplay() {
selectedtypeid = null;
selectedprodid = null;
clearProductsSelection();
requestProdInformation();
requestOrderedInformation();
$("#search").val("");
$("#searchpanel").show();
$("#remarkpanel").show();
}
function clearProductsSelection() {
neworders = [];
groupedNewOrders = [];
selectedtypeid = null;
$("#groupchain").html("");
$("#groupchoice").html("");
$("#productspanel").html("");
$("#remark").val("");
$("#neworders").html("");
$("#ordered").html("");
$("#searchpanel").hide();
$("#remarkpanel").hide();
}var allOrderdItems = [];
function requestOrderedInformation() {
if (panelMode != "waiter") {
return;
}
var tableid = 0;
if (selectedroomindex != "-1") {
var theTable = roominfo.roomstables[selectedroomindex].tables[selectedtableindex];
tableid = theTable.id;
}
doAjax("GET","php/contenthandler.php?module=queue&command=getJsonLongNamesOfProdsForTableNotDelivered&tableid=" + tableid,null,insertOrderedInformation,true);
}
function insertOrderedInformation_old(orderedItems) {
var txt = "";
$.each(orderedItems, function (i, anItem) {
txt += '<div id="ordered_' + i + '" class="ordereditem-item-sent">' + anItem.longname + '</div>';
});
$("#ordered").html(txt);
}
function insertOrderedInformation(orderedItems) {
allOrderdItems = orderedItems;
// REM* assignedProds: this is the list of products of the list that is not delivered or paid
// REM* assignedProdsGrouping: this is the element for handling the grouping of assignedProds
var assignedProdsGrouping = new Grouping(orderedItems, createTxtAssignedProd);
assignedProdsGrouping.group();
var txt = "";
txt += assignedProdsGrouping.outputList(createListElOfAssignedProd);
$("#ordered").html(txt);
bindOrderedItem();
}
//REM* also for hash function for the assignedProd (list of undelivered/unpaid prod) for grouping
function createTxtAssignedProd(p) {
var optiontext = "";
if (p.option != '') {
optiontext = "<p><i>" + toHtml(p.option) + "</i>";
}
var togotxt = "";
var prodname = toHtml(p.longname);
if (p.togo == 1) {
togotxt = "To-Go: ";
}
prodname = '<div class="ordereditem-name">' + togotxt + '<span class="ordereditem-bold">' + prodname + '</span></div>';
if (p.pricechanged == 1) {
prodname += " - " + p.price.replace(".", decpoint);
}
var status = "";
if (p.isready == '1') {
status += " &#9758";
}
if (p.isCooking == '1') {
status += " &#9832";
}
if (p.isPaid == '1') {
status += " &#9745";
}
return prodname + '<div class="oredereditem-misc">' + optiontext + status + createExtraParagraphForOrderedEl(p.extras) + '</div>';
}
function createListElOfAssignedProd(aProd) {
var count = "";
if ("count" in aProd) {
if (aProd["count"] > 1) {
count = '<div class="ordereditem-count">' + aProd["count"] + "x " + '</div>';
}
}
var txt = "<div id='ordered_" + aProd["id"] + "' class='ordereditem-item-sent' >" + count + createTxtAssignedProd(aProd) + "</div>";
return txt;
}
function createExtraParagraphForOrderedEl(extras) {
if ((extras == null) || (extras == "")) {
return "";
}
var extratxt = "";
var extrasarr = [];
for (var j = 0; j < extras.length; j++) {
extrasarr[extrasarr.length] = toHtml(extras[j]);
extratxt += "+ " + toHtml(extras[j]) + "<br>";
}
return "<p>" + extrasarr.join('<br>');
}
function bindOrderedItem() {
$(".ordereditem-item-sent").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
var queueId = this.id.split("_")[1];
var test = allOrderdItems;
// REM* find item
for (var i=0;i<allOrderdItems.length;i++) {
var anItem = allOrderdItems[i];
var otherId = anItem.id;
if(queueId == otherId) {
// REM* item is found!
handleClickOnOrderedItem(anItem,queueId);
break;
}
}
});
}
function handleClickOnOrderedItem(anEntry,queueid) {
var isReady = anEntry.isready;
var isPaid = anEntry.isPaid;
var isCooking = anEntry.isCooking;
var infoTxt = "Das Produkt ist diesem Tisch zugewiesen.";
if ((isPaid == "1") && (isReady == "1")) {
infoTxt = "Produkt wurde schon zubereitet und bezahlt.";
} else if (isReady == "1") {
infoTxt = "Produkt wurde schon zubereitet.";
} else if (isPaid == "1") {
infoTxt = "Produkt wurde schon bezahlt.";
} else if (isCooking == "1") {
infoTxt = "Produkt wird soeben zubereitet.";
}
$("#ordereditem-info").html(infoTxt);
$("#ordereditemdlg").dialog(
{autoOpen: false,
modal: true,
height: 400,
width: 600,
position:{my:"center top",at:"center top", of:"body"}
});
if (cancelunpaidcode != "") {
$("#orderedcancelpanel").show();
$("#cancelcode").val("");
} else {
$("#orderedcancelpanel").hide();
}
$("#ordereditemdlg").dialog("open");
bindOrderItemAction(anEntry);
return;
if ((isPaid == "1") && (isReady == "1")) {
var dialogText = "Entfernen oder nachbestellen?";
var this_elem = this;
doYouWantDelOrReorder("Produkt wurde schon zubereitet und bezahlt", dialogText, W_REMOVE[lang],
function () {
removeProductFromQueue(queueid, isPaid, isCooking, isReady, stornoCodeOk);
},
function () {
reorderProduct(anEntry.prodid, anEntry.extrasids, anEntry.extras);
}
);
} else if (isReady == "1") {
var dialogText = "Entfernen oder nachbestellen?";
var this_elem = this;
doYouWantDelOrReorder("Produkt wurde schon zubereitet.", dialogText, W_REMOVE[lang],
function () {
removeProductFromQueue(queueid, isPaid, isCooking, isReady, stornoCodeOk);
},
function () {
reorderProduct(anEntry.prodid, anEntry.extrasids, anEntry.extras);
}
);
} else if (isPaid == "1") {
var dialogText = "Entfernen oder nachbestellen?";
var this_elem = this;
doYouWantDelOrReorder("Produkt wurde schon bezahlt.", dialogText, W_REMOVE[lang],
function () {
removeProductFromQueue(queueid, isPaid, isCooking, isReady, stornoCodeOk);
},
function () {
reorderProduct(anEntry.prodid, anEntry.extrasids, anEntry.extras);
}
);
} else if (isCooking == "1") {
var dialogText = "Entfernen oder nachbestellen?";
var this_elem = this;
doYouWantDelOrReorder("Produkt wird soeben zubereitet.", dialogText, W_REMOVE[lang],
function () {
removeProductFromQueue(queueid, isPaid, isCooking, isReady, stornoCodeOk);
},
function () {
reorderProduct(anEntry.prodid, anEntry.extrasids, anEntry.extras);
}
);
} else {
// REM* delete or reorder, but do not show the message about prepared, cooking or paid status
var dialogText = "Entfernen oder nachbestellen?";
var this_elem = this;
doYouWantDelOrReorder("", dialogText, W_REMOVE[lang],
function () {
removeProductFromQueue(queueid, isPaid, isCooking, isReady, stornoCodeOk);
},
function () {
reorderProduct(anEntry.prodid, anEntry.extrasids, anEntry.extras);
}
);
}
}
function bindOrderItemAction(anEntry) {
var isReady = anEntry.isready;
var isPaid = anEntry.isPaid;
var isCooking = anEntry.isCooking;
var queueid = anEntry.id;
$("#ordereditemcancel").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
$("#ordereditemdlg").dialog("close");
});
$("#ordereditemremove").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
if (cancelunpaidcode != "") {
var enteredCode = $("#cancelcode").val();
if (cancelunpaidcode != enteredCode) {
alert("Falscher Stornocode!");
return;
}
}
removeProductFromQueue(queueid, isPaid, isCooking, isReady);
});
$("#ordereditemreorder").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
reorderProduct(anEntry.prodid, anEntry.extrasids, anEntry.extras);
});
}
function removeProductFromQueue(queueid, isPaid, isCooking, isReady) {
$.ajax({type: "POST",
dataType: "json",
url: "php/contenthandler.php?module=queue&command=removeProductFromQueue",
data: {queueid: queueid,
isPaid: isPaid,
isCooking: isCooking,
isReady: isReady},
async: false,
success: function (text) {
requestOrderedInformation();
$("#ordereditemdlg").dialog("close");
},
error: function (text) {
alert("Sorry, Fehler bei Produktentfernung!");
}
});
}
function reorderProduct(prodid, extrasids, extrasnames) {
// REM* create array frtom id and names of extras which is expected by addProductToNewOrdersList
var extras = [];
for (var i = 0; i < extrasids.length; i++) {
extras[extras.length] = {id: extrasids[i], name: extrasnames[i]};
}
$("#ordereditemdlg").dialog("close");
addProductToNewOrders(prodid, "", extras, "NO", 0);
}
function requestProdInformation() {
doAjax("GET","php/contenthandler.php?module=products&command=getAllTypesAndAvailProds",null,insertProductInformation,true);
}
function insertProductInformation(productInfo) {
productInformation = productInfo;
updateProductInfoDisplay();
}
function updateProductInfoDisplay() {
showAllTypesToChoose();
showAllProdsToChoose();
disableSendButton();
}
function getType(id) {
var allTypes = productInformation.types;
for (var i=0;i<allTypes.length;i++) {
var aType = allTypes[i];
if (aType.id == id) {
return aType;
}
}
return null;
}
function getSubTypes() {
var allTypes = productInformation.types;
var types = [];
if (selectedtypeid != null) {
// REM* a type was selected - find subtypes
var currentType = getType(selectedtypeid);
for (var i=0;i<allTypes.length;i++) {
var aType = allTypes[i];
if ((aType != null) && (aType.ref == currentType.id)) {
types[types.length] = { id:aType.id, name:aType.name};
}
}
} else {
// REM* no type selected yet
for (var i=0;i<allTypes.length;i++) {
var aType = allTypes[i];
if ((aType.ref == null) || (aType.ref == 0)) {
types[types.length] = { id:aType.id, name:aType.name};
}
}
}
return types;
}
// REM* get all products that belong the the chosen prodtype - or return all with name starting wirth filter
function getAllProds(filter) {
var allProds = productInformation.prods;
var prods = [];
if (filter != null) {
filter = filter.trim().toLowerCase();
for (var i=0;i<allProds.length;i++) {
var aProd = allProds[i];
var longName = aProd.name;
if (longName.toLowerCase().indexOf(filter) >= 0) {
prods[prods.length] = { id:aProd.id, name:aProd.name};
}
}
} else {
if (selectedtypeid != null) {
// REM* a Type was selected
var currentType = getType(selectedtypeid);
for (var i=0;i<allProds.length;i++) {
var aProd = allProds[i];
if ((aProd.ref == currentType.id)) {
prods[prods.length] = { id:aProd.id, name:aProd.name};
}
}
} else {
// REM* no type selected yet - highest level
for (var i=0;i<allProds.length;i++) {
var aProd = allProds[i];
if ((aProd.ref == null) || (aProd.ref == 0)) {
prods[prods.length] = { id:aProd.id, name:aProd.name};
}
}
}
}
return prods;
}
function showAllTypesToChoose() {
var txt = "";
if ((selectedroomindex == "-1") || (selectedtableindex != null)) {
var allTypes = getSubTypes();
$.each(allTypes, function (i, aType) {
if (selectedtypeid == aType.id) {
txt += '<div id="type_' + aType.id+ '" class="groupitemchoiceselected">' + aType.name + '</div>';
} else {
txt += '<div id="type_' + aType.id + '" class="groupitemchoice">' + aType.name + '</div>';
}
});
}
$("#groupchoice").html(txt);
showChain();
bindType();
}
function bindType() {
$(".groupitemchoice").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
$("#search").val("");
selectedtypeid = parseInt(this.id.split('_')[1]);
updateProductInfoDisplay();
});
}
function showAllProdsToChoose() {
var txt = "";
if ((selectedroomindex == "-1") || (selectedtableindex != null)) {
var allProds = getAllProds(productFilter);
$.each(allProds, function (i, aProd) {
txt += '<div id="prod_' + aProd.id + '" class="productitem">' + aProd.name + '</div>';
});
}
$("#productspanel").html(txt);
bindProduct();
}
function getTypeChain() {
var currentType = getType(selectedtypeid);
if (currentType == null) {
return [];
}
var chain = [currentType];
var stop = false;
while (!stop) {
var currentRef = currentType.ref;
if ((currentRef == null) || (currentRef == 0)) {
stop = true;
break;
} else {
currentType = getType(currentRef);
chain[chain.length] = currentType;
}
}
return chain;
}
function showChain() {
var txt = "";
if ((selectedroomindex == "-1") || (selectedtableindex != null)) {
var chain = getTypeChain();
txt += '<div id="groupchainitem_-1" class="groupitem">Auswahl</div>';
for (var i = chain.length-1; i >= 0; i--) {
var aType = chain[i];
txt += '<div id="groupchainitem_' + aType.id+ '" class="groupitem">' + aType.name + '</div>';
}
}
$("#groupchain").html(txt);
bindChain();
bindSearch();
}
function bindChain() {
$(".groupitem").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
selectedtypeid = parseInt(this.id.split('_')[1]);
if (selectedtypeid == "-1") {
selectedtypeid = null;
}
updateProductInfoDisplay();
$("#search").val("");
});
}
function bindSearch() {
$("#search").off("keyup").on("keyup", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
productFilter = ($("#search").val().trim().toLowerCase()).trim();
if (productFilter == "") {
productFilter = null;
}
showAllProdsToChoose();
});
}
function bindProduct() {
$(".productitem").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
$("#search").val("");
selectedprodid = parseInt(this.id.split('_')[1]);
var option = $("#remark").val();
var prod = getProdEntry(selectedprodid);
var extras = prod.extras;
if ((extras != null) && (extras.length > 0)) {
showExtras(prod,option);
} else {
addProductToNewOrders(selectedprodid,option,null,"NO",0);
}
});
}
function getProdEntry(prodid) {
var allprods = productInformation.prods;
for (var i = 0; i < allprods.length; i++) {
var aProd = allprods[i];
if (parseInt(aProd.id) == prodid) {
return aProd;
}
}
return null;
}
function getProdProperties(prodid) {
var aProd = getProdEntry(prodid);
if (aProd != null) {
return {name: aProd.longname, price: aProd.price};
} else {
return "FEHLER!";
}
}
function addProductToNewOrders(productid, option, extras, changedPrice, togo) {
$("#remark").val("");
var prodprop = getProdProperties(productid);
var prodname = prodprop.name;
var prodprice = prodprop.price;
var entry = {
name: prodname,
option: option,
extras: extras,
prodid: productid,
price: prodprice,
changedPrice: changedPrice,
togo: togo
};
// for (var i = 0; i < selectedProdCount; i++) {
// REM* clone!!!
neworders[neworders.length] = {
name: entry.name,
option: entry.option,
extras: entry.extras,
prodid: entry.prodid,
price: entry.price,
changedPrice: entry.changedPrice,
togo: entry.togo
}
// }
showNewOrders();
$("#remark").val("");
}
function group(theSet) {
// create 2d array
var counts = [];
var joinedvals = [];
var name = [];
var price = []; // not used for grouping
var option = [];
var extras = [];
var prodids = [];
var origidxs = [];
var changedPrices = [];
var togos = [];
var grouped = {
count: counts,
joinedvals: joinedvals,
name: name,
price: price,
option: option,
extras: extras,
prodids: prodids,
origidxs: origidxs,
changedPrices: changedPrices,
togos: togos
};
var i = 0;
for (i = 0; i < theSet.length; i++) {
var anEntry = theSet[i];
var name = anEntry.name;
var price = anEntry.price;
var option = anEntry.option;
var prodid = anEntry.prodid;
var changedPrice = anEntry.changedPrice;
var togo = anEntry.togo;
var extra = anEntry.extras;
var extrastxt = "";
// Generate extras name composition
var extrasarr = [];
if (extra != null) {
for (var j = 0; j < extra.length; j++) {
extrasarr[extrasarr.length] = "+" + toHtml(extra[j].name);
}
}
if (extrasarr.length > 0) {
extrastxt += "<p>" + extrasarr.join('<br>');
} else {
extrastxt = "";
}
var joinedNeedle = name + "-" + option + "-" + extrastxt;
if (changedPrice != "NO") {
joinedNeedle = name + "-" + option + "-" + extrastxt + changedPrice;
}
if (togo == 1) {
joinedNeedle += " - To-Go";
}
var index = grouped.joinedvals.indexOf(joinedNeedle);
if (index >= 0) {
// element is already in group
grouped.count[index] = grouped.count[index] + 1;
//var idsarr = grouped.ids[index];
//idsarr[idsarr.length] = id;
idxarr = grouped.origidxs[index]
idxarr[idxarr.length] = i;
grouped.origidxs[index] = idxarr; // append
} else {
// new element to be inserted in grouped
var gLength = grouped.count.length;
grouped.count[gLength] = 1;
grouped.joinedvals[gLength] = joinedNeedle;
grouped.name[gLength] = name;
grouped.price[gLength] = price;
grouped.option[gLength] = option;
grouped.extras[gLength] = extrastxt;
grouped.prodids[gLength] = prodid;
grouped.changedPrices[gLength] = changedPrice;
grouped.togos[gLength] = togo;
grouped.origidxs[gLength] = [i];
}
}
return grouped;
}
function showNewOrders() {
groupedNewOrders = group(neworders);
var txt = "";
var grouplength = groupedNewOrders.count.length; // because of vertical structure...
for (i = 0; i < grouplength; i++) {
var lname = toHtml(groupedNewOrders.name[i]);
var optiontext = groupedNewOrders.option[i];
var count = groupedNewOrders.count[i];
if (count > 1) {
lname = "<span style='font-size: 23px;'>" + count.toString() + "x</span> " + lname;
}
var prodid = groupedNewOrders.prodids[i];
if (optiontext != '') {
optiontext = "<p>" + toHtml(optiontext) + "</p>";
}
var changedPrice = groupedNewOrders.changedPrices[i];
var togo = groupedNewOrders.togos[i];
var extrastxt = "";
var extras = groupedNewOrders.extras[i];
if ((extras != null) && (extras != "")) {
// REM* do not use toHtml for extras because this is done already in group() and would replace <p>s
extrastxt = "<span style='font-size: 14px;'><i>" + extras + "</i></span>";
}
// REM* information about togo and changedPrice
var addInfo = "";
if (changedPrice != "NO") {
// REM* show price
if (togo != 0) {
addInfo = "<br> (" + changedPrice.replace(".", decpoint) + " " + currency + " - To-Go)";
} else {
addInfo = "<br> (" + changedPrice.replace(".", decpoint) + " " + currency + ")";
}
} else {
if (togo != 0) {
addInfo = "<br> (To-Go)";
}
}
txt += '<div id="neworder_' + prodid + '_' + i + '" class="ordereditem-item-new">' + lname + optiontext + extrastxt + addInfo + '</div>';
}
$("#neworders").html(txt);
$("#remark").val("");
if (neworders.length > 0) {
// REM* mark button green
enableSendButton();
} else {
disableSendButton();
}
bindNewOrderItem();
displayRightButtons();
}
// REM* location
var roominfo = null;
var selectedroomindex = null;
var selectedtableindex = null;
// REM* products
var productInformation = null;
var selectedtypeid = null;
var selectedprodid = null;
var neworders = [];
var groupedNewOrders = {
count: [],
joinedvals: [],
name: [],
prodids: [],
extras: [],
origidxs: [],
changedPrices: [],
togos: []
};
// REM* 0: both, 1:only digital, 2: only with working receipts
var workflowconfig = 0;
var decpoint = '.';
var currency = '';
// REM* is user allowed to change prices during ordering process? (Values: 0 or 1)
var rightchangeprice = 0;
var rightpaydesk = false;
// REM* the serve buttons shall only be vivisible if the waiter has the supply right
var supplyright = 0;
// REM* prominent product search means that the product search is on top and has autofocus
var prominentsearch = 0;
// REM* the default discounts - will be overwritten by waiter settings
var discount1 = 50;
var discount2 = 20;
var discount3 = 10;
// REM* shaöl the button 'gopaydesk' automatically print the work receipts?
var waitergopayprint = 0;
var mainmenu = [];
var version = "";
var loggedinUser = "";
var lang = 0;
// REM* the payments as they are returned from server
var payments = "";
// REM* Vorlage für Bewirtungsbeleg
var hostTemplate = "";
var showHostTemplate = false;
var cancelunpaidcode = '';
var WORKFLOW_DIGI_AND_WORK = 0;
var WORKFLOW_DIGI = 1;
var WORKFLOW_WORK = 2;
var WORKFLOW_WORK_TRANSFER = 3;
var productFilter = null;
var panelMode = "waiter";
$(document).ready(function(){
selectedroomindex = null;
productFilter = null;
doAjax("GET", "php/contenthandler.php?module=admin&command=getWaiterSettings", null, insertWaiterConfig, "Fehler Konfigurationsdaten",true);
doAjax("GET", "php/contenthandler.php?module=admin&command=getJsonMenuItemsAndVersion", null, saveMenuInfo, null, true);
getGeneralConfigItems();
intervalGetItemsToPayAndRoomInfo(10);
getMenuInBackground(60);
getPayments(savePayments);
getHostTemplate();
});
function savePayments(allPayments) {
payments = allPayments;
}
function intervalGetItemsToPayAndRoomInfo(seconds) {
var fetchTimer = setInterval(function() {
getAndShowPayItems();
requestRoomInformation();
requestOrderedInformation();
}, seconds * 1000);
}
function getMenuInBackground(seconds) {
var fetchTimer = setInterval(function() {
requestProdInformation();
}, seconds * 1000);
}
function insertWaiterConfig(settings) {
var isUserLoggedIn = settings.isUserLoggedIn;
if (isUserLoggedIn != 1) {
setTimeout(function(){document.location.href = "index.html"},250);
} else {
var config = settings.config;
workflowconfig = config.workflowconfig;
decpoint = config.decpoint;
currency = config.currency;
rightchangeprice = settings.rightchangeprice;
supplyright = settings.supplyright;
prominentsearch = config.prominentsearch;
waitergopayprint = config.waitergopayprint;
discount1 = config.discount1;
discount2 = config.discount2;
discount3 = config.discount3;
rightpaydesk = settings.rightpaydesk;
if ((config.cancelunpaidcode != null) && (config.cancelunpaidcode != "")) {
cancelunpaidcode = config.cancelunpaidcode;
} else {
cancelunpaidcode = '';
}
initializeOrderView();
}
}
function initializeOrderView() {
panelMode = "waiter";
initGui();
clearProductsSelection();
requestRoomInformation();
requestProdInformation();
bindMainMenuButton();
bindRightButtons();
}
function getHostTemplate() {
$.ajax({
url: "customer/bon-bewirtungsvorlage.html",
async: false,
success: function (hostdata) {
hostTemplate = hostdata;
},
error: function (text) {
},
cache: false
});
}
function saveMenuInfo(menuAndVersion) {
if (menuAndVersion.loggedin == 1) {
loggedinUser = menuAndVersion.user;
$("#loggedinuser").html("&nbsp;" + loggedinUser);
$("#versioninfo").html(menuAndVersion.version);
version = menuAndVersion.version;
$.each(menuAndVersion.menu, function (i, module) {
var name = module.name;
var link = module.link;
mainmenu[mainmenu.length] = { name: name, link: link };
});
$("#mainmenubtn").show();
} else {
$("#mainmenubtn").hide();
}
}
function bindMainMenuButton() {
$( "#selectiondialog" ).dialog({
autoOpen: false,
modal: true,
height: 400,
buttons: {
Anwenden: function() {$(this).dialog("close"); applyExtras(); }
}
});
$( "#unsentorderdlg" ).dialog({
autoOpen: false,
modal: true,
height: 400,
buttons: {
Nein: function() {$(this).dialog("close"); },
Ja: function() {$(this).dialog("close"); }
}
});
$("#actmenudlg").dialog({
autoOpen: false,
modal: true,
height: 400,
});
$("#mainmenudlg").dialog(
{autoOpen: false,
modal: true,
height: 400,
width: 200,
position:{my:"right top",at:"right top", of:"body"},
buttons: {
Abbrechen: function() {$(this).dialog("close"); }
}
});
$("#ordereditemdlg").dialog(
{autoOpen: false,
modal: true,
height: 400,
width: 200,
});
$("#mainmenubtn").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
var txt = "<div><ul class='mainmenuchoice'>";
for (var i = 0; i < mainmenu.length; i++) {
txt += "<li id='mainmenu_" + i + "' class='mainmenuitem' >" + toHtml(mainmenu[i].name) + "</li>";
}
txt += "</ul></div>";
$("#mainmenudlg").html(txt);
var height = 280 + mainmenu.length * 40;
$("#mainmenudlg").dialog(
{autoOpen: false,
modal: true,
height: height,
width: 200,
position:{my:"right top",at:"right top", of:"body"},
buttons: {
Abbrechen: function() {$(this).dialog("close"); }
}
});
$("#mainmenudlg").dialog("open");
$(".mainmenuitem").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
var selectedmenuindex = parseInt(this.id.split('_')[1]);
var url = mainmenu[selectedmenuindex].link;
$("#mainmenudlg").dialog("close");
setTimeout(function(){document.location.href = url},250);
});
});
}
function goOrderDesk() {
panelMode = "waiter";
initGui();
clearProductsSelection();
requestProdInformation();
requestOrderedInformation();
}
function goPayDesk() {
panelMode = "paydesk";
initGui();
startCashProcess();
}
// REM* show panels and buttons due to panel mode and availability of items
function initGui() {
displayPanels();
displayRightButtons();
}
// REM* show/hide panels due to panelMode (waiter/paydesk)
function displayPanels() {
if (panelMode === "waiter") {
$("#panelmodetxt").html("Bestellung");
$("#groupchain").show();
$("#groupchoice").show();
$("#searchpanel").show();
$("#productspanel").show();
$("#remarkpanel").show();
$("#ordered").show();
$("oben").html("");
$("#oben").hide();
$("#unten").html("");
$("#unten").hide();
$("#receiptpanel").hide();
$("#paybuttonpanel").hide();
$("#receiptpanel").hide();
} else {
// REM* paydesk
$("#panelmodetxt").html("Kasse");
$("#groupchain").hide();
$("#groupchoice").hide();
$("#searchpanel").hide();
$("#productspanel").hide();
$("#remarkpanel").hide();
$("#ordered").hide();
$("oben").html("");
$("#oben").show();
$("#unten").html("");
$("#unten").show();
$("#goorderbtn").show();
$("#receiptpanel").show();
$("#paybuttonpanel").show();
$("#receiptpanel").show();
}
}
// REM* show/hide buttons due to workflowconfig and availability of items
function displayRightButtons() {
if (panelMode === "waiter") {
if (rightpaydesk == 1) {
$("#paydeskbtn").show();
}
$("#hostbutton").hide();
$("#paydeskcash").hide();
$("#paydeskprint").hide();
$("#goorderbtn").hide();
if (neworders.length > 0) {
if ((workflowconfig == WORKFLOW_DIGI_AND_WORK) || (workflowconfig == WORKFLOW_WORK) || (workflowconfig == WORKFLOW_WORK_TRANSFER)) {
$("#workbtn").show();
}
if ((workflowconfig == WORKFLOW_DIGI_AND_WORK) || (workflowconfig == WORKFLOW_DIGI) || (workflowconfig == WORKFLOW_WORK_TRANSFER)) {
$("#sendNewOrders").show();
}
}
} else {
// REM* paydesk
$("#paydeskbtn").hide();
$("#hostbutton").show();
if (prodsaccounted.length > 0) {
// REM* there are orders so show buttons
$("#paydeskcash").show();
$("#paydeskprint").show();
$("#goorderbtn").show();
}
$("#workbtn").hide();
$("#sendNewOrders").hide();
}
}
var e_extras = [];
var e_extras_selection = [];
var e_prod = null;
var e_option = null;
function showExtras(prod,option) {
e_prod = prod;
e_option = option;
e_extras = prod.extras;
e_extras_selection = [];
for (var i = 0; i < e_extras.length; i++) {
e_extras_selection[i] = false;
}
$( "#selectiondialog" ).dialog({
autoOpen: false,
modal: true,
height: 400,
buttons: {
Anwenden: function() {$(this).dialog("close"); applyExtras(); }
}
});
displayExtras();
$("#selectiondialog").dialog("open");
}
function displayExtras() {
var txt = "<div><ul class='extraschoice'>";
for (var i = 0; i < e_extras.length; i++) {
var anExtra = e_extras[i];
var extraid = anExtra.extraid;
var extraname = anExtra.name;
if (e_extras_selection[i]) {
txt += "<li id='extra_" + extraid + "_" + i + "' class='extraitemselected' >" + toHtml(extraname) + "</li>";
} else {
txt += "<li id='extra_" + extraid + "_" + i + "' class='extraitem' >" + toHtml(extraname) + "</li>";
}
}
txt += "</ul></div>";
$("#selectiondialog").html(txt);
$(".ui-dialog-buttonset .ui-button").css('background-color', '#44ff44');
$(".ui-widget-header").css('background-color', '#ff4400');
bindExtra();
}
function bindExtra() {
$(".extraitem").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
extraClicked(parseInt(this.id.split('_')[2]));
});
$(".extraitemselected").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
extraClicked(parseInt(this.id.split('_')[2]));
});
}
function extraClicked(index) {
if (e_extras_selection[index]) {
e_extras_selection[index] = false;
} else {
e_extras_selection[index] = true;
}
displayExtras();
}
// REM* this applyExtras call is defined in waiterdesktop.js - the dialog is already closed
function applyExtras() {
var assignedExtras = [];
for (var i = 0; i < e_extras.length; i++) {
var anExtra = e_extras[i];
var extraid = anExtra.extraid;
var extraname = anExtra.name;
if (e_extras_selection[i]) {
// REM* yes this extra was selected
assignedExtras[assignedExtras.length] = {id: extraid, name: extraname};
}
}
addProductToNewOrders(e_prod.id,e_option,assignedExtras,"NO",0);
}var actcount = 0;
var actprice = 0;
var actname = "";
var selectedEntry = null;
var actchangedprice = false;
var actoption = "";
var acttogo = 0;
var origprice = 0.00;
// REM* some defines:
var CHANGE_ALL = 0;
var CHANGE_ONE = 1
function bindNewOrderItem() {
$(".ordereditem-item-new").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
var indexInGroupedNewOrders = parseInt(this.id.split('_')[2]);
selectedEntry = {
count: groupedNewOrders.count[indexInGroupedNewOrders],
name: groupedNewOrders.name[indexInGroupedNewOrders],
price: groupedNewOrders.price[indexInGroupedNewOrders],
option: groupedNewOrders.option[indexInGroupedNewOrders],
extras: groupedNewOrders.extras[indexInGroupedNewOrders],
prodid: groupedNewOrders.prodids[indexInGroupedNewOrders],
origidxs: groupedNewOrders.origidxs[indexInGroupedNewOrders],
changedPrices: groupedNewOrders.changedPrices[indexInGroupedNewOrders],
togos: groupedNewOrders.togos[indexInGroupedNewOrders]
};
acttogo = groupedNewOrders.togos[indexInGroupedNewOrders];
actcount = groupedNewOrders.count[indexInGroupedNewOrders];
actname = groupedNewOrders.name[indexInGroupedNewOrders];
actchangedprice = groupedNewOrders.changedPrices[indexInGroupedNewOrders];
actoption = groupedNewOrders.option[indexInGroupedNewOrders];
origprice = groupedNewOrders.price[indexInGroupedNewOrders];
if (actchangedprice === "NO") {
actprice = origprice;
} else {
actprice = actchangedprice;
}
insertDataIntoActDialog();
// REM* open dialog
var height = 400;
if (rightchangeprice == 1) {
height = 600;
}
$( "#actmenudlg" ).dialog({
autoOpen: false,
modal: true,
height: height,
width: 600,
buttons: {
"Abbrechen": function() {$(this).dialog("close"); },
"Löschen": function() {$(this).dialog("close"); delNewOrderItem(); },
"Alle ändern": function() {$(this).dialog("close"); changeAllNewOrders(); },
"Einen Artikel ändern": function() {$(this).dialog("close"); changeOneNewOrder();}
}
});
$(".ui-dialog-buttonset .ui-button").css("font-weight","bold");
$(".ui-dialog-buttonset .ui-button").css("color","black");
$(".ui-dialog-buttonset .ui-button:nth-child(2)").css("background-color","#ff0000");
$("#actmenudlg").dialog("open");
});
}
function insertDataIntoActDialog() {
$("#actdiscount1btn").html(discount1 + "%");
$("#actdiscount2btn").html(discount2 + "%");
$("#actdiscount3btn").html(discount3 + "%");
$("#actcountno").html(actcount + "x");
$("#actname").html(actname);
var formattedPrice = actprice.replace(".",decpoint);
$("#actpriceinfo").html(formattedPrice + " " + currency);
$("#actremarkfield").val(actoption);
if (acttogo == 0) {
$('#acttogocheckbox').prop('checked', false);
} else {
$('#acttogocheckbox').prop('checked', true);
}
if (rightchangeprice == 1) {
$("#actdiscount").show();
$("#actprice").show();
} else {
$("#actdiscount").hide();
$("#actprice").hide();
}
bindActBtn();
}
function bindActBtn() {
$(".actbtn").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
var cmd = this.id;
if (cmd === "actminusbtn") {
if (actcount > 0) {
actcount--;
}
} else if (cmd === "actplusbtn") {
actcount++;
} else if (cmd === "actdiscount1btn") {
actprice = origprice - origprice * discount1/100;
$("#actpricefield").val(actprice.toString().replace(".", decpoint));
} else if (cmd === "actdiscount2btn") {
actprice = origprice - origprice * discount2/100;
$("#actpricefield").val(actprice.toString().replace(".", decpoint));
} else if (cmd === "actdiscount3btn") {
actprice = origprice - origprice * discount3/100;
$("#actpricefield").val(actprice.toString().replace(".", decpoint));
}
insertDataIntoActDialog();
});
}
function changeAllNewOrders() {
actionNewOrderConfirm(CHANGE_ALL);
}
function changeOneNewOrder() {
actionNewOrderConfirm(CHANGE_ONE);
}
function delNewOrderItem() {
actcount = 0;
actionNewOrderConfirm(CHANGE_ALL);
}
function actionNewOrderConfirm(howmany) {
// which entry was modified?
var groupEntry = selectedEntry;
if (rightchangeprice == 1) {
var changedPrice = $("#actpricefield").val().trim();
changedPrice = changedPrice.replace(",", ".");
if (changedPrice > 999.99) {
alert("Maximaler Preis für das Produkt überschritten");
return;
}
if (changedPrice == "") {
changedPrice = "NO";
} else {
// REM* test for numeric
if (!$.isNumeric(changedPrice)) {
alert("Es wurde ein falsches Zahklenformat angegeben");
return;
} else {
actprice = changedPrice;
$("#actpricefield").val("");
}
}
} else {
changedPrice = "NO";
}
var togo = $("#acttogocheckbox").prop('checked');
if (togo) {
togo = 1;
} else {
togo = 0;
}
if (howmany == CHANGE_ONE) {
// REM* change only one item
var allIdx = groupEntry.origidxs;
neworders[allIdx[0]].option = $("#actremarkfield").val();
neworders[allIdx[0]].changedPrice = changedPrice;
neworders[allIdx[0]].togo = togo;
} else {
// REM* change all items
var allIdx = groupEntry.origidxs;
for (i = 0; i < allIdx.length; i++) {
var idx = allIdx[i];
neworders[idx].option = $("#actremarkfield").val();
neworders[idx].changedPrice = changedPrice;
neworders[idx].togo = togo;
}
}
$("#actremarkfield").val("");
var oldcount = groupEntry.count;
var newcount = actcount;
var diff = newcount - oldcount;
if (diff < 0) {
// less entries
var entriesToRemove = 0 - diff; // now again positiv
var allIdx = groupEntry.origidxs;
var i = 0;
for (i = 0; i < entriesToRemove; i++) {
var anIdxToRemove = allIdx.pop();
neworders.splice(anIdxToRemove, 1);
}
}
if (diff > 0) {
// more entries - duplicate an entry
var allIdx = groupEntry.origidxs;
var sampleIdx = allIdx[0]; // take for copy
var prodid = neworders[sampleIdx].prodid;
var changedPrice = neworders[sampleIdx].changedPrice;
var togo = neworders[sampleIdx].togo;
var option = neworders[sampleIdx].option;
var extras = neworders[sampleIdx].extras;
for (i = 0; i < diff; i++) {
addProductToNewOrders(prodid, option, extras, changedPrice, togo);
}
}
showNewOrders();
}var taxtype = "normal";
// REM* info about items to pay and the table - after products are retrieved for table
// REM* this is the list of items, including double entries:
var prodsToPayList = [];
// REM* this is the list that is grouped of all items in the "oben" list, i.e. still not on the receipt
var prodsToPayListGrouping = [];
//REM* this is the list of items, including double entries, of all entries already marked as being on the receipt
var prodsOnReceiptList = [];
// REM* this is the list that is grouped of all items in the "unten" list, i.e. on the receipt
var prodsOnReceiptListGrouping = [];
// REM* following is array of hashvalue -> onreceipt,
var prodsaccounted = [];
// REM* if a receipt shall be printed or only cash operation
var doPrint = false;
function startCashProcess() {
prodsaccounted = [];
getAndShowPayItems();
}
function getAndShowPayItems() {
if (panelMode === "paydesk") {
var tableid = 0;
if (selectedroomindex != null) {
if (selectedroomindex >= 0) {
if (selectedtableindex != null) {
var theTable = roominfo.roomstables[selectedroomindex].tables[selectedtableindex];
tableid = theTable.id;
taxtype = "normal";
} else {
tableid = null;
}
} else {
// REM* togo
tabeid = 0;
taxtype = "togo";
}
} else {
// no room or table set
tableid = null;
}
if (tableid != null) {
doAjax("GET","php/contenthandler.php?module=queue&command=getJsonProductsOfTableToPay",{ tableid: tableid },showProductsToPay,"Fehler bei der Datenübermittlung",true);
} else {
// REM* a table or TOGO-Room was not selected -> empty set of products to pay
prodsToPayList = [];
displayProdsToPayForTable();
displayProdsOnReceipt();
}
}
}
function showProductsToPay(answer) {
if (answer.status != "OK") {
alert("Fehler");
return;
}
prodsToPayList = answer.msg;
displayProdsToPayForTable();
displayProdsOnReceipt();
}
function displayProdsToPayForTable() {
bindHostButton("#hostbutton");
if (prodsToPayList.length == 0) {
$("#oben").html("Keine weiteren Artikel vorhanden.");
} else {
// REM* first group the items
prodsToPayListGrouping = new Grouping(prodsToPayList,createHashOfPayableItem);
prodsToPayListGrouping.group();
var listContent = prodsToPayListGrouping.outputList(createPayableItemListElement);
$("#oben").html(listContent);
}
$(".payable").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
// REM* get id - it is something like: payable_3 (because only this needs to be updated)
var id = this.id;
// REM* get rowIndex of item
var rowIndex = $( ".payable" ).index(this );
// REM* get an item from the payableList
var clickedEntry = prodsToPayListGrouping.sortedset[rowIndex];
var accounted = aProdToPayIsClicked(clickedEntry);
// prodsOnReceiptList[prodsOnReceiptList.length] = removedEntry;
updateAccounted(id,accounted,clickedEntry.count);
displayProdsOnReceipt();
});
$("#payall").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
for (var i=0;i<prodsToPayListGrouping.sortedset.length;i++) {
var aGroupedPayableItem = prodsToPayListGrouping.sortedset[i];
var count = aGroupedPayableItem.count;
var hash = createHashOfPayableItem(aGroupedPayableItem);
setAccountedNumber(aGroupedPayableItem,count);
}
displayProdsToPayForTable();
displayProdsOnReceipt();
});
$("#paydeskcash").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
doPrint = false;
// REM* the payments should already be saved in "payments" in waiterdesktop.js
displayPayments();
});
$("#paydeskprint").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
doPrint = true;
// REM* the payments should already be saved in "payments" in waiterdesktop.js
displayPayments();
});
}
function displayPayments() {
var paymentList = "";
var max = 20;
if (paymentconfig == 1) {
// small selection
max = 2;
}
var sepAfterFirstPayment = false;
$.each(payments, function (i, payType) {
if (i < max) {
paymentList += '<div id="paym_' + payType.id + '" class="paymentitem" >' + payType.name + '</div>';
if (!sepAfterFirstPayment) {
paymentList += '<br><hr><br>';
sepAfterFirstPayment = true;
}
}
});
paymentList += '<div id="paym_cancel" class="paymentcancel" >' + P_CANCEL[lang] + '</div>';
$("#selectiondialog").html(paymentList);
var heightOfBox = 600;
if (paymentconfig == 1) {
heightOfBox = 380;
}
$("#selectiondialog").dialog({
autoOpen: false,
modal: true,
height: heightOfBox,
buttons: {
Abbrechen: function() {$(this).dialog("close"); }
}
});
$("#selectiondialog").dialog("open");
bindPayment();
}
function bindPayment() {
$(".paymentcancel").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
$("#selectiondialog").dialog("close");
});
$(".paymentitem").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
var id = this.id.split('_')[1];
$("#selectiondialog").dialog("close");
// REM* now really do the cash operation
startPayProcess(id);
});
}
function updateAccounted(divid,number,maxCount) {
if(number === maxCount) {
// REM* make it gray
$("#" + divid).removeClass("paystillopen");
$("#" + divid).removeClass("payallaccounted");
$("#" + divid).addClass("payallaccounted");
} else {
// REM* make is yellow
$("#" + divid).removeClass("paystillopen");
$("#" + divid).removeClass("payallaccounted");
$("#" + divid).addClass("paystillopen");
}
if (number === 0) {
$("#" + divid + " .payitemaccounted").html("");
} else {
$("#" + divid + " .payitemaccounted").html(number);
}
}
function getProdAccountedEntry(item) {
var hash = createHashOfPayableItem(item);
// REM* search for this hash
for (var i=0;i<prodsaccounted.length;i++) {
var aProd = prodsaccounted[i];
var otherHash = aProd.hash;
if (hash === otherHash) {
return aProd;
}
}
return null;
}
function setAccountedNumber(itemToCount,number) {
var theAccountedProd = getProdAccountedEntry(itemToCount);
if (theAccountedProd !== null) {
theAccountedProd.count = number;
} else {
var aProd = {
hash:createHashOfPayableItem(itemToCount),
count:number};
prodsaccounted[prodsaccounted.length] = aProd;
}
}
// REM* register a click on a payable item and return the number of items of this group
function aProdToPayIsClicked(itemToCount) {
var theAccountedProd = getProdAccountedEntry(itemToCount);
if (theAccountedProd !== null) {
// REM* ok the product was alreeady clicked - check that the maximum number is not exceeded
if (theAccountedProd.count < itemToCount.count) {
theAccountedProd.count = theAccountedProd.count + 1;
return theAccountedProd.count;
} else {
theAccountedProd.count = 0;
return 0;
}
} else {
var aProd = {
hash:createHashOfPayableItem(itemToCount),
count:1};
prodsaccounted[prodsaccounted.length] = aProd;
return 1;
}
}
function displayProdsOnReceipt() {
createProdsOnReceiptList();
// REM* first group the items
prodsOnReceiptListGrouping = new Grouping(prodsOnReceiptList,createHashOfPayableItem);
prodsOnReceiptListGrouping.group();
createAllEntriesInReceipt();
};
function createHashOfPayableItem(aProd) {
var longname = aProd["longname"];
if (aProd["pricelevelname"] != "A") {
longname += " (" + aProd["pricelevelname"] + ")";
}
longname += " - " + (parseFloat(aProd["price"]).toFixed(2).replace(".",decpoint));
if (aProd["togo"] == 1) {
longname = "To-Go: " + longname;
}
var extratxt = createExtraParagraphForOrderedEl(aProd["extras"]);
return toHtml(longname) + extratxt;
}
// REM* oben
function createPayableItemListElement(aProd) {
var count = "";
var numberOfPayable = 1;
if("count" in aProd) {
if (aProd["count"] > 1) {
count = aProd["count"] + "x ";
numberOfPayable = aProd["count"];
}
}
// REM* find the number of prods that have already been counted on the receipt
var complete = false;
var accountedItem = getProdAccountedEntry(aProd);
var accountedStr = "";
if (accountedItem !== null) {
if (accountedItem.count != 0) {
accountedStr = accountedItem.count;
}
if (accountedItem.count == numberOfPayable) {
complete = true;
}
}
var item = "";
if (complete) {
item = '<div id="payable_' + aProd["id"] + '" class="payitem payable payallaccounted">'
+ "<div class='payitemmain'>" + count + createHashOfPayableItem(aProd) + "</div>"
+ "<div class='payitemaccounted'>" + accountedStr + "</div>"
+ '</div>';
} else {
item = '<div id="payable_' + aProd["id"] + '" class="payitem payable paystillopen">'
+ "<div class='payitemmain'>"+ count + createHashOfPayableItem(aProd) + "</div>"
+ "<div class='payitemaccounted'>" + accountedStr + "</div>"
+ '</div>';
}
return item;
}
// REM* unten
function createOnReceiptItemListElement(aProd) {
var count = "";
if("count" in aProd) {
if (aProd["count"] > 1) {
count = aProd["count"] + "x ";
}
}
var item = '<div id="payable_' + aProd["id"] + '" class="payitem onreceipt">' + count + createHashOfPayableItem(aProd) + '</div>';
return item;
}
function getProdOfAllProdsWithHash(hash) {
var allSortedProds = prodsToPayListGrouping.sortedset;
for (var i=0;i<allSortedProds.length;i++) {
var aProd = allSortedProds[i];
if (createHashOfPayableItem(aProd) === hash) {
return aProd;
}
}
return null;
}
function createProdsOnReceiptList() {
prodsOnReceiptList = [];
for (var i=0;i<prodsaccounted.length;i++) {
var accountedProd = prodsaccounted[i];
var hash = accountedProd.hash;
var payableItem = getProdOfAllProdsWithHash(hash);
for (j=0;j<accountedProd.count;j++) {
prodsOnReceiptList[prodsOnReceiptList.length] = clonePayableItem(payableItem);
}
}
}
function clonePayableItem(otherItem) {
var newItem = {
extras: otherItem.extras,
id: otherItem.id,
ids: otherItem.ids,
longname: otherItem.longname,
price: otherItem.price,
pricelevelname: otherItem.pricelevelname,
prodid: otherItem.prodid,
tax: otherItem.tax,
togo: otherItem.togo
}
return newItem;
}
// REM* use prodsOnReceiptListGrouping
function createAllEntriesInReceipt() {
var entryListForReceipt = new Array();
// REM* collect all entries in the list #unten
for (var i = 0; i < prodsOnReceiptList.length; i++) {
var item = prodsOnReceiptList[i];
var entry = {
prodid: item["prodid"],
queueid: item["id"],
longname: item["longname"],
price: item["price"],
tax: item["tax"],
togo: item["togo"],
extras: item["extras"],
pricelevelname: item["pricelevelname"]
};
entryListForReceipt = addEntryOrIncreaseCount(entryListForReceipt, entry);
}
var tablecontent = createReceiptHeader();
tablecontent += generateProdPart(decpoint, entryListForReceipt)
var taxGerFormat = $("#info-page").data("usstGerVal");
if ($("#info-page").data("taxtype") == "togo") {
taxGerFormat = $("#info-page").data("togoTaxGerVal");
}
var taxes = listTaxesBasedOnUntenList(decpoint);
// REM* taxes are now strings with country-specific decpoint
tablecontent += createReceiptFooter(taxGerFormat, lang, taxes);
if (showHostTemplate) {
tablecontent += hostTemplate;
}
var completetable = "<table><br>" + tablecontent + "</table>";
$('#receiptpanel').html(completetable);
calcSum(); // updates info:
var calculatedBill = $('#receiptpart').html();
$('#info-page').data("receipthtml", calculatedBill);
displayRightButtons();
}
function getTableName() {
if (selectedtableindex != null) {
var theTable = roominfo.roomstables[selectedroomindex].tables[selectedtableindex];
return theTable.name;
} else if (selectedroomindex == "-1") {
return "Zum Mitnehmen";
} else {
return null;
}
}
function createReceiptHeader() {
var header = genCreateReceiptHeader(0,
"",
getTableName(),
loggedinUser,
currency
);
return header;
}
function createReceiptFooter(taxGerFormat, lang, taxes) {
var footer = genCreateReceiptFooterNoSum(taxGerFormat,
0,
"",
taxes);
return footer;
}
// REM* on the prodsaccounted there is an item with a count, but a single queueid. This is not good.
// REM* --> so get the different queueids and so many as the count says -> this is for paying
function getQueueIdsDueToCountOfItem(item) {
var ids = [];
var hash = item.hash;
// REM* get the prods queue ids from prodsToPayList
var count = item["count"];
for (var i=0;i<prodsToPayList.length;i++) {
var candidate = prodsToPayList[i];
var hashOfCandidate = createHashOfPayableItem(candidate);
if (hashOfCandidate === hash) {
ids[ids.length] = candidate["id"];
if (ids.length >= count) {
break;
}
}
}
return ids;
}
function startPayProcess(paymentid) {
var tablename = getTableName();
var tableid = 0;
if (selectedroomindex != -1) {
tableid = selectedtableindex;
}
var tax = $("#info-page").data("usst");
if ($("#info-page").data("taxtype") == "togo") {
tax = $("#info-page").data("togotax");
}
checkForLogIn();
var ids=[];
var a = prodsOnReceiptList;
var b = prodsaccounted;
var c = prodsOnReceiptListGrouping;
for (var i=0;i<prodsaccounted.length;i++) {
var item = prodsaccounted[i];
// REM* the count may be 0 if an item was added and removed again
if (item.count != 0) {
$.merge(ids, getQueueIdsDueToCountOfItem(item));
}
}
ids = ids.join();
// REM* default: declare as ready and served if user has pressed Paydesk button in waiters view
var declareAsReady = 1;
// REM* but if "only digital" then use the setting of digigopaysetready
if (workflowconfig == 1) {
// REM* only digital workflow: products shall be set to ready if specified in config
declareAsReady = digigopaysetready;
}
$.ajax({ type: "POST",
dataType: "json",
data : { ids: ids,
// html : htmlContentWithoutHosting,
brutto: billbrutto,
netto: billnetto,
tableid : tableid,
paymentid : paymentid,
tax : tax,
decpoint : decpoint,
declareready: declareAsReady,
host: (showHostTemplate ? 1 : 0)
},
url: "php/contenthandler.php?module=queue&command=declarePaidCreateBillReturnBillId",
async: false,
success : function(jsonText)
{
var status = jsonText.status;
var billinfo = jsonText.msg;
if (status != "ERROR") {
billid = billinfo.billid;
billdate = billinfo.date;
if (billid < 0) {
alert("Error! Bitte erneut versuchen. Error code: " + billid);
window.location.reload(false);
} else {
requestRoomInformation();
var lang = $("#info-page").data("billlanguage");
$("#billid").html(P_ID[lang] + billid);
$("#billdate").html(billdate);
if (doPrint) {
var payPrintType = $("#info-page").data("payPrintType");
if (payPrintType == 's') {
printBill(billid);
} else {
$("#oben").hide();
var receiptToPrint = "<table>" + $(".receipttable").html() + "</table>";
printContent(receiptToPrint);
}
}
startCashProcess();
}
} else {
alert("Fehler: " + billinfo);
}
},
error: function( text ) {
alert( "Sorry, there was a problem! " + text);
}
});
}var P_DESCR = ["Beschreibung","Description","Descripción"];
var P_PRICE = ["Preis","Price","Precio"];
var P_TOTAL = ["Total","Total","Total"];
var P_ID = ["Id:","Id:","Id:"];
// for the UI
var P_ROOMSEL = ["Raumauswahl","Room selection","Selección de espacio"];
var P_PAYDESK_ACTIONS = ["Kassenaktionen","Paydesk actions","Acciones de caja"];
var P_BAR_INPUT = ["Bareinlage","Input money","Insertar dinero"];
var P_BAR_GET = ["Barentnahme","Take money","Sacar dinero"];
var P_BAR_SUM = ["Einnahmen","Revenue","Cobro"];
var P_TITLE = ["Kasse","Paydesk","Caja"];
var P_TABLE = ["Tisch","Table","Mesa"];
var P_TABLE_SEL = ["Tischauswahl","Select table","Qué mesa?"];
var P_NOT_PAID = ["Ausstehend für ","Not paid for ","Impagado para "];
var P_ALL = ["Alles","All","Todo"];
var P_CONTENT_RECEIPT = ["Inhalt Kassenbon","Content of receipt","Contenido del tique"];
var P_ONLY_PAY = ["Nur Zahlung","Only pay","Solo pagar"];
var P_PAY_PRINT = ["Bondruck","Pay+Print","Pagar+Imprimir"];
var P_CHANGE_CALC = ["Wechselgeldrechner:","Change Calculator:","Calculadora de Cambio:"];
var P_CHOOSE_PAYWAY = ["Auswahl der Zahlungsart:","Selection of method of payment:","Selección del modo de pago:"];
var P_CANCEL = ["Abbrechen","Cancel","Cancelar"];
var P_CASHTAKEOUT = ["Barentnahme aus der Kasse","Cash take-out","Sacar dinero"];
var P_CASHTAKIN = ["Bareinlage in die Kasse","Cash insert","Insertar dinero"];
var P_AMOUNT = ["Betrag:","Amount:","Valor:"];
var P_OVERVIEW = ["Übersicht Kellnerkasse", "Overview waiter purse","Resumen cartera de bolsillo"];
var P_PUT_IN = ["Einlegen","Insert","Insertar"];
var P_TAKE_OUT = ["Entnehmen","Take out","Sacar"];
var P_OVERV_DETAILS = ["Diese Übersicht enthält die Bar-Bewirtungseinnahme durch den Kellner seit der letzten Tageslosung sowie als weiteren Wert den Kassenstand unter Berücksichtigung der eigenen Eingaben und Entnahmen.",
"This overview contains the cash amount of money of this waiter since the last closing as well as the total amount of money including the own cash insert and take-out actions.",
"Este resumen contiene todo el dinero al contado por cobro para el camarero, y también el dinero incluido con acciones de insertar y sacar."];
var P_CASH_SUM = ["Bewirtungseinnahmen:","Cash by payment:", "Cobro:"];
var P_INCLUDE_OWN = ["inkl. eigener Kassen-Eingaben/Entnahmen:","incl. own cash insert/take-outs:","incl. tomas y entradas proprias:"];
var P_NO_ELEM = ["Keine Rechnungselemente","No items selected","Ningún producto selecionado"];
var P_NO_ELEM_DETAILS = ["Es wurden keine abrechenbaren Produkte festgelegt (der Bon ist leer!).",
"There are no selected items. The receipt is empty!",
"No hay ningún elemento seleccionado para pagar."];
var P_CASHACTION_OK = ["Kassenaktion abgeschlossen.","Action completed.","Acción terminado."];
var P_NAV = ["Navigation","Navigation","Navigación"];
var P_ORDER_ACTION = ["-> Bestellansicht","-> Order view", "-> Vista de Orden"];
var P_TO_PAY = ["Zu zahlen: ","To pay: ", "Pagar total: "];
var P_PAY_RETURN = ["Zurück: ", "Return: ","Torna: "];
var P_CALC_PAYBACK = ["Berechne","Calculate","Calcular"];
var P_HAS_PAID = ["Bezahlt: ","Paid: ","Pagado: "];
var P_TOGO = ["Außer-Haus-Verkauf","Sale with Tax No 2","Venta IVA 2"];
var P_TIP = ["nur Trinkg.: ","Only tip: ","Solo prop.: "];
var P_TOTAL_INCL_TIP = ["Zielbetrag:","Target pay:","Quiere pagar:"];
var CALC_TIP_TXT = ["Angabe extra Trinkg.","Do Tip separate","Propina individual"];
var CALC_TOTAL_TXT = ["Angabe inkl.Trinkg.","Do Tip incl.","Propina incl."];
function getGeneralConfigItems() {
doAjax("GET", "php/contenthandler.php?module=admin&command=getGeneralConfigItems", null, insertGeneralConfigItems, "Fehler Konfigurationsdaten");
}
function getPayments(fct) {
doAjax("GET", "php/contenthandler.php?module=admin&command=getPayments", null, fct, "Fehler Zahlungswege");
}
function insertGeneralConfigItems(configResult) {
if (configResult.status == "OK") {
var values = configResult.msg;
decpoint = values.decpoint;
$("#info-page").data("decpoint",values.decpoint);
currency = values.currency;
var taxval = values.tax;
var usstGerVal = taxval.replace(".", decpoint);
$("#info-page").data("usstGerVal",usstGerVal);
$("#info-page").data("usst",taxval);
taxval = values.togotax;
usstGerVal = taxval.replace(".", decpoint);
$("#info-page").data("togoTaxGerVal",usstGerVal);
$("#info-page").data("togotax",taxval);
$("#info-page").data("companyinfo",values.companyinfo);
$("#info-page").data("payPrintType",values.payprinttype);
$("#info-page").data("currency",values.currency);
$("#info-page").data("billlanguage",values.billlanguage);
$("#info-page").data("userlanguage",values.userlanguage);
receiptfontsize = parseInt(values.receiptfontsize);
$("#receiptpart").css("font-size",receiptfontsize + "px");
paymentconfig = values.paymentconfig;
$("#curtopay2").html(" " + values.currency);
workflowconfig = values.workflowconfig;
digigopaysetready = values.digigopaysetready;
setLanguage(values.userlanguage);
} else {
$("#contentpart").hide();
setTimeout(function(){document.location.href = "index.html"},250); // not logged in
//alert("Fehler beim Aufruf der Seite: " + configResult.msg);
}
}
// arrayToFill:
// [0]: count prodid prodid-pricelevelname queueid longname price pricelevelname
// [1]: count prodid prodid-pricelevelname queueid longname price pricelevelname
//
// entry:
// [0]: prodid queueid longname price pricelevelname
// REM* [2]: name, [3]: price, [4]: tax, [5]: togo, [6] extras, [7]: pricelevel
function addEntryOrIncreaseCount(arrayToFill,entry) {
var index=0;
var found = false;
var combinedIdPricelevelPriceExtras = entry.prodid + "-" + entry.extras.join("_") + entry.price + "-" + entry.pricelevelname + "#" + entry.tax + "_" + entry.togo;
for (index=0;index<arrayToFill.length;index++) {
var anEntry = arrayToFill[index];
// REM* entry = prodid,queueid,longname,price,pricelevelname
// REM* anEntry = count,prodid,"prodid-pricelevel",queueid,longname,price
if (anEntry[2] == combinedIdPricelevelPriceExtras) {
// REM* prodid equal
anEntry[0] += 1;
found = true;
}
}
if (!found) {
arrayToFill.push(new Array(1,entry,combinedIdPricelevelPriceExtras));
}
return arrayToFill;
}
function genCreateReceiptHeader(lang,billid,tablename,username,currency) {
var priceStyle = 'style="border: solid black 0px;padding: 3px;text-align:right;vertical-align:bottom;"';
var tableinfo = P_TABLE[lang] + " " + tablename;
var waiterinfo = P_WAITER[lang] + " " + username;
var header = '';
header += '<tr><td colspan=6>&nbsp;</tr>';
header += '<tr><td colspan=4>' + tableinfo + ' <td id="billid" colspan=2 ' + priceStyle + '>ID:' + billid + '</tr>';
header += '<tr><td colspan=4>&nbsp;<td id="billdate" colspan=2 ' + priceStyle + '></tr>';
header += '<tr><td colspan=6>' + waiterinfo + "</tr>";
header += '<tr><td colspan=6>&nbsp</tr>';
header += '<tr><td>' + P_NO[lang] + '<td colspan=3>' + P_DESCR[lang] + '<td ' + priceStyle + '>' + P_PRICE[lang] + '<td ' + priceStyle + '>' + P_TOTAL[lang] + '</tr>';
return header;
}
function genCreateReceiptFooterNoSum(taxGerFormat, lang, companyInfo, taxes) {
return genCreateReceiptFooter(taxGerFormat, lang, companyInfo,"","","", taxes);
}
// REM* taxes must be strings with decpoint already country-specific!
function genCreateReceiptFooter(taxGerFormat, lang, companyInfo,mwst,netto,sum, taxes) {
var priceStyle = 'style="border: solid black 0px;padding: 3px;text-align:right;vertical-align:bottom;"';
var infoStyle = 'style="text-align:center;vertical-align:bottom;"';
var emptyLine = '<tr><td colspan=6>&nbsp</tr>';
var footer = emptyLine;
footer += '<tr><td colspan=2>' + P_MWST[lang] + '% <td ' + priceStyle + '>' + P_MWST[lang] + '<td ' + priceStyle + '>' + P_NETTO[lang] + '<td ' + priceStyle + ' colspan=2>' + P_BRUTTO[lang] + '</tr>';
// REM* for each tax create a line
for (var i=0;i<taxes.length;i++) {
var tax = taxes[i];
tax = tax.replace(",","-");
footer += '<tr><td id="taxval' + tax + '" colspan=2><td id="mwst' + tax + '" ' + priceStyle + '>' + mwst + '<td id="netto' + tax + '" ' + priceStyle + '>' + netto + '<td id="brutto' + tax + '" ' + priceStyle + ' colspan=2>' + sum + '</tr>';
}
footer += emptyLine;
footer += '<tr><td> &nbsp; <td colspan=3>' + P_SUM[lang] + '<td id="priceinreceipt2" ' + priceStyle + ' colspan=2>' + sum + '</td></tr>';
footer += emptyLine;
footer += '<tr><td ' + infoStyle + ' colspan=6><center>&nbsp;<br>';
footer += toHtml(companyInfo).replace(/(?:\r\n|\r|\n)/g, '<br />');
footer += '</center></tr>';
return footer;
}
function generateOneProdLine(count,productname,price,pricelevelname,decPoint,togo) {
var priceStyle = 'style="border: solid black 0px;padding: 3px;text-align:right;vertical-align:bottom;"';
var noStyle = 'style="border: solid black 0px;padding: 3px;text-align:center;vertical-align:bottom;"';
var formattedPrice = (parseFloat(price)).toFixed(2).replace(".",decPoint);
if (pricelevelname != "A") {
productname += " (" + pricelevelname + ")";
}
if (togo == 1) {
productname = "To-Go: " + productname;
}
var totalPrice = count * price;
var aProductLine = '<tr>';
var cutStyle = 'style="white-space: nowrap;overflow: hidden;text-overflow:ellipsis;width: 60%;"';
aProductLine += '<td ' + noStyle + ' id="count">' + count + '<td colspan=3 ' + cutStyle + '>' + productname;
aProductLine = aProductLine + '<td ' + priceStyle + '>' + formattedPrice;
aProductLine += '<td ' + priceStyle + '>' + totalPrice.toFixed(2).replace(".",decPoint) + '</tr>';
return aProductLine;
}
function generateProdPartByDbContent(decPoint,prods) {
var index=0;
tablecontent = '';
for (index=0;index<prods.length;index++) {
// for the html receipt
var anEntry = prods[index];
var count = anEntry.count;
var productname = anEntry.productname;
var price = anEntry.price;
var pricelevelname = anEntry.pricelevel;
tablecontent += generateOneProdLine(count,productname,price,pricelevelname,decPoint);
}
return tablecontent;
}
// REM* create an array of taxes that are present in the current bill
function listTaxes(collectionOfTaxes,decpointx) {
var taxes = [];
for (var i=0;i<collectionOfTaxes.length;i++) {
var tax = parseFloat(String(collectionOfTaxes[i]));
tax = tax.toFixed(2).replace(".",decpointx);
if (taxes.indexOf(tax) < 0) {
// REM* tax was not yet in the list
taxes[taxes.length] = tax;
}
}
return taxes;
}
function listTaxesBasedOnUntenList(decpointx) {
// REM* which different taxes do we have?
var mytaxes = [];
for (var i=0;i<prodsOnReceiptList.length;i++) {
var prodEl = prodsOnReceiptList[i];
mytaxes.push(prodEl.tax);
}
return listTaxes(mytaxes,decpointx);
}
function calcSum() {
// REM* which different taxes do we have?
var taxes = listTaxesBasedOnUntenList(decpoint);
var jsonContent = prodsToPayList;
var sum = 0.0;
var nettosum = [];
var bruttosum = [];
var mwstsum = [];
// REM* initiate
for (var i=0;i<taxes.length;i++) {
nettosum[i] = 0.0;
bruttosum[i] = 0.0;
mwstsum[i] = 0.0;
}
var overallnetto = 0.0;
var overallbrutto = 0.0;
var overallmwst = 0.0;
for (var k=0;k<prodsOnReceiptList.length;k++) {
var item = prodsOnReceiptList[k];
var bruttoprice = parseFloat(item["price"]);
var taxStr = item["tax"];
var tax = parseFloat(taxStr);
taxStr = taxStr.replace(".",decpoint);
var nettoprice = bruttoprice/(1 + tax/100.0);
var mwst = bruttoprice - nettoprice;
// REM* find index of tax in array
var taxIndex = 0;
for (var i=0;i<taxes.length;i++) {
if (taxes[i] == taxStr) {
taxIndex = i;
}
}
nettosum[taxIndex] = nettosum[taxIndex] + nettoprice;
bruttosum[taxIndex] = bruttosum[taxIndex] + bruttoprice;
mwstsum[taxIndex] = mwstsum[taxIndex] + mwst;
overallnetto += nettoprice;
overallbrutto += bruttoprice;
overallmwst += mwst;
};
for (var j=0;j<taxes.length;j++) {
var tax = taxes[j];
var taxid = tax.replace(",","-");
// REM* comma in id is not good - replace by a line
$("#taxval" + taxid).html(tax + "%");
$("#mwst" + taxid).html(mwstsum[j].toFixed(2).replace(".",decpoint));
$("#netto" + taxid).html(nettosum[j].toFixed(2).replace(".",decpoint));
$("#brutto" + taxid).html(bruttosum[j].toFixed(2).replace(".",decpoint));
}
billbrutto = overallbrutto;
billnetto = overallnetto;
$("#priceinreceipt").html(overallbrutto.toFixed(2).replace(".",decpoint) + " " + currency);
$("#priceinreceipt2").html(overallbrutto.toFixed(2).replace(".",decpoint) + " " + currency);
}
function bindHostButton(hostbtnid) {
$("#hostbutton").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
if (showHostTemplate) {
showHostTemplate = false;
} else {
showHostTemplate = true;
}
if (hostbtnid != null) {
// REM* mark button on/off
$(hostbtnid).removeClass('btnswitchon');
$(hostbtnid).removeClass('btnswitchoff');
if (showHostTemplate) {
$(hostbtnid).addClass('btnswitchon');
} else {
$(hostbtnid).addClass('btnswitchoff');
}
}
var billlang = $("#info-page").data("billlanguage");
if (billlang == 0) {
createAllEntriesInReceipt();
} else {
if (lang == 0) {
alert("Bewirtungsbeleg steht nur für deutsche Kassenbons zur Verfügung.");
} else if (lang == 1) {
alert("Bewirtungsbeleg is only possible for German receipts.");
} else if (lang == 2) {
alert("Bewirtungsbeleg se puedo usar solo para tiques alemanes.");
}
}
});
}
function printBill(billid) {
doAjax("POST","php/contenthandler.php?module=printqueue&command=queueReceiptPrintJob",
{billid : billid , useaddrecprinter: 1}, null, "Druckfehler");
} </script>
</head>
<style>
</style>
<body>
<div class="ospage">
<header class="header">Kellneransicht (<span id="panelmodetxt">Bestellung</span>)</header>
<aside class="aside aside1">
<div class="tablepanel">
<header id="location" class="tablepanelheader">Raum: Raum xyz</header>
<div id="roompanel" class="roompanel"></div>
<div id="tablepanelcontent" class="tablepanelcontent"></div>
<div id="receiptpanel" style="display:none;"></div>
</div>
</aside>
<article class="main">
<div id="groupchain" class="grouppanel"></div>
<div id="groupchoice" class="grouppanel"></div>
<div id="paybuttonpanel" style="display:none;">
<input id="payall" class="input50 inputwhite" type="submit" value="Alles" />
<div class="infoarea"><span id="priceinreceipt"></span></div>
</div>
<div id="oben" class="paypanel" style="display:none;"></div>
<hr>
<div id="unten" class="paypanel" style="display:none;"></div>
<!-- a hack: info-page is for compatibility to mobile view at which data is stored -->
<div id="info-page" style='display:none;'></div>
<div id="searchpanel" style="display:none;"><input id="search" class="input100 inputwhite" type="text" placeholder="Suchen..." /></div>
<div id="productspanel" class="productspanel" style="display:none;"></div>
<div id="remarkpanel" style="display:none;"><input id="remark" class="input100 inputwhite" type="text" placeholder="Produktbemerkung" /></div>
</article>
<aside class="aside aside2">
<div class="buttonarea">
<input id="mainmenubtn" class="input100 inputwhite"type="submit" value="Hautmenü" />
<input id="paydeskbtn" class="input100 inputwhite"type="submit" value="Kasse" style="display:none;"/><br>
<input id="hostbutton" class="input100 inputwhite btnswitchoff"type="submit" style="display:none;" value="Bewirtungsbeleg" />
<input id="paydeskcash" class="input100 inputwhite"type="submit" style="display:none;" value="Zahlung" />
<input id="paydeskprint" class="input100 inputwhite"type="submit" style="display:none;" value="Bondruck" />
<input id="goorderbtn" class="input100 inputwhite"type="submit" value="Bestellung" style="display:none;"/>
<input id="workbtn" class="input100 inputwhite" type="submit" value="Arbeitsbon" style="display:none;" />
<input id="sendNewOrders" class="input100 inputwhite" type="submit" value="Bestellung abschließen" style="display:none;" />
</div>
<div id="neworders" class="ordereditem-container"></div>
</aside>
<div id="ordered" class="ordereditem-sentcontainer"></div>
<footer class="footer">
<div id="loggedinuser" style="color:white;"></div>
<div id="versioninfo"></div>
</footer>
</div>
<div id="selectiondialog" title="Auswahl">Extras to select...</div>
<div id="unsentorderdlg" title="Achtung">
Die Bestellung würde noch nicht abgeschlossen. Wollen Sie die Bestellung verwerfen?
</div>
<div id="mainmenudlg" title="Hauptmenü">Hauptmenü</div>
<div id="actmenudlg" title="Aktion auswählen">
<header id="actprodinfo"><span id=actcountno>3x</span> <span id="actname">Warsteiner</span> (<span id="actpriceinfo">(1,00 Euro)</span>)</header>
<div id="actcounttogo">
<div id="actminusbtn" class="actbtn">-1</div>
<div id="actplusbtn" class="actbtn">+1</div>
<div id="acttogobtn" class="actbtn_notclickable"><input type="checkbox" id="acttogocheckbox" /> To-Go</div>
</div>
<div id="actremark">
<div>Bemerkung:&nbsp;</div>
<div>
<input id="actremarkfield" class="input100 inputwhite" type="text" placeholder="Notiz" />
</div>
</div>
<div id="actdiscount">
<div id="actdiscount1btn" class="actbtn">-1</div>
<div id="actdiscount2btn" class="actbtn">-1</div>
<div id="actdiscount3btn" class="actbtn">-1</div>
</div>
<div id="actprice">
<div>Neuer Preis:&nbsp;</div>
<div>
<input id="actpricefield" class="input100 inputwhite" type="text" placeholder="Neuer Preis" />
</div>
</div>
</div>
<div id="ordereditemdlg" title="Aktion">
<div id="ordereditem-info"></div>
<div id="orderedcancelpanel">
<input id="cancelcode" class="input100 inputwhite" type="text" placeholder="Stornierungscode" />
</div>
<div id="ordereditemremove" class="actbtn">Entfernen</div>
<div id="ordereditemreorder" class="actbtn">Nachbestellen</div>
<div id="ordereditemcancel" class="actbtn">Abbrechen</div>
</div>
</body>
</html>