Kunden/Lieferanten: UStId/Steuernr. eindeutig: Prüfung im Controller
[kivitendo-erp.git] / t / controllers / csvimport / artransactions.t
index dd0a8f1..6c902c3 100644 (file)
@@ -26,11 +26,16 @@ use SL::DB::Chart;
 use SL::DB::AccTransaction;
 
 my ($customer, $currency_id, $employee, $taxzone, $project, $department);
+my ($transdate, $transdate_string);
 
 sub reset_state {
   # Create test data
   my %params = @_;
 
+  $transdate = DateTime->today_local;
+  $transdate->set_year(2019) if $transdate->year == 2020; # hardcode for 2019 in 2020, because of tax rate change in Germany
+  $transdate_string = $transdate->to_kivitendo;
+
   $params{$_} ||= {} for qw(buchungsgruppe customer tax);
 
   clear_up();
@@ -65,7 +70,16 @@ reset_state(customer => {id => 960, customernumber => 2});
 sub test_import {
   my $file = shift;
 
-  my $controller = SL::Controller::CsvImport->new();
+  my $controller = SL::Controller::CsvImport->new(
+    type => 'ar_transactions'
+  );
+  $controller->load_default_profile;
+  $controller->profile->set(
+    charset      => 'utf-8',
+    sep_char     => ',',
+    quote_char   => '"',
+    numberformat => $::myconfig{numberformat},
+  );
 
   my $csv_artransactions_import = SL::Controller::CsvImport::ARTransaction->new(
     settings    => {'ar_column'          => 'Rechnung',
@@ -77,56 +91,7 @@ sub test_import {
   );
 
   # $csv_artransactions_import->init_vc_by;
-  $csv_artransactions_import->test_run(0);
-  $csv_artransactions_import->csv(SL::Helper::Csv->new(file                    => $csv_artransactions_import->file,
-                                                       profile                 => $csv_artransactions_import->profile,
-                                                       encoding                => 'utf-8',
-                                                       ignore_unknown_columns  => 1,
-                                                       strict_profile          => 1,
-                                                       case_insensitive_header => 1,
-                                                       sep_char                => ',',
-                                                       quote_char              => '"',
-                                                       ignore_unknown_columns  => 1,
-                                                     ));
-
-  $csv_artransactions_import->csv->parse;
-
-  $csv_artransactions_import->controller->errors([ $csv_artransactions_import->csv->errors ]) if $csv_artransactions_import->csv->errors;
-
-  return if ( !$csv_artransactions_import->csv->header || $csv_artransactions_import->csv->errors );
-
-  my $headers;
-  my $i = 0;
-  foreach my $header (@{ $csv_artransactions_import->csv->header }) {
-
-    my $profile   = $csv_artransactions_import->csv->profile->[$i]->{profile};
-    my $row_ident = $csv_artransactions_import->csv->profile->[$i]->{row_ident};
-
-    my $h = { headers => [ grep { $profile->{$_} } @{ $header } ] };
-    $h->{methods} = [ map { $profile->{$_} } @{ $h->{headers} } ];
-    $h->{used}    = { map { ($_ => 1) }      @{ $h->{headers} } };
-
-    $headers->{$row_ident} = $h;
-    $i++;
-  }
-
-  $csv_artransactions_import->controller->headers($headers);
-
-  my $raw_data_headers;
-  my $info_headers;
-  foreach my $p (@{ $csv_artransactions_import->csv->profile }) {
-    my $ident = $p->{row_ident};
-    $raw_data_headers->{$ident} = { used => { }, headers => [ ] };
-    $info_headers->{$ident}     = { used => { }, headers => [ ] };
-  }
-  $csv_artransactions_import->controller->raw_data_headers($raw_data_headers);
-  $csv_artransactions_import->controller->info_headers($info_headers);
-
-  my $objects  = $csv_artransactions_import->csv->get_objects;
-  my @raw_data = @{ $csv_artransactions_import->csv->get_data };
-
-  $csv_artransactions_import->controller->data([ pairwise { no warnings 'once'; { object => $a, raw_data => $b, errors => [], information => [], info_data => {} } } @$objects, @raw_data ]);
-  $csv_artransactions_import->check_objects;
+  $csv_artransactions_import->run(test => 0);
 
   # don't try and save objects that have errors
   $csv_artransactions_import->save_objects unless scalar @{$csv_artransactions_import->controller->data->[0]->{errors}};
@@ -136,6 +101,7 @@ sub test_import {
 
 ##### manually create an ar transaction from scratch, testing the methods
 $::myconfig{numberformat} = '1000.00';
+$::myconfig{dateformat}   = 'dd.mm.yyyy';
 my $old_locale = $::locale;
 # set locale to en so we can match errors
 $::locale = Locale->new('en');
@@ -149,7 +115,7 @@ my $ar = SL::DB::Invoice->new(
   currency_id  => $currency_id,
   taxincluded  => 'f',
   customer_id  => $customer->id,
-  transdate    => DateTime->today,
+  transdate    => $transdate,
   employee_id  => SL::DB::Manager::Employee->current->id,
   transactions => [],
 );
@@ -178,7 +144,7 @@ is scalar @{$ar->transactions}, 3, 'manual invoice has 3 acc_trans entries';
 
 $ar->pay_invoice(  chart_id      => SL::DB::Manager::Chart->find_by(accno => '1200')->id, # bank
                    amount        => $ar->open_amount,
-                   transdate     => DateTime->now->to_kivitendo,
+                   transdate     => $transdate,
                    payment_type  => 'without_skonto',  # default if not specified
                   );
 $result = $ar->validate_acc_trans(debug => 0);
@@ -192,10 +158,10 @@ my ($entries, $entry, $file);
 # to debug errors in certain tests, run after test_import:
 #   die Dumper($entry->{errors});
 ##### basic test
-$file = \<<EOL;
-datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart
+$file = \<<"EOL";
+datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart,transdate
 datatype,accno,amount,taxkey
-"Rechnung",960,4,1,"invoice 1",f,1400
+"Rechnung",960,4,1,"invoice 1",f,1400,"$transdate_string"
 "AccTransaction",8400,159.48,3
 EOL
 $entries = test_import($file);
@@ -212,10 +178,10 @@ is $entry->{object}->amount, '189.78', 'ar amount tax not included is 189.78';
 is $entry->{object}->netamount, '159.48', 'ar netamount tax not included is 159.48';
 
 ##### test for duplicate invnumber
-$file = \<<EOL;
-datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart
+$file = \<<"EOL";
+datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart,transdate
 datatype,accno,amount,taxkey
-"Rechnung",960,4,1,"invoice 1",f,1400
+"Rechnung",960,4,1,"invoice 1",f,1400,"$transdate_string"
 "AccTransaction",8400,159.48,3
 EOL
 $entries = test_import($file);
@@ -224,10 +190,10 @@ $entry->{object}->validate_acc_trans;
 is $entry->{errors}->[0], 'Error: invnumber already exists', 'detects verify_amount differences';
 
 ##### test for no invnumber given
-$file = \<<EOL;
-datatype,customer_id,taxzone_id,currency_id,taxincluded,archart
+$file = \<<"EOL";
+datatype,customer_id,taxzone_id,currency_id,taxincluded,archart,transdate
 datatype,accno,amount,taxkey
-"Rechnung",960,4,1,f,1400
+"Rechnung",960,4,1,f,1400,"$transdate_string"
 "AccTransaction",8400,159.48,3
 EOL
 $entries = test_import($file);
@@ -236,10 +202,10 @@ $entry->{object}->validate_acc_trans;
 is $entry->{object}->invnumber =~ /^\d+$/, 1, 'invnumber assigned automatically';
 
 ##### basic test without amounts in Rechnung, only specified in AccTransaction
-$file = \<<EOL;
-datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart
+$file = \<<"EOL";
+datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart,transdate
 datatype,accno,amount,taxkey
-"Rechnung",960,4,1,"invoice 1 no amounts",f,1400
+"Rechnung",960,4,1,"invoice 1 no amounts",f,1400,"$transdate_string"
 "AccTransaction",8400,159.48,3
 EOL
 $entries = test_import($file);
@@ -254,10 +220,10 @@ is $::form->round_amount($entry->{object}->transactions->[0]->amount, 2), '159.4
 is $::form->round_amount($entry->{object}->transactions->[0]->amount, 2), 159.48, 'invoice 1 ar amount is 159.48';
 
 ##### basic test: credit_note
-$file = \<<EOL;
-datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart
+$file = \<<"EOL";
+datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart,transdate
 datatype,accno,amount,taxkey
-"Rechnung",960,4,1,"credit note",f,1400
+"Rechnung",960,4,1,"credit note",f,1400,"$transdate_string"
 "AccTransaction",8400,-159.48,3
 EOL
 $entries = test_import($file);
@@ -273,10 +239,10 @@ is $entry->{object}->amount, '-189.78', 'credit note amount tax not included is
 is $entry->{object}->netamount, '-159.48', 'credit note netamount tax not included is 159.48';
 
 #### verify_amount differs: max_amount_diff = 0.02, 189.80 is ok, 189.81 is not
-$file = \<<EOL;
-datatype,customer_id,verify_amount,verify_netamount,taxzone_id,currency_id,invnumber,taxincluded,archart
+$file = \<<"EOL";
+datatype,customer_id,verify_amount,verify_netamount,taxzone_id,currency_id,invnumber,taxincluded,archart,transdate
 datatype,accno,amount,taxkey
-"Rechnung",960,189.81,159.48,4,1,"invoice amounts differing",f,1400
+"Rechnung",960,189.81,159.48,4,1,"invoice amounts differing",f,1400,"$transdate_string"
 "AccTransaction",8400,159.48,3
 EOL
 $entries = test_import($file);
@@ -284,10 +250,10 @@ $entry = $entries->[0];
 is $entry->{errors}->[0], 'Amounts differ too much', 'detects verify_amount differences';
 
 #####  direct debit
-$file = \<<EOL;
-datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,direct_debit,archart
+$file = \<<"EOL";
+datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,direct_debit,archart,transdate
 datatype,accno,amount,taxkey
-"Rechnung",960,4,1,"invoice with direct debit",f,t,1400
+"Rechnung",960,4,1,"invoice with direct debit",f,t,1400,"$transdate_string"
 "AccTransaction",8400,159.48,3
 EOL
 
@@ -297,10 +263,10 @@ $entry->{object}->validate_acc_trans;
 is $entry->{object}->direct_debit, '1', 'direct debit';
 
 #### tax included
-$file = \<<EOL;
-datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart
+$file = \<<"EOL";
+datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart,transdate
 datatype,accno,amount,taxkey
-"Rechnung",960,4,1,"invoice 1 tax included no amounts",t,1400
+"Rechnung",960,4,1,"invoice 1 tax included no amounts",t,1400,"$transdate_string"
 "AccTransaction",8400,189.78,3
 EOL
 
@@ -313,10 +279,10 @@ is $::form->round_amount($entry->{object}->netamount, 2), '159.48', 'taxincluded
 is $::form->round_amount($entry->{object}->transactions->[0]->amount, 2), '159.48', 'taxincluded acc_trans netamount';
 
 #### multiple tax included
-$file = \<<EOL;
-datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart
+$file = \<<"EOL";
+datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart,transdate
 datatype,accno,amount,taxkey
-"Rechnung",960,4,1,"invoice multiple tax included",t,1400
+"Rechnung",960,4,1,"invoice multiple tax included",t,1400,"$transdate_string"
 "AccTransaction",8400,94.89,3
 "AccTransaction",8400,94.89,3
 EOL