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 <noreply@anthropic.com>
This commit is contained in:
+34
-19
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user