2713 lines
86 KiB
PHP
2713 lines
86 KiB
PHP
|
<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 += " ☞";
|
||
|
}
|
||
|
if (p.isCooking == '1') {
|
||
|
status += " ♨";
|
||
|
}
|
||
|
if (p.isPaid == '1') {
|
||
|
status += " ☑";
|
||
|
}
|
||
|
|
||
|
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(" " + 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> </tr>';
|
||
|
header += '<tr><td colspan=4>' + tableinfo + ' <td id="billid" colspan=2 ' + priceStyle + '>ID:' + billid + '</tr>';
|
||
|
header += '<tr><td colspan=4> <td id="billdate" colspan=2 ' + priceStyle + '></tr>';
|
||
|
header += '<tr><td colspan=6>' + waiterinfo + "</tr>";
|
||
|
header += '<tr><td colspan=6> </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> </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> <td colspan=3>' + P_SUM[lang] + '<td id="priceinreceipt2" ' + priceStyle + ' colspan=2>' + sum + '</td></tr>';
|
||
|
footer += emptyLine;
|
||
|
|
||
|
footer += '<tr><td ' + infoStyle + ' colspan=6><center> <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: </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: </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>
|