dbutils = new DbUtils(); $this->commonUtils = new CommonUtils(); $this->userrights = new Userrights(); } function handleCommand($command) { header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0"); header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); if ($command == "getJsonTableNameFromId") { $this->getJsonTableNameFromId($_GET['tableid']); return; } // these command are only allowed for user with supply rights $cmdArray = array('getJsonAllPreparedProducts', 'getJsonLastDeliveredProducts', 'declareProductBeDelivered', 'declareMultipleProductsDelivered','declareProductNotBeDelivered'); if (in_array($command, $cmdArray)) { if (!($this->userrights->hasCurrentUserRight('right_supply'))) { echo "Benutzerrechte nicht ausreichend!"; return false; } } // these command are only allowed for user with kitchen or bar rights $cmdArray = array('declareProductBeCookingOrCooked', 'declareProductNOTBeCooked'); if (in_array($command, $cmdArray)) { if (!($this->userrights->hasCurrentUserRight('right_kitchen')) && !($this->userrights->hasCurrentUserRight('right_bar'))) { echo "Benutzerrechte nicht ausreichend!"; return false; } } // these command are only allowed for user with waiter rights $cmdArray = array('addProductListToQueue', 'removeProductFromQueue', 'changeTable','getProdsForTableChange'); if (in_array($command, $cmdArray)) { if (!($this->userrights->hasCurrentUserRight('right_waiter'))) { echo "Benutzerrechte nicht ausreichend!"; return false; } } // these command are only allowed for user with paydesk rights $cmdArray = array('getJsonProductsOfTableToPay', 'declarePaidCreateBillReturnBillId'); if (in_array($command, $cmdArray)) { if (!($this->userrights->hasCurrentUserRight('right_paydesk'))) { echo json_encode(array("status" => "ERROR", "code" => ERROR_PAYDESK_NOT_AUTHOTRIZED, "msg" => ERROR_PAYDESK_NOT_AUTHOTRIZED_MSG)); return false; } } if ($command == 'addProductListToQueue') { $this->addProductListToQueue($_POST["tableid"],$_POST["prods"],$_POST["print"],$_POST["payprinttype"]); } else if ($command == 'kitchenToCook') { $this->kitchenToCook(); } else if ($command == 'declareProductBeCookingOrCooked') { $this->declareProductBeCookingOrCooked($_POST['queueid'],$_POST['action']); } else if ($command == 'declareProductNotBeCooked') { $this->declareProductNotBeCooked($_POST['queueid']); } else if ($command == 'showProductsOfTableToPay') { $this->showProductsOfTableToPay($_GET['tableid']); } else if ($command == 'getJsonAllPreparedProducts') { $this->getJsonAllPreparedProducts(); } else if ($command == 'declareProductBeDelivered') { $this->declareProductBeDelivered($_POST['queueid']); } else if ($command == 'declareMultipleProductsDelivered') { $this->declareMultipleProductsDelivered($_POST['queueids']); } else if ($command == 'declareProductNotBeDelivered') { $this->declareProductNotBeDelivered($_POST['queueid']); } else if ($command == 'getJsonLongNamesOfProdsForTableNotDelivered') { $this->getJsonLongNamesOfProdsForTableNotDelivered($_GET["tableid"]); } else if ($command == 'getProdsForTableChange') { $this->getProdsForTableChange($_GET['tableId']); } else if ($command == 'changeTable') { $this->changeTable($_POST['fromTableId'],$_POST['toTableId'],$_POST['queueids']); } else if ($command == 'removeProductFromQueue') { $this->removeProductFromQueue($_POST["queueid"],$_POST["isPaid"],$_POST["isCooking"],$_POST["isReady"]); } else if ($command == 'getJsonAllQueueItemsToMake') { $this->getJsonAllQueueItemsToMake(intval($_GET["kind"])); } else if ($command == 'getJsonLastMadeItems') { $this->getJsonLastMadeItems(intval($_GET["kind"])); } else if ($command == 'getJsonLastDeliveredProducts') { $this->getJsonLastDeliveredProducts(); } else if ($command == 'getJsonProductsOfTableToPay') { $this->getJsonProductsOfTableToPay($_GET['tableid']); } else if ($command == 'declarePaidCreateBillReturnBillId') { $this->declarePaidCreateBillReturnBillId($_POST['ids'],$_POST['brutto'],$_POST['netto'],$_POST['tableid'],$_POST['paymentid'],$_POST['tax'],$_POST['decpoint'],$_POST['declareready'],$_POST['host']); } else { echo "Command not supported."; } } // needed if paydesk gets the tableid by direct call function getJsonTableNameFromId($tableid) { $pdo = DbUtils::openDbAndReturnPdoStatic(); $commonUtils = new CommonUtils(); echo json_encode($commonUtils->getTableNameFromId($pdo,$tableid)); } function getDateValueAsBoolInterpretatedIcon($aValue) { if ($aValue != '0000-00-00 00:00:00' ) { $imgFile = "ok.png"; } else { $imgFile = "wait.png"; } return ""; } function getUserName($userid) { $pdo = $this->dbutils->openDbAndReturnPdo(); $sql = "SELECT username FROM %user% WHERE id=?"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($userid)); $row =$stmt->fetchObject(); if ($row != null) { return($row->username); } else { return ""; } } private function areBillExisting($pdo) { $sql = "SELECT count(id) as countid FROM %bill%"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(); $row = $stmt->fetchObject(); $count = intval($row->countid); if ($count > 0) { return true; } else { return false; } } /* * Get the queue items for the kitchen view that have to be still be cooked * as a json element array * * 1. It is sorted for ordertime * 2. From this ordertime search for the distinct tables * 3. Sort it that way that tables are grouped together * * $kind=0 -> return only food elements, =1 -> return drinks */ private function getJsonAllQueueItemsToMake($kind) { // current time date_default_timezone_set(DbUtils::getTimeZone()); $currentTime = date('Y-m-d H:i:s'); $pdo = $this->dbutils->openDbAndReturnPdo(); // first sort all non-ready products ordered by ordertime if ($this->areBillExisting($pdo)) { $sql = "SELECT DISTINCT %queue%.id as id,%resttables%.id as tableid,tablenr,longname,anoption,tableno,date_format(ordertime,'%Y-%m-%d %H:%i:00') as ordertime,cooking,TIMESTAMPDIFF(MINUTE,ordertime,?) AS waittime FROM %queue%,%products%,%prodtype%,%resttables%,%bill% "; } else { $sql = "SELECT DISTINCT %queue%.id as id,%resttables%.id as tableid,tablenr,longname,anoption,tableno,date_format(ordertime,'%Y-%m-%d %H:%i:00') as ordertime,cooking,TIMESTAMPDIFF(MINUTE,ordertime,?) AS waittime FROM %queue%,%products%,%prodtype%,%resttables% "; } $sql .= "WHERE (readytime = '0000-00-00 00:00:00' AND "; $sql .= " ordertime is not null AND "; $sql .= "%queue%.productid=%products%.id AND "; $sql .= "%queue%.tablenr = %resttables%.id AND "; $sql .= "%products%.category=%prodtype%.id AND "; $sql .= "%prodtype%.kind=? AND "; $sql .= "%queue%.isclosed is null AND "; $sql .= "%queue%.workprinted='0') "; if ($this->areBillExisting($pdo)) { // now remove closed items $sql .= "AND (%queue%.billid is null OR ("; $sql .= "%queue%.billid=%bill%.id AND %bill%.closingid is null)) "; } $sql .= "ORDER BY ordertime,longname,anoption,cooking DESC,%queue%.id"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($currentTime,$kind)); $result1 = $stmt->fetchAll(); $sql = "SELECT DISTINCT %queue%.id as id,'-' as tableid,'-' as tablenr,longname,anoption,'-' as tableno,date_format(ordertime,'%Y-%m-%d %H:%i:00') as ordertime,cooking,TIMESTAMPDIFF(MINUTE,ordertime,?) AS waittime FROM %queue%,%products%,%prodtype%,%resttables%,%bill% "; $sql .= "WHERE (readytime = '0000-00-00 00:00:00' AND "; $sql .= " ordertime is not null AND "; $sql .= "%queue%.productid=%products%.id AND "; $sql .= "%queue%.tablenr is null AND "; $sql .= "%products%.category=%prodtype%.id AND "; $sql .= "%prodtype%.kind=? AND "; $sql .= "%queue%.isclosed is null AND "; $sql .= "%queue%.workprinted='0') "; $sql .= "AND (%queue%.billid is null OR ("; $sql .= "%queue%.billid=%bill%.id AND %bill%.closingid is null)) "; $sql .= "ORDER BY ordertime,longname,anoption,cooking DESC"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($currentTime,$kind)); $result2 = $stmt->fetchAll(); $result = array_merge($result1,$result2); $resultarray = array(); foreach($result as $zeile) { $waitTime = $zeile['waittime']; $cook = $zeile['cooking']; if (is_null($cook)) { $cook = 0; } $arr = array("id" => $zeile['id'], "tableid" => $zeile['tableid'], "tablenr" => $zeile['tableno'], "longname" => $zeile['longname'], "option" => $zeile['anoption'], "cooking" => $cook, "waittime" => $waitTime ); $resultarray[] = $arr; } $tablearray = array(); $insertedTables = array(); $table = (-1); if (count($resultarray) <> 0) { for ($queue_index=0;$queue_index < count($resultarray);$queue_index++) { $aTable = $resultarray[$queue_index]['tablenr']; if (($table <> $aTable) && !in_array($aTable,$insertedTables)) { // sort all entries for this table $table = $aTable; $tableid = $resultarray[$queue_index]['tableid']; $maxWaitTime = $resultarray[$queue_index]['waittime']; $tableArr = array(); for ($i=0;$igetExtrasOfQueueItem($pdo,$foundItem['id']); $anEntryForThisTable = array("id" => $foundItem['id'], "longname" => $foundItem['longname'], "option" => $foundItem['option'], "extras" => $extras, "cooking" => $this->getUserName($foundItem['cooking']), "waiticon" => $waitIconMinStep, "waittime" => $waittimeofentry ); $tableArr[] = $anEntryForThisTable; } } // Now fit max wait time of table to entry wait time steps: if (($maxWaitTime > 20) && ($maxWaitTime < 60)) { if ($maxWaitTime >= 50) { $maxWaitTime = "> 50"; } else if ($maxWaitTime >= 40) { $maxWaitTime = "> 40"; } else if ($maxWaitTime >= 30) { $maxWaitTime = "> 30"; } else if ($maxWaitTime >= 25) { $maxWaitTime = "> 25"; } else { $maxWaitTime = "> 20"; } } else if ($maxWaitTime <= 1) { $maxWaitTime = "1"; } $tablearray[] = array("table" => $table, "tableid" => $tableid,"count" => count($tableArr), "queueitems" => $tableArr, "maxwaittime" => $maxWaitTime); $insertedTables[] = $aTable; } } } echo json_encode($tablearray); } private function getExtrasOfQueueItem($pdo,$queueid) { if (is_null($pdo)) { $pdo = $this->dbutils->openDbAndReturnPdo(); } $sql = "SELECT name FROM %queueextras% WHERE queueid=?"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($queueid)); $extras = $stmt->fetchAll(); $extrasarr = array(); foreach($extras as $anExtra) { $extrasarr[] = $anExtra["name"]; } return $extrasarr; } private function getJobsToPrint($pdo,$kind,$printer,$queueIds) { if (is_null($queueIds) || (count($queueIds) == 0)) { return array(); } $queueStr = implode(',',$queueIds); $sql = "SELECT setting FROM %config% where name=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array('groupworkitems')); $row = $stmt->fetchObject(); $groupworkitems = $row->setting; if (is_null($groupworkitems)) { $groupworkitems = 1; } $sql = "SELECT %queue%.id as id,%queue%.tablenr as tableid, %queue%.productid,%queue%.productname as longname,anoption,%prodtype%.kind as kind,%prodtype%.printer as printer FROM %queue%,%products%,%prodtype% WHERE %prodtype%.kind=? AND %queue%.id IN ($queueStr) AND productid=%products%.id AND %products%.category=%prodtype%.id ORDER BY productname"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($kind)); $queueItems = $stmt->fetchAll(); $jobs = array(); foreach($queueItems as $aQueueItem) { // is the job for that printer? $thePrinter = $aQueueItem["printer"]; $queueid = $aQueueItem["id"]; $tableid = $aQueueItem["tableid"]; if (!is_null($tableid) && ($tableid != 0)) { $sql = "SELECT DISTINCT %room%.printer as printer FROM %queue%,%resttables%,%room% WHERE %resttables%.id=? AND %resttables%.roomid=%room%.id LIMIT 1"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($tableid)); $row = $stmt->fetchObject(); $roomPrinter = $row->printer; if (!is_null($roomPrinter)) { $thePrinter = $roomPrinter; } } if ($thePrinter == $printer) { $extras = $this->getExtrasOfQueueItem($pdo,$queueid); $theEntry = array( "id" => $queueid, "productid" => $aQueueItem["productid"], "longname" => $aQueueItem["longname"], "anoption" => $aQueueItem["anoption"], "kind" => $aQueueItem["kind"], "printer" => $aQueueItem["printer"], "extras" => $extras ); if ($groupworkitems) { $this->grouping($jobs, $theEntry); } else { $jobs[] = $theEntry; } } } if ($groupworkitems) { // new put the count number into the longname foreach($jobs as &$aJob) { $cnt = $aJob["count"]; if ($cnt > 1) { $aJob["longname"] = $cnt . "x " . $aJob["longname"]; } } } return $jobs; } private function grouping(&$collection,$entry) { $extrasTxt = join(",",$entry["extras"]); $found = false; foreach($collection as &$anEntry) { if (($anEntry["longname"] == $entry["longname"]) && ($anEntry["anoption"] == $entry["anoption"]) && (join(",",$anEntry["extras"]) == $extrasTxt)) { $found = true; $anEntry["count"] = $anEntry["count"] + 1; } } if (!$found) { $collection[] = array("id" => $entry["id"], "productid" => $entry["productid"], "longname" => $entry["longname"], "printer" => $entry["printer"], "anoption" => $entry["anoption"], "kind" => $entry["kind"], "extras" => $entry["extras"], "count" => 1 ); } } private function doWorkPrint($pdo,$theTableid,$insertedQueueIds,$username,$payPrintType,$lang) { // is it server or local print? $foodJobsPrinter1 = $this->getJobsToPrint($pdo, 0, 1, $insertedQueueIds); $foodJobsPrinter2 = $this->getJobsToPrint($pdo, 0, 2, $insertedQueueIds); $drinkJobsPrinter1 = $this->getJobsToPrint($pdo, 1, 1, $insertedQueueIds); $drinkJobsPrinter2 = $this->getJobsToPrint($pdo, 1, 2, $insertedQueueIds); if ($payPrintType == "s") { $this->createAWorkReceiptAndQueueWorkPrint($pdo,$foodJobsPrinter1,$theTableid,0,1,$username,$lang); $this->createAWorkReceiptAndQueueWorkPrint($pdo,$foodJobsPrinter2,$theTableid,0,2,$username,$lang); $this->createAWorkReceiptAndQueueWorkPrint($pdo,$drinkJobsPrinter1,$theTableid,1,1,$username,$lang); $this->createAWorkReceiptAndQueueWorkPrint($pdo,$drinkJobsPrinter2,$theTableid,1,1,$username,$lang); } // REM * for local print return all values - client will sort them for printer and kind. $result = array_merge($foodJobsPrinter1,$foodJobsPrinter2,$drinkJobsPrinter1,$drinkJobsPrinter2); return $result; } private function createAWorkReceiptAndQueueWorkPrint($pdo,$jobs,$theTableid,$kind,$printer,$user,$lang) { if (count($jobs) < 1) { return; } date_default_timezone_set(DbUtils::getTimeZone()); $now = date('Y-m-d H:i:s'); $germanTime = date('H:i'); $resultarray = array(); foreach($jobs as $aJob) { $queueId = $aJob["id"]; $extras = $this->getExtrasOfQueueItem($pdo,$queueId); $arr = array("id" => $queueId, "longname" => $aJob['longname'], "option" => $aJob['anoption'], "extras" => $extras, "ordertime" => $germanTime, "kind" => $kind, "printer" => $printer ); $resultarray[] = $arr; $sql = "UPDATE %queue% SET workprinted='1',readytime='$now',delivertime='$now' WHERE id=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($queueId)); } if (is_null($theTableid) || ($theTableid == 0)) { $takeAwayStr = array("Zum Mitnehmen","Take away","Para llevar"); $tablename = $takeAwayStr[$lang]; } else { $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(); if (is_null($row->abbreviation)) { $tablename = $row->tableno; } else { $tablename = $row->abbreviation . "-" . $row->tableno; } } PrintQueue::queueWorkPrintJob($pdo, $tablename, $germanTime, $resultarray, $kind, $printer, $user); } private function getJsonLastMadeItems($kind) { $pdo = DbUtils::openDbAndReturnPdoStatic(); // first sort all non-ready products ordered by ordertime if ($this->areBillExisting($pdo)) { $sql = "SELECT DISTINCT %queue%.id as id,tablenr,longname,anoption,tableno,readytime,%products%.id as prodid FROM %queue%,%products%,%prodtype%,%resttables%,%bill% "; } else { $sql = "SELECT DISTINCT %queue%.id as id,tablenr,longname,anoption,tableno,readytime,%products%.id as prodid FROM %queue%,%products%,%prodtype%,%resttables% "; } $sql .= "WHERE (readytime <> '0000-00-00 00:00:00' AND "; $sql .= "delivertime = '0000-00-00 00:00:00' AND "; $sql .= "ordertime is not null AND "; $sql .= "%queue%.productid=%products%.id AND "; $sql .= "%queue%.tablenr = %resttables%.id AND "; $sql .= "%products%.category=%prodtype%.id AND "; $sql .= "%prodtype%.kind=? AND "; $sql .= "%queue%.isclosed is null AND "; $sql .= "%queue%.workprinted='0') "; if ($this->areBillExisting($pdo)) { // now remove closed items $sql .= "AND (%queue%.billid is null OR ("; $sql .= "%queue%.billid=%bill%.id AND %bill%.closingid is null)) "; } $sql .= "ORDER BY readytime DESC LIMIT 10;"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($kind)); $result1 = $stmt->fetchAll(); if ($this->areBillExisting($pdo)) { $sql = "SELECT DISTINCT %queue%.id as id,0 as tablenr,longname,anoption,'-' as tableno,readytime,%products%.id as prodid FROM %queue%,%products%,%prodtype%,%resttables%,%bill% "; } else { $sql = "SELECT DISTINCT %queue%.id as id,0 as tablenr,longname,anoption,'-' as tableno,readytime,%products%.id as prodid FROM %queue%,%products%,%prodtype%,%resttables% "; } $sql .= "WHERE (readytime <> '0000-00-00 00:00:00' AND "; $sql .= "delivertime = '0000-00-00 00:00:00' AND "; $sql .= "ordertime is not null AND "; $sql .= "%queue%.productid=%products%.id AND "; $sql .= "%queue%.tablenr is null AND "; $sql .= "%products%.category=%prodtype%.id AND "; $sql .= "%prodtype%.kind=? AND "; $sql .= "%queue%.isclosed is null AND "; $sql .= "%queue%.workprinted='0') "; if ($this->areBillExisting($pdo)) { // now remove closed items $sql .= "AND (%queue%.billid is null OR ("; $sql .= "%queue%.billid=%bill%.id AND %bill%.closingid is null)) "; } $sql .= "ORDER BY readytime DESC LIMIT 10;"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($kind)); $result2 = $stmt->fetchAll(); $result = array_merge($result1,$result2); $resultarray = array(); foreach($result as $zeile) { $extras = $this->getExtrasOfQueueItem($pdo,$zeile['id']); $productid = $zeile['prodid']; $useConditions = $this->getUseKitchenAndSupplyForProd($pdo,$productid); if ($useConditions["usekitchen"] == 1) { // yes, display it in kitchen view as cooked $arr = array("id" => $zeile['id'], "tablename" => $zeile['tableno'], "longname" => $zeile['longname'], "option" => $zeile['anoption'], "extras" => $extras, "readytime" => $zeile['readytime'] ); $resultarray[] = $arr; } } // now look for items that are made and auto-delivered // They must appear if: // a) in category autosupply yes // b) they have the right kind // c) they shall appear in bar/kitchen module at all $resultarray = $this->appendProdsForBarKitchenAndAutoDelivery($pdo,$kind, $resultarray); echo json_encode($resultarray); } private function appendProdsForBarKitchenAndAutoDelivery($pdo,$kind,$resultarray) { $sql = "SELECT DISTINCT %queue%.id as id,tableno,longname,delivertime,anoption,%products%.id as prodid "; $sql .= "FROM %queue%,%resttables%,%products%,%bill%,%prodtype% "; $sql .= "WHERE (%queue%.productid=%products%.id "; $sql .= "AND %queue%.tablenr=%resttables%.id "; $sql .= "AND %queue%.readytime <> '0000-00-00 00:00:00' "; $sql .= "AND toremove <> '1' AND "; $sql .= "ordertime is not null AND "; $sql .= "(%queue%.productid = %products%.id AND %products%.category = %prodtype%.id AND %prodtype%.kind=? AND %prodtype%.usesupplydesk='0' AND %prodtype%.usekitchen='1') AND "; $sql .= "%queue%.workprinted='0') "; // now remove closed items $sql .= "AND (%queue%.billid is null OR ("; $sql .= "%queue%.billid=%bill%.id AND %bill%.closingid is null)) "; $sql = $sql . "ORDER BY delivertime DESC LIMIT 10"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($kind)); $result = $stmt->fetchAll(); foreach ($result as $zeile) { $productid = $zeile['prodid']; $extras = $this->getExtrasOfQueueItem($pdo,$zeile['id']); $deliveredProd = array( "id" => $zeile['id'], "tablename" => $zeile['tableno'], "longname" => $zeile['longname'], "option" => $zeile['anoption'], "extras" => $extras, "readytime" => $zeile['delivertime'] ); $resultarray[] = $deliveredProd; } return($resultarray); } /* * Kitchen can delare a product as being cooked */ function declareProductBeCookingOrCooked($queueid,$action) { if (is_numeric($queueid)) { $pdo = $this->dbutils->openDbAndReturnPdo(); $pdo->beginTransaction(); // is product already cooking or will it be set to cooking? $sql = "SELECT cooking,productid FROM %queue% WHERE id=?"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($queueid)); $row =$stmt->fetchObject(); if ($row != null) { $cooking = $row->cooking; $productid = $row->productid; if ($action == 'r') { // product shall be declared ready if (is_null($cooking)) { // a product must be cooking before it can be ready! $pdo->rollBack(); echo json_encode(array("status" => "ERROR", "code" => ERROR_DB_PAR_ACCESS, "msg" => ERROR_DB_PAR_ACCESS_MSG)); } else { $this->reallyDeclareAsCooked($pdo,$queueid); $useConditions = $this->getUseKitchenAndSupplyForProd($pdo,$productid); if ($useConditions["usesupply"] == 0) { // can bypass the supplydesk $this->declareProductBeDeliveredWithGivenPdo($pdo,$queueid); } $pdo->commit(); echo json_encode(array("status" => "OK")); } } else if ($action == 'c') { // product shall be declared as cooking (in progress) if (!is_null($cooking)) { // a product must not be cooking before it can becomes cooking $pdo->rollBack(); echo json_encode(array("status" => "ERROR", "code" => ERROR_DB_PAR_ACCESS, "msg" => ERROR_DB_PAR_ACCESS_MSG)); } else { $userid = $this->getUserId(); $updSql = "UPDATE %queue% SET cooking=? WHERE id=?"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($updSql)); $stmt->execute(array($userid,$queueid)); $pdo->commit(); echo json_encode(array("status" => "OK")); } } } else { $pdo->rollBack(); } } else { echo json_encode(array("status" => "ERROR", "code" => ERROR_GENERAL_ID_TYPE, "msg" => ERROR_GENERAL_ID_TYPE_MSG)); } } private function reallyDeclareAsCooked($pdo,$queueid) { date_default_timezone_set(DbUtils::getTimeZone()); $readytime = date('Y-m-d H:i:s'); $insertSql = "UPDATE %queue% SET readytime=? WHERE id=?"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($insertSql)); $stmt->execute(array($readytime,$queueid)); } /* * Product is not cooked (undo of kitchen) */ function declareProductNotBeCooked($queueid) { if (is_numeric($queueid)) { $pdo = $this->dbutils->openDbAndReturnPdo(); $pdo->beginTransaction(); // first: is the product still declared as delivered? $sql = "SELECT id FROM %queue% WHERE id=? AND readytime <> '0000-00-00 00:00:00'"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($queueid)); $row =$stmt->fetchObject(); if ($row != null) { $foundid = $row->id; if ($foundid == $queueid) { $sql = "UPDATE %queue% SET readytime='0000-00-00 00:00:00', delivertime='0000-00-00 00:00:00', cooking=NULL WHERE id=?"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($queueid)); $pdo->commit(); echo json_encode(array("status" => "OK")); } else { echo json_encode(array("status" => "ERROR", "code" => ERROR_DB_PAR_ACCESS, "msg" => ERROR_DB_PAR_ACCESS_MSG)); $pdo->rollBack(); } } else { $pdo->rollBack(); echo json_encode(array("status" => "ERROR", "code" => ERROR_DB_PAR_ACCESS, "msg" => ERROR_DB_PAR_ACCESS_MSG)); } } else { echo json_encode(array("status" => "ERROR", "code" => ERROR_GENERAL_ID_TYPE, "msg" => ERROR_GENERAL_ID_TYPE_MSG)); } } private function findCategoryOfProd($pdo,$prodid) { $sql = "SELECT category FROM %products% WHERE id=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($prodid)); $row = $stmt->fetchObject(); return $row->category; } private function getUseKitchenAndSupplyForProdInCat($pdo,$catid) { $sql = "SELECT usekitchen, usesupplydesk FROM %prodtype% WHERE id=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($catid)); $row = $stmt->fetchObject(); return array("usekitchen" => $row->usekitchen, "usesupply" => $row->usesupplydesk); } private function getUseKitchenAndSupplyForProd($pdo,$prodid) { $catid = $this->findCategoryOfProd($pdo,$prodid); return $this->getUseKitchenAndSupplyForProdInCat($pdo,$catid); } private function getUseKitchenAndSupplyForProdWithPdo($pdo,$prodid) { $sql = "SELECT usekitchen, usesupplydesk FROM %prodtype%,%products% WHERE %products%.category=%prodtype%.id AND %products%.id=?"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($prodid)); $row = $stmt->fetchObject(); if ($row != null) { return array("usekitchen" => $row->usekitchen, "usesupply" => $row->usesupplydesk); } else { return array("usekitchen" => "1", "usesupply" => "1"); } } /* * Add a product list to the queue as if it was ordered by the waiter. * The ordertime is set by the time that this method is invoked. * * If product shall not be run over kitchen or supplydesk this is * managed here as well */ function addProductListToQueue($theTableid,$prods,$doPrint,$payprinttype) { if (intval($theTableid) == 0) { $theTableid = null; // togo room } if(session_id() == '') { session_start(); } $pdo = $this->dbutils->openDbAndReturnPdo(); $pdo->beginTransaction(); $sql = "SELECT setting FROM %config% where name=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array('togotax')); $row = $stmt->fetchObject(); $togotax = $row->setting; $stmt->execute(array('tax')); $row = $stmt->fetchObject(); $normaltax = $row->setting; // get current pricelevel $currentPriceLevel = $this->commonUtils->getCurrentPriceLevel($pdo); $currentPriceLevelId = $currentPriceLevel["id"]; $insertedQueueIds = array(); $i = 0; for ($i=0;$iprepare($this->dbutils->resolveTablenamesInSqlString($getPriceSql)); $stmt->execute(array($productid)); $row = $stmt->fetchObject(); if ($row == null) { echo "Fehler: Preise nicht vorhanden"; // error return; } $productname = $row->longname; if (($theChangedPrice == "NO") || (!is_numeric($theChangedPrice))) { $price_for_level_A = $row->priceA; $price_for_level_B = $row->priceB; $price_for_level_C = $row->priceC; $price = $price_for_level_A; // default - levl 1 if ($currentPriceLevelId == 2) { $price = $price_for_level_B; } else if ($currentPriceLevelId == 3) { $price = $price_for_level_C; } // else: use default price A } else { $price = $theChangedPrice; } $tax = $normaltax; if (is_null($theTableid)) { $tax = $togotax; } if (!is_null($row->tax)) { $tax = $row->tax; } $extras = null; if (array_key_exists("extras",$aProd)) { $extras = $aProd["extras"]; } if (!is_null($extras) && ($extras != "")) { for ($j=0;$jprepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($extraid)); $row = $stmt->fetchObject(); $price += floatval($row->price); } } if (is_null($theTableid) || (is_numeric($theTableid) && is_numeric($productid))) { // first get category of product $useConditions = $this->getUseKitchenAndSupplyForProdWithPdo($pdo,$productid); date_default_timezone_set(DbUtils::getTimeZone()); $ordertime = date('Y-m-d H:i:s'); $insertSql = "INSERT INTO `%queue%` ( `id` , `tablenr`,`productid`,`pricelevel`,`price`,`tax`,`productname`,`ordertime`,`orderuser`,`anoption`,`readytime`,`delivertime`,`paidtime`,`billid`,`toremove`,`cooking`,`workprinted`) VALUES ( NULL , ?,?,?,?,?,?,?,?,?, '0000-00-00 00:00:00', '0000-00-00 00:00:00', NULL,NULL,'0',NULL,'0');"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($insertSql)); $stmt->execute(array($theTableid,$productid,$currentPriceLevelId,$price,$tax,$productname,$ordertime,$_SESSION['userid'],$theOption)); $queueid = $pdo->lastInsertId(); if (!is_null($extras) && ($extras != "")) { for ($j=0;$jprepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($queueid,$extraid,$extraname)); } } if ($useConditions["usekitchen"] == 0) { // no - can bypass the kitchen $this->reallyDeclareAsCooked($pdo,$queueid); // then also look for supplydesk, since kitchen action won't do this! if ($useConditions["usesupply"] == 0) { // can bypass the supplydesk $this->declareProductBeDeliveredWithGivenPdo($pdo,$queueid); // THIS autop declares as "prepared" (cooked)!!! } } else { $insertedQueueIds[] = $queueid; } } } if ($doPrint == 1) { if ($payprinttype == "s") { $this->doWorkPrint($pdo,$theTableid,$insertedQueueIds,$_SESSION['currentuser'],$payprinttype, $_SESSION['language']); echo json_encode(array("status" => "OK")); } else { $result = $this->doWorkPrint($pdo,$theTableid,$insertedQueueIds,$_SESSION['currentuser'],$payprinttype, $_SESSION['language']); echo json_encode(array("status" => "OK", "msg" => $result)); } } else { echo json_encode(array("status" => "OK")); } $pdo->commit(); } /* * Do as if the product would have been removed from queue - but don't do it exactly, * because then it would not appear in the reports any more. Instead declare the * ordertime = null (was never ordered...) */ function removeProductFromQueue($queueid,$isPaid,$isCooking,$isReady) { if (is_numeric($queueid)) { $pdo = $this->dbutils->openDbAndReturnPdo(); $sql = "SELECT count(id) as countid FROM %bill%"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(); $row = $stmt->fetchObject(); $hasBills = ($row->countid > 0 ? true : false); if ($hasBills) { $sql = "UPDATE %queue%,%bill% "; } else { $sql = "UPDATE %queue% "; } $sql .= "SET ordertime=null WHERE %queue%.id=? AND ordertime <> '0000-00-00 00:00:00' "; if ($isPaid == '1') { $sql .= " AND paidtime <> '0000-00-00 00:00:00' "; } else { $sql .= " AND (paidtime = '0000-00-00 00:00:00' or paidtime is null) "; } if ($isCooking == '1') { $sql .= " AND cooking is not null "; } else { $sql .= " AND cooking is null "; } if ($isReady == '1') { $sql .= " AND readytime <> '0000-00-00 00:00:00' "; } else { $sql .= " AND (readytime = '0000-00-00 00:00:00' or readytime is null) "; } // and not in a closing: if ($hasBills) { $sql .= " AND (billid is null OR ("; $sql .= " billid = %bill%.id AND %bill%.closingid is null)) "; } $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($queueid)); $rowsAffected = $stmt->rowCount(); if ($rowsAffected == 1) { echo json_encode(array("status" => "OK")); } else { echo json_encode(array("status" => "Failed", "msg" => "Affected rows: $rowsAffected")); } } } /* * Return as JSON structure all products that are assigned to a specified table, with the * specification that they are not delivered yet. * * ordertime must not be null, because =null means that is is paid but was cancelled later * by the waiter! (in a previous version such entries were deleted from queue, but then * they won't appear in reports any more) * * Return is: [ * {"queueid":"2","longname":"EL Greco 1 Person", "isReady":"1"}, * {"queueid":"5","longname":"Souvlaki","isReady":"0"}] * (a sample) * */ function getJsonLongNamesOfProdsForTableNotDelivered($tableid) { if (is_numeric($tableid)) { $prods = array(); $pdo = DbUtils::openDbAndReturnPdoStatic(); $sql = "SELECT count(id) as countid FROM %bill%"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(); $row = $stmt->fetchObject(); if ($row->countid == 0) { $sql = "SELECT DISTINCT %queue%.id as quid FROM %queue% WHERE ordertime is not null AND isclosed is null AND "; } else { $sql = "SELECT DISTINCT %queue%.id as quid FROM %queue%,%bill% WHERE ordertime is not null AND isclosed is null AND ((%queue%.billid is null AND %queue%.paidtime is null) OR (%queue%.billid=%bill%.id AND %bill%.closingid is null)) AND "; } if ($tableid == 0) { $sql .= "%queue%.tablenr is null ORDER BY ordertime"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(); } else { $sql .= "%queue%.tablenr=? ORDER BY ordertime"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($tableid)); } $allNotClosedQueueIds = $stmt->fetchAll(); $resultids = array(); $sql = "SELECT count(id) as countid FROM %queue% WHERE %queue%.id=? AND (%queue%.delivertime = '0000-00-00 00:00:00' "; $sql .= " OR %queue%.readytime = '0000-00-00 00:00:00' "; $sql .= " OR (%queue%.billid is null AND %queue%.paidtime is null)) "; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); foreach($allNotClosedQueueIds as $aQueueId) {# $aQId = $aQueueId["quid"]; $stmt->execute(array($aQId)); $row = $stmt->fetchObject(); if ($row->countid > 0) { $resultids[] = $aQId; } } $prods = array(); $sql = "SELECT readytime,paidtime,cooking,productname,anoption,productname FROM %queue% WHERE id=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); foreach ($resultids as $anId) { $stmt->execute(array($anId)); $row = $stmt->fetchObject(); $isReady = "1"; $isDelivered = "1"; $isPaid = "1"; $isCooking = '1'; if ($row->readytime == '0000-00-00 00:00:00') { $isReady = "0"; // not yet prepared by the kitchen } if ($row->paidtime == null) { $isPaid = "0"; // not yet paid } if (is_null($row->cooking)) { $isCooking = '0'; } $extras = $this->getExtrasOfQueueItem($pdo,$anId); $prodEntry = array( "id" =>$anId, "longname" => $row->productname, "option" => $row->anoption, "extras" => $extras, "isready" => $isReady, "isPaid" => $isPaid, "isCooking" => $isCooking); $prods[] = $prodEntry; } echo json_encode($prods); } } function getProdsForTableChange($tableid) { $pdo = DbUtils::openDbAndReturnPdoStatic(); if ($tableid == 0) { $tableid = null; } $sql = "SELECT count(%queue%.id) as mycount,productname, GROUP_CONCAT(%queue%.id) AS queueids FROM "; $sql .= "%queue% WHERE "; $sql .= "(tablenr=? OR (tablenr IS NULL AND ? IS NULL)) AND ordertime is not null AND isclosed is null AND billid is null "; $sql .= "GROUP BY productid"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($tableid,$tableid)); $unpaidresult = $stmt->fetchAll(); $sql = "SELECT count(%queue%.id) as mycount,productname, GROUP_CONCAT(%queue%.id) AS queueids FROM "; $sql .= "%queue% LEFT OUTER JOIN %bill% ON %queue%.billid=%bill%.id WHERE "; $sql .= "(tablenr=? OR (tablenr IS NULL AND ? IS NULL)) AND ordertime is not null AND isclosed is null AND billid is null AND ("; $sql .= "%queue%.delivertime = '0000-00-00 00:00:00' OR "; $sql .= "(%queue%.delivertime <> '0000-00-00 00:00:00' AND workprinted='1')) "; $sql .= "GROUP BY productid"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($tableid,$tableid)); $undeliveredresult = $stmt->fetchAll(); echo json_encode(array("status" => "OK","unpaid" => $unpaidresult,"undeliveredunpaid" => $undeliveredresult)); } function changeTable($fromTableId, $toTableId, $queueids) { $ids = explode(",",$queueids); foreach($ids as $id) { if (!is_numeric($id)) { echo json_encode(array("status" => "ERROR", "code" => NUMBERFORMAT_ERROR, "msg" => NUMBERFORMAT_ERROR_MSG)); return; } } $pdo = $this->dbutils->openDbAndReturnPdo(); $pdo->beginTransaction(); $sql = "UPDATE %queue% SET tablenr=? WHERE id IN($queueids) AND tablenr=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($toTableId,$fromTableId)); $pdo->commit(); echo json_encode(array("status" => "OK")); } function getJsonProductsOfTableToPay($tableid) { $pdo = DbUtils::openDbAndReturnPdoStatic(); $sql = "SELECT %queue%.id as id,longname,%queue%.price as price,%queue%.tax,%pricelevel%.name as pricelevelname,%products%.id as prodid FROM %queue% INNER JOIN %products% ON %queue%.productid = %products%.id INNER JOIN %pricelevel% ON %queue%.pricelevel = %pricelevel%.id "; if ($tableid == 0) { $sql .= "WHERE tablenr is null "; } else { $sql .= "WHERE tablenr = $tableid "; } $sql .= "AND paidtime is null AND toremove <> '1' AND ordertime is not null AND isclosed is null ORDER BY ordertime;"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(); $result = $stmt->fetchAll(); $prodsToPay = array(); foreach ($result as $zeile) { $thePrice = $zeile['price']; $theTax = $zeile['tax']; $thePriceLevelName = $zeile['pricelevelname']; $longName = $zeile['longname']; $queueid = $zeile['id']; $extras = $this->getExtrasOfQueueItem($pdo,$queueid); $prodId = $zeile['prodid']; $prodsToPay[] = array("id" => $queueid, "prodid" => $prodId, "longname" => $longName, "pricelevelname" => $thePriceLevelName, "price" => $thePrice, "tax" => $theTax, "extras" => $extras); } echo json_encode(array("status" => "OK", "msg" => $prodsToPay)); } // This function gets the items to pay and creates a table, in which these items // are listed up. It can be used as a receipt to print later function displayBill($billtableitems,$totalPrice) { $currency = $this->commonUtils->getCurrency(); $numberOfItemsToPay = count($billtableitems); if ($numberOfItemsToPay > 0) { echo "

"; echo ""; for ($i=0;$i < $numberOfItemsToPay; $i++) { $aProductToPay = $billtableitems[$i]; echo ""; echo ""; } echo ""; } echo "
Speise/GetränkPreis ($currency)
" . $aProductToPay['textOfButton'] . "" . $aProductToPay['price'] . "
Gesamtpreis: " . $totalPrice . " $currency
"; } // ********************************** // * Bereitstellung * // ********************************** function declareProductBeDeliveredWithGivenPdo($pdo,$queueid) { if (is_numeric($queueid)) { date_default_timezone_set(DbUtils::getTimeZone()); $delivertime = date('Y-m-d H:i:s'); $updateSql = "UPDATE %queue% SET delivertime=? WHERE id=?"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($updateSql)); $stmt->execute(array($delivertime,$queueid)); // then it was probably already prepared $updateSql = "UPDATE %queue% SET readytime=? WHERE id=?"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($updateSql)); $stmt->execute(array($delivertime,$queueid)); } } function declareProductBeDelivered($queueid) { if (is_numeric($queueid)) { $pdo = $this->dbutils->openDbAndReturnPdo(); $this->declareProductBeDeliveredWithGivenPdo($pdo, $queueid); } } function declareMultipleProductsDelivered($queueids) { $ids = explode(",",$queueids); $pdo = DbUtils::openDbAndReturnPdoStatic(); $pdo->beginTransaction(); for ($i=0;$i < count($ids); $i++) { $aQueueId = $ids[$i]; if (is_numeric($aQueueId)) { $this->declareProductBeDeliveredWithGivenPdo($pdo,$aQueueId); } } $pdo->commit(); echo json_encode(array("status" => "OK")); } function declareProductNotBeDelivered($queueid) { $pdo = DbUtils::openDbAndReturnPdoStatic(); if (is_numeric($queueid)) { date_default_timezone_set(DbUtils::getTimeZone()); $delivertime = date('Y-m-d H:i:s'); $updateSql = "UPDATE %queue% SET delivertime='0000-00-00 00:00:00' WHERE id=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($updateSql)); $stmt->execute(array($queueid)); } } public function getAllPreparedProductsForTableidAsArray($pdo,$tableid) { if (!is_null($tableid)) { $sql = "SELECT DISTINCT %queue%.id as id,tableno,longname,anoption,readytime "; if ($this->areBillExisting($pdo)) { $sql .= "FROM %queue%,%products%,%resttables%,%bill% "; } else { $sql .= "FROM %queue%,%products%,%resttables% "; } $sql .= "WHERE (readytime <> '0000-00-00 00:00:00' and delivertime = '0000-00-00 00:00:00' "; $sql .= "AND %queue%.productid=%products%.id "; $sql .= "AND %queue%.tablenr=%resttables%.id "; $sql .= "AND %queue%.isclosed is null "; $sql .= "AND ordertime is not null "; $sql .= "AND %resttables%.id=" . $tableid . " "; $sql .= "AND toremove <> '1') "; if ($this->areBillExisting($pdo)) { // now remove closed items $sql .= "AND (%queue%.billid is null OR ("; $sql .= "%queue%.billid=%bill%.id AND %bill%.closingid is null)) "; } $sql .= " ORDER BY tableno"; } else { // togo $sql = "SELECT DISTINCT %queue%.id as id,'' as tableno,longname,anoption,readytime "; if ($this->areBillExisting($pdo)) { $sql .= "FROM %queue%,%products%,%resttables%,%bill% "; } else { $sql .= "FROM %queue%,%products%,%resttables% "; } $sql .= "WHERE (readytime <> '0000-00-00 00:00:00' and delivertime = '0000-00-00 00:00:00' "; $sql .= "AND %queue%.productid=%products%.id "; $sql .= "AND %queue%.tablenr is null "; $sql .= "AND ordertime is not null "; $sql .= "AND %queue%.isclosed is null "; $sql .= "AND toremove <> '1') "; if ($this->areBillExisting($pdo)) { $sql .= "AND (%queue%.billid is null OR ("; $sql .= "%queue%.billid=%bill%.id AND %bill%.closingid is null)) "; } $sql = $sql . " ORDER BY tableno"; } $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(); $dbresult = $stmt->fetchAll(); // create a table that is optimal (sqrt-like size) $numberOfIcons = count($dbresult); $arrayOfProdsForTable = array(); $idsProdsOfTable = ''; // this is a hack! All queueids of a table redundant for "Deliver all" foreach($dbresult as $zeile) { $theAction= "deliver"; $longname = $zeile['longname']; $extras = $this->getExtrasOfQueueItem(null,$zeile['id']); $anProdElem = array( "id" => $zeile['id'], "longname" => $zeile['longname'], "option" => $zeile['anoption'], "extras" => $extras, "status" => "ready_to_deliver"); $arrayOfProdsForTable[] = $anProdElem; if ($idsProdsOfTable == '') { $idsProdsOfTable = $idsProdsOfTable . $zeile['id']; } else { $idsProdsOfTable = $idsProdsOfTable . ',' . $zeile['id']; } } return array("prods" => $arrayOfProdsForTable, "ids" => $idsProdsOfTable); } // total number of products for table // can later be used for color indication if products can be delivered completly for a table public function numberOfProductsForTableNotDelivered($pdo,$tableid) { $sql = "SELECT DISTINCT %queue%.id as id "; if (!is_null($tableid)) { // not togo $sql .= "FROM %queue%,%resttables% "; } else { $sql .= "FROM %queue% "; } $sql .= "WHERE delivertime = '0000-00-00 00:00:00' "; $sql .= "AND ordertime is not null "; $sql .= "AND %queue%.isclosed is null "; $sql .= "AND workprinted='0' "; $sql .= "AND toremove <> '1' "; if (!is_null($tableid)) { // not togo $sql .= "AND %queue%.tablenr=%resttables%.id "; $sql .= "AND %resttables%.id=" . $tableid; } else { $sql .= "AND %queue%.tablenr is null "; } $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(); $dbresult = $stmt->fetchAll(); $numberOfProducts = count($dbresult); return $numberOfProducts; } function getJsonAllPreparedProducts() { $pdo = DbUtils::openDbAndReturnPdoStatic(); // find out the tables that are relevant $sql = "SELECT DISTINCT tablenr "; if ($this->areBillExisting($pdo)) { $sql .= "FROM %queue%,%resttables%,%bill% "; } else { $sql .= "FROM %queue%,%resttables% "; } $sql .= "WHERE (readytime <> '0000-00-00 00:00:00' and delivertime = '0000-00-00 00:00:00' "; $sql .= "AND toremove <> '1' "; $sql .= "AND %queue%.tablenr=%resttables%.id AND "; $sql .= "ordertime is not null AND "; $sql .= "%queue%.isclosed is null AND "; $sql .= "%queue%.workprinted='0') "; if ($this->areBillExisting($pdo)) { // now remove closed items $sql .= "AND (%queue%.billid is null OR ("; $sql .= "%queue%.billid=%bill%.id AND %bill%.closingid is null)) "; } $sql .= " ORDER BY tablenr"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(); $result1 = $stmt->fetchAll(); $sql = "SELECT DISTINCT tablenr "; if ($this->areBillExisting($pdo)) { $sql .= "FROM %queue%,%bill% "; } else { $sql .= "FROM %queue% "; } $sql .= "WHERE (readytime <> '0000-00-00 00:00:00' and delivertime = '0000-00-00 00:00:00' "; $sql .= "AND toremove <> '1' "; $sql .= "AND %queue%.tablenr is null AND "; $sql .= "ordertime is not null AND "; $sql .= "%queue%.isclosed is null AND "; $sql .= "%queue%.workprinted='0') "; if ($this->areBillExisting($pdo)) { $sql .= "AND (%queue%.billid is null OR ("; $sql .= "%queue%.billid=%bill%.id AND %bill%.closingid is null)) "; } $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(); $result2 = $stmt->fetchAll(); $result = array_merge($result1,$result2); $tablesToServe = array(); foreach($result as $zeile) { $tablesToServe[] = $zeile['tablenr']; } // to sort complete prepared tables use two arrays: $preparedProds_incomplete_tables = array(); $preparedProds = array(); $commonUtils = new CommonUtils(); foreach ($tablesToServe as $tableid) { $arrayOfProdsAndIdsOfATable = $this->getAllPreparedProductsForTableidAsArray($pdo,$tableid); $arrayOfProdsOfATable = $arrayOfProdsAndIdsOfATable['prods']; $numberOfProductsTotalToServe = $this->numberOfProductsForTableNotDelivered($pdo,$tableid); $numberOfReadyProducts = count($arrayOfProdsOfATable); if ($numberOfReadyProducts >= $numberOfProductsTotalToServe) { $tablestatus = "complete"; $tableheadeline = $commonUtils->getTableNameFromId($pdo,$tableid); $preparedProds[] = array( "tableheadline" => $tableheadeline, "tableid" => $tableid, "tablestatus" => $tablestatus, "ids" => $arrayOfProdsAndIdsOfATable['ids'], "prodsOfTable" => $arrayOfProdsOfATable); } else { $tablestatus = "incomplete"; $tableheadeline = "Tisch: " . $commonUtils->getTableNameFromId($pdo,$tableid); $preparedProds_incomplete_tables[] = array( "tableheadline" => $tableheadeline, "tableid" => $tableid, "tablestatus" => $tablestatus, "ids" => $arrayOfProdsAndIdsOfATable['ids'], "prodsOfTable" => $arrayOfProdsOfATable); } } echo json_encode(array_merge($preparedProds,$preparedProds_incomplete_tables)); } /* * Return as JSON object a list of max 10 entries of products that * have been delivered to a table */ function getJsonLastDeliveredProducts() { $pdo = DbUtils::openDbAndReturnPdoStatic(); // 1. no togo products $sql = "SELECT DISTINCT %queue%.id as id,tableno,longname,delivertime,anoption,%products%.id as prodid "; if ($this->areBillExisting($pdo)) { $sql .= "FROM %queue%,%resttables%,%products%,%bill% "; } else { $sql .= "FROM %queue%,%resttables%,%products% "; } $sql .= "WHERE (delivertime <> '0000-00-00 00:00:00' "; $sql .= "AND %queue%.productid=%products%.id "; $sql .= "AND %queue%.tablenr=%resttables%.id "; $sql .= "AND toremove <> '1' AND "; $sql .= "ordertime is not null AND "; $sql .= "%queue%.isclosed is null AND "; $sql .= "%queue%.workprinted='0') "; if ($this->areBillExisting($pdo)) { // now remove closed items $sql .= "AND (%queue%.billid is null OR ("; $sql .= "%queue%.billid=%bill%.id AND %bill%.closingid is null)) "; } $sql = $sql . "ORDER BY delivertime DESC LIMIT 10"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(); $result1 = $stmt->fetchAll(); // 2.togo products $sql = "SELECT DISTINCT %queue%.id as id,'' as tableno,longname,delivertime,anoption,%products%.id as prodid "; if ($this->areBillExisting($pdo)) { $sql .= "FROM %queue%,%resttables%,%products%,%bill% "; } else { $sql .= "FROM %queue%,%resttables%,%products% "; } $sql .= "WHERE (delivertime <> '0000-00-00 00:00:00' "; $sql .= "AND %queue%.productid=%products%.id "; $sql .= "AND %queue%.tablenr is null "; $sql .= "AND toremove <> '1' AND "; $sql .= "ordertime is not null AND "; $sql .= "%queue%.isclosed is null AND "; $sql .= "%queue%.workprinted='0') "; if ($this->areBillExisting($pdo)) { $sql .= "AND (%queue%.billid is null OR ("; $sql .= "%queue%.billid=%bill%.id AND %bill%.closingid is null)) "; } $sql = $sql . "ORDER BY delivertime DESC LIMIT 10"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(); $result2 = $stmt->fetchAll(); $result = array_merge($result1,$result2); $lastDeliveredProds = array(); foreach($result as $zeile) { $productid = $zeile['prodid']; $useConditions = $this->getUseKitchenAndSupplyForProd($pdo,$productid); if ($useConditions["usesupply"] == 1) { // yes, display it in supplydesk view as cooked $extras = $this->getExtrasOfQueueItem(null,$zeile['id']); $deliveredProd = array( "id" => $zeile['id'], "longname" => $zeile['longname'], "option" => $zeile['anoption'], "extras" => $extras, "delivertime" => $zeile['delivertime'], "tablename" => $zeile['tableno']); $lastDeliveredProds[] = $deliveredProd; } } echo json_encode($lastDeliveredProds); } // ********************************** // * Kasse * // ********************************** /* * Test if all queue items with the given ids are not paid * -> if there are paid items --> report error by return negative value * * Set paid column with the given date * Create bill * Return a bill id */ function declarePaidCreateBillReturnBillId($ids,$brutto,$netto,$tableid,$paymentId,$tax,$decpoint,$declareready,$host) { $userid = $this->getUserId(); $ids_array = explode ( ',', $ids ); $pdo = $this->dbutils->openDbAndReturnPdo(); $pdo->beginTransaction(); // check if all items are not paid yet! $allNotPaid = true; for ($i=0;$iprepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($anId)); $row =$stmt->fetchObject(); if ($row != null) { $aCount = $row->countid; if (($aCount != null) && ($aCount == 1)) { $allNotPaid = false; } } } } // current time date_default_timezone_set(DbUtils::getTimeZone()); $currentTime = date('Y-m-d H:i:s'); $billid = (-1); if ($allNotPaid == true) { $billid = -1; // find highest bill id $sql = "SELECT id from %bill% ORDER BY id DESC"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(); $numberOfIds = $stmt->rowCount(); if ($numberOfIds > 0) { $row =$stmt->fetchObject(); if ($row != null) { $billid = intval($row->id)+1; } else { echo " - row ist null - "; $pdo->rollBack(); return; } } else { $billid = 1; } // Test if it is allowed to use this billid or if manipulation has happened if (!$this->commonUtils->verifyLastBillId($pdo, $billid)) { echo json_encode(array("status" => "ERROR", "code" => ERROR_INCONSISTENT_DB, "msg" => ERROR_INCONSISTENT_DB_MSG)); $pdo->rollBack(); return; } else { // ok - then increment that last id in the work table $this->commonUtils->setLastBillIdInWorkTable($pdo, $billid); } if (is_null($tableid)) { $tableid = 0; } // now calculate the signature for the bill entry $signature = $this->commonUtils->calcSignatureForBill($pdo,$currentTime, $brutto, $netto, '0.00', $userid); $billInsertSql = "INSERT INTO `%bill%` (`id` , `billdate`,`brutto`,`netto`,`tableid`,`paymentid`,`userid`,`ref`,`tax`,`host`,`signature`) VALUES (?,?,?,?,?,?,?,NULL,NULL,?,?)"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($billInsertSql)); $stmt->execute(array($billid,$currentTime,$brutto,$netto,$tableid,$paymentId,$userid,$host,$signature)); // now declare them all to be paid: for ($i=0;$iprepare(DbUtils::substTableAlias($updateSql)); $stmt->execute(array($currentTime,$billid,$queueid)); } else { $updateSql = "UPDATE %queue% SET paidtime=?, billid=?,readytime=?,delivertime=? WHERE id=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($updateSql)); $stmt->execute(array($currentTime,$billid,$currentTime,$currentTime,$queueid)); } $billProdsSql = "INSERT INTO `%billproducts%` (`queueid`,`billid`) VALUES ( ?,?)"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($billProdsSql)); $stmt->execute(array($queueid,$billid)); } } } $pdo->commit(); $billInfo = array("billid" => $billid, "date" => $currentTime); echo json_encode(array("status" => "OK", "msg" => $billInfo)); } private function getUserId() { if(session_id() == '') { session_start(); } return $_SESSION['userid']; } } ?>