Merge branch 'master' of vc.linet-services.de:public/lx-office-erp
[kivitendo-erp.git] / SL / DATEV.pm
index 1a455f3..6c6f1c7 100644 (file)
@@ -26,7 +26,8 @@
 
 package DATEV;
 
-use List::Util qw(max);
+use utf8;
+use strict;
 
 use SL::DBUtils;
 use SL::DATEV::KNEFile;
@@ -34,10 +35,9 @@ use SL::Taxkeys;
 
 use Data::Dumper;
 use File::Path;
+use List::Util qw(max);
 use Time::HiRes qw(gettimeofday);
 
-use strict;
-
 sub _get_export_path {
   $main::lxdebug->enter_sub();
 
@@ -58,7 +58,7 @@ sub get_path_for_download_token {
   my $path;
 
   if ($token =~ m|^(\d+)-(\d+)-(\d+)$|) {
-    $path = "${main::userspath}/datev-export-${1}-${2}-${3}";
+    $path = $::lx_office_conf{paths}->{userspath} . "/datev-export-${1}-${2}-${3}";
   }
 
   $main::lxdebug->leave_sub();
@@ -84,7 +84,7 @@ sub get_download_token_for_path {
 sub clean_temporary_directories {
   $main::lxdebug->enter_sub();
 
-  foreach my $path (glob "${main::userspath}/datev-export-*") {
+  foreach my $path (glob($::lx_office_conf{paths}->{userspath} . "/datev-export-*")) {
     next unless (-d $path);
 
     my $mtime = (stat($path))[9];
@@ -330,6 +330,9 @@ sub _get_transactions {
   my ($notsplitindex);
   my @errors   = ();
 
+  $form->{net_gross_differences}     = [];
+  $form->{sum_net_gross_differences} = 0;
+
   $fromto      =~ s/transdate/ac\.transdate/g;
 
   my $taxkeys  = Taxkeys->new();
@@ -383,6 +386,7 @@ sub _get_transactions {
        ORDER BY trans_id, acc_trans_id|;
 
   my $sth = prepare_execute_query($form, $dbh, $query);
+  $form->{DATEV} = [];
 
   my $counter = 0;
   while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
@@ -395,14 +399,15 @@ sub _get_transactions {
 
     my $count    = $ref->{amount};
     my $firstrun = 1;
+    my $subcent  = abs($count) < 0.02;
 
-    while (abs($count) > 0.01 || $firstrun) {
+    while (abs($count) > 0.01 || $firstrun || ($subcent && abs($count) > 0.005)) {
       my $ref2 = $sth->fetchrow_hashref("NAME_lc");
       last unless ($ref2);
 
       if ($ref2->{trans_id} != $trans->[0]->{trans_id}) {
         $form->error("Unbalanced ledger! old trans_id " . $trans->[0]->{trans_id} . " new trans_id " . $ref2->{trans_id} . " count $count");
-        exit 1;
+        ::end_of_request();
       }
 
       push @{ $trans }, $ref2;
@@ -445,6 +450,7 @@ sub _get_transactions {
 
     my $ml             = ($trans->[0]->{'umsatz'} > 0) ? 1 : -1;
     my $rounding_error = 0;
+    my @taxed;
 
     for my $j (0 .. (scalar(@{$trans}) - 1)) {
       if (   ($j != $notsplitindex)
@@ -481,23 +487,24 @@ sub _get_transactions {
           $absumsatz               += -1 * $new_trans{'amount'};
 
         } else {
-          my $unrounded             = $trans->[$j]->{'amount'} * (1 + $tax_rate) * -1; # + $rounding_error;
+          my $unrounded             = $trans->[$j]->{'amount'} * (1 + $tax_rate) * -1 + $rounding_error;
           my $rounded               = $form->round_amount($unrounded, 2);
-          $rounding_error          += $unrounded - $rounded;
+
+          $rounding_error           = $unrounded - $rounded;
           $new_trans{'amount'}      = $rounded;
-          $new_trans{'umsatz'}      = abs($form->round_amount(($trans->[$j]->{'amount'} * (1 + $tax_rate)), 2)) * $ml;
-          $trans->[$j]->{'umsatz'}  = abs($form->round_amount(($trans->[$j]->{'amount'} * (1 + $tax_rate)), 2)) * $ml;
-          $absumsatz               += $form->round_amount($trans->[$j]->{'amount'} + $trans->[$j]->{'amount'} * $tax_rate, 2);
+          $new_trans{'umsatz'}      = abs($rounded) * $ml;
+          $trans->[$j]->{'umsatz'}  = $new_trans{umsatz};
+          $absumsatz               -= $rounded;
         }
 
         push @{ $form->{DATEV} }, [ \%new_trans, $trans->[$j] ];
+        push @taxed, $form->{DATEV}->[-1];
       }
     }
 
     my $idx        = 0;
     my $correction = 0;
-    our @taxed;          # most likely defunct
-    while (abs($absumsatz) >= 0.01) {
+    while ((abs($absumsatz) >= 0.01) && (abs($absumsatz) < 1.00)) {
       if ($idx >= scalar @taxed) {
         last if (!$correction);
 
@@ -533,8 +540,13 @@ sub _get_transactions {
       $idx++;
     }
 
-    if (abs($absumsatz) >= 0.01) {
-      push @errors, "Datev-Export fehlgeschlagen! Bei Transaktion $trans->[0]->{trans_id} ($absumsatz, Rundungsfehler $rounding_error)\n";
+    $absumsatz = $form->round_amount($absumsatz, 2);
+    if (abs($absumsatz) >= (0.01 * (1 + scalar @taxed))) {
+      push @errors, "Datev-Export fehlgeschlagen! Bei Transaktion $trans->[0]->{trans_id} ($absumsatz)\n";
+
+    } elsif (abs($absumsatz) >= 0.01) {
+      push @{ $form->{net_gross_differences} }, $absumsatz;
+      $form->{sum_net_gross_differences} += $absumsatz;
     }
   }
 
@@ -766,14 +778,14 @@ sub kne_buchungsexport {
       my $taxkey         = 0;
       my $charttax       = 0;
       my ($haben, $soll);
-      my $iconv          = $main::locale->{iconv_iso8859};
-      my %umlaute = ($iconv->convert('ä') => 'ae',
-                     $iconv->convert('ö') => 'oe',
-                     $iconv->convert('ü') => 'ue',
-                     $iconv->convert('Ä') => 'Ae',
-                     $iconv->convert('Ö') => 'Oe',
-                     $iconv->convert('Ü') => 'Ue',
-                     $iconv->convert('ß') => 'sz');
+      my $iconv          = $::locale->{iconv_utf8};
+      my %umlaute = ($iconv->convert('ä') => 'ae',
+                     $iconv->convert('ö') => 'oe',
+                     $iconv->convert('ü') => 'ue',
+                     $iconv->convert('Ä') => 'Ae',
+                     $iconv->convert('Ö') => 'Oe',
+                     $iconv->convert('Ü') => 'Ue',
+                     $iconv->convert('ß') => 'sz');
       for (my $i = 0; $i < $trans_lines; $i++) {
         if ($trans_lines == 2) {
           if (abs($transaction->[$i]->{'amount'}) > abs($umsatz)) {
@@ -856,7 +868,7 @@ sub kne_buchungsexport {
     $kne_file->add_block($mandantenendsumme);
     $kne_file->flush();
 
-    open(ED, "> $ed_filename") or die "can't open outputfile: $!\n";
+    open(ED, ">", $ed_filename) or die "can't open outputfile: $!\n";
     print(ED $kne_file->get_data());
     close(ED);
 
@@ -868,7 +880,7 @@ sub kne_buchungsexport {
   my $ev_header = &make_ev_header($form, $fileno);
   my $ev_filename = $export_path . $evfile;
   push(@filenames, $evfile);
-  open(EV, "> $ev_filename") or die "can't open outputfile: EV01\n";
+  open(EV, ">", $ev_filename) or die "can't open outputfile: EV01\n";
   print(EV $ev_header);
 
   foreach my $file (@ed_versionset) {
@@ -910,7 +922,7 @@ sub kne_stammdatenexport {
   $filename++;
   my $ed_filename = $export_path . $filename;
   push(@filenames, $filename);
-  open(ED, "> $ed_filename") or die "can't open outputfile: $!\n";
+  open(ED, ">", $ed_filename) or die "can't open outputfile: $!\n";
   my $header = &make_kne_data_header($myconfig, $form, "");
   $remaining_bytes -= length($header);
 
@@ -982,7 +994,7 @@ sub kne_stammdatenexport {
   my $ev_header = &make_ev_header($form, $fileno);
   my $ev_filename = $export_path . $evfile;
   push(@filenames, $evfile);
-  open(EV, "> $ev_filename") or die "can't open outputfile: EV01\n";
+  open(EV, ">", $ev_filename) or die "can't open outputfile: EV01\n";
   print(EV $ev_header);
 
   foreach my $file (@ed_versionset) {