]> wagnertech.de Git - mfinanz.git/blobdiff - SL/DO.pm
PriceSource: Rabattbehandlung
[mfinanz.git] / SL / DO.pm
index a598f025d6642a87d8c3b25c7a6525912b701eac..478a12512ed12a917c91d8a9e3d8a1974a37becc 100644 (file)
--- a/SL/DO.pm
+++ b/SL/DO.pm
@@ -39,9 +39,13 @@ use YAML;
 use SL::AM;
 use SL::Common;
 use SL::CVar;
 use SL::AM;
 use SL::Common;
 use SL::CVar;
+use SL::DB::DeliveryOrder;
+use SL::DB::Status;
 use SL::DBUtils;
 use SL::DBUtils;
+use SL::HTML::Restrict;
 use SL::RecordLinks;
 use SL::IC;
 use SL::RecordLinks;
 use SL::IC;
+use SL::TransNumber;
 
 use strict;
 
 
 use strict;
 
@@ -61,7 +65,7 @@ sub transactions {
   my $vc = $form->{vc} eq "customer" ? "customer" : "vendor";
 
   my $query =
   my $vc = $form->{vc} eq "customer" ? "customer" : "vendor";
 
   my $query =
-    qq|SELECT dord.id, dord.donumber, dord.ordnumber,
+    qq|SELECT dord.id, dord.donumber, dord.ordnumber, dord.cusordnumber,
          dord.transdate, dord.reqdate,
          ct.${vc}number, ct.name, dord.${vc}_id, dord.globalproject_id,
          dord.closed, dord.delivered, dord.shippingpoint, dord.shipvia,
          dord.transdate, dord.reqdate,
          ct.${vc}number, ct.name, dord.${vc}_id, dord.globalproject_id,
          dord.closed, dord.delivered, dord.shippingpoint, dord.shipvia,
@@ -72,6 +76,7 @@ sub transactions {
          sm.name AS salesman
        FROM delivery_orders dord
        LEFT JOIN $vc ct ON (dord.${vc}_id = ct.id)
          sm.name AS salesman
        FROM delivery_orders dord
        LEFT JOIN $vc ct ON (dord.${vc}_id = ct.id)
+       LEFT JOIN contacts cp ON (dord.cp_id = cp.cp_id)
        LEFT JOIN employee e ON (dord.employee_id = e.id)
        LEFT JOIN employee sm ON (dord.salesman_id = sm.id)
        LEFT JOIN project pr ON (dord.globalproject_id = pr.id)
        LEFT JOIN employee e ON (dord.employee_id = e.id)
        LEFT JOIN employee sm ON (dord.salesman_id = sm.id)
        LEFT JOIN project pr ON (dord.globalproject_id = pr.id)
@@ -102,6 +107,11 @@ sub transactions {
     push @values, '%' . $form->{$vc} . '%';
   }
 
     push @values, '%' . $form->{$vc} . '%';
   }
 
+  if ($form->{"cp_name"}) {
+    push @where, "(cp.cp_name ILIKE ? OR cp.cp_givenname ILIKE ?)";
+    push @values, ('%' . $form->{"cp_name"} . '%')x2;
+  }
+
   foreach my $item (qw(employee_id salesman_id)) {
     next unless ($form->{$item});
     push @where, "dord.$item = ?";
   foreach my $item (qw(employee_id salesman_id)) {
     next unless ($form->{$item});
     push @where, "dord.$item = ?";
@@ -128,6 +138,11 @@ sub transactions {
     push @where, ($form->{delivered} ? "" : "NOT ") . "COALESCE(dord.delivered, FALSE)";
   }
 
     push @where, ($form->{delivered} ? "" : "NOT ") . "COALESCE(dord.delivered, FALSE)";
   }
 
+  if ($form->{serialnumber}) {
+    push @where, 'dord.id IN (SELECT doi.delivery_order_id FROM delivery_order_items doi WHERE doi.serialnumber LIKE ?)';
+    push @values, '%' . $form->{serialnumber} . '%';
+  }
+
   if($form->{transdatefrom}) {
     push @where,  qq|dord.transdate >= ?|;
     push @values, conv_date($form->{transdatefrom});
   if($form->{transdatefrom}) {
     push @where,  qq|dord.transdate >= ?|;
     push @values, conv_date($form->{transdatefrom});
@@ -138,6 +153,16 @@ sub transactions {
     push @values, conv_date($form->{transdateto});
   }
 
     push @values, conv_date($form->{transdateto});
   }
 
+  if($form->{reqdatefrom}) {
+    push @where,  qq|dord.reqdate >= ?|;
+    push @values, conv_date($form->{reqdatefrom});
+  }
+
+  if($form->{reqdateto}) {
+    push @where,  qq|dord.reqdate <= ?|;
+    push @values, conv_date($form->{reqdateto});
+  }
+
   if (@where) {
     $query .= " WHERE " . join(" AND ", map { "($_)" } @where);
   }
   if (@where) {
     $query .= " WHERE " . join(" AND ", map { "($_)" } @where);
   }
@@ -198,6 +223,7 @@ sub save {
 
   # connect to database, turn off autocommit
   my $dbh = $form->get_standard_dbh($myconfig);
 
   # connect to database, turn off autocommit
   my $dbh = $form->get_standard_dbh($myconfig);
+  my $restricter = SL::HTML::Restrict->create;
 
   my ($query, @values, $sth, $null);
 
 
   my ($query, @values, $sth, $null);
 
@@ -207,7 +233,8 @@ sub save {
   my $ic_cvar_configs = CVar->get_configs(module => 'IC',
                                           dbh    => $dbh);
 
   my $ic_cvar_configs = CVar->get_configs(module => 'IC',
                                           dbh    => $dbh);
 
-  $form->{donumber}    = $form->update_defaults($myconfig, $form->{type} eq 'sales_delivery_order' ? 'sdonumber' : 'pdonumber', $dbh) unless $form->{donumber};
+  my $trans_number     = SL::TransNumber->new(type => $form->{type}, dbh => $dbh, number => $form->{donumber}, id => $form->{id});
+  $form->{donumber}  ||= $trans_number->create_unique;
   $form->{employee_id} = (split /--/, $form->{employee})[1] if !$form->{employee_id};
   $form->get_employee($dbh) unless ($form->{employee_id});
 
   $form->{employee_id} = (split /--/, $form->{employee})[1] if !$form->{employee_id};
   $form->get_employee($dbh) unless ($form->{employee_id});
 
@@ -229,8 +256,8 @@ sub save {
     $query = qq|SELECT nextval('id')|;
     ($form->{id}) = selectrow_query($form, $dbh, $query);
 
     $query = qq|SELECT nextval('id')|;
     ($form->{id}) = selectrow_query($form, $dbh, $query);
 
-    $query = qq|INSERT INTO delivery_orders (id, donumber, employee_id) VALUES (?, '', ?)|;
-    do_query($form, $dbh, $query, $form->{id}, conv_i($form->{employee_id}));
+    $query = qq|INSERT INTO delivery_orders (id, donumber, employee_id, currency_id, taxzone_id) VALUES (?, '', ?, (SELECT currency_id FROM defaults LIMIT 1), ?)|;
+    do_query($form, $dbh, $query, $form->{id}, conv_i($form->{employee_id}), $form->{taxzone_id});
   }
 
   my $project_id;
   }
 
   my $project_id;
@@ -257,9 +284,10 @@ sub save {
          id, delivery_order_id, parts_id, description, longdescription, qty, base_qty,
          sellprice, discount, unit, reqdate, project_id, serialnumber,
          ordnumber, transdate, cusordnumber,
          id, delivery_order_id, parts_id, description, longdescription, qty, base_qty,
          sellprice, discount, unit, reqdate, project_id, serialnumber,
          ordnumber, transdate, cusordnumber,
-         lastcost, price_factor_id, price_factor, marge_price_factor, pricegroup_id)
+         lastcost, price_factor_id, price_factor, marge_price_factor, pricegroup_id,
+         active_price_source, active_discount_source)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
-         (SELECT factor FROM price_factors WHERE id = ?), ?, ?)|;
+         (SELECT factor FROM price_factors WHERE id = ?), ?, ?, ?, ?)|;
   my $h_item = prepare_query($form, $dbh, $q_item);
 
   my $q_item_stock =
   my $h_item = prepare_query($form, $dbh, $q_item);
 
   my $q_item_stock =
@@ -304,7 +332,7 @@ sub save {
 
     # save detail record in delivery_order_items table
     @values = (conv_i($item_id), conv_i($form->{id}), conv_i($form->{"id_$i"}),
 
     # save detail record in delivery_order_items table
     @values = (conv_i($item_id), conv_i($form->{id}), conv_i($form->{"id_$i"}),
-               $form->{"description_$i"}, $form->{"longdescription_$i"},
+               $form->{"description_$i"}, $restricter->process($form->{"longdescription_$i"}),
                $form->{"qty_$i"}, $baseqty,
                $form->{"sellprice_$i"}, $form->{"discount_$i"} / 100,
                $form->{"unit_$i"}, conv_date($items_reqdate), conv_i($form->{"project_id_$i"}),
                $form->{"qty_$i"}, $baseqty,
                $form->{"sellprice_$i"}, $form->{"discount_$i"} / 100,
                $form->{"unit_$i"}, conv_date($items_reqdate), conv_i($form->{"project_id_$i"}),
@@ -314,7 +342,8 @@ sub save {
                $form->{"lastcost_$i"},
                conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"price_factor_id_$i"}),
                conv_i($form->{"marge_price_factor_$i"}),
                $form->{"lastcost_$i"},
                conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"price_factor_id_$i"}),
                conv_i($form->{"marge_price_factor_$i"}),
-               $pricegroup_id);
+               $pricegroup_id,
+               $form->{"active_price_source_$i"}, $form->{"active_discount_source_$i"});
     do_statement($form, $h_item, $q_item, @values);
 
     my $stock_info = DO->unpack_stock_information('packed' => $form->{"stock_${in_out}_$i"});
     do_statement($form, $h_item, $q_item, @values);
 
     my $stock_info = DO->unpack_stock_information('packed' => $form->{"stock_${in_out}_$i"});
