Vermeidung von SQL injection durch Verwendung parametrisierter Abfragen.
[kivitendo-erp.git] / SL / OE.pm
index 1967fc0..5b7c031 100644 (file)
--- a/SL/OE.pm
+++ b/SL/OE.pm
@@ -52,6 +52,15 @@ sub transactions {
   my ($null, $department_id) = split /--/, $form->{department};
 
   my $department = " AND o.department_id = $department_id" if $department_id;
+  my @values;
+
+  if ($form->{"project_id"}) {
+    $department .=
+      qq|AND ((globalproject_id = ?) OR EXISTS | .
+      qq|  (SELECT * FROM orderitems oi | .
+      qq|   WHERE oi.project_id = ? AND oi.trans_id = o.id))|;
+    push(@values, $form->{"project_id"}, $form->{"project_id"});
+  }
 
   my $rate = ($form->{vc} eq 'customer') ? 'buy' : 'sell';
 
@@ -65,6 +74,7 @@ sub transactions {
 
   my $query = qq|SELECT o.id, o.ordnumber, o.transdate, o.reqdate,
                  o.amount, ct.name, o.netamount, o.$form->{vc}_id,
+                 o.globalproject_id, pr.projectnumber AS globalprojectnumber,
                 ex.$rate AS exchangerate,
                 o.closed, o.delivered, o.quonumber, o.shippingpoint, o.shipvia,
                 e.name AS employee
@@ -73,6 +83,7 @@ sub transactions {
                 LEFT JOIN employee e ON (o.employee_id = e.id)
                 LEFT JOIN exchangerate ex ON (ex.curr = o.curr
                                               AND ex.transdate = o.transdate)
+                 LEFT JOIN project pr ON o.globalproject_id = pr.id
                 WHERE o.quotation = '$quotation'
                 $department|;
 
@@ -107,7 +118,10 @@ sub transactions {
   $query .= " ORDER by $sortorder";
 
   my $sth = $dbh->prepare($query);
-  $sth->execute || $form->dberror($query);
+  $sth->execute(@values) ||
+    $form->dberror($query . " (" . join(", ", @values) . ")");
+
+  dump_query(0, "laqje", $query, @values);
 
   my %id = ();
   while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
@@ -311,10 +325,6 @@ sub save {
 
       $netamount += $form->{"sellprice_$i"} * $form->{"qty_$i"};
 
-      $project_id = 'NULL';
-      if ($form->{"projectnumber_$i"}) {
-        $project_id = $form->{"projectnumber_$i"};
-      }
       $reqdate =
         ($form->{"reqdate_$i"}) ? qq|'$form->{"reqdate_$i"}'| : "NULL";
 
@@ -335,7 +345,7 @@ sub save {
       $query .= qq|$form->{id}, $form->{"id_$i"},
                   '$form->{"description_$i"}', '$form->{"longdescription_$i"}', $form->{"qty_$i"}, $baseqty,
                   $fxsellprice, $form->{"discount_$i"},
-                  '$form->{"unit_$i"}', $reqdate, (SELECT id from project where projectnumber = '$project_id'),
+                  '$form->{"unit_$i"}', $reqdate, | . conv_i($form->{"project_id_$i"}, 'NULL') . qq|,
                   '$form->{"serialnumber_$i"}', $form->{"ship_$i"}, '$pricegroup_id',
                   '$form->{"ordnumber_$i"}', '$form->{"transdate_$i"}', '$form->{"cusordnumber_$i"}', '$subtotal')|;
       $dbh->do($query) || $form->dberror($query);
@@ -671,13 +681,12 @@ sub retrieve {
                o.closed, o.reqdate, o.quonumber, o.department_id, o.cusordnumber,
                d.description AS department, o.payment_id, o.language_id, o.taxzone_id,
                 o.delivery_customer_id, o.delivery_vendor_id, o.proforma, o.shipto_id,
-                o.globalproject_id, pr.projectnumber AS globalprojectnumber,
+                o.globalproject_id,
                 o.delivered
                FROM oe o
                JOIN $form->{vc} cv ON (o.$form->{vc}_id = cv.id)
                LEFT JOIN employee e ON (o.employee_id = e.id)
                LEFT JOIN department d ON (o.department_id = d.id)
-          LEFT JOIN project pr ON (o.globalproject_id = pr.id)
                |
       . ($form->{id}
          ? qq|WHERE o.id = $form->{id}|
@@ -926,6 +935,10 @@ sub order_details {
   my %oid = ('Pg'     => 'oid',
              'Oracle' => 'rowid');
 
+  my (@project_ids, %projectnumbers);
+
+  push(@project_ids, $form->{"globalproject_id"}) if ($form->{"globalproject_id"});
+
   # sort items by partsgroup
   for $i (1 .. $form->{rowcount}) {
     $partsgroup = "";
@@ -933,8 +946,30 @@ sub order_details {
       $partsgroup = $form->{"partsgroup_$i"};
     }
     push @partsgroup, [$i, $partsgroup];
+    push(@project_ids, $form->{"project_id_$i"}) if ($form->{"project_id_$i"});
+  }
+
+  if (@project_ids) {
+    $query = "SELECT id, projectnumber FROM project WHERE id IN (" .
+      join(", ", map({ "?" } @project_ids)) . ")";
+    $sth = $dbh->prepare($query);
+    $sth->execute(@project_ids) ||
+      $form->dberror($query . " (" . join(", ", @project_ids) . ")");
+    while (my $ref = $sth->fetchrow_hashref()) {
+      $projectnumbers{$ref->{id}} = $ref->{projectnumber};
+    }
+    $sth->finish();
   }
 
+  $form->{"globalprojectnumber"} =
+    $projectnumbers{$form->{"globalproject_id"}};
+
+  my @arrays =
+    qw(runningnumber number description longdescription qty ship unit bin
+       partnotes serialnumber reqdate sellprice listprice netprice
+       discount p_discount discount_sub nodiscount_sub
+       linetotal  nodiscount_linetotal tax_rate projectnumber);
+
   my $sameitem = "";
   foreach $item (sort { $a->[1] cmp $b->[1] } @partsgroup) {
     $i = $item->[0];
@@ -943,10 +978,7 @@ sub order_details {
       push(@{ $form->{description} }, qq|$item->[1]|);
       $sameitem = $item->[1];
 
-      map { push(@{ $form->{$_} }, "") }
-        qw(runningnumber number qty ship unit bin partnotes
-           serialnumber reqdate sellprice listprice netprice
-           discount p_discount linetotal);
+      map({ push(@{ $form->{$_} }, "") } grep({ $_ ne "description" } @arrays));
     }
 
     $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
@@ -1027,7 +1059,7 @@ sub order_details {
       push(@{ $form->{p_discount} }, $form->{"discount_$i"});
 
       $form->{ordtotal} += $linetotal;
-     $discount_subtotal += $linetotal;
+      $discount_subtotal += $linetotal;
       $form->{nodiscount_total} += $nodiscount_linetotal;
       $nodiscount_subtotal += $nodiscount_linetotal;
       $form->{discount_total} += $form->parse_amount($myconfig, $discount);
@@ -1053,6 +1085,8 @@ sub order_details {
       push(@{ $form->{nodiscount_linetotal} },
            $form->format_amount($myconfig, $nodiscount_linetotal, 2));
 
+      push(@{ $form->{projectnumber} }, $projectnumbers{$form->{"project_id_$i"}});
+
       my ($taxamount, $taxbase);
       my $taxrate = 0;
 
@@ -1105,10 +1139,8 @@ sub order_details {
 
         while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
           if ($form->{groupitems} && $ref->{partsgroup} ne $sameitem) {
-            map { push(@{ $form->{$_} }, "") }
-              qw(runningnumber ship bin serialnumber number unit bin qty 
-                 reqdate sellprice listprice netprice discount p_discount
-                 linetotal nodiscount_linetotal);
+            map({ push(@{ $form->{$_} }, "") }
+                grep({ $_ ne "description" } @arrays));
             $sameitem = ($ref->{partsgroup}) ? $ref->{partsgroup} : "--";
             push(@{ $form->{description} }, $sameitem);
           }
@@ -1118,11 +1150,8 @@ sub order_details {
                  )
                  . qq|, $ref->{partnumber}, $ref->{description}|);
 
-          map { push(@{ $form->{$_} }, "") }
-            qw(number unit qty runningnumber ship bin serialnumber reqdate 
-               sellprice listprice netprice discount p_discount linetotal 
-               nodiscount_linetotal);
-
+          map({ push(@{ $form->{$_} }, "") }
+              grep({ $_ ne "description" } @arrays));
         }
         $sth->finish;
       }
@@ -1132,16 +1161,16 @@ sub order_details {
 
   my $tax = 0;
   foreach $item (sort keys %taxaccounts) {
-      push(@{ $form->{taxbase} },
-           $form->format_amount($myconfig, $taxbase{$item}, 2));
+    push(@{ $form->{taxbase} },
+         $form->format_amount($myconfig, $taxbase{$item}, 2));
 
-      $tax += $taxamount = $form->round_amount($taxaccounts{$item}, 2);
+    $tax += $taxamount = $form->round_amount($taxaccounts{$item}, 2);
 
-      push(@{ $form->{tax} }, $form->format_amount($myconfig, $taxamount, 2));
-      push(@{ $form->{taxdescription} }, $form->{"${item}_description"});
-      push(@{ $form->{taxrate} },
-           $form->format_amount($myconfig, $form->{"${item}_rate"} * 100));
-      push(@{ $form->{taxnumber} }, $form->{"${item}_taxnumber"});
+    push(@{ $form->{tax} }, $form->format_amount($myconfig, $taxamount, 2));
+    push(@{ $form->{taxdescription} }, $form->{"${item}_description"});
+    push(@{ $form->{taxrate} },
+         $form->format_amount($myconfig, $form->{"${item}_rate"} * 100));
+    push(@{ $form->{taxnumber} }, $form->{"${item}_taxnumber"});
   }
   $form->{subtotal} = $form->format_amount($myconfig, $form->{total}, 2);
   $yesdiscount = $form->{nodiscount_total} - $nodiscount;
@@ -1164,9 +1193,6 @@ sub order_details {
     $form->set_payment_options($myconfig, $form->{orddate});
   }
 
-  # myconfig variables
-  map { $form->{$_} = $myconfig->{$_} }
-    (qw(company address tel fax signature businessnumber));
   $form->{username} = $myconfig->{name};
 
   $dbh->disconnect;