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();
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',
);
# $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}};
##### 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');
currency_id => $currency_id,
taxincluded => 'f',
customer_id => $customer->id,
- transdate => DateTime->today,
+ transdate => $transdate,
employee_id => SL::DB::Manager::Employee->current->id,
transactions => [],
);
$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);
# 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);
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);
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);
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);
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);
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);
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
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
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