Artikel-Klassifizierung: Neue Option "Preis separat ausweisen"
[kivitendo-erp.git] / SL / IS.pm
index a05f25e..8186986 100644 (file)
--- a/SL/IS.pm
+++ b/SL/IS.pm
@@ -54,6 +54,7 @@ use SL::DB::Default;
 use SL::DB::Tax;
 use SL::DB::TaxZone;
 use SL::TransNumber;
+use SL::DB;
 use Data::Dumper;
 
 use strict;
@@ -148,6 +149,7 @@ sub invoice_details {
   # so that they can be sorted in later
   my %prepared_template_arrays = IC->prepare_parts_for_printing(myconfig => $myconfig, form => $form);
   my @prepared_arrays          = keys %prepared_template_arrays;
+  my @separate_totals          = qw(non_separate_subtotal);
 
   my $ic_cvar_configs = CVar->get_configs(module => 'IC');
   my $project_cvar_configs = CVar->get_configs(module => 'Projects');
@@ -331,6 +333,17 @@ sub invoice_details {
       push @{ $form->{TEMPLATE_ARRAYS}->{discount_nofmt} }, ($discount != 0) ? $discount * -1 : '';
       push @{ $form->{TEMPLATE_ARRAYS}->{p_discount} },     $form->{"discount_$i"};
 
+      if ( $prepared_template_arrays{separate}[$i - 1]  ) {
+        my $pabbr = $prepared_template_arrays{separate}[$i - 1];
+        if ( ! $form->{"separate_${pabbr}_subtotal"} ) {
+            push @separate_totals , "separate_${pabbr}_subtotal";
+            $form->{"separate_${pabbr}_subtotal"} = 0;
+        }
+        $form->{"separate_${pabbr}_subtotal"} += $linetotal;
+      } else {
+        $form->{non_separate_subtotal} += $linetotal;
+      }
+
       $form->{total}            += $linetotal;
       $form->{nodiscount_total} += $nodiscount_linetotal;
       $form->{discount_total}   += $discount;
@@ -538,6 +551,7 @@ sub invoice_details {
   $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};
+  $form->{$_} = $form->format_amount($myconfig, $form->{$_}, 2) for @separate_totals;
 
   $main::lxdebug->leave_sub();
 }
@@ -655,12 +669,19 @@ sub customer_details {
 }
 
 sub post_invoice {
+  my ($self, $myconfig, $form, $provided_dbh, $payments_only) = @_;
   $main::lxdebug->enter_sub();
 
+  my $rc = SL::DB->client->with_transaction(\&_post_invoice, $self, $myconfig, $form, $provided_dbh, $payments_only);
+
+  $::lxdebug->leave_sub;
+  return $rc;
+}
+
+sub _post_invoice {
   my ($self, $myconfig, $form, $provided_dbh, $payments_only) = @_;
 
-  # connect to database, turn off autocommit
-  my $dbh = $provided_dbh ? $provided_dbh : $form->get_standard_dbh;
+  my $dbh = $provided_dbh || SL::DB->client->dbh;
   my $restricter = SL::HTML::Restrict->create;
 
   my ($query, $sth, $null, $project_id, @values);
@@ -1257,9 +1278,6 @@ SQL
 
     $form->new_lastmtime('ar');
 
-    $dbh->commit if !$provided_dbh;
-
-    $main::lxdebug->leave_sub();
     return;
   }
 
@@ -1398,17 +1416,11 @@ SQL
     $datev->export;
 
     if ($datev->errors) {
-      $dbh->rollback;
       die join "\n", $::locale->text('DATEV check returned errors:'), $datev->errors;
     }
   }
 
-  my $rc = 1;
-  $dbh->commit if !$provided_dbh;
-
-  $main::lxdebug->leave_sub();
-
-  return $rc;
+  return 1;
 }
 
 sub transfer_out {
@@ -1580,12 +1592,19 @@ sub _delete_payments {
 }
 
 sub post_payment {
+  my ($self, $myconfig, $form, $locale) = @_;
   $main::lxdebug->enter_sub();
 
+  my $rc = SL::DB->client->with_transaction(\&_post_payment, $self, $myconfig, $form, $locale);
+
+  $::lxdebug->leave_sub;
+  return $rc;
+}
+
+sub _post_payment {
   my ($self, $myconfig, $form, $locale) = @_;
 
-  # connect to database, turn off autocommit
-  my $dbh = $form->get_standard_dbh;
+  my $dbh = SL::DB->client->dbh;
 
   my (%payments, $old_form, $row, $item, $query, %keep_vars);
 
@@ -1641,11 +1660,7 @@ sub post_payment {
 
   restore_form($old_form);
 
-  my $rc = $dbh->commit();
-
-  $main::lxdebug->leave_sub();
-
-  return $rc;
+  return 1;
 }
 
 sub process_assembly {
@@ -1654,8 +1669,7 @@ sub process_assembly {
   my ($dbh, $myconfig, $form, $position, $id, $totalqty) = @_;
 
   my $query =
-    qq|SELECT a.parts_id, a.qty, p.assembly, p.partnumber, p.description, p.unit,
-         p.inventory_accno_id, p.income_accno_id, p.expense_accno_id
+    qq|SELECT a.parts_id, a.qty, p.part_type, p.partnumber, p.description, p.unit
        FROM assembly a
        JOIN parts p ON (a.parts_id = p.id)
        WHERE (a.id = ?)|;
@@ -1795,7 +1809,7 @@ sub reverse_invoice {
 
   # reverse inventory items
   my $query =
-    qq|SELECT i.id, i.parts_id, i.qty, i.assemblyitem, p.assembly, p.inventory_accno_id
+    qq|SELECT i.id, i.parts_id, i.qty, i.assemblyitem, p.part_type
        FROM invoice i
        JOIN parts p ON (i.parts_id = p.id)
        WHERE i.trans_id = ?|;
@@ -1843,12 +1857,19 @@ sub reverse_invoice {
 }
 
 sub delete_invoice {
+  my ($self, $myconfig, $form) = @_;
   $main::lxdebug->enter_sub();
 
+  my $rc = SL::DB->client->with_transaction(\&_delete_invoice, $self, $myconfig, $form);
+
+  $::lxdebug->leave_sub;
+  return $rc;
+}
+
+sub _delete_invoice {
   my ($self, $myconfig, $form) = @_;
 
-  # connect to database
-  my $dbh = $form->get_standard_dbh;
+  my $dbh = SL::DB->client->dbh;
 
   &reverse_invoice($dbh, $form);
   _delete_transfers($dbh, $form, $form->{id});
@@ -1881,25 +1902,26 @@ sub delete_invoice {
 
   map { do_query($form, $dbh, $_, @values) } @queries;
 
-  my $rc = $dbh->commit;
-
-  if ($rc) {
-    my $spool = $::lx_office_conf{paths}->{spool};
-    map { unlink "$spool/$_" if -f "$spool/$_"; } @spoolfiles;
-  }
-
-  $main::lxdebug->leave_sub();
+  my $spool = $::lx_office_conf{paths}->{spool};
+  map { unlink "$spool/$_" if -f "$spool/$_"; } @spoolfiles;
 
-  return $rc;
+  return 1;
 }
 
 sub retrieve_invoice {
+  my ($self, $myconfig, $form) = @_;
   $main::lxdebug->enter_sub();
 
+  my $rc = SL::DB->client->with_transaction(\&_retrieve_invoice, $self, $myconfig, $form);
+
+  $::lxdebug->leave_sub;
+  return $rc;
+}
+
+sub _retrieve_invoice {
   my ($self, $myconfig, $form) = @_;
 
-  # connect to database
-  my $dbh = $form->get_standard_dbh;
+  my $dbh = SL::DB->client->dbh;
 
   my ($sth, $ref, $query);
 
@@ -1993,7 +2015,8 @@ sub retrieve_invoice {
            i.description, i.longdescription, i.qty, i.fxsellprice AS sellprice, i.discount, i.parts_id AS id, i.unit, i.deliverydate AS reqdate,
            i.project_id, i.serialnumber, i.pricegroup_id, i.ordnumber, i.donumber, i.transdate, i.cusordnumber, i.subtotal, i.lastcost,
            i.price_factor_id, i.price_factor, i.marge_price_factor, i.active_price_source, i.active_discount_source,
-           p.partnumber, p.assembly, p.notes AS partnotes, p.inventory_accno_id AS part_inventory_accno_id, p.formel, p.listprice,
+           p.partnumber, p.part_type, p.notes AS partnotes, p.formel, p.listprice,
+           p.classification_id,
            pr.projectnumber, pg.partsgroup, prg.pricegroup
 
          FROM invoice i
@@ -2086,11 +2109,7 @@ sub retrieve_invoice {
     Common::webdav_folder($form);
   }
 
-  my $rc = $dbh->commit;
-
-  $main::lxdebug->leave_sub();
-
-  return $rc;
+  return 1;
 }
 
 sub get_customer {
@@ -2293,8 +2312,9 @@ sub retrieve_item {
   my $query =
     qq|SELECT
          p.id, p.partnumber, p.description, p.sellprice,
-         p.listprice, p.inventory_accno_id, p.lastcost,
+         p.listprice, p.part_type, p.lastcost,
          p.ean, p.notes,
+         p.classification_id,
 
          c1.accno AS inventory_accno,
          c1.new_chart_id AS inventory_new_chart,
@@ -2308,13 +2328,13 @@ sub retrieve_item {
          c3.new_chart_id AS expense_new_chart,
          date($transdate) - c3.valid_from AS expense_valid,
 
-         p.unit, p.assembly, p.onhand,
+         p.unit, p.part_type, p.onhand,
          p.notes AS partnotes, p.notes AS longdescription,
          p.not_discountable, p.formel, p.payment_id AS part_payment_id,
          p.price_factor_id, p.weight,
 
          pfac.factor AS price_factor,
-
+         pt.used_for_sale AS used_for_sale,
          pg.partsgroup
 
        FROM parts p
@@ -2331,6 +2351,7 @@ sub retrieve_item {
            FROM taxzone_charts tc
            WHERE tc.buchungsgruppen_id = p.buchungsgruppen_id and tc.taxzone_id = ${taxzone_id}) = c3.id)
        LEFT JOIN partsgroup pg ON (pg.id = p.partsgroup_id)
+       LEFT JOIN parts_classifications pt ON (pt.id = p.classification_id)
        LEFT JOIN price_factors pfac ON (pfac.id = p.price_factor_id)
        WHERE $where|;
   my $sth = prepare_execute_query($form, $dbh, $query, @values);
@@ -2348,6 +2369,7 @@ sub retrieve_item {
                                    LIMIT 1| ] );
   map { push @{ $_ }, prepare_query($form, $dbh, $_->[0]) } @translation_queries;
 
+  my $has_wrong_pclass = 0;
   while (my $ref = $sth->fetchrow_hashref('NAME_lc')) {
 
     if ($mm_by_id{$ref->{id}}) {
@@ -2359,6 +2381,12 @@ sub retrieve_item {
       push @{ $ref->{matches} ||= [] }, $::locale->text('EAN') . ': ' . $ref->{ean};
     }
 
+    $ref->{type_and_classific} = $::request->presenter->type_abbreviation($ref->{part_type}).
+                                 $::request->presenter->classification_abbreviation($ref->{classification_id});
+    if (! $ref->{used_for_sale} ) {
+        $has_wrong_pclass = 1;
+        next;
+    }
     # In der Buchungsgruppe ist immer ein Bestandskonto verknuepft, auch wenn
     # es sich um eine Dienstleistung handelt. Bei Dienstleistungen muss das
     # Buchungskonto also aus dem Ergebnis rausgenommen werden.
@@ -2442,15 +2470,15 @@ sub retrieve_item {
   $sth->finish;
   $_->[1]->finish for @translation_queries;
 
+  $form->{is_wrong_pclass} = $has_wrong_pclass;
   foreach my $item (@{ $form->{item_list} }) {
     my $custom_variables = CVar->get_custom_variables(module   => 'IC',
                                                       trans_id => $item->{id},
                                                       dbh      => $dbh,
                                                      );
-
+    $form->{is_wrong_pclass} = 0; # one correct type
     map { $item->{"ic_cvar_" . $_->{name} } = $_->{value} } @{ $custom_variables };
   }
-
   $main::lxdebug->leave_sub();
 }