OrderSprinter 1.2.0

This commit is contained in:
Geno 2020-11-19 22:59:47 +01:00
parent 2cdb1242c5
commit 27a1ab8de0
34 changed files with 2132 additions and 1686 deletions

Binary file not shown.

View File

@ -5,7 +5,7 @@
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="author" content="Stefan Pichel">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.1.30">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.2.0">
<link rel="stylesheet" href="php/3rdparty/orderstyle/orderstyle.min.css" />
<link rel="stylesheet" href="php/3rdparty/orderstyle/jquery.mobile.icons.min.css" />

View File

@ -5,7 +5,7 @@
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="author" content="Stefan Pichel">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.1.30">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.2.0">
<link rel="stylesheet" href="php/3rdparty/orderstyle/orderstyle.min.css" />
<link rel="stylesheet" href="php/3rdparty/orderstyle/jquery.mobile.icons.min.css" />
@ -82,6 +82,10 @@ var BILL_STORNO_REASON = ["Stornogrund","Reason","Razón"];
var BILL_TOGGLE_HOST = ["Der ursprüngliche Bon wurde storniert und mit geänderter Bewirtungseigenschaft neu angelegt. Er befindet sich an erster Stelle in der Bonliste.",
"Der original receipt was discarded and recreated with the changed guest receipt property. The new receipt is on top of the list",
"El tique original esta descartado y iniciado de nuevo en la forma modificada"];;
var BILL_WRONG_FORMAT = ["Falsches Zahlenformat","Wrong number format","Formato de precio incorecto"];
var BILL_FIRST_JOB = ["Erste Bon-ID","First job id","Id primero"];
var BILL_LAST_JOB = ["Letzte Bon-ID","Last job id","Id último"];
var BILL_BATCH = ["Stapelverarbeitung","Batch processing","Accion con muchos elementos"];
var lang = 0;
@ -102,6 +106,11 @@ function setLanguage(language) {
$("#datetxt").html(BILL_DATE[lang]);
$("#stornoreasontxt").html(BILL_STORNO_REASON[lang]);
$("#printjobstxt").html(BILL_PRINT[lang]);
$("#fromjobidtxt").html(BILL_FIRST_JOB[lang]);
$("#tojobidtxt").html(BILL_LAST_JOB[lang]);
$("#batchheadertxt").html(BILL_BATCH[lang]);
var langtxt = "de";
if (lang == 1) {
langtxt = "en";
@ -129,6 +138,29 @@ function updatelistener() {
});
}
function batchjoblistener() {
$("#printjobsbtn").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
var start = $("#fromjobidfield").val();
var end = $("#tojobidfield").val();
if (!isInt(start) || !isInt(end)) {
alert(BILL_WRONG_FORMAT[lang]);
return;
}
doAjax("POST","php/contenthandler.php?module=printqueue&command=batchReceiptPrintJob",{start : start, end:end }, handleBatchResult, null);
});
}
function handleBatchResult(answer) {
if (answer.status != "OK") {
alert("Fehler " + answer.code + ": " + answer.msg);
} else {
$("#fromjobidfield").val("");
$("#tojobidfield").val("");
}
}
function getLastBills() {
var date = $("#datepicker").datepicker("getDate");
@ -360,7 +392,13 @@ function insertGenConfigStartRest(configResult) {
setLanguage(values.userlanguage);
getLastBills();
updatelistener();
batchjoblistener();
bindWhenSelection();
if (values.payprinttype == "s") {
// REM* only then allow batch processing
$("#batchpanel").show();
}
} else {
setTimeout(function(){document.location.href = "index.html"},250); // not logged in
}
@ -383,6 +421,8 @@ $(document).on("pageinit", "#bill-page", function () {
hideMenu();
$.ajaxSetup({ cache: false });
getGeneralConfigItems();
$("#fromjobidfield").val("");
$("#tojobidfield").val("");
});
@ -390,7 +430,7 @@ $(document).on("pageinit", "#bill-page", function () {
<div data-role="page" id="bill-page">
<div data-role="panel" id="modulepanel" data-position="right" data-display="overlay">
<ul data-role="listview" id="modulemenu" data-divider-theme="a" data-inset="true">
<li data-role="list-divider" data-theme="b" data-role="heading">Module</li>
<li data-role="list-divider" data-theme="b">Module</li>
</ul>
</div><!-- /panel -->
<div data-role="header" data-theme="b" data-position="fixed" id="theheader">
@ -409,6 +449,17 @@ $(document).on("pageinit", "#bill-page", function () {
<a href="#" data-role="button" data-theme="f" id="updatebtn"><span id="updatebtntxt">Aktualisieren</span></a>
<br><br>
<div id=billlist></div>
<div id="batchpanel" data-role="collapsible" data-collapsed="false" data-theme="e" data-content-theme="c" style="display:none;">
<h3><span id="batchheadertxt">Stapelverarbeitung</span></h3>
<p>
<form>
<span id="fromjobidtxt">Erste Bon-ID:</span><input type="text" id="fromjobidfield" style="background-color:white;"/><br>
<span id="tojobidtxt">Letzte Bon-ID:</span><input type="text" id="tojobidfield" style="background-color:white;" /><br>
<a href="#" data-role="button" data-icon="check" id="printjobsbtn" data-theme="f"><span id="printjobstxt">Drucken</span></a>
</form>
</div>
<div id=receiptbill></div>
</div>
<div data-role="footer" data-theme="b" id="thefooterr">
@ -418,7 +469,7 @@ $(document).on("pageinit", "#bill-page", function () {
</div><!-- /grid-a -->
</div> <!-- footer -->
<div data-role="popup" id="cancelfailed" name="cancelfailed" data-overlay-theme="a" style="max-width:70%;" class="ui-corner-all">
<div data-role="popup" id="cancelfailed" data-overlay-theme="a" style="max-width:70%;" class="ui-corner-all">
<div data-role="header" class="ui-corner-top">
<h1>Storno fehlgeschlagen</h1>
</div>

File diff suppressed because one or more lines are too long

View File

@ -1,61 +1,5 @@
# ***** Diese Speisekarte hat ein bestimmtes Format. ****
# ***** Das Format, insbesondere die Einrückungen, müssen ****
# ***** genau eingehalten werden, damit der Inhalt korrekt ****
# ***** übernommen werden kann. ****
#
# Einrückungen bauen die Produktpalette hierarchisch auf
# Die tiefsten Einrückungen stellen die Produkte dar, alle
# Ebenen darüber die Kategorien
# ***** Diese Speisekarte ist vom System bereits eingespeichert worden (erkennbar an den zugewiesenen IDs). ****
#
# Die einfachste Struktur sieht wie folgt aus (Beispiel):
#
# Speisen
# Gericht 1 ; 2,90
# Gericht 2 ; 3,90
# Untergruppe xy
# Gericht 3 ; 2,90
# Getränke
# ...
#
# Kategorien und Produkte können zusätzlich noch weiter spezifiziert
# werden:
#
# Ein Produkteintrag hat folgendes Format:
# Kurzname (ID:123); NormalPreis (Stufe A); Langname # Preis (Stufe B); Preis (Stufe C); Steuersatz
# dabei ist der Kurzname nur in der Kellneransicht bei der Produktauswahl zu sehen,
# anschließend wird stets der Langname angezeigt.
# Nur Kurzname und Preis (A) sind erforderlich, die anderen Teile werden bei
# Auslassung automatisch gefüllt (Preis B=C=A und Langname = Kurzname).
#
# Wurde dem Produkt bereits eine ID von OrderSprinter zugewiesen, wird diese angezeigt.
# So können spätere Produktänderungen vom OrderSprinter erkannt werden.
# Es ist wichtig, keine eigenen IDs zu vergeben, denn neue IDs werden stets vom
# OrderSprinter erzeugt!
#
# Wird ein Steuersatz angegeben, der für das Produkt vorgegeben sein soll, so
# müssen auch die Preise A und B angegeben werden.
#
# Bei Kategorien:
# Das Gleichheitszeichen dient als Trenner zwischen Namen und weiteren Eigenschaften.
# Wird ein K und B mitgegeben, so werden diese Produkte über die Küchen-
# und Bereitstellungsansicht geführt. Die Einstellung wird auf die Unterkategorien
# vererbt, wenn die darunter liegenden Kategorien keine Angabe dazu machen.
# Hinter dem zweiten Gleichheitszeichen kann die Nummer eines Arbeitsbondruckers
# des jeweiligen Typs (Speise/Getränk) angegeben werden.
#
# Wenn ein D da steht, wird als Typ "Getränk" angenommen, bei einem F "Speise".
# Auch hier wird der übergeordnete Eintrag genommen, wenn Angabe fehlt.
#
# Extras werden mit einem Ausrufezeichen am Zeilenanfang deklariert.
# Das Format ist:
# !Extraname (ID:8) # 12,34 ; (45),Langname eines Produkts,(49),(50)
# - Die ID-Angabe ist optional (kann weggelassen werden)
# - Der Wert 12,34 ist der Aufpreis
# - Hinter dem Semikolon können Komma-getrennt Produkte angegebenen werden, die
# dieses Extra haben dürfen. Angabe entweder ID des Produkts in Klammern oder
# der Langname eines Produkts. (Gibt es den Langnamen mehrfach, wird das Extra
# auch mehrfach zugewiesen.)
#
# Reservierte Buchstaben: = ; # !
# (Diese werden als Trenner verwendet!)
# ***** Eine Erklärung der Syntax ist im Aufklappfeld "Legende" zu lesen.
#

View File

@ -1,100 +1,62 @@
#
# ***** Diese Speisekarte kann als Vorlage dienen. ****
#
# Einrückungen bauen die Produktpalette hierarchisch auf
# Die tiefsten Einrückungen stellen die Produkte dar, alle
# Ebenen darüber die Kategorien
# ***** Eine Erklärung der Syntax ist im Aufklappfeld "Legende" zu lesen.
#
# Ein Produkteintrag hat folgendes Format:
# Kurzname ; NormalPreis (Stufe A); Langname # Preis (Stufe B); Preis (Stufe C)
# dabei ist der Kurzname nur in der Kellneransicht bei der Produktauswahl zu sehen,
# anschließend wird stets der Langname angezeigt.
# Nur Kurzname und Preis (A) sind erforderlich, die anderen Teile werden bei
# Auslassung automatisch gefüllt (Preis B=C=A und Langname = Kurzname)
# Wird ein Steuersatz angegeben, der für das Produkt vorgegeben sein soll, so
# müssen auch die Preise A und B angegeben werden.
# Wurde dem Produkt bereits eine ID von OrderSprinter zugewiesen, wird diese angezeigt.
# So können spätere Produktänderungen vom OrderSprinter erkannt werden.
# Es ist wichtig, keine eigenen IDs zu vergeben, denn neue IDs werden stets vom
# OrderSprinter erzeugt!
#
# Bei Kategorien:
# Das Gleichheitszeichen dient als Trenner zwischen Namen und weiteren Eigenschaften.
# Wird ein K und B mitgegeben, so werden diese Produkte über die Küchen-
# und Bereitstellungsansicht geführt. Die Einstellung wird auf die Unterkategorien
# vererbt, wenn die darunter liegenden Kategorien keine Angabe dazu machen.
# Hinter dem zweiten Gleichheitszeichen kann die Nummer eines Arbeitsbondruckers
# des jeweiligen Typs (Speise/Getränk) angegeben werden.
#
# Wenn ein D da steht, wird als Typ "Getränk" angenommen, bei einem F "Speise".
# Auch hier wird der übergeordnete Eintrag genommen, wenn Angabe fehlt.
#
# Extras werden mit einem Ausrufezeichen am Zeilenanfang deklariert.
# Das Format ist:
# !Extraname (ID:8) # 12,34 ; (45),Langname eines Produkts,(49),(50)
# - Die ID-Angabe ist optional (kann weggelassen werden)
# - Der Wert 12,34 ist der Aufpreis
# - Hinter dem Semikolon können Komma-getrennt Produkte angegebenen werden, die
# dieses Extra haben dürfen. Angabe entweder ID des Produkts in Klammern oder
# der Langname eines Produkts. (Gibt es den Langnamen mehrfach, wird das Extra
# auch mehrfach zugewiesen.)
#
# Reservierte Buchstaben: = ; # !
# (Diese werden als Trenner verwendet!)
#
Speisen = KBF
Fastfood
Speisen = KBF = 1
Fastfood = KBF = 1
Pommes; 3,00
Schnitzel; 4,00
Vom Grill
El Greco 2P; 26{.}90; EL Greco 2 Personen # 20{.}90; 13{.}80
El Greco 1P; 14{.}80; EL Greco 1 Person
Fleisch-Gerichte
Lammkotelett; 13{.}50; Lammkotelett # 11{.}30; 6{.}00
Zigeuner/Jägerschnitzel; 10{.}50 # 9{.}80; 3{.}50
Suzukakia 4H; 10{.}50; Suzukakia 4 Hacksteaks
Suzukakia 2H; 10{.}50; Suzukakia 2 Hacksteaks
Souvlaki; 10{.}50
Italienische Küche
Pizza
Siciliana
klein; 7{.}50; Pizza Siciliana klein
groß; 7{.}50; Pizza Siciliana groß
Salami
klein; 6{.}20; Pizza Salami klein
groß; 7{.}80; Pizza Salami groß
Special; 6{.}90; Ital. Tagesspecial
Kategorie Selbstbedienung =
Frühstücksbuffet; 8{.}90
Frühstücksbuffet + Kaffe; 12{.}20
Kategorie vorbereitet = B
Deserts; 2{.}20
Fertigprodukte; 1{.}20
Kategorie Nur Küche = K
Tischzubereitung Fisch; 2{.}20
Tischzubereitung Fleischmenü; 1{.}20
Getränke = KBD
Kaffee
Vom Grill = KBF = 1
EL Greco 2 Personen; 26,00 # Kurzname:El Greco 2P; PreisB:20,00; PreisC:13,00
EL Greco 1 Person; 14,00 # Kurzname:El Greco 1P
Fleisch-Gerichte = KBF = 1
Lammkotelett; 13,00 # PreisB:11,00; PreisC:6,00
Zigeuner/Jägerschnitzel; 10,00 # PreisB:9,00; PreisC:3,00
Suzukakia 4 Hacksteaks; 10,00 # Kurzname:Suzukakia 4H
Suzukakia 2 Hacksteaks; 10,00 # Kurzname:Suzukakia 2H
Souvlaki; 10,00 # ID:9
Italienische Küche = KBF = 1
Ital. Tagesspecial; 6,00 # Kurzname:Special
Pizza = KBF = 1
Siciliana = KBF = 1
Pizza Siciliana klein; 7,00 # Kurzname:klein
Pizza Siciliana groß; 7,00 # Kurzname:groß
Salami = KBF = 1
Pizza Salami klein; 6,00 # Kurzname:klein
Pizza Salami groß; 7,00 # Kurzname:groß
Kategorie Selbstbedienung = F = 1
Frühstücksbuffet; 8,00
Frühstücksbuffet + Kaffe; 12,00
Kategorie vorbereitet = BF = 1
Deserts; 2,00
Fertigprodukte; 1,00
Kategorie Nur Küche = KF = 1
Tischzubereitung Fisch; 2,00
Tischzubereitung Fleischmenü; 1,00
Getränke = KBD = 1
Kaffee = KBD = 1
Cappuchino; 2,50
Tasse Kaffee; 3,00
Becher Kaffee; 3,50
Latte Macchiato; 3,00
Biere
Holsten; 1{.}60 # 1{.}00; 0{.}80
Warsteiner; 1{.}80 # 1{.}20
Becks Gold; 1{.}80
Alsterwasser; 1{.}50
Softdrinks
Coca-Cola; 2{.}50
Fanta; 2{.}50
Ohne Zucker = B
Cola Zero; 2{.}21
Sprite; 2{.}50
Eistee; 1{.}60
Wasser
Apollinaris; 2{.}20
still; 1{.}20; Stilles Wasser
Weine
Lambrusco; 7{.}00; Wein Lambrusco
Biere = KBD = 1
Holsten; 1,00 # PreisB:1,00; PreisC:0,00
Warsteiner; 1,00
Becks Gold; 1,00
Alsterwasser; 1,00
Softdrinks = KBD = 1
Coca-Cola; 2,00
Fanta; 2,00
Sprite; 2,00
Eistee; 1,00
Ohne Zucker = BD = 1
Cola Zero; 2,00
Wasser = KBD = 1
Apollinaris; 2,00
Stilles Wasser; 1,00 # Kurzname:still
Weine = KBD = 1
Wein Lambrusco; 7,00 # Kurzname:Lambrusco
#
# Es folgen die Extras
!Sahne # 0,50 ; Tasse Kaffee , Becher Kaffee

View File

@ -4,7 +4,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.1.30">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.2.0">
<link rel="stylesheet" href="php/3rdparty/orderstyle/orderstyle.min.css" />
<link rel="stylesheet" href="php/3rdparty/orderstyle/jquery.mobile.icons.min.css" />

View File

@ -7,8 +7,8 @@
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="author" content="Stefan Pichel">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.1.30">
<link rel="stylesheet" type="text/css" href="css/numfield.css?v=1.1.30">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.2.0">
<link rel="stylesheet" type="text/css" href="css/numfield.css?v=1.2.0">
<link rel="stylesheet" href="php/3rdparty/orderstyle/orderstyle.min.css" />
<link rel="stylesheet" href="php/3rdparty/orderstyle/jquery.mobile.icons.min.css" />

View File

@ -679,7 +679,7 @@ $(document).ready(function() {
<tr id=updateline>
<td>&nbsp;</td>
<td align=center>
<button id="updatebtn">Update -> 1.1.30</button>
<button id="updatebtn">Update -> 1.2.0</button>
</td>
<td>&nbsp;</td>
</tr>

View File

@ -95,6 +95,39 @@ $ret = array("extensions_status" => $extensions_status, "missing_extensions" =>
echo json_encode($ret);
}
private function getForeignKeyName($pdo,$fromtable,$totable,$dbname) {
$foreignKey = null;
try {
$sql = "SELECT constraint_name as foreignkey FROM information_schema.REFERENTIAL_CONSTRAINTS WHERE constraint_schema = '$dbname' AND table_name = '%$fromtable%' AND REFERENCED_TABLE_NAME='%$totable%'";
$stmt = $pdo->prepare($this->basedb->resolveTablenamesInSqlString($sql));
$stmt->execute();
$result = $stmt->fetchAll();
if (count($result) != 1) {
return null;
}
$foreignKey = $result[0]["foreignkey"];
} catch (Exception $e) {
return null;
}
return $foreignKey;
}
private function replaceForeignIdKey($pdo,$fromtable,$totable,$dbname,$foreignkeyname,$colname) {
$foreignkeyorig = $this->getForeignKeyName($pdo, $fromtable, $totable, $dbname);
if (!is_null($foreignkeyorig)) {
$this->execSql($pdo, "alter table %$fromtable% drop foreign key $foreignkeyorig");
$this->execSql($pdo, "ALTER TABLE %$fromtable% ADD CONSTRAINT $foreignkeyname FOREIGN KEY ($colname) REFERENCES %$totable%(id)");
}
}
private function replaceForeignKeysToBillAndClosing($pdo,$dbname) {
$this->replaceForeignIdKey($pdo, 'billproducts', 'bill', $dbname, 'billprodref', 'billid');
$this->replaceForeignIdKey($pdo, 'queue', 'bill', $dbname, 'queuebillref', 'billid');
$this->replaceForeignIdKey($pdo, 'bill', 'closing', $dbname, 'billclosingref', 'closingid');
$this->replaceForeignIdKey($pdo, 'bill', 'bill', $dbname, 'billbillref', 'ref');
}
function updateVersion($pdo,$version) {
$setVersion = "update %config% set setting=? where name='version'";
$stmt = $pdo->prepare($this->basedb->resolveTablenamesInSqlString($setVersion));
@ -1168,6 +1201,39 @@ return false;
}
}
private function execSql($pdo,$sql) {
$stmt = $pdo->prepare($this->basedb->resolveTablenamesInSqlString($sql));
$stmt->execute();
}
function updateUserTable1130_1200($prefix, $version, $dbname) {
$pdo = $this->pdo;
try {
if ($version != "1.1.30") {
$ret = $this->updateUserTable1129_1130($prefix, $version);
if (!$ret) {
return false;
}
}
DbUtils::overrulePrefix($prefix);
$this->replaceForeignKeysToBillAndClosing($pdo,$dbname);
$this->execSql($pdo, "ALTER TABLE %user% ADD right_closing INT (1) NULL AFTER right_products");
$this->execSql($pdo, "ALTER TABLE %histuser% ADD right_closing INT (1) NULL AFTER right_products");
$this->execSql($pdo, "UPDATE %user% SET right_closing=right_manager");
$this->execSql($pdo, "UPDATE %histuser% SET right_closing=right_manager");
$this->execSql($pdo, "ALTER TABLE %user% MODIFY right_closing INT(1) NOT NULL");
$this->execSql($pdo, "ALTER TABLE %histuser% MODIFY right_closing INT(1) NOT NULL");
$this->updateVersion($pdo, '1.2.0');
return true;
} catch (PDOException $e) {
return false;
}
}
function setVersion($prefix,$theVersion) {
$pdo = $this->pdo;
try {
@ -1252,7 +1318,7 @@ $this->basedb->doSQL($pdo,"INSERT INTO `%config%` (`id` , `name`, `setting`) VAL
$this->basedb->doSQL($pdo,"INSERT INTO `%config%` (`id` , `name`, `setting`) VALUES (NULL , 'billlanguage', $billlanguage)");
$this->basedb->doSQL($pdo,"INSERT INTO `%config%` (`id` , `name`, `setting`) VALUES (NULL , 'currency', '$currency')");
$this->basedb->doSQL($pdo,"INSERT INTO `%config%` (`id` , `name`, `setting`) VALUES (NULL , 'receiptfontsize', '12')");
$this->basedb->doSQL($pdo,"INSERT INTO `%config%` (`id` , `name`, `setting`) VALUES (NULL , 'version', '1.1.30')");
$this->basedb->doSQL($pdo,"INSERT INTO `%config%` (`id` , `name`, `setting`) VALUES (NULL , 'version', '1.2.0')");
$this->basedb->doSQL($pdo,"INSERT INTO `%config%` (`id` , `name`, `setting`) VALUES (NULL , 'paymentconfig', '0')");
$this->basedb->doSQL($pdo,"INSERT INTO `%config%` (`id` , `name`, `setting`) VALUES (NULL , 'remoteaccesscode', null)");
$this->basedb->doSQL($pdo,"INSERT INTO `%config%` (`id` , `name`, `setting`) VALUES (NULL , 'decpoint', '$decpoint')");
@ -1349,24 +1415,24 @@ $stmt_insert_hist->execute(array($currentTime, $action, $refIdForHist));
function insertUser($username,$adminpass,$is_admin,$right_waiter,$right_kitchen,$right_bar,
$right_supply,$right_paydesk,$right_statistics,$right_bill,$right_products,$right_changeprice,
$right_manager,$right_reservation,$right_rating,$lang,$prefertablemap) {
$right_manager,$right_closing,$right_reservation,$right_rating,$lang,$prefertablemap) {
$md5adminpass = md5($adminpass);
$pdo = $this->pdo;
$userInsertSql = "INSERT INTO `%user%` (`id` , `username` , `userpassword`, `is_admin`, `right_waiter`,`right_kitchen`,`right_bar`,`right_supply`,`right_paydesk`,`right_statistics`,`right_bill`,`right_products`,`right_changeprice`,`right_manager`,`right_reservation`,`right_rating`,`language`,`prefertablemap`,`keeptypelevel`,`extrasapplybtnpos`,`active`) VALUES (NULL,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,'1','1')";
$userInsertSql = "INSERT INTO `%user%` (`id` , `username` , `userpassword`, `is_admin`, `right_waiter`,`right_kitchen`,`right_bar`,`right_supply`,`right_paydesk`,`right_statistics`,`right_bill`,`right_products`,`right_changeprice`,`right_manager`,`right_closing`,`right_reservation`,`right_rating`,`language`,`prefertablemap`,`keeptypelevel`,`extrasapplybtnpos`,`active`) VALUES (NULL,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,'1','1')";
$stmt = $pdo->prepare(DbUtils::substTableAlias($userInsertSql));
$stmt->execute(array($username,$md5adminpass,$is_admin,$right_waiter,$right_kitchen,$right_bar,$right_supply,$right_paydesk,$right_statistics,$right_bill,$right_products,$right_changeprice,$right_manager,$right_reservation,$right_rating,$lang,$prefertablemap,0));
$stmt->execute(array($username,$md5adminpass,$is_admin,$right_waiter,$right_kitchen,$right_bar,$right_supply,$right_paydesk,$right_statistics,$right_bill,$right_products,$right_changeprice,$right_manager,$right_closing,$right_reservation,$right_rating,$lang,$prefertablemap,0));
$newUserIdForHist = $pdo->lastInsertId();
// now insert into hist
$sql_insert_histuser = "INSERT INTO %histuser% (`id` , `userid`, `username` ,
`is_admin`, `right_waiter`,`right_kitchen`,`right_bar`,`right_supply`,`right_paydesk`,
`right_statistics`,`right_bill`,`right_products`,`right_changeprice`,`right_manager`,`right_reservation`,`right_rating`,`active`) VALUES (
NULL,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
`right_statistics`,`right_bill`,`right_products`,`right_changeprice`,`right_manager`,`right_closing`,`right_reservation`,`right_rating`,`active`) VALUES (
NULL,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
$stmt_insert_histuser = $pdo->prepare($this->basedb->resolveTablenamesInSqlString($sql_insert_histuser));
$stmt_insert_histuser->execute(array($newUserIdForHist,$username,$is_admin,$right_waiter,$right_kitchen,$right_bar,$right_supply,$right_paydesk,$right_statistics,$right_bill,$right_products,$right_changeprice,$right_manager,$right_reservation,$right_rating,1));
$stmt_insert_histuser->execute(array($newUserIdForHist,$username,$is_admin,$right_waiter,$right_kitchen,$right_bar,$right_supply,$right_paydesk,$right_statistics,$right_bill,$right_products,$right_changeprice,$right_manager,$right_closing,$right_reservation,$right_rating,1));
$newRefIdForHist = $pdo->lastInsertId();
$this->insertIntoHist($pdo, '3', $newRefIdForHist);
}
@ -1616,7 +1682,7 @@ $zones[] = $timezone_identifiers[$i];
}
echo json_encode($zones);
} else if ($command == 'update') {
$installerVersion = "1.1.30";
$installerVersion = "1.2.0";
$admin = new InstallAdmin();
$pdo = $admin->openDbAndReturnPdo($_POST['host'],$_POST['db'],$_POST['user'],$_POST['password']);
@ -1645,7 +1711,7 @@ $supportedVersions = array("1.0.22","1.0.23","1.0.24","1.0.25","1.0.26","1.0.27"
"1.0.30","1.0.31","1.0.32","1.0.33","1.0.34","1.0.35","1.0.36","1.0.37","1.0.38","1.0.39",
"1.0.40","1.0.41","1.0.42","1.0.43",
"1.1.0","1.1.1","1.1.2","1.1.3","1.1.4","1.1.5","1.1.6","1.1.7","1.1.8", "1.1.9","1.1.10","1.1.11","1.1.12","1.1.13","1.1.14","1.1.15","1.1.16","1.1.17",
"1.1.18","1.1.19","1.1.20","1.1.21","1.1.22","1.1.23","1.1.24","1.1.25","1.1.26","1.1.27","1.1.28","1.1.29"
"1.1.18","1.1.19","1.1.20","1.1.21","1.1.22","1.1.23","1.1.24","1.1.25","1.1.26","1.1.27","1.1.28","1.1.29","1.1.30"
);
if (!in_array($version, $supportedVersions)) {
@ -1653,7 +1719,7 @@ echo json_encode("Quellversion nicht unterstützt");
return;
}
$ret = $admin->updateUserTable1129_1130($_POST['prefix'], $version);
$ret = $admin->updateUserTable1130_1200($_POST['prefix'], $version, $_POST['db']);
if(session_id() == '') {
session_start();

View File

@ -5,7 +5,7 @@
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="author" content="Stefan Pichel">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.1.30">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.2.0">
<link rel="stylesheet" href="php/3rdparty/orderstyle/orderstyle.min.css" />
<link rel="stylesheet" href="php/3rdparty/orderstyle/jquery.mobile.icons.min.css" />

View File

@ -5,7 +5,7 @@
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="author" content="Stefan Pichel">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.1.30">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.2.0">
<link rel="stylesheet" href="php/3rdparty/orderstyle/orderstyle.min.css" />
<link rel="stylesheet" href="php/3rdparty/orderstyle/jquery.mobile.icons.min.css" />
@ -65,6 +65,7 @@ var MAN_RESERVATION = ["Reservierung","Reservation","Reserva"];
var MAN_RATING = ["Bewertung","Rating","Valoración"];
var MAN_CHANGEPRICE = ["Preisänderung während Bestellung","Change price during ordering","Modificar precio durante ordenar"];
var MAN_MANAGER = ["Verwaltung","Administration","Administración"];
var MAN_CLOSINGRIGHT = ["Tageserfassung","Closing","Cerrar día"];
var MAN_USER_NAME = ["Benutzername","User name","Nombre de usario"];
var MAN_USER_PASS = ["Passwort","Password","Contraseña"];
var MAN_YES = ["Ja","Yes","Si"];
@ -169,11 +170,12 @@ var MAN_BAK_REST_INFO_ALL = ['Die Datensicherung kann auch die gesamte Datenbank
'Exportar puede guarda la base de datos completamente. Con "Importar" este data se puede re-importado. '
+ 'Las acciones estan escritos en un log.'];
var MAN_REST_INFO = ["Der Import dauert eine Weile...","The import takes a while...","Importar necesita un rato..."];
var MAN_UPLOAD_FILE = ["Diese Datei hochladen: ", "Upload this file: ","Importar este file: "];
var MAN_UPLOAD_FILE = ["Diese Datei hochladen (<i>importieren</i>): ", "Upload this file: ","Importar este file: "];
var MAN_BAK_REST_HEAD = ["Sicherung und Import","Backup and Restore","Exportar y Importar"];
var MAN_BAK_BTN = ["Sicherung (Konfiguration)","Backup (Configuration)","Exportar (configuración)"];
var MAN_BAK_BTN_ALL = ["Sicherung (Alles)","Backup (all)","Exportar (todo)"];
var MAN_RESTORE_BTN = ["Importieren","Restore","Importar"];
var MAN_GO_LIVE = ["Starte Produktivbetrieb","Start productive mode","Empezar trabajar realmente"];
var MAN_SHUTDOWN = ["Server herunterfahren","Shutdown server","Apagar servidor"];
var MAN_SHUTDOWN_HINT = ["(Herunterfahren nur möglich, wenn Webserver die erforderlichen Rechte besitzt).",
"(Shutdown only possible if web server has the required privileges to do so.)",
@ -210,6 +212,7 @@ var MAN_PRINTER = ["Kassenbon-Drucker","Receipts Printer","Impresora de tiques"]
var MAN_FOOD_PRINTER = ["Speisearbeitsbon-Drucker","Food work ticket printer","Impreso de tiques de comida"];
var MAN_DRINK_PRINTER = ["Getränkearbeitsbon-Drucker","Drinks work ticket printer","Impreso de tiques de bebidas"];
var MAN_UPDATE_PRINTJOBS = ["Aktualisieren","Update","Actualizar"];
var MAN_CLEAR_PRINTJOBS = ["Alle Druckjobs löschen","Clear all print jobs","Remover todo"];
var MAN_PRINT_JOBS_COUNT = ["Druckaufträge","print jobs","tareas de impresión"];
var MAN_PARSE_ERROR = ["Speisekarte konnte nicht erfolgreich eingelesen werden. Stimmt die Syntax, z.B. die korrekte Einrückung?",
"Menu could not be parsed - is the intendation correct?",
@ -272,6 +275,9 @@ var MAN_AESKEY_WRONG_LENGTH = ["Ein AES256-Schlüssel muss in Hex-Darstellung 64
var MAN_AESKEY_NO_HEX = ["Der AES-Schlüssel muss als Hex-Zahl angegeben werden.","The AES key must be specified as hex number","La llava AES tiene que especificado en formato hex."];
var MAN_CERTIFICATE_SN = ["Zertifikatsseriennummer", "Certificate Serial No","Certificado ID"];
var MAN_TAX = ["Steuersatz (%)","Tax (%)","Impuesto (%)"];
var MAN_CONFIRM_GO_LIVE = ["Die Umsatz- und Logdaten wurden gelöscht und nur die Konfiguration übernommen. Deswegen ist nun ein erneutes Einloggen erforderlich.",
"The sales and log data is deleted and configuration is recreated. Therefore a log-in is required now.",
"La configuración esta re-creado. Entonces es necesario registrar de nuevo."];
var lang = 0;
var generalVals = [12,2,0,3,0,1,1,0,0,1, 0,50,20,10,1,0];
@ -391,6 +397,7 @@ function setLanguage(l) {
$("#backupbtntxt").html(MAN_BAK_BTN[l]);
$("#backupbtntxtall").html(MAN_BAK_BTN_ALL[l]);
$("#restorebtntxt").html(MAN_RESTORE_BTN[l]);
$("#golivetxt").html(MAN_GO_LIVE[l]);
$("#shutdownbtntxt").html(MAN_SHUTDOWN[l]);
$("#shutdownhinttxt").html(MAN_SHUTDOWN_HINT[l]);
@ -401,6 +408,7 @@ function setLanguage(l) {
$("#printjobsheader").html(MAN_PRINTJOBS[l]);
$("#updateprintqueue").html(MAN_UPDATE_PRINTJOBS[l]);
$("#clearprintqueue").html(MAN_CLEAR_PRINTJOBS[l]);
$("#tmimgdelbtntxt").html(MAN_TM_DEL[l]);
$("#tmimgbtntxt").html(MAN_TM[l]);
@ -438,14 +446,19 @@ function createMonthSelection(label) {
return monthHtml;
}
function hideElementsForNonAdminUser(jsonAnswer) {
if (jsonAnswer != "Yes") {
$("#dbactionui").hide();
function showPanelsDueToUserStatus(jsonAnswer) {
if (jsonAnswer == "admin") {
$("#dbactionui").show();
}
if (jsonAnswer == "manager" || (jsonAnswer == 'admin')) {
$("#userpart").show();
$("#configpart").show();
$("#printerqueue").show();
$("#dataexport").show();
$("#printserverdownloadpart").show();
}
function hideElementsForNonAdminManagerUser(jsonAnswer) {
if (jsonAnswer != "Yes") {
if(jsonAnswer == "No") {
$("#allpagecontent").hide();
}
}
@ -771,10 +784,10 @@ function changeConfig(changedEntries) {
}
function reactOnConfigChange(result) {
if (result == "OK") {
if (result.status == "OK") {
alert(MAN_CONFIG_CHANGED[lang]);
} else {
alert(MAN_CONFIG_CHANGE_ERROR[lang]);
alert(MAN_CONFIG_CHANGE_ERROR[lang] + ": " + result.msg);
}
}
@ -1006,7 +1019,6 @@ function binding() {
};
if (isValid) {
changeConfig(changedEntries);
setTimeout(function(){document.location.href = "manager.html"},500);
}
});
}
@ -1092,6 +1104,14 @@ function binding() {
$("#restinfoafterclick").html(MAN_REST_INFO[lang]);
});
$("#golive").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
areYouSure("Produktivbetrieb beginnen", "Alle Umsatz- und Logdaten löschen?", "Ja", function() {
golive();
});
});
$("#shutdown_btn").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
@ -1115,6 +1135,11 @@ function binding() {
e.preventDefault();
doAjax("GET","php/contenthandler.php?module=printqueue&command=getPrintJobOverview",null,insertPrintQueue,null);
});
$("#clearprintqueue").off("click").on("click", function (e) {
e.stopImmediatePropagation();
e.preventDefault();
doAjax("GET","php/contenthandler.php?module=printqueue&command=clearprintjobs",null,insertPrintQueue,null);
});
$("#taxass_apply").off("click").on("click", function (e) {
e.stopImmediatePropagation();
@ -1486,7 +1511,7 @@ function createLabelWithOption(aLabel,displayedName,hasTheRight) {
* the username and the rights that the user has to work in the
* various modules.
*/
function createCollapsibeOfUser(id,username,isAdmin,rWaiter,rKitchen,rBar,rSupply,rPay,rStat,rBill,rProd,rReservation,rRating,rChangeprice,rManager,forNewUser) {
function createCollapsibeOfUser(id,username,isAdmin,rWaiter,rKitchen,rBar,rSupply,rPay,rStat,rBill,rProd,rReservation,rRating,rChangeprice,rClosing, rManager,forNewUser) {
var collapsiblePart = '<div data-role="collapsible" id="' + id + '"';
if (forNewUser) {
collapsiblePart += ' data-theme="d" data-content-theme="d">';
@ -1511,6 +1536,7 @@ function createCollapsibeOfUser(id,username,isAdmin,rWaiter,rKitchen,rBar,rSuppl
collapsiblePart += createLabelWithOption("reservation",MAN_RESERVATION[lang],rReservation);
collapsiblePart += createLabelWithOption("rating",MAN_RATING[lang],rRating);
collapsiblePart += createLabelWithOption("changeprice",MAN_CHANGEPRICE[lang],rChangeprice);
collapsiblePart += createLabelWithOption("closingright",MAN_CLOSINGRIGHT[lang],rClosing);
collapsiblePart += createLabelWithOption("manager",MAN_MANAGER[lang],rManager);
if (forNewUser) {
@ -1531,6 +1557,7 @@ function fillUserListIntoGui(userinfo) {
$.each(userinfo, function (i, aUser) {
var userid = aUser.id;
var username = aUser.username;
userPart += createCollapsibeOfUser(
"userid_" + userid,
username,
@ -1546,6 +1573,7 @@ function fillUserListIntoGui(userinfo) {
aUser.right_reservation == 1,
aUser.right_rating == 1,
aUser.right_changeprice == 1,
aUser.right_closing == 1,
aUser.right_manager == 1,
false
);
@ -1554,7 +1582,7 @@ function fillUserListIntoGui(userinfo) {
userPart += createCollapsibeOfUser(
"userid_newuser",
MAN_NEW_USER[lang],
false,false,false,false,false,false,false,false,false,false,false,false,false,true);
false,false,false,false,false,false,false,false,false,false,false,false,false,false,true);
$("#userlist").html(userPart);
$('#userpart').trigger('create');
@ -1597,6 +1625,7 @@ function dynamicUserBinding() {
var rRating = newUserInfoContainer.find("#userlabel_rating").val();
var rChangeprice = newUserInfoContainer.find("#userlabel_changeprice").val();
var rManager = newUserInfoContainer.find("#userlabel_manager").val();
var rClosing = newUserInfoContainer.find("#userlabel_closingright").val();
if ((username.length == 0) || (password.length == 0)) {
alert ("Benutzername oder Passwort sind nicht gesetzt");
@ -1616,7 +1645,8 @@ function dynamicUserBinding() {
rReservation: rReservation,
rRating: rRating,
rChangeprice : rChangeprice,
rManager: rManager
rManager: rManager,
rClosing: rClosing
};
doAjax("POST","php/contenthandler.php?module=admin&command=createNewUser",data,doCreateNewUser,"Anlegen neuer Benutzer");
}
@ -1641,6 +1671,7 @@ function dynamicUserBinding() {
var rRating = userInfoContainer.find("#userlabel_rating").val();
var rChangeprice = userInfoContainer.find("#userlabel_changeprice").val();
var rManager = userInfoContainer.find("#userlabel_manager").val();
var rClosing = userInfoContainer.find("#userlabel_closingright").val();
var data = {
userid: userid,
@ -1656,7 +1687,8 @@ function dynamicUserBinding() {
rReservation: rReservation,
rRating: rRating,
rChangeprice: rChangeprice,
rManager: rManager
rManager: rManager,
rClosing: rClosing
};
doAjax("POST","php/contenthandler.php?module=admin&command=updateUser",data,askAndFillUserListNoData,"Benutzerdaten");
});
@ -1711,13 +1743,10 @@ function reloadPage(dummyData) {
}
function doCreateNewUser(result) {
if (result == "exists") {
alert ("Benutzer existiert bereits");
}
else if (result == "noadmin") {
alert (MAN_NO_ADMIN_CREATE[lang]);
} else {
if (result.status == "OK") {
askAndFillUserList("OK");
} else {
alert("Fehler: " + result.msg);
}
}
@ -1949,6 +1978,20 @@ function initroomfield(roomfield_json) {
var roomMap = new Roommap("#tablemaps");
}
function golive() {
doAjax("POST","php/contenthandler.php?module=admin&command=golive",null,handleGoLive,"Produktivbetriebsstart");
}
function handleGoLive(answer) {
if (answer.status == "OK") {
alert(MAN_CONFIRM_GO_LIVE[lang]);
setTimeout(function(){document.location.href = "logout.php"},250);
} else {
alert("Error: " + answer.msg);
}
}
function roomfield_prefill() {
var n = $("#maxrooms_val").val();
var m = $("#maxtables_val").val();
@ -2051,13 +2094,11 @@ function insertPrintQueue(queue) {
$(document).on("pageinit", "#admin-page", function () {
initializeMainMenu("#modulemenu");
getGeneralConfigItems();
doAjax("GET","php/contenthandler.php?module=admin&command=isLoggedinUserAdminOrManager",null,hideElementsForNonAdminManagerUser,"Fehler");
doAjax("GET","php/contenthandler.php?module=admin&command=isLoggedinUserAdminOrManagerOrTE",null,showPanelsDueToUserStatus,"Fehler");
askAndFillUserList();
hideMenu();
doAjax("GET","php/contenthandler.php?module=admin&command=isLoggedinUserAdmin",null,hideElementsForNonAdminUser,"Pruefe Adminberechtigung");
createYearPartFor("select-year","#yearselection",'#closinglist');
createYearPartFor("select-year-export-start","#yearselectionexportstart",'#dataexport');
createYearPartFor("select-year-export-end","#yearselectionexportend",'#dataexport');
@ -2133,7 +2174,7 @@ $(document).on("pageinit", "#admin-page", function () {
</div><!-- closinglist -->
<div id="dataexport" data-role="collapsible" data-content-theme="c">
<div id="dataexport" data-role="collapsible" data-content-theme="c" style="display:none;">
<h3><span id="dataexporttxt">Datenexport</span></h3>
<p><span id="dataexportdettxt">Hier können Sie eine csv-Datei erzeugen lassen, die ...
</span>
@ -2180,13 +2221,13 @@ $(document).on("pageinit", "#admin-page", function () {
</div> <!-- collapsible Abrechnung und Datenexport -->
<div id="userpart" data-role="collapsible" data-collapsed="true" data-theme="e" data-content-theme="c" class="noprint">
<div id="userpart" data-role="collapsible" data-collapsed="true" data-theme="e" data-content-theme="c" class="noprint" style="display:none;">
<h3><span id="usertxt">Benutzer</span></h3>
<div id="userlist" data-role="collapsible" data-theme="c" data-content-theme="c">
</div> <!-- userlist -->
</div> <!-- Benutzer -->
<div data-role="collapsible" data-collapsed="true" data-theme="e" data-content-theme="c" class="noprint" id="configpart">
<div data-role="collapsible" data-collapsed="true" data-theme="e" data-content-theme="c" class="noprint" id="configpart" style="display:none;">
<h3><span id="configtxt">Konfiguration</span></h3>
<form action="#" method="get">
<div data-role="fieldcontain">
@ -2316,7 +2357,7 @@ $(document).on("pageinit", "#admin-page", function () {
<button type="submit" data-theme="f" data-icon="check" id="changeConfig">Ändern</button>
</form><!-- Konfiguration -->
<img id="logoimgpart" height="70px" src=php/contenthandler.php?module=printqueue&command=getLogoAsPng />
<img id="logoimgpart" height="70px" src="php/contenthandler.php?module=printqueue&command=getLogoAsPng" />
<form id="logoform" enctype="multipart/form-data" action="php/contenthandler.php?module=admin&command=readlogo" method="POST" data-ajax="false">
<input type="hidden" name="MAX_FILE_SIZE" value="16777210" />
<span id=upllogotxt>Logo-Datei hochladen:</span>
@ -2329,13 +2370,18 @@ $(document).on("pageinit", "#admin-page", function () {
</form>
</div> <!-- Konfiguration -->
<div data-role="collapsible" data-collapsed="true" data-theme="e" data-content-theme="c" class="noprint" id="printerqueue">
<div data-role="collapsible" data-collapsed="true" data-theme="e" data-content-theme="c" class="noprint" id="printerqueue" style="display:none;">
<h3><span id="printjobsheader">Druckerwarteschlangen</span></h3>
<p><div id=printjobsarea>Daten</div></p>
<div><button type="submit" data-theme="f" data-icon="check" id="updateprintqueue">Refresh</button></div>
<p><div id=printjobsarea>Daten</div>
<div class="ui-grid-a" class="noprint">
<div class="ui-block-a"><button type="submit" data-theme="f" data-icon="check" id="updateprintqueue">Refresh</button></div>
<div class="ui-block-b"><button type="submit" data-theme="d" data-icon="delete" id="clearprintqueue">Clear print jobs</button></div>
</div><!-- /grid-a -->
</div> <!-- Druckerwarteschlangen -->
<div data-role="collapsible" data-collapsed="true" data-theme="e" data-content-theme="c" class="noprint" id="dbactionui">
<div data-role="collapsible" data-collapsed="true" data-theme="e" data-content-theme="c" class="noprint" id="dbactionui" style="display:none;">
<h3><span id="dbtxt">Datenbank</span></h3>
<div data-role="collapsible" data-collapsed="true" data-theme="f" data-content-theme="c" class="noprint" id="dbactionspeisenconfig">
@ -2344,8 +2390,113 @@ $(document).on("pageinit", "#admin-page", function () {
<div class="ui-block-a"><button data-theme="e" data-icon="plus" id="readsamplemenu"><span id=samplemenutxt>Beispielkarte</span></button></div>
<div class="ui-block-b grid_right"><button type="submit" data-theme="f" class="applySpeisekarte" data-icon="check" id="readspeisekarte">Anwenden</button></div>
</div><!-- /grid-a -->
<div data-role="collapsible" data-collapsed="true" data-theme="e" data-collapsed-icon="info" data-expanded-icon="info" data-content-theme="c" class="noprint" id="menulegenddiv">
<p><h3><span id="legendheader">Legende</span></h3>
<h2>Aufbau der Speisekarte</h2>
<p>Die Syntax der Speisekarte ist sehr strikt. Das Format, insbesondere die Einrückungen, müssen genau
eingehalten werden, damit der Inhalt korrekt übernommen werden kann!
<h3>Struktur</h3>
<p>Einrückungen bilden das Produktangebot hierarchisch ab. Die tiefsten Einrückungen stellen die <i>Produkte</i> dar,
alle Eebenen darüber die <i>Kategorien</i>.
<p>Die einfachste Form einer Speisekarte (Angabe des Langnames und des Preises für alle Preisstufen) sieht folgendermaßen aus:
<pre>
Speisen
Gericht 1 ; 2,90
Gericht 2 ; 3,90
Untergruppe xy
Gericht 3 ; 2,90
Getränke
...
</pre>
<p>In diesem Beispiel wurde jedem Produkt ein Preis zugewiesen, der für alle Preisstufen verwendet wird. Kategorien und Produkte können zusätzlich noch weiter spezifiziert werden.
<h3>Produkteinträge</h3>
<p>Ein Produkteintrag hat in der einfachsten Schreibweise folgende Syntax: <i>Produktname; Preis</i>. Sollen jedoch weitere Eigenschaften
festgelegt werden, können diese hinter einem Doppelkreuz per Semikolon getrennt angegeben werden: <i>Produktname; Preis # Eigenschaft1:Wert1; Eigenschaft2: Wert2</i>.
<p>Folgende Eigenschaften können angegeben werden:
<ul>
<li><b>ID</b>: Eine ID wird vom System festgelegt, sobald ein Produkt erstmalig angelegt wurde. Wenn ein Produkt verändert wird,
so sollte man die ID-Kennzeichnung beibehalten. Nur so kann das System das Produkt eindeutig identifizieren und in der
Statistik später eindeutig zuordnen. Es ist wichtig, keine eigenen IDs zu vergeben, denn neue IDs werden stets
vom OrderSprinter erzeugt!
<li><b>Kurzname</b>: Der Kurzname ist die Produktbezeichnung, die auf dem Bestellterminal erscheint. Wenn beispielsweise die übergeordnete
Kategorie <i>Cola</i> lautet, kann man darunter Produkte mit den Kurznamen <i>0,3l</i> und <i>0,5l</i> eintragen und damit die Übersicht auf
mobilen Geräten verbessern. Der Langname sollte jedoch die komplette Bezeichnung enthalten (<i>Cola 0,2l</i> und <i>Cola 0,5l</i>). Wird
der Kurzname nicht angegeben, wird automatisch der Langname verwendet.
<li><b>vorhanden</b>: Wenn ein Produkt zwar in der Speisekarte eingetragen werden soll, jedoch temporär nicht verfügbar ist, kann man dies
kennzeichnen, indem man den Wert auf <i>0</i> oder <i>nein</i> setzt.
<li><b>PreisB</b>: Preis der Preisstufe B. Wird diese Eigenschaft nicht angegeben, wird der Preis A verwendet, d.h. der Preis vor dem Doppelkreuz.
<li><b>PreisC</b>: Preis der Preisstufe C. Wird diese Eigenschaft nicht angegeben, wird der Preis A verwendet, d.h. der Preis vor dem Doppelkreuz.
<li><b>Fixsteuersatz</b>: Es ist möglich, einem Produkt einen fixen Umsatzsteuersatz zuzuordnen, so dass das Produkt bei der Bestellung
unabhängig von der Zuordnung <i>Tischbestellung</i> oder <i>Außer-Haus-Bestellung</i> immer den hier zugeordneten Steuersatz zugeordnet
bekommt.
</ul>
<p>Ein Produkteintrag mit weiteren Eigenschaften kann beispielsweise so aussehen:
<pre>
Cola 0,2l; 2,30 # Kurzname: 0.2l; vorhanden:nein; PreisB: 1,90
</pre>
<h3>Kategorien</h3>
<p>Das Gleichheitszeichen dient als Trenner zwischen Namen und weiteren Eigenschaften.
Wird ein <i>K</i> und <i>B</i> mitgegeben, so werden diese Produkte über die Küchen-
und Bereitstellungsansicht geführt. Die Einstellung wird auf die Unterkategorien
vererbt, wenn die darunter liegenden Kategorien keine Angabe dazu enthalten.
Hinter dem zweiten Gleichheitszeichen kann die Nummer eines Arbeitsbondruckers
des jeweiligen Typs (Speise/Getränk) angegeben werden.
<p>Wenn ein <i>D</i> angegeben ist, wird als Typ <b>Getränk</b> angenommen, bei einem <i>F</i> <b>Speise</b>.
Wenn die Angabe fehlt, wird die Eigenschaft des übergeordneten Eintrags verwendet.
<h3>Extras</h3>
<p>Extras werden mit einem Ausrufezeichen am Zeilenanfang deklariert. Nach dem Namen und der (vom OrderSprinter vergebenenen ID, die also
nicht vom Benutzer angegeben werden muss), können nach einem Semikolon die Produkte angegeben werden, die mit diesem Extra
verkauft werden dürfen. Zur Angabe eines Produktes kann man dessen Name oder in Klammern dessen ID verwenden. Ein Eintrag
hat demnach folgendes Aussehen (Beispiel):
<pre>
!Extraname (ID:8) 12,34 ; (45),Langname eines Produkts,(49),(50)
</pre>
<p>Dabei gilt:
<ul>
<li>Die ID-Angabe ist optional (kann weggelassen werden). Wenn OrderSprinter diese hinzugefügt hat, sollte man sie
beibehalten. Ein selbt erstellter neuer Extras-Eintrag sollte keine ID-Nummer enthalten.
<li>Der Wert 12,34 ist der Aufpreis.
<li>Hinter dem Semikolon wurden Komma-getrennt Produkte angegeben, die mit diesem Extra bestellt werden können, in diesem Fall
die Produkte mit der ID 45, 49 und 50 sowie ein Produkt mit dem Langnamen <i>Langname eines Produkts</i>.
</ul>
<p><i>Hinweis:</i> Gibt es den Langnamen mehrfach, wird das Extra auch mehrfach zugewiesen.
<h3>Reservierte Buchstaben</h3>
<p>Aus der beschriebenen Syntax ergibt sich, dass einige Buchstaben eine spezielle Bedeutung haben und nicht überall
verwendet werden dürfen:
<ul>
<li><b>#</b>: Ein Doppelkreuz zu Beginn einer Zeile leitet einen Kommentar ein, d.h. diese Zeile wird nicht interpretiert. Innerhalb
einer Zeile trennt das Doppelkreuz die Grundeigenschaften eines Produkts von den optionalen Eigenschaften.
<li><b>=</b>: Das Gleichheitszeichen hat bei einem Kategorieneintrag die Funktion eines Trennzeichens.
<li><b>;</b>: Das Semikolon wird bei einem Produkteintrag als Trenner der Eigenschaften verwendet.
<li><b>!</b>: Das Ausrufezeichen am Anfang einer Zeile leitet die Deklaration eines Extras ein.
</ul>
</div>
<textarea cols="40" rows="8" name="speiseninfo" id="speiseninfo" data-theme="a" style='font-family:"monospace"'></textarea>
</div> <!-- Speisekarte -->
<p>
@ -2413,7 +2564,7 @@ $(document).on("pageinit", "#admin-page", function () {
</div>
</div>
</p>
<p>
<div data-role="collapsible" data-collapsed="true" data-theme="f" data-content-theme="c" class="noprint" id="dbactionbakrest">
<p><h3><span id="bakrestxt">Sicherung und Import</span></h3></p>
@ -2434,28 +2585,29 @@ $(document).on("pageinit", "#admin-page", function () {
<div id=restorearea>
<form id="restoreform" enctype="multipart/form-data" action="php/contenthandler.php?module=admin&command=restore" method="POST" data-ajax="false">
<input type="hidden" name="MAX_FILE_SIZE" value="50000000" />
<span id=uplfiletxt>Diese Datei hochladen:</span>
<span id=uplfiletxt>Diese Datei hochladen (<i>importieren</i>):</span>
<input name="userfile" id="userfile" type="file" />
<div id=restinfoafterclick></div>
<input type="submit" data-theme="d" value="Importieren" id="restorebtntxt" formaction="php/contenthandler.php?module=admin&command=restore"/>
</form>
</div>
<p><button type="submit" data-theme="d" id="golive"><span id="golivetxt">Starte Produktivbetrieb</span></button>
</div>
</p>
<p>
<form action="dummy" method="GET">
<button type="submit" data-theme="d" id="shutdown_btn"><span id="shutdownbtntxt">Shutdown</span></button>
</form>
<div id="shutdownhinttxt"></div>
</p>
</div> <!-- collapsible Datenbank -->
<div id="tableforprint" class="printpart">Wenn dieser Text dargestellt wird, liegt ein Fehler vor!</div>
<div id="printserverdownloadpart" style="display:none;">
<a class="noprint" href="OrderSprinterPrintserver.exe" data-role="button" data-icon="arrow-d" data-ajax="false">Download Printserver</a>
</div> <!-- printerdownloadpart -->
<div data-role="footer" data-theme="b" id="thefooterr" class="noprint">
<div class="ui-grid-a">
<div class="ui-block-a userinfo" id="loggedinuser"></div>
@ -2465,7 +2617,7 @@ $(document).on("pageinit", "#admin-page", function () {
</div>
<div data-role="popup" id="nochangeddata" name="nochangeddata" data-overlay-theme="a" style="max-width:70%;" class="ui-corner-all">
<div data-role="popup" id="nochangeddata" data-overlay-theme="a" style="max-width:70%;" class="ui-corner-all">
<div data-role="header" class="ui-corner-top">
<h1>Keine Datenänderung</h1>
</div>

File diff suppressed because one or more lines are too long

View File

@ -17,20 +17,112 @@ class Admin {
private static $timezone = null;
private static $rights = array(
"createNewUser" => array("loggedin" => 1, "isadmin" => 0, "rights" => array("manager_or_admin")),
"updateUser" => array("loggedin" => 1, "isadmin" => 0, "rights" => array("manager_or_admin")),
"deleteUser" => array("loggedin" => 1, "isadmin" => 0, "rights" => array("manager_or_admin")),
"changepassword" => array("loggedin" => 1, "isadmin" => 0, "rights" => array("manager_or_admin")),
"changeConfig" => array("loggedin" => 1, "isadmin" => 0, "rights" => array("manager_or_admin")),
"readlogo" => array("loggedin" => 1, "isadmin" => 0, "rights" => array("manager_or_admin")),
"deletelogo" => array("loggedin" => 1, "isadmin" => 0, "rights" => array("manager_or_admin")),
"getCurrentUser" => array("loggedin" => 0, "isadmin" => 0, "rights" => null),
"tryAuthenticate" => array("loggedin" => 0, "isadmin" => 0, "rights" => null),
"setLastModuleOfUser" => array("loggedin" => 1, "isadmin" => 0, "rights" => null),
"getViewAfterLogin" => array("loggedin" => 1, "isadmin" => 0, "rights" => null),
"isUserAlreadyLoggedIn" => array("loggedin" => 0, "isadmin" => 0, "rights" => null),
"isLoggedinUserAdmin" => array("loggedin" => 0, "isadmin" => 0, "rights" => null),
"isLoggedinUserKitchen" => array("loggedin" => 0, "isadmin" => 0, "rights" => null),
"isLoggedinUserBar" => array("loggedin" => 0, "isadmin" => 0, "rights" => null),
"isLoggedinUserAdminOrManagerOrTE" => array("loggedin" => 0, "isadmin" => 0, "rights" => null),
"hasUserPaydeskRight" => array("loggedin" => 1, "isadmin" => 0, "rights" => null),
"getJsonMenuItemsAndVersion" => array("loggedin" => 0, "isadmin" => 0, "rights" => null),
"getUserList" => array("loggedin" => 0, "isadmin" => 0, "rights" => null),
"setTime" => array("loggedin" => 1, "isadmin" => 1, "rights" => null),
"changeOwnPassword" => array("loggedin" => 1, "isadmin" => 0, "rights" => null),
"setUserLanguage" => array("loggedin" => 1, "isadmin" => 0, "rights" => null),
"setUserReceiptPrinter" => array("loggedin" => 1, "isadmin" => 0, "rights" => null),
"setBtnSize" => array("loggedin" => 1, "isadmin" => 0, "rights" => null),
"getGeneralConfigItems" => array("loggedin" => 1, "isadmin" => 0, "rights" => null),
"getWaiterSettings" => array("loggedin" => 1, "isadmin" => 0, "rights" => null),
"getPayPrintType" => array("loggedin" => 1, "isadmin" => 0, "rights" => null),
"getPayments" => array("loggedin" => 1, "isadmin" => 0, "rights" => null),
"autobackup" => array("loggedin" => 0, "isadmin" => 0, "rights" => null),
"shutdown" => array("loggedin" => 1, "isadmin" => 1, "rights" => null),
"backup" => array("loggedin" => 1, "isadmin" => 1, "rights" => null),
"restore" => array("loggedin" => 1, "isadmin" => 1, "rights" => null),
"golive" => array("loggedin" => 1, "isadmin" => 1, "rights" => null),
"drop" => array("loggedin" => 1, "isadmin" => 1, "rights" => null),
"fill" => array("loggedin" => 1, "isadmin" => 1, "rights" => null),
"fillSpeisekarte" => array("loggedin" => 1, "isadmin" => 1, "rights" => null),
"assignTaxes" => array("loggedin" => 1, "isadmin" => 1, "rights" => null),
"exportConfigCsv" => array("loggedin" => 1, "isadmin" => 0, "rights" => array("manager_or_admin")),
"exportUserCsv" => array("loggedin" => 1, "isadmin" => 0, "rights" => array("manager_or_admin")),
"setOrderVolume" => array("loggedin" => 1, "isadmin" => 0, "rights" => null),
"setPreferTableMap" => array("loggedin" => 1, "isadmin" => 0, "rights" => null),
"setKeepTypeLevel" => array("loggedin" => 1, "isadmin" => 0, "rights" => null),
"setApplyExtrasBtnPos" => array("loggedin" => 1, "isadmin" => 0, "rights" => null),
"getOrderVolume" => array("loggedin" => 1, "isadmin" => 0, "rights" => null),
"getButtonSizes" => array("loggedin" => 1, "isadmin" => 0, "rights" => null),
"getPreferTableMap" => array("loggedin" => 1, "isadmin" => 0, "rights" => null),
"getKeepTypeLevel" => array("loggedin" => 1, "isadmin" => 0, "rights" => null),
"getApplyExtrasBtnPos" => array("loggedin" => 1, "isadmin" => 0, "rights" => null),
"isInstalled" => array("loggedin" => 0, "isadmin" => 0, "rights" => null)
);
function __construct() {
$this->dbutils = new DbUtils();
$this->userrights = new Userrights();
$this->histfiller = new HistFiller();
}
function handleCommand($command) {
// these command are only allowed for user with manager or admin rights
$cmdArray = array('createNewUser', 'updateUser', 'deleteUser','changepassword' , 'changeConfig', 'readlogo','deletelogo');
if (in_array($command, $cmdArray)) {
if (!($this->userrights->hasCurrentUserRight('right_manager')) && !($this->userrights->hasCurrentUserRight('is_admin'))) {
echo "Benutzerrechte nicht ausreichend!";
private static function checkRights($command) {
if(session_id() == '') {
session_start();
}
if (!array_key_exists($command, self::$rights)) {
echo json_encode(array("status" => "ERROR", "code" => ERROR_COMMAND_NOT_FOUND, "msg" => ERROR_COMMAND_NOT_FOUND_MSG));
return false;
}
$cmdRights = self::$rights[$command];
if ($cmdRights["loggedin"] == 1) {
if (!isset($_SESSION['angemeldet']) || !$_SESSION['angemeldet']) {
echo json_encode(array("status" => "ERROR", "code" => ERROR_NOT_AUTHOTRIZED, "msg" => ERROR_NOT_AUTHOTRIZED_MSG));
return false;
}
}
if ($cmdRights["isadmin"] == 1) {
if (!isset($_SESSION['angemeldet']) || !$_SESSION['angemeldet']) {
echo json_encode(array("status" => "ERROR", "code" => ERROR_NOT_AUTHOTRIZED, "msg" => ERROR_NOT_AUTHOTRIZED_MSG));
return false;
} else {
if ($_SESSION['is_admin'] == 0) {
echo json_encode(array("status" => "ERROR", "code" => ERROR_COMMAND_NOT_ADMIN, "msg" => ERROR_COMMAND_NOT_ADMIN_MSG));
return false;
}
}
}
if (!is_null($cmdRights["rights"])) {
foreach($cmdRights["rights"] as $aRight) {
if ($aRight == 'manager_or_admin') {
if (($_SESSION['is_admin'] == 1) || ($_SESSION['right_manager'] == 1)) {
return true;
}
}
}
echo json_encode(array("status" => "ERROR", "code" => ERROR_NOT_AUTHOTRIZED, "msg" => ERROR_NOT_AUTHOTRIZED_MSG));
return false;
}
return true;
}
function handleCommand($command) {
if (!self::checkRights($command)) {
return false;
}
if ($command == 'tryAuthenticate') {
@ -51,8 +143,8 @@ class Admin {
$this->isLoggedinUserKitchen();
} else if ($command == 'isLoggedinUserBar') {
$this->isLoggedinUserBar();
} else if ($command == 'isLoggedinUserAdminOrManager') {
$this->isLoggedinUserAdminOrManager();
} else if ($command == 'isLoggedinUserAdminOrManagerOrTE') {
$this->isLoggedinUserAdminOrManagerOrTE();
} else if ($command == 'hasUserPaydeskRight') {
$this->hasUserPaydeskRight();
} else if ($command == 'getJsonMenuItemsAndVersion') {
@ -62,40 +154,9 @@ class Admin {
} else if ($command == 'setTime') {
$this->setTime($_POST['day'],$_POST['month'],$_POST['year'],$_POST['hour'],$_POST['minute']);
} else if ($command == 'createNewUser') {
$this->createNewUser(
$_POST['username'],
$_POST['password'],
$_POST['isAdmin'],
$_POST['rWaiter'],
$_POST['rKitchen'],
$_POST['rBar'],
$_POST['rSupply'],
$_POST['rPayDesk'],
$_POST['rStat'],
$_POST['rBill'],
$_POST['rProducts'],
$_POST['rReservation'],
$_POST['rRating'],
$_POST['rChangeprice'],
$_POST['rManager']
);
$this->createNewUser();
} else if ($command == 'updateUser') {
$this->updateUser(
$_POST['userid'],
$_POST['isAdmin'],
$_POST['rWaiter'],
$_POST['rKitchen'],
$_POST['rBar'],
$_POST['rSupply'],
$_POST['rPayDesk'],
$_POST['rStat'],
$_POST['rBill'],
$_POST['rProducts'],
$_POST['rReservation'],
$_POST['rRating'],
$_POST['rChangeprice'],
$_POST['rManager']
);
$this->updateUser();
} else if ($command == 'deleteUser') {
$this->deleteUser($_POST['userid']);
} else if ($command == 'changepassword') {
@ -125,14 +186,9 @@ class Admin {
$this->getPayments();
} else if ($command == 'autobackup') {
$this->backup('auto',$_POST['remoteaccesscode']);
} else if (($command == 'new') || ($command == 'shutdown') || ($command == 'backup') || ($command == 'restore') || ($command == 'drop') || ($command == 'fill') || ($command == 'fillSampleProdType') || ($command == 'fillSpeisekarte') || ($command == 'assignTaxes')) {
if ($this->isCurrentUserAdmin()) {
if ($command == 'fill') {
} else if ($command == 'fill') {
$this->fillSampleContent();
echo json_encode(array("status" => "OK"));
} else if ($command == 'fillSampleProdType') {
$this->fillSampleProdType("samples/speisekarte.txt");
echo json_encode(array("status" => "OK"));
} else if ($command == 'fillSpeisekarte') {
$this->fillSpeisekarte($_POST['speisekarte']);
} else if ($command == 'backup') {
@ -141,17 +197,15 @@ class Admin {
} else if ($command == 'restore') {
$this->restore();
return;
} else if ($command == 'golive') {
$this->golive();
return;
} else if ($command == 'shutdown') {
$this->shutdown();
return;
} else if ($command == 'assignTaxes') {
$this->assignTaxes($_POST['food'],$_POST['drinks']);
return;
}
} else {
echo json_encode(array("status" => "ERROR", "code" => ERROR_NOT_AUTHOTRIZED, "msg" => ERROR_NOT_AUTHOTRIZED_MSG));
}
// end area for admins
} else if ($command == 'exportConfigCsv') {
if ($this->isCurrentUserAdmin() || $this->hasCurrentUserRight('right_manager')) {
$this->exportConfigCsv();
@ -328,7 +382,8 @@ class Admin {
$rights = array($zeile['is_admin'],$zeile['right_waiter'],$zeile['right_kitchen'],
$zeile['right_bar'],$zeile['right_supply'],$zeile['right_paydesk'],
$zeile['right_statistics'],$zeile['right_bill'],$zeile['right_products'],
$zeile['right_reservation'],$zeile['right_changeprice'],$zeile['right_manager']);
$zeile['right_reservation'],$zeile['right_changeprice'],$zeile['right_manager'],
$zeile['right_closing']);
$right_rating = $zeile['right_rating'];
if (self::isOnlyRatingUser($rights,$right_rating, 1)) {
@ -346,6 +401,7 @@ class Admin {
$_SESSION['right_reservation'] = false;
$_SESSION['right_changeprice'] = false;
$_SESSION['right_manager'] = false;
$_SESSION['right_closing'] = false;
$_SESSION['keeptypelevel'] = false;
} else {
$_SESSION['is_admin'] = ($zeile['is_admin'] == 1 ? true : false);
@ -367,12 +423,14 @@ class Admin {
$_SESSION['right_rating'] = ($zeile['right_rating'] == 1 ? true : false);
$_SESSION['right_changeprice'] = ($zeile['right_changeprice'] == 1 ? true : false);
$_SESSION['right_manager'] = ($zeile['right_manager'] == 1 ? true : false);
$_SESSION['right_closing'] = ($zeile['right_closing'] == 1 ? true : false);
$_SESSION['keeptypelevel'] = ($zeile['keeptypelevel'] == 1 ? true : false);
}
$this->userrights->setSession($_SESSION['is_admin'], $_SESSION['right_waiter'], $_SESSION['right_kitchen'],
$_SESSION['right_bar'], $_SESSION['right_supply'], $_SESSION['right_paydesk'], $_SESSION['right_statistics'],
$_SESSION['right_bill'], $_SESSION['right_products'], $_SESSION['right_reservation'], $_SESSION['right_rating'], $_SESSION['right_changeprice'], $_SESSION['right_manager']);
$_SESSION['right_bill'], $_SESSION['right_products'], $_SESSION['right_reservation'], $_SESSION['right_rating'],
$_SESSION['right_changeprice'], $_SESSION['right_manager'], $_SESSION['right_closing']);
$assoc = array ("0" => "roombtnsize","1" => "tablebtnsize","2" => "prodbtnsize");
@ -874,7 +932,7 @@ class Admin {
$rights = array($_SESSION['is_admin'],$_SESSION['right_waiter'],$_SESSION['right_kitchen'],
$_SESSION['right_bar'],$_SESSION['right_supply'],$_SESSION['right_paydesk'],
$_SESSION['right_statistics'],$_SESSION['right_bill'],$_SESSION['right_products'],
$_SESSION['right_reservation'],$_SESSION['right_changeprice'],$_SESSION['right_manager']);
$_SESSION['right_reservation'],$_SESSION['right_changeprice'],$_SESSION['right_manager'],$_SESSION['right_closing']);
$right_rating = $_SESSION['right_rating'];
if (self::isOnlyRatingUser($rights, $right_rating, true)) {
@ -916,7 +974,7 @@ class Admin {
// always ok
$valid = true;
} else if ($view == 'manager.html') {
if (($_SESSION['is_admin'] == 1) || ($_SESSION['right_manager'] == 1)) {
if (($_SESSION['is_admin'] == 1) || ($_SESSION['right_manager'] == 1) || ($_SESSION['right_closing'] == 1)) {
$valid = true;
}
} else {
@ -928,7 +986,7 @@ class Admin {
$view = "preferences.html";
}
echo json_encode($view);
echo json_encode($view . "?v=1.2.0");
}
}
@ -941,9 +999,13 @@ class Admin {
}
}
function isLoggedinUserAdminOrManager() {
if ($this->hasCurrentUserRight('is_admin') || $this->hasCurrentUserRight('right_manager')) {
echo json_encode(YES);
function isLoggedinUserAdminOrManagerOrTE() {
if ($this->hasCurrentUserRight('is_admin')) {
echo json_encode("admin");
} else if ($this->hasCurrentUserRight('right_manager')) {
echo json_encode("manager");
} else if ($this->hasCurrentUserRight('right_closing')) {
echo json_encode("closing");
} else {
echo json_encode(NO);
}
@ -1009,13 +1071,6 @@ class Admin {
fclose ($handle);
}
private function fillSampleProdType($fileName) {
$speisekartenHandler = new TypeAndProductFileManager();
$speisekartenHandler->manageSpeisekarteFile($fileName);
$this->histfiller->readProdTableAndSendToHist();
}
private function assignTaxes($foodTax,$drinksTax) {
$pdo = DbUtils::openDbAndReturnPdoStatic();
$pdo->beginTransaction();
@ -1038,7 +1093,7 @@ class Admin {
$stmt->execute(array($foodTax,0));
$stmt->execute(array($drinksTax,1));
$this->histfiller->readAllProdsAndFillHistByDb($pdo);
HistFiller::readAllProdsAndFillHistByDb($pdo);
$pdo->commit();
echo json_encode (array("status" => "OK"));
@ -1140,23 +1195,24 @@ class Admin {
$rights = array($_SESSION['is_admin'],$_SESSION['right_waiter'],$_SESSION['right_kitchen'],
$_SESSION['right_bar'],$_SESSION['right_supply'],$_SESSION['right_paydesk'],
$_SESSION['right_statistics'],$_SESSION['right_bill'],$_SESSION['right_products'],
$_SESSION['right_reservation'],$_SESSION['right_changeprice'],$_SESSION['right_manager']);
$_SESSION['right_reservation'],$_SESSION['right_changeprice'],$_SESSION['right_manager'],
$_SESSION['right_closing']);
$right_rating = $_SESSION['right_rating'];
if (!self::isOnlyRatingUser($rights, $right_rating, true)) {
if ($_SESSION['right_waiter']) { $mainMenu[] = array("name" => $waitertxt[$lang], "link" => "waiter.html?v=1.1.30"); };
if ($_SESSION['right_kitchen']) { $mainMenu[] = array("name" => $kitchentxt[$lang], "link" => "kitchen.html?v=1.1.30"); };
if ($_SESSION['right_bar']) { $mainMenu[] = array("name" => "Bar", "link" => "bar.html?v=1.1.30"); };
if ($_SESSION['right_supply']) { $mainMenu[] = array("name" => $supplytxt[$lang], "link" => "supplydesk.html?v=1.1.30"); };
if ($_SESSION['right_paydesk']) { $mainMenu[] = array("name" => $paydesktxt[$lang], "link" => "paydesk.html?v=1.1.30"); };
if ($_SESSION['right_statistics']) { $mainMenu[] = array("name" => $stattxt[$lang], "link" => "reports.html?v=1.1.30"); };
if ($_SESSION['right_bill']) { $mainMenu[] = array("name" => $bontxt[$lang], "link" => "bill.html?v=1.1.30"); };
if ($_SESSION['right_products']) { $mainMenu[] = array("name" => $prodtxt[$lang], "link" => "products.html?v=1.1.30"); };
if ($_SESSION['right_reservation']) { $mainMenu[] = array("name" => $restxt[$lang], "link" => "reservation.html?v=1.1.30"); };
if ($_SESSION['right_rating']) { $mainMenu[] = array("name" => $ratingtxt[$lang], "link" => "rating.html?v=1.1.30"); };
if ($_SESSION['right_manager'] || $_SESSION['is_admin']) { $mainMenu[] = array("name" => $admintxt[$lang], "link" => "manager.html?v=1.1.30"); };
$mainMenu[] = array("name" => $settingtxt[$lang], "link" => "preferences.html?v=1.1.30");
$mainMenu[] = array("name" => "Feedback", "link" => "feedback.html?v=1.1.30");
if ($_SESSION['right_waiter']) { $mainMenu[] = array("name" => $waitertxt[$lang], "link" => "waiter.html?v=1.2.0"); };
if ($_SESSION['right_kitchen']) { $mainMenu[] = array("name" => $kitchentxt[$lang], "link" => "kitchen.html?v=1.2.0"); };
if ($_SESSION['right_bar']) { $mainMenu[] = array("name" => "Bar", "link" => "bar.html?v=1.2.0"); };
if ($_SESSION['right_supply']) { $mainMenu[] = array("name" => $supplytxt[$lang], "link" => "supplydesk.html?v=1.2.0"); };
if ($_SESSION['right_paydesk']) { $mainMenu[] = array("name" => $paydesktxt[$lang], "link" => "paydesk.html?v=1.2.0"); };
if ($_SESSION['right_statistics']) { $mainMenu[] = array("name" => $stattxt[$lang], "link" => "reports.html?v=1.2.0"); };
if ($_SESSION['right_bill']) { $mainMenu[] = array("name" => $bontxt[$lang], "link" => "bill.html?v=1.2.0"); };
if ($_SESSION['right_products']) { $mainMenu[] = array("name" => $prodtxt[$lang], "link" => "products.html?v=1.2.0"); };
if ($_SESSION['right_reservation']) { $mainMenu[] = array("name" => $restxt[$lang], "link" => "reservation.html?v=1.2.0"); };
if ($_SESSION['right_rating']) { $mainMenu[] = array("name" => $ratingtxt[$lang], "link" => "rating.html?v=1.2.0"); };
if ($_SESSION['right_manager'] || $_SESSION['is_admin'] || $_SESSION['right_closing']) { $mainMenu[] = array("name" => $admintxt[$lang], "link" => "manager.html?v=1.2.0"); };
$mainMenu[] = array("name" => $settingtxt[$lang], "link" => "preferences.html?v=1.2.0");
$mainMenu[] = array("name" => "Feedback", "link" => "feedback.html?v=1.2.0");
}
$mainMenu[] = array("name" => $logout[$lang], "link" => "logout.php");
@ -1165,7 +1221,7 @@ class Admin {
$waiterMessage = $this->getMessage(null, "waitermessage");
}
// CAUTION: change version also in config.txt!!!
$mainMenuAndVersion = array ("version" => "OrderSprinter 1.1.30",
$mainMenuAndVersion = array ("version" => "OrderSprinter 1.2.0",
"user" => $currentUser,
"menu" => $mainMenu,
"waitermessage" => $waiterMessage,
@ -1209,16 +1265,19 @@ class Admin {
}
function createNewUser($username, $password, $isAdmin, $rWaiter, $rKitchen, $rBar, $rSupply, $rPayDesk, $rStat, $rBill, $rProducts, $rReservation, $rRating, $rChangeprice, $rManager) {
function createNewUser() {
$pdo = DbUtils::openDbAndReturnPdoStatic();
$username = $_POST['username'];
$isAdmin = $_POST['isAdmin'];
$password = $_POST['password'];
$sql = "SELECT count(id) as countid FROM %user% WHERE active='1' AND username=?";
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
$stmt->execute(array($username));
$row = $stmt->fetchObject();
if ($row->countid > 0) {
echo json_encode("exists");
echo json_encode(array("status" => "ERROR", "code" => ERROR_NAME_EXISTS_ALREADY, "msg" => ERROR_NAME_EXISTS_ALREADY_MSG));
return;
} else {
// create the new user
@ -1229,25 +1288,42 @@ class Admin {
$lang = $_SESSION['language'];
if ($isAdmin && !($this->isCurrentUserAdmin())) {
echo json_encode("noadmin");
echo json_encode(array("status" => "ERROR", "code" => ERROR_COMMAND_NOT_ADMIN, "msg" => ERROR_COMMAND_NOT_ADMIN_MSG));
return;
} else {
// instead if password_hash (PHP > 5.5) use MD5...
$password_hash = md5($password);
$userInsertSql = "INSERT INTO `%user%` (`id` , `username` , `userpassword`, `is_admin`, `right_waiter`,`right_kitchen`,`right_bar`,`right_supply`,`right_paydesk`,`right_statistics`,`right_bill`,`right_products`,`right_reservation`,`right_rating`,`right_changeprice`,`right_manager`,`language`,`receiptprinter`,`prefertablemap`,`keeptypelevel`,`extrasapplybtnpos`,`active`) VALUES (";
$userInsertSql .= " NULL, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
$keys = array('id','userpassword','language');
$vals = array(null,$password_hash,$lang);
$quests = array('?','?','?');
foreach(DbUtils::$userCols as $userCol) {
if (!is_null($userCol["new"])) {
$quests[] = '?';
$keys[] = $userCol["col"];
$vals[] = $_POST[$userCol['new']];
} else if (isset($userCol["default"])) {
$quests[] = '?';
$keys[] = $userCol["col"];
$vals[] = $userCol["default"];
}
}
$keysStr = join(",",$keys);
$questsStr = join(",",$quests);
$userInsertSql = "INSERT INTO %user% (" . $keysStr . ") VALUES(" . $questsStr . ")";
$stmt = $pdo->prepare(DbUtils::substTableAlias($userInsertSql));
$stmt->execute(array($username,$password_hash,$isAdmin,$rWaiter,$rKitchen,$rBar,$rSupply,$rPayDesk,$rStat,$rBill,$rProducts,$rReservation,$rRating,$rChangeprice,$rManager,$lang,1,1,0,1,1));
$stmt->execute($vals);
$lastId = $pdo->lastInsertId();
echo json_encode("OK");
echo json_encode(array("status" => "OK"));
}
}
// now this has to be logged in the history tables...
$this->histfiller->createUserInHist($pdo,$lastId,$username,
$isAdmin,$rWaiter,$rKitchen,$rBar,$rSupply,$rPayDesk,$rStat,$rBill,$rProducts,$rReservation,$rRating,$rChangeprice,$rManager);
HistFiller::createUserInHist($pdo,$lastId);
}
function getPayPrintType() {
@ -1428,10 +1504,10 @@ class Admin {
$this->changeOneConfigDbItem($pdo,$dbcol,$aVal,"%config%",true);
}
}
if ($problem) {
echo json_encode("FAILED");
if (!$problem) {
echo json_encode(array("status" => "OK"));
} else {
echo json_encode("OK");
echo json_encode(array("status" => "ERROR", "code" => ERROR_COMMAND_ERROR, "msg" => ERROR_COMMAND_ERROR_MSG));
}
}
@ -1468,14 +1544,16 @@ class Admin {
return $theUserId;
}
function updateUser($theUserId, $isAdmin, $rWaiter, $rKitchen, $rBar, $rSupply, $rPayDesk, $rStat, $rBill, $rProducts, $rReservation, $rRat, $rChangeprice, $rManager) {
function updateUser() {
// get the name of the user
$pdo = $this->dbutils->openDbAndReturnPdo();
$pdo = DbUtils::openDbAndReturnPdoStatic();
$theUserId = $_POST['userid'];
$isAdmin = $_POST['isAdmin'];
$sql = "SELECT username,is_admin FROM %user% WHERE id=?";
$stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql));
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
$stmt->execute(array($theUserId));
$row = $stmt->fetchObject();
$username = $row->username;
$userToModIsAdmin = $row->is_admin;
$doChangeAdminRights = false;
@ -1486,14 +1564,23 @@ class Admin {
if ($doChangeAdminRights && !($this->isCurrentUserAdmin())) {
echo json_encode("noadmin");
} else {
$sql = "UPDATE %user% SET is_admin=?, right_waiter=?,right_kitchen=?,right_bar=?,right_supply=?,right_paydesk=?,right_statistics=?,right_bill=?,right_products=?,right_reservation=?,right_rating=?,right_changeprice=?,right_manager=? WHERE active='1' AND id=?";
$stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql));
$stmt->execute(array($isAdmin,$rWaiter,$rKitchen,$rBar,$rSupply,$rPayDesk,$rStat,$rBill,$rProducts,$rReservation,$rRat,$rChangeprice,$rManager,$theUserId));
$keys = array();
$vals = array();
// now this has to be logged in the history tables...
foreach(DbUtils::$userCols as $userCol) {
if (!is_null($userCol["update"])) {
$keys[] = $userCol["col"] . "=?";
$vals[] = $_POST[$userCol["update"]];
}
}
$vals[] = $theUserId;
$this->histfiller->updateUserInHist($pdo,$theUserId,$username,
$isAdmin,$rWaiter,$rKitchen,$rBar,$rSupply,$rPayDesk,$rStat,$rBill,$rProducts,$rReservation,$rRat,$rChangeprice,$rManager,'1');
$keysStr = join(",",$keys);
$sql = "UPDATE %user% SET " . $keysStr . " WHERE active='1' AND id=?";
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
$stmt->execute($vals);
HistFiller::updateUserInHist($pdo,$theUserId);
echo json_encode("OK");
}
@ -1524,7 +1611,7 @@ class Admin {
$stmt = $pdo->prepare(DbUtils::substTableAlias($userSql));
$stmt->execute(array($theUserId));
$this->histfiller->updateOneUser($pdo,$theUserId);
HistFiller::updateUserInHist($pdo,$theUserId);
echo json_encode("OK");
}
@ -1532,9 +1619,6 @@ class Admin {
}
function getCurrentUser() {
if(session_id() == '') {
session_start();
}
if (!isset($_SESSION['angemeldet']) || !$_SESSION['angemeldet']) {
// no user logged in
echo json_encode("Nobody");
@ -1700,11 +1784,11 @@ class Admin {
$pdo = DbUtils::openDbAndReturnPdoStatic();
$this->writeCsvHeader("datenexport-benutzer.csv");
echo("Eintragsid; Datum ; Benutzerid; Benutzername; Adminrechte; Kellnerrechte;Kuechenrechte; Barrechte; Bereitstellungsrechte; Kassenrechte; Reportrechte; Kassenbonrechte; Angebotsrechte; Beurteilungsrechte; Preisänderungsrechte; Managerrechte; Aktiviert\n");
echo("Eintragsid; Datum ; Benutzerid; Benutzername; Adminrechte; Kellnerrechte;Kuechenrechte; Barrechte; Bereitstellungsrechte; Kassenrechte; Reportrechte; Kassenbonrechte; Angebotsrechte; Beurteilungsrechte; Preisänderungsrechte; Tageserfassungsrecht; Managerrechte; Aktiviert\n");
$sql = "SELECT DISTINCT %hist%.id as id,date,";
$sql .= "userid,username,is_admin,right_waiter,right_kitchen,right_bar,right_supply,";
$sql .= "right_paydesk,right_statistics,right_bill,right_products,right_rating,right_changeprice,right_manager,active,";
$sql .= "right_paydesk,right_statistics,right_bill,right_products,right_rating,right_changeprice,right_closing,right_manager,active,";
$sql .= "description ";
$sql .= " FROM %hist%, %histuser%, %histactions% ";
$sql .= " WHERE (refid=%histuser%.id) ";
@ -1732,12 +1816,13 @@ class Admin {
$val13 = ($zeile['right_products'] == '1' ? "Ja" : "Nein");
$val14 = ($zeile['right_rating'] == '1' ? "Ja" : "Nein");
$val15 = ($zeile['right_changeprice'] == '1' ? "Ja" : "Nein");
$val16 = ($zeile['right_manager'] == '1' ? "Ja" : "Nein");
$val17 = ($zeile['active'] == '1' ? "Ja" : "Nein");
$val18 = $zeile['description'];
$val16 = ($zeile['right_closing'] == '1' ? "Ja" : "Nein");
$val17 = ($zeile['right_manager'] == '1' ? "Ja" : "Nein");
$val18 = ($zeile['active'] == '1' ? "Ja" : "Nein");
$val19 = $zeile['description'];
echo "$val1; $val2; $val3; $val4; $val5; $val6; $val7; $val8; $val9; $val10;";
echo "$val11;$val12;$val13;$val14;$val15;$val16;$val17;$val18\n";
echo "$val11;$val12;$val13;$val14;$val15;$val16;$val17;$val18;$val19\n";
}
}
@ -1814,8 +1899,7 @@ class Admin {
if ($theType == "configuration") {
$tables = $this->getConfigTablesToBackupRestore();
} else {
$histFiller = new HistFiller();
$histFiller->insertSaveHistEntry($pdo);
HistFiller::insertSaveHistEntry($pdo);
$tables = $this->getAllTablesToBackupRestore();
}
@ -1961,8 +2045,7 @@ class Admin {
}
if (!$typeIsOnlyConfig) {
$histFiller = new HistFiller();
$histFiller->insertRestoreHistEntry($pdo);
HistFiller::insertRestoreHistEntry($pdo);
}
$basedb->signLastBillid($pdo);
@ -2023,6 +2106,91 @@ class Admin {
}
}
private function golive() {
try {
$pdo = DButils::openDbAndReturnPdoStatic();
self::doSql($pdo, "DELETE FROM %hist%", null);
self::doSql($pdo, "DELETE FROM %histprod%", null);
self::doSql($pdo, "DELETE FROM %histconfig%", null);
self::doSql($pdo, "DELETE FROM %histuser%", null);
HistFiller::readUserTableAndSendToHist($pdo);
$products = new Products();
$menu = $products->getSpeisekarte($pdo);
if ($menu['status'] != "OK") {
echo json_encode(array("status" => "ERROR", "code" => ERROR_COMMAND_ERROR, "msg" => ERROR_COMMAND_ERROR_MSG));
return;
} else {
self::doSql($pdo, "SET foreign_key_checks = 0;", null);
self::doSql($pdo, "DELETE FROM %queueextras%", null);
self::doSql($pdo, "DELETE FROM %extrasprods%", null);
self::doSql($pdo, "DELETE FROM %extras%", null);
self::doSql($pdo, "DELETE FROM %billproducts%", null);
self::doSql($pdo, "DELETE FROM %queue%", null);
self::doSql($pdo, "DELETE FROM %printjobs%", null);
self::doSql($pdo, "DELETE FROM %bill%", null);
self::doSql($pdo, "DELETE FROM %ratings%", null);
self::doSql($pdo, "DELETE FROM %closing%", null);
self::doSql($pdo, "SET foreign_key_checks = 1;", null);
$ret = $this->fillSpeisekarteCore($pdo, $menu['msg']);
self::doSql($pdo, "DELETE FROM %products% WHERE removed is not null", null);
self::doSql($pdo, "SET foreign_key_checks = 0;", null);
self::doSql($pdo, "DELETE FROM %prodtype% WHERE removed is not null", null);
self::doSql($pdo, "SET foreign_key_checks = 1;", null);
if ($ret["status"] != "OK") {
echo json_encode(array("status" => "ERROR", "code" => ERROR_COMMAND_ERROR, "msg" => ERROR_COMMAND_ERROR_MSG));
return;
}
HistFiller::readAllProdsAndFillHistByDb($pdo);
self::doSql($pdo, "DELETE w FROM %histprod% w INNER JOIN %hist% e ON refid=w.id WHERE action='4'", null);
self::doSql($pdo, "DELETE FROM %hist% where action='4'", null);
}
self::doSql($pdo, "alter table %bill% drop foreign key billbillref", null);
self::doSql($pdo, "alter table %billproducts% drop foreign key billprodref", null);
self::doSql($pdo, "alter table %queue% drop foreign key queuebillref", null);
self::doSql($pdo, "ALTER TABLE %bill% DROP id", null);
self::doSql($pdo, "ALTER TABLE %bill% ADD id INT (10) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST", null);
self::doSql($pdo, "ALTER TABLE %bill% ADD CONSTRAINT billbillref FOREIGN KEY (ref) REFERENCES %bill%(id)", null);
self::doSql($pdo, "ALTER TABLE %billproducts% ADD CONSTRAINT billprodref FOREIGN KEY (billid) REFERENCES %bill%(id)", null);
self::doSql($pdo, "ALTER TABLE %queue% ADD CONSTRAINT queuebillref FOREIGN KEY (billid) REFERENCES %bill%(id)", null);
self::doSql($pdo, "alter table %bill% drop foreign key billclosingref", null);
self::doSql($pdo, "ALTER TABLE %closing% DROP id", null);
self::doSql($pdo, "ALTER TABLE %closing% ADD id INT (10) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST", null);
self::doSql($pdo, "ALTER TABLE %bill% ADD CONSTRAINT billclosingref FOREIGN KEY (closingid) REFERENCES %closing%(id)", null);
$basedb = new Basedb();
$basedb->setPrefix(TAB_PREFIX);
$basedb->setTimeZone(DbUtils::getTimeZone());
$basedb->signLastBillid($pdo);
$histFiller = new HistFiller();
$histFiller->readConfigTableAndSendToHist();
self::doSql($pdo, "DELETE FROM %resttables% WHERE removed is not null", null);
self::doSql($pdo, "DELETE FROM %room% WHERE removed is not null", null);
echo json_encode(array("status" => "OK"));
} catch(Exception $e) {
echo json_encode(array("status" => "ERROR", "code" => ERROR_COMMAND_ERROR, "msg" => ERROR_COMMAND_ERROR_MSG));
}
}
private static function doSql($pdo,$sql,$params) {
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
if (is_null($params)) {
$stmt->execute();
} else {
$stmt->execute($params);
}
}
}
?>

View File

@ -16,8 +16,8 @@ require_once 'translations.php';
}
function handleCommand($command) {
// all commands require manager rights
if (!($this->hasCurrentUserManagerOrAdminRights())) {
// all commands require closing,manager or admin rights
if (!($this->hasCurrentUserManagerOrAdminOrClosingRights())) {
if ($command != 'exportCsv') {
echo json_encode(array("status" => "ERROR", "code" => ERROR_MANAGER_NOT_AUTHOTRIZED, "msg" => ERROR_MANAGER_NOT_AUTHOTRIZED_MSG));
} else {
@ -45,13 +45,13 @@ echo "Command not supported.";
}
}
private function hasCurrentUserManagerOrAdminRights() {
private function hasCurrentUserManagerOrAdminOrClosingRights() {
session_start();
if (!isset($_SESSION['angemeldet']) || !$_SESSION['angemeldet']) {
// no user logged in
return false;
} else {
return ($_SESSION['right_manager'] || $_SESSION['is_admin']);
return ($_SESSION['right_manager'] || $_SESSION['right_closing'] || $_SESSION['is_admin']);
}
}

View File

@ -155,5 +155,54 @@ class DbUtils {
return self::$timezone;
}
}
public static $userCols = array(
array("col" => 'id', "hist" => 1, "new" => null, "update" => null),
array("col" => 'username', "hist" => 1, "new" => 'username', "update" => null),
array("col" => 'userpassword', "hist" => 0, "new" => null, "update" => null),
array("col" => 'is_admin', "hist" => 1, "new" => 'isAdmin', "update" => 'isAdmin'),
array("col" => 'right_waiter', "hist" => 1, "new" => 'rWaiter', "update" => 'rWaiter'),
array("col" => 'right_kitchen', "hist" => 1, "new" => 'rKitchen', "update" => 'rKitchen'),
array("col" => 'right_bar', "hist" => 1, "new" => 'rBar', "update" => 'rBar'),
array("col" => 'right_supply', "hist" => 1, "new" => 'rSupply', "update" => 'rSupply'),
array("col" => 'right_paydesk', "hist" => 1, "new" => 'rPayDesk', "update" => 'rPayDesk'),
array("col" => 'right_statistics', "hist" => 1, "new" => 'rStat', "update" => 'rStat'),
array("col" => 'right_bill', "hist" => 1, "new" => 'rBill', "update" => 'rBill'),
array("col" => 'right_products', "hist" => 1, "new" => 'rProducts', "update" => 'rProducts'),
array("col" => 'right_reservation', "hist" => 1, "new" => 'rReservation', "update" => 'rReservation'),
array("col" => 'right_rating', "hist" => 1, "new" => 'rRating', "update" => 'rRating'),
array("col" => 'right_changeprice', "hist" => 1, "new" => 'rChangeprice', "update" => 'rChangeprice'),
array("col" => 'right_manager', "hist" => 1, "new" => 'rManager', "update" => 'rManager'),
array("col" => 'right_closing', "hist" => 1, "new" => 'rClosing', "update" => 'rClosing'),
array("col" => 'active', "hist" => 1, "new" => null ,"default" => 1, "update" => null),
array("col" => 'lastmodule', "hist" => 0, "new" => null ,"default" => null, "update" => null),
array("col" => 'ordervolume', "hist" => 0, "new" => null ,"default" => null, "update" => null),
array("col" => 'language', "hist" => 0, "new" => null, "update" => null),
array("col" => 'receiptprinter', "hist" => 0, "new" => null ,"default" => null, "update" => null),
array("col" => 'roombtnsize', "hist" => 0, "new" => null ,"default" => null, "update" => null),
array("col" => 'tablebtnsize', "hist" => 0, "new" => null ,"default" => null, "update" => null),
array("col" => 'prodbtnsize', "hist" => 0, "new" => null ,"default" => null, "update" => null),
array("col" => 'prefertablemap', "hist" => 0, "new" => null ,"default" => 1, "update" => null),
array("col" => 'keeptypelevel', "hist" => 0, "new" => null ,"default" => 0, "update" => null),
array("col" => 'extrasapplybtnpos', "hist" => 0, "new" => null ,"default" => 1, "update" => null)
);
public static $prodCols = array(
array("col" => 'id', "hist" => 1),
array("col" => 'shortname', "hist" => 1),
array("col" => 'longname', "hist" => 1),
array("col" => 'priceA', "hist" => 1),
array("col" => 'priceB', "hist" => 1),
array("col" => 'priceC', "hist" => 1),
array("col" => 'tax', "hist" => 1),
array("col" => 'category', "hist" => 0),
array("col" => 'favorite', "hist" => 1),
array("col" => 'sorting', "hist" => 1),
array("col" => 'available', "hist" => 1),
array("col" => 'audio', "hist" => 1),
array("col" => 'removed', "hist" => 0)
);
}
?>

View File

@ -88,4 +88,13 @@ define ( 'ERROR_BILL_CANCEL_IMOSSIBLE_MSG', 'Stornierung unmöglich');
define ( 'FOOD_PRINT_TYPE', 1);
define ( 'DRINK_PRINT_TYPE', 2);
define ( 'PAY_PRINT_TYPE', 3);
define ( 'ERROR_COMMAND_NOT_FOUND', 29);
define ( 'ERROR_COMMAND_NOT_FOUND_MSG', 'Rechte für Kommando konnten nicht verifiziert werden');
define ( 'ERROR_COMMAND_NOT_ADMIN', 30);
define ( 'ERROR_COMMAND_NOT_ADMIN_MSG', 'Benutzer besitzt keine Admin-Rechte');
define ( 'ERROR_COMMAND_ERROR', 31);
define ( 'ERROR_COMMAND_ERROR_MSG', 'Kommando konnte nicht korrekt ausgeführt werden');
?>

View File

@ -59,7 +59,13 @@ class PrintQueue {
} else if ($command == 'getLogoAsWbmp') {
$this->getLogoAsWbmp();
} else if ($command == 'getPrintJobOverview') {
$this->getPrintJobOverview();
$pdo = DbUtils::openDbAndReturnPdoStatic();
$this->getPrintJobOverview($pdo);
} else if ($command == 'clearprintjobs') {
$pdo = DbUtils::openDbAndReturnPdoStatic();
$this->clearprintjobs($pdo);
} else if ($command == 'batchReceiptPrintJob') {
$this->batchReceiptPrintJob($_POST['start'],$_POST['end']);
} else {
echo "Kommando nicht erkannt!";
}
@ -96,7 +102,7 @@ class PrintQueue {
$stmt->execute(array($content,intval($kind) + 1,$printer));
}
function getPrintJobOverview() {
function getPrintJobOverview($pdo) {
if (!($this->userrights->hasCurrentUserRight('right_manager')) &&
!($this->userrights->hasCurrentUserRight('is_admin'))
) {
@ -104,8 +110,6 @@ class PrintQueue {
return;
}
$pdo = DbUtils::openDbAndReturnPdoStatic();
$jobs = array();
for ($printer=1;$printer<7;$printer++) {
// bills:
@ -128,6 +132,60 @@ class PrintQueue {
echo json_encode(array("status" => "OK", "msg" => $jobs));
}
// REM* delete all printjobs
function clearprintjobs($pdo) {
if (!($this->userrights->hasCurrentUserRight('right_manager')) &&
!($this->userrights->hasCurrentUserRight('is_admin'))
) {
echo json_encode(array("status" => "ERROR", "code" => ERROR_DB_PRIVS_MISSING, "msg" => ERROR_DB_PRIVS_MISSING_MSG));
return;
}
$sql = "DELETE FROM %printjobs%";
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
$stmt->execute();
$this->getPrintJobOverview($pdo);
}
function batchReceiptPrintJob($start,$end) {
try {
$start = intval($start);
$end = intval($end);
} catch (Exception $ex) {
echo json_encode(array("status" => "ERROR", "code" => NUMBERFORMAT_ERROR, "msg" => NUMBERFORMAT_ERROR_MSG));
return;
}
if(!($this->userrights->hasCurrentUserRight('right_bill'))) {
echo json_encode(array("status" => "ERROR", "code" => ERROR_BILL_NOT_AUTHOTRIZED, "msg" => ERROR_BILL_NOT_AUTHOTRIZED_MSG));
} else {
// REM* sort it that start is <= end job id
if ($start > $end) {
$tmp = $end;
$end = $start;
$start = $tmp;
}
if(session_id() == '') {
session_start();
}
$printer = $_SESSION['receiptprinter'];
$pdo = DbUtils::openDbAndReturnPdoStatic();
for($jobId=$start;$jobId <= $end;$jobId++) {
// REM* check if bill id exists
$sql = "SELECT count(id) as countid FROM %bill% WHERE id=?";
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
$stmt->execute(array($jobId));
$row =$stmt->fetchObject();
if ($row->countid == 1) {
// REM* yes, print
$printInsertSql = "INSERT INTO `%printjobs%` (`id` , `content`,`type`,`printer`) VALUES ( NULL,?,?,?)";
$stmt = $pdo->prepare(DbUtils::substTableAlias($printInsertSql));
$stmt->execute(array($jobId,'3',$printer));
}
}
echo json_encode(array("status" => "OK"));
}
}
function queueReceiptPrintJob($billid) {
// waiter, or manager, bill, admin rights required
if (!($this->userrights->hasCurrentUserRight('right_paydesk')) &&
@ -162,6 +220,7 @@ class PrintQueue {
if (!($this->userrights->hasCurrentUserRight('right_paydesk')) &&
!($this->userrights->hasCurrentUserRight('right_manager')) &&
!($this->userrights->hasCurrentUserRight('right_bill')) &&
!($this->userrights->hasCurrentUserRight('right_closing')) &&
!($this->userrights->hasCurrentUserRight('right_waiter')) &&
!($this->userrights->hasCurrentUserRight('is_admin'))
) {

View File

@ -6,6 +6,7 @@ require_once ('commonutils.php');
require_once ('utilities/userrights.php');
require_once ('utilities/HistFiller.php');
require_once ('utilities/sorter.php');
require_once ('utilities/TypeAndProducts/ProductEntry.php');
class Products {
var $dbutils;
@ -57,7 +58,8 @@ class Products {
$this->getMenuLevelUp($_GET['ref']);
} else if ($command == 'getSpeisekarte') {
if ($this->userrights->hasCurrentUserRight('is_admin') || ($this->userrights->hasCurrentUserRight('right_manager'))) {
$this->getSpeisekarte();
$pdo = DbUtils::openDbAndReturnPdoStatic();
echo json_encode($this->getSpeisekarte($pdo));
} else {
echo json_encode(array("status" => "ERROR", "code" => ERROR_NOT_AUTHOTRIZED, "msg" => ERROR_NOT_AUTHOTRIZED_MSG));
}
@ -109,8 +111,6 @@ class Products {
$this->getPriceLevelInfo();
} else if ($command == 'setPriceLevelInfo') {
$this->setPriceLevelInfo($_POST['priceLevelId']);
} else if ($command == 'getSpeisekarte') {
$this->getSpeisekarte();
} else if ($command == 'getAudioFiles') {
$this->getAudioFiles();
} else if ($command == 'addGeneralComment') {
@ -389,7 +389,7 @@ class Products {
function readDbProducts($pdo) {
$speisekarte = $this->readDbProductsWithRef_json_version($pdo,0,0);
$speisekarte .= $this->readExtrasFromDb(null);
$speisekarte .= $this->readExtrasFromDb($pdo);
return $speisekarte;
}
@ -402,7 +402,7 @@ class Products {
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_OBJ);
$extrasTxt = "";
$decpoint = $this->getDecPoint();
$decpoint = $this->getDecPoint($pdo);
foreach ($result as $aRes) {
$extrasTxt .= "!" . $aRes->name . " (ID:" . $aRes->id . ") #" ;
$priceTxt = number_format($aRes->price, 2, $decpoint, '');
@ -423,9 +423,8 @@ class Products {
return $extrasTxt;
}
private function getDecPoint() {
private function getDecPoint($pdo) {
$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();
@ -435,7 +434,7 @@ class Products {
private function exportCsv() {
$pdo = DbUtils::openDbAndReturnPdoStatic();
$decpoint = $this->getDecPoint();
$decpoint = $this->getDecPoint($pdo);
$file_name = "datenexport-produkte.csv";
header("Content-type: text/x-csv");
header("Content-Disposition: attachment; filename=$file_name");
@ -913,11 +912,8 @@ class Products {
if ($changeExtras == 1) {
$this->changeExtraAssignment($pdo, $id, $extras);
}
$histextra = self::getExtrasForProd($pdo,$id);
// now this has to be logged in the history tables...
$this->histfiller->updateProdInHist($pdo,$id, $shortname, $longname, $priceA, $priceB, $priceC, $tax,
NULL, $available,$audioFile,$favorite,$histextra);
HistFiller::updateProdInHist($pdo,$id);
} else {
$prodids = self::getAllProdIdOfSameTypeAndBelow($pdo,$id);
@ -934,14 +930,7 @@ class Products {
}
private static function updateHistOnlyForExtrasOfProd($pdo,$aProdId,$histextra) {
$sql = "SELECT shortname,longname,priceA,priceB,priceC,tax,available,audio,favorite FROM %products% WHERE id=?";
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
$stmt->execute(array($aProdId));
$row = $stmt->fetchObject();
$histfiller = new HistFiller();
$histfiller->updateProdInHist($pdo,$aProdId, $row->shortname, $row->longname, $row->priceA, $row->priceB, $row->priceC,
$row->tax, NULL, $row->available,$row->audio,$row->favorite,$histextra);
HistFiller::updateProdInHist($pdo, $aProdId);
}
function changeExtraAssignment($pdo,$prodid,$extras) {
@ -1037,9 +1026,7 @@ class Products {
$pdo->commit();
// now this has to be logged in the history tables...
$this->histfiller->createProdInHist ($pdo,$newProdId, $shortname, $longname, $priceA, $priceB, $priceC,$tax,
NULL, $available,$audioFile,$favorite);
HistFiller::createProdInHist($pdo, $newProdId);
echo json_encode("OK: sql");
}
@ -1119,9 +1106,8 @@ class Products {
// return in text format
private function readDbProductsWithRef_json_version($pdo,$ref,$depth) {
$decpoint = $this->getDecPoint();
$decpoint = $this->getDecPoint($pdo);
$text = "";
$allProdsAndTypesInThisLevel = array();
$allProdsInThisLevel = $this->getProductsWithReferenz($pdo,$ref);
$allTypesInThisLevel = $this->getProdTypesWithReferenz($pdo,$ref);
@ -1130,32 +1116,7 @@ class Products {
$aProd = $allProdsInThisLevel[$index_prod];
// Kurzname ; NormalPreis (Stufe A); Langname # Preis (Stufe B); Preis (Stufe C)
$shortname = $aProd['shortname'] . " (ID:" . $aProd['id'] . ")";
$longname = $aProd['longname'];
$available = $aProd['available'];
$prodid = $aProd['id'];
// prices (back from db-point to wished decimal point)
$priceA = str_replace('.',$decpoint,$aProd['priceA']);
$priceB = str_replace('.',$decpoint,$aProd['priceB']);
$priceC = str_replace('.',$decpoint,$aProd['priceC']);
$tax = str_replace('.',$decpoint,$aProd['tax']);
$prodstart = "$shortname ; $priceA";
if ($aProd['shortname'] != $longname) {
$prodstart .= " ; " . $longname;
}
if ($tax == "null") {
$tax = null;
}
if (($priceB != $priceA) || ($priceC != $priceA) || (!is_null($tax))) {
$prodText = "$prodstart # $priceB ; $priceC; $tax";
} else {
$prodText = "$prodstart";
}
$prodText = ProductEntry::createProductStr($aProd,$decpoint);
$text .= substr(" ", 0, $depth) . $prodText . "\n";
}
@ -1230,20 +1191,18 @@ class Products {
}
}
private function getSpeisekarte() {
$pdo = DbUtils::openDbAndReturnPdoStatic();
public function getSpeisekarte($pdo) {
$legend = file_get_contents("../customer/menulegend.txt");
$decpoint = $this->getDecPoint();
$pdo = $this->dbutils->openDbAndReturnPdo();
$decpoint = $this->getDecPoint($pdo);
$sql = "SELECT * FROM %products% WHERE removed is null";
$stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql));
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
$stmt->execute();
$numberOfProds = $stmt->rowCount();
$sql = "SELECT * FROM %prodtype% WHERE removed is null";
$stmt = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql));
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
$stmt->execute();
$numberOfProdTypes = $stmt->rowCount();
@ -1256,7 +1215,7 @@ class Products {
$text = $legend . $this->readDbProducts($pdo);
}
echo json_encode(array("status" => "OK","msg" => $text, "predef" => $predef));
return array("status" => "OK","msg" => $text, "predef" => $predef);
}
private function endsWith($haystack, $needle)

View File

@ -1107,27 +1107,43 @@ class QueueContent {
$tableid = null;
}
$sql = "SELECT count(%queue%.id) as mycount,productname, GROUP_CONCAT(%queue%.id) AS queueids FROM ";
$sql = "SELECT %queue%.id as queueid,productname FROM ";
$sql .= "%queue% WHERE ";
$sql .= "(tablenr=? OR (tablenr IS NULL AND ? IS NULL)) AND ordertime is not null AND isclosed is null AND billid is null ";
$sql .= "GROUP BY productid";
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
$stmt->execute(array($tableid,$tableid));
$unpaidresult = $stmt->fetchAll();
$unpaidresultungrouped = $stmt->fetchAll();
$sql = "SELECT count(%queue%.id) as mycount,productname, GROUP_CONCAT(%queue%.id) AS queueids FROM ";
$sql = "SELECT %queue%.id as queueid,productname FROM ";
$sql .= "%queue% LEFT OUTER JOIN %bill% ON %queue%.billid=%bill%.id WHERE ";
$sql .= "(tablenr=? OR (tablenr IS NULL AND ? IS NULL)) AND ordertime is not null AND isclosed is null AND billid is null AND (";
$sql .= "%queue%.delivertime = '0000-00-00 00:00:00' OR ";
$sql .= "(%queue%.delivertime <> '0000-00-00 00:00:00' AND workprinted='1')) ";
$sql .= "GROUP BY productid";
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
$stmt->execute(array($tableid,$tableid));
$undeliveredresult = $stmt->fetchAll();
$undeliveredresultungrouped = $stmt->fetchAll();
$merged = array();
foreach($unpaidresultungrouped as $entry) {
$qid = $entry["queueid"];
$prodname = $entry["productname"];
$status = "unpaid";
if ($this->isQueueIdInList($qid, $undeliveredresultungrouped)) {
$status = "unpaid_undelivered";
}
$merged[] = array("queueid" => $qid,"productname" => $prodname,"status" => $status);
}
echo json_encode(array("status" => "OK","unpaid" => $unpaidresult,"undeliveredunpaid" => $undeliveredresult));
echo json_encode(array("status" => "OK","msg" => $merged));
}
function isQueueIdInList($queueid,$list) {
foreach($list as $entry) {
if ($entry['queueid'] == $queueid) {
return true;
}
}
return false;
}

View File

@ -9,7 +9,6 @@ class HistFiller {
$this->dbutils = new DbUtils();
}
public function defineHistActions () {
$pdo = $this->dbutils->openDbAndReturnPdo();
$sql = "INSERT INTO %histactions% (id,name,description) VALUES (?,?,?)";
@ -27,164 +26,113 @@ class HistFiller {
$stmt->execute(array('10','DbRestore', 'Wiederherstellung der Datenbank aus einer Sicherungskopie'));
}
public function readUserTableAndSendToHist($pdo) {
private static function getColNamesForHistTable($tableDescr) {
$cols = array();
foreach($tableDescr as $aCol) {
if ($aCol["hist"] == 1) {
$cols[] = $aCol["col"];
}
}
return $cols;
}
private static function getColNamesForUserHistTable() {
return self::getColNamesForHistTable(DbUtils::$userCols);
}
public static function readUserTableAndSendToHist($pdo) {
$sql = "SELECT * FROM %user%";
$this->readSqlUserTableAndSendToHist($pdo,$sql,'3');
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
$stmt->execute(array());
$result = $stmt->fetchAll();
foreach($result as $aUser) {
self::createUserInHist($pdo, $aUser["id"]);
}
public function updateOneUser($pdo,$userid) {
$sql = "SELECT * FROM %user% WHERE id='$userid'";
$this->readSqlUserTableAndSendToHist($pdo,$sql,'8');
}
/*
* Read the complete user table and fill in these values to the histtable
*/
private function readSqlUserTableAndSendToHist($pdo,$sql_query, $histaction) {
$sql_insert_histuser = "INSERT INTO %histuser% (id,userid,username,
is_admin,right_waiter,right_kitchen,right_bar,right_supply,right_paydesk,right_statistics,
right_bill,right_products,right_reservation,right_rating,right_changeprice,right_manager,active) VALUES (
NULL,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
public static function createUserInHist($pdo,$userid) {
$pdo->beginTransaction();
$stmt_query = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql_query));
$stmt_insert_histuser = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql_insert_histuser));
$stmt_query->execute();
$result = $stmt_query->fetchAll();
foreach($result as $row){
$stmt_insert_histuser->execute(array($row['id'], $row['username'],
$row['is_admin'],$row['right_waiter'],$row['right_kitchen'],$row['right_bar'],
$row['right_supply'],$row['right_paydesk'],$row['right_statistics'],$row['right_bill'],
$row['right_products'],$row['right_reservation'],$row['right_rating'],$row['right_changeprice'],$row['right_manager'],$row['active']));
$newRefIdForHist = $pdo->lastInsertId();
$this->insertIntoHist($pdo, $histaction, $newRefIdForHist);
}
self::updateOrCreateUserInHist($pdo,$userid,'7');
$pdo->commit();
}
public function updateUserInHist($pdo,$userid,$username,
$isAdmin,$rWaiter,$rKitchen,$rBar,$rSupply,$rPayDesk,$rStat,$rBill,$rProducts,$rReservation,$rRat,$rChangeprice,$rManager,$active)
{
$this->updateOrCreateUserInHist($pdo,$userid,$username,
$isAdmin,$rWaiter,$rKitchen,$rBar,$rSupply,$rPayDesk,$rStat,
$rBill,$rProducts,$rReservation,$rRat,$rChangeprice,$rManager,$active,'8');
}
public function createUserInHist($pdo,$lastId,$username,
$isAdmin,$rWaiter,$rKitchen,$rBar,$rSupply,$rPayDesk,$rStat,$rBill,$rProducts,$rRes,$rRat,$rChangeprice,$rManager)
{
$this->updateOrCreateUserInHist($pdo,$lastId,$username,
$isAdmin,$rWaiter,$rKitchen,$rBar,$rSupply,$rPayDesk,$rStat,
$rBill,$rProducts,$rRes,$rRat,$rChangeprice,$rManager,'1','7');
}
public function updateOrCreateUserInHist($pdo,$id,$username,
$isAdmin,$rWaiter,$rKitchen,$rBar,$rSupply,$rPayDesk,$rStat,$rBill,$rProducts,$rRes,$rRat,$rChangeprice,$rManager,
$active,$histaction) {
$sql_insert_histuser = "INSERT INTO %histuser% (`id` , `userid`, `username` ,
`is_admin`, `right_waiter`,`right_kitchen`,`right_bar`,`right_supply`,`right_paydesk`,
`right_statistics`,`right_bill`,`right_products`,`right_reservation`,`right_rating`,`right_changeprice`,`right_manager`,`active`) VALUES (
NULL,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
public static function updateUserInHist($pdo,$userid) {
$pdo->beginTransaction();
$stmt_insert_histuser = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql_insert_histuser));
$stmt_insert_histuser->execute(array($id,$username,
$isAdmin,$rWaiter,$rKitchen,$rBar,$rSupply,$rPayDesk,$rStat,$rBill,$rProducts,$rRes,$rRat,$rChangeprice,$rManager,
$active));
$newRefIdForHist = $pdo->lastInsertId();
$this->insertIntoHist($pdo, $histaction, $newRefIdForHist);
self::updateOrCreateUserInHist($pdo,$userid,'8');
$pdo->commit();
}
public function insertSaveHistEntry($pdo) {
$this->insertIntoHist($pdo, 9, null);
private static function updateOrCreateUserInHist($pdo,$userid,$histaction) {
self::updateOrCreateEntryInHist($pdo, $userid, $histaction, self::getColNamesForUserHistTable(), 'userid', 'user','histuser',null,null);
}
public function insertRestoreHistEntry($pdo) {
$this->insertIntoHist($pdo, 10, null);
}
public function readAllProdsAndFillHistByDb($pdo) {
public static function readAllProdsAndFillHistByDb($pdo) {
$sql = "SELECT id FROM %products% WHERE removed is null";
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
$stmt->execute(array());
$result = $stmt->fetchAll();
foreach ($result as $aProd) {
$prodid = $aProd["id"];
foreach($result as $anElement) {
self::createProdInHist($pdo, $anElement["id"]);
}
}
private static function getColNamesForProdHistTable() {
return self::getColNamesForHistTable(DbUtils::$prodCols);
}
public static function createProdInHist($pdo,$prodid) {
self::updateOrCreateProdInHist($pdo,$prodid,'5');
}
public static function updateProdInHist($pdo,$prodid) {
self::updateOrCreateProdInHist($pdo,$prodid,'4');
}
private static function getExtrasList($pdo,$prodid) {
$sql = "SELECT GROUP_CONCAT(%extras%.name) as extraslist FROM %extras%,%extrasprods% WHERE %extrasprods%.prodid=? AND %extrasprods%.extraid=%extras%.id";
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
$stmt->execute(array($prodid));
$row =$stmt->fetchObject();
$extrasList = $row->extraslist;
return $row->extraslist;
}
private static function updateOrCreateProdInHist($pdo,$prodid,$histaction) {
$extras = self::getExtrasList($pdo, $prodid);
$extraCol = (is_null($extras) ? null : 'extras');
self::updateOrCreateEntryInHist($pdo, $prodid, $histaction, self::getColNamesForProdHistTable(), 'prodid', 'products', 'histprod',$extraCol,$extras);
}
$sql = "INSERT INTO %histprod% (id,prodid,shortname,longname,priceA,priceB,priceC,tax,sorting,available,extras) ";
$sql .= "SELECT null,id as prodid,shortname,longname,priceA,priceB,priceC,tax,sorting,available,'$extrasList' as extras FROM %products% ";
$sql .= "WHERE %products%.id=?";
private static function updateOrCreateEntryInHist($pdo,$id,$histaction,$colsInSourceTable,$idInHist,$sourcetable, $histtable,$extraCol,$extraVal) {
$sql = "SELECT * from %". $sourcetable . "% WHERE id=?";
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
$stmt->execute(array($prodid));
$stmt->execute(array($id));
$row = $stmt->fetchObject();
$cols = $colsInSourceTable;
array_splice($cols, 0, 1, $idInHist);
$valuesStr = implode(",", $cols);
$quests = array();
$vals = array();
foreach($colsInSourceTable as $aHistCol) {
$vals[] = $row->$aHistCol;
$quests[] = "?";
}
$sql_insert_hist = "INSERT INTO %". $histtable . "% (id," . $valuesStr . ") VALUES(NULL," . implode(",",$quests) . ")";
$stmt_insert_hist = $pdo->prepare(DbUtils::substTableAlias($sql_insert_hist));
$stmt_insert_hist->execute($vals);
$newRefIdForHist = $pdo->lastInsertId();
$this->insertIntoHist($pdo, '1', $newRefIdForHist);
}
if (!is_null($extraCol)) {
$sql = "UPDATE %". $histtable . "% SET " . $extraCol . "=? WHERE id=?";
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
$stmt->execute(array($extraVal,$newRefIdForHist));
}
/*
* Read the complete products table and fill in these values to the histtable
*/
public function readProdTableAndSendToHist($pdo) {
$sql_query = "SELECT * FROM %products% WHERE removed is null";
$sql_insert_histprod = "INSERT INTO %histprod% (id,prodid,shortname,longname,
priceA,priceB,priceC,tax,sorting,available,favorite) VALUES (
NULL,?,?,?,?,?,?,?,?,?,?)";
$stmt_query = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql_query));
$stmt_insert_histprod = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql_insert_histprod));
$stmt_query->execute();
$result = $stmt_query->fetchAll();
foreach($result as $row){
$stmt_insert_histprod->execute(array($row['id'], $row['shortname'],
$row['longname'],$row['priceA'],$row['priceB'],$row['priceC'],
$row['tax'],$row['sorting'],$row['available'],'0'));
$newRefIdForHist = $pdo->lastInsertId();
$this->insertIntoHist($pdo, '1', $newRefIdForHist);
}
self::insertIntoHist($pdo, $histaction, $newRefIdForHist);
}
public function updateProdInHist($pdo,$prodid,$shortname,$longname,
$priceA,$priceB,$priceC,$tax,$sorting,$available,$audioFile,$favorite,$histextra) {
$this->updateOrCreateProdInHist($pdo,$prodid,$shortname,$longname,
$priceA,$priceB,$priceC,$tax,$sorting,$available, '4',$audioFile,$favorite,$histextra);
public static function insertSaveHistEntry($pdo) {
self::insertIntoHist($pdo, 9, null);
}
public function createProdInHist($pdo,$prodid,$shortname,$longname,
$priceA,$priceB,$priceC,$tax,$sorting,$available,$audioFile,$favorite) {
$this->updateOrCreateProdInHist($pdo,$prodid,$shortname,$longname,
$priceA,$priceB,$priceC,$tax,$sorting,$available, '5',$audioFile,$favorite,null);
}
public function updateOrCreateProdInHist($pdo,$prodid,$shortname,$longname,
$priceA,$priceB,$priceC,$tax,$sorting,$available, $histaction,$audioFile,$favorite,$histextra) {
$sql_insert_histprod = "INSERT INTO %histprod% (id,prodid,shortname,longname,
priceA,priceB,priceC,tax,sorting,available,audio,favorite,extras) VALUES (
NULL,?,?,?,?,?,?,?,?,?,?,?,?)";
if (is_null($pdo)) {
$pdo = $this->dbutils->openDbAndReturnPdo();
}
$stmt_insert_histprod = $pdo->prepare($this->dbutils->resolveTablenamesInSqlString($sql_insert_histprod));
$stmt_insert_histprod->execute(array($prodid,$shortname,$longname,
$priceA,$priceB,$priceC,$tax,$sorting,$available,$audioFile,$favorite,$histextra));
$newRefIdForHist = $pdo->lastInsertId();
$this->insertIntoHist($pdo, $histaction, $newRefIdForHist);
public static function insertRestoreHistEntry($pdo) {
self::insertIntoHist($pdo, 10, null);
}
public function updateConfigInHist($pdo,$theItem, $theValue) {
@ -201,7 +149,7 @@ class HistFiller {
$stmt_insert_histconfig = $pdo->prepare(DbUtils::substTableAlias($sql_insert_histconfig));
$stmt_insert_histconfig->execute(array($theConfigId,"$theValue"));
$newRefIdForHist = $pdo->lastInsertId();
$this->insertIntoHist($pdo, '6', $newRefIdForHist);
self::insertIntoHist($pdo, '6', $newRefIdForHist);
$pdo->commit();
}
/*
@ -229,7 +177,7 @@ class HistFiller {
$pdo->commit();
}
private function insertIntoHist($pdo,$action,$refIdForHist) {
private static function insertIntoHist($pdo,$action,$refIdForHist) {
date_default_timezone_set(DbUtils::getTimeZone());
$currentTime = date('Y-m-d H:i:s');
$sql_insert_hist = "INSERT INTO %hist% (id,date,action,refid) VALUES (NULL,?,?,?)";

View File

@ -1,6 +1,7 @@
<?php
// print_r(explode('|', $str, 2));
class ProductEntry {
private $shortName; // the name that shall appear on the button of the waiter
private $priceA; // the price of the product (default)
private $priceB; // price level B
@ -8,73 +9,109 @@ class ProductEntry {
private $tax;
private $longName; // the name that shall appear on the receipt
private $prodid = null;
private $available = 1;
private static $PRICE_B = "PreisB";
private static $PRICE_C = "PreisC";
private static $TAX = "Fixsteuersatz";
private static $SHORTNAME = "Kurzname";
private static $AVAILABLE = "vorhanden";
private static $ID = "ID";
//
public static function createProductStr($aProd, $decpoint) {
$shortname = $aProd['shortname'];
$longname = $aProd['longname'];
$prodId = $aProd['id'];
$available = $aProd['available'];
$priceA = str_replace('.', $decpoint, $aProd['priceA']);
$priceB = str_replace('.', $decpoint, $aProd['priceB']);
$priceC = str_replace('.', $decpoint, $aProd['priceC']);
$tax = str_replace('.', $decpoint, $aProd['tax']);
$prodText = "$longname; $priceA";
$extArr = array();
if ($shortname != $longname) {
$extArr[] = self::$SHORTNAME . ":" . $shortname;
}
if (!is_null($tax) && ($tax != "null")) {
$extArr[] = self::$TAX . ":" . $tax;
}
if (($priceB != $priceA) || ($priceC != $priceA)) {
$extArr[] = self::$PRICE_B . ":$priceB";
$extArr[] = self::$PRICE_C . ":$priceC";
}
if ($available == 0) {
$extArr[] = self::$AVAILABLE . ":nein";
}
if (!is_null($prodId)) {
$extArr[] = self::$ID . ":" . $prodId;
}
if (count($extArr) > 0) {
$prodText .= " # " . join("; ", $extArr);
}
return $prodText;
}
// Constructor - gehts the line as it is in the Speisekarte
function parse($aTextLine) {
try {
// is there multiple price levels?
$numberOfPrices = 1;
$priceparts = explode('#', $aTextLine, 2);
$price_level_B = "0.00";
$price_level_C = "0.00";
$price_tax = null;
$aTextLine = trim($aTextLine);
$propertyparts = explode('#', $aTextLine, 2);
if (count($priceparts) == 2) {
// there is a # in the line --> probably two prices
$otherPrices = $priceparts[1];
// are there level 2&3 or only 2?
$otherPriceParts = explode(';', $otherPrices, 3);
$price_level_B = floatval(str_replace(",",".",(string) $otherPriceParts[0]));
if (count($otherPriceParts) == 1) {
$numberOfPrices = 2;
} else if (count($otherPriceParts) == 2) {
$price_level_C = floatval(str_replace(",",".",(string) $otherPriceParts[1]));
$numberOfPrices = 3;
} else if (count($otherPriceParts) == 3) {
$price_level_C = floatval(str_replace(",",".",(string) $otherPriceParts[1]));
$price_tax = floatval(str_replace(",",".",(string) $otherPriceParts[2]));
$numberOfPrices = 4;
$shortAndPriceA = $propertyparts[0];
$basic = explode(';',$shortAndPriceA);
$this->longName = $basic[0];
$this->priceA = floatval(str_replace(",",".",(string) $basic[1]));
$this->priceB = null;
$this->priceC = null;
$this->shortName = null;
if (count($propertyparts) > 1) {
if (trim($propertyparts[1]) == "") {
return;
}
$exts = explode(";",$propertyparts[1]);
foreach($exts as $anExtProp) {
$parts = explode(":",$anExtProp);
$identifier = trim($parts[0]);
$value = trim($parts[1]);
if ($identifier == self::$PRICE_B) {
$this->priceB = floatval(str_replace(",",".",(string) $value));
} else if ($identifier == self::$PRICE_C) {
$this->priceC = floatval(str_replace(",",".",(string) $value));
} else if ($identifier == self::$AVAILABLE) {
if (($value == "ja") || ($value == "yes") || ($value == "si") || ($value == "1")) {
$this->available = 1;
} else {
// undefined
$numberOfPrices = 1; // fall back to default
$this->available = 0;
}
} else if ($identifier == self::$TAX) {
$this->tax = floatval(str_replace(",",".",(string) $value));
} else if ($identifier == self::$SHORTNAME) {
$this->shortName = $value;
} else if ($identifier == self::$ID) {
$this->prodid = $value;
}
}
}
$parts = explode(';', $priceparts[0], 4);
$this->shortName = trim($parts[0]);
$matches = array();
preg_match('/\(ID:([0-9]+)\)$/', $this->shortName,$matches,PREG_OFFSET_CAPTURE);
if (count($matches) > 0) {
$theMatch = $matches[0];
$this->prodid = intval(substr($theMatch[0],4,strlen($theMatch[0])-5));
$theMatchPos = $theMatch[1];
$this->shortName = trim(substr($this->shortName,0,$theMatchPos-1));
}
$this->longName = $this->shortName;
$this->priceA = floatval(str_replace(",",".",(string) $parts[1]));
// default: all the same price
if (is_null($this->priceB)) {
$this->priceB = $this->priceA;
}
if (is_null($this->priceC)) {
$this->priceC = $this->priceA;
$this->tax = null;
if ($numberOfPrices == 2) {
$this->priceB = $price_level_B; // A = C, only B is different
} else if ($numberOfPrices == 3) {
$this->priceB = $price_level_B;
$this->priceC = $price_level_C;
} else if ($numberOfPrices == 4) {
$this->priceB = $price_level_B;
$this->priceC = $price_level_C;
$this->tax = $price_tax;
}
if (count($parts) > 2) {
$thirdpart = trim($parts[2]);
if ($thirdpart != "") {
// in this case the button name is the not same as the name on the bill
$this->longName = trim($parts[2]);
}
if (is_null($this->shortName)) {
$this->shortName = $this->longName;
}
return array("status" => "OK");
} catch (Exception $e) {
@ -85,24 +122,35 @@ class ProductEntry {
function getShortName() {
return $this->shortName;
}
function getPriceA() {
return $this->priceA;
}
function getPriceB() {
return $this->priceB;
}
function getPriceC() {
return $this->priceC;
}
function getTax() {
return $this->tax;
}
function getLongName() {
return $this->longName;
}
function getProdId() {
return $this->prodid;
}
function getAvailable() {
return $this->available;
}
function toString() {
return "S:" . $this->shortName . " PA:" . $this->priceA . " PB:" . $this->priceB . " PC:" . $this->priceC . " Tax:" . $this->tax . " R:" . $this->longName;
}

View File

@ -339,7 +339,6 @@ class TypeAndProductFileManager {
}
private function fillProductDbTable($pdo,$leafArray) {
$histFiller = new HistFiller();
for ($i=0;$i < $leafArray->size(); $i++) {
$theLeafEntry = $leafArray->get($i);
$product = new ProductEntry();
@ -354,7 +353,7 @@ class TypeAndProductFileManager {
$shortName = $product->getShortName();
$longName = $product->getLongName();
$prodid = $product->getProdId();
$available = 1; // default: product is available
$available = $product->getAvailable();
$favorite = 0;
$category = $theLeafEntry->getReference();
@ -375,10 +374,10 @@ class TypeAndProductFileManager {
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
$stmt->execute(array($shortName,$longName,$priceA,$priceB,$priceC,$tax, $category,$available,$favorite));
$prodid = $pdo->lastInsertId();
$histFiller->createProdInHist($pdo, $prodid, $shortName, $longName, $priceA, $priceB, $priceC, $tax, 0, $available, null, $favorite);
HistFiller::createProdInHist($pdo, $prodid);
} else {
$sql = "SELECT shortname,longname,priceA,priceB,priceC,tax,category FROM %products% WHERE id=?";
$sql = "SELECT shortname,longname,priceA,priceB,priceC,tax,available,category FROM %products% WHERE id=?";
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
$stmt->execute(array($prodid));
$row = $stmt->fetchObject();
@ -388,19 +387,20 @@ class TypeAndProductFileManager {
|| ($row->priceA != $priceA)
|| ($row->priceB != $priceB)
|| ($row->priceC != $priceC)
|| ($row->available != $available)
|| ($row->tax != $tax));
if ($changed) {
$sql = "UPDATE %products% SET shortname=?,longname=?,priceA=?,priceB=?,priceC=?,tax=? WHERE id=?";
$sql = "UPDATE %products% SET shortname=?,longname=?,priceA=?,priceB=?,priceC=?,tax=?,available=? WHERE id=?";
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
$stmt->execute(array($shortName,$longName,$priceA,$priceB,$priceC,$tax,$prodid));
$stmt->execute(array($shortName,$longName,$priceA,$priceB,$priceC,$tax,$available,$prodid));
$sql = "SELECT sorting,available,favorite,audio FROM %products% WHERE id=?";
$stmt = $pdo->prepare(DbUtils::substTableAlias($sql));
$stmt->execute(array($prodid));
$row = $stmt->fetchObject();
$histFiller->updateOrCreateProdInHist($pdo, $prodid, $shortName, $longName, $priceA, $priceB, $priceC, $tax, $row->sorting, $row->available, '4', $row->audio, $row->favorite, null);
HistFiller::updateProdInHist($pdo, $prodid);
}
$sql = "UPDATE %products% SET category=?,removed=? WHERE id=?";

View File

@ -218,6 +218,7 @@ class Basedb {
`right_bill` INT (1) NOT NULL,
`right_products` INT (1) NOT NULL,
`right_manager` INT (1) NOT NULL,
`right_closing` INT (1) NOT NULL,
`right_reservation` INT (1) NOT NULL,
`right_rating` INT (1) NOT NULL,
`right_changeprice` INT (1) NOT NULL,
@ -469,10 +470,10 @@ class Basedb {
`host` INT(2) NULL,
`reason` VARCHAR ( 150 ) NULL,
`signature`blob NULL,
FOREIGN KEY (closingid) REFERENCES %closing%(id),
FOREIGN KEY billclosingref (closingid) REFERENCES %closing%(id),
FOREIGN KEY (paymentid) REFERENCES %payment%(id),
FOREIGN KEY (userid) REFERENCES %user%(id),
FOREIGN KEY (ref) REFERENCES %bill%(id)
FOREIGN KEY billbillref (ref) REFERENCES %bill%(id)
) CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDb ;
";
$stmt = $pdo->prepare($this->resolveTablenamesInSqlString($sql));
@ -510,7 +511,7 @@ class Basedb {
FOREIGN KEY (tablenr) REFERENCES %resttables%(id),
FOREIGN KEY (pricelevel) REFERENCES %pricelevel%(id),
FOREIGN KEY (productid) REFERENCES %products%(id),
FOREIGN KEY (billid) REFERENCES %bill%(id),
FOREIGN KEY queuebillref (billid) REFERENCES %bill%(id),
FOREIGN KEY (cooking) REFERENCES %user%(id),
FOREIGN KEY (orderuser) REFERENCES %user%(id)
) CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDb ;
@ -524,7 +525,7 @@ class Basedb {
`queueid` INT( 10 ) NOT NULL,
`billid` INT(10) NOT NULL,
FOREIGN KEY (queueid) REFERENCES %queue%(id),
FOREIGN KEY (billid) REFERENCES %bill%(id)
FOREIGN KEY billprodref (billid) REFERENCES %bill%(id)
) CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDb ;
";
$this->doSQL($pdo,$sql);
@ -586,6 +587,7 @@ class Basedb {
`right_bill` INT (1) NOT NULL,
`right_products` INT (1) NOT NULL,
`right_manager` INT (1) NOT NULL,
`right_closing` INT (1) NOT NULL,
`right_reservation` INT (1) NOT NULL,
`right_rating` INT (1) NOT NULL,
`right_changeprice` INT (1) NOT NULL,

View File

@ -16,13 +16,15 @@ define ( 'R_RES', 512);
define ( 'R_RAT', 1024);
define ( 'R_MAN', 2048);
define ( 'R_CP', 4096);
define ( 'R_CL', 8192);
class Userrights {
function setSession($isAdm,$rWait,$rKit,$rBar,$rSupply,$rPay,$rStat,$rBill,$rProd,$rRes,$rRat,$rChangePrice,$rMan) {
function setSession($isAdm,$rWait,$rKit,$rBar,$rSupply,$rPay,$rStat,$rBill,$rProd,$rRes,$rRat,$rChangePrice,$rMan,$rClos) {
$ret = R_ADM * ($isAdm ? 1:0) | R_WAI * ($rWait ? 1:0) | R_KIT * ($rKit ? 1:0) | R_BAR * ($rBar ? 1:0) | R_SUP * ($rSupply ? 1:0) | R_PAY * ($rPay ? 1:0);
$ret |= R_STA * ($rStat ? 1:0) | R_BIL * ($rBill ? 1:0) | R_PRO * ($rProd ? 1:0) | R_RES * ($rRes ? 1:0) | R_RAT * ($rRat ? 1:0) | R_CP * ($rChangePrice ? 1:0) | R_MAN * (($rMan ? 1:0) ? 1:0);
$ret |= R_STA * ($rStat ? 1:0) | R_BIL * ($rBill ? 1:0) | R_PRO * ($rProd ? 1:0) | R_RES * ($rRes ? 1:0) | R_RAT * ($rRat ? 1:0) |
R_CP * ($rChangePrice ? 1:0) | R_MAN * (($rMan ? 1:0) | R_CL * (($rClos ? 1:0)));
$_SESSION['allrights'] = $ret;
}

View File

@ -5,7 +5,7 @@
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="author" content="Stefan Pichel">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.1.30">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.2.0">
<link rel="stylesheet" href="php/3rdparty/orderstyle/orderstyle.min.css" />
<link rel="stylesheet" href="php/3rdparty/orderstyle/jquery.mobile.icons.min.css" />

View File

@ -7,7 +7,7 @@
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="author" content="Stefan Pichel">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.1.30">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.2.0">
<link rel="stylesheet" href="php/3rdparty/orderstyle/orderstyle.min.css" />
<link rel="stylesheet" href="php/3rdparty/orderstyle/jquery.mobile.icons.min.css" />

View File

@ -7,7 +7,7 @@
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="author" content="Stefan Pichel">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.1.30">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.2.0">
<link rel="stylesheet" href="php/3rdparty/orderstyle/orderstyle.min.css" />
<link rel="stylesheet" href="php/3rdparty/orderstyle/jquery.mobile.icons.min.css" />

View File

@ -7,7 +7,7 @@
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="author" content="Stefan Pichel">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.1.30">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.2.0">
<link rel="stylesheet" href="php/3rdparty/orderstyle/orderstyle.min.css" />
<link rel="stylesheet" href="php/3rdparty/orderstyle/jquery.mobile.icons.min.css" />

View File

@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="author" content="Stefan Pichel">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.1.30">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.2.0">
<link rel="stylesheet" href="php/3rdparty/orderstyle/orderstyle.min.css" />
<link rel="stylesheet" href="php/3rdparty/orderstyle/jquery.mobile.icons.min.css" />

View File

@ -5,7 +5,7 @@
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="author" content="Stefan Pichel">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.1.30">
<link rel="stylesheet" type="text/css" href="css/bestformat.css?v=1.2.0">
<link rel="stylesheet" href="php/3rdparty/orderstyle/orderstyle.min.css" />
<link rel="stylesheet" href="php/3rdparty/orderstyle/jquery.mobile.icons.min.css" />

View File

@ -174,3 +174,10 @@ function handleTestForLoggedIn(answer) {
setTimeout(function(){document.location.href = "index.html"},250);
}
}
function isInt(value) {
if(Math.floor(value) == value && $.isNumeric(value)) {
return true;
} else {
return false;
}
}

File diff suppressed because one or more lines are too long