@@ -350,7 +379,8 @@ sub save {
          shippingpoint = ?, shipvia = ?, notes = ?, intnotes = ?, closed = ?,
          delivered = ?, department_id = ?, language_id = ?, shipto_id = ?,
          globalproject_id = ?, employee_id = ?, salesman_id = ?, cp_id = ?, transaction_description = ?,
          shippingpoint = ?, shipvia = ?, notes = ?, intnotes = ?, closed = ?,
          delivered = ?, department_id = ?, language_id = ?, shipto_id = ?,
          globalproject_id = ?, employee_id = ?, salesman_id = ?, cp_id = ?, transaction_description = ?,
-         is_sales = ?, taxzone_id = ?, taxincluded = ?, terms = ?, curr = ?
+         is_sales = ?, taxzone_id = ?, taxincluded = ?, terms = ?, currency_id = (SELECT id FROM currencies WHERE name = ?),
+         delivery_term_id = ?
        WHERE id = ?|;
 
   @values = ($form->{donumber}, $form->{ordnumber},
        WHERE id = ?|;
 
   @values = ($form->{donumber}, $form->{ordnumber},
@@ -364,14 +394,15 @@ sub save {
              conv_i($form->{salesman_id}), conv_i($form->{cp_id}),
              $form->{transaction_description},
              $form->{type} =~ /^sales/ ? 't' : 'f',
              conv_i($form->{salesman_id}), conv_i($form->{cp_id}),
              $form->{transaction_description},
              $form->{type} =~ /^sales/ ? 't' : 'f',
-             conv_i($form->{taxzone_id}), $form->{taxincluded} ? 't' : 'f', conv_i($form->{terms}), substr($form->{currency}, 0, 3),
+             conv_i($form->{taxzone_id}), $form->{taxincluded} ? 't' : 'f', conv_i($form->{terms}), $form->{currency},
+             conv_i($form->{delivery_term_id}),
              conv_i($form->{id}));
   do_query($form, $dbh, $query, @values);
 
              conv_i($form->{id}));
   do_query($form, $dbh, $query, @values);
 
-  # add shipto
   $form->{name} = $form->{ $form->{vc} };
   $form->{name} =~ s/--$form->{"$form->{vc}_id"}//;
 
   $form->{name} = $form->{ $form->{vc} };
   $form->{name} =~ s/--$form->{"$form->{vc}_id"}//;
 
+  # add shipto
   if (!$form->{shipto_id}) {
     $form->add_shipto($dbh, $form->{id}, "DO");
   }
   if (!$form->{shipto_id}) {
     $form->add_shipto($dbh, $form->{id}, "DO");
   }
@@ -396,6 +427,8 @@ sub save {
   my $rc = $dbh->commit();
 
   $form->{saved_donumber} = $form->{donumber};
   my $rc = $dbh->commit();
 
   $form->{saved_donumber} = $form->{donumber};
+  $form->{saved_ordnumber} = $form->{ordnumber};
+  $form->{saved_cusordnumber} = $form->{cusordnumber};
 
   Common::webdav_folder($form);
 
 
   Common::webdav_folder($form);
 
@@ -507,59 +540,16 @@ sub delete {
   my $form     = $main::form;
   my $spool    = $::lx_office_conf{paths}->{spool};
 
   my $form     = $main::form;
   my $spool    = $::lx_office_conf{paths}->{spool};
 
-  # connect to database
-  my $dbh = $form->get_standard_dbh($myconfig);
-
-  # delete spool files
-  my $query = qq|SELECT s.spoolfile FROM status s WHERE s.trans_id = ?|;
-  my $sth   = prepare_execute_query($form, $dbh, $query, conv_i($form->{id}));
-
-  my $spoolfile;
-  my @spoolfiles = ();
-  my @values;
-
-  while (($spoolfile) = $sth->fetchrow_array) {
-    push @spoolfiles, $spoolfile;
-  }
-  $sth->finish();
-
-  # delete-values
-  @values = (conv_i($form->{id}));
-
-  # delete status entries
-  $query = qq|DELETE FROM status
-              WHERE trans_id = ?|;
-  do_query($form, $dbh, $query, @values);
+  my $rc = SL::DB::Order->new->db->with_transaction(sub {
+    my @spoolfiles = grep { $_ } map { $_->spoolfile } @{ SL::DB::Manager::Status->get_all(where => [ trans_id => $form->{id} ]) };
 
 
-  # delete individual entries
-  $query = qq|DELETE FROM delivery_order_items_stock
-              WHERE delivery_order_item_id IN (
-                SELECT id FROM delivery_order_items
-                WHERE delivery_order_id = ?
-              )|;
-  do_query($form, $dbh, $query, @values);
+    SL::DB::DeliveryOrder->new(id => $form->{id})->delete;
 
 
-  # delete individual entries
-  $query = qq|DELETE FROM delivery_order_items
-              WHERE delivery_order_id = ?|;
-  do_query($form, $dbh, $query, @values);
+    my $spool = $::lx_office_conf{paths}->{spool};
+    unlink map { "$spool/$_" } @spoolfiles if $spool;
 
 
-  # delete DO record
-  $query = qq|DELETE FROM delivery_orders
-              WHERE id = ?|;
-  do_query($form, $dbh, $query, @values);
-
-  $query = qq|DELETE FROM shipto
-              WHERE trans_id = ? AND module = 'DO'|;
-  do_query($form, $dbh, $query, @values);
-
-  my $rc = $dbh->commit();
-
-  if ($rc) {
-    foreach $spoolfile (@spoolfiles) {
-      unlink "$spool/$spoolfile" if $spoolfile;
-    }
-  }
+    1;
+  });
 
   $main::lxdebug->leave_sub();
 
 
   $main::lxdebug->leave_sub();
 
@@ -618,7 +608,8 @@ sub retrieve {
          d.description AS department, dord.language_id,
          dord.shipto_id,
          dord.globalproject_id, dord.delivered, dord.transaction_description,
          d.description AS department, dord.language_id,
          dord.shipto_id,
          dord.globalproject_id, dord.delivered, dord.transaction_description,
-         dord.taxzone_id, dord.taxincluded, dord.terms, dord.curr AS currency
+         dord.taxzone_id, dord.taxincluded, dord.terms, (SELECT cu.name FROM currencies cu WHERE cu.id=dord.currency_id) AS currency,
+         dord.delivery_term_id
        FROM delivery_orders dord
        JOIN ${vc} cv ON (dord.${vc}_id = cv.id)
        LEFT JOIN employee e ON (dord.employee_id = e.id)
        FROM delivery_orders dord
        JOIN ${vc} cv ON (dord.${vc}_id = cv.id)
        LEFT JOIN employee e ON (dord.employee_id = e.id)
@@ -627,6 +618,9 @@ sub retrieve {
   $sth = prepare_execute_query($form, $dbh, $query, @do_ids);
 
   delete $form->{"${vc}_id"};
   $sth = prepare_execute_query($form, $dbh, $query, @do_ids);
 
   delete $form->{"${vc}_id"};
+  my $pos = 0;
+  $form->{ordnumber_array} = ' ';
+  $form->{cusordnumber_array} = ' ';
   while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
     if ($form->{"${vc}_id"} && ($ref->{"${vc}_id"} != $form->{"${vc}_id"})) {
       $sth->finish();
   while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
     if ($form->{"${vc}_id"} && ($ref->{"${vc}_id"} != $form->{"${vc}_id"})) {
       $sth->finish();
@@ -637,15 +631,26 @@ sub retrieve {
 
     map { $form->{$_} = $ref->{$_} } keys %$ref if ($ref);
     $form->{donumber_array} .= $form->{donumber} . ' ';
 
     map { $form->{$_} = $ref->{$_} } keys %$ref if ($ref);
     $form->{donumber_array} .= $form->{donumber} . ' ';
+    $pos = index($form->{ordnumber_array},' ' . $form->{ordnumber} . ' ');
+    if ($pos == -1) {
+      $form->{ordnumber_array} .= $form->{ordnumber} . ' ';
+    }
+    $pos = index($form->{cusordnumber_array},' ' . $form->{cusordnumber} . ' ');
+    if ($pos == -1) {
+      $form->{cusordnumber_array} .= $form->{cusordnumber} . ' ';
+    }
   }
   $sth->finish();
 
   }
   $sth->finish();
 
-  # remove any trailing whitespace
-  $form->{currency} =~ s/\s*$//;
-
   $form->{donumber_array} =~ s/\s*$//g;
   $form->{donumber_array} =~ s/\s*$//g;
+  $form->{ordnumber_array} =~ s/ //;
+  $form->{ordnumber_array} =~ s/\s*$//g;
+  $form->{cusordnumber_array} =~ s/ //;
+  $form->{cusordnumber_array} =~ s/\s*$//g;
 
   $form->{saved_donumber} = $form->{donumber};
 
   $form->{saved_donumber} = $form->{donumber};
+  $form->{saved_ordnumber} = $form->{ordnumber};
+  $form->{saved_cusordnumber} = $form->{cusordnumber};
 
   # if not given, fill transdate with current_date
   $form->{transdate} = $form->current_date($myconfig) unless $form->{transdate};
 
   # if not given, fill transdate with current_date
   $form->{transdate} = $form->current_date($myconfig) unless $form->{transdate};
@@ -675,9 +680,6 @@ sub retrieve {
     delete $form->{id};
   }
 
     delete $form->{id};
   }
 
-  my %oid = ('Pg'     => 'oid',
-             'Oracle' => 'rowid');
-
   # retrieve individual items
   # this query looks up all information about the items
   # stuff different from the whole will not be overwritten, but saved with a suffix.
   # retrieve individual items
   # this query looks up all information about the items
   # stuff different from the whole will not be overwritten, but saved with a suffix.
@@ -688,7 +690,8 @@ sub retrieve {
          doi.reqdate, doi.project_id, doi.serialnumber, doi.lastcost,
          doi.ordnumber, doi.transdate, doi.cusordnumber, doi.longdescription,
          doi.price_factor_id, doi.price_factor, doi.marge_price_factor, doi.pricegroup_id,
          doi.reqdate, doi.project_id, doi.serialnumber, doi.lastcost,
          doi.ordnumber, doi.transdate, doi.cusordnumber, doi.longdescription,
          doi.price_factor_id, doi.price_factor, doi.marge_price_factor, doi.pricegroup_id,
-         pr.projectnumber, dord.transdate AS dord_transdate,
+         doi.active_price_source, doi.active_discount_source,
+         pr.projectnumber, dord.transdate AS dord_transdate, dord.donumber,
          pg.partsgroup
        FROM delivery_order_items doi
        JOIN parts p ON (doi.parts_id = p.id)
          pg.partsgroup
        FROM delivery_order_items doi
        JOIN parts p ON (doi.parts_id = p.id)
@@ -696,7 +699,7 @@ sub retrieve {
        LEFT JOIN project pr ON (doi.project_id = pr.id)
        LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
        WHERE doi.delivery_order_id IN ($do_ids_placeholders)
        LEFT JOIN project pr ON (doi.project_id = pr.id)
        LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
        WHERE doi.delivery_order_id IN ($do_ids_placeholders)
-       ORDER BY doi.$oid{$myconfig->{dbdriver}}|;
+       ORDER BY doi.oid|;
 
   $form->{form_details} = selectall_hashref_query($form, $dbh, $query, @do_ids);
 
 
   $form->{form_details} = selectall_hashref_query($form, $dbh, $query, @do_ids);
 
@@ -754,11 +757,11 @@ sub order_details {
   my @partsgroup = ();
   my $partsgroup;
   my $position = 0;
   my @partsgroup = ();
   my $partsgroup;
   my $position = 0;
+  my $subtotal_header = 0;
+  my $subposition = 0;
+  my $si_position = 0;
 
 
-  my %oid = ('Pg'     => 'oid',
-             'Oracle' => 'rowid');
-
-  my (@project_ids, %projectnumbers, %projectdescriptions);
+  my (@project_ids);
 
   push(@project_ids, $form->{"globalproject_id"}) if ($form->{"globalproject_id"});
 
 
   push(@project_ids, $form->{"globalproject_id"}) if ($form->{"globalproject_id"});
 
@@ -772,21 +775,21 @@ sub order_details {
     push(@project_ids, $form->{"project_id_$i"}) if ($form->{"project_id_$i"});
   }
 
     push(@project_ids, $form->{"project_id_$i"}) if ($form->{"project_id_$i"});
   }
 
+  my $projects = [];
+  my %projects_by_id;
   if (@project_ids) {
   if (@project_ids) {
-    $query = "SELECT id, projectnumber, description FROM project WHERE id IN (" .
-      join(", ", map("?", @project_ids)) . ")";
-    $sth = prepare_execute_query($form, $dbh, $query, @project_ids);
-    while (my $ref = $sth->fetchrow_hashref()) {
-      $projectnumbers{$ref->{id}} = $ref->{projectnumber};
-      $projectdescriptions{$ref->{id}} = $ref->{description};
-    }
-    $sth->finish();
+    $projects = SL::DB::Manager::Project->get_all(query => [ id => \@project_ids ]);
+    %projects_by_id = map { $_->id => $_ } @$projects;
   }
 
   }
 
-  $form->{"globalprojectnumber"} =
-    $projectnumbers{$form->{"globalproject_id"}};
-  $form->{"globalprojectdescription"} =
-      $projectdescriptions{$form->{"globalproject_id"}};
+  if ($projects_by_id{$form->{"globalproject_id"}}) {
+    $form->{globalprojectnumber} = $projects_by_id{$form->{"globalproject_id"}}->projectnumber;
+    $form->{globalprojectdescription} = $projects_by_id{$form->{"globalproject_id"}}->description;
+
+    for (@{ $projects_by_id{$form->{"globalproject_id"}}->cvars_by_config }) {
+      $form->{"project_cvar_" . $_->config->name} = $_->value_as_text;
+    }
+  }
 
   my $q_pg     = qq|SELECT p.partnumber, p.description, p.unit, a.qty, pg.partsgroup
                     FROM assembly a
 
   my $q_pg     = qq|SELECT p.partnumber, p.description, p.unit, a.qty, pg.partsgroup
                     FROM assembly a
@@ -805,6 +808,7 @@ sub order_details {
   my $num_si   = 0;
 
   my $ic_cvar_configs = CVar->get_configs(module => 'IC');
   my $num_si   = 0;
 
   my $ic_cvar_configs = CVar->get_configs(module => 'IC');
+  my $project_cvar_configs = CVar->get_configs(module => 'Projects');
 
   $form->{TEMPLATE_ARRAYS} = { };
   IC->prepare_parts_for_printing(myconfig => $myconfig, form => $form);
 
   $form->{TEMPLATE_ARRAYS} = { };
   IC->prepare_parts_for_printing(myconfig => $myconfig, form => $form);
@@ -812,24 +816,26 @@ sub order_details {
   my @arrays =
     qw(runningnumber number description longdescription qty unit
        partnotes serialnumber reqdate projectnumber projectdescription
   my @arrays =
     qw(runningnumber number description longdescription qty unit
        partnotes serialnumber reqdate projectnumber projectdescription
+       weight lineweight
        si_runningnumber si_number si_description
        si_runningnumber si_number si_description
-       si_warehouse si_bin si_chargenumber si_bestbefore si_qty si_unit);
+       si_warehouse si_bin si_chargenumber si_bestbefore
+       si_qty si_qty_nofmt si_unit);
 
   map { $form->{TEMPLATE_ARRAYS}->{$_} = [] } (@arrays);
 
   push @arrays, map { "ic_cvar_$_->{name}" } @{ $ic_cvar_configs };
 
   map { $form->{TEMPLATE_ARRAYS}->{$_} = [] } (@arrays);
 
   push @arrays, map { "ic_cvar_$_->{name}" } @{ $ic_cvar_configs };
+  push @arrays, map { "project_cvar_$_->{name}" } @{ $project_cvar_configs };
 
   $form->get_lists('price_factors' => 'ALL_PRICE_FACTORS');
   my %price_factors = map { $_->{id} => $_->{factor} } @{ $form->{ALL_PRICE_FACTORS} };
 
 
   $form->get_lists('price_factors' => 'ALL_PRICE_FACTORS');
   my %price_factors = map { $_->{id} => $_->{factor} } @{ $form->{ALL_PRICE_FACTORS} };
 
+  my $totalweight = 0;
   my $sameitem = "";
   foreach $item (sort { $a->[1] cmp $b->[1] } @partsgroup) {
     $i = $item->[0];
 
     next if (!$form->{"id_$i"});
 
   my $sameitem = "";
   foreach $item (sort { $a->[1] cmp $b->[1] } @partsgroup) {
     $i = $item->[0];
 
     next if (!$form->{"id_$i"});
 
-    $position++;
-
     if ($item->[1] ne $sameitem) {
       push(@{ $form->{description} }, qq|$item->[1]|);
       $sameitem = $item->[1];
     if ($item->[1] ne $sameitem) {
       push(@{ $form->{description} }, qq|$item->[1]|);
       $sameitem = $item->[1];
@@ -840,8 +846,24 @@ sub order_details {
     $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
 
     # add number, description and qty to $form->{number}, ....
     $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
 
     # add number, description and qty to $form->{number}, ....
+    if ($form->{"subtotal_$i"} && !$subtotal_header) {
+      $subtotal_header = $i;
+      $position = int($position);
+      $subposition = 0;
+      $position++;
+    } elsif ($subtotal_header) {
+      $subposition += 1;
+      $position = int($position);
+      $position = $position.".".$subposition;
+    } else {
+      $position = int($position);
+      $position++;
+    }
+
+    $si_position++;
 
     my $price_factor = $price_factors{$form->{"price_factor_id_$i"}} || { 'factor' => 1 };
 
     my $price_factor = $price_factors{$form->{"price_factor_id_$i"}} || { 'factor' => 1 };
+    my $project = $projects_by_id{$form->{"project_id_$i"}} || SL::DB::Project->new;
 
     push @{ $form->{TEMPLATE_ARRAYS}{runningnumber} },   $position;
     push @{ $form->{TEMPLATE_ARRAYS}{number} },          $form->{"partnumber_$i"};
 
     push @{ $form->{TEMPLATE_ARRAYS}{runningnumber} },   $position;
     push @{ $form->{TEMPLATE_ARRAYS}{number} },          $form->{"partnumber_$i"};
@@ -853,9 +875,39 @@ sub order_details {
     push @{ $form->{TEMPLATE_ARRAYS}{partnotes} },       $form->{"partnotes_$i"};
     push @{ $form->{TEMPLATE_ARRAYS}{serialnumber} },    $form->{"serialnumber_$i"};
     push @{ $form->{TEMPLATE_ARRAYS}{reqdate} },         $form->{"reqdate_$i"};
     push @{ $form->{TEMPLATE_ARRAYS}{partnotes} },       $form->{"partnotes_$i"};
     push @{ $form->{TEMPLATE_ARRAYS}{serialnumber} },    $form->{"serialnumber_$i"};
     push @{ $form->{TEMPLATE_ARRAYS}{reqdate} },         $form->{"reqdate_$i"};
-    push @{ $form->{TEMPLATE_ARRAYS}{projectnumber} },   $projectnumbers{$form->{"project_id_$i"}};
-    push @{ $form->{TEMPLATE_ARRAYS}{projectdescription} },
-      $projectdescriptions{$form->{"project_id_$i"}};
+    push @{ $form->{TEMPLATE_ARRAYS}{projectnumber} },   $project->projectnumber;
+    push @{ $form->{TEMPLATE_ARRAYS}{projectdescription} }, $project->description;
+
+    if ($form->{"subtotal_$i"} && $subtotal_header && ($subtotal_header != $i)) {
+      $subtotal_header     = 0;
+    }
+
+    my $lineweight = $form->{"qty_$i"} * $form->{"weight_$i"};
+    $totalweight += $lineweight;
+    push @{ $form->{TEMPLATE_ARRAYS}->{weight} },            $form->format_amount($myconfig, $form->{"weight_$i"}, 3);
+    push @{ $form->{TEMPLATE_ARRAYS}->{weight_nofmt} },      $form->{"weight_$i"};
+    push @{ $form->{TEMPLATE_ARRAYS}->{lineweight} },        $form->format_amount($myconfig, $lineweight, 3);
+    push @{ $form->{TEMPLATE_ARRAYS}->{lineweight_nofmt} },  $lineweight;
+
+    my $stock_info = DO->unpack_stock_information('packed' => $form->{"stock_${in_out}_$i"});
+
+    foreach my $si (@{ $stock_info }) {
+      $num_si++;
+
+      do_statement($form, $h_bin_wh, $q_bin_wh, conv_i($si->{bin_id}), conv_i($si->{warehouse_id}));
+      my $bin_wh = $h_bin_wh->fetchrow_hashref();
+
+      push @{ $form->{TEMPLATE_ARRAYS}{si_runningnumber}[$si_position-1] }, $num_si;
+      push @{ $form->{TEMPLATE_ARRAYS}{si_number}[$si_position-1] },        $form->{"partnumber_$i"};
+      push @{ $form->{TEMPLATE_ARRAYS}{si_description}[$si_position-1] },   $form->{"description_$i"};
+      push @{ $form->{TEMPLATE_ARRAYS}{si_warehouse}[$si_position-1] },     $bin_wh->{warehouse};
+      push @{ $form->{TEMPLATE_ARRAYS}{si_bin}[$si_position-1] },           $bin_wh->{bin};
+      push @{ $form->{TEMPLATE_ARRAYS}{si_chargenumber}[$si_position-1] },  $si->{chargenumber};
+      push @{ $form->{TEMPLATE_ARRAYS}{si_bestbefore}[$si_position-1] },    $si->{bestbefore};
+      push @{ $form->{TEMPLATE_ARRAYS}{si_qty}[$si_position-1] },           $form->format_amount($myconfig, $si->{qty} * 1);
+      push @{ $form->{TEMPLATE_ARRAYS}{si_qty_nofmt}[$si_position-1] },     $si->{qty} * 1;
+      push @{ $form->{TEMPLATE_ARRAYS}{si_unit}[$si_position-1] },          $si->{unit};
+    }
 
     if ($form->{"assembly_$i"}) {
       $sameitem = "";
 
     if ($form->{"assembly_$i"}) {
       $sameitem = "";
@@ -864,55 +916,47 @@ sub order_details {
       my $sortorder = "";
       if ($form->{groupitems}) {
         $sortorder =
       my $sortorder = "";
       if ($form->{groupitems}) {
         $sortorder =
-          qq|ORDER BY pg.partsgroup, a.$oid{$myconfig->{dbdriver}}|;
+          qq|ORDER BY pg.partsgroup, a.oid|;
       } else {
       } else {
-        $sortorder = qq|ORDER BY a.$oid{$myconfig->{dbdriver}}|;
+        $sortorder = qq|ORDER BY a.oid|;
       }
 
       do_statement($form, $h_pg, $q_pg, conv_i($form->{"id_$i"}));
 
       while (my $ref = $h_pg->fetchrow_hashref("NAME_lc")) {
         if ($form->{groupitems} && $ref->{partsgroup} ne $sameitem) {
       }
 
       do_statement($form, $h_pg, $q_pg, conv_i($form->{"id_$i"}));
 
       while (my $ref = $h_pg->fetchrow_hashref("NAME_lc")) {
         if ($form->{groupitems} && $ref->{partsgroup} ne $sameitem) {
-          map({ push(@{ $form->{TEMPLATE_ARRAYS}->{$_} }, "") } grep({ $_ ne "description" } @arrays));
+          map({ push(@{ $form->{TEMPLATE_ARRAYS}->{$_} }, "") } grep({ $_ ne "description" && $_ !~ /^si_/} @arrays));
+          map({ push(@{ $form->{TEMPLATE_ARRAYS}->{$_} }, []) } grep({ $_ =~ /^si_/} @arrays));
           $sameitem = ($ref->{partsgroup}) ? $ref->{partsgroup} : "--";
           push(@{ $form->{TEMPLATE_ARRAYS}->{description} }, $sameitem);
           $sameitem = ($ref->{partsgroup}) ? $ref->{partsgroup} : "--";
           push(@{ $form->{TEMPLATE_ARRAYS}->{description} }, $sameitem);
+          $si_position++;
         }
         }
-        push(@{ $form->{TEMPLATE_ARRAYS}->{"description"} }, $form->format_amount($myconfig, $ref->{qty} * $form->{"qty_$i"}) . qq| -- $ref->{partnumber}, $ref->{description}|);
 
 
-        map({ push(@{ $form->{TEMPLATE_ARRAYS}->{$_} }, "") } grep({ $_ ne "description" } @arrays));
-      }
-    }
-
-    if ($form->{"inventory_accno_$i"} && !$form->{"assembly_$i"}) {
-      my $stock_info = DO->unpack_stock_information('packed' => $form->{"stock_${in_out}_$i"});
-
-      foreach my $si (@{ $stock_info }) {
-        $num_si++;
-
-        do_statement($form, $h_bin_wh, $q_bin_wh, conv_i($si->{bin_id}), conv_i($si->{warehouse_id}));
-        my $bin_wh = $h_bin_wh->fetchrow_hashref();
-
-        push @{ $form->{TEMPLATE_ARRAYS}{si_runningnumber}[$position-1] }, $num_si;
-        push @{ $form->{TEMPLATE_ARRAYS}{si_number}[$position-1] },        $form->{"partnumber_$i"};
-        push @{ $form->{TEMPLATE_ARRAYS}{si_description}[$position-1] },   $form->{"description_$i"};
-        push @{ $form->{TEMPLATE_ARRAYS}{si_warehouse}[$position-1] },     $bin_wh->{warehouse};
-        push @{ $form->{TEMPLATE_ARRAYS}{si_bin}[$position-1] },           $bin_wh->{bin};
-        push @{ $form->{TEMPLATE_ARRAYS}{si_chargenumber}[$position-1] },  $si->{chargenumber};
-        push @{ $form->{TEMPLATE_ARRAYS}{si_bestbefore}[$position-1] },    $si->{bestbefore};
-        push @{ $form->{TEMPLATE_ARRAYS}{si_qty}[$position-1] },           $form->format_amount($myconfig, $si->{qty} * 1);
-        push @{ $form->{TEMPLATE_ARRAYS}{si_qty_nofmt}[$position-1] },     $si->{qty} * 1;
-        push @{ $form->{TEMPLATE_ARRAYS}{si_unit}[$position-1] },          $si->{unit};
+        push(@{ $form->{TEMPLATE_ARRAYS}->{"description"} }, $form->format_amount($myconfig, $ref->{qty} * $form->{"qty_$i"}) . qq| -- $ref->{partnumber}, $ref->{description}|);
+        map({ push(@{ $form->{TEMPLATE_ARRAYS}->{$_} }, "") } grep({ $_ ne "description" && $_ !~ /^si_/} @arrays));
+        map({ push(@{ $form->{TEMPLATE_ARRAYS}->{$_} }, []) } grep({ $_ =~ /^si_/} @arrays));
+        $si_position++;
       }
     }
 
     push @{ $form->{TEMPLATE_ARRAYS}->{"ic_cvar_$_->{name}"} },
       CVar->format_to_template(CVar->parse($form->{"ic_cvar_$_->{name}_$i"}, $_), $_)
         for @{ $ic_cvar_configs };
       }
     }
 
     push @{ $form->{TEMPLATE_ARRAYS}->{"ic_cvar_$_->{name}"} },
       CVar->format_to_template(CVar->parse($form->{"ic_cvar_$_->{name}_$i"}, $_), $_)
         for @{ $ic_cvar_configs };
+
+    push @{ $form->{TEMPLATE_ARRAYS}->{"project_cvar_" . $_->config->name} }, $_->value_as_text for @{ $project->cvars_by_config };
   }
 
   }
 
+  $form->{totalweight}       = $form->format_amount($myconfig, $totalweight, 3);
+  $form->{totalweight_nofmt} = $totalweight;
+  my $defaults = AM->get_defaults();
+  $form->{weightunit}        = $defaults->{weightunit};
+
   $h_pg->finish();
   $h_bin_wh->finish();
 
   $h_pg->finish();
   $h_bin_wh->finish();
 
+  $form->{delivery_term} = SL::DB::Manager::DeliveryTerm->find_by(id => $form->{delivery_term_id} || undef);
+  $form->{delivery_term}->description_long($form->{delivery_term}->translated_attribute('description_long', $form->{language_id})) if $form->{delivery_term} && $form->{language_id};
+
   $form->{username} = $myconfig->{name};
 
   $main::lxdebug->leave_sub();
   $form->{username} = $myconfig->{name};
 
   $main::lxdebug->leave_sub();