From d8fff4aeb6de0eb83bcb787c8c2b84ce7f212275 Mon Sep 17 00:00:00 2001 From: Moirtz Wagner Date: Thu, 17 Sep 2026 10:41:43 +0200 Subject: [PATCH] Rechnungsmodul auf Prepared Statements umgebaut - incs/rechnung.php: alle Abfragen mit Platzhaltern. saveRechnung() setzte $_POST ungeprueft in SQL (Injection; ein Apostroph im Text brach das Speichern ab). Speichern, Kopieren und Loeschen laufen in Transaktionen, bei Fehlern bleibt nichts Halbes zurueck. Formularwerte ueber formularText/-Zahl/-Ganzzahl (strikter Modus). - copyRech() trug die Rechnungsnummer ohne typ_id ein (Fehler im strikten Modus) und zaehlte typuebergreifend; jetzt wie beim Anlegen pro Typ (neueRechnungsnummer()). Artikel und Eigenschaften per INSERT ... SELECT. - Adressblock-Formatierung aus makeadressblock() und makeadressblockUmschlag() in formatiereAdressblock() zusammengefuehrt. - ajax/autosave.php und ajax/preview.php teilen sich saveTmpRechnung(); ueberzaehlige Entwuerfe werden samt Artikeln entfernt (vorher FK-Fehler). - sites/rechnungadd.php: Storno ohne SQL-Injection ueber $_GET["id"], Auswahllisten ueber db_zuordnung(), tote Kommissions-Abfrage entfernt. - Rechnungssuche (createRechQry/createKdnRechQry) liefert SQL und Parameter getrennt; Suchbegriffe waren ungeprueft im SQL. - saveLog() mit Platzhaltern, Protokolltext ueber db_sql_text(). - db.php: db_zuordnung(), db_sql_text(); Helfer liefern Strings wie mysqli_query(), damit alter Code sich gleich verhaelt. Getestet: alter und neuer Code lesen dieselbe migrierte Datenbank, 150 von 155 Pruefungen (10.936 Werte) identisch, die uebrigen 5 sind der Injection-Suchbegriff (alt: SQL-Fehler). Schreibtests fuer Entwurf, Anlegen, Nummernkreise, Aendern, Rollback, Kopieren, Adresse, Storno und Loeschen im strikten Modus. Co-Authored-By: Claude Opus 5 --- CLAUDE.md | 10 + ajax/autosave.php | 194 +------ ajax/preview.php | 204 +------- ajax/searchkdnrech.php | 26 +- ajax/searchrech.php | 18 +- incs/db.php | 57 +- incs/listfuncs.php | 53 +- incs/rechnung.php | 1130 +++++++++++++++++----------------------- incs/saveNchange.php | 22 +- sites/rechnungadd.php | 177 ++----- sites/umschlagshow.php | 18 +- 11 files changed, 666 insertions(+), 1243 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 0f21abc..969f70a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -86,6 +86,16 @@ Eine Schemaänderung besteht also aus: neuer Eintrag **vorn** in `update/version **Umbau läuft (Branch `db-umbau`):** Verbindungen entstehen nur noch über `db_verbinden()` aus `incs/db.php`. Die Funktion setzt `utf8mb4`, den strikten `sql_mode` und schaltet die mysqli-Exceptions ab. Neue und umgebaute Abfragen nutzen `db_abfrage()`, `db_zeilen()`, `db_zeile()` und `db_wert()` mit `?`-Platzhaltern statt String-Verkettung. Ziel-Schema ist das der Instanz `kunden` in `utf8mb4`; die Altdaten sind teils doppelt kodiert und werden per Migration repariert. Dieser Stand darf nur zusammen mit der migrierten Datenbank live gehen. +Regeln für den Umbau: + +- **Ergebnisse sind Strings** wie früher bei `mysqli_query()`: `db_zeilen()`, `db_zeile()`, `db_wert()` und `db_zuordnung()` wandeln die nativen int/float-Werte der Prepared Statements um. Wer `db_abfrage()` selbst ausliest, bekommt native Typen. +- **Formularwerte** über `formularText()`, `formularZahl()` (Komma als Dezimaltrenner, leer wird 0) und `formularGanzzahl()` aus `incs/rechnung.php` holen – der strikte Modus lehnt `''` in Zahlenspalten ab. +- **Änderungsprotokoll:** `saveLog()` bekommt den Text aus `db_sql_text()`. Die Tabelle `log` ist reine Dokumentation, nichts daraus wird ausgeführt. +- **Mehrschrittiges Speichern** in eine Transaktion (`mysqli_begin_transaction` / `commit` / `rollback`), damit bei Fehlern keine halben Datensätze bleiben. +- **Tabellen- und Spaltennamen** lassen sich nicht binden; nur feste Werte aus dem Code einsetzen, `LIMIT` als `(int)`. + +Umgebaut: Login/Passkeys, Benutzereinstellungen, Änderungsprotokoll, Rechnungsmodul (`incs/rechnung.php`, `sites/rechnungadd.php`, `sites/umschlagshow.php`, `ajax/autosave.php`, `ajax/preview.php`, Rechnungssuche). Offen: Kunden/Adressen (`incs/saveNchange.php`), Termine, Projekte, Zeiten, Benutzerverwaltung, übrige Suchen, `incs/makepdf.php`, `update/`. + Prozedurales `mysqli`. `$dbconn` wird zusätzlich in `$_SESSION["dbconn"]` abgelegt, damit `incs/mysql_ecape_wrapper.php` eine globale Funktion `mysql_escape_string()` als Shim über diese Verbindung bereitstellen kann — ein Überbleibsel der `mysql_*`-Ära, das in altem Code noch aufgerufen wird. SQL wird durchgehend per String-Verkettung gebaut. Escaping ist Handarbeit über `mysqli_real_escape_string($dbconn, …)` und muss bei jeder Änderung mitgedacht werden. diff --git a/ajax/autosave.php b/ajax/autosave.php index 157e6fd..a2dd7f1 100644 --- a/ajax/autosave.php +++ b/ajax/autosave.php @@ -1,4 +1,4 @@ -".mysqli_error($dbconn)); - $progressid = mysqli_fetch_array($qry); - $progressid = $progressid[0]; - if(!$progressid) - { - - $qry = mysqli_query($dbconn, "INSERT INTO tmp_rechnung SET - user_id = '".$_SESSION["user"]."', - adressfields='$show', - anrede1='$anr1', - anrede2='$anr2', - intro='$intro', - outro='$outro', - typ_id = '$type', - adresse_id='$adressid', - partner_id='$partnerid', - mwst_id = '$mwst', - zahlziel_id = '$zahlziel', - wahrung_id='$wahrung', - sub_mwst='$sub_mwst', - rabatt='$rabatt', - rabattdesc='$rabattdesc', - adresserweiterung='$adrerw', - lieferdatum='$lieferdatum', - buchungsKto_id = '$buchKto', - datetime=NOW()") or $err=error("[autosave.js] Fehler beim erstellen der Rechnung
".mysqli_error($dbconn)); - $progressid = mysqli_insert_id($dbconn); - } - else - { - $qry = mysqli_query($dbconn, "UPDATE tmp_rechnung SET - user_id = '".$_SESSION["user"]."', - adressfields='$show', - anrede1='$anr1', - anrede2='$anr2', - intro='$intro', - outro='$outro', - typ_id = '$type', - adresse_id='$adressid', - partner_id='$partnerid', - mwst_id = '$mwst', - zahlziel_id = '$zahlziel', - wahrung_id='$wahrung', - sub_mwst='$sub_mwst', - rabatt='$rabatt', - rabattdesc='$rabattdesc', - lieferdatum='$lieferdatum', - adresserweiterung='$adrerw', - buchungsKto_id = '$buchKto', - datetime=NOW() WHERE id='$progressid'") or $err=error("Fehler beim aktualisieren der Rechnung
".mysqli_error($dbconn)); - $qry = mysqli_query($dbconn, "DELETE FROM tmp_rechnung WHERE user_id = '".$_SESSION["user"]."' AND typ_id = '$type' AND id != '$progressid' LIMIT 1") or $err=error("Fehler beim löschen alter tmp Rechnungen
".mysqli_error($dbconn)); - } - - $qry= mysqli_query($dbconn, "SELECT id FROM tmp_artikel WHERE rech_id = '".$progressid."'"); - while($res=mysqli_fetch_assoc($qry)) - { - mysqli_query($dbconn, "DELETE FROM tmp_eigensch WHERE art_id = '".$res["id"]."'") or $err=error("Fehler beim löschen der eigenschaften
".mysqli_error($dbconn)); - } - - $qry = mysqli_query($dbconn, "DELETE FROM tmp_artikel WHERE rech_id = '".$progressid."'") or $err=error("Fehler beim löschen der Artikel
".mysqli_error($dbconn)); - if(!isset($err)) - { - $i = 1; - while($_POST["arthead".$i] && !isset($err)) - { - $angtyp = trim($_POST["angtyp".$i]); - $arttyp = trim($_POST["arttyp".$i]); - $arthead = trim($_POST["arthead".$i]); - $artpr = str_replace(",",".",trim($_POST["artpr".$i])); - $artmen = str_replace(",",".",trim($_POST["artmen".$i])); - $artrab = trim($_POST["artrab".$i]); - if(!isset($_POST["artrabtyp".$i])) - $_POST["artrabtyp".$i] = ""; - $artrabtyp = trim($_POST["artrabtyp".$i]); - $artmeneinh = trim($_POST["artmeneinh".$i]); - $artwa = trim($_POST["artwa".$i]); - $artmwst = trim($_POST["artmwst".$i]); - $pagebreak = trim($_POST["pagebreak".$i]); - - - $qry = mysqli_query($dbconn, "INSERT INTO tmp_artikel SET bezeichn='$arthead', preis='$artpr', mwst_id='$artmwst', pagebreak='$pagebreak', einheit_id='$artmeneinh', typ_id='$arttyp', datetime=NOW(), wanr='$artwa', rech_id='$progressid',posnr='$i',rabatt='$artrab',rabatttyp='$artrabtyp',menge='$artmen',angtyp='$angtyp'") or $err=error("Fehler beim anlegen der Artikel
".mysqli_error($dbconn)); - $artid=mysqli_insert_id($dbconn); - $ii = 1; - while($_POST["arteig".$i."_".$ii] && !isset($err)) - { - $arteig = trim($_POST["arteig".$i."_".$ii]); - $artval = trim($_POST["artval".$i."_".$ii]); - $arteinh = trim($_POST["arteinh".$i."_".$ii]); - $qry = mysqli_query($dbconn, "INSERT INTO tmp_eigensch SET bezeichn='$arteig', wert='$artval', einheit_id='$arteinh', datetime=NOW(), posnr='$ii', art_id='$artid'") or $err=error("Fehler beim anlegen der Eigenschaften
".mysqli_error($dbconn)); - $eigid=mysqli_insert_id($dbconn); - $ii++; - } - $i++; - } - } - if(!isset($err)) { + $type = formularGanzzahl("type"); $adresse = makeadressblock($dbconn,$progressid,1); $rechnung = makerechnungsarray($dbconn,$progressid,1); $artikel = makeartikelarray($dbconn,$progressid,1); if($adresse["lines"]>6) error("Die Adresse hat zu viele Zeilen!
Bitte wählen Sie einige Elemente ab."); - if(!$_POST["show_ort"] || !$_POST["show_str"]) - error("Die Adresse erscheint nicht vollständig auf der Rechnung!
Falls die Rechnung über den Postweg zugestellt werden soll muss die Adresse vervollständigt werden!"); + if(!formularText("show_ort") || !formularText("show_str")) + error("Die Adresse erscheint nicht vollständig auf der Rechnung!
Falls die Rechnung über den Postweg zugestellt werden soll muss die Adresse vervollständigt werden!"); if($rechnung["rabatt"] && !$rechnung["rabattdesc"]) warning("Ein Rabatt wird von der Gesamtsumme abgezogen, jedoch ist die Rabattbeschreibung leer!
Bitte geben Sie eine Rabattbeschreibung ein (z.B.: Sonderrabatt, Winterrabatt, etc.)."); - if(!$artikel[0] && $type != 5) + if(empty($artikel) && $type != 5) warning("Es sind noch keine Artikel vorhanden. Bitte Fügen Sie Artikel durch eintragen einer Artikelbeschreibung ein."); if(!is_file("../".UPLOADS_PATH."signs/".$_SESSION["user"].".png")) error("Für Ihren Benutzer wurde noch keine Unterschrift hinterlegt. Bitte vergessen Sie nicht zu unterschreiben.
("."./".UPLOADS_PATH."signs/".$_SESSION["user"].".png"); - + ok("
Dokument wurde um ".date("H:i:s")." Uhr gespeichert!"); } - } -?> \ No newline at end of file +?> diff --git a/ajax/preview.php b/ajax/preview.php index 2bd18fd..ef2938c 100644 --- a/ajax/preview.php +++ b/ajax/preview.php @@ -1,4 +1,4 @@ -".mysqli_error($dbconn)); - $progressid = mysqli_fetch_array($qry); - $progressid = $progressid[0]; - if(!$progressid) - { - - $qry = mysqli_query($dbconn, "INSERT INTO tmp_rechnung SET - user_id = '".$_SESSION["user"]."', - adressfields='$show', - anrede1='$anr1', - anrede2='$anr2', - intro='$intro', - outro='$outro', - typ_id = '$type', - adresse_id='$adressid', - partner_id='$partnerid', - mwst_id = '$mwst', - zahlziel_id = '$zahlziel', - wahrung_id='$wahrung', - sub_mwst='$sub_mwst', - rabatt='$rabatt', - adresserweiterung='$adrerw', - rabattdesc='$rabattdesc', - buchungsKto_id = '$buchKto', - lieferdatum='$lieferdatum', - datetime=NOW()") or $err=error("Fehler beim erstellen der Rechnung
".mysqli_error($dbconn)); - $progressid = mysqli_insert_id($dbconn); - } - else - { - $qry = mysqli_query($dbconn, "UPDATE tmp_rechnung SET - user_id = '".$_SESSION["user"]."', - adressfields='$show', - anrede1='$anr1', - anrede2='$anr2', - intro='$intro', - outro='$outro', - typ_id = '$type', - adresse_id='$adressid', - partner_id='$partnerid', - mwst_id = '$mwst', - zahlziel_id = '$zahlziel', - wahrung_id='$wahrung', - sub_mwst='$sub_mwst', - rabatt='$rabatt', - adresserweiterung='$adrerw', - rabattdesc='$rabattdesc', - buchungsKto_id = '$buchKto', - lieferdatum='$lieferdatum', - datetime=NOW() WHERE id='$progressid'") or $err=error("Fehler beim aktualisieren der Rechnung
".mysqli_error($dbconn)); - $qry = mysqli_query($dbconn, "DELETE FROM tmp_rechnung WHERE user_id = '".$_SESSION["user"]."' AND typ_id = '$type' AND id != '$progressid' LIMIT 1") or $err=error("Fehler beim löschen alter tmp Rechnungen
".mysqli_error($dbconn)); - } - $qry= mysqli_query($dbconn, "SELECT id FROM tmp_artikel WHERE rech_id = '".$progressid."'"); - while($res=mysqli_fetch_assoc($qry)) - { - mysqli_query($dbconn, "DELETE FROM tmp_eigensch WHERE art_id = '".$res["id"]."'") or $err=error("Fehler beim löschen der eigenschaften
".mysqli_error($dbconn)); - } - - $qry = mysqli_query($dbconn, "DELETE FROM tmp_artikel WHERE rech_id = '".$progressid."'") or $err=error("Fehler beim löschen der Artikel
".mysqli_error($dbconn)); - if(!isset($err)) - { - $i = 1; - while($_POST["arthead".$i] && !isset($err)) - { - if($_POST["artact".$i]) - { - $angtyp = trim($_POST["angtyp".$i]); - $arttyp = trim($_POST["arttyp".$i]); - $arthead = trim($_POST["arthead".$i]); - $artpr = str_replace(",",".",trim($_POST["artpr".$i])); - $artmen = str_replace(",",".",trim($_POST["artmen".$i])); - $artrab = trim($_POST["artrab".$i]); - if(!isset($_POST["artrabtyp".$i])) - $_POST["artrabtyp".$i] = ""; - $artrabtyp = trim($_POST["artrabtyp".$i]); - $artmeneinh = trim($_POST["artmeneinh".$i]); - $artwa = trim($_POST["artwa".$i]); - $artmwst = trim($_POST["artmwst".$i]); - $pagebreak = trim($_POST["pagebreak".$i]); - - - $qry = mysqli_query($dbconn, "INSERT INTO tmp_artikel SET bezeichn='$arthead', preis='$artpr', mwst_id='$artmwst', pagebreak='$pagebreak', einheit_id='$artmeneinh', typ_id='$arttyp', datetime=NOW(), wanr='$artwa', rech_id='$progressid',posnr='$i',rabatt='$artrab',rabatttyp='$artrabtyp',menge='$artmen',angtyp='$angtyp'") or $err=error("Fehler beim anlegen der Artikel
".mysqli_error($dbconn)); - $artid=mysqli_insert_id($dbconn); - $ii = 1; - while($_POST["arteig".$i."_".$ii] && !isset($err)) - { - $arteig = trim($_POST["arteig".$i."_".$ii]); - $artval = trim($_POST["artval".$i."_".$ii]); - $arteinh = trim($_POST["arteinh".$i."_".$ii]); - $qry = mysqli_query($dbconn, "INSERT INTO tmp_eigensch SET bezeichn='$arteig', wert='$artval', einheit_id='$arteinh', datetime=NOW(), posnr='$ii', art_id='$artid'") or $err=error("Fehler beim anlegen der Eigenschaften
".mysqli_error($dbconn)); - $eigid=mysqli_insert_id($dbconn); - $ii++; - } - } - $i++; - } - } - if(!isset($err)) { $adresse = makeadressblock($dbconn,$progressid,1); $rechnung = makerechnungsarray($dbconn,$progressid,1); $artikel = makeartikelarray($dbconn,$progressid,1); - /* - if($adresse["lines"]>6) - error("Die Adresse hat zu viele Zeilen!
Bitte wählen Sie einige Elemente ab."); - if(!$_POST["show_ort"] || !$_POST["show_str"]) - error("Die Adresse erscheint nicht vollständig auf der Rechnung!
Falls die Rechnung über den Postweg zugestellt werden soll muss die Adresse vervollständigt werden!"); - if($rechnung["rabatt"] && !$rechnung["rabattdesc"]) - warning("Ein Rabatt wird von der Gesamtsumme abgezogen, jedoch ist die Rabattbeschreibung leer!
Bitte geben Sie eine Rabattbeschreibung ein (z.B.: Sonderrabatt, Winterrabatt, etc.)."); - if(!$artikel[0] && $type != 5) - warning("Es sind noch keine Artikel vorhanden. Bitte Fügen Sie Artikel durch eintragen einer Artikelbeschreibung ein."); - if(!is_file("../pics/users/".$_SESSION["user"].".png")) - error("Für Ihren Benutzer wurde noch keine Unterschrift hinterlegt. Bitte vergessen Sie nicht zu unterschreiben."); - */ + $pdf = makerawPDF(1); - + makefirstpage($pdf,$adresse["adresse"],$rechnung,1); + $gesamtpreis = 0; if(count($artikel)) { - $gesamtpreis = maketable($pdf,$artikel,$rechnung,1); + $gesamtpreis = maketable($pdf,$artikel,$rechnung,1); } makeEndPage($pdf,$rechnung,$gesamtpreis,1); - + $tmppdfname = str_replace(array(" ","."),array("_","_"),microtime()); savePDF($pdf,"../temp/pdfpreview/$tmppdfname.pdf"); echo makeImageFromPDF("../temp/pdfpreview/$tmppdfname.pdf"); } - } -?> \ No newline at end of file +?> diff --git a/ajax/searchkdnrech.php b/ajax/searchkdnrech.php index 535168e..d976098 100644 --- a/ajax/searchkdnrech.php +++ b/ajax/searchkdnrech.php @@ -18,24 +18,25 @@ if(!isset($err)) } $fulltag = utf8_encode($_GET["search"]); $src = explode(" ",$fulltag); - $combiner = mysql_escape_string($_GET["link"]); + $combiner = $_GET["link"]; if($combiner != "AND" && $combiner != "OR") { $combiner = "AND"; } - $page = $_GET["page"]; - $skspage = $_GET["skspage"]; - $typ = $_GET["typ"]; - $id = $_GET["kdnid"]; + $page = (int)$_GET["page"]; + $skspage = (int)$_GET["skspage"]; + // landen auch in JavaScript-Aufrufen der Seitennavigation + $typ = (int)$_GET["typ"]; + $id = (int)$_GET["kdnid"]; $queries = createKdnRechQry($page,$pagesize,$src,$combiner,$id,$typ,0); - $qry = mysqli_query($dbconn,$queries["all"]) + $qry = db_abfrage($dbconn,$queries["all"],$queries["params"]) or die("Datenbank fehler: ".mysqli_error($dbconn)); $numres = mysqli_num_rows($qry); /* if(!$numres) { $queries = createKdnRechQry($page,$pagesize,$src,$combiner,1); - $qry = mysqli_query($dbconn,$queries["all"]) + $qry = db_abfrage($dbconn,$queries["all"],$queries["params"]) or die("Datenbank fehler: ".mysqli_error($dbconn)); $numres = mysqli_num_rows($qry); message("veraltete Datensätze wurden in die Suche einbezogen"); @@ -44,7 +45,7 @@ if(!isset($err)) if($numres) { $listlines=array(); - $qry = mysqli_query($dbconn,$queries["limited"]) + $qry = db_abfrage($dbconn,$queries["limited"],$queries["params"]) or die("Datenbank fehler: ".mysqli_error($dbconn)); while($res=mysqli_fetch_assoc($qry)) { @@ -53,8 +54,7 @@ if(!isset($err)) $actions .= ""; $actions .= ""; $actions .= ""; - $tmpqry = mysqli_query($dbconn,"SELECT id FROM kontakt WHERE partner_id = '$id' AND typ_id = 1"); - if(mysqli_fetch_array($tmpqry)) + if(db_wert($dbconn, "SELECT id FROM kontakt WHERE partner_id = ? AND typ_id = 1 LIMIT 1", array($id))) $actions .= ""; switch($res["typ_id"]) @@ -128,14 +128,14 @@ if(!isset($err)) echo "

SKS Dokumente:

"; $queries=""; $queries = createKdnRechQry($skspage,$pagesize,$src,$combiner,$id,$typ,1); - $qry = mysqli_query($dbconn,$queries["all"]) + $qry = db_abfrage($dbconn,$queries["all"],$queries["params"]) or die("Datenbank fehler: ".mysqli_error($dbconn)); $numres = mysqli_num_rows($qry); /* if(!$numres) { $queries = createKdnRechQry($page,$pagesize,$src,$combiner,1); - $qry = mysqli_query($dbconn,$queries["all"]) + $qry = db_abfrage($dbconn,$queries["all"],$queries["params"]) or die("Datenbank fehler: ".mysqli_error($dbconn)); $numres = mysqli_num_rows($qry); message("veraltete Datensätze wurden in die Suche einbezogen"); @@ -145,7 +145,7 @@ if(!isset($err)) { $speciallines[]=array(); $listlines[]=array(); - $qry = mysqli_query($dbconn,$queries["limited"]) + $qry = db_abfrage($dbconn,$queries["limited"],$queries["params"]) or die("Datenbank fehler: ".mysqli_error($dbconn)); while($res=mysqli_fetch_assoc($qry)) { diff --git a/ajax/searchrech.php b/ajax/searchrech.php index 6a25454..91abca1 100644 --- a/ajax/searchrech.php +++ b/ajax/searchrech.php @@ -24,24 +24,24 @@ if(!isset($err)) } $fulltag = utf8_encode($_GET["search"]); $src = explode(" ",$fulltag); - $combiner = mysql_escape_string($_GET["link"]); + $combiner = $_GET["link"]; if($combiner != "AND" && $combiner != "OR") { $combiner = "AND"; } - $page = $_GET["page"]; - $skspage = $_GET["skspage"]; + $page = (int)$_GET["page"]; + $skspage = (int)$_GET["skspage"]; $typ = $_GET["typ"]; $id = $_GET["kdnid"]; $queries = createRechQry($page,$pagesize,$src,$combiner,0); - $qry = mysqli_query($dbconn,$queries["all"]) + $qry = db_abfrage($dbconn,$queries["all"],$queries["params"]) or die("Datenbank fehler: ".mysqli_error($dbconn)); $numres = mysqli_num_rows($qry); /* if(!$numres) { $queries = createKdnRechQry($page,$pagesize,$src,$combiner,1); - $qry = mysqli_query($dbconn,$queries["all"]) + $qry = db_abfrage($dbconn,$queries["all"],$queries["params"]) or die("Datenbank fehler: ".mysqli_error($dbconn)); $numres = mysqli_num_rows($qry); message("veraltete Datensätze wurden in die Suche einbezogen"); @@ -49,7 +49,7 @@ if(!isset($err)) */ if($numres) { - $qry = mysqli_query($dbconn,$queries["limited"]) + $qry = db_abfrage($dbconn,$queries["limited"],$queries["params"]) or die("Datenbank fehler: ".mysqli_error($dbconn)); while($res=mysqli_fetch_assoc($qry)) { @@ -122,14 +122,14 @@ if(!isset($err)) { echo "

SKS Dokumente:

"; $queries = createRechQry($skspage,$pagesize,$src,$combiner,1); - $qry = mysqli_query($dbconn,$queries["all"]) + $qry = db_abfrage($dbconn,$queries["all"],$queries["params"]) or die("Datenbank fehler: ".mysqli_error($dbconn)); $numres = mysqli_num_rows($qry); /* if(!$numres) { $queries = createKdnRechQry($page,$pagesize,$src,$combiner,1); - $qry = mysqli_query($dbconn,$queries["all"]) + $qry = db_abfrage($dbconn,$queries["all"],$queries["params"]) or die("Datenbank fehler: ".mysqli_error($dbconn)); $numres = mysqli_num_rows($qry); message("veraltete Datensätze wurden in die Suche einbezogen"); @@ -137,7 +137,7 @@ if(!isset($err)) */ if($numres) { - $qry = mysqli_query($dbconn,$queries["limited"]); + $qry = db_abfrage($dbconn,$queries["limited"],$queries["params"]); while($res=mysqli_fetch_assoc($qry)) { $speciallines[] = array("".$res["rechnr"]."", diff --git a/incs/db.php b/incs/db.php index f4eaa8e..5a29310 100644 --- a/incs/db.php +++ b/incs/db.php @@ -44,19 +44,36 @@ function db_verbinden($server, $user, $pw, $db) /* * Führt eine Abfrage mit ?-Platzhaltern aus. Gibt bei SELECT ein * mysqli_result zurück, sonst true, bei Fehlern false. + * + * Achtung: Prepared Statements liefern Zahlen als int/float, mysqli_query() + * lieferte Strings. db_zeilen(), db_zeile(), db_wert() und db_zuordnung() + * wandeln deshalb in Strings um, damit sich alter Code (=== "0", "1" etc.) + * gleich verhält. Wer das Ergebnis von db_abfrage() selbst ausliest, bekommt + * die nativen Typen. */ function db_abfrage($dbconn, $sql, $params = array()) { return mysqli_execute_query($dbconn, $sql, array_values($params)); } +/* Werte einer Zeile als Strings wie bei mysqli_query(), NULL bleibt NULL */ +function db_als_text($zeile) +{ + if(!is_array($zeile)) + return $zeile; + foreach($zeile as $spalte => $wert) + if($wert !== null && !is_string($wert)) + $zeile[$spalte] = (string)$wert; + return $zeile; +} + /* Alle Zeilen als Liste assoziativer Arrays, bei Fehlern false. */ function db_zeilen($dbconn, $sql, $params = array()) { $res = db_abfrage($dbconn, $sql, $params); if(!$res) return false; - return mysqli_fetch_all($res, MYSQLI_ASSOC); + return array_map("db_als_text", mysqli_fetch_all($res, MYSQLI_ASSOC)); } /* Erste Zeile als assoziatives Array, null ohne Treffer, bei Fehlern false. */ @@ -65,7 +82,41 @@ function db_zeile($dbconn, $sql, $params = array()) $res = db_abfrage($dbconn, $sql, $params); if(!$res) return false; - return mysqli_fetch_assoc($res); + return db_als_text(mysqli_fetch_assoc($res)); +} + +/* + * Zwei Spalten als Zuordnung erste => zweite, etwa für Auswahllisten + * (SELECT id, anrede FROM anrede). Bei Fehlern false. + */ +function db_zuordnung($dbconn, $sql, $params = array()) +{ + $res = db_abfrage($dbconn, $sql, $params); + if(!$res) + return false; + $zuordnung = array(); + while($zeile = mysqli_fetch_row($res)) + $zuordnung[$zeile[0]] = $zeile[1] === null ? null : (string)$zeile[1]; + return $zuordnung; +} + +/* + * Die Abfrage mit eingesetzten Werten als lesbarer Text - ausschließlich für + * das Änderungsprotokoll (Tabelle log). Nie ausführen. + */ +function db_sql_text($dbconn, $sql, $params = array()) +{ + $teile = explode("?", $sql); + $text = array_shift($teile); + foreach(array_values($params) as $i => $wert) + { + if($wert === null) + $text .= "NULL"; + else + $text .= "'".mysqli_real_escape_string($dbconn, (string)$wert)."'"; + $text .= isset($teile[$i]) ? $teile[$i] : ""; + } + return $text; } /* Erste Spalte der ersten Zeile, null ohne Treffer, bei Fehlern false. */ @@ -75,5 +126,5 @@ function db_wert($dbconn, $sql, $params = array()) if(!$res) return false; $zeile = mysqli_fetch_row($res); - return $zeile === null ? null : $zeile[0]; + return $zeile === null || $zeile[0] === null ? null : (string)$zeile[0]; } diff --git a/incs/listfuncs.php b/incs/listfuncs.php index c2015b8..7cc7ce5 100644 --- a/incs/listfuncs.php +++ b/incs/listfuncs.php @@ -180,12 +180,16 @@ function createAdressQry($page,$pagesize,$src,$combiner,$fields,$full=0,$typ=1) return $ret; } +/* + * Suche in den Dokumenten eines Kunden. Liefert array("all" => sql, + * "limited" => sql mit LIMIT, "params" => Platzhalterwerte für beide). + * $combiner muss "AND" oder "OR" sein. + */ function createKdnRechQry($page,$pagesize,$src,$combiner,$id,$typ,$sks=0) { - if($typ == 1) - $docnr = "rechnr"; - else - $docnr = "rechnr"; + $docnr = "rechnr"; + $combiner = $combiner == "OR" ? "OR" : "AND"; + $params = array($id, $typ); if(!$sks) { $query = "SELECT rechnung.$docnr AS rechnr, @@ -199,11 +203,12 @@ function createKdnRechQry($page,$pagesize,$src,$combiner,$id,$typ,$sks=0) LEFT JOIN rechtyp ON rechnung.typ_id = rechtyp.id LEFT JOIN artikel_rechn ON rechnung.id = artikel_rechn.rech_id LEFT JOIN artikel ON artikel_rechn.art_id = artikel.id - WHERE partner_id='".$id."' AND rechtyp.id = '".$typ."' AND rechnung.sks = 0 "; + WHERE partner_id = ? AND rechtyp.id = ? AND rechnung.sks = 0 "; foreach($src AS $tag) { $tag .= "%"; - $query .= " $combiner (artikel.bezeichn LIKE '$tag' OR rechnung.rechnr LIKE '$tag' OR DATE_FORMAT(rechnung.datetime, '%d.%m.%Y') LIKE '$tag')"; + $query .= " $combiner (artikel.bezeichn LIKE ? OR rechnung.rechnr LIKE ? OR DATE_FORMAT(rechnung.datetime, '%d.%m.%Y') LIKE ?)"; + array_push($params, $tag, $tag, $tag); } } else @@ -217,19 +222,21 @@ function createKdnRechQry($page,$pagesize,$src,$combiner,$id,$typ,$sks=0) FROM rechnung LEFT JOIN rechtyp ON rechnung.typ_id = rechtyp.id RIGHT JOIN artikelsks ON rechnung.rechnr = artikelsks.rechnr - WHERE partner_id='".$id."' AND rechtyp.id = '".$typ."' AND rechnung.sks = 1 "; + WHERE partner_id = ? AND rechtyp.id = ? AND rechnung.sks = 1 "; foreach($src AS $tag) { $tag .= "%"; - $query .= " $combiner (artikelsks.bezeichn1 LIKE '$tag' OR artikelsks.bezeichn2 LIKE '$tag' OR rechnung.rechnr LIKE '$tag' OR DATE_FORMAT(rechnung.datetime, '%d.%m.%Y') LIKE '$tag')"; + $query .= " $combiner (artikelsks.bezeichn1 LIKE ? OR artikelsks.bezeichn2 LIKE ? OR rechnung.rechnr LIKE ? OR DATE_FORMAT(rechnung.datetime, '%d.%m.%Y') LIKE ?)"; + array_push($params, $tag, $tag, $tag, $tag); } } $query .= " GROUP BY rechnung.rechnr ORDER BY rechnung.datetime DESC "; - + $ret["all"] = $query; - $query .= " LIMIT ".$page*$pagesize.", $pagesize"; + $query .= " LIMIT ".((int)$page*(int)$pagesize).", ".(int)$pagesize; $ret["limited"] = $query; + $ret["params"] = $params; return $ret; } @@ -283,9 +290,14 @@ function createKommQry($page,$pagesize,$src,$combiner,$id) return $ret; } +/* + * Suche über alle Dokumente, Rückgabe wie createKdnRechQry(). + */ function createRechQry($page,$pagesize,$src,$combiner,$sks=0) { $docnr = "rechnr"; + $combiner = $combiner == "OR" ? "OR" : "AND"; + $params = array(); if(!$sks) { $query = "SELECT CONCAT(ELT(rechnung.typ_id,'R','G','A','B','L','M'),MID(rechnung.$docnr,1,4),'-',MID(rechnung.$docnr,5,2),'-',MID(rechnung.$docnr,7,2),'.',MID(rechnung.$docnr,9,2)) AS drechnr, @@ -304,9 +316,10 @@ function createRechQry($page,$pagesize,$src,$combiner,$sks=0) foreach($src AS $tag) { $tag = "%".$tag."%"; - $query .= " $combiner (artikel.bezeichn LIKE '$tag' OR - CONCAT(ELT(rechnung.typ_id,'R','G','A','B','L','M'),MID(rechnung.$docnr,1,4),'-',MID(rechnung.$docnr,5,2),'-',MID(rechnung.$docnr,7,2),'.',MID(rechnung.$docnr,9,2)) LIKE '$tag' OR - DATE_FORMAT(rechnung.datetime, '%d.%m.%Y') LIKE '$tag')"; + $query .= " $combiner (artikel.bezeichn LIKE ? OR + CONCAT(ELT(rechnung.typ_id,'R','G','A','B','L','M'),MID(rechnung.$docnr,1,4),'-',MID(rechnung.$docnr,5,2),'-',MID(rechnung.$docnr,7,2),'.',MID(rechnung.$docnr,9,2)) LIKE ? OR + DATE_FORMAT(rechnung.datetime, '%d.%m.%Y') LIKE ?)"; + array_push($params, $tag, $tag, $tag); } } else @@ -326,18 +339,20 @@ function createRechQry($page,$pagesize,$src,$combiner,$sks=0) foreach($src AS $tag) { $tag = "%".$tag."%"; - $query .= " $combiner (artikelsks.bezeichn1 LIKE '$tag' OR - artikelsks.bezeichn2 LIKE '$tag' OR - rechnung.rechnr LIKE '$tag' OR - DATE_FORMAT(rechnung.datetime, '%d.%m.%Y') LIKE '$tag')"; + $query .= " $combiner (artikelsks.bezeichn1 LIKE ? OR + artikelsks.bezeichn2 LIKE ? OR + rechnung.rechnr LIKE ? OR + DATE_FORMAT(rechnung.datetime, '%d.%m.%Y') LIKE ?)"; + array_push($params, $tag, $tag, $tag, $tag); } } $query .= " GROUP BY rechnung.rechnr ORDER BY rechnung.datetime DESC "; - + $ret["all"] = $query; - $query .= " LIMIT ".$page*$pagesize.", $pagesize"; + $query .= " LIMIT ".((int)$page*(int)$pagesize).", ".(int)$pagesize; $ret["limited"] = $query; + $ret["params"] = $params; return $ret; } diff --git a/incs/rechnung.php b/incs/rechnung.php index eafc97a..4a32ea9 100644 --- a/incs/rechnung.php +++ b/incs/rechnung.php @@ -1,39 +1,59 @@ -".mysqli_error($dbconn)); - else - $qry=mysqli_query($dbconn,"SELECT adressfields, adresserweiterung, nname, sks, titel_id, titel2_id, zusatz, vname, nname2, vname2, str, ort, plz, hnr, land, firma, anrede_id, anrede2_id FROM rechnung - JOIN adresse ON rechnung.adresse_id = adresse.id - JOIN strasse ON strasse.id = str_id - JOIN ort ON ort.id = ort_id JOIN land ON land.id = land_id - WHERE rechnung.id = $rechid") or $err= error("Fehler beim ermitteln der Adressdaten
".mysqli_error($dbconn)); - - - $adresse = mysqli_fetch_assoc($qry); - - $qry = mysqli_query($dbconn,"SELECT * FROM anrede"); - while($res=mysqli_fetch_assoc($qry)) - { - $anrs[$res["id"]] = $res["anrede"]; - } +/* --------------------------------------------------------------------- + * Hilfsfunktionen für Formularwerte + * ------------------------------------------------------------------ */ - $qry = mysqli_query($dbconn,"SELECT * FROM titel"); - while($res=mysqli_fetch_assoc($qry)) - { - $titels[$res["id"]] = $res["titel"]; - } - - $adressfields= $adresse["adressfields"]; - if($adresse["sks"]) - $adressfields = "011111111100"; +/* Getrimmter Text aus $_POST, fehlend oder kein Text ergibt "" */ +function formularText($name) +{ + return isset($_POST[$name]) && is_string($_POST[$name]) ? trim($_POST[$name]) : ""; +} + +/* + * Zahl aus $_POST, Komma als Dezimaltrenner. Leere oder ungültige Eingaben + * werden 0 - so hat sie der frühere, nicht strikte Modus gespeichert. + */ +function formularZahl($name) +{ + $wert = str_replace(",", ".", formularText($name)); + return is_numeric($wert) ? $wert : "0"; +} + +/* Ganzzahl aus $_POST, gerundet wie MariaDB beim Speichern */ +function formularGanzzahl($name) +{ + return (int)round((float)formularZahl($name)); +} + +/* Die zwölf Ankreuzfelder für den Adressblock als 0/1-Zeichenkette */ +function formularAdressfelder() +{ + $show = ""; + foreach(array("firmaanr", "firma", "anr", "titel", "name", "anr2", "titel2", "name2", "str", "ort", "land", "zusatz") as $feld) + $show .= formularText("show_".$feld) ? "1" : "0"; + return $show; +} + +/* --------------------------------------------------------------------- + * Adressblock + * ------------------------------------------------------------------ */ + +function anredenUndTitel($dbconn) +{ + return array( + db_zuordnung($dbconn, "SELECT id, anrede FROM anrede") ?: array(), + db_zuordnung($dbconn, "SELECT id, titel FROM titel") ?: array(), + ); +} + +/* + * Baut den Adressblock als HTML-Zeilen. $adressfields ist die 12-stellige + * 0/1-Zeichenkette aus den Ankreuzfeldern (Positionen: ADRFIELD_*). + */ +function formatiereAdressblock($adresse, $adressfields, $anrs, $titels) +{ $firmaanr = substr($adressfields,ADRFIELD_FIRMAANR,1); $firma = substr($adressfields,ADRFIELD_FIRMA,1); $anr1 = substr($adressfields,ADRFIELD_ANR1,1); @@ -55,7 +75,7 @@ function makeadressblock($dbconn,$rechid,$tmp) { $adrstr .= "
".trim($adresse["firma"]); } - + if($anr1 && $anr2 && $name1 && !$name2) { if($adrstr) @@ -94,7 +114,7 @@ function makeadressblock($dbconn,$rechid,$tmp) if($zusatz) $adrstr .= "
".trim($adresse["zusatz"]); } - else + else { if($anr1) { @@ -102,7 +122,7 @@ function makeadressblock($dbconn,$rechid,$tmp) $adrstr .= "
"; $adrstr .= $anrs[$adresse["anrede_id"]]." "; } - + if($titel1) { if($adrstr) @@ -173,206 +193,68 @@ function makeadressblock($dbconn,$rechid,$tmp) $lines=explode("
",$adrstr); $lines = count($lines); return array("lines"=>$lines,"adresse"=>$adrstr); - +} + +function makeadressblock($dbconn,$rechid,$tmp) +{ + $tabelle = $tmp ? "tmp_rechnung" : "rechnung"; + $sks = $tmp ? "0 AS sks" : "sks"; + $adresse = db_zeile($dbconn, "SELECT adressfields, adresserweiterung, nname, $sks, titel_id, titel2_id, zusatz, vname, nname2, vname2, str, ort, plz, hnr, land, firma, anrede_id, anrede2_id FROM $tabelle + JOIN adresse ON $tabelle.adresse_id = adresse.id + JOIN strasse ON strasse.id = str_id + JOIN ort ON ort.id = ort_id JOIN land ON land.id = land_id + WHERE $tabelle.id = ?", array($rechid)); + if($adresse === false) + error("Fehler beim ermitteln der Adressdaten
".mysqli_error($dbconn)); + + list($anrs, $titels) = anredenUndTitel($dbconn); + $adressfields = $adresse["adressfields"]; + if($adresse["sks"]) + $adressfields = "011111111100"; + return formatiereAdressblock($adresse, $adressfields, $anrs, $titels); } function makeadressblockUmschlag($dbconn,$adressid,$adressfields,$adresserweiterung) { - - $qry=mysqli_query($dbconn,"SELECT * FROM adresse - JOIN strasse ON strasse.id = str_id + $adresse = db_zeile($dbconn, "SELECT * FROM adresse + JOIN strasse ON strasse.id = str_id JOIN ort ON ort.id = ort_id JOIN land ON land.id = land_id - WHERE adresse.id = $adressid") or $err= error("Fehler beim ermitteln der Adressdaten
".mysqli_error($dbconn)); - - - $adresse = mysqli_fetch_assoc($qry); + WHERE adresse.id = ?", array($adressid)); + if($adresse === false) + error("Fehler beim ermitteln der Adressdaten
".mysqli_error($dbconn)); $adresse["adresserweiterung"] = $adresserweiterung; - $qry = mysqli_query($dbconn,"SELECT * FROM anrede"); - while($res=mysqli_fetch_assoc($qry)) - { - $anrs[$res["id"]] = $res["anrede"]; - } - $qry = mysqli_query($dbconn,"SELECT * FROM titel"); - while($res=mysqli_fetch_assoc($qry)) - { - $titels[$res["id"]] = $res["titel"]; - } - - $firmaanr = substr($adressfields,ADRFIELD_FIRMAANR,1); - $firma = substr($adressfields,ADRFIELD_FIRMA,1); - $anr1 = substr($adressfields,ADRFIELD_ANR1,1); - $titel1 = substr($adressfields,ADRFIELD_TITEL1,1); - $name1 = substr($adressfields,ADRFIELD_NAME1,1); - $anr2 = substr($adressfields,ADRFIELD_ANR2,1); - $titel2 = substr($adressfields,ADRFIELD_TITEL2,1); - $name2 = substr($adressfields,ADRFIELD_NAME2,1); - $str = substr($adressfields,ADRFIELD_STR,1); - $ort = substr($adressfields,ADRFIELD_ORT,1); - $land = substr($adressfields,ADRFIELD_LAND,1); - $zusatz = substr($adressfields,ADRFIELD_ZUSATZ,1); - if($firmaanr) - { - $adrstr .= "Firma"; - } - if($firma && trim($adresse["firma"])) - { - $adrstr .= "
".trim($adresse["firma"]); - } - - if($anr1 && $anr2 && $name1 && !$name2) - { - if($adrstr) - $adrstr .= "
"; - $adrstr .= $anrs[$adresse["anrede_id"]]; - if($titel1) - $adrstr .= " ".$titels[$adresse["titel_id"]]; - $adrstr .= " und "; - $adrstr .= $anrs[$adresse["anrede2_id"]]; - if($titel2) - $adrstr .= " ".$titels[$adresse["titel2_id"]]; - $adrstr .= "
"; - if($adresse["vname"]) - $adrstr .= trim($adresse["vname"])." ".trim($adresse["nname"]); - else - $adrstr .= trim($adresse["nname"]); - if($zusatz) - $adrstr .= "
".trim($adresse["zusatz"]); - } - elseif($anr1 && $anr2 && $name2 && !$name1) - { - if($adrstr) - $adrstr .= "
"; - $adrstr .= $anrs[$adresse["anrede_id"]]; - if($titel1) - $adrstr .= " ".$titels[$adresse["titel_id"]]; - $adrstr .= " und "; - $adrstr .= $anrs[$adresse["anrede2_id"]]; - if($titel2) - $adrstr .= " ".$titels[$adresse["titel2_id"]]; - $adrstr .= "
"; - if($adresse["vname2"]) - $adrstr .= trim($adresse["vname2"])." ".trim($adresse["nname2"]); - else - $adrstr .= trim($adresse["nname2"]); - if($zusatz) - $adrstr .= "
".trim($adresse["zusatz"]); - } - else - { - if($anr1) - { - if($adrstr) - $adrstr .= "
"; - $adrstr .= $anrs[$adresse["anrede_id"]]." "; - } - - if($titel1) - { - if($adrstr) - $adrstr .= "
"; - if($titels[$adresse["titel_id"]]) - $adrstr .= $titels[$adresse["titel_id"]]." "; - } - if($name1) - { - if(!$titel1 && !$firma && !$firmaanr && !$name2 && $adrstr) - $adrstr .= "
"; - if(!$anr1 && !$titel1 && $adrstr) - $adrstr .= "
"; - if($adresse["vname"]) - $adrstr .= trim($adresse["vname"])." ".trim($adresse["nname"]); - else - $adrstr .= trim($adresse["nname"]); - } - if($anr2 && $anrs[$adresse["anrede2_id"]]) - { - if($adrstr) - $adrstr .= "
"; - $adrstr .= $anrs[$adresse["anrede2_id"]]." "; - } - if($titel2 && $titels[$adresse["titel2_id"]]) - { - if($adrstr) - $adrstr .= "
"; - $adrstr .= $titels[$adresse["titel2_id"]]." "; - } - if(trim($name2)) - { - if(!$titel2 && !$firma && !$firmaanr && !$name1 && !$anr1 && $adrstr) - $adrstr .= "
"; - if(!$anr2 && !$titel2 && $adrstr) - $adrstr .= "
"; - if($adresse["vname2"]) - $adrstr .= trim($adresse["vname2"])." ".trim($adresse["nname2"]); - else - $adrstr .= trim($adresse["nname2"]); - } - if($zusatz) - $adrstr .= "
".trim($adresse["zusatz"]); - } - if(trim($adresse["adresserweiterung"])){ - $adrstr .= "
".trim($adresse["adresserweiterung"]); - } - if($str) - { - if($adrstr) - $adrstr .= "
"; - $adrstr .= trim($adresse["str"])." ".trim($adresse["hnr"]); - } - if($ort) - { - if($adrstr) - $adrstr .= "
"; - if($land) - $adresse["ort"] = strtoupper($adresse["ort"]); - $adrstr .= trim($adresse["plz"])." ".trim($adresse["ort"]); - } - if($land) - { - if($adrstr) - $adrstr .= "
"; - $adrstr .= trim(strtoupper($adresse["land"])); - } - $lines=explode("
",$adrstr); - $lines = count($lines); - return array("lines"=>$lines,"adresse"=>$adrstr); - + list($anrs, $titels) = anredenUndTitel($dbconn); + return formatiereAdressblock($adresse, $adressfields, $anrs, $titels); } +/* --------------------------------------------------------------------- + * Lesen + * ------------------------------------------------------------------ */ + function makerechnungsarray($dbconn,$rechid,$tmp) { - if($tmp){ - $qry=mysqli_query($dbconn,"SELECT adressfields, 0 AS sks, intro, adresserweiterung, outro, anrede1, storno, anrede2, rabatt, rechnr, sub_mwst, rabatt, kommission, rabattdesc, partner_id, mwst, ziel as zahlziel, vname, nname, user_id, user.vname AS uvname, user.nname AS unname, lieferdatum, typ, typ_id, datetime, wahrung, wahrung_id, mwst_id, zahlziel_id, kurs, buchungsKto_id - FROM tmp_rechnung - JOIN wahrung ON wahrung_id = wahrung.id - JOIN rechtyp ON typ_id = rechtyp.id - JOIN zahlziel ON zahlziel_id = zahlziel.id + $tabelle = $tmp ? "tmp_rechnung" : "rechnung"; + $sks = $tmp ? "0 AS sks" : "sks"; + $rechnung = db_zeile($dbconn, "SELECT adressfields, $sks, intro, adresserweiterung, lieferdatum, outro, anrede1, storno, anrede2, rabatt, rechnr, sub_mwst, kommission, rabattdesc, partner_id, mwst, ziel as zahlziel, vname, nname, user_id, user.vname AS uvname, user.nname AS unname, typ, typ_id, datetime, wahrung, wahrung_id, mwst_id, zahlziel_id, kurs, buchungsKto_id + FROM $tabelle + JOIN wahrung ON wahrung_id = wahrung.id + JOIN rechtyp ON typ_id = rechtyp.id + JOIN zahlziel ON zahlziel_id = zahlziel.id JOIN mwst ON mwst_id = mwst.id JOIN user ON user_id = user.id - WHERE tmp_rechnung.id = $rechid") or $err=error("Fehler beim ermitteln der Rechnungsdaten
".mysqli_error($dbconn)); + WHERE $tabelle.id = ?", array($rechid)); + if($rechnung === false) + error("Fehler beim ermitteln der Rechnungsdaten
".mysqli_error($dbconn)); - }else{ - $qry=mysqli_query($dbconn,"SELECT adressfields, sks, intro, adresserweiterung, lieferdatum, outro, anrede1, storno, anrede2, rabatt, rechnr, sub_mwst, rabatt, kommission, rabattdesc, partner_id, mwst, ziel as zahlziel, vname, nname, user_id, user.vname AS uvname, user.nname AS unname, typ, typ_id, datetime, wahrung, wahrung_id, mwst_id, zahlziel_id, kurs, buchungsKto_id - FROM rechnung - JOIN wahrung ON wahrung_id = wahrung.id - JOIN rechtyp ON typ_id = rechtyp.id - JOIN zahlziel ON zahlziel_id = zahlziel.id - JOIN mwst ON mwst_id = mwst.id - JOIN user ON user_id = user.id - WHERE rechnung.id = $rechid") or $err=error("Fehler beim ermitteln der Rechnungsdaten
".mysqli_error($dbconn)); - } - $rechnung = mysqli_fetch_assoc($qry); - - $qry=mysqli_query($dbconn,"SELECT ktonr FROM konto WHERE partner_id = ".$rechnung["partner_id"]); - if($res=mysqli_fetch_assoc($qry)){ - $rechnung["ktonr"] = $res["ktonr"]; - } + $ktonr = db_wert($dbconn, "SELECT ktonr FROM konto WHERE partner_id = ?", array($rechnung["partner_id"])); + if($ktonr !== null && $ktonr !== false) + $rechnung["ktonr"] = $ktonr; if($rechnung["sks"]) $rechnung["mwst"] = "19"; if($rechnung["rechnr"]) $rechnung["drechnr"] = substr($rechnung["rechnr"],0,4)."-".substr($rechnung["rechnr"],4,2)."-".substr($rechnung["rechnr"],6,2).".".substr($rechnung["rechnr"],8,2); - else + else $rechnung["drechnr"] = "(Noch nicht vergeben)"; switch($rechnung["typ_id"]) @@ -395,376 +277,267 @@ function makerechnungsarray($dbconn,$rechid,$tmp) } return $rechnung; } + function makeadressarray($dbconn,$adressid) { - $qry = mysqli_query($dbconn,"SELECT plz, ortsteil, ort, str, zusatz, adresstyp.typ AS adresstyp, hnr, vname, partner_id, nname, vname2, nname2, firma, adresse.id, land, anrede_id, titel_id, anrede2_id, titel2_id - FROM adresse - LEFT JOIN strasse ON str_id = strasse.id - LEFT JOIN ort ON ort_id = ort.id - LEFT JOIN land ON land_id = land.id + $kdnres = db_zeile($dbconn, "SELECT plz, ortsteil, ort, str, zusatz, adresstyp.typ AS adresstyp, hnr, vname, partner_id, nname, vname2, nname2, firma, adresse.id, land, anrede_id, titel_id, anrede2_id, titel2_id + FROM adresse + LEFT JOIN strasse ON str_id = strasse.id + LEFT JOIN ort ON ort_id = ort.id + LEFT JOIN land ON land_id = land.id JOIN adresstyp ON adresse.typ_id = adresstyp.id - WHERE adresse.id='".mysql_escape_string($adressid)."' - ORDER BY typ_id ASC") or $err = error("Fehler beim abrufen der adressdaten ".mysqli_error($dbconn)); - $kdnres=mysqli_fetch_assoc($qry); + WHERE adresse.id = ? + ORDER BY typ_id ASC", array((string)$adressid)); + if($kdnres === false) + error("Fehler beim abrufen der adressdaten ".mysqli_error($dbconn)); return $kdnres; } + function makeartikelarray($dbconn,$rechid,$tmp) { + $artikel = array(); if($tmp) - { - $qry=mysqli_query($dbconn,"SELECT tmp_artikel.bezeichn as bezeichn, preis, wanr, pagebreak, mwst AS artmwst, rabatt, rabatttyp, artikeltyp.bezeichn as typ, typ_id, einheit, einheit_id, menge, angtyp, tmp_artikel.id as id + { + $zeilen = db_zeilen($dbconn, "SELECT tmp_artikel.bezeichn as bezeichn, preis, wanr, pagebreak, mwst AS artmwst, rabatt, rabatttyp, artikeltyp.bezeichn as typ, typ_id, einheit, einheit_id, menge, angtyp, tmp_artikel.id as id FROM tmp_artikel - JOIN artikeltyp ON typ_id = artikeltyp.id + JOIN artikeltyp ON typ_id = artikeltyp.id JOIN einheit ON einheit_id = einheit.id JOIN mwst ON mwst_id = mwst.id - WHERE rech_id = $rechid ORDER BY posnr ASC") or $err=error("Fehler beim ermitteln der Artikeldaten
".mysqli_error($dbconn)); - $artikel = array(); - while($art=mysqli_fetch_assoc($qry)) + WHERE rech_id = ? ORDER BY posnr ASC", array($rechid)); + if($zeilen === false) + error("Fehler beim ermitteln der Artikeldaten
".mysqli_error($dbconn)); + foreach($zeilen ?: array() as $art) { - $qry2=mysqli_query($dbconn,"SELECT bezeichn, wert, einheit, einheit_id + $eigenschaften = db_zeilen($dbconn, "SELECT bezeichn, wert, einheit, einheit_id FROM tmp_eigensch JOIN einheit ON einheit_id = einheit.id - WHERE art_id = '".$art["id"]."' ORDER BY posnr ASC") or $err=error("Fehler beim ermitteln der Eigenschaften
".mysqli_error($dbconn)); - $eigenschaften = array(); - while($eig=mysqli_fetch_assoc($qry2)) - { - $eigenschaften[] = $eig; - } - $artikel[]=array("art"=>$art,"eig"=>$eigenschaften); + WHERE art_id = ? ORDER BY posnr ASC", array($art["id"])); + if($eigenschaften === false) + error("Fehler beim ermitteln der Eigenschaften
".mysqli_error($dbconn)); + $artikel[]=array("art"=>$art,"eig"=>$eigenschaften ?: array()); } } else { - $qry=mysqli_query($dbconn,"SELECT artikel.bezeichn as bezeichn, preis, wanr, posnr, pagebreak, mwst AS artmwst, rabatt, rabatttyp, artikeltyp.bezeichn AS typ, typ_id, einheit, einheit_id, menge, angtyp, artikel.id as id + $zeilen = db_zeilen($dbconn, "SELECT artikel.bezeichn as bezeichn, preis, wanr, posnr, pagebreak, mwst AS artmwst, rabatt, rabatttyp, artikeltyp.bezeichn AS typ, typ_id, einheit, einheit_id, menge, angtyp, artikel.id as id FROM artikel - JOIN artikeltyp ON typ_id = artikeltyp.id + JOIN artikeltyp ON typ_id = artikeltyp.id JOIN einheit ON einheit_id = einheit.id JOIN artikel_rechn ON artikel.id = art_id JOIN mwst ON artmwst = mwst.id - WHERE rech_id = $rechid ORDER BY posnr ASC") or $err=error("Fehler beim ermitteln der Artikeldaten
".mysqli_error($dbconn)); - $artikel = array(); - while($art=mysqli_fetch_assoc($qry)) + WHERE rech_id = ? ORDER BY posnr ASC", array($rechid)); + if($zeilen === false) + error("Fehler beim ermitteln der Artikeldaten
".mysqli_error($dbconn)); + foreach($zeilen ?: array() as $art) { - $qry2=mysqli_query($dbconn,"SELECT bezeichn, wert, einheit, einheit_id + $eigenschaften = db_zeilen($dbconn, "SELECT bezeichn, wert, einheit, einheit_id FROM eigensch JOIN einheit ON einheit_id = einheit.id JOIN artikel_eigensch ON eigensch.id = eig_id - WHERE art_id = '".$art["id"]."' AND rech_id = '$rechid' AND artposnr = '".$art["posnr"]."' ORDER BY posnr ASC") or $err=error("Fehler beim ermitteln der Eigenschaften
".mysqli_error($dbconn)); - $eigenschaften = array(); - while($eig=mysqli_fetch_assoc($qry2)) - { - $eigenschaften[] = $eig; - } - $artikel[]=array("art"=>$art,"eig"=>$eigenschaften); + WHERE art_id = ? AND rech_id = ? AND artposnr = ? ORDER BY posnr ASC", array($art["id"], $rechid, $art["posnr"])); + if($eigenschaften === false) + error("Fehler beim ermitteln der Eigenschaften
".mysqli_error($dbconn)); + $artikel[]=array("art"=>$art,"eig"=>$eigenschaften ?: array()); } - } + } return $artikel; } -function makesksartikelarray($dbconn,$rechid) +function makesksartikelarray($dbconn,$rechnr) { - - $qry=mysqli_query($dbconn,"SELECT bezeichn1 as bezeichn, preis, rabatt, menge, id + $zeilen = db_zeilen($dbconn, "SELECT bezeichn1 as bezeichn, preis, rabatt, menge, id, bezeichn2 FROM artikelsks - WHERE rechnr = '$rechid' ORDER BY pos ASC") or $err=error("Fehler beim ermitteln der SKS Artikeldaten
".mysqli_error($dbconn)); + WHERE rechnr = ? ORDER BY pos ASC", array($rechnr)); + if($zeilen === false) + error("Fehler beim ermitteln der SKS Artikeldaten
".mysqli_error($dbconn)); $artikel = array(); - while($art=mysqli_fetch_assoc($qry)) + foreach($zeilen ?: array() as $art) { + // Die zweite Bezeichnung wird wie eine Eigenschaft ausgegeben + $eigenschaften = array(array("bezeichn" => $art["bezeichn2"])); + unset($art["bezeichn2"]); $art["artmwst"] = 0; - $qry2=mysqli_query($dbconn,"SELECT bezeichn2 AS bezeichn - FROM artikelsks - WHERE id = '".$art["id"]."'") or $err=error("Fehler beim ermitteln der SKS Eigenschaften
".mysqli_error($dbconn)); - $eigenschaften = array(); - while($eig=mysqli_fetch_assoc($qry2)) - { - $eigenschaften[] = $eig; - } $artikel[]=array("art"=>$art,"eig"=>$eigenschaften); } return $artikel; } +/* --------------------------------------------------------------------- + * Schreiben + * ------------------------------------------------------------------ */ + +/* + * Nächste freie Dokumentnummer des Tages für einen Dokumenttyp + * (JJJJMMTTnn) und trägt sie in rechnr ein. Gibt array(nummer, fehler). + */ +function neueRechnungsnummer($dbconn, $typ) +{ + $heute = date("Ymd"); + $letzte = db_wert($dbconn, "SELECT rechnr FROM rechnr WHERE SUBSTRING(rechnr,1,8) = ? AND typ_id = ? ORDER BY rechnr DESC LIMIT 1", array($heute, $typ)); + if($letzte === false) + return array("", error("Fehler beim ermitteln der Rechnungsnummer
".mysqli_error($dbconn))); + if($letzte === null) + $rechnr = $heute."01"; + elseif(substr($letzte,8,2) < 99) + $rechnr = $letzte + 1; + else + return array("", error("Es wurden bereits 99 Rechnungen heute geschrieben. Das rechnungsnummern-Format lässt nicht mehr Rechnungen pro tag zu...")); + + if(!db_abfrage($dbconn, "INSERT INTO rechnr SET rechnr = ?, typ_id = ?", array($rechnr, $typ))) + return array("", error("Rechnungsnummer wurde nicht eingetragen...
".mysqli_error($dbconn))); + return array($rechnr, 0); +} + function saveRechnung($dbconn,$update) { - $show = str_pad($_POST["show_firmaanr"],1,"0").str_pad($_POST["show_firma"],1,"0"); - $show .= str_pad($_POST["show_anr"],1,"0").str_pad($_POST["show_titel"],1,"0"); - $show .= str_pad($_POST["show_name"],1,"0"); - $show .= str_pad($_POST["show_anr2"],1,"0").str_pad($_POST["show_titel2"],1,"0"); - $show .= str_pad($_POST["show_name2"],1,"0").str_pad($_POST["show_str"],1,"0"); - $show .= str_pad($_POST["show_ort"],1,"0").str_pad($_POST["show_land"],1,"0"); - $show .= str_pad($_POST["show_zusatz"],1,"0"); - $anr1 = trim($_POST["anr1"]); - $adrerw = trim($_POST["adresserweiterung"]); - $anr2 = trim($_POST["anr2"]); - $intro = trim($_POST["intro"]); - $outro = trim($_POST["outro"]); - $type = $_POST["type"]; - $adressid = $_POST["adressid"]; - $partnerid = $_POST["partnerid"]; - $mwst = $_POST["mwst"]; - $zahlziel = $_POST["zahlziel"]; - $wahrung = $_POST["wahrung"]; - $sub_mwst = $_POST["sub_mwst"]; - $rabatt = $_POST["rabatt"]; - $rabattdesc = $_POST["rabattdesc"]; - $lieferdatum = trim($_POST["lieferdatum"]); - $buchKto = $_POST["buchKto"]; - + $show = formularAdressfelder(); + $type = formularGanzzahl("type"); + + // Kopfdaten, identisch für Anlegen und Ändern + $felder = array( + "user_id" => $_SESSION["user"], + "adressfields" => $show, + "anrede1" => formularText("anr1"), + "anrede2" => formularText("anr2"), + "intro" => formularText("intro"), + "outro" => formularText("outro"), + "typ_id" => $type, + "adresse_id" => formularGanzzahl("adressid"), + "partner_id" => formularGanzzahl("partnerid"), + "mwst_id" => formularGanzzahl("mwst"), + "zahlziel_id" => formularGanzzahl("zahlziel"), + "wahrung_id" => formularGanzzahl("wahrung"), + "sub_mwst" => formularGanzzahl("sub_mwst"), + "rabatt" => formularGanzzahl("rabatt"), + "rabattdesc" => formularText("rabattdesc"), + "adresserweiterung" => formularText("adresserweiterung"), + "lieferdatum" => formularText("lieferdatum"), + "buchungsKto_id" => formularGanzzahl("buchKto"), + ); + $set = implode(", ", array_map(function($spalte) { return "`$spalte` = ?"; }, array_keys($felder))); + + // Alles oder nichts: bricht ein Schritt ab, bleibt keine halbe Rechnung + // zurück. Der Entwurf in tmp_rechnung bleibt dann erhalten. + mysqli_begin_transaction($dbconn); + $err = 0; + if($update) { - $rechid=$update; - $undoqry=mysqli_query($dbconn,"SELECT * FROM rechnung WHERE id ='".mysqli_escape_string($dbconn,$update)."'") or $err=error("Fehler beim einholen der Informationen für die LOG
".mysqli_error($dbconn)); - $undores=mysqli_fetch_assoc($undoqry); + $rechid = $update; + $alt = db_zeile($dbconn, "SELECT * FROM rechnung WHERE id = ?", array($rechid)); + if($alt === false) + $err = error("Fehler beim einholen der Informationen für die LOG
".mysqli_error($dbconn)); if(!$err) { - $querystr = "UPDATE rechnung SET - user_id = '".$_SESSION["user"]."', - adressfields='$show', - anrede1='$anr1', - anrede2='$anr2', - intro='$intro', - outro='$outro', - typ_id = '$type', - adresse_id='$adressid', - partner_id='$partnerid', - mwst_id = '$mwst', - zahlziel_id = '$zahlziel', - wahrung_id='$wahrung', - sub_mwst='$sub_mwst', - rabatt='$rabatt', - rabattdesc='$rabattdesc', - adresserweiterung='$adrerw', - lieferdatum='$lieferdatum', - buchungsKto_id='$buchKto',"; - if($_POST["change_date"] == 1){ - $querystr .= "datetime=NOW(),"; + $sql = "UPDATE rechnung SET $set, ".(formularText("change_date") == "1" ? "datetime = NOW(), " : "")."changetime = NOW() WHERE id = ?"; + $werte = array_merge(array_values($felder), array($rechid)); + db_abfrage($dbconn, $sql, $werte) or $err = error("Fehler beim aktualisieren der Rechnung
".mysqli_error($dbconn)); + } + if(!$err && $alt) + { + $altWerte = array(); + foreach(array_keys($felder) as $spalte) + $altWerte[] = $alt[$spalte]; + $undo = db_sql_text($dbconn, "UPDATE rechnung SET $set, changetime = ? WHERE id = ?", array_merge($altWerte, array($alt["changetime"], $rechid))); + $err = saveLog($dbconn, db_sql_text($dbconn, $sql, $werte)." [rechnung change]", $undo, "ändern"); + } + // Artikel- und Eigenschaftsverknüpfungen werden unten neu angelegt + foreach(array("artikel_rechn", "artikel_eigensch") as $tabelle) + { + if(!$err) + { + $sql = "DELETE FROM $tabelle WHERE rech_id = ?"; + db_abfrage($dbconn, $sql, array($rechid)) or $err = error("Fehler beim löschen der Verknüpfungen
".mysqli_error($dbconn)); + if(!$err) + $err = saveLog($dbconn, db_sql_text($dbconn, $sql, array($rechid))." [rechnung change]", "", "löschen"); } - $querystr .= " changetime=NOW() - WHERE id = '".mysqli_escape_string($dbconn,$update)."'"; - mysqli_query($dbconn,$querystr) or $err=error("Fehler beim aktualisieren der Rechnung
".mysqli_error($dbconn)); - } - if(!$err) - { - $undoquerystr = "UPDATE rechnung SET - user_id = '".$undores["user_id"]."', - adressfields='".$undores["adressfields"]."', - anrede1='".$undores["anrede1"]."', - anrede2='".$undores["anrede2"]."', - intro='".$undores["intro"]."', - outro='".$undores["outro"]."', - typ_id = '".$undores["typ_id"]."', - adresse_id='".$undores["adresse_id"]."', - partner_id='".$undores["partner_id"]."', - mwst_id = '".$undores["mwst_id"]."', - zahlziel_id = '".$undores["zahlziel_id"]."', - wahrung_id='".$undores["wahrung_id"]."', - sub_mwst='".$undores["sub_mwst"]."', - rabatt='".$undores["rabatt"]."', - rabattdesc='".$undores["rabattdesc"]."', - adresserweiterung='".$undores["adresserweiterung"]."', - lieferdatum='".$undores["lieferdatum"]."', - buchungsKto_id='".$undores["buchungsKto_id"].", - changetime='".$undores["changetime"]."' - WHERE id = '".mysqli_escape_string($dbconn,$update)."'"; - $err = saveLog($dbconn,$querystr." [rechnung change]",$undoquerystr,"ändern"); - } - //delete ART-RECHN-LINKS - if(!$err) - { - $undoqry=mysqli_query($dbconn,"SELECT GROUP_CONCAT(art_id SEPARATOR ', ') AS art_id FROM artikel_rechn WHERE rech_id ='".mysqli_escape_string($dbconn,$update)."' GROUP BY rech_id") or $err=error("Fehler beim einholen der Verknüpfungen für die LOG
".mysqli_error($dbconn)); - $undores=mysqli_fetch_assoc($undoqry); - } - if(!$err) - { - $querystr = "DELETE FROM artikel_rechn WHERE rech_id = '".mysqli_escape_string($dbconn,$update)."'"; - mysqli_query($dbconn,$querystr) or $err=error("Fehler beim löschen der Verknüpfungen
".mysqli_error($dbconn)); - } - if(!$err) - { - $undoquerystr = "INSERT INTO artikel_rechn SET rech_id = '".mysqli_escape_string($dbconn,$update)."', art_id='".$undores["art_id"]."'"; - $err = saveLog($dbconn,$querystr." [rechnung change]",$undoquerystr,"löschen"); - } - //delete ART-EIG-LINKS - if(!$err) - { - $undoqry=mysqli_query($dbconn,"SELECT GROUP_CONCAT(artposnr SEPARATOR ', ') AS artposnr, GROUP_CONCAT(art_id SEPARATOR ', ') AS art_id, GROUP_CONCAT(eig_id SEPARATOR ', ') AS eig_id FROM artikel_eigensch WHERE rech_id ='".mysqli_escape_string($dbconn,$update)."' GROUP BY rech_id") or $err=error("Fehler beim einholen der Verknüpfungen für die LOG
".mysqli_error($dbconn)); - $undores=mysqli_fetch_assoc($undoqry); - } - if(!$err) - { - $querystr = "DELETE FROM artikel_eigensch WHERE rech_id = '".mysqli_escape_string($dbconn,$update)."'"; - mysqli_query($dbconn,$querystr) or $err=error("Fehler beim löschen der Verknüpfungen
".mysqli_error($dbconn)); - } - if(!$err) - { - $undoquerystr = "INSERT INTO artikel_eigensch SET artposnr = '".$undores["artposnr"]."', rech_id = '".mysqli_escape_string($dbconn,$update)."', art_id='".$undores["art_id"].", 'eig_id='".$undores["eig_id"]."'"; - $err = saveLog($dbconn,$querystr." [rechnung change]",$undoquerystr,"löschen"); } } else { - $qry=mysqli_query($dbconn,"SELECT rechnr FROM rechnr WHERE SUBSTRING(rechnr,1,8) = '".date("Ymd")."' AND typ_id = '$type' ORDER BY rechnr DESC LIMIT 1") or $err=error("Fehler beim ermitteln der Rechnungsnummer
".mysqli_error($dbconn)); - if(mysqli_num_rows($qry) == 1) - { - $res=mysqli_fetch_assoc($qry); - $rechnr = $res["rechnr"]; - if(substr($rechnr,8,2) < 99) - { - $rechnr = $rechnr+1; - $qry=mysqli_query($dbconn,"INSERT INTO rechnr SET rechnr = '$rechnr', typ_id = '$type'") or $err = error("Rechnungsnummer wurde nicht eingetragen...
".mysqli_error($dbconn)); - } - else - { - $err=error("Es wurden bereits 99 Rechnungen heute geschrieben. Das rechnungsnummern-Format lässt nicht mehr Rechnungen pro tag zu..."); - $rechnr = ''; - } - } - else - { - $rechnr = date("Ymd")."01"; - $qry=mysqli_query($dbconn,"INSERT INTO rechnr SET rechnr = '$rechnr', typ_id = '$type'") or $err = error("Rechnungsnummer wurde nicht eingetragen...
".mysqli_error($dbconn)); - } - //echo "
".$rechnr; - //angebote rechnungen gutschriften bestätigungen A/R/G/ B2012.03.22-24 + list($rechnr, $err) = neueRechnungsnummer($dbconn, $type); if(!$err) { - $querystr = "INSERT INTO rechnung SET - user_id = '".$_SESSION["user"]."', - adressfields='$show', - anrede1='$anr1', - anrede2='$anr2', - intro='$intro', - outro='$outro', - typ_id = '$type', - adresse_id='$adressid', - partner_id='$partnerid', - mwst_id = '$mwst', - zahlziel_id = '$zahlziel', - wahrung_id='$wahrung', - sub_mwst='$sub_mwst', - rabatt='$rabatt', - rabattdesc='$rabattdesc', - datetime=NOW(), - lieferdatum='$lieferdatum', - adresserweiterung='$adrerw', - buchungsKto_id='$buchKto', - rechnr= '$rechnr'"; - mysqli_query($dbconn,$querystr) or $err=error("Fehler beim einfügen der Rechnung
".mysqli_error($dbconn)); - $rechid=mysqli_insert_id($dbconn); + $sql = "INSERT INTO rechnung SET $set, datetime = NOW(), rechnr = ?"; + $werte = array_merge(array_values($felder), array($rechnr)); + db_abfrage($dbconn, $sql, $werte) or $err = error("Fehler beim einfügen der Rechnung
".mysqli_error($dbconn)); + $rechid = mysqli_insert_id($dbconn); } if(!$err) - { - $undoquerystr = "DELETE FROM rechnung WHERE id = '".$rechid."'"; - $err = saveLog($dbconn,$querystr." [rechnung add]",$undoquerystr,"anlegen"); - } + $err = saveLog($dbconn, db_sql_text($dbconn, $sql, $werte)." [rechnung add]", "DELETE FROM rechnung WHERE id = '".$rechid."'", "anlegen"); } - + if(!$err) { - //check if artikel already exists $i = 1; - while($_POST["arthead".$i] && !$err) + while(!empty($_POST["arthead".$i]) && !$err) { - if($_POST["artact".$i]) + if(!empty($_POST["artact".$i])) { - $angtyp = trim($_POST["angtyp".$i]); - $arttyp = trim($_POST["arttyp".$i]); - $arthead = trim($_POST["arthead".$i]); - $artpr = str_replace(",",".",trim($_POST["artpr".$i])); - $artmen = str_replace(",",".",trim($_POST["artmen".$i])); - $artrab = trim($_POST["artrab".$i]); - $artrabtyp = trim($_POST["artrabtyp".$i]); - $artmeneinh = trim($_POST["artmeneinh".$i]); - $artwa = trim($_POST["artwa".$i]); - $artmwst = trim($_POST["artmwst".$i]); - $pagebreak = trim($_POST["pagebreak".$i]); - - $qry = mysqli_query($dbconn, "SELECT id FROM artikel WHERE bezeichn=BINARY '$arthead' AND typ_id='$arttyp' AND einheit_id = '$artmeneinh'") or $err=error("Fehler beim ermitteln vorhandener Artikel
".mysqli_error($dbconn)); - if($res=mysqli_fetch_assoc($qry)) + $arthead = formularText("arthead".$i); + $arttyp = formularGanzzahl("arttyp".$i); + $artmeneinh = formularGanzzahl("artmeneinh".$i); + + // Artikel wiederverwenden, wenn Bezeichnung (exakt), Typ und Einheit passen + $artid = db_wert($dbconn, "SELECT id FROM artikel WHERE bezeichn = BINARY ? AND typ_id = ? AND einheit_id = ?", array($arthead, $arttyp, $artmeneinh)); + if($artid === false) + $err = error("Fehler beim ermitteln vorhandener Artikel
".mysqli_error($dbconn)); + elseif($artid === null) { - $artid = $res["id"]; - } - else - { - $querystr = "INSERT INTO artikel SET bezeichn='$arthead', typ_id='$arttyp', einheit_id = '$artmeneinh', datetime=NOW(), user_id = '".$_SESSION["user"]."'"; - $qry = mysqli_query($dbconn, $querystr) or $err=error("Fehler beim erstellen neuer Artikel ($arteinh)
".mysqli_error($dbconn)); + $sql = "INSERT INTO artikel SET bezeichn = ?, typ_id = ?, einheit_id = ?, datetime = NOW(), user_id = ?"; + $werte = array($arthead, $arttyp, $artmeneinh, $_SESSION["user"]); + db_abfrage($dbconn, $sql, $werte) or $err = error("Fehler beim erstellen neuer Artikel
".mysqli_error($dbconn)); $artid = mysqli_insert_id($dbconn); if(!$err) - { - $err = saveLog($dbconn,$querystr." [rechnung change]","DELETE FROM artikel WHERE id ='$artid'","anlegen"); - } - + $err = saveLog($dbconn, db_sql_text($dbconn, $sql, $werte)." [rechnung change]", "DELETE FROM artikel WHERE id ='$artid'", "anlegen"); } if(!$err) { - $querystr = "INSERT INTO artikel_rechn SET - angtyp = '$angtyp', - wanr = '$artwa', - menge = '$artmen', - rabatt = '$artrab', - posnr = '$i', - art_id = '$artid', - artmwst = '$artmwst', - rech_id = '$rechid', - rabatttyp = '$artrabtyp', - pagebreak = '$pagebreak', - preis = '$artpr'"; - $qry = mysqli_query($dbconn, $querystr) or $err=error("Fehler beim erstellen der Artikel-Rechnung Beziehung
".mysqli_error($dbconn)); + db_abfrage($dbconn, "INSERT INTO artikel_rechn SET angtyp = ?, wanr = ?, menge = ?, rabatt = ?, posnr = ?, art_id = ?, artmwst = ?, rech_id = ?, rabatttyp = ?, pagebreak = ?, preis = ?", + array(formularGanzzahl("angtyp".$i), formularText("artwa".$i), formularZahl("artmen".$i), formularGanzzahl("artrab".$i), $i, $artid, + formularGanzzahl("artmwst".$i), $rechid, formularGanzzahl("artrabtyp".$i), formularGanzzahl("pagebreak".$i), formularZahl("artpr".$i))) + or $err = error("Fehler beim erstellen der Artikel-Rechnung Beziehung
".mysqli_error($dbconn)); } - if(!$err) + $ii = 1; + while(!$err && !empty($_POST["arteig".$i."_".$ii])) { - //check if eigenschaften already exists - $ii = 1; - while($_POST["arteig".$i."_".$ii] && !$err) + $arteig = formularText("arteig".$i."_".$ii); + $artval = formularText("artval".$i."_".$ii); + $arteinh = formularGanzzahl("arteinh".$i."_".$ii); + + $eigid = db_wert($dbconn, "SELECT id FROM eigensch WHERE bezeichn = BINARY ? AND wert = ? AND einheit_id = ?", array($arteig, $artval, $arteinh)); + if($eigid === false) + $err = error("Fehler beim ermitteln vorhandener Eigenschaften
".mysqli_error($dbconn)); + elseif($eigid === null) { - $arteig = trim($_POST["arteig".$i."_".$ii]); - $artval = trim($_POST["artval".$i."_".$ii]); - $arteinh = trim($_POST["arteinh".$i."_".$ii]); - - $qry = mysqli_query($dbconn, "SELECT id FROM eigensch WHERE bezeichn=BINARY '$arteig' AND wert='$artval' AND einheit_id='$arteinh'") or $err=error("Fehler beim ermitteln vorhandener Eigenschaften
".mysqli_error($dbconn)); - if($res=mysqli_fetch_assoc($qry)) - { - $eigid = $res["id"]; - } - else - { - $querystr = "INSERT INTO eigensch SET bezeichn='$arteig', einheit_id='$arteinh', wert='$artval', datetime=NOW(), user_id = '".$_SESSION["user"]."'"; - $qry = mysqli_query($dbconn, $querystr) or $err=error("Fehler beim erstellen neuer Eigenschaften ($arteinh)
".mysqli_error($dbconn)); - $eigid = mysqli_insert_id($dbconn); - if(!$err) - { - $err = saveLog($dbconn,$querystr." [rechnung change]","DELETE FROM einh WHERE id ='$eigid'","anlegen"); - } - - } + $sql = "INSERT INTO eigensch SET bezeichn = ?, einheit_id = ?, wert = ?, datetime = NOW(), user_id = ?"; + $werte = array($arteig, $arteinh, $artval, $_SESSION["user"]); + db_abfrage($dbconn, $sql, $werte) or $err = error("Fehler beim erstellen neuer Eigenschaften
".mysqli_error($dbconn)); + $eigid = mysqli_insert_id($dbconn); if(!$err) - { - $qry = mysqli_query($dbconn, "INSERT INTO artikel_eigensch SET posnr='$ii', artposnr = '$i', rech_id='$rechid', eig_id='$eigid', art_id='$artid'") or $err=error("Fehler beim anlegen der Eigenschaften-Artikel-Beziehung
".mysqli_error($dbconn)); - $eigid=mysqli_insert_id($dbconn); - $ii++; - } + $err = saveLog($dbconn, db_sql_text($dbconn, $sql, $werte)." [rechnung change]", "DELETE FROM eigensch WHERE id ='$eigid'", "anlegen"); + } + if(!$err) + { + db_abfrage($dbconn, "INSERT INTO artikel_eigensch SET posnr = ?, artposnr = ?, rech_id = ?, eig_id = ?, art_id = ?", array($ii, $i, $rechid, $eigid, $artid)) + or $err = error("Fehler beim anlegen der Eigenschaften-Artikel-Beziehung
".mysqli_error($dbconn)); + $ii++; } } } $i++; } } + if(!$err) + $err = loescheEntwurf($dbconn, $type); + if(!$err) { - $qry = mysqli_query($dbconn, "SELECT id FROM tmp_rechnung WHERE user_id = '".$_SESSION["user"]."' AND typ_id = '".$type."'") or $err=error("Fehler beim ermitteln der Temp Rechnung
".mysqli_error($dbconn)); - while($res=mysqli_fetch_assoc($qry)) - { - $artqry = mysqli_query($dbconn, "SELECT id FROM tmp_artikel WHERE rech_id = '".$res["id"]."' ") or $err=error("Fehler beim ermitteln der Temp Artikel
".mysqli_error($dbconn)); - while($artres=mysqli_fetch_assoc($artqry)) - { - $delqry = mysqli_query($dbconn, "DELETE FROM tmp_eigensch WHERE art_id = '".$artres["id"]."' ") or $err=error("Fehler beim löschen der Temp Eigenschaften
".mysqli_error($dbconn)); - } - $delqry = mysqli_query($dbconn, "DELETE FROM tmp_artikel WHERE rech_id = '".$res["id"]."' ") or $err=error("Fehler beim löschen der Temp Artikel
".mysqli_error($dbconn)); - } - $qry = mysqli_query($dbconn, "DELETE FROM tmp_rechnung WHERE user_id = '".$_SESSION["user"]."' AND typ_id = '".$type."'") or $err=error("Fehler beim löschen der Temp Rechnung
".mysqli_error($dbconn)); + mysqli_commit($dbconn); } - else + else { + mysqli_rollback($dbconn); $err = error("Es ist ein Fehler beim Speichern aufgetreten,
Ihre Rechnung ist aber noch vorhanden,
Bitte gehen Sie zurück zum Rechnungsformular
@@ -773,161 +546,215 @@ function saveRechnung($dbconn,$update) return $err; } -function delRechnung($dbconn,$id) +/* Entwurf (tmp_rechnung samt Artikeln und Eigenschaften) des Benutzers für einen Typ löschen */ +function loescheEntwurf($dbconn, $type) { - $qry= mysqli_query($dbconn, "DELETE FROM artikel_rechn WHERE rech_id = '".mysql_escape_string($id)."'") or $err=error("Fehler beim löschen der Artikel-Rechnung Beziehung
".mysqli_error($dbconn)); - $qry= mysqli_query($dbconn, "DELETE FROM artikel_eigensch WHERE rech_id = '".mysql_escape_string($id)."'") or $err=error("Fehler beim löschen der Artikel-Eigenschaften Beziehung
".mysqli_error($dbconn)); - $qry= mysqli_query($dbconn, "DELETE FROM rechnung WHERE id = '".mysql_escape_string($id)."' LIMIT 1") or $err=error("Fehler beim löschen der Rechnung
".mysqli_error($dbconn)); + $err = 0; + db_abfrage($dbconn, "DELETE tmp_eigensch FROM tmp_eigensch JOIN tmp_artikel ON tmp_eigensch.art_id = tmp_artikel.id JOIN tmp_rechnung ON tmp_artikel.rech_id = tmp_rechnung.id WHERE tmp_rechnung.user_id = ? AND tmp_rechnung.typ_id = ?", array($_SESSION["user"], $type)) + or $err = error("Fehler beim löschen der Temp Eigenschaften
".mysqli_error($dbconn)); if(!$err) - { - $err = saveLog($dbconn,"DELETE FROM rechnung WHERE id = '".mysql_escape_string($id)."' LIMIT 1 [rechnung DEL]","","löschen"); - } + db_abfrage($dbconn, "DELETE tmp_artikel FROM tmp_artikel JOIN tmp_rechnung ON tmp_artikel.rech_id = tmp_rechnung.id WHERE tmp_rechnung.user_id = ? AND tmp_rechnung.typ_id = ?", array($_SESSION["user"], $type)) + or $err = error("Fehler beim löschen der Temp Artikel
".mysqli_error($dbconn)); + if(!$err) + db_abfrage($dbconn, "DELETE FROM tmp_rechnung WHERE user_id = ? AND typ_id = ?", array($_SESSION["user"], $type)) + or $err = error("Fehler beim löschen der Temp Rechnung
".mysqli_error($dbconn)); return $err; } -function changeRechAdr($dbconn,$id,$adrid) + +/* + * Zwischenspeichern des Rechnungsformulars (ajax/autosave.php, + * ajax/preview.php) als Entwurf. Pro Benutzer und Dokumenttyp gibt es einen + * Entwurf; seine Artikel werden jedes Mal neu geschrieben. Mit + * $nurAktive = true werden nur Artikel mit gesetztem artact übernommen. + * Gibt array(entwurf_id, fehler) zurück. + */ +function saveTmpRechnung($dbconn, $nurAktive) { - $qry= mysqli_query($dbconn, "SELECT adresse_id, partner_id FROM rechnung WHERE id = '".mysqli_escape_string($dbconn,$id)."'") or $err=error("Fehler beim ermitteln der Rechnungsadresse für die LOG
".mysqli_error($dbconn)); - $res=mysqli_fetch_assoc($qry); - if($res["adresse_id"]) + $type = formularGanzzahl("type"); + $felder = array( + "user_id" => $_SESSION["user"], + "adressfields" => formularAdressfelder(), + "anrede1" => formularText("anr1"), + "anrede2" => formularText("anr2"), + "intro" => formularText("intro"), + "outro" => formularText("outro"), + "typ_id" => $type, + "adresse_id" => formularGanzzahl("adressid"), + "partner_id" => formularGanzzahl("partnerid"), + "mwst_id" => formularGanzzahl("mwst"), + "zahlziel_id" => formularGanzzahl("zahlziel"), + "wahrung_id" => formularGanzzahl("wahrung"), + "sub_mwst" => formularGanzzahl("sub_mwst"), + "rabatt" => formularGanzzahl("rabatt"), + "rabattdesc" => formularText("rabattdesc"), + "adresserweiterung" => formularText("adresserweiterung"), + "lieferdatum" => formularText("lieferdatum"), + "buchungsKto_id" => formularGanzzahl("buchKto"), + ); + $set = implode(", ", array_map(function($spalte) { return "`$spalte` = ?"; }, array_keys($felder))); + + mysqli_begin_transaction($dbconn); + $err = 0; + $progressid = db_wert($dbconn, "SELECT id FROM tmp_rechnung WHERE user_id = ? AND typ_id = ? ORDER BY id LIMIT 1", array($_SESSION["user"], $type)); + if($progressid === false) + $err = error("Fehler beim ermitteln der Rechnung
".mysqli_error($dbconn)); + elseif($progressid === null) { - $qry= mysqli_query($dbconn, "SELECT partner_id FROM adresse WHERE id = '".mysqli_escape_string($dbconn,$adrid)."'") or $err=error("Fehler beim ermitteln der Rechnungsadresse für die LOG
".mysqli_error($dbconn)); - $res2=mysqli_fetch_assoc($qry); - $querystr="UPDATE rechnung SET adresse_id = '".mysqli_escape_string($dbconn,$adrid)."', partner_id = '".$res2["partner_id"]."' WHERE id = '".mysqli_escape_string($dbconn,$id)."'"; - $undoquerystr="UPDATE rechnung SET adresse_id = '".$res["adresse_id"]."', partner_id = '".$res["partner_id"]."' WHERE id = '".mysqli_escape_string($dbconn,$id)."'"; - $qry= mysqli_query($dbconn, $querystr) or $err=error("Fehler beim ändern der Rechnungsadresse
".mysqli_error($dbconn)); + db_abfrage($dbconn, "INSERT INTO tmp_rechnung SET $set, datetime = NOW()", array_values($felder)) + or $err = error("Fehler beim erstellen der Rechnung
".mysqli_error($dbconn)); + $progressid = mysqli_insert_id($dbconn); } else { - $err=error("Rechnung nicht gefunden!!"); + db_abfrage($dbconn, "UPDATE tmp_rechnung SET $set, datetime = NOW() WHERE id = ?", array_merge(array_values($felder), array($progressid))) + or $err = error("Fehler beim aktualisieren der Rechnung
".mysqli_error($dbconn)); + // Überzählige Entwürfe desselben Typs aufräumen + if(!$err) + db_abfrage($dbconn, "DELETE tmp_eigensch FROM tmp_eigensch JOIN tmp_artikel ON tmp_eigensch.art_id = tmp_artikel.id JOIN tmp_rechnung ON tmp_artikel.rech_id = tmp_rechnung.id WHERE tmp_rechnung.user_id = ? AND tmp_rechnung.typ_id = ? AND tmp_rechnung.id != ?", array($_SESSION["user"], $type, $progressid)) + && db_abfrage($dbconn, "DELETE tmp_artikel FROM tmp_artikel JOIN tmp_rechnung ON tmp_artikel.rech_id = tmp_rechnung.id WHERE tmp_rechnung.user_id = ? AND tmp_rechnung.typ_id = ? AND tmp_rechnung.id != ?", array($_SESSION["user"], $type, $progressid)) + && db_abfrage($dbconn, "DELETE FROM tmp_rechnung WHERE user_id = ? AND typ_id = ? AND id != ?", array($_SESSION["user"], $type, $progressid)) + or $err = error("Fehler beim löschen alter tmp Rechnungen
".mysqli_error($dbconn)); } + if(!$err) + db_abfrage($dbconn, "DELETE tmp_eigensch FROM tmp_eigensch JOIN tmp_artikel ON tmp_eigensch.art_id = tmp_artikel.id WHERE tmp_artikel.rech_id = ?", array($progressid)) + && db_abfrage($dbconn, "DELETE FROM tmp_artikel WHERE rech_id = ?", array($progressid)) + or $err = error("Fehler beim löschen der Artikel
".mysqli_error($dbconn)); + + $i = 1; + while(!$err && !empty($_POST["arthead".$i])) { - $err = saveLog($dbconn,$querystr." [rechnungsadr change]",$undoquerystr,"ändern"); + if(!$nurAktive || !empty($_POST["artact".$i])) + { + db_abfrage($dbconn, "INSERT INTO tmp_artikel SET bezeichn = ?, preis = ?, mwst_id = ?, pagebreak = ?, einheit_id = ?, typ_id = ?, datetime = NOW(), wanr = ?, rech_id = ?, posnr = ?, rabatt = ?, rabatttyp = ?, menge = ?, angtyp = ?", + array(formularText("arthead".$i), formularZahl("artpr".$i), formularGanzzahl("artmwst".$i), formularGanzzahl("pagebreak".$i), formularGanzzahl("artmeneinh".$i), + formularGanzzahl("arttyp".$i), formularText("artwa".$i), $progressid, $i, formularGanzzahl("artrab".$i), formularGanzzahl("artrabtyp".$i), + formularZahl("artmen".$i), formularGanzzahl("angtyp".$i))) + or $err = error("Fehler beim anlegen der Artikel
".mysqli_error($dbconn)); + $artid = mysqli_insert_id($dbconn); + $ii = 1; + while(!$err && !empty($_POST["arteig".$i."_".$ii])) + { + db_abfrage($dbconn, "INSERT INTO tmp_eigensch SET bezeichn = ?, wert = ?, einheit_id = ?, datetime = NOW(), posnr = ?, art_id = ?", + array(formularText("arteig".$i."_".$ii), formularText("artval".$i."_".$ii), formularGanzzahl("arteinh".$i."_".$ii), $ii, $artid)) + or $err = error("Fehler beim anlegen der Eigenschaften
".mysqli_error($dbconn)); + $ii++; + } + } + $i++; } + + if($err) + mysqli_rollback($dbconn); + else + mysqli_commit($dbconn); + return array($progressid, $err); +} + +function delRechnung($dbconn,$id) +{ + $err = 0; + mysqli_begin_transaction($dbconn); + db_abfrage($dbconn, "DELETE FROM artikel_rechn WHERE rech_id = ?", array($id)) or $err = error("Fehler beim löschen der Artikel-Rechnung Beziehung
".mysqli_error($dbconn)); + if(!$err) + db_abfrage($dbconn, "DELETE FROM artikel_eigensch WHERE rech_id = ?", array($id)) or $err = error("Fehler beim löschen der Artikel-Eigenschaften Beziehung
".mysqli_error($dbconn)); + if(!$err) + db_abfrage($dbconn, "DELETE FROM rechnung WHERE id = ? LIMIT 1", array($id)) or $err = error("Fehler beim löschen der Rechnung
".mysqli_error($dbconn)); + if(!$err) + $err = saveLog($dbconn, db_sql_text($dbconn, "DELETE FROM rechnung WHERE id = ? LIMIT 1", array($id))." [rechnung DEL]", "", "löschen"); + $err ? mysqli_rollback($dbconn) : mysqli_commit($dbconn); return $err; } + +/* Storno setzen (1) oder zurücknehmen (0) */ +function stornoRechnung($dbconn, $id, $storno) +{ + $err = 0; + if($storno) + $sql = "UPDATE rechnung SET storno = 1, stornodate = NOW() WHERE id = ?"; + else + $sql = "UPDATE rechnung SET storno = 0 WHERE id = ?"; + db_abfrage($dbconn, $sql, array($id)) or $err = error("Fehler beim aktualisieren der Rechnung
".mysqli_error($dbconn)); + return $err; +} + +function changeRechAdr($dbconn,$id,$adrid) +{ + $err = 0; + $res = db_zeile($dbconn, "SELECT adresse_id, partner_id FROM rechnung WHERE id = ?", array($id)); + if($res === false) + return error("Fehler beim ermitteln der Rechnungsadresse für die LOG
".mysqli_error($dbconn)); + if(!$res || !$res["adresse_id"]) + return error("Rechnung nicht gefunden!!"); + + $partnerid = db_wert($dbconn, "SELECT partner_id FROM adresse WHERE id = ?", array($adrid)); + if($partnerid === false) + return error("Fehler beim ermitteln der Rechnungsadresse für die LOG
".mysqli_error($dbconn)); + + $sql = "UPDATE rechnung SET adresse_id = ?, partner_id = ? WHERE id = ?"; + $werte = array($adrid, $partnerid, $id); + db_abfrage($dbconn, $sql, $werte) or $err = error("Fehler beim ändern der Rechnungsadresse
".mysqli_error($dbconn)); + if(!$err) + $err = saveLog($dbconn, db_sql_text($dbconn, $sql, $werte)." [rechnungsadr change]", db_sql_text($dbconn, $sql, array($res["adresse_id"], $res["partner_id"], $id)), "ändern"); + return $err; +} + +/* Kopiert ein Dokument samt Artikeln und Eigenschaften auf eine andere Adresse, mit neuer Nummer */ function copyRech($dbconn,$id,$adrid) { - $qry=mysqli_query($dbconn,"SELECT rechnr FROM rechnr WHERE SUBSTRING(rechnr,1,8) = '".date("Ymd")."' ORDER BY rechnr DESC LIMIT 1") or $err=error("Fehler beim ermitteln der Rechnungsnummer
".mysqli_error($dbconn)); - if(mysqli_num_rows($qry) == 1) - { - $res=mysqli_fetch_assoc($qry); - $rechnr = $res["rechnr"]; - if(substr($rechnr,8,2) < 99) - { - $rechnr = $rechnr+1; - $qry=mysqli_query($dbconn,"INSERT INTO rechnr SET rechnr = '$rechnr'") or $err = error("Rechnungsnummer wurde nicht eingetragen..."); - } - else - { - $err=error("Es wurden bereits 99 Rechnungen heute geschrieben. Das rechnungsnummern-Format lässt nicht mehr Rechnungen pro tag zu..."); - $rechnr = ''; - } - } - else - { - $rechnr = date("Ymd")."01"; - $qry=mysqli_query($dbconn,"INSERT INTO rechnr SET rechnr = '$rechnr'") or $err = error("Rechnungsnummer wurde nicht eingetragen..."); - } - + $err = 0; + $res = db_zeile($dbconn, "SELECT * FROM rechnung WHERE id = ?", array($id)); + if($res === false) + return error("Fehler beim ermitteln der Rechnungsdaten
".mysqli_error($dbconn)); + if(!$res) + return error("Rechnung nicht gefunden!!"); + $partnerid = db_wert($dbconn, "SELECT partner_id FROM adresse WHERE id = ?", array($adrid)); + if($partnerid === false) + return error("Fehler beim ermitteln der Adressdaten
".mysqli_error($dbconn)); + + mysqli_begin_transaction($dbconn); + list($rechnr, $err) = neueRechnungsnummer($dbconn, $res["typ_id"]); if(!$err) { - $qry= mysqli_query($dbconn, "SELECT partner_id FROM adresse WHERE id = '".mysqli_escape_string($dbconn,$adrid)."'") or $err=error("Fehler beim ermitteln der Adressdaten
".mysqli_error($dbconn)); - $res=mysqli_fetch_assoc($qry); - $partnerid = $res["partner_id"]; - $qry= mysqli_query($dbconn, "SELECT * FROM rechnung WHERE id = '".mysqli_escape_string($dbconn,$id)."'") or $err=error("Fehler beim ermitteln der Rechnungsdaten
".mysqli_error($dbconn)); - $res=mysqli_fetch_assoc($qry); - $querystr = "INSERT INTO rechnung SET - adressfields = '".$res["adressfields"]."', - anrede1 = '".$res["anrede1"]."', - anrede2 = '".$res["anrede2"]."', - partner_id = '$partnerid', - mwst_id = '".$res["mwst_id"]."', - user_id = '".$_SESSION["user"]."', - typ_id = ".$res["typ_id"].", - zahlziel_id = '".$res["zahlziel_id"]."', - adresse_id = '".mysqli_escape_string($dbconn,$adrid)."', - wahrung_id = '".$res["wahrung_id"]."', - adresserweiterung = '".$res["adresserweiterung"]."', - datetime = NOW(), - intro = '".$res["intro"]."', - outro = '".$res["outro"]."', - rechnr = '".$rechnr."', - lieferdatum = '".$res["lieferdatum"]."', - buchungsKto_id = '".$res["buchungsKto_id"]."', - sub_mwst = '".$res["sub_mwst"]."'"; - $qry= mysqli_query($dbconn, $querystr) or $err=error("Fehler beim Kopieren der Rechnungsdaten
".mysqli_error($dbconn)); + $sql = "INSERT INTO rechnung SET adressfields = ?, anrede1 = ?, anrede2 = ?, partner_id = ?, mwst_id = ?, user_id = ?, typ_id = ?, zahlziel_id = ?, adresse_id = ?, wahrung_id = ?, adresserweiterung = ?, datetime = NOW(), intro = ?, outro = ?, rechnr = ?, lieferdatum = ?, buchungsKto_id = ?, sub_mwst = ?"; + $werte = array($res["adressfields"], $res["anrede1"], $res["anrede2"], $partnerid, $res["mwst_id"], $_SESSION["user"], $res["typ_id"], $res["zahlziel_id"], $adrid, + $res["wahrung_id"], $res["adresserweiterung"], $res["intro"], $res["outro"], $rechnr, $res["lieferdatum"], $res["buchungsKto_id"], $res["sub_mwst"]); + db_abfrage($dbconn, $sql, $werte) or $err = error("Fehler beim Kopieren der Rechnungsdaten
".mysqli_error($dbconn)); $rechid = mysqli_insert_id($dbconn); - $undoquerystr = "DELETE FROM rechnung WHERE id = $rechid"; + } + if(!$err) + $err = saveLog($dbconn, db_sql_text($dbconn, $sql, $werte)." [rechnung copy]", "DELETE FROM rechnung WHERE id = $rechid", "anlegen"); + + if(!$err) + { + $sql = "INSERT INTO artikel_rechn (art_id, rech_id, posnr, rabatt, rabatttyp, menge, preis, angtyp, artmwst, wanr, pagebreak) + SELECT art_id, ?, posnr, rabatt, rabatttyp, menge, preis, angtyp, artmwst, wanr, pagebreak FROM artikel_rechn WHERE rech_id = ? ORDER BY id"; + db_abfrage($dbconn, $sql, array($rechid, $id)) or $err = error("Fehler beim Kopieren der Dokument-Artikelbeziehnung
".mysqli_error($dbconn)); + if(!$err) + $err = saveLog($dbconn, db_sql_text($dbconn, $sql, array($rechid, $id))." [rechnung copy]", "DELETE FROM artikel_rechn WHERE rech_id = $rechid", "anlegen"); } if(!$err) { - $err = saveLog($dbconn,$querystr." [rechnung copy]",$undoquerystr,"anlegen"); + $sql = "INSERT INTO artikel_eigensch (art_id, eig_id, rech_id, posnr, artposnr) + SELECT art_id, eig_id, ?, posnr, artposnr FROM artikel_eigensch WHERE rech_id = ?"; + db_abfrage($dbconn, $sql, array($rechid, $id)) or $err = error("Fehler beim Kopieren der Artikel-Eigenschaftenbeziehung
".mysqli_error($dbconn)); + if(!$err) + $err = saveLog($dbconn, db_sql_text($dbconn, $sql, array($rechid, $id))." [rechnung copy]", "DELETE FROM artikel_eigensch WHERE rech_id = $rechid", "anlegen"); } - if(!$err) - { - $qry= mysqli_query($dbconn, "SELECT * FROM artikel_rechn WHERE rech_id = '".mysqli_escape_string($dbconn,$id)."'") or $err=error("Fehler beim ermitteln der Artikel-Dokumentbeziehung
".mysqli_error($dbconn)); - while($res=mysqli_fetch_assoc($qry)) - { - $querystr = "INSERT INTO artikel_rechn SET - art_id = '".$res["art_id"]."', - rech_id = '".$rechid."', - posnr = '".$res["posnr"]."', - rabatt = '".$res["rabatt"]."', - rabatttyp = '".$res["rabatttyp"]."', - menge = ".$res["menge"].", - preis = '".$res["preis"]."', - angtyp = '".$res["angtyp"]."', - artmwst = '".$res["artmwst"]."', - wanr = '".$res["wanr"]."', - pagebreak = '".$res["pagebreak"]."'"; - mysqli_query($dbconn, $querystr) or $err=error("Fehler beim Kopieren der Dokument-Artikelbeziehnung
".mysqli_error($dbconn)); - $art_rech_id = mysqli_insert_id($dbconn); - $undoquerystr = "DELETE FROM artikel_rechn WHERE id = $art_rech_id"; - if(!$err) - { - $err = saveLog($dbconn,$querystr." [rechnung copy]",$undoquerystr,"anlegen"); - } - } - } - if(!$err) - { - $qry= mysqli_query($dbconn, "SELECT * FROM artikel_eigensch WHERE rech_id = '".mysqli_escape_string($dbconn,$id)."'") or $err=error("Fehler beim ermitteln der Artikel-Eigenschaftenbeziehung
".mysqli_error($dbconn)); - while($res=mysqli_fetch_assoc($qry)) - { - $querystr = "INSERT INTO artikel_eigensch SET - art_id = '".$res["art_id"]."', - eig_id = '".$res["eig_id"]."', - rech_id = '".$rechid."', - posnr = '".$res["posnr"]."', - artposnr = '".$res["artposnr"]."'"; - mysqli_query($dbconn, $querystr) or $err=error("Fehler beim Kopieren der Artikel-Eigenschaftenbeziehung
".mysqli_error($dbconn)); - $art_eig_id = mysqli_insert_id($dbconn); - $undoquerystr = "DELETE FROM artikel_eigensch WHERE id = $art_eig_id"; - if(!$err) - { - $err = saveLog($dbconn,$querystr." [rechnung copy]",$undoquerystr,"anlegen"); - } - } - } - + $err ? mysqli_rollback($dbconn) : mysqli_commit($dbconn); return $err; } function calculateRechnungsSum($dbconn, $rechid, $inclmwst) { - $qry = mysqli_query($dbconn, "SELECT mwst, rabatt, sub_mwst, sks, rabatt FROM rechnung JOIN mwst ON mwst.id = mwst_id WHERE rechnung.id ='".$rechid."'"); - $res = mysqli_fetch_assoc($qry); + $res = db_zeile($dbconn, "SELECT mwst, rabatt, sub_mwst, sks FROM rechnung JOIN mwst ON mwst.id = mwst_id WHERE rechnung.id = ?", array($rechid)); if($res["sks"] == 1) - { - $qry = mysqli_query($dbconn,"SELECT menge, preis, '19' AS artmwst FROM artikelsks WHERE rechnr = '".$rechid."'"); - } - else { - $qry = mysqli_query($dbconn,"SELECT rabatt AS artrabatt, menge, preis, mwst AS artmwst, artikel_rechn.id AS id FROM artikel_rechn JOIN mwst ON artikel_rechn.artmwst = mwst.id WHERE rech_id = '".$rechid."'"); - } + $artikel = db_zeilen($dbconn, "SELECT menge, preis, '19' AS artmwst FROM artikelsks WHERE rechnr = ?", array($rechid)); + else + $artikel = db_zeilen($dbconn, "SELECT rabatt AS artrabatt, menge, preis, mwst AS artmwst, artikel_rechn.id AS id FROM artikel_rechn JOIN mwst ON artikel_rechn.artmwst = mwst.id WHERE rech_id = ?", array($rechid)); $sum = Array(); $mixedmwst = 0; - while($artres = mysqli_fetch_assoc($qry)) + foreach($artikel ?: array() as $artres) { if($artres["artmwst"] > 0 && $artres["artmwst"] != 999 && $artres["artmwst"] != $res["mwst"]) { @@ -938,42 +765,28 @@ function calculateRechnungsSum($dbconn, $rechid, $inclmwst) $artres["artmwst"] = $res["mwst"]; $artmwst=$artres["artmwst"]; if($res["sub_mwst"]) - $artres["preis"] = round(100*$artres["preis"]/(100+$artmwst),2); - //if($artres["artmwst"] == 999) - // $artres["artmwst"] = $res["mwst"]; - //if($res["sub_mwst"]) - // $artres["preis"] = round((100*$artres["preis"])/(100+$artres["artmwst"]),2,PHP_ROUND_HALF_UP); - //if($inclmwst) - // $artres["preis"] = round((100+$artres["artmwst"])*$artres["preis"]/(100),2,PHP_ROUND_HALF_UP); - - //$sum += round($artres["menge"] * $artres["preis"] * (1 - ($artres["artrabatt"]/100)),2,PHP_ROUND_HALF_UP); - if($artres["artrabatt"]) + $artres["preis"] = round(100*$artres["preis"]/(100+$artmwst),2); + if(!isset($sum[$artres["artmwst"]])) + $sum[$artres["artmwst"]] = 0; + if(!empty($artres["artrabatt"])) { $sum[$artres["artmwst"]] += round(-1*$artres["preis"]*$artres["menge"]*($artres["artrabatt"]/100),2); } $sum[$artres["artmwst"]] += $artres["preis"]*$artres["menge"]; - //if($artres["artmwst"] != 19){ - // echo "Mwst: ".$artres["artmwst"]." ID: ".$artres["id"]."
"; - // } } - - + if($mixedmwst == 0 && $res["mwst"] == 0) { - - //RABATT + //RABATT if ($res["rabatt"] != "0") { - - $multi=$res["rabatt"]/100; - foreach($sum AS $mwst => $ubertr_mwst) { $sum[$mwst]=$sum[$mwst]-$sum[$mwst]*$multi; } } - + //Mwst ausweisen $sum_all = 0; foreach($sum as $mwst => $ubertr_mwst){ @@ -983,25 +796,15 @@ function calculateRechnungsSum($dbconn, $rechid, $inclmwst) else{ $sum_all += $ubertr_mwst; } - } } - else { - $multi=$res["rabatt"]/100; foreach($sum AS $mwst => $ubertr_mwst) { $sum[$mwst]= round($sum[$mwst]-$sum[$mwst]*$multi,2); } - - - //foreach($sum AS $mwst => $ubertr_mwst) - //{ - // $multi=$mwst/100; - // $sum[$mwst] = $sum[$mwst]+round($sum[$mwst]*$multi,2); - //} $sum_all = 0; foreach($sum as $mwst => $ubertr_mwst){ if($inclmwst){ @@ -1011,11 +814,8 @@ function calculateRechnungsSum($dbconn, $rechid, $inclmwst) $sum_all += $ubertr_mwst; } } - //foreach($sum as $ubertr_mwst) - // $sum_all += $ubertr_mwst; - } return round($sum_all,2); } -?> \ No newline at end of file +?> diff --git a/incs/saveNchange.php b/incs/saveNchange.php index a86e650..3c6341b 100644 --- a/incs/saveNchange.php +++ b/incs/saveNchange.php @@ -1,18 +1,20 @@ ".mysqli_error($dbconn)); - $res=mysqli_fetch_array($qry); - - $qry=mysqli_query($dbconn,"INSERT INTO log SET - typ_id= '$res[0]', - datetime=NOW(), - qry='".mysql_escape_string($qrystr)."', - undo_qry='".mysql_escape_string($undoqry)."', - user_id='".mysql_escape_string($_SESSION["user"])."'") - or $err=error("Fehler beim LOGGEN der Aktion:
".mysqli_error($dbconn)); + $err = 0; + $typId = db_wert($dbconn, "SELECT id FROM accesstype WHERE typ = ?", array($type)); + if($typId === false) + return error("Fehler beim Eintragen der Aktion in die LOG:
".mysqli_error($dbconn)); + db_abfrage($dbconn, "INSERT INTO log SET typ_id = ?, datetime = NOW(), qry = ?, undo_qry = ?, user_id = ?", + array((int)$typId, $qrystr, $undoqry, $_SESSION["user"])) + or $err = error("Fehler beim LOGGEN der Aktion:
".mysqli_error($dbconn)); return $err; } diff --git a/sites/rechnungadd.php b/sites/rechnungadd.php index d3af215..58bcc2b 100644 --- a/sites/rechnungadd.php +++ b/sites/rechnungadd.php @@ -42,58 +42,25 @@ elseif($_GET["copy"] == 1 && $_GET["id"]) doneNreturn("Erfolgreich geändert"); } } -elseif($_GET["storno"] == "YES" && $_GET["id"]){ - $querystr = "UPDATE rechnung SET - storno = 1, stornodate = NOW() WHERE id = '".$_GET["id"]."'"; - mysqli_query($dbconn,$querystr) or $err=error("Fehler beim aktualisieren der Rechnung
".mysqli_error($dbconn)); - doneNreturn("Erfolgreich geändert"); -} -elseif($_GET["storno"] == "NO" && $_GET["id"]){ - $querystr = "UPDATE rechnung SET - storno = 0 WHERE id = '".$_GET["id"]."'"; - mysqli_query($dbconn,$querystr) or $err=error("Fehler beim aktualisieren der Rechnung
".mysqli_error($dbconn)); - doneNreturn("Erfolgreich geändert"); +elseif(($_GET["storno"] == "YES" || $_GET["storno"] == "NO") && $_GET["id"]){ + $err = stornoRechnung($dbconn, $_GET["id"], $_GET["storno"] == "YES"); + if(!$err) + doneNreturn("Erfolgreich geändert"); } elseif($_GET["mail"] == 1 && $_GET["id"]) { $kdnres=makeadressarray($dbconn, $_GET["adressid"]); - $typnames=array(); - $qry=mysqli_query($dbconn, "SELECT id,anrede FROM anrede"); - while($res=mysqli_fetch_assoc($qry)) - { - $typnames[$res["id"]] = $res["anrede"]; - } - $smarty->assign("anrs",$typnames); - - $typnames=array(); - $qry=mysqli_query($dbconn, "SELECT id,titel FROM titel"); - while($res=mysqli_fetch_assoc($qry)) - { - $typnames[$res["id"]] = $res["titel"]; - } - $smarty->assign("titels",$typnames); - - $mails=array(); - $mailids=array(); - $qry = mysqli_query($dbconn,"SELECT kontakt.id, kontakt, partner_id, typ FROM kontakt LEFT JOIN kontakttyp ON kontakttyp.id = kontakt.typ_id WHERE partner_id='".mysql_escape_string($kdnres["partner_id"])."' AND typ_id = 1"); - while($res=mysqli_fetch_assoc($qry)) - { - $mails[] = $res["kontakt"]; - $mailids[] = $res["id"]; - } - $smarty->assign("mails",$mails); - $smarty->assign("mailids",$mailids); - - $typids=array(); - $typnames=array(); - $qry=mysqli_query($dbconn, "SELECT id,bezeichn FROM artikeltyp"); - while($res=mysqli_fetch_assoc($qry)) - { - $typids[] = $res["id"]; - $typnames[] = $res["bezeichn"]; - } - $smarty->assign("typids",$typids); - $smarty->assign("typs",$typnames); + list($anrs, $titels) = anredenUndTitel($dbconn); + $smarty->assign("anrs",$anrs); + $smarty->assign("titels",$titels); + + $mails = db_zuordnung($dbconn, "SELECT id, kontakt FROM kontakt WHERE partner_id = ? AND typ_id = 1", array($kdnres["partner_id"] ?? 0)) ?: array(); + $smarty->assign("mails",array_values($mails)); + $smarty->assign("mailids",array_keys($mails)); + + $typen = db_zuordnung($dbconn, "SELECT id, bezeichn FROM artikeltyp") ?: array(); + $smarty->assign("typids",array_keys($typen)); + $smarty->assign("typs",array_values($typen)); $rechnung=makerechnungsarray($dbconn, $_GET["id"], 0); $smarty->assign("rechnung",$rechnung); $smarty->assign("adresse",$kdnres); @@ -197,72 +164,29 @@ else if($kdnres["adresstyp"] == "Kommission") { $smarty->assign("kommission",$kdnres); - $qry = mysqli_query($dbconn,"SELECT plz, ortsteil, ort, str, adresstyp.typ AS adresstyp, hnr, vname, partner_id, nname, vname2, nname2, firma, adresse.id, land, anrede_id, titel_id, anrede2_id, titel2_id - FROM adresse - LEFT JOIN strasse ON str_id = strasse.id - LEFT JOIN ort ON ort_id = ort.id - LEFT JOIN land ON land_id = land.id - JOIN adresstyp ON adresse.typ_id = adresstyp.id - WHERE adresse.typ_id='1' AND adresse.partner_id = '".$kdnres["partner_id"]."' - ORDER BY typ_id ASC") or $err = error("Fehler beim abrufen der Daten ".mysqli_error($dbconn)); - //$kdnres=mysqli_fetch_assoc($qry); } if($kdnres["partner_id"]) { - $typnames=array(); - $qry=mysqli_query($dbconn, "SELECT id,anrede FROM anrede"); - while($res=mysqli_fetch_assoc($qry)) - { - $typnames[$res["id"]] = $res["anrede"]; - } - $smarty->assign("anrs",$typnames); - - $typnames=array(); - $qry=mysqli_query($dbconn, "SELECT id,titel FROM titel"); - while($res=mysqli_fetch_assoc($qry)) - { - $typnames[$res["id"]] = $res["titel"]; - } - $smarty->assign("titels",$typnames); - + list($anrs, $titels) = anredenUndTitel($dbconn); + $smarty->assign("anrs",$anrs); + $smarty->assign("titels",$titels); + + $liste = db_zuordnung($dbconn, "SELECT id, bezeichn FROM artikeltyp") ?: array(); + $smarty->assign("typids",array_keys($liste)); + $smarty->assign("typs",array_values($liste)); + + $liste = db_zuordnung($dbconn, "SELECT id, einheit FROM einheit") ?: array(); + $smarty->assign("einhids",array_keys($liste)); + $smarty->assign("einhs",array_values($liste)); + + $liste = db_zuordnung($dbconn, "SELECT id, wahrung FROM wahrung") ?: array(); + $smarty->assign("wahrids",array_keys($liste)); + $smarty->assign("wahrs",array_values($liste)); + $typids=array(); $typnames=array(); - $qry=mysqli_query($dbconn, "SELECT id,bezeichn FROM artikeltyp"); - while($res=mysqli_fetch_assoc($qry)) - { - $typids[] = $res["id"]; - $typnames[] = $res["bezeichn"]; - } - $smarty->assign("typids",$typids); - $smarty->assign("typs",$typnames); - - $typids=array(); - $typnames=array(); - $qry=mysqli_query($dbconn, "SELECT id,einheit FROM einheit"); - while($res=mysqli_fetch_assoc($qry)) - { - $typids[] = $res["id"]; - $typnames[] = $res["einheit"]; - } - $smarty->assign("einhids",$typids); - $smarty->assign("einhs",$typnames); - - $typids=array(); - $typnames=array(); - $qry=mysqli_query($dbconn, "SELECT id,wahrung FROM wahrung"); - while($res=mysqli_fetch_assoc($qry)) - { - $typids[] = $res["id"]; - $typnames[] = $res["wahrung"]; - } - $smarty->assign("wahrids",$typids); - $smarty->assign("wahrs",$typnames); - - $typids=array(); - $typnames=array(); - $qry=mysqli_query($dbconn, "SELECT id,mwst FROM mwst"); - while($res=mysqli_fetch_assoc($qry)) + foreach(db_zeilen($dbconn, "SELECT id, mwst FROM mwst") ?: array() as $res) { if($res["mwst"] != "999") { @@ -283,31 +207,18 @@ else $smarty->assign("artmwstids",$typids2); $smarty->assign("artmwsts",$typnames2); - $typids=array(); - $typnames=array(); - $qry=mysqli_query($dbconn, "SELECT id,ziel FROM zahlziel"); - while($res=mysqli_fetch_assoc($qry)) - { - $typids[] = $res["id"]; - $typnames[] = $res["ziel"]; - } - $smarty->assign("zzielids",$typids); - $smarty->assign("zziels",$typnames); - - $typids=array(); - $typnames=array(); - $qry=mysqli_query($dbconn, "SELECT id,kto,name FROM buchungsKontos"); - while($res=mysqli_fetch_assoc($qry)) - { - $typids[] = $res["id"]; - - $typnames[] = $res["kto"]." (".$res["name"].")"; - } - $smarty->assign("buchKtoids",$typids); - $smarty->assign("buchKtos",$typnames); - - $qry=mysqli_query($dbconn,"SELECT tmp_rechnung.id,adresse_id, vname, nname, str, hnr FROM tmp_rechnung JOIN adresse ON adresse_id = adresse.id JOIN strasse ON str_id = strasse.id WHERE tmp_rechnung.typ_id='".mysql_escape_string($_GET["type"])."' AND user_id = '".mysql_escape_string($_SESSION["user"])."' ORDER BY datetime DESC LIMIT 1") or $err=error("Fehler beim Suchen nach nicht gespeicherten Daten
".mysqli_error($dbconn)); - if($res = mysqli_fetch_assoc($qry)) + $liste = db_zuordnung($dbconn, "SELECT id, ziel FROM zahlziel") ?: array(); + $smarty->assign("zzielids",array_keys($liste)); + $smarty->assign("zziels",array_values($liste)); + + $liste = db_zuordnung($dbconn, "SELECT id, CONCAT(kto, ' (', name, ')') FROM buchungsKontos") ?: array(); + $smarty->assign("buchKtoids",array_keys($liste)); + $smarty->assign("buchKtos",array_values($liste)); + + $res = db_zeile($dbconn, "SELECT tmp_rechnung.id, adresse_id, vname, nname, str, hnr FROM tmp_rechnung JOIN adresse ON adresse_id = adresse.id JOIN strasse ON str_id = strasse.id WHERE tmp_rechnung.typ_id = ? AND user_id = ? ORDER BY datetime DESC LIMIT 1", array((string)$_GET["type"], $_SESSION["user"])); + if($res === false) + $err = error("Fehler beim Suchen nach nicht gespeicherten Daten
".mysqli_error($dbconn)); + if($res) { $smarty->assign("draft",$res["id"]); $smarty->assign("draftname",$res["vname"]." ".$res["nname"]); diff --git a/sites/umschlagshow.php b/sites/umschlagshow.php index be4c0bd..e92450b 100644 --- a/sites/umschlagshow.php +++ b/sites/umschlagshow.php @@ -6,21 +6,9 @@ $kdnres=makeadressarray($dbconn, $_GET["adressid"]); if($kdnres["partner_id"]) { $kdnres["adressid"] = $_GET["adressid"]; - $typnames=array(); - $qry=mysqli_query($dbconn, "SELECT id,anrede FROM anrede"); - while($res=mysqli_fetch_assoc($qry)) - { - $typnames[$res["id"]] = $res["anrede"]; - } - $smarty->assign("anrs",$typnames); - - $typnames=array(); - $qry=mysqli_query($dbconn, "SELECT id,titel FROM titel"); - while($res=mysqli_fetch_assoc($qry)) - { - $typnames[$res["id"]] = $res["titel"]; - } - $smarty->assign("titels",$typnames); + list($anrs, $titels) = anredenUndTitel($dbconn); + $smarty->assign("anrs",$anrs); + $smarty->assign("titels",$titels); $smarty->assign("adresse",$kdnres); $smarty->display("umschlagshow.tpl");