Controller für Mandantenkonfiguration.
[kivitendo-erp.git] / SL / IS.pm
index c9a4428..8f00225 100644 (file)
--- a/SL/IS.pm
+++ b/SL/IS.pm
@@ -40,6 +40,7 @@ use SL::AM;
 use SL::ARAP;
 use SL::CVar;
 use SL::Common;
+use SL::DATEV qw(:CONSTANTS);
 use SL::DBUtils;
 use SL::DO;
 use SL::GenericTranslations;
@@ -47,6 +48,7 @@ use SL::MoreCommon;
 use SL::IC;
 use SL::IO;
 use SL::TransNumber;
+use SL::DB::Default;
 use Data::Dumper;
 
 use strict;
@@ -257,8 +259,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"}) {
@@ -450,7 +451,8 @@ sub customer_details {
   # get rest for the customer
   my $query =
     qq|SELECT ct.*, cp.*, ct.notes as customernotes,
-         ct.phone AS customerphone, ct.fax AS customerfax, ct.email AS customeremail
+         ct.phone AS customerphone, ct.fax AS customerfax, ct.email AS customeremail,
+         ct.curr AS currency
        FROM customer ct
        LEFT JOIN contacts cp on ct.id = cp.cp_cv_id
        WHERE (ct.id = ?) $where
@@ -470,6 +472,9 @@ sub customer_details {
 
   map { $form->{$_} = $ref->{$_} } keys %$ref;
 
+  # remove any trailing whitespace
+  $form->{currency} =~ s/\s*$// if ($form->{currency});
+
   if ($form->{delivery_customer_id}) {
     $query =
       qq|SELECT *, notes as customernotes
@@ -882,7 +887,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;
       }
 
@@ -928,18 +933,16 @@ sub post_invoice {
 
       # exchangerate difference
       $form->{fx}{$accno}{ $form->{"datepaid_$i"} } +=
-      $form->{"paid_$i"} * ($form->{"exchangerate_$i"} - 1) + $diff;
+        $form->{"paid_$i"} * ($form->{"exchangerate_$i"} - 1) + $diff;
 
       # gain/loss
       $amount =
-      $form->{"paid_$i"} * $form->{exchangerate} - $form->{"paid_$i"} *
-      $form->{"exchangerate_$i"};
+        $form->{"paid_$i"} * $form->{exchangerate} - $form->{"paid_$i"} *
+        $form->{"exchangerate_$i"};
       if ($amount > 0) {
-        $form->{fx}{ $form->{fxgain_accno} }{ $form->{"datepaid_$i"} } +=
-        $amount;
+        $form->{fx}{ $form->{fxgain_accno} }{ $form->{"datepaid_$i"} } += $amount;
       } else {
-        $form->{fx}{ $form->{fxloss_accno} }{ $form->{"datepaid_$i"} } +=
-        $amount;
+        $form->{fx}{ $form->{fxloss_accno} }{ $form->{"datepaid_$i"} } += $amount;
       }
 
       $diff = 0;
@@ -958,35 +961,32 @@ sub post_invoice {
 
   IO->set_datepaid(table => 'ar', id => $form->{id}, dbh => $dbh);
 
-  if ($payments_only) {
-    $query = qq|UPDATE ar SET paid = ? WHERE id = ?|;
-    do_query($form, $dbh, $query,  $form->{paid}, conv_i($form->{id}));
-
-    $dbh->commit if !$provided_dbh;
-
-    $main::lxdebug->leave_sub();
-    return;
-  }
-
   # record exchange rate differences and gains/losses
   foreach my $accno (keys %{ $form->{fx} }) {
     foreach my $transdate (keys %{ $form->{fx}{$accno} }) {
-      if (
-          ($form->{fx}{$accno}{$transdate} =
-           $form->round_amount($form->{fx}{$accno}{$transdate}, 2)
-          ) != 0
-        ) {
+      $form->{fx}{$accno}{$transdate} = $form->round_amount($form->{fx}{$accno}{$transdate}, 2);
+      if ( $form->{fx}{$accno}{$transdate} != 0 ) {
 
         $query =
           qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate, cleared, fx_transaction, taxkey, project_id)
              VALUES (?, (SELECT id FROM chart WHERE accno = ?), ?, ?, '0', '1',
              (SELECT taxkey_id FROM chart WHERE accno = ?), ?)|;
-        @values = (conv_i($form->{"id"}), $accno, $form->{fx}{$accno}{$transdate}, conv_date($transdate), $accno, $project_id);
+        @values = (conv_i($form->{"id"}), $accno, $form->{fx}{$accno}{$transdate}, conv_date($transdate), $accno, conv_i($project_id));
         do_query($form, $dbh, $query, @values);
       }
     }
   }
 
+  if ($payments_only) {
+    $query = qq|UPDATE ar SET paid = ? WHERE id = ?|;
+    do_query($form, $dbh, $query,  $form->{paid}, conv_i($form->{id}));
+
+    $dbh->commit if !$provided_dbh;
+
+    $main::lxdebug->leave_sub();
+    return;
+  }
+
   $amount = $netamount + $tax;
 
   # save AR record
@@ -1076,6 +1076,27 @@ sub post_invoice {
                                'arap_id' => $form->{id},
                                'table'   => 'ar',);
 
+  # safety check datev export
+  if ($::lx_office_conf{datev_check}{check_on_sales_invoice}) {
+    my $transdate = $::form->{invdate} ? DateTime->from_lxoffice($::form->{invdate}) : undef;
+    $transdate  ||= DateTime->today;
+
+    my $datev = SL::DATEV->new(
+      exporttype => DATEV_ET_BUCHUNGEN,
+      format     => DATEV_FORMAT_KNE,
+      dbh        => $dbh,
+      from       => $transdate,
+      to         => $transdate,
+    );
+
+    $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;
 
@@ -1137,7 +1158,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);
   }
 
@@ -1409,14 +1430,16 @@ sub delete_invoice {
     do_query($form, $dbh, qq|UPDATE ar SET storno = 'f', paid = 0 WHERE id = ?|, $invoice_id);
   }
 
-  # delete AR record
-  do_query($form, $dbh, qq|DELETE FROM ar WHERE id = ?|, @values);
-
   # delete spool files
   my @spoolfiles = selectall_array_query($form, $dbh, qq|SELECT spoolfile FROM status WHERE trans_id = ?|, @values);
 
-  # delete status entries
-  do_query($form, $dbh, qq|DELETE FROM status WHERE trans_id = ?|, @values);
+  my @queries = (
+    qq|DELETE FROM status WHERE trans_id = ?|,
+    qq|DELETE FROM periodic_invoices WHERE ar_id = ?|,
+    qq|DELETE FROM ar WHERE id = ?|,
+  );
+
+  map { do_query($form, $dbh, $_, @values) } @queries;
 
   my $rc = $dbh->commit;
 
@@ -1440,7 +1463,7 @@ sub retrieve_invoice {
 
   my ($sth, $ref, $query);
 
-  my $query_transdate = ", current_date AS invdate" if !$form->{id};
+  my $query_transdate = !$form->{id} ? ", current_date AS invdate" : '';
 
   $query =
     qq|SELECT
@@ -1647,7 +1670,8 @@ sub get_customer {
          c.id AS customer_id, c.name AS customer, c.discount as customer_discount, c.creditlimit, c.terms,
          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.notes AS intnotes, c.klass as customer_klass, c.taxzone_id, c.salesman_id, c.curr,
+         c.taxincluded_checked,
          $duedate + COALESCE(pt.terms_netto, 0) AS duedate,
          b.discount AS tradediscount, b.description AS business
        FROM customer c
@@ -1661,6 +1685,12 @@ sub get_customer {
 
   map { $form->{$_} = $ref->{$_} } keys %$ref;
 
+  # remove any trailing whitespace
+  $form->{curr} =~ s/\s*$//;
+
+  # use customer currency if not empty
+  $form->{currency} = $form->{curr} if $form->{curr};
+
   $query =
     qq|SELECT sum(amount - paid) AS dunning_amount
        FROM ar
@@ -2076,9 +2106,10 @@ sub get_pricegroups_for_parts {
 
       $pkr->{price} *= $form->{"basefactor_$i"};
       $pkr->{price} *= $basefactor;
+      $pkr->{price_ufmt} = $pkr->{price};
       $pkr->{price} = $form->format_amount($myconfig, $pkr->{price}, 5);
 
-      if ($selectedpricegroup_id eq undef) {
+      if (!defined $selectedpricegroup_id) {
         # new entries in article list, either old invoice was loaded (edit) or a new article was added
         # Case A: open old invoice, no pricegroup selected
         # Case B: add new article to invoice, no pricegroup selected
@@ -2090,18 +2121,16 @@ sub get_pricegroups_for_parts {
         if ($pkr->{pricegroup_id} eq $form->{"pricegroup_id_$i"} and defined $form->{"pricegroup_id_$i"}) {
           # Case A
           $pkr->{selected}  = ' selected';
-
         } elsif ($pkr->{pricegroup_id} eq $form->{customer_klass}
                  and not defined $form->{"pricegroup_id_$i"}
-                 and $pkr->{price} != 0    # only use customer pricegroup price if it has a value, else use default_sellprice
-                                           # for the case where pricegroup prices haven't been set
+                 and $pkr->{price_ufmt} != 0    # only use customer pricegroup price if it has a value, else use default_sellprice
+                                                # for the case where pricegroup prices haven't been set
                 ) {
           # Case B: use default pricegroup of customer
 
           $pkr->{selected}  = ' selected'; # unless $form->{selected};
-
           # no customer pricesgroup set
-          if ($pkr->{price} == $pkr->{default_sellprice}) {
+          if ($pkr->{price_unfmt} == $pkr->{default_sellprice}) {
 
             $pkr->{price} = $form->{"sellprice_$i"};
 
@@ -2112,7 +2141,7 @@ sub get_pricegroups_for_parts {
             $form->{"sellprice_$i"} = $pkr->{price};
           }
 
-        } elsif ($pkr->{price} == $pkr->{default_sellprice} and $pkr->{default_sellprice} != 0) {
+        } elsif ($pkr->{price_unfmt} == $pkr->{default_sellprice} and $pkr->{default_sellprice} != 0) {
           $pkr->{price}    = $form->{"sellprice_$i"};
           $pkr->{selected} = ' selected';
         }