ordersprinter/webapp/php/closing.php

900 lines
31 KiB
PHP

<?php
// Datenbank-Verbindungsparameter
require_once ('dbutils.php');
require_once ('commonutils.php');
require_once ('globals.php');
require_once ('admin.php');
require_once ('customers.php');
require_once ('utilities/Emailer.php');
class Closing {
var $dbutils;
var $t;
function __construct() {
$this->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 if ($command == 'htmlreport') {
$this->htmlreport($_GET["closid"]);
} 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%` (`closingdate`,`remark`,`billcount`,`billsum`,`signature`) VALUES (?,?,?,?,?)";
CommonUtils::execSql($pdo, $closingEntrySql, 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
$sql = "UPDATE %bill% SET closingid='$newClosingId' WHERE closingid is null AND (tableid >= '0' OR status='c') ";
CommonUtils::execSql($pdo, $sql, null);
$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)";
$signature = md5($data);
// now add values to closing table to prepare for electronic signature
$sql = "UPDATE %closing% SET billcount=?, billsum=?,signature=? WHERE id=?";
CommonUtils::execSql($pdo, $sql, array($billsToTake,$pricesum,$signature,$newClosingId));
$sql = "DELETE FROM %queueextras% where queueid in (SELECT Q.id as quid FROM %queue% Q WHERE id not in (select distinct queueid FROM %billproducts% BP) AND billid is null)";
CommonUtils::execSql($pdo, $sql, null);
$sql = "DELETE FROM %queue% WHERE id not in (select distinct queueid FROM %billproducts%) AND billid is null";
CommonUtils::execSql($pdo, $sql, null);
CommonUtils::execSql($pdo, "OPTIMIZE TABLE %queue%", null);
$sql = "UPDATE %queue% set paidtime=?,delivertime=? WHERE billid is not null AND paidtime is null";
CommonUtils::execSql($pdo, $sql, array($closingTime,$closingTime));
$sql = "UPDATE %queue% set delivertime=?,workprinted=? WHERE billid is not null AND delivertime IS NULL";
CommonUtils::execSql($pdo, $sql, array($closingTime,1));
$sql = "DELETE FROM %printjobs%";
CommonUtils::execSql($pdo, $sql, null);
CommonUtils::execSql($pdo, "OPTIMIZE TABLE %printjobs%", null);
$sql = "UPDATE %queue% SET isclosed=?";
CommonUtils::execSql($pdo, $sql, array(1));
$dblogging = CommonUtils::getConfigValue($pdo, 'dblog', 1);
if ($dblogging == 0) {
$sql = "DELETE FROM %log%";
CommonUtils::execSql($pdo, $sql, null);
CommonUtils::execSql($pdo, "OPTIMIZE TABLE %log%", 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);
}
private function getCategoriasBruttoOfClosing($pdo,$closingid) {
$sql = "SELECT SUM(price) as brutto,kind FROM %queue% Q,%bill%,%closing%,%prodtype% T,%products% P ";
$sql .= " WHERE billid=%bill%.id AND %bill%.closingid=%closing%.id AND closingid=? ";
$sql .= " AND Q.productid=P.id AND P.category=T.id ";
$sql .= " GROUP BY kind";
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
$stmt->execute(array($closingid));
return ($stmt->fetchAll(PDO::FETCH_OBJ));
}
/*
* 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);
$categorysums = $this->getCategoriasBruttoOfClosing($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, "categorysums" => $categorysums, "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 id<?";
$stmt = $pdo->prepare(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['Category'][$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)";
$md5ofData = md5($data);
$ok = 1;
if ($signature != $md5ofData) {
$ok = 0;
}
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
"kind" => "-",
"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,Q.tax as tax,anoption,kind FROM %queue% Q,%billproducts%,%prodtype%,%products% P WHERE %billproducts%.billid=? AND %billproducts%.queueid=Q.id AND Q.productid=P.id AND P.category=%prodtype%.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,Q.tax as tax,kind FROM %queue% Q,%prodtype%,%products% P WHERE billid=? AND Q.productid=P.id AND P.category=%prodtype%.id";
}
$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'];
$kind = "Speise";
if ($zeile['kind'] == 1) {
$kind = "Getraenk";
}
$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,
"kind" => $kind,
"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\" ; \"$kind\" ; \"$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 signAllClosings($pdo) {
$sql = "select id,closingdate,billcount,billsum,remark,signature from %closing%";
$r = CommonUtils::fetchSqlAll($pdo, $sql);
$sql = "UPDATE %closing% SET signature=? WHERE id=?";
foreach ($r as $c) {
$closingid = $c["id"];
$previousClosingDate = self::getDateOfPreviousClosing($pdo,$closingid);
if (is_null($previousClosingDate)) {
$startDate = "";
} else {
$startDate = $previousClosingDate;
}
$billsumstr = number_format($c["billsum"], 2, ".", '');
$billcount = $c["billcount"];
$closingdate = $c["closingdate"];
$data = "I($closingid)-S($startDate)-E($closingdate)-D($billcount)-S($billsumstr)";
$md5ofdata = md5($data);
CommonUtils::execSql($pdo, $sql, array($md5ofdata,$closingid));
}
}
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)";
$md5ofdata = md5($data);
$ok = 1;
if (($closingpart->signature) != $md5ofdata) {
$ok = 0;
}
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;
}
}
private function htmlreport($closingid) {
$pdo = DbUtils::openDbAndReturnPdoStatic();
$ok = self::checkForClosingConsistency($pdo, $closingid);
if (($ok == 0)) {
echo "Datenbank inkonsistent";
return;
}
$closing = $this->getClosingSummaryCore($closingid,$pdo,false,false,8);
$clostemplate = CommonUtils::getConfigValue($pdo, "clostemplate", "Kein Template festgelegt");
$templatelines = Templateutils::getTemplateAsLineArray($clostemplate);
$reporter = new ClosTemplater($templatelines,$closingid,$closing);
$txt = $reporter->createWithTemplate($pdo);
$html = "<html>";
$html = "<head><meta charset='UTF-8'></head>";
$html .= "<body><style>";
$html .= "</style>";
$html .= $txt;
$version = CommonUtils::getConfigValue($pdo, "version", "");
$html .= "<br><br><hr><div style='text-align:right;font-style:italic;'>OrderSprinter $version</div>";
$html .= "</body></html>";
echo $html;
}
}