From 6f9dcaf7ea5719956115412995a083385cead3e8 Mon Sep 17 00:00:00 2001 From: Geno Date: Thu, 19 Nov 2020 22:55:09 +0100 Subject: [PATCH] OrderSprinter 1.1.12 --- printserver/OrderSprinterPrintserver.exe | Bin 260096 -> 260096 bytes scripts/Liesmich.txt | 32 +++ scripts/backup-db-linux.sh | 61 ++++ webapp/OrderSprinterPrintserver.exe | Bin 260096 -> 260096 bytes webapp/bar.html | 2 +- webapp/bill.html | 2 +- webapp/elements/grouping.js | 97 +++++++ webapp/feedback.html | 2 +- webapp/index.html | 4 +- webapp/install.html | 2 +- webapp/install/installer.php | 32 ++- webapp/kitchen.html | 2 +- webapp/manager.html | 27 +- webapp/paydesk.html | 269 ++++++++++-------- webapp/php/admin.php | 68 +++-- webapp/php/bill.php | 114 ++++++-- webapp/php/closing.php | 2 +- webapp/php/printqueue.php | 2 +- webapp/php/queuecontent.php | 11 +- webapp/php/roomtables.php | 17 +- webapp/php/utilities/basedb.php | 1 + webapp/preferences.html | 2 +- webapp/products.html | 2 +- webapp/rating.html | 2 +- webapp/reports.html | 2 +- webapp/reservation.html | 2 +- webapp/supplydesk.html | 2 +- webapp/waiter.html | 344 +++++++++++++++-------- 28 files changed, 792 insertions(+), 311 deletions(-) create mode 100644 scripts/Liesmich.txt create mode 100755 scripts/backup-db-linux.sh create mode 100644 webapp/elements/grouping.js diff --git a/printserver/OrderSprinterPrintserver.exe b/printserver/OrderSprinterPrintserver.exe index 5475577caa1dcb30daf34efd4ad9b62082975360..3aa6d3c310b21ae7c18334d2b33b59f040eaa106 100644 GIT binary patch delta 25800 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 delta 24964 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 k /dev/null 2>&1 diff --git a/scripts/backup-db-linux.sh b/scripts/backup-db-linux.sh new file mode 100755 index 0000000..2d3c318 --- /dev/null +++ b/scripts/backup-db-linux.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# Die folgenden Werte müssen je nach Installation angepasst werden: + +mount="/dev/sdc1" +database="ordersprinter" +user="Benutzer" +password="DasPasswort" +serverbase="http://localhost/ordersprinter" +remoteaccesscode="123" + +if grep -qs "$mount" /proc/mounts; then + echo "Der USB-Stick ist bereits eingehaengt" +else + echo "Der USB-Stick ist noch nicht eingehaengt." + mount "$mount" /mnt + if [ $? -eq 0 ]; then + echo "Der USB-Stick konnte eingehaengt werden." + + # Halte die letzten 3 Sicherungen der DB vor: + if [ -f /mnt/db-dump-1.json ] + then mv /mnt/db-dump-1.json /mnt/db-dump-2.json + fi + if [ -f /mnt/db-dump.json ] + then mv /mnt/db-dump.json /mnt/db-dump-1.json + fi + + # Halte die letzten 3 Sicherungen des Kassenbuchs vor + if [ -f /mnt/kassenbuch-1.pdf ] + then mv /mnt/kassenbuch-1.pdf /mnt/kassenbuch-2.pdf + fi + if [ -f /mnt/kassenbuch.pdf ] + then mv /mnt/kassenbuch.pdf /mnt/kassenbuch-1.pdf + fi + + # + # Sicherung der Datenbank über die OrderSprinter Backup-Funktion + # (das ist die bevorzugte Variante, weil die Ausgabe-Datei wieder über die Wiederherstellungsfunktion + # vom OrderSprinter eingelesen werden kann). + # + # + wget --post-data "remoteaccesscode=$remoteaccesscode" -O /mnt/db-dump.json 2>>/dev/null "$serverbase/php/contenthandler.php?module=admin&command=autobackup" + # + # + # Sicherung der Datenbank direkt über mysqldump: + # (wird diese Variante genutzt, ist das Umkopieren anzupassen, wenn mehrere Datensicherungen aufbewahrt + # werden sollen.) + # + #mysqldump --user=$user --password=$password --databases $database > /mnt/db-dump.sql + + # + # Sicherung des Kassenbuchs als PDF + wget --post-data "remoteaccesscode=$remoteaccesscode" -O /mnt/kassenbuch.pdf 2>>/dev/null "$serverbase/php/contenthandler.php?module=bill&command=autoBackupPdfSummary&lang=0" + # + + umount /mnt + echo "Das Datenbank-Backup ist erfolgt, der USB-Stick wurde wieder ausgehaengt." + else + echo "Der USB-Stick konnte nicht eingehaengt werden, das Backup ist nicht erfolgt!" + fi +fi diff --git a/webapp/OrderSprinterPrintserver.exe b/webapp/OrderSprinterPrintserver.exe index 5475577caa1dcb30daf34efd4ad9b62082975360..3aa6d3c310b21ae7c18334d2b33b59f040eaa106 100644 GIT binary patch delta 25800 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 delta 24964 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 k - + diff --git a/webapp/bill.html b/webapp/bill.html index e4999fc..bf8b07d 100644 --- a/webapp/bill.html +++ b/webapp/bill.html @@ -5,7 +5,7 @@ - + diff --git a/webapp/elements/grouping.js b/webapp/elements/grouping.js new file mode 100644 index 0000000..eafe741 --- /dev/null +++ b/webapp/elements/grouping.js @@ -0,0 +1,97 @@ +function Grouping(set,hashFct) { + // initialization during construction of class + this.set = set; + + // setting by group() + this.sortedset = []; + + this.group = function() { + this.sortedset = []; + for (var i=0;i - + diff --git a/webapp/index.html b/webapp/index.html index 51512a8..6879c10 100644 --- a/webapp/index.html +++ b/webapp/index.html @@ -7,8 +7,8 @@ - - + + diff --git a/webapp/install.html b/webapp/install.html index 56deb8a..356daa6 100644 --- a/webapp/install.html +++ b/webapp/install.html @@ -679,7 +679,7 @@ $(document).ready(function() {   - +   diff --git a/webapp/install/installer.php b/webapp/install/installer.php index ed2b864..eb100f9 100644 --- a/webapp/install/installer.php +++ b/webapp/install/installer.php @@ -778,6 +778,30 @@ $ret &= $this->setVersion($prefix, '1.1.11'); return $ret; } +function updateUserTable1111_1112($prefix,$version) { +$pdo = $this->pdo; +try { +if ($version != "1.1.11") { +$ret = $this->updateUserTable1110_1111($prefix,$version); +if (!$ret) { +return false; +} +} + +$adminCl = new Admin(); +DbUtils::overrulePrefix($prefix); + +$sql = "ALTER TABLE %room% ADD `abbreviation` VARCHAR (10) NULL AFTER roomname"; +$stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); +$stmt->execute(); + +$this->updateVersion($pdo, '1.1.12'); +return true; +} catch (PDOException $e) { +return false; +} +} + function setVersion($prefix,$theVersion) { $pdo = $this->pdo; try { @@ -849,7 +873,7 @@ $this->basedb->doSQL($pdo,"INSERT INTO `%config%` (`id` , `name`, `setting`) VAL $this->basedb->doSQL($pdo,"INSERT INTO `%config%` (`id` , `name`, `setting`) VALUES (NULL , 'billlanguage', $billlanguage)"); $this->basedb->doSQL($pdo,"INSERT INTO `%config%` (`id` , `name`, `setting`) VALUES (NULL , 'currency', '$currency')"); $this->basedb->doSQL($pdo,"INSERT INTO `%config%` (`id` , `name`, `setting`) VALUES (NULL , 'receiptfontsize', '12')"); -$this->basedb->doSQL($pdo,"INSERT INTO `%config%` (`id` , `name`, `setting`) VALUES (NULL , 'version', '1.1.11')"); +$this->basedb->doSQL($pdo,"INSERT INTO `%config%` (`id` , `name`, `setting`) VALUES (NULL , 'version', '1.1.12')"); $this->basedb->doSQL($pdo,"INSERT INTO `%config%` (`id` , `name`, `setting`) VALUES (NULL , 'paymentconfig', '0')"); $this->basedb->doSQL($pdo,"INSERT INTO `%config%` (`id` , `name`, `setting`) VALUES (NULL , 'remoteaccesscode', null)"); $this->basedb->doSQL($pdo,"INSERT INTO `%config%` (`id` , `name`, `setting`) VALUES (NULL , 'decpoint', '$decpoint')"); @@ -1221,8 +1245,8 @@ return; $supportedVersions = array("1.0.22","1.0.23","1.0.24","1.0.25","1.0.26","1.0.27","1.0.28","1.0.29", "1.0.30","1.0.31","1.0.32","1.0.33","1.0.34","1.0.35","1.0.36","1.0.37","1.0.38","1.0.39", -"1.0.40", -"1.1.0","1.1.1","1.1.2","1.1.3","1.1.4","1.1.5","1.1.6","1.1.7","1.1.8", "1.1.9","1.1.10" +"1.0.40","1.0.41","1.0.42","1.0.43", +"1.1.0","1.1.1","1.1.2","1.1.3","1.1.4","1.1.5","1.1.6","1.1.7","1.1.8", "1.1.9","1.1.10","1.1.11" ); if (!in_array($version, $supportedVersions)) { @@ -1230,7 +1254,7 @@ echo json_encode("Quellversion nicht unterstützt"); return; } -$ret = $admin->updateUserTable1110_1111($_POST['prefix'], $version); +$ret = $admin->updateUserTable1111_1112($_POST['prefix'], $version); if(session_id() == '') { session_start(); diff --git a/webapp/kitchen.html b/webapp/kitchen.html index 16aac9c..3e668f4 100644 --- a/webapp/kitchen.html +++ b/webapp/kitchen.html @@ -5,7 +5,7 @@ - + diff --git a/webapp/manager.html b/webapp/manager.html index 31c7aff..0f6e1b3 100644 --- a/webapp/manager.html +++ b/webapp/manager.html @@ -5,7 +5,7 @@ - + @@ -229,6 +229,7 @@ var MAN_ROOM_PRINTER_NO = ["Kategorieeinstellung","Category setting","Configurac var MAN_ROOM_PRINTER_1 = ["Drucker 1","Printer 1","Imprimadora 1"]; var MAN_ROOM_PRINTER_2 = ["Drucker 2","Printer 2","Imprimadora 2"]; var MAN_ROOM_PRINTER_TXT = ["Arbeitsdrucker","Work printer","Imprimadora de trabajo"]; +var MAN_ROOM_ABBR_TXT = ["Kürzel","Abbr.","Abbr."]; var MAN_USERNAME = ["Benutzer","User","Usario"]; var MAN_BILLSUMALL = ["Gesamtbrutto","Total (brutto)","Todo (brutto)"]; @@ -889,17 +890,9 @@ function binding() { } else if (theId == "createdbexportxlsx") { window.location.href = "php/contenthandler.php?module=bill&command=exportXlsx&" + dateparams; } else if (theId == "createpdfexport") { - if (numberOfClosings == 0) { - alert(MAN_NO_CLOSINGS[lang]); - } else { - window.location.href = "php/contenthandler.php?module=bill&command=exportPdfReport&" + dateparams; - } + window.location.href = "php/contenthandler.php?module=bill&command=exportPdfReport&" + dateparams; } else if (theId == "createpdfsummary") { - if (numberOfClosings == 0) { - alert(MAN_NO_CLOSINGS[lang]); - } else { - window.location.href = "php/contenthandler.php?module=bill&command=exportPdfSummary&" + dateparams; - } + window.location.href = "php/contenthandler.php?module=bill&command=exportPdfSummary&" + dateparams; } }); @@ -1682,9 +1675,10 @@ function createRoomPrinterSelection(roomid,selectedPrinter) { function createEmptyRoomField(n,m) { var i=0; var text = ""; - text += ''; + text += ''; for (i=0;i'; + text += ''; - var id_in_jsonText = $(this).attr('id'); + + for (var i=0;i 0) { diff --git a/webapp/php/admin.php b/webapp/php/admin.php index 33dc53f..a548542 100644 --- a/webapp/php/admin.php +++ b/webapp/php/admin.php @@ -123,6 +123,8 @@ class Admin { $this->getPayPrintType(); } else if ($command == 'getPayments') { $this->getPayments(); + } else if ($command == 'autobackup') { + $this->backup('auto',$_POST['remoteaccesscode']); } else if (($command == 'new') || ($command == 'shutdown') || ($command == 'backup') || ($command == 'restore') || ($command == 'drop') || ($command == 'fill') || ($command == 'fillSampleProdType') || ($command == 'fillSpeisekarte') || ($command == 'assignTaxes')) { if ($this->isCurrentUserAdmin()) { if ($command == 'fill') { @@ -134,7 +136,7 @@ class Admin { } else if ($command == 'fillSpeisekarte') { $this->fillSpeisekarte($_POST['speisekarte']); } else if ($command == 'backup') { - $this->backup($_GET['type']); + $this->backup($_GET['type'],null); return; } else if ($command == 'restore') { $this->restore(); @@ -1104,19 +1106,19 @@ class Admin { $right_rating = $_SESSION['right_rating']; if (!self::isOnlyRatingUser($rights, $right_rating, true)) { - if ($_SESSION['right_waiter']) { $mainMenu[] = array("name" => $waitertxt[$lang], "link" => "waiter.html?v=1.1.11"); }; - if ($_SESSION['right_kitchen']) { $mainMenu[] = array("name" => $kitchentxt[$lang], "link" => "kitchen.html?v=1.1.11"); }; - if ($_SESSION['right_bar']) { $mainMenu[] = array("name" => "Bar", "link" => "bar.html?v=1.1.11"); }; - if ($_SESSION['right_supply']) { $mainMenu[] = array("name" => $supplytxt[$lang], "link" => "supplydesk.html?v=1.1.11"); }; + if ($_SESSION['right_waiter']) { $mainMenu[] = array("name" => $waitertxt[$lang], "link" => "waiter.html?v=1.1.12"); }; + if ($_SESSION['right_kitchen']) { $mainMenu[] = array("name" => $kitchentxt[$lang], "link" => "kitchen.html?v=1.1.12"); }; + if ($_SESSION['right_bar']) { $mainMenu[] = array("name" => "Bar", "link" => "bar.html?v=1.1.12"); }; + if ($_SESSION['right_supply']) { $mainMenu[] = array("name" => $supplytxt[$lang], "link" => "supplydesk.html?v=1.1.12"); }; if ($_SESSION['right_paydesk']) { $mainMenu[] = array("name" => $paydesktxt[$lang], "link" => "paydesk.html"); }; - if ($_SESSION['right_statistics']) { $mainMenu[] = array("name" => $stattxt[$lang], "link" => "reports.html?v=1.1.11"); }; - if ($_SESSION['right_bill']) { $mainMenu[] = array("name" => $bontxt[$lang], "link" => "bill.html?v=1.1.11"); }; - if ($_SESSION['right_products']) { $mainMenu[] = array("name" => $prodtxt[$lang], "link" => "products.html?v=1.1.11"); }; - if ($_SESSION['right_reservation']) { $mainMenu[] = array("name" => $restxt[$lang], "link" => "reservation.html?v=1.1.11"); }; - if ($_SESSION['right_rating']) { $mainMenu[] = array("name" => $ratingtxt[$lang], "link" => "rating.html?v=1.1.11"); }; - if ($_SESSION['right_manager'] || $_SESSION['is_admin']) { $mainMenu[] = array("name" => $admintxt[$lang], "link" => "manager.html?v=1.1.11"); }; - $mainMenu[] = array("name" => $settingtxt[$lang], "link" => "preferences.html?v=1.1.11"); - $mainMenu[] = array("name" => "Feedback", "link" => "feedback.html?v=1.1.11"); + if ($_SESSION['right_statistics']) { $mainMenu[] = array("name" => $stattxt[$lang], "link" => "reports.html?v=1.1.12"); }; + if ($_SESSION['right_bill']) { $mainMenu[] = array("name" => $bontxt[$lang], "link" => "bill.html?v=1.1.12"); }; + if ($_SESSION['right_products']) { $mainMenu[] = array("name" => $prodtxt[$lang], "link" => "products.html?v=1.1.12"); }; + if ($_SESSION['right_reservation']) { $mainMenu[] = array("name" => $restxt[$lang], "link" => "reservation.html?v=1.1.12"); }; + if ($_SESSION['right_rating']) { $mainMenu[] = array("name" => $ratingtxt[$lang], "link" => "rating.html?v=1.1.12"); }; + if ($_SESSION['right_manager'] || $_SESSION['is_admin']) { $mainMenu[] = array("name" => $admintxt[$lang], "link" => "manager.html?v=1.1.12"); }; + $mainMenu[] = array("name" => $settingtxt[$lang], "link" => "preferences.html?v=1.1.12"); + $mainMenu[] = array("name" => "Feedback", "link" => "feedback.html?v=1.1.12"); } $mainMenu[] = array("name" => $logout[$lang], "link" => "logout.php"); @@ -1125,7 +1127,7 @@ class Admin { $waiterMessage = $this->getMessage(null, "waitermessage"); } // CAUTION: change version also in config.txt!!! - $mainMenuAndVersion = array ("version" => "OrderSprinter 1.1.11", + $mainMenuAndVersion = array ("version" => "OrderSprinter 1.1.12", "user" => $currentUser, "menu" => $mainMenu, "waitermessage" => $waiterMessage, @@ -1724,13 +1726,33 @@ class Admin { "user","reservations","bill","queue","billproducts","comments","histprod","histconfig","histuser","histactions","hist","extras","extrasprods","queueextras"); } - public function backup($theType) { + public function backup($theType,$remoteaccesscode) { date_default_timezone_set(DbUtils::getTimeZone()); $nowtime = date('Y-m-d'); ini_set('memory_limit', '1000M'); - $pdo = DButils::openDbAndReturnPdoStatic(); + + if ($theType == "auto") { + $sql = "SELECT count(id) as number,setting FROM %config% WHERE name=?"; + $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); + $stmt->execute(array("remoteaccesscode")); + $row = $stmt->fetchObject(); + if ($row->number == 0) { + echo "No remote access code available - backup not allowed"; + return; + } + $code = $row->setting; + if (is_null($code) || (trim($code) == "")) { + echo "No remote access code set - backup not allowed"; + return; + } + if ($code != md5($remoteaccesscode)) { + echo "Wrong remote access code used - backup not allowed"; + return; + } + } + $pdo->beginTransaction(); $genInfo = $this->getGeneralConfigItems(false, $pdo); @@ -1801,18 +1823,24 @@ class Admin { } private function restore() { + ini_set('memory_limit', '1000M'); + set_time_limit(60*5); + if ($_FILES['userfile']['error'] != UPLOAD_ERR_OK //checks for errors && is_uploaded_file($_FILES['userfile']['tmp_name'])) { //checks that file is uploaded header("Location: ../infopage.html?e=manager.html=Kann_Datei_nicht_laden."); exit(); } - if(!file_exists($_FILES['userfile']['tmp_name']) || !is_uploaded_file($_FILES['userfile']['tmp_name'])) { - header("Location: ../infopage.html?e=manager.html=Datei_nicht_angegeben."); + if(!file_exists($_FILES['userfile']['tmp_name'])) { + header("Location: ../infopage.html?e=manager.html=Datei_existiert_nicht._Bitte_PHP-Variable_upload_max_filesize_checken."); exit(); } - ini_set('memory_limit', '1000M'); + if(!is_uploaded_file($_FILES['userfile']['tmp_name'])) { + header("Location: ../infopage.html?e=manager.html=Datei_konnte_nicht_hochgeladen_werden."); + exit(); + } $binaryFields = array("signature","img","setting","content"); @@ -1822,8 +1850,6 @@ class Admin { $basedb->setPrefix(TAB_PREFIX); $basedb->setTimeZone(DbUtils::getTimeZone()); - set_time_limit(60*5); - $pdo = DbUtils::openDbAndReturnPdoStatic(); $pdo->beginTransaction(); diff --git a/webapp/php/bill.php b/webapp/php/bill.php index 6a0f839..981ab79 100644 --- a/webapp/php/bill.php +++ b/webapp/php/bill.php @@ -54,7 +54,7 @@ class Bill { } if ($command == 'exportPdfReport') { if ($this->hasCurrentUserAdminOrManagerRights()) { - $this->exportPdfReport($_GET['lang'],$_GET['startMonth'],$_GET['startYear'],$_GET['endMonth'],$_GET['endYear']); + $this->exportPdfReport($_GET['startMonth'],$_GET['startYear'],$_GET['endMonth'],$_GET['endYear']); } else { echo "Benutzer nicht berechtigt"; } @@ -62,12 +62,16 @@ class Bill { } if ($command == 'exportPdfSummary') { if ($this->hasCurrentUserAdminOrManagerRights()) { - $this->exportPdfSummary($_GET['lang'],$_GET['startMonth'],$_GET['startYear'],$_GET['endMonth'],$_GET['endYear']); + $this->exportPdfSummary($_GET['startMonth'],$_GET['startYear'],$_GET['endMonth'],$_GET['endYear']); } else { echo "Benutzer nicht berechtigt"; } return; } + if ($command == 'autoBackupPdfSummary') { + $this->autoBackupPdfSummary($_POST['remoteaccesscode']); + return; + } if ($command == 'exportCsvOfClosing') { if ($this->hasCurrentUserAdminOrManagerRights()) { @@ -146,14 +150,26 @@ class Bill { } } + function billIsCancelled($pdo,$billid) { + $sql = "SELECT status FROM %bill% WHERE id=?"; + $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); + $stmt->execute(array($billid)); + $row = $stmt->fetchObject(); + $status = $row->status; + $ret = false; + if (($status == "x") || ($status == "s")) { + $ret = true; + } + return $ret; + } + /** * get the content of a bill (to be used for printserver etc.) * * @param unknown $billid */ - function getBillWithId($billid,$language,$printer) { + function getBillWithId($pdo,$billid,$language,$printer) { set_time_limit(120); - $pdo = $this->dbutils->openDbAndReturnPdo(); // is bill correct with signature? $commonUtils = new CommonUtils(); @@ -176,25 +192,43 @@ class Bill { $stmt->execute(array($billid)); $qrow = $stmt->fetchObject(); + $tableid = $row->tableid; if ($qrow->countid == 0) { - if ($row->tableid == 0) { + if ($tableid == 0) { // togo - $sql = "SELECT DISTINCT billdate,brutto,netto,'-' as tablename,username,host FROM %bill%,%user% WHERE %bill%.id=? AND userid=%user%.id AND tableid='0' "; + $sql = "SELECT DISTINCT billdate,brutto,netto,'-' as tablename,username,host,IFNULL(%bill%.status,'') as status FROM %bill%,%user% WHERE %bill%.id=? AND userid=%user%.id AND tableid='0' "; } else { - $sql = "SELECT DISTINCT billdate,brutto,netto,tableno as tablename,username,host FROM %bill%,%user%,%resttables% WHERE %bill%.id=? AND userid=%user%.id AND tableid=%resttables%.id "; + $sql = "SELECT DISTINCT billdate,brutto,netto,tableno as tablename,username,host,IFNULL(%bill%.status,'') as status FROM %bill%,%user%,%resttables% WHERE %bill%.id=? AND userid=%user%.id AND tableid=%resttables%.id "; } } else { - if ($row->tableid == 0) { + if ($tableid == 0) { // togo - $sql = "SELECT DISTINCT billdate,brutto,netto,'-' as tablename,username,host FROM %bill%,%user%,%queue% WHERE %bill%.id=? AND %bill%.id=%queue%.billid AND userid=%user%.id AND tableid='0' AND paidtime is not null "; + $sql = "SELECT DISTINCT billdate,brutto,netto,'-' as tablename,username,host,IFNULL(%bill%.status,'') as status FROM %bill%,%user%,%queue% WHERE %bill%.id=? AND %bill%.id=%queue%.billid AND userid=%user%.id AND tableid='0' AND paidtime is not null "; } else { - $sql = "SELECT DISTINCT billdate,brutto,netto,tableno as tablename,username,host FROM %bill%,%user%,%resttables%,%queue% WHERE %bill%.id=? AND %bill%.id=%queue%.billid AND userid=%user%.id AND tableid=%resttables%.id AND paidtime is not null "; + $sql = "SELECT DISTINCT billdate,brutto,netto,tableno as tablename,username,host,IFNULL(%bill%.status,'') as status FROM %bill%,%user%,%resttables%,%queue% WHERE %bill%.id=? AND %bill%.id=%queue%.billid AND userid=%user%.id AND tableid=%resttables%.id AND paidtime is not null "; } } $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($billid)); $row = $stmt->fetchObject(); + $status = $row->status; + $sign = ($status == "s" ? "-" : ""); + + if ($tableid != 0) { + $sql = "SELECT abbreviation FROM %room%,%resttables% WHERE %resttables%.id=? AND %resttables%.roomid=%room%.id"; + $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); + $stmt->execute(array($tableid)); + $trow = $stmt->fetchObject(); + if (is_null($trow->abbreviation)) { + $tablename = $row->tablename; + } else { + $tablename = $trow->abbreviation . "-" . $row->tablename; + } + } else { + $tablename = "-"; + } + if ($row == null) { // no rows found -> deliver no content echo json_encode(array("billoverallinfo" => array())); @@ -228,7 +262,7 @@ class Bill { "billmin" => $min, "brutto" => $row->brutto, "netto" => $row->netto, - "table" => $row->tablename, + "table" => $tablename, "username" => $row->username, "printer" => $printer, "host" => $host @@ -250,7 +284,7 @@ class Bill { } // now get all products of this bill - $sql = "select productname,price,%pricelevel%.name as pricelevelname,count(%queue%.productname) as count from %bill%,%queue%,%pricelevel% where %bill%.id=? and %queue%.billid=%bill%.id AND paidtime is not null AND %queue%.pricelevel = %pricelevel%.id group by productname,price,pricelevelname"; + $sql = "select productname,price,%pricelevel%.name as pricelevelname,count(%queue%.productname) as count from %queue%,%pricelevel%,%billproducts% where %billproducts%.billid=? AND %billproducts%.queueid=%queue%.id AND %queue%.pricelevel = %pricelevel%.id group by productname,price,pricelevelname"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($billid)); $result = $stmt->fetchAll(); @@ -260,16 +294,16 @@ class Bill { $prodarray[] = array("count" => $zeile['count'], "productname" => $zeile['productname'], "pricelevel" => $zeile['pricelevelname'], - "price" => $zeile['price'] + "price" => $sign . $zeile['price'] ); } - $sql = "select tax,round(sum(price) - sum(price / (1.0 + tax/100.0)),2) as mwst, round(sum(price / (1.0 + tax/100.0)),2) as netto, sum(price) as brutto FROM %queue% WHERE billid=? group by tax ORDER BY tax"; - $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); + $sql = "select tax,concat('$sign',round(sum(price) - sum(price / (1.0 + tax/100.0)),2)) as mwst, concat('$sign',round(sum(price / (1.0 + tax/100.0)),2)) as netto, concat('$sign',sum(price)) as brutto FROM %queue%,%billproducts% WHERE %billproducts%.billid=? AND %billproducts%.queueid=%queue%.id group by tax ORDER BY tax"; + $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($billid)); $result = $stmt->fetchAll(PDO::FETCH_OBJ); - + $out = array("billoverallinfo" => $billoverallinfo,"translations" => $billtranslations,"products" => $prodarray, "taxes" => $result); return $out; } @@ -376,7 +410,7 @@ class Bill { $commonUtils = new CommonUtils(); - $sql = "SELECT id,billdate,brutto,tableid,closingid,status FROM %bill% WHERE tableid >= '0' AND status is null AND $whenClause ORDER BY billdate DESC "; + $sql = "SELECT id,billdate,brutto,tableid,closingid,status FROM %bill% WHERE tableid >= '0' AND $whenClause ORDER BY billdate DESC "; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($startDate,$endDate)); $result = $stmt->fetchAll(); @@ -393,13 +427,16 @@ class Bill { $shortdate = $date->format('H:i'); $closingID = $zeile['closingid']; $isClosed = (is_null($closingID) ? 0 : 1); + if ($this->billIsCancelled($pdo,$theId)) { + $isClosed = 1; + } $arr = array("id" => $theId, "longdate" => $zeile['billdate'], "shortdate" => $shortdate, "brutto" => $zeile['brutto'], "tablename" => $commonUtils->getTableNameFromId($pdo,$zeile['tableid']), - "billcontent" => $this->getBillWithId($theId,$l,0), + "billcontent" => $this->getBillWithId($pdo,$theId,$l,0), "isClosed" => $isClosed ); @@ -580,13 +617,50 @@ class Bill { return; } + private function autoBackupPdfSummary($remoteaccesscode) { + $pdo = DbUtils::openDbAndReturnPdoStatic(); + $sql = "SELECT count(id) as number,setting FROM %config% WHERE name=?"; + $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); + $stmt->execute(array("remoteaccesscode")); + $row = $stmt->fetchObject(); + if ($row->number == 0) { + echo "No remote access code available - backup not allowed"; + return; + } + $code = $row->setting; + if (is_null($code) || (trim($code) == "")) { + echo "No remote access code set - backup not allowed"; + return; + } + + if ($code != md5($remoteaccesscode)) { + echo "Wrong remote access code used - backup not allowed"; + return; + } + $pdo = null; + + date_default_timezone_set(DbUtils::getTimeZone()); + $currentYear = date('Y'); + $currentMonth = date('n'); + + $this->exportPdfSummary(1, $currentYear, $currentMonth, $currentYear); + } + private function exportPdfReport($startMonth,$startYear,$endMonth,$endYear) { $pdfExport = new PdfExport(); - $pdfExport->exportPdfReport($_GET['lang'],$_GET['startMonth'],$_GET['startYear'],$_GET['endMonth'],$_GET['endYear']); + $lang = 0; + if(isset($_GET["lang"])) { + $lang = $_GET['lang']; + } + $pdfExport->exportPdfReport($lang,$startMonth,$startYear,$endMonth,$endYear); } private function exportPdfSummary($startMonth,$startYear,$endMonth,$endYear) { $pdfExport = new PdfExport(); - $pdfExport->exportPdfSummary($_GET['lang'],$_GET['startMonth'],$_GET['startYear'],$_GET['endMonth'],$_GET['endYear']); + $lang = 0; + if(isset($_GET["lang"])) { + $lang = $_GET['lang']; + } + $pdfExport->exportPdfSummary($lang,$startMonth,$startYear,$endMonth,$endYear); } private function exportCsv($startMonth,$startYear,$endMonth,$endYear,$exportType) { diff --git a/webapp/php/closing.php b/webapp/php/closing.php index d57ebfc..771e4ac 100644 --- a/webapp/php/closing.php +++ b/webapp/php/closing.php @@ -501,7 +501,7 @@ $csv .= "$aBillId; \"$billdate\" ; \"" . $this->t['cashaction'][$l] . "\" ; \"$b } } else { -$sql = "SELECT DISTINCT productname,price,%queue%.tax as tax FROM %queue%,%billproducts% WHERE %billproducts%.billid=?' AND %billproducts%.queueid=%queue%.id"; +$sql = "SELECT DISTINCT productname,price,%queue%.tax as tax FROM %queue%,%billproducts% WHERE %billproducts%.billid=? AND %billproducts%.queueid=%queue%.id"; if ($status == 'x') { $statusTxt = $this->t["laterCancelled"][$l]; } else if ($status == 's') { diff --git a/webapp/php/printqueue.php b/webapp/php/printqueue.php index 1c25fc2..846aa2c 100644 --- a/webapp/php/printqueue.php +++ b/webapp/php/printqueue.php @@ -331,7 +331,7 @@ class PrintQueue { $printer = $aBill["printer"]; if (in_array($printer, $printersArr)) { - $receiptJob = array("id" => $printJobId,"bill" => $bill->getBillWithId($aBillId,$language,$printer)); + $receiptJob = array("id" => $printJobId,"bill" => $bill->getBillWithId($pdo,$aBillId,$language,$printer)); $billarray[] = $receiptJob; } } diff --git a/webapp/php/queuecontent.php b/webapp/php/queuecontent.php index 4416ccb..6be8848 100644 --- a/webapp/php/queuecontent.php +++ b/webapp/php/queuecontent.php @@ -474,12 +474,16 @@ class QueueContent { $takeAwayStr = array("Zum Mitnehmen","Take away","Para llevar"); $tablename = $takeAwayStr[$lang]; } else { - $sql = "SELECT tableno FROM %resttables% WHERE id=?"; + $sql = "SELECT tableno,%room%.abbreviation FROM %resttables%,%room% WHERE %resttables%.id=? AND %resttables%.roomid=%room%.id"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($theTableid)); $row = $stmt->fetchObject(); - $tablename = $row->tableno; + if (is_null($row->abbreviation)) { + $tablename = $row->tableno; + } else { + $tablename = $row->abbreviation . "-" . $row->tableno; + } } PrintQueue::queueWorkPrintJob($pdo, $tablename, $germanTime, $resultarray, $kind, $printer, $user); @@ -1025,7 +1029,7 @@ class QueueContent { $extras = $this->getExtrasOfQueueItem($pdo,$anId); $prodEntry = array( - "queueid" =>$anId, + "id" =>$anId, "longname" => $row->productname, "option" => $row->anoption, "extras" => $extras, @@ -1108,6 +1112,7 @@ class QueueContent { $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(); $result = $stmt->fetchAll(); + $prodsToPay = array(); foreach ($result as $zeile) { $thePrice = $zeile['price']; $theTax = $zeile['tax']; diff --git a/webapp/php/roomtables.php b/webapp/php/roomtables.php index 6fd468a..4f81ed7 100644 --- a/webapp/php/roomtables.php +++ b/webapp/php/roomtables.php @@ -275,17 +275,21 @@ class Roomtables { for ($roomindex = 0;$roomindex < $noOfRooms; $roomindex++) { $aRoom = $rooms[$roomindex]; $aRoomName = $aRoom[0]; - $roomPrinter = $aRoom[1]; + $aRoomAbbr = $aRoom[1]; + if ($aRoomAbbr == "") { + $aRoomAbbr = null; + } + $roomPrinter = $aRoom[2]; if ($roomPrinter == 0) { $roomPrinter = null; } - $sql = "INSERT INTO `%room%` (`id`, `roomname`, `printer`) VALUES (NULL,?,?)"; + $sql = "INSERT INTO `%room%` (`id`, `roomname`, `abbreviation`, `printer`) VALUES (NULL,?,?,?)"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); - $stmt->execute(array($aRoomName,$roomPrinter)); + $stmt->execute(array($aRoomName,$aRoomAbbr,$roomPrinter)); $roomId = $pdo->lastInsertId(); - $tablesArr = $aRoom[2]; + $tablesArr = $aRoom[3]; $noOfTables = count($tablesArr); for ($tableindex = 0; $tableindex < $noOfTables; $tableindex++) { @@ -302,7 +306,7 @@ class Roomtables { function getRoomfield() { $pdo = $this->dbutils->openDbAndReturnPdo(); - $sql = "SELECT id,roomname,IFNULL(printer,0) as printer FROM %room% WHERE removed is null ORDER BY 'sorting'"; + $sql = "SELECT id,roomname,IFNULL(abbreviation,'') as abbreviation,IFNULL(printer,0) as printer FROM %room% WHERE removed is null ORDER BY 'sorting'"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(); $result = $stmt->fetchAll(); @@ -315,6 +319,7 @@ class Roomtables { foreach($result as $row) { $roomid = $row['id']; $roomname = $row['roomname']; + $abbreviation = $row['abbreviation']; $printer = $row['printer']; // now get the tables of this room @@ -329,7 +334,7 @@ class Roomtables { foreach($tableresult as $aTable) { $tableArr[] = array("id" => $aTable['id'], "tablename" => $aTable['tableno']); } - $roomArr[] = array("roomid" => $roomid, "roomname" => $roomname, "printer" => $printer, "tables" => $tableArr, "noOfTables" => $numberOfTables); + $roomArr[] = array("roomid" => $roomid, "roomname" => $roomname, "abbreviation" => $abbreviation, "printer" => $printer, "tables" => $tableArr, "noOfTables" => $numberOfTables); } echo json_encode(array("status" => "OK", "noOfRooms" => $numberOfRooms, "maxTables" => $maxTables, "roomfield" => $roomArr)); diff --git a/webapp/php/utilities/basedb.php b/webapp/php/utilities/basedb.php index 2634e7b..4303722 100644 --- a/webapp/php/utilities/basedb.php +++ b/webapp/php/utilities/basedb.php @@ -243,6 +243,7 @@ class Basedb { CREATE TABLE `%room%` ( `id` INT (10) NOT NULL AUTO_INCREMENT PRIMARY KEY , `roomname` VARCHAR ( 150 ) NOT NULL, + `abbreviation` VARCHAR (10) NULL, `printer` INT(2) NULL, `removed` INT(2) NULL, `sorting` INT(2) NULL diff --git a/webapp/preferences.html b/webapp/preferences.html index 9e0b01a..ddd8315 100644 --- a/webapp/preferences.html +++ b/webapp/preferences.html @@ -5,7 +5,7 @@ - + diff --git a/webapp/products.html b/webapp/products.html index 4cb19a4..57721a9 100644 --- a/webapp/products.html +++ b/webapp/products.html @@ -7,7 +7,7 @@ - + diff --git a/webapp/rating.html b/webapp/rating.html index 637a46b..55b9ade 100644 --- a/webapp/rating.html +++ b/webapp/rating.html @@ -7,7 +7,7 @@ - + diff --git a/webapp/reports.html b/webapp/reports.html index 5445eb4..804d257 100644 --- a/webapp/reports.html +++ b/webapp/reports.html @@ -7,7 +7,7 @@ - + diff --git a/webapp/reservation.html b/webapp/reservation.html index a5d8b5a..c68ea89 100644 --- a/webapp/reservation.html +++ b/webapp/reservation.html @@ -5,7 +5,7 @@ - + diff --git a/webapp/supplydesk.html b/webapp/supplydesk.html index 2bb3f1d..f2ac6ce 100644 --- a/webapp/supplydesk.html +++ b/webapp/supplydesk.html @@ -5,7 +5,7 @@ - + diff --git a/webapp/waiter.html b/webapp/waiter.html index cc7b874..047eaff 100644 --- a/webapp/waiter.html +++ b/webapp/waiter.html @@ -4,7 +4,7 @@ - + @@ -81,6 +81,103 @@ var W_UNDELIVERED = ["nicht serviert (+ unbezahlt)","not served (and unpaid)","n var W_MOVE_PRODS = ["Produkte verschieben","Move products","Productos a otra mesa"]; var W_NO_PRODS_SELECTED = ["Es wurden keine Produkte ausgewählt!","You have not chosen any products!","No ha seleccionado ningún producto!"]; +function Grouping(set,hashFct) { + // initialization during construction of class + this.set = set; + + // setting by group() + this.sortedset = []; + + this.group = function() { + this.sortedset = []; + for (var i=0;i" + createExtraParagraph(p.extras); +} -function fillNotDeliveredProductsOfATable(urlProdOfTableNotDelivered,prodListToFill) { - $.getJSON(urlProdOfTableNotDelivered,function(prodOfTable) { - - if (prodOfTable.length > 0) { - notDeliveredProdsAvailable = true; - } else { - notDeliveredProdsAvailable = false; - } - var li = "
  • " + W_KIT_BAR[lang] + "
  • "; - $.each(prodOfTable, function (i, name) { - var optiontext = ""; - if (name.option != '') { - optiontext = " (" + toHtml(name.option) + ")"; - } - if (name.isready == '0') { - li += '
  • ' + toHtml(name.longname) + optiontext + '
  • '; - } else { - li += '
  • ' + toHtml(name.longname) + optiontext + '
  • '; - } - }); - - $("#cancelcodefield").val(""); - if (cancelunpaidcode != "") { - if (prodOfTable.length > 0) { - $("#cancelcodearea").show(); - } else { - $("#cancelcodearea").hide(); - } - } else { - $("#cancelcodearea").hide(); - } - - $(prodListToFill).empty().append(li).promise().done(function () { - - $("#undeliveredheader").off("click").on("click", function (e) { - e.stopImmediatePropagation(); - e.preventDefault(); - alert(W_UNDELIV_INFO[lang]); - }); - - // now set as data the queueid - var index=0; - $(".notdelprod").each(function() { - $(this).data("queueid",prodOfTable[index].queueid); - index++; - }); - - $(this).off("click").on("click", "a", function (e) { - e.stopImmediatePropagation(); - e.preventDefault(); - - if (cancelunpaidcode != "") { - if ($("#cancelcodefield").val() != cancelunpaidcode) { - alert(W_WRONG_PIN[lang]); - return; - } - } - - var isReady = prodOfTable[this.id]["isready"]; - var isPaid = prodOfTable[this.id]["isPaid"]; - var isCooking = prodOfTable[this.id]["isCooking"]; - - if ((isPaid == "1") && (isReady=="1")) { - var dialogText = "Entfernen?"; - var this_elem = this; - areYouSure("Produkt wurde schon zubereitet und bezahlt", dialogText, "Ja", function() { - removeProductFromQueue(prodOfTable[this_elem.id]["queueid"],isPaid,isCooking,isReady); - fillNotDeliveredProductsOfATable(urlProdOfTableNotDelivered,prodListToFill); - }); - } else if (isReady=="1") { - var dialogText = "Entfernen?"; - var this_elem = this; - areYouSure("Produkt wurde schon zubereitet.", dialogText, "Ja", function() { - removeProductFromQueue(prodOfTable[this_elem.id]["queueid"],isPaid,isCooking,isReady); - fillNotDeliveredProductsOfATable(urlProdOfTableNotDelivered,prodListToFill); - }); - } else if (isPaid == "1") { - var dialogText = "Entfernen?"; - var this_elem = this; - areYouSure("Produkt wurde schon bezahlt.", dialogText, "Ja", function() { - removeProductFromQueue(prodOfTable[this_elem.id]["queueid"],isPaid,isCooking,isReady); - fillNotDeliveredProductsOfATable(urlProdOfTableNotDelivered,prodListToFill); - }); - } else if (isCooking == "1") { - var dialogText = "Entfernen?"; - var this_elem = this; - areYouSure("Produkt wird soeben zubereitet.", dialogText, "Ja", function() { - removeProductFromQueue(prodOfTable[this_elem.id]["queueid"],isPaid,isCooking,isReady); - fillNotDeliveredProductsOfATable(urlProdOfTableNotDelivered,prodListToFill); - }); - - } else { - removeProductFromQueue(prodOfTable[this.id]["queueid"],isPaid,isCooking,isReady); - fillNotDeliveredProductsOfATable(urlProdOfTableNotDelivered,prodListToFill); - } + +function createListElOfAssignedProd(aProd) { + var count = ""; + if("count" in aProd) { + if (aProd["count"] > 1) { + count = aProd["count"] + "x "; + } + } + if (aProd.isready == '0') { + return '
  • ' + count + createTxtAssignedProd(aProd) + '
  • '; + } else { + return '
  • ' + count + createTxtAssignedProd(aProd) + '
  • '; + } +} + +function fillAssignedProdList(assignedProds) { + if (assignedProds.length > 0) { + notDeliveredProdsAvailable = true; + } else { + notDeliveredProdsAvailable = false; + } + + $("#cancelcodefield").val(""); + if (cancelunpaidcode != "") { + if (assignedProds.length > 0) { + $("#cancelcodearea").show(); + } else { + $("#cancelcodearea").hide(); + } + } else { + $("#cancelcodearea").hide(); + } + + var assignedProdsGrouping = new Grouping(assignedProds,createTxtAssignedProd); + assignedProdsGrouping.group(); + + var listContent = "
  • " + W_KIT_BAR[lang] + "
  • "; + listContent += assignedProdsGrouping.outputList(createListElOfAssignedProd); + $("#orderedprod-list-0").html(listContent); + refreshList("#orderedprod-list-0"); + + $("#undeliveredheader").off("click").on("click", function (e) { + e.stopImmediatePropagation(); + e.preventDefault(); + alert(W_UNDELIV_INFO[lang]); + }); + + bindingOfAssignedProds(assignedProdsGrouping); +} + +function bindingOfAssignedProds(assignedProdsGrouping) { + $(".notdelprod").off("click").on("click", "a", function (e) { + e.stopImmediatePropagation(); + e.preventDefault(); + + if (cancelunpaidcode != "") { + if ($("#cancelcodefield").val() != cancelunpaidcode) { + alert(W_WRONG_PIN[lang]); + return; + } + } + + var listItem = $(this).closest("li"); + var rowIndex = $( "#orderedprod-list-0 li" ).index(listItem) - 1; + var rowEntries = assignedProdsGrouping.getItemsOfRow(rowIndex); + var anEntry = rowEntries[0]; + var queueid = anEntry.id; + + var isReady = anEntry.isready; + var isPaid = anEntry.isPaid; + var isCooking = anEntry.isCooking; + + if ((isPaid == "1") && (isReady=="1")) { + var dialogText = "Entfernen?"; + var this_elem = this; + areYouSure("Produkt wurde schon zubereitet und bezahlt", dialogText, "Ja", function() { + removeProductFromQueue(queueid,isPaid,isCooking,isReady); + }); + } else if (isReady=="1") { + var dialogText = "Entfernen?"; + var this_elem = this; + areYouSure("Produkt wurde schon zubereitet.", dialogText, "Ja", function() { + removeProductFromQueue(queueid,isPaid,isCooking,isReady); }); - refreshList(this); - }); - }); // ende json call + } else if (isPaid == "1") { + var dialogText = "Entfernen?"; + var this_elem = this; + areYouSure("Produkt wurde schon bezahlt.", dialogText, "Ja", function() { + removeProductFromQueue(queueid,isPaid,isCooking,isReady); + }); + } else if (isCooking == "1") { + var dialogText = "Entfernen?"; + var this_elem = this; + areYouSure("Produkt wird soeben zubereitet.", dialogText, "Ja", function() { + removeProductFromQueue(queueid,isPaid,isCooking,isReady); + }); + } else { + removeProductFromQueue(queueid,isPaid,isCooking,isReady); + } + }); + +} + +function fillNotDeliveredProductsOfATable(urlProdOfTableNotDelivered) { + doJsonAjaxAsync("GET", urlProdOfTableNotDelivered, null, fillAssignedProdList); } function fillOrderVolume(volume) { @@ -1669,11 +1788,9 @@ $(document).on("pagebeforeshow", "#typprodpage", function () { fillTypeProdList(0); // now the products that are assigned to table but yet not delivered - var urlProdOfTableNotDelivered = "php/contenthandler.php?module=queue&command=getJsonLongNamesOfProdsForTableNotDelivered&" - + "tableid=" + tableid; + var urlProdOfTableNotDelivered = "php/contenthandler.php?module=queue&command=getJsonLongNamesOfProdsForTableNotDelivered&tableid=" + tableid; - var prodListToFill = "#orderedprod-list-0"; - fillNotDeliveredProductsOfATable(urlProdOfTableNotDelivered,prodListToFill); + fillNotDeliveredProductsOfATable(urlProdOfTableNotDelivered); $("#workprint_btn").data("tableid",tableid); $("#gopaydesk_btn").data("tableid",tableid); @@ -1998,8 +2115,7 @@ function bindSendNewOrdersButton() { var urlProdOfTableNotDelivered = "php/contenthandler.php?module=queue&command=getJsonLongNamesOfProdsForTableNotDelivered&" + "tableid=" + tableid; var prodListToFill = "#orderedprod-list-0"; - fillNotDeliveredProductsOfATable(urlProdOfTableNotDelivered, - prodListToFill); + fillNotDeliveredProductsOfATable(urlProdOfTableNotDelivered); } function doJsonAjax(getOrPost, url, data, functionToCallIfSuccess, errorMsg) { $.ajax({
    ' + MAN_ROOM_LABEL[lang] + '' + MAN_ROOM_PRINTER_TXT[lang] + '' + MAN_TABLE_LABEL[lang] + '
    ' + MAN_ROOM_LABEL[lang] + '' + MAN_ROOM_ABBR_TXT[lang] + '' + MAN_ROOM_PRINTER_TXT[lang] + '' + MAN_TABLE_LABEL[lang] + '
    '; text += '' + createRoomPrinterSelection(i,0); text += tablelist(m,i); } @@ -1710,6 +1704,8 @@ function initroomfield(roomfield_json) { r_id = "#r_" + room_index.toString(); $(r_id).val(aRoom.roomname); + $("#rabbr_" + room_index).val(aRoom.abbreviation); + var noOfTables = aRoom.noOfTables; var roomPrinter = aRoom.printer; @@ -1744,6 +1740,7 @@ function roomfield_prefill() { var endNumber = startNumber + parseInt(m) - 1; $(id).val(MAN_TABLE_LABEL[lang] + " " + startNumber + "-" + endNumber); + $("#rabbr_" + i).val(''); for (j=0;j 0) { - roominfo[2] = tablesOfRoom; + roominfo[3] = tablesOfRoom; } else { continue; } diff --git a/webapp/paydesk.html b/webapp/paydesk.html index 9b5483f..394ce8f 100644 --- a/webapp/paydesk.html +++ b/webapp/paydesk.html @@ -5,7 +5,7 @@ - + @@ -16,6 +16,7 @@ + @@ -116,6 +117,18 @@ var cameFromOrdering = 0; var billbrutto = 0.0; var billnetto = 0.0; +// 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 tablename that shall appear on the receipt and on the lists +var payTable = ""; +//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 = []; + function getGeneralConfigItems() { doAjax("GET", "php/contenthandler.php?module=admin&command=getGeneralConfigItems", null, insertGeneralConfigItems, "Fehler Konfigurationsdaten"); } @@ -516,7 +529,7 @@ function getProdsToPayForTable(tableid,tablename) { $("#info-page").data("tableprods",msg); bindPayButton(msg,tableid,tablename); - displayProdsToPayForTable(msg,tablename); + initiatePayableView(msg,tablename); } else { alert("Fehler: " + msg); } @@ -527,32 +540,94 @@ function getProdsToPayForTable(tableid,tablename) { }); } -function displayProdsToPayForTable(jsonContent,tablename) { + +function initiatePayableView(jsonContent,tablename) { $('#tableinreceipt').html(tablename + '
     '); clearUntenAndReceipt(); createAllEntriesInReceipt(); calcSum(); + prodsToPayList = jsonContent; + payTable = tablename; + displayProdsToPayForTable(); +} + +function displayProdsToPayForTable() { + // REM* first group the items + prodsToPayListGrouping = new Grouping(prodsToPayList,createHashOfPayableItem); + prodsToPayListGrouping.group(); + var size = getProdSizeClass(); - $("#oben").empty().promise().done(function () { - var li = '
  • ' + P_NOT_PAID[lang] + tablename + '
  • '; // init a list - $("#oben").empty().append(li); - $("#oben").append('
  • ' + P_ALL[lang] + '
  • '); - $.each(jsonContent, function (index,aProd) { - // var queueid = jsonContent[this.id]["id"]; - addToOben(aProd["prodid"],toHtml(aProd["longname"]),aProd["price"],aProd["tax"],aProd["pricelevelname"],aProd["extras"],index); - }); - }); + + var txt = '
  • ' + P_NOT_PAID[lang] + payTable + '
  • '; // init a list + txt += '
  • ' + P_ALL[lang] + '
  • '; + + var listContent = txt + prodsToPayListGrouping.outputList(createPayableItemListElement); + $("#oben").html(listContent); refreshList("#oben"); - addAllToUnten(jsonContent,tablename); + $(".payable").off("click").on("click", function (e) { + e.stopImmediatePropagation(); + e.preventDefault(); + // REM* get rowIndex of item + var listItem = $(this).closest("li"); + var rowIndex = $( "#oben li" ).index(listItem) - 2; + // REM* get an item from the payableList + var removedEntry = prodsToPayListGrouping.popSortedEntry(rowIndex); + prodsOnReceiptList[prodsOnReceiptList.length] = removedEntry; + displayProdsToPayForTable(); + displayProdsOnReceipt(); + }); + + $("#payall").off("click").on("click", function (e) { + e.stopImmediatePropagation(); + e.preventDefault(); + for (var i=0;i0,00 ' + currency + '

    '; + + var listContent = txt + prodsOnReceiptListGrouping.outputList(createOnReceiptItemListElement); + $("#unten").html(listContent); + refreshList("#unten"); + + createAllEntriesInReceipt(); + + $(".onreceipt").off("click").on("click", function (e) { + e.stopImmediatePropagation(); + e.preventDefault(); + // REM* get rowIndex of item + var listItem = $(this).closest("li"); + var rowIndex = $( "#unten li" ).index(listItem) - 1; + // REM* get an item from the payableList + var removedEntry = prodsOnReceiptListGrouping.popSortedEntry(rowIndex); + prodsToPayList[prodsToPayList.length] = removedEntry; + displayProdsToPayForTable(); + displayProdsOnReceipt(); + }); +}; + + +function generateListItem(theme,icon,id,content,classname) { var size = getProdSizeClass(); var li = '
  • '; - li += '' + content + '
  • '; + li += '' + content + ''; return li; } @@ -591,39 +666,39 @@ function addAllToUnten(jsonContent,tablename) { } - - -function addToOben(prodid,longname,price,tax,pricelevelname,extras,index) { - var jsonContent = $("#info-page").data("tableprods"); - var tablename = $("#info-page").data("tablename"); - if (pricelevelname != "A") { - longname += " (" + pricelevelname + ")"; +function createHashOfPayableItem(aProd) { + var longname = aProd["longname"]; + if (aProd["pricelevelname"] != "A") { + longname += " (" + aProd["pricelevelname"] + ")"; } - longname += " - " + (parseFloat(price).toFixed(2).replace(".",decpoint)); - - var extratxt = createExtraParagraph(extras); - - var li_item = generateListItem("c","plus",index,toHtml(longname) + extratxt); - $("#oben").append(li_item).promise().done(function () { - createAllEntriesInReceipt(); - $(this).off("click").on("click", ".info-go", function (e) { - e.stopImmediatePropagation(); - e.preventDefault(); - var prodid = jsonContent[this.id]["prodid"]; - var price = jsonContent[this.id]["price"]; - var tax = jsonContent[this.id]["tax"]; - var pricelevelname = jsonContent[this.id]["pricelevelname"]; - var longname = jsonContent[this.id]["longname"]; - var extras = jsonContent[this.id]["extras"]; - addToUnten(prodid,longname,price,tax,pricelevelname,extras,this.id); - createAllEntriesInReceipt(); - $(this).closest("li").remove(); - refreshList("#oben"); - }); - }); - refreshList("#oben"); + longname += " - " + (parseFloat(aProd["price"]).toFixed(2).replace(".",decpoint)); + var extratxt = createExtraParagraph(aProd["extras"]); + return toHtml(longname) + extratxt; } +function createPayableItemListElement(aProd) { + var count = ""; + if("count" in aProd) { + if (aProd["count"] > 1) { + count = aProd["count"] + "x "; + } + } + var li_item = generateListItem("c","plus","payable_" + aProd["id"],count + createHashOfPayableItem(aProd),"payable"); + return li_item; +} + +function createOnReceiptItemListElement(aProd) { + var count = ""; + if("count" in aProd) { + if (aProd["count"] > 1) { + count = aProd["count"] + "x "; + } + } + var li_item = generateListItem("c","plus","payable_" + aProd["id"],count + createHashOfPayableItem(aProd),"onreceipt"); + return li_item; +} + + // Make table empty... function clearUntenAndReceipt() { var untenHeader = '
  • '; @@ -639,36 +714,6 @@ function clearUntenAndReceipt() { $("#thedate").html('

     
    '); } -function addToUnten(prodid,longname,price,tax,pricelevelname,extras,index) { - var jsonContent = $("#info-page").data("tableprods"); - var tablename = $("#info-page").data("tablename"); - if (pricelevelname != "A") { - longname += " (" + pricelevelname + ")"; - } - longname += " - " + (parseFloat(price).toFixed(2).replace(".",decpoint)); - - var extratxt = createExtraParagraph(extras); - - var li_item = generateListItem("f","minus",index,toHtml(longname) + extratxt); - $("#unten").append(li_item).promise().done(function () { - createAllEntriesInReceipt(); - $(this).off("click").on("click", ".info-go", function (e) { - e.stopImmediatePropagation(); - e.preventDefault(); - var prodid = jsonContent[this.id]["prodid"]; - var price = jsonContent[this.id]["price"]; - var tax = jsonContent[this.id]["tax"]; - var extras = jsonContent[this.id]["extras"]; - var pricelevelname = jsonContent[this.id]["pricelevelname"]; - var longname = jsonContent[this.id]["longname"]; - addToOben(prodid,longname,price,tax,pricelevelname,extras,this.id); - $(this).closest("li").remove(); - createAllEntriesInReceipt(); - refreshList("#unten"); - }); - }); - refreshList("#unten"); -} // arrayToFill: // [0]: count prodid prodid-pricelevelname queueid longname price pricelevelname @@ -714,18 +759,15 @@ function listTaxes(collectionOfTaxes,decpointx) { } function listTaxesBasedOnUntenList(decpointx) { - var jsonContent = $("#info-page").data("tableprods"); - // REM* which different taxes do we have? var mytaxes = []; var count = 0; - - $("#unten li a.info-go").each(function() { - var id_in_jsonText = this.id; - var prodEl = jsonContent[id_in_jsonText]; - mytaxes.push(prodEl.tax); - }); + for (var i=0;i' + (eval(price)).toFixed(2) + '
  • ' + (eval(price)).toFixed(2) + '