dbutils = new DbUtils(); require_once 'translations.php'; } function handleCommand($command) { if ($command == 'exportCsv') { if ($this->hasCurrentUserAdminOrManagerRights()) { // yes, we can export the data $this->exportCsv($_GET['startMonth'],$_GET['startYear'],$_GET['endMonth'],$_GET['endYear'],DO_CSV); } else { echo json_encode(array("status" => "ERROR", "code" => ERROR_BILL_NOT_AUTHOTRIZED, "msg" => ERROR_BILL_NOT_AUTHOTRIZED_MSG)); } return; } if ($command == 'exportXlsx') { if ($this->hasCurrentUserAdminOrManagerRights()) { // yes, we can export the data $this->exportCsv($_GET['startMonth'],$_GET['startYear'],$_GET['endMonth'],$_GET['endYear'],DO_EXCEL); } else { echo json_encode(array("status" => "ERROR", "code" => ERROR_BILL_NOT_AUTHOTRIZED, "msg" => ERROR_BILL_NOT_AUTHOTRIZED_MSG)); } return; } if ($command == 'exportPdfReport') { if ($this->hasCurrentUserAdminOrManagerRights()) { $this->exportPdfReport($_GET['startMonth'],$_GET['startYear'],$_GET['endMonth'],$_GET['endYear']); } else { echo "Benutzer nicht berechtigt"; } return; } if ($command == 'exportPdfSummary') { if ($this->hasCurrentUserAdminOrManagerRights()) { $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()) { // yes, we can export the data $this->exportCsvOfClosing($_GET['closingid'],DO_CSV); } else { echo json_encode(array("status" => "ERROR", "code" => ERROR_MANAGER_NOT_AUTHOTRIZED, "msg" => ERROR_MANAGER_NOT_AUTHOTRIZED_MSG)); } return; } if ($command == 'exportXlsxOfClosing') { if ($this->hasCurrentUserAdminOrManagerRights()) { // yes, we can export the data $this->exportCsvOfClosing($_GET['closingid'],DO_EXCEL); } else { echo json_encode(array("status" => "ERROR", "code" => ERROR_MANAGER_NOT_AUTHOTRIZED, "msg" => ERROR_MANAGER_NOT_AUTHOTRIZED_MSG)); } return; } if ($command == 'doCashAction') { if ($this->hasCurrentUserPaydeskRights()) { $remark = ""; if(isset($_POST["remark"])) { $remark = $_POST['remark']; } $this->doCashAction($_POST['money'],$remark); } else { echo json_encode(array("status" => "ERROR", "code" => ERROR_PAYDESK_NOT_AUTHOTRIZED, "msg" => ERROR_PAYDESK_NOT_AUTHOTRIZED_MSG)); } return; } else if ($command == 'getCashOverviewOfUser') { if ($this->hasCurrentUserPaydeskRights()) { $this->getCashOverviewOfUser(); } else { echo json_encode(array("status" => "ERROR", "code" => ERROR_PAYDESK_NOT_AUTHOTRIZED, "msg" => ERROR_PAYDESK_NOT_AUTHOTRIZED_MSG)); } return; } if ($command == 'changeBillHost') { if ($this->hasCurrentUserPaydeskRights()) { $pdo = DbUtils::openDbAndReturnPdoStatic(); $this->changeBillHost($pdo,$_POST['billid'],$_POST['isNowHost']); } else { echo json_encode(array("status" => "ERROR", "code" => ERROR_PAYDESK_NOT_AUTHOTRIZED, "msg" => ERROR_PAYDESK_NOT_AUTHOTRIZED_MSG)); } return; } if ($this->hasCurrentUserBillRights()) { if ($command == 'getLastBillsWithContent') { $this->getLastBillsWithContent($_GET['day'],$_GET['month'],$_GET['year']); } else if ($command == 'cancelBill') { $pdo = DbUtils::openDbAndReturnPdoStatic(); $this->cancelBill($pdo,$_POST['billid'],$_POST['stornocode'],$_POST['reason'],true,true,true,$_POST['removeproducts']); } } else { echo json_encode(array("status" => "ERROR", "code" => ERROR_BILL_NOT_AUTHOTRIZED, "msg" => ERROR_BILL_NOT_AUTHOTRIZED_MSG)); } } // for internal request private function hasCurrentUserBillRights() { session_start(); if (!isset($_SESSION['angemeldet']) || !$_SESSION['angemeldet']) { // no user logged in return false; } else { return ($_SESSION['right_bill']); } } private function hasCurrentUserPaydeskRights() { session_start(); if (!isset($_SESSION['angemeldet']) || !$_SESSION['angemeldet']) { // no user logged in return false; } else { return ($_SESSION['right_paydesk']); } } // for internal request private function hasCurrentUserAdminOrManagerRights() { session_start(); if (!isset($_SESSION['angemeldet']) || !$_SESSION['angemeldet']) { // no user logged in return false; } else { return ($_SESSION['right_manager'] || $_SESSION['is_admin']); } } 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($pdo,$billid,$language,$printer) { set_time_limit(120); // is bill correct with signature? $commonUtils = new CommonUtils(); $correct = $commonUtils->verifyBill($pdo, $billid); if (!$correct) { echo json_encode(array("status" => "ERROR", "code" => ERROR_INCONSISTENT_DB, "msg" => ERROR_INCONSISTENT_DB_MSG)); return; } // first: get the bill overall data // is the bill for a table or togo $sql = "SELECT tableid FROM %bill% WHERE id=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($billid)); $row = $stmt->fetchObject(); $sql = "SELECT count(id) as countid FROM %queue% WHERE billid=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($billid)); $qrow = $stmt->fetchObject(); $tableid = $row->tableid; if ($qrow->countid == 0) { if ($tableid == 0) { // togo $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,IFNULL(%bill%.status,'') as status FROM %bill%,%user%,%resttables% WHERE %bill%.id=? AND userid=%user%.id AND tableid=%resttables%.id "; } } else { if ($tableid == 0) { // togo $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,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())); return; } else { if (is_null($row->host)) { $host = 0; // default } else { $host = $row->host; } $thetimedate = $row->billdate; $thetimedate_arr = explode ( ' ', $thetimedate ); $thedate = $thetimedate_arr[0]; $datearr = explode ( '-', $thedate ); $day = sprintf("%02s", $datearr[2]); $month = sprintf("%02s", $datearr[1]); $year = sprintf("%04s", $datearr[0]); $thetime = $thetimedate_arr[1]; $thetimearr = explode ( ':', $thetime ); $hour = $thetimearr[0]; $min = $thetimearr[1]; $thetimedate = "$day.$month.$year $hour:$min"; $billoverallinfo = array( "id" => $billid, "billdate" => $thetimedate, "billday" => $day, "billmonth" => $month, "billyear" => $year, "billhour" => $hour, "billmin" => $min, "brutto" => $row->brutto, "netto" => $row->netto, "table" => $tablename, "username" => $row->username, "printer" => $printer, "host" => $host ); $billtranslations = array( "sum" => $this->P_SUM[$language], "total" => $this->P_TOTAL[$language], "mwst" => $this->P_MWST[$language], "netto" => $this->P_NETTO[$language], "brutto" => $this->P_BRUTTO[$language], "id" => $this->P_ID[$language], "table" => $this->P_TABLE[$language], "waiter" => $this->P_WAITER[$language], "no" => $this->P_NO[$language], "descr" => $this->P_DESCR[$language], "price" => $this->P_PRICE[$language] ); } // now get all products of this bill $sql = "select productname,price,%pricelevel%.name as pricelevelname,togo,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,togo"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($billid)); $result = $stmt->fetchAll(); $prodarray = array(); foreach($result as $zeile) { $productname = $zeile['productname']; if ($zeile["togo"] == 1) { $productname = "To-Go: " . $productname; } $prodarray[] = array("count" => $zeile['count'], "productname" => $productname, "pricelevel" => $zeile['pricelevelname'], "price" => $sign . $zeile['price'] ); } $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; } public function getAustriaTaxes($pdo,$billid) { $sql = "select tax,IF(taxaustria is not null, taxaustria, 0) as taxaustria,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 taxaustria"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($billid)); $result = $stmt->fetchAll(PDO::FETCH_OBJ); return $result; } /* * insert or take out cash money. The direction done by sign of $money value */ private function doCashAction($money,$remark) { // current time date_default_timezone_set(DbUtils::getTimeZone()); $currentTime = date('Y-m-d H:i:s'); $pdo = $this->dbutils->openDbAndReturnPdo(); $pdo->beginTransaction(); $sql = "SELECT sum(brutto) as bruttosum FROM %bill% WHERE closingid is null AND paymentid='1'"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(); $row =$stmt->fetchObject(); if ($row != null) { $sum = $row->bruttosum; if (is_null($sum)) { // no transaction after last closing $sum = 0.0; } if (($sum + floatval($money)) >= 0.0) { // Test if it is allowed to insert new bill as storno bill or if manipulation has happened $nextbillid = $this->testForNewBillIdAndUpdateWorkTable($pdo); if ($nextbillid < 0) { echo json_encode(array("status" => "ERROR", "code" => ERROR_INCONSISTENT_DB, "msg" => ERROR_INCONSISTENT_DB_MSG)); $pdo->rollBack(); } $userId = $this->getUserId(); // now calculate the signature for the bill entry $commonUtils = new CommonUtils(); $signature = $commonUtils->calcSignatureForBill($pdo,$currentTime, $money, $money, 0.0, $userId); $sql = "INSERT INTO `%bill%` (`id` , `billdate`,`brutto`,`netto`,`tax`,`tableid`, `status`, `paymentid`,`userid`,`ref`,`reason`,`signature`) VALUES ( ?, ? , ?,?,?, ?, 'c', ?,?,?,?,?)"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($nextbillid,$currentTime,$money,$money,'0.00',-1,1,$userId,NULL,$remark,$signature)); $lastId = $pdo->lastInsertId(); $prevbrutto = 0; $prevnetto = 0; if ($lastId > 1) { $sql = "SELECT brutto,prevbrutto,netto,prevnetto FROM %bill% WHERE id=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($lastId-1)); $row =$stmt->fetchObject(); } $sql = "UPDATE %bill% SET prevbrutto=?,prevnetto=? WHERE id=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($row->brutto + $row->prevbrutto,$row->netto + $row->prevnetto,$lastId)); $pdo->commit(); echo json_encode(array("status" => "OK")); } else { echo json_encode(array("status" => "ERROR", "code" => ERROR_BILL_LESS_MONEY_TO_TAKE_OUT, "msg" => ERROR_BILL_LESS_MONEY_TO_TAKE_OUT_MSG)); } } else { $pdo->rollBack(); echo json_encode(array("status" => "ERROR", "code" => ERROR_GENERAL_PAYDESK_SUM, "msg" => ERROR_GENERAL_PAYDESK_SUM_MSG)); return; } } /* * User may ask what money he should have in his pocket by serving the guests. If the inserts and * take outs are in in his waiter paydesk then this value is of interest, too. Return both. */ function getCashOverviewOfUser() { $userId = $this->getUserId(); // without cash insert and cash takeout $onlyCashByGuests = 0.0; $pdo = $this->dbutils->openDbAndReturnPdo(); $sql = "SELECT sum(brutto) as sumtotal FROM %bill% WHERE closingid is null AND status is null AND paymentid=1 AND userid='$userId'"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(); $row =$stmt->fetchObject(); if ($row != null) { if ($row->sumtotal != null) { $onlyCashByGuests = $row->sumtotal; } } // with cash $cashByGuestsAndInsertTakeOut = 0.0; $sql = "SELECT sum(brutto) as sumtotal FROM %bill% WHERE closingid is null AND paymentid='1' AND userid='$userId' AND (status is null OR status ='c')"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(); $row =$stmt->fetchObject(); if ($row != null) { if ($row->sumtotal != null) { $cashByGuestsAndInsertTakeOut = $row->sumtotal; } } echo json_encode(array("guestmoney" => $onlyCashByGuests, "total" => $cashByGuestsAndInsertTakeOut)); } function getLastBillsWithContent($day,$month,$year) { date_default_timezone_set(DbUtils::getTimeZone()); $currentTime = date('Y-m-d H:i:s'); $startDate = "$year-$month-$day 00:00:00"; $endDate = "$year-$month-$day 23:59:59"; $whenClause = " (billdate >= ? AND billdate <= ?)"; // search for the bill language $pdo = $this->dbutils->openDbAndReturnPdo(); $admin = new Admin(); $genValues = $admin->getGeneralConfigItems(false, $pdo); $l = $genValues['billlanguage']; $commonUtils = new CommonUtils(); $sql = "SELECT id,billdate,brutto,tableid,closingid,status,host FROM %bill% WHERE tableid >= '0' AND $whenClause ORDER BY id DESC,billdate DESC "; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($startDate,$endDate)); $result = $stmt->fetchAll(); $resultarray = array(); foreach($result as $zeile) { $theId = $zeile['id']; if (!$commonUtils->verifyBill($pdo, $theId)) { echo json_encode(array("status" => "ERROR", "code" => ERROR_INCONSISTENT_DB, "msg" => ERROR_INCONSISTENT_DB_MSG)); return; } date_default_timezone_set(DbUtils::getTimeZone()); $date = new DateTime($zeile['billdate']); $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($pdo,$theId,$l,0), "isClosed" => $isClosed, "host" => $zeile['host'] ); $resultarray[] = $arr; } // insert also the host-html just in case it is needed $hosthtml = file_get_contents("../customer/bon-bewirtungsvorlage.html"); ob_start(); echo json_encode(array("status" => "OK", "code" => OK, "msg" => $resultarray, "hosthtml" => $hosthtml)); ob_end_flush(); } private function getUserId() { if(session_id() == '') { session_start(); } return $_SESSION['userid']; } /** * Test if it is allowed to insert new bill as storno bill or if manipulation has happened * * Returns (-1) in case of an error, a positive return value is the new id, (which is already updated in work table) */ private function testForNewBillIdAndUpdateWorkTable($pdo) { $commonUtils = new CommonUtils(); $sql = "SELECT MAX(id) as maxbillid FROM %bill%"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(); $row = $stmt->fetchObject(); $nextbillid = intval($row->maxbillid) + 1; if (!$commonUtils->verifyLastBillId($pdo, $nextbillid)) { return (-1); } else { // ok - then increment that last id in the work table $commonUtils->setLastBillIdInWorkTable($pdo, $nextbillid); return $nextbillid; } } private function changeBillHost($pdo,$billid,$isNowHost) { $sql = "SELECT host,closingid FROM %bill% WHERE id=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($billid)); $row = $stmt->fetchObject(); if ($row->host != $isNowHost) { echo json_encode(array("status" => "ERROR", "code" => ERROR_BILL_NOT_WO_HOST, "msg" => ERROR_BILL_NOT_WO_HOST_MSG)); return; } if (!is_null($row->closingid)) { echo json_encode(array("status" => "ERROR", "code" => ERROR_BILL_ALREADY_CLOSED, "msg" => ERROR_BILL_ALREADY_CLOSED_MSG)); return; } $pdo->beginTransaction(); $sql = "SELECT queueid FROM %billproducts% WHERE billid=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($billid)); $idsOfBill = $stmt->fetchAll(); $ids = array(); foreach($idsOfBill as $anId) { $ids[] = $anId["queueid"]; } $sql = "SELECT brutto,netto,tableid,paymentid,tax FROM %bill% WHERE id=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($billid)); $row = $stmt->fetchObject(); $ok = $this->cancelBill($pdo, $billid, "", "OrderSprinter-Bewirtungseigenschaft", false, false, false, 0); if (!$ok) { $pdo->rollBack(); echo json_encode(array("status" => "ERROR", "code" => ERROR_BILL_CANCEL_IMOSSIBLE, "msg" => ERROR_BILL_CANCEL_IMOSSIBLE_MSG)); return; } $this->recreateBill($pdo, $ids, $row->brutto, $row->netto, $row->tableid, $row->paymentid, $row->tax, 1-$isNowHost); $pdo->commit(); echo json_encode(array("status" => "OK", "code" => OK)); } function recreateBill($pdo,$ids_array,$brutto,$netto,$tableid,$paymentId,$tax,$host) { $userid = $this->getUserId(); // current time date_default_timezone_set(DbUtils::getTimeZone()); $currentTime = date('Y-m-d H:i:s'); $billid = (-1); // find highest bill id $sql = "SELECT id from %bill% ORDER BY id DESC"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(); $numberOfIds = $stmt->rowCount(); $row =$stmt->fetchObject(); $billid = intval($row->id)+1; $commonUtils = new CommonUtils(); $commonUtils->setLastBillIdInWorkTable($pdo, $billid); if (is_null($tableid)) { $tableid = 0; } // now calculate the signature for the bill entry $signature = $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)); $billProdsSql = "INSERT INTO `%billproducts%` (`queueid`,`billid`) VALUES ( ?,?)"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($billProdsSql)); $stmt->execute(array($queueid,$billid)); } } /* * Cancel a bill - set all queue items to not paid and drop the bill entry */ private function cancelBill($pdo,$billid,$stornocode,$reason,$doOwnTransaction,$doEcho,$checkStornoCode,$removeproducts = 0) { // current time date_default_timezone_set(DbUtils::getTimeZone()); $currentTime = date('Y-m-d H:i:s'); // check if stornocode is correct $stornocodeInDb = CommonUtils::getConfigValue($pdo, 'stornocode', null); if (is_null($stornocodeInDb)) { // stornocode not fixed if ($doEcho) { echo json_encode(array("status" => "ERROR", "code" => ERROR_BILL_NOT_STORNO_CODE, "msg" => ERROR_BILL_NOT_STORNO_CODE_MSG)); } return false; } if ($checkStornoCode) { if ($stornocode != $stornocodeInDb) { if ($doEcho) { echo json_encode(array("status" => "ERROR", "code" => ERROR_BILL_WRONG_STORNO_CODE, "msg" => ERROR_BILL_WRONG_STORNO_CODE_MSG)); } return false; } } if (!is_numeric($billid)) { // this may be an attack... if ($doEcho) { echo json_encode(array("status" => "ERROR", "code" => ERROR_BILL_WRONG_NUMERIC_VALUE, "msg" => ERROR_BILL_WRONG_NUMERIC_VALUE_MSG)); } return false; } // Do transactional cancel if ($doOwnTransaction) { $pdo->beginTransaction(); } // is the bill already closed? In this case no cancel is allowed! $sql = "SELECT brutto,netto,tax,tableid,closingid,status,paymentid FROM %bill% WHERE id=?"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($billid)); $row =$stmt->fetchObject(); $closingId = null; if ($row != null) { $closingId = $row->closingid; // save the next data for a copy! $brutto = $row->brutto; $netto = $row->netto; $tax = $row->tax; $tableid = $row->tableid; $status = $row->status; $paymentid = $row->paymentid; } if (!is_null($closingId) || ($status == 's') || ($status == 'x')) { // no cancel possible anymore! if ($doOwnTransaction) { $pdo->rollBack(); } if ($doEcho) { if (($status == 's') || ($status == 'x')) { echo json_encode(array("status" => "ERROR", "code" => ERROR_BILL_ALREADY_CANCELLED, "msg" => ERROR_BILL_ALREADY_CANCELLED_MSG)); } else { echo json_encode(array("status" => "ERROR", "code" => ERROR_BILL_ALREADY_CLOSED, "msg" => ERROR_BILL_ALREADY_CLOSED_MSG)); } } return false; } // is bill correct with signature? $commonUtils = new CommonUtils(); $correct = $commonUtils->verifyBill($pdo, $billid); if (!$correct) { if ($doOwnTransaction) { $pdo->rollBack(); } if ($doEcho) { echo json_encode(array("status" => "ERROR", "code" => ERROR_INCONSISTENT_DB, "msg" => ERROR_INCONSISTENT_DB_MSG)); } return false; } // Test if it is allowed to insert new bill as storno bill or if manipulation has happened $nextbillid = $this->testForNewBillIdAndUpdateWorkTable($pdo); if ($nextbillid < 0) { if ($doEcho) { echo json_encode(array("status" => "ERROR", "code" => ERROR_INCONSISTENT_DB, "msg" => ERROR_INCONSISTENT_DB_MSG)); } if ($doOwnTransaction) { $pdo->rollBack(); } return false; } // 0. find the queueitems that are related to that bill $sql = "SELECT id FROM %queue% WHERE billid=?"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($billid)); $result = $stmt->fetchAll(); $queueIdArray = array(); foreach($result as $row) { $queueIdArray[] = $row['id']; } // 1. clear connection between queue item and bill if ($removeproducts == 0) { $sql = "UPDATE %queue% SET paidtime=null,billid=null WHERE billid=?"; } else { $sql = "UPDATE %queue% SET ordertime=null,paidtime=null,billid=null WHERE billid=?"; } $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($billid)); // 2. copy bill with negativ brutto as part of storno $userIdOfStornoUser = $this->getUserId(); $stornval = 0.0 - floatval($brutto); $stornonettoval = 0.0 - floatval($netto); $commonUtils = new CommonUtils(); $signature = $commonUtils->calcSignatureForBill($pdo,$currentTime, $stornval, $stornonettoval, $tax, $userIdOfStornoUser); $sql = "INSERT INTO `%bill%` (`id` , `billdate`,`brutto`,`netto`,`tax`,`tableid`, `status`, `paymentid`,`userid`,`ref`,`host`,`signature`) VALUES (?,?,?,?,?,?, 's', ?,?,?,?,?)"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($nextbillid,$currentTime,$stornval,$stornonettoval,$tax,$tableid,$paymentid,$userIdOfStornoUser,$billid,0,$signature)); $refIdOfStornoEntry = $pdo->lastInsertId(); $sql = "SELECT brutto,netto,prevbrutto,prevnetto FROM %bill% WHERE id=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($refIdOfStornoEntry-1)); $row =$stmt->fetchObject(); $sql = "UPDATE %bill% set prevbrutto=?,prevnetto=? WHERE id=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($row->brutto + $row->prevbrutto + $stornval,$row->netto + $row->prevnetto + $stornonettoval,$refIdOfStornoEntry)); // 3. mark bill as part of storno $sql = "UPDATE %bill% SET status='x', closingid=null, ref=? WHERE id=?"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($refIdOfStornoEntry,$billid)); if (!is_null($reason) && ($reason != "")) { $sql = "UPDATE %bill% SET reason=? WHERE id=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($reason,$billid)); } // 4. now put the queue items into the billproducts so that later storno is evaluable foreach ($queueIdArray as $aQueueid) { $billProdsSql = "INSERT INTO `%billproducts%` (`queueid` , `billid`) VALUES ( ?,?)"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($billProdsSql)); $stmt->execute(array($aQueueid,$refIdOfStornoEntry)); } if ($doOwnTransaction) { $pdo->commit(); } // end of transactional cancel if ($doEcho) { echo json_encode(array("status" => "OK", "code" => OK)); } return true; } private function autoBackupPdfSummary($remoteaccesscode) { $pdo = DbUtils::openDbAndReturnPdoStatic(); $code = CommonUtils::getConfigValue($pdo, 'remoteaccesscode', null); if (is_null($code)) { echo "No remote access code available - backup not allowed"; return; } 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(); $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(); $lang = 0; if(isset($_GET["lang"])) { $lang = $_GET['lang']; } $pdfExport->exportPdfSummary($lang,$startMonth,$startYear,$endMonth,$endYear); } private function exportCsv($startMonth,$startYear,$endMonth,$endYear,$exportType) { $this->exportCsv_bin($startMonth,$startYear,$endMonth,$endYear,null,$exportType); } /* * Method to export data of a special closing */ private function exportCsvOfClosing($closingid,$exportFormat) { $this->exportCsv_bin(null,null,null,null,$closingid,$exportFormat); } private function getDecPoint() { $sql = "SELECT name,setting FROM %config% WHERE name=?"; $pdo = $this->dbutils->openDbAndReturnPdo(); $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array("decpoint")); $row = $stmt->fetchObject(); return($row->setting); } private function exportCsv_bin($startMonth,$startYear,$endMonth,$endYear,$onlyClosingId,$exportFormat) { if(session_id() == '') { session_start(); } $l = $_SESSION['language']; $commonUtils = new CommonUtils(); $currency = $commonUtils->getCurrency(); $decpoint = "."; $formatCode = "0.00"; if ($onlyClosingId == null) { if ($startMonth < 10) { $startMonth = "0" . $startMonth; } if ($endMonth < 10) { $endMonth = "0" . $endMonth; } $startDate = $startYear . "-" . $startMonth . "-01 00:00:00"; // now find last day of month of end date! $endDate = $endYear . "-" . $endMonth . "-01"; $lastdayOfMonth = date("t", strtotime($endDate)); $endDate = $endYear . "-" . $endMonth . "-" . $lastdayOfMonth . " 23:59:59"; } $objPHPExcel = new PHPExcel(); PHPExcel_Settings::setZipClass(PHPExcel_Settings::PCLZIP); $locale = 'De'; if ($l == 1) { $locale = 'En'; } else if ($l == 2) { $locale = 'Es'; } $validLocale = PHPExcel_Settings::setLocale($locale); $objPHPExcel->getProperties() ->setCreator("OrderSprinter") ->setLastModifiedBy($_SESSION['currentuser']) ->setTitle("OrderSprinter Umsatzdatenexport") ->setSubject("OrderSprinter Umsatzdatenexport") ->setDescription("Umsätze") ->setKeywords("OrderSprinter Umsätze") ->setCategory("OrderSprinter Datenexport"); $objWorksheet = $objPHPExcel->getActiveSheet(); $allcells = array(); $firstRow = array( $this->t['ID'][$l], $this->t['Date'][$l], $this->t['Brutto'][$l] ."($currency)", $this->t['Netto'][$l] . "($currency)", $this->t['State'][$l], $this->t['Ref'][$l], $this->t['host'][$l], $this->t['reason'][$l], $this->t['Userid'][$l], $this->t['User'][$l]); if ($onlyClosingId == null) { $firstRow[] = $this->t['ClosId'][$l]; $firstRow[] = $this->t['ClosDate'][$l]; $firstRow[] = $this->t['PayWay'][$l]; $firstRow[] = $this->t['ClosRemark'][$l]; } else { // closing id is know - do not output unnecessary info $firstRow[] = $this->t['PayWay'][$l]; } $lineLength = count($firstRow); $allcells[] = $firstRow; $billIdsForThatClosing = array(); $payment_lang = array("name","name_en","name_esp"); $payment_col = $payment_lang[$l]; $pdo = DbUtils::openDbAndReturnPdoStatic(); $sql = "SELECT DISTINCT %bill%.id,%bill%.signature,billdate,brutto,netto,IF(tax is not null, tax, '0.00') as tax,status,closingdate,remark,%bill%.host,%bill%.closingid,%payment%.$payment_col as payway,userid,ref,username,IF(%bill%.reason is not null,reason,'') as reason FROM %bill%,%closing%,%payment%,%user% "; $sql .= "WHERE closingid is not null AND %bill%.closingid=%closing%.id "; $sql .= " AND %bill%.paymentid=%payment%.id "; if ($onlyClosingId == null) { // search for time span $sql .= " AND %bill%.billdate BETWEEN ? AND ? "; } else { // search for a special closing id $sql .= " AND closingid=? "; } $sql .= " AND %bill%.userid = %user%.id "; $sql .= "ORDER BY billdate"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); if ($onlyClosingId == null) { $stmt->execute(array($startDate,$endDate)); } else { $stmt->execute(array($onlyClosingId)); } $dbresult = $stmt->fetchAll(); foreach($dbresult as $zeile) { $billid = $zeile['id']; $billdate = $zeile['billdate']; $brutto_orig = $zeile['brutto']; $netto_orig = $zeile['netto']; $tax_orig = $zeile['tax']; $brutto = str_replace(".",$decpoint,$brutto_orig); $netto = str_replace(".",$decpoint,$netto_orig); $tax = str_replace(".",$decpoint,$tax_orig); $signature = $zeile['signature']; $status = $zeile['status']; if ($status == 'x') { $status = $this->t["laterCancelled"][$l]; } else if ($status == 's') { $status = $this->t["storno"][$l]; } else if ($status == 'c') { $status = $this->t["cashact"][$l]; } else { $status = ""; } $ref = ($zeile['ref'] == null ? "" : $zeile['ref']); $userid = $zeile['userid']; $username = $zeile['username']; $closingid = $zeile['closingid']; $closingdate = $zeile['closingdate']; $remark = $zeile['remark']; $paymentname = $zeile['payway']; $host = ($zeile['host'] == 1 ? "x" : "-"); $reason = $zeile['reason']; if (!$commonUtils->verifyBillByValues(null,$billdate, $brutto_orig, $netto_orig, $tax_orig, $userid, $signature)) { echo "Inconsistent Data Base Content!\n"; return; } if ($billid == null) { $billid = "-"; } if ($onlyClosingId == null) { $line = array($billid , $billdate, $brutto, $netto, $status, $ref, $host, $reason, $userid,$username , $closingid, $closingdate, $paymentname, $remark); } else { $line = array($billid , $billdate, $brutto, $netto, $status, $ref, $host, $reason, $userid,$username , $paymentname); } $allcells[] = $line; } $objWorksheet->fromArray( $allcells, // The data to set NULL, // Array values with this value will not be set 'A1' // Top left coordinate of the worksheet range where ); $lastChar = chr(ord('A') + $lineLength - 1); $range = "A1:$lastChar" . "1"; $objWorksheet->getStyle($range)->getFill() ->setFillType(PHPExcel_Style_Fill::FILL_SOLID) ->getStartColor()->setARGB('FFadf6aa'); $range = "A2:" . $lastChar . count($allcells); $objWorksheet->getStyle($range)->getFill() ->setFillType(PHPExcel_Style_Fill::FILL_SOLID) ->getStartColor()->setARGB('FFd6edf8'); for ($i=1;$igetCell('C' . ($i+1)) ->getValue(); $objWorksheet->getCell('C' . ($i+1)) ->setValueExplicit($aVal,PHPExcel_Cell_DataType::TYPE_NUMERIC); $objWorksheet->getStyle('C' . ($i+1))->getNumberFormat()->setFormatCode($formatCode); $aVal = $objWorksheet->getCell('D' . ($i+1)) ->getValue(); $objWorksheet->getCell('D' . ($i+1)) ->setValueExplicit($aVal,PHPExcel_Cell_DataType::TYPE_NUMERIC); $objWorksheet->getStyle('D' . ($i+1))->getNumberFormat()->setFormatCode($formatCode); } if ($exportFormat == DO_CSV) { header("Content-type: text/x-csv"); header("Content-Disposition: attachment; filename=\"ordersprinter-datenexport.csv\""); header("Cache-Control: max-age=0"); $objWriter = new PHPExcel_Writer_CSV($objPHPExcel); $objWriter->setDelimiter(';'); } else { header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); header("Content-Disposition: attachment; filename=\"ordersprinter-datenexport.xls\""); header("Cache-Control: max-age=0"); $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); } $objWriter->save("php://output"); $objPHPExcel->disconnectWorksheets(); unset($objPHPExcel); } } ?>