Merge branch 'master' of github.com:kivitendo/kivitendo-erp
[kivitendo-erp.git] / SL / IS.pm
index 82226ee..28c4a66 100644 (file)
--- a/SL/IS.pm
+++ b/SL/IS.pm
@@ -48,6 +48,7 @@ use SL::MoreCommon;
 use SL::IC;
 use SL::IO;
 use SL::TransNumber;
+use SL::DB::Default;
 use Data::Dumper;
 
 use strict;
@@ -221,12 +222,18 @@ sub invoice_details {
       my ($dec)         = ($sellprice =~ /\.(\d+)/);
       my $decimalplaces = max 2, length($dec);
 
-      my $parsed_discount      = $form->parse_amount($myconfig, $form->{"discount_$i"});
-      my $linetotal_exact      =                     $form->{"qty_$i"} * $sellprice * (100 - $parsed_discount) / 100 / $price_factor->{factor};
-      my $linetotal            = $form->round_amount($linetotal_exact, 2);
-      my $discount             = $form->round_amount($form->{"qty_$i"} * $sellprice * $parsed_discount / 100 / $price_factor->{factor} - ($linetotal - $linetotal_exact),
-                                                     $decimalplaces);
-      my $nodiscount_linetotal = $form->round_amount($form->{"qty_$i"} * $sellprice / $price_factor->{factor}, 2);
+      my $parsed_discount            = $form->parse_amount($myconfig, $form->{"discount_$i"});
+
+      my $linetotal_exact            = $form->{"qty_$i"} * $sellprice * (100 - $parsed_discount) / 100 / $price_factor->{factor};
+      my $linetotal                  = $form->round_amount($linetotal_exact, 2);
+
+      my $nodiscount_exact_linetotal = $form->{"qty_$i"} * $sellprice                                  / $price_factor->{factor};
+      my $nodiscount_linetotal       = $form->round_amount($nodiscount_exact_linetotal,2);
+
+      my $discount                   = $nodiscount_linetotal - $linetotal; # is always rounded because $nodiscount_linetotal and $linetotal are rounded
+
+      my $discount_round_error       = $discount + ($linetotal_exact - $nodiscount_exact_linetotal); # not used
+
       $form->{"netprice_$i"}   = $form->round_amount($form->{"qty_$i"} ? ($linetotal / $form->{"qty_$i"}) : 0, 2);
 
       push @{ $form->{TEMPLATE_ARRAYS}->{netprice} },       ($form->{"netprice_$i"} != 0) ? $form->format_amount($myconfig, $form->{"netprice_$i"}, $decimalplaces) : '';
@@ -258,8 +265,7 @@ sub invoice_details {
         $subtotal_header     = 0;
 
       } else {
-        push @{ $form->{TEMPLATE_ARRAYS}->{discount_sub} },   "";
-        push @{ $form->{TEMPLATE_ARRAYS}->{nodiscount_sub} }, "";
+        push @{ $form->{TEMPLATE_ARRAYS}->{$_} }, "" for qw(discount_sub nodiscount_sub discount_sub_nofmt nodiscount_sub_nofmt);
       }
 
       if (!$form->{"discount_$i"}) {
@@ -701,9 +707,13 @@ sub post_invoice {
         }
       }
 
-      # get pricegroup_id and save it
+      # Get pricegroup_id and save it. Unfortunately the interface
+      # also uses ID "0" for signalling that none is selected, but "0"
+      # must not be stored in the database. Therefore we cannot simply
+      # use conv_i().
       ($null, my $pricegroup_id) = split(/--/, $form->{"sellprice_pg_$i"});
       $pricegroup_id *= 1;
+      $pricegroup_id  = undef if !$pricegroup_id;
 
       my ($invoice_id) = selectfirst_array_query($form, $dbh, qq|SELECT nextval('invoiceid')|);
 
@@ -723,7 +733,7 @@ sub post_invoice {
                  $form->{"sellprice_$i"}, $fxsellprice,
                  $form->{"discount_$i"}, $allocated, 'f',
                  $form->{"unit_$i"}, conv_date($form->{"reqdate_$i"}), conv_i($form->{"project_id_$i"}),
-                 $form->{"serialnumber_$i"}, conv_i($pricegroup_id),
+                 $form->{"serialnumber_$i"}, $pricegroup_id,
                  $form->{"ordnumber_$i"}, conv_date($form->{"transdate_$i"}),
                  $form->{"cusordnumber_$i"}, $baseqty, $form->{"subtotal_$i"} ? 't' : 'f',
                  $form->{"marge_percent_$i"}, $form->{"marge_absolut_$i"},
@@ -887,7 +897,7 @@ sub post_invoice {
 
       if ($form->{"acc_trans_id_$i"}
           && $payments_only
-          && ($::lx_office_conf{features}->{payments_changeable} == 0)) {
+          && (SL::DB::Default->get->payments_changeable == 0)) {
         next;
       }
 
@@ -1004,7 +1014,7 @@ sub post_invoice {
                 cp_id       = ?, marge_total   = ?, marge_percent = ?,
                 globalproject_id               = ?, delivery_customer_id             = ?,
                 transaction_description        = ?, delivery_vendor_id               = ?,
-                donumber    = ?, invnumber_for_credit_note = ?
+                donumber    = ?, invnumber_for_credit_note = ?,        direct_debit  = ?
               WHERE id = ?|;
   @values = (          $form->{"invnumber"},           $form->{"ordnumber"},             $form->{"quonumber"},          $form->{"cusordnumber"},
              conv_date($form->{"invdate"}),  conv_date($form->{"orddate"}),    conv_date($form->{"quodate"}),    conv_i($form->{"customer_id"}),
@@ -1017,7 +1027,7 @@ sub post_invoice {
                 conv_i($form->{"cp_id"}),            1 * $form->{marge_total} ,      1 * $form->{marge_percent},
                 conv_i($form->{"globalproject_id"}),                              conv_i($form->{"delivery_customer_id"}),
                        $form->{transaction_description},                          conv_i($form->{"delivery_vendor_id"}),
-                       $form->{"donumber"}, $form->{"invnumber_for_credit_note"},
+                       $form->{"donumber"}, $form->{"invnumber_for_credit_note"},        $form->{direct_debit} ? 't' : 'f',
                 conv_i($form->{"id"}));
   do_query($form, $dbh, $query, @values);
 
@@ -1077,7 +1087,7 @@ sub post_invoice {
                                'table'   => 'ar',);
 
   # safety check datev export
-  if ($::lx_office_conf{datev_check}{check_on_sales_invoice}) {
+  if ($::instance_conf->get_datev_check_on_sales_invoice) {
     my $transdate = $::form->{invdate} ? DateTime->from_lxoffice($::form->{invdate}) : undef;
     $transdate  ||= DateTime->today;
 
@@ -1158,7 +1168,7 @@ sub post_payment {
   $old_form = save_form();
 
   # Delete all entries in acc_trans from prior payments.
-  if ($::lx_office_conf{features}->{payments_changeable} != 0) {
+  if (SL::DB::Default->get->payments_changeable != 0) {
     $self->_delete_payments($form, $dbh);
   }
 
@@ -1495,7 +1505,7 @@ sub retrieve_invoice {
            a.employee_id, a.salesman_id, a.payment_id,
            a.language_id, a.delivery_customer_id, a.delivery_vendor_id, a.type,
            a.transaction_description, a.donumber, a.invnumber_for_credit_note,
-           a.marge_total, a.marge_percent,
+           a.marge_total, a.marge_percent, a.direct_debit,
            e.name AS employee
          FROM ar a
          LEFT JOIN employee e ON (e.id = a.employee_id)
@@ -1671,7 +1681,7 @@ sub get_customer {
          c.email, c.cc, c.bcc, c.language_id, c.payment_id,
          c.street, c.zipcode, c.city, c.country,
          c.notes AS intnotes, c.klass as customer_klass, c.taxzone_id, c.salesman_id, c.curr,
-         c.taxincluded_checked,
+         c.taxincluded_checked, c.direct_debit,
          $duedate + COALESCE(pt.terms_netto, 0) AS duedate,
          b.discount AS tradediscount, b.description AS business
        FROM customer c
@@ -2028,7 +2038,7 @@ sub get_pricegroups_for_parts {
 
     my $pricegroup_old = $form->{"pricegroup_old_$i"};
 
-    # sellprice has format 13,0000 or 0,00000, can't check for 0 numerically
+    # sellprice has format 13,0000 or 0,00000,  can't check for 0 numerically
     my $sellprice = $form->{"sellprice_$i"};
     my $pricegroup_id = $form->{"pricegroup_id_$i"};
     $form->{"new_pricegroup_$i"} = $selectedpricegroup_id;
@@ -2130,7 +2140,7 @@ sub get_pricegroups_for_parts {
 
           $pkr->{selected}  = ' selected'; # unless $form->{selected};
           # no customer pricesgroup set
-          if ($pkr->{price_unfmt} == $pkr->{default_sellprice}) {
+          if ($pkr->{price_ufmt} == $pkr->{default_sellprice}) {
 
             $pkr->{price} = $form->{"sellprice_$i"};
 
@@ -2141,7 +2151,7 @@ sub get_pricegroups_for_parts {
             $form->{"sellprice_$i"} = $pkr->{price};
           }
 
-        } elsif ($pkr->{price_unfmt} == $pkr->{default_sellprice} and $pkr->{default_sellprice} != 0) {
+        } elsif ($pkr->{price_ufmt} == $pkr->{default_sellprice} and $pkr->{default_sellprice} != 0) {
           $pkr->{price}    = $form->{"sellprice_$i"};
           $pkr->{selected} = ' selected';
         }