dbutils = new DbUtils(); require_once 'translations.php'; } function handleCommand($command) { // all commands require closing,manager or admin rights if (!($this->hasCurrentUserManagerOrAdminRights()) && ($command != 'createClosing') && ($command != 'getClosings') && ($command != 'remotecreateclosing')) { if ($command != 'exportCsv') { echo json_encode(array("status" => "ERROR", "code" => ERROR_MANAGER_NOT_AUTHOTRIZED, "msg" => ERROR_MANAGER_NOT_AUTHOTRIZED_MSG)); } else { // exception - result is not handled on HTML/JS side echo "Fehlende Benutzerrechte"; } return; } // user has manager rights if($command == 'createClosing') { $this->createClosing($_POST['remark'],$_POST['print']); } else if ($command == 'remotecreateclosing') { if (isset($_POST['remoteaccesscode'])) { if (isset($_POST['remark'])) { $this->remotecreateclosing($_POST['remoteaccesscode'],$_POST['remark']); } else { $this->remotecreateclosing($_POST['remoteaccesscode'],''); } } else { echo json_encode("Remote access code not given"); } return; } else if ($command == 'getClosings') { $this->getClosings($_GET['month'], $_GET['year']); } else if ($command == 'exportCsv') { $this->exportCsv($_GET['closingid']); } else if ($command == 'exportGuestCsv') { $this->exportGuestCsv($_GET['closingid']); } else if ($command == 'emailCsv') { $this->emailCsv($_GET['closingid'],$_GET['emailaddress'],$_GET['topic']); } else if ($command == 'getClosing') { $this->getClosing($_GET['closingid']); } else if ($command == 'getClosingSummary') { $this->getClosingSummary($_GET['closingid'],null,true); } else { echo "Command not supported."; } } private function hasCurrentUserManagerOrAdminRights() { session_start(); if (!isset($_SESSION['angemeldet']) || !$_SESSION['angemeldet']) { // no user logged in return false; } else { return ($_SESSION['right_manager'] || $_SESSION['is_admin']); } } 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 saveLastClosingCreation($pdo) { date_default_timezone_set(DbUtils::getTimeZone()); $date = new DateTime(); $unixTimeStamp = $date->getTimestamp(); $sql = "SELECT count(id) as countid FROM %work% WHERE item=?"; $row = CommonUtils::getRowSqlObject($pdo, $sql, array('lastclosing')); if ($row->countid == 0) { $sql = "INSERT INTO %work% (item,value,signature) VALUES(?,?,?)"; CommonUtils::execSql($pdo, $sql, array('lastclosing', $unixTimeStamp, null)); } else { $sql = "UPDATE %work% SET value=? WHERE item=?"; CommonUtils::execSql($pdo, $sql, array($unixTimeStamp, 'lastclosing')); } } private function isClosingAllowed($pdo) { $TIMEOUT = 120; $sql = "SELECT count(id) as countid FROM %work% WHERE item=?"; $row = CommonUtils::getRowSqlObject($pdo, $sql, array('lastclosing')); if ($row->countid == 0) { return true; } else { $sql = "SELECT value FROM %work% WHERE item=?"; $row = CommonUtils::getRowSqlObject($pdo, $sql, array('lastclosing')); $lastaccess = $row->value; date_default_timezone_set(DbUtils::getTimeZone()); $date = new DateTime(); $currentTimeStamp = $date->getTimestamp(); if (($currentTimeStamp - $lastaccess) > $TIMEOUT) { return true; } else { return false; } } } private function remotecreateclosing($remoteaccesscode,$remark) { $pdo = DbUtils::openDbAndReturnPdoStatic(); $code = CommonUtils::getConfigValue($pdo, 'remoteaccesscode', null); if (is_null($code) || ($code == '')) { echo json_encode("Remote access code was not configured!"); } else { if (md5($remoteaccesscode) == $code) { $this->createClosing($remark,0); } else { echo json_encode("Remote access code not correct!"); } } } private function createClosing ($remark,$doPrint = 1) { set_time_limit(60*60); if (is_null($remark)) { $remark = ""; } $decpoint = $this->getDecPoint(); // first create a closing entry date_default_timezone_set(DbUtils::getTimeZone()); $closingTime = date('Y-m-d H:i:s'); $pdo = DbUtils::openDbAndReturnPdoStatic(); if (!$this->isClosingAllowed($pdo)) { echo json_encode(array("status" => "ERROR", "msg" => "Time between closings too short", "code" => ERROR_CLOSING_TIME_LIMIT)); return; } $pdo->beginTransaction(); $this->saveLastClosingCreation($pdo); if (CommonUtils::callPlugin($pdo, "createClosing", "replace")) { return; } CommonUtils::callPlugin($pdo, "createClosing", "before"); CommonUtils::execSql($pdo, 'DELETE FROM %recordsqueue%', null); CommonUtils::execSql($pdo, 'DELETE FROM %records%', null); $closingEntrySql = "INSERT INTO `%closing%` (`id` , `closingdate`,`remark`,`billcount`,`billsum`,`signature`) VALUES (NULL ,?,?,?,?,?)"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($closingEntrySql)); $stmt->execute(array($closingTime,$remark,0,0.0,null)); $newClosingId = $pdo->lastInsertId(); // test for consistency of bills $sql = "SELECT id FROM %bill% WHERE closingid is null AND (tableid >= '0' OR status='c') "; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(); $result = $stmt->fetchAll(); $utils = new CommonUtils(); $ok = true; foreach($result as $row) { $aBillId = $row['id']; if (!$utils->verifyBill($pdo, $aBillId)) { $ok=false; break; } } if (!$ok) { echo json_encode(array("status" => "ERROR", "code" => ERROR_INCONSISTENT_DB, "msg" => ERROR_INCONSISTENT_DB_MSG)); return; } // declare not closed bills as closed $declareClosedSql = "UPDATE %bill% SET closingid='$newClosingId' WHERE closingid is null AND (tableid >= '0' OR status='c') "; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($declareClosedSql)); $stmt->execute(); $sql ="SELECT count(id) as billstotake FROM %bill% WHERE closingid=? AND (tableid >= '0' OR status='c')"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($newClosingId)); $row = $stmt->fetchObject(); $billsToTake = $row->billstotake; $pricesum = null; // now calculate the sum of the prices of this closing if ($billsToTake > 0) { $sql = "SELECT sum(brutto) as pricesum FROM %bill% WHERE closingid=? AND (tableid >= '0' OR status='c')"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($newClosingId)); $row = $stmt->fetchObject(); $pricesum = $row->pricesum; } if (is_null($pricesum)) { $pricesum = 0; } $prevClosingDate = self::getDateOfPreviousClosing($pdo,$newClosingId); if (is_null($prevClosingDate)) { $prevClosingDate = ""; } // sign the date $pricesumstr = number_format($pricesum, 2, ".", ''); $data = "I($newClosingId)-S($prevClosingDate)-E($closingTime)-D($billsToTake)-S($pricesumstr)"; $pkeyid = $utils->getPrivkey($pdo); openssl_sign($data, $signature, $pkeyid); openssl_free_key($pkeyid); // now add values to closing table to prepare for electronic signature $sql = "UPDATE %closing% SET billcount=?, billsum=?,signature=? WHERE id=?"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($billsToTake,$pricesum,$signature,$newClosingId)); $sql = "DELETE FROM %queue% WHERE id not in (select distinct queueid FROM %billproducts%) AND billid is null"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(); $sql = "UPDATE %queue% set paidtime=?,delivertime=? WHERE billid is not null AND paidtime is null"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($closingTime,$closingTime)); $sql = "UPDATE %queue% set delivertime=?,workprinted=? WHERE billid is not null AND delivertime IS NULL"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($closingTime,1)); $sql = "DELETE FROM %printjobs%"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(); $sql = "UPDATE %queue% SET isclosed=?"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array(1)); $dblogging = CommonUtils::getConfigValue($pdo, 'dblog', 1); if ($dblogging == 0) { $sql = "DELETE FROM %log%"; CommonUtils::execSql($pdo, $sql, null); } workreceipts::resetWorkReceiptId($pdo); // commit must before email, because there direct access to db happens $pdo->commit(); // now send the email $toEmail = $this->getGeneralItemFromDbWithPdo($pdo,"receiveremail"); if (($toEmail != '') && (strpos($toEmail,'@') !== false)) { $theSum = number_format($pricesum, 2, $decpoint, ''); $this->emailCsvCore($pdo,$newClosingId, $toEmail, "Tagesabschluss",$prevClosingDate,$closingTime,$theSum,$billsToTake); } $admin = new Admin(); $versionInfo = $admin->getEnv($pdo); $content = array("env" => $versionInfo,"result" => $pricesum, "closingid" => $newClosingId); // check if new version is evailable // (do not inform user if last install or update is right before new version - let new version mature a bit..) $url = "http://www.ordersprinter.de/version/checkversion.php?"; $url .= "v=" .$versionInfo["version"] . "&i=" . $versionInfo["installdate"] . "l=" . $versionInfo["lastupdate"]; $ctx = stream_context_create(array('http'=> array( 'timeout' => 5, // 5 seconds ) )); $newversionavailable = @file_get_contents($url, false, $ctx); // TODO: has to be forwarded to user to inform him CommonUtils::keepOnlyLastLog($pdo); // call plugin after completion of closing CommonUtils::callPlugin($pdo, "createClosing", "after"); echo json_encode(array("status" => "OK", "msg" => $content, "print" => $doPrint)); } private function getSumOfBillsWithClosingId($pdo,$closingid,$onlyBar) { $sql = "SELECT count(id) as countid FROM %bill% WHERE closingid=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($closingid)); $row = $stmt->fetchObject(); if ($row->countid == 0) { return 0.0; } $sql = "SELECT sum(brutto) as billsum FROM %bill% WHERE closingid=?"; if ($onlyBar) { $sql .= " AND paymentid='1'"; } $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($closingid)); $row = $stmt->fetchObject(); $sum = floatval($row->billsum); return $sum; } private function getUserGroupedSumOfClosing($pdo,$closingid) { $sql = "SELECT userid,username,"; $sql .= "ROUND(sum(brutto),2) as billsumall,"; $sql .= "ROUND(sum(if(paymentid='1',brutto,'0.00')),2) as sumonlybar,"; $sql .= "ROUND(sum(if(status = 'c',brutto,'0.00')),2) as sumcash "; $sql .= "FROM %bill%,%user% WHERE userid=%user%.id AND closingid=? GROUP BY userid,username"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($closingid)); $result = $stmt->fetchAll(); return $result; } private function getTaxesGroupedOfClosing($pdo,$closingid) { $sql = "SELECT %queue%.tax as tax,SUM(price) as brutto,ROUND(SUM(price)/(1 + %queue%.tax/100.0),2) as netto FROM %queue%,%bill%,%closing% "; $sql .= " WHERE billid=%bill%.id AND %bill%.closingid=%closing%.id AND closingid=? GROUP BY tax"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($closingid)); return ($stmt->fetchAll(PDO::FETCH_OBJ)); } private function getCashOpsOfClosing($pdo,$closingid) { $sql = "SELECT SUM(brutto) as cashsum FROM %bill%,%closing% WHERE status=? AND closingid=%closing%.id AND closingid=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array('c',$closingid)); $row = $stmt->fetchObject(); return ($row->cashsum); } /* * Get all closings that are requested: * if month and year is null or empty ==> last 30 closings * otherwise query by date */ private function getClosings($month, $year) { $pdo = DbUtils::openDbAndReturnPdoStatic(); date_default_timezone_set(DbUtils::getTimeZone()); $monthText=$month; if ($month < 10) { $monthText = "0" . $month; } $lastDayInMonth = date("t", mktime(0, 0, 0, $month, 1, $year)); $dateStart = $year . $monthText . "01"; $dateEnd = $year . $monthText . $lastDayInMonth; $sql = "SELECT id,closingdate,remark FROM %closing% WHERE DATE(closingdate) BETWEEN ? AND ? ORDER BY closingdate DESC;"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($dateStart,$dateEnd)); $result = $stmt->fetchAll(); $resultarray = array(); foreach($result as $zeile) { $theId = $zeile['id']; $closingDate = $zeile['closingdate']; $remark = $zeile['remark']; $totalSum = $this->getSumOfBillsWithClosingId($pdo,$theId, false); $cashSum = $this->getSumOfBillsWithClosingId($pdo,$theId, true); $userSums = $this->getUserGroupedSumOfClosing($pdo, $theId); $taxessums = $this->getTaxesGroupedOfClosing($pdo,$theId); $cashops = $this->getCashOpsOfClosing($pdo,$theId); $daynameno = date('N', strtotime($closingDate)); $closingEntry = array("id" => $theId, "closingDate" => $closingDate, "daynameno" => $daynameno, "remark" => $remark, "totalsum" => $totalSum, "cashsum" => $cashSum, "usersums" => $userSums, "taxessums" => $taxessums,"cashops" => $cashops); $resultarray[] = $closingEntry; } echo json_encode(array("status" => "OK", "msg" => $resultarray)); } private function getPaymentArray($pdo) { $sql = "SELECT id,name FROM %payment%"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(); $result = $stmt->fetchAll(); $retArray = array(); foreach($result as $zeile) { $retArray[$zeile['id']] = $zeile['name']; } return $retArray; } private function getClosing($closingid) { $pdo = DbUtils::openDbAndReturnPdoStatic(); $this->retrieveClosingFromDb($pdo,$closingid, false, false); } private function exportCsv($closingid) { $pdo = DbUtils::openDbAndReturnPdoStatic(); $this->retrieveClosingFromDb($pdo,$closingid, true, false); } private function exportGuestCsv($closingid) { $pdo = DbUtils::openDbAndReturnPdoStatic(); $prevClosingDate = self::getDateOfPreviousClosing($pdo,$closingid); $sql = "SELECT closingdate FROM %closing% WHERE id=?"; $curClosingDateRow = CommonUtils::getRowSqlObject($pdo, $sql, array($closingid)); $curClosingDate = $curClosingDateRow->closingdate; Customers::exportLog($pdo, $prevClosingDate, $curClosingDate); } private function emailCsvCore($pdo,$closingid,$toEmail,$topic,$startdate,$enddate,$billsum,$billcount) { $msg = $this->getClosingByTaxAndUser($pdo,$closingid); $msg .= $this->retrieveClosingFromDb($pdo,$closingid, false, true); $msg = "Zeitraum: $startdate - $enddate\nBrutto-Summe: $billsum\nEnthaltene Bons: $billcount\n\n" . $msg; $msg = str_replace("\n", "\r\n", $msg); $topictxt = $topic . " " . $closingid . "\r\n"; if (Emailer::sendEmail($pdo, $msg, $toEmail, $topictxt)) { return true; } else { return false; } } private function emailCsv($closingid,$toEmail,$topic) { // additional info to insert into email $decpoint = $this->getDecPoint(); $pdo = $this->dbutils->openDbAndReturnPdo(); $prevClosingDate = self::getDateOfPreviousClosing($pdo,$closingid); if (is_null($prevClosingDate)) { $prevClosingDate = ""; } $sql = "SELECT closingdate, billcount, billsum FROM %closing% WHERE id=?"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($closingid)); $row = $stmt->fetchObject(); $billsum = number_format($row->billsum, 2, $decpoint, ''); $billcount = $row->billcount; $closdate = $row->closingdate; if ($this->emailCsvCore($pdo,$closingid, $toEmail, $topic, $prevClosingDate,$closdate,$billsum,$billcount)) { echo json_encode(array("status" => "OK")); } else { echo json_encode(array("status" => "ERROR", "code" => ERROR_EMAIL_FAILURE, "msg" => ERROR_EMAIL_FAILURE_MSG)); } } private function getGeneralItemFromDb($field) { $pdo = $this->dbutils->openDbAndReturnPdo(); $this->getGeneralItemFromDbWithPdo($pdo, $field); } private function getGeneralItemFromDbWithPdo($pdo,$field) { if (is_null($pdo)) { $pdo = $this->dbutils->openDbAndReturnPdo(); } $aValue=""; $sql = "SELECT setting FROM %config% where name='$field'"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(); $row =$stmt->fetchObject(); if ($row != null) { $aValue = $row->setting; } return $aValue; } public static function getDateOfPreviousClosing($pdoval,$closingid) { if (is_null($pdoval)) { $pdo = DbUtils::openDbAndReturnPdoStatic(); } else { $pdo = $pdoval; } // ids can be generated but not used in case of rollback $sql = "SELECT MAX(id) as previousid FROM %closing% WHERE idprepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($closingid)); $row =$stmt->fetchObject(); if ($row != null) { $previousId = intval($row->previousid); $sql = "SELECT closingdate FROM %closing% WHERE id=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($previousId)); $row =$stmt->fetchObject(); if ($row != null) { return $row->closingdate; } else { return null; } } else { return null; } } private function returnErrorInconsDB($doCsvExport,$onlyresultreturn) { if ($doCsvExport) { echo "ERROR - signatures do not fit"; } else if ($onlyresultreturn) { return "Tagesabschluss-Datum: $closingdate\nBemerkung: $remark\nStatus: Inkonsistente Datenbank\n\ncsv-Daten:\n" . $csv; } else { echo json_encode(array("status" => "ERROR", "code" => ERROR_INCONSISTENT_DB, "msg" => ERROR_INCONSISTENT_DB_MSG)); } } private function getClosingByTaxAndUser($pdo,$closingid) { $sql = "SELECT sum(price) as sumprice,%queue%.tax as thetax,username "; $sql .= "FROM %bill%,%billproducts%,%queue%,%user% "; $sql .= "WHERE %billproducts%.billid=%bill%.id AND %bill%.closingid=? AND %bill%.userid=%user%.id AND %billproducts%.queueid=%queue%.id "; $sql .= "AND (%bill%.status is null OR %bill%.status != (? OR ? OR ?)) "; $sql .= "GROUP BY username,thetax "; $decpoint = CommonUtils::getConfigValue($pdo, "decpoint", ","); $result = CommonUtils::fetchSqlAll($pdo, $sql, array($closingid,'c','x','s')); $count = count($result); if ($count == 0) { return ""; } else { $msg = "Umsätze aufgeschlüsselt nach Benutzer und Steuersatz (ohne Ein-/Auslagen):\n\n"; $msg .= "Benutzer;Steuersatz;Umsatz (Brutto)\n"; foreach($result as $res) { // sumprice | thetax | username $tax = str_replace('.', $decpoint, $res['thetax']); $sumprice = str_replace('.', $decpoint, $res['sumprice']); $msg .= $res['username'] . ";$tax;$sumprice\n"; } return $msg . "\n"; } } private function retrieveClosingFromDb($pdo,$closingid,$doCsvExport,$onlyresultreturn) { if(session_id() == '') { session_start(); } $l = $_SESSION['language']; $commonUtils = new CommonUtils(); $currency = $commonUtils->getCurrency(); $decpoint = $this->getDecPoint(); $paymentArray = $this->getPaymentArray($pdo); $previousClosingDate = self::getDateOfPreviousClosing(null,$closingid); $csv = ""; if ($doCsvExport || $onlyresultreturn) { $file_name = "tagesabschluss.csv"; header("Content-type: text/x-csv"); header("Content-Disposition: attachment; filename=$file_name"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Pragma: no-cache"); header("Expires: 0"); $csv .= $this->t['ID'][$l] . ";" . $this->t['Date'][$l] . ";" . $this->t['Tablename'][$l] . ";" . $this->t['Prod'][$l] . ";" . $this->t['Option'][$l] . ";" . $this->t['Brutto'][$l] . "($currency);"; $csv .= $this->t['Netto'][$l] . "($currency);"; $csv .= $this->t['Tax'][$l] . ";"; $csv .= $this->t['PayWay'][$l] . ";"; $csv .= $this->t['Userid'][$l] . ";"; $csv .= $this->t['User'][$l] . ";"; $csv .= $this->t['State'][$l] . ";"; $csv .= $this->t['Ref'][$l] . "\n"; } $sql = "SELECT closingdate,remark,signature,billsum,billcount FROM %closing% WHERE id=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($closingid)); $row = $stmt->fetchObject(); $closingdate = $row->closingdate; $remark = $row->remark; $billsum = $row->billsum; $billcount = $row->billcount; $signature = $row->signature; $sql = "SELECT %bill%.id as id,IF(tableid > '0',(SELECT tableno FROM %resttables% WHERE id=tableid),'') as tablename,paymentid,billdate,userid,ref,username,status,brutto,netto,IF(tax is not null, tax, '0.00') as tax FROM %bill%,%user% WHERE closingid=? AND %bill%.userid = %user%.id ORDER BY billdate"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($closingid)); $billIdsAndPaymentsForThatClosing = $stmt->fetchAll(); $foundBillCount = count($billIdsAndPaymentsForThatClosing); if (is_null($previousClosingDate)) { $startDate = ""; } else { $startDate = $previousClosingDate; } $billsumstr = number_format($billsum, 2, ".", ''); $data = "I($closingid)-S($startDate)-E($closingdate)-D($billcount)-S($billsumstr)"; $pubkeyid = $commonUtils->getCert($pdo); $ok = openssl_verify($data, $signature, $pubkeyid); openssl_free_key($pubkeyid); if (($ok == 0) || ($billcount <> $foundBillCount)) { // something went wrong! $this->returnErrorInconsDB($doCsvExport, $onlyresultreturn); return; } $retValues = array(); for ($index=0;$index < count($billIdsAndPaymentsForThatClosing);$index++) { $aBillId = $billIdsAndPaymentsForThatClosing[$index]['id']; if (!$commonUtils->verifyBill($pdo, $aBillId)) { $this->returnErrorInconsDB($doCsvExport, $onlyresultreturn); return; } $tablename = $billIdsAndPaymentsForThatClosing[$index]['tablename']; $billdate = $billIdsAndPaymentsForThatClosing[$index]['billdate']; $paymentid = $billIdsAndPaymentsForThatClosing[$index]['paymentid']; $userid = $billIdsAndPaymentsForThatClosing[$index]['userid']; $username = $billIdsAndPaymentsForThatClosing[$index]['username']; $status = $billIdsAndPaymentsForThatClosing[$index]['status']; $brutto = $billIdsAndPaymentsForThatClosing[$index]['brutto']; $netto = $billIdsAndPaymentsForThatClosing[$index]['netto']; $tax = $billIdsAndPaymentsForThatClosing[$index]['tax']; $ref = $billIdsAndPaymentsForThatClosing[$index]['ref']; $ref = ($ref == null ? "" : $ref); if ($status == 'c') { $statusTxt = $this->t['cashact'][$l]; // "Bareinlage/-entnahme"; $brutto = number_format($brutto, 2, $decpoint, ''); $netto = number_format($netto, 2, $decpoint, ''); $tax = number_format($tax, 2, $decpoint, ''); $retValues[] = array ( "billid" => $aBillId, "tablename" => '', "paidtime" => $billdate, "productname" => $this->t['cashaction'][$l], // Kassenaktion "option" => '', "price" => $brutto, "netto" => $netto, "tax" => number_format(0.00, 2, $decpoint, ''), "payment" => $paymentArray[$paymentid], "userid" => $userid, "username" => $username, "status" => $statusTxt, "ref" => $ref); if ($doCsvExport || $onlyresultreturn) { $csv .= "$aBillId; \"$billdate\" ; \"$tablename\" ; \"" . $this->t['cashaction'][$l] . "\" ; \"$brutto\" ; \"$netto\" ; \"$tax\" ; \"$paymentArray[$paymentid]\";$userid; \"$username\"; \"$statusTxt\"; $ref\n"; } } else { $sql = "SELECT DISTINCT productname,price,%queue%.tax as tax,anoption FROM %queue%,%billproducts% WHERE %billproducts%.billid=? AND %billproducts%.queueid=%queue%.id"; if ($status == 'x') { $statusTxt = $this->t["laterCancelled"][$l]; } else if ($status == 's') { $statusTxt = $this->t["storno"][$l]; } else { $statusTxt = ""; $sql = "SELECT productname,anoption,paidtime,price,tax FROM %queue% WHERE billid=?"; } $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($aBillId)); $result = $stmt->fetchAll(); foreach ($result as $zeile) { $productname = $zeile['productname']; $option = $zeile['anoption']; $tax = $zeile['tax']; $paidtime = ($billdate == null ? "" : $billdate) ; $price = ($status == 's' ? 0.0-floatval($zeile['price']) : $zeile['price']); $netto = $price/(1 + $tax/100.0); $netto = number_format($netto, 2, $decpoint, ''); $price = number_format($price, 2, $decpoint, ''); $formattedtax = number_format($tax, 2, $decpoint, ''); $retValues[] = array ( "billid" => $aBillId, "tablename" => $tablename, "paidtime" => $paidtime, "productname" => $productname, "option" => $option, "price" => $price, "netto" => $netto, "tax" => $formattedtax, "payment" => $paymentArray[$paymentid], "userid" => $userid, "username" => $username, "status" => $statusTxt, "ref" => $ref); $productname = str_replace('"','""',$productname); $option = str_replace('"','""',$option); if ($doCsvExport || $onlyresultreturn) { $csv .= "$aBillId; \"$paidtime\" ; \"$tablename\" ; \"$productname\" ; \"$option\" ; \"$price\" ; \"$netto\" ; \"$formattedtax\" ; \"$paymentArray[$paymentid]\"; $userid; \"$username\"; \"$statusTxt\"; $ref\n"; } } } } if ($doCsvExport) { echo $csv; } else if ($onlyresultreturn) { return "Tagesabschluss-Datum: $closingdate\nBemerkung: $remark\n\ncsv-Daten:\n" . $csv; } else { echo json_encode(array("status" => "OK", "msg" => $retValues, "closingid" => $closingid, "closingdate" => $closingdate, "previousClosingDate" => $previousClosingDate)); } } public function getClosingSummaryWoSign($closingid,$pdo,$fromWeb,$fl=0) { return $this->getClosingSummaryCore($closingid, $pdo, $fromWeb, false,$fl); } public function getClosingSummary($closingid,$pdo,$fromWeb,$fl=0) { return $this->getClosingSummaryCore($closingid, $pdo, $fromWeb, true,$fl); } public static function checkForClosingConsistency($pdo,$closingid) { $sql = "select id,closingdate,billcount,billsum,remark,signature from %closing% where id=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($closingid)); $closingpart = $stmt->fetchObject(); $previousClosingDate = self::getDateOfPreviousClosing($pdo,$closingid); if (is_null($previousClosingDate)) { $startDate = ""; } else { $startDate = $previousClosingDate; } $billsumstr = number_format($closingpart->billsum, 2, ".", ''); $billcount = $closingpart->billcount; $closingdate = $closingpart->closingdate; $data = "I($closingid)-S($startDate)-E($closingdate)-D($billcount)-S($billsumstr)"; $commonUtils = new CommonUtils(); $pubkeyid = $commonUtils->getCert($pdo); $ok = openssl_verify($data, $closingpart->signature, $pubkeyid); openssl_free_key($pubkeyid); return $ok; } public function getClosingSummaryCore($closingid,$pdo,$fromWeb,$exportSignature,$fl=0) { if(is_null($pdo)) { $pdo = $this->dbutils->openDbAndReturnPdo(); }; $sql = "select id,closingdate,billcount,billsum,remark,signature from %closing% where id=?"; $stmt = $pdo->prepare(DbUtils::substTableAlias($sql)); $stmt->execute(array($closingid)); $closingpart = $stmt->fetchObject(); $ok = self::checkForClosingConsistency($pdo, $closingid); if (($ok == 0)) { if ($fromWeb) { echo json_encode(array("status" => "ERROR", "code" => ERROR_INCONSISTENT_DB, "msg" => ERROR_INCONSISTENT_DB_MSG)); return; } else { return null; } } $sql = "select sum(%bill%.brutto) as sum,round(sum(%bill%.netto),2) as netto,%payment%.name,%bill%.status from %bill%,%payment% where "; $sql .= "%bill%.closingid=? and "; $sql .= "%bill%.paymentid=%payment%.id "; $sql .= "group by %bill%.tax,%payment%.name,%bill%.status"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($closingid)); $overview = $stmt->fetchAll(PDO::FETCH_ASSOC); $sql = "select %queue%.tax as t,SUM(%queue%.price) as bruttosum,ROUND(SUM(%queue%.price)/(1 + %queue%.tax/100.0),2) as nettosum "; $sql .= " FROM %bill%,%queue% "; $sql .= " WHERE %bill%.closingid=? AND %queue%.billid=%bill%.id GROUP BY t"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($closingid)); $taxessum = $stmt->fetchAll(PDO::FETCH_ASSOC); $sql = "SELECT DISTINCT paymentid,name FROM %bill%,%payment% WHERE %bill%.closingid=? AND %bill%.paymentid=%payment%.id"; $payments = CommonUtils::fetchSqlAll($pdo, $sql, array($closingid)); $paymenttaxes = array(); foreach($payments as $aPayment) { $sql = "select %queue%.tax as t,SUM(%queue%.price) as bruttosum,ROUND(SUM(%queue%.price)/(1 + %queue%.tax/100.0),2) as nettosum "; $sql .= " FROM %bill%,%queue% "; $sql .= " WHERE %bill%.closingid=? AND %queue%.billid=%bill%.id AND %bill%.paymentid=? GROUP BY t"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($closingid,$aPayment["paymentid"])); $paymenttaxessum = $stmt->fetchAll(PDO::FETCH_ASSOC); $paymenttaxes[] = array("payment" => $aPayment["name"],"paymenttaxessum" => $paymenttaxessum); } $sql = "select count(%queue%.productname) as count,%queue%.productname,%queue%.price,%queue%.tax as tax,sum(%queue%.price) as sumprice "; $sql .= " from %queue%,%bill% where "; $sql .= "%queue%.billid=%bill%.id AND %bill%.closingid=? AND "; $sql .= "%bill%.status is null "; $sql .= "group by %queue%.productname,%queue%.tax,%queue%.price"; $stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql)); $stmt->execute(array($closingid)); $details = $stmt->fetchAll(PDO::FETCH_ASSOC); // -> returns something like this: if (!$exportSignature || $fromWeb) { unset($closingpart->signature); } if ($fl >= 8) { $closshowci = CommonUtils::getConfigValue($pdo, 'closshowci', 1); $closshowpaytaxes = CommonUtils::getConfigValue($pdo, 'closshowpaytaxes', 1); $closshowprods = CommonUtils::getConfigValue($pdo, 'closshowprods', 1); $companyinfo = CommonUtils::getConfigValue($pdo, 'companyinfo', ''); $retVal = array("closing" => $closingpart, "overview" => $overview, "details" => $details, "taxessum" => $taxessum, "companyinfo" => $companyinfo, "paymenttaxessum" => $paymenttaxes, "closshowci" => $closshowci, "closshowpaytaxes" => $closshowpaytaxes, "closshowprods" => $closshowprods, ); } else if ($fl >= 3) { $retVal = array("closing" => $closingpart, "overview" => $overview, "details" => $details, "taxessum" => $taxessum); } else { $retVal = array("closing" => $closingpart, "overview" => $overview, "details" => $details); } if ($fromWeb) { echo json_encode(array("status" => "OK", "msg" => $retVal)); } else { return $retVal; } } }