847 lines
30 KiB
PHP
847 lines
30 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 {
|
|
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)";
|
|
$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=?";
|
|
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);
|
|
|
|
$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);
|
|
|
|
$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);
|
|
}
|
|
|
|
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)";
|
|
|
|
$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
|
|
"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 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;
|
|
}
|
|
}
|
|
}
|