1 use Test::More tests => 70;
 
   9 use Support::TestSetup;
 
  12 use List::MoreUtils qw(pairwise);
 
  13 use SL::Controller::CsvImport;
 
  17 use_ok 'SL::Controller::CsvImport::ARTransaction';
 
  19 use SL::DB::Buchungsgruppe;
 
  26 use SL::DB::AccTransaction;
 
  28 my ($customer, $currency_id, $employee, $taxzone, $project, $department);
 
  34   $params{$_} ||= {} for qw(buchungsgruppe customer tax);
 
  37   $employee        = SL::DB::Manager::Employee->current                          || croak "No employee";
 
  38   $taxzone         = SL::DB::Manager::TaxZone->find_by( description => 'Inland') || croak "No taxzone";
 
  39   $currency_id     = $::instance_conf->get_currency_id;
 
  41   $customer     = SL::DB::Customer->new(
 
  42     name        => 'Test Customer',
 
  43     currency_id => $currency_id,
 
  44     taxzone_id  => $taxzone->id,
 
  45     %{ $params{customer} }
 
  48   $project     = SL::DB::Project->new(
 
  49     projectnumber  => 'P1',
 
  50     description    => 'Project X',
 
  51     project_type   => SL::DB::Manager::ProjectType->find_by(description => 'Standard'),
 
  52     project_status => SL::DB::Manager::ProjectStatus->find_by(name => 'running'),
 
  55   $department     = SL::DB::Department->new(
 
  56     description    => 'Department 1',
 
  60 Support::TestSetup::login();
 
  62 reset_state(customer => {id => 960, customernumber => 2});
 
  68   my $controller = SL::Controller::CsvImport->new();
 
  70   my $csv_artransactions_import = SL::Controller::CsvImport::ARTransaction->new(
 
  71     settings    => {'ar_column'          => 'Rechnung',
 
  72                     'transaction_column' => 'AccTransaction',
 
  73                     'max_amount_diff'    => 0.02
 
  75     controller => $controller,
 
  79   # $csv_artransactions_import->init_vc_by;
 
  80   $csv_artransactions_import->test_run(0);
 
  81   $csv_artransactions_import->csv(SL::Helper::Csv->new(file                    => $csv_artransactions_import->file,
 
  82                                                        profile                 => $csv_artransactions_import->profile,
 
  84                                                        ignore_unknown_columns  => 1,
 
  86                                                        case_insensitive_header => 1,
 
  89                                                        ignore_unknown_columns  => 1,
 
  92   $csv_artransactions_import->csv->parse;
 
  94   $csv_artransactions_import->controller->errors([ $csv_artransactions_import->csv->errors ]) if $csv_artransactions_import->csv->errors;
 
  96   return if ( !$csv_artransactions_import->csv->header || $csv_artransactions_import->csv->errors );
 
 100   foreach my $header (@{ $csv_artransactions_import->csv->header }) {
 
 102     my $profile   = $csv_artransactions_import->csv->profile->[$i]->{profile};
 
 103     my $row_ident = $csv_artransactions_import->csv->profile->[$i]->{row_ident};
 
 105     my $h = { headers => [ grep { $profile->{$_} } @{ $header } ] };
 
 106     $h->{methods} = [ map { $profile->{$_} } @{ $h->{headers} } ];
 
 107     $h->{used}    = { map { ($_ => 1) }      @{ $h->{headers} } };
 
 109     $headers->{$row_ident} = $h;
 
 113   $csv_artransactions_import->controller->headers($headers);
 
 115   my $raw_data_headers;
 
 117   foreach my $p (@{ $csv_artransactions_import->csv->profile }) {
 
 118     my $ident = $p->{row_ident};
 
 119     $raw_data_headers->{$ident} = { used => { }, headers => [ ] };
 
 120     $info_headers->{$ident}     = { used => { }, headers => [ ] };
 
 122   $csv_artransactions_import->controller->raw_data_headers($raw_data_headers);
 
 123   $csv_artransactions_import->controller->info_headers($info_headers);
 
 125   my $objects  = $csv_artransactions_import->csv->get_objects;
 
 126   my @raw_data = @{ $csv_artransactions_import->csv->get_data };
 
 128   $csv_artransactions_import->controller->data([ pairwise { no warnings 'once'; { object => $a, raw_data => $b, errors => [], information => [], info_data => {} } } @$objects, @raw_data ]);
 
 129   $csv_artransactions_import->check_objects;
 
 131   # don't try and save objects that have errors
 
 132   $csv_artransactions_import->save_objects unless scalar @{$csv_artransactions_import->controller->data->[0]->{errors}};
 
 134  return $csv_artransactions_import->controller->data;
 
 137 ##### manually create an ar transaction from scratch, testing the methods
 
 138 $::myconfig{numberformat} = '1000.00';
 
 139 my $old_locale = $::locale;
 
 140 # set locale to en so we can match errors
 
 141 $::locale = Locale->new('en');
 
 145 my $ar = SL::DB::Invoice->new(
 
 147   invnumber    => 'manual invoice',
 
 148   taxzone_id   => $taxzone->id,
 
 149   currency_id  => $currency_id,
 
 151   customer_id  => $customer->id,
 
 152   transdate    => DateTime->today,
 
 153   employee_id  => SL::DB::Manager::Employee->current->id,
 
 157 my $tax3 = SL::DB::Manager::Tax->find_by(rate => 0.19, taxkey => 3) || die "can't find tax with taxkey 3";
 
 158 my $income_chart = SL::DB::Manager::Chart->find_by(accno => '8400') || die "can't find income chart";
 
 160 $ar->add_ar_amount_row(
 
 162   chart  => $income_chart,
 
 166 $ar->recalculate_amounts; # set amount and netamount from transactions
 
 167 is $ar->amount, '10', 'amount of manual invoice is 10';
 
 168 is $ar->netamount, '8.4', 'netamount of manual invoice is 10';
 
 170 $ar->create_ar_row( chart => SL::DB::Manager::Chart->find_by(accno => '1400', link => 'AR') );
 
 171 my $result = $ar->validate_acc_trans(debug => 0);
 
 172 is $result, 1, 'manual $ar validates';
 
 175 is ${ $ar->transactions }[0]->chart->accno, '8400', 'assigned income chart after save ok';
 
 176 is ${ $ar->transactions }[2]->chart->accno, '1400', 'assigned receivable chart after save ok';
 
 177 is scalar @{$ar->transactions}, 3, 'manual invoice has 3 acc_trans entries';
 
 179 $ar->pay_invoice(  chart_id      => SL::DB::Manager::Chart->find_by(accno => '1200')->id, # bank
 
 180                    amount        => $ar->open_amount,
 
 181                    transdate     => DateTime->now->to_kivitendo,
 
 182                    payment_type  => 'without_skonto',  # default if not specified
 
 184 $result = $ar->validate_acc_trans(debug => 0);
 
 185 is $result, 1, 'manual invoice validates after payment';
 
 187 reset_state(customer => {id => 960, customernumber => 2});
 
 189 my ($entries, $entry, $file);
 
 191 # starting test of csv imports
 
 192 # to debug errors in certain tests, run after test_import:
 
 193 #   die Dumper($entry->{errors});
 
 196 datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart
 
 197 datatype,accno,amount,taxkey
 
 198 "Rechnung",960,4,1,"invoice 1",f,1400
 
 199 "AccTransaction",8400,159.48,3
 
 201 $entries = test_import($file);
 
 202 $entry = $entries->[0];
 
 203 $entry->{object}->validate_acc_trans;
 
 205 is $entry->{object}->invnumber, 'invoice 1', 'simple invnumber ok (customer)';
 
 206 is $entry->{object}->customer_id, '960', 'simple customer_id ok (customer)';
 
 207 is scalar @{$entry->{object}->transactions}, 3, 'invoice 1 has 3 acc_trans entries';
 
 208 is $::form->round_amount($entry->{object}->transactions->[0]->amount, 2), 159.48, 'invoice 1 ar amount is 159.48';
 
 209 is $entry->{object}->direct_debit, '0', 'no direct debit';
 
 210 is $entry->{object}->taxincluded, '0', 'taxincluded is false';
 
 211 is $entry->{object}->amount, '189.78', 'ar amount tax not included is 189.78';
 
 212 is $entry->{object}->netamount, '159.48', 'ar netamount tax not included is 159.48';
 
 214 ##### test for duplicate invnumber
 
 216 datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart
 
 217 datatype,accno,amount,taxkey
 
 218 "Rechnung",960,4,1,"invoice 1",f,1400
 
 219 "AccTransaction",8400,159.48,3
 
 221 $entries = test_import($file);
 
 222 $entry = $entries->[0];
 
 223 $entry->{object}->validate_acc_trans;
 
 224 is $entry->{errors}->[0], 'Error: invnumber already exists', 'detects verify_amount differences';
 
 226 ##### test for no invnumber given
 
 228 datatype,customer_id,taxzone_id,currency_id,taxincluded,archart
 
 229 datatype,accno,amount,taxkey
 
 230 "Rechnung",960,4,1,f,1400
 
 231 "AccTransaction",8400,159.48,3
 
 233 $entries = test_import($file);
 
 234 $entry = $entries->[0];
 
 235 $entry->{object}->validate_acc_trans;
 
 236 is $entry->{object}->invnumber =~ /^\d+$/, 1, 'invnumber assigned automatically';
 
 238 ##### basic test without amounts in Rechnung, only specified in AccTransaction
 
 240 datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart
 
 241 datatype,accno,amount,taxkey
 
 242 "Rechnung",960,4,1,"invoice 1 no amounts",f,1400
 
 243 "AccTransaction",8400,159.48,3
 
 245 $entries = test_import($file);
 
 246 $entry = $entries->[0];
 
 247 $entry->{object}->validate_acc_trans;
 
 249 is $entry->{object}->invnumber, 'invoice 1 no amounts', 'simple invnumber ok (customer)';
 
 250 is $entry->{object}->customer_id, '960', 'simple customer_id ok (customer)';
 
 251 is scalar @{$entry->{object}->transactions}, 3, 'invoice 1 has 3 acc_trans entries';
 
 252 is $::form->round_amount($entry->{object}->amount, 2), '189.78', 'not taxincluded ar amount';
 
 253 is $::form->round_amount($entry->{object}->transactions->[0]->amount, 2), '159.48', 'not taxincluded acc_trans netamount';
 
 254 is $::form->round_amount($entry->{object}->transactions->[0]->amount, 2), 159.48, 'invoice 1 ar amount is 159.48';
 
 256 ##### basic test: credit_note
 
 258 datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart
 
 259 datatype,accno,amount,taxkey
 
 260 "Rechnung",960,4,1,"credit note",f,1400
 
 261 "AccTransaction",8400,-159.48,3
 
 263 $entries = test_import($file);
 
 264 $entry = $entries->[0];
 
 265 $entry->{object}->validate_acc_trans;
 
 267 is $entry->{object}->invnumber, 'credit note', 'simple credit note ok';
 
 268 is scalar @{$entry->{object}->transactions}, 3, 'credit note has 3 acc_trans entries';
 
 269 is $::form->round_amount($entry->{object}->amount, 2), '-189.78', 'taxincluded ar amount';
 
 270 is $::form->round_amount($entry->{object}->netamount, 2), '-159.48', 'taxincluded ar net amount';
 
 271 is $::form->round_amount($entry->{object}->transactions->[0]->amount, 2), -159.48, 'credit note ar amount is -159.48';
 
 272 is $entry->{object}->amount, '-189.78', 'credit note amount tax not included is 189.78';
 
 273 is $entry->{object}->netamount, '-159.48', 'credit note netamount tax not included is 159.48';
 
 275 #### verify_amount differs: max_amount_diff = 0.02, 189.80 is ok, 189.81 is not
 
 277 datatype,customer_id,verify_amount,verify_netamount,taxzone_id,currency_id,invnumber,taxincluded,archart
 
 278 datatype,accno,amount,taxkey
 
 279 "Rechnung",960,189.81,159.48,4,1,"invoice amounts differing",f,1400
 
 280 "AccTransaction",8400,159.48,3
 
 282 $entries = test_import($file);
 
 283 $entry = $entries->[0];
 
 284 is $entry->{errors}->[0], 'Amounts differ too much', 'detects verify_amount differences';
 
 288 datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,direct_debit,archart
 
 289 datatype,accno,amount,taxkey
 
 290 "Rechnung",960,4,1,"invoice with direct debit",f,t,1400
 
 291 "AccTransaction",8400,159.48,3
 
 294 $entries = test_import($file);
 
 295 $entry = $entries->[0];
 
 296 $entry->{object}->validate_acc_trans;
 
 297 is $entry->{object}->direct_debit, '1', 'direct debit';
 
 301 datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart
 
 302 datatype,accno,amount,taxkey
 
 303 "Rechnung",960,4,1,"invoice 1 tax included no amounts",t,1400
 
 304 "AccTransaction",8400,189.78,3
 
 307 $entries = test_import($file);
 
 308 $entry = $entries->[0];
 
 309 $entry->{object}->validate_acc_trans(debug => 0);
 
 310 is $entry->{object}->taxincluded, '1', 'taxincluded is true';
 
 311 is $::form->round_amount($entry->{object}->amount, 2), '189.78', 'taxincluded ar amount';
 
 312 is $::form->round_amount($entry->{object}->netamount, 2), '159.48', 'taxincluded ar net amount';
 
 313 is $::form->round_amount($entry->{object}->transactions->[0]->amount, 2), '159.48', 'taxincluded acc_trans netamount';
 
 315 #### multiple tax included
 
 317 datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart
 
 318 datatype,accno,amount,taxkey
 
 319 "Rechnung",960,4,1,"invoice multiple tax included",t,1400
 
 320 "AccTransaction",8400,94.89,3
 
 321 "AccTransaction",8400,94.89,3
 
 324 $entries = test_import($file);
 
 325 $entry = $entries->[0];
 
 326 $entry->{object}->validate_acc_trans;
 
 327 is $::form->round_amount($entry->{object}->amount, 2),    '189.78', 'taxincluded ar amount';
 
 328 is $::form->round_amount($entry->{object}->netamount, 2), '159.48', 'taxincluded ar netamount';
 
 329 is $::form->round_amount($entry->{object}->transactions->[0]->amount, 2), '79.74', 'taxincluded amount';
 
 330 is $::form->round_amount($entry->{object}->transactions->[1]->amount, 2), '15.15', 'taxincluded tax';
 
 332 # different receivables chart
 
 334 datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart
 
 335 datatype,accno,amount,taxkey
 
 336 "Rechnung",960,4,1,"invoice mit archart 1448",f,1448
 
 337 "AccTransaction",8400,159.48,3
 
 339 $entries = test_import($file);
 
 340 $entry = $entries->[0];
 
 341 $entry->{object}->validate_acc_trans;
 
 342 is $entry->{object}->transactions->[2]->chart->accno, '1448', 'archart set to 1448';
 
 346 datatype,taxzone_id,currency_id,invnumber,taxincluded,archart
 
 347 datatype,accno,amount,taxkey
 
 348 "Rechnung",4,1,"invoice missing customer",f,1400
 
 349 "AccTransaction",8400,159.48,3
 
 351 $entries = test_import($file);
 
 352 $entry = $entries->[0];
 
 353 is $entry->{errors}->[0], 'Error: Customer/vendor missing', 'detects missing customer or vendor';
 
 356 ##### customer by name
 
 358 datatype,customer,taxzone_id,currency_id,invnumber,taxincluded,archart
 
 359 datatype,accno,amount,taxkey
 
 360 "Rechnung","Test Customer",4,1,"invoice customer name",f,1400
 
 361 "AccTransaction",8400,159.48,3
 
 363 $entries = test_import($file);
 
 364 $entry = $entries->[0];
 
 365 $entry->{object}->validate_acc_trans;
 
 366 is $entry->{object}->customer->name, "Test Customer", 'detects customer by name';
 
 368 ##### detect missing chart
 
 370 datatype,taxzone_id,currency_id,invnumber,customer,archart
 
 371 datatype,amount,taxkey
 
 372 "Rechnung",4,1,"invoice missing chart","Test Customer",1400
 
 375 $entries = test_import($file);
 
 376 $entry = $entries->[1];
 
 377 is $entry->{errors}->[0], 'Error: chart missing', 'detects missing chart (chart_id or accno)';
 
 379 ##### detect illegal chart by accno
 
 381 datatype,taxzone_id,currency_id,invnumber,customer,archart
 
 382 datatype,accno,amount,taxkey
 
 383 "Rechnung",4,1,"invoice illegal chart accno","Test Customer",1400
 
 384 "AccTransaction",9999,4,3
 
 386 $entries = test_import($file);
 
 387 $entry = $entries->[1];
 
 388 is $entry->{errors}->[0], 'Error: invalid chart (accno)', 'detects invalid chart (chart_id or accno)';
 
 390 # ##### detect illegal archart
 
 392 datatype,taxzone_id,currency_id,invnumber,customer,taxincluded,archart
 
 393 datatype,accno,amount,taxkey
 
 394 "Rechnung",4,1,"invoice illegal archart","Test Customer",f,11400
 
 395 "AccTransaction",8400,159.48,3
 
 397 $entries = test_import($file);
 
 398 $entry = $entries->[0];
 
 399 is $entry->{errors}->[0], "Error: can't find ar chart with accno 11400", 'detects illegal receivables chart (archart)';
 
 401 ##### detect chart by id
 
 403 datatype,taxzone_id,currency_id,invnumber,customer,taxincluded,archart
 
 404 datatype,amount,chart_id,taxkey
 
 405 "Rechnung",4,1,"invoice chart_id","Test Customer",f,1400
 
 406 "AccTransaction",159.48,184,3
 
 408 $entries = test_import($file);
 
 409 $entry = $entries->[1]; # acc_trans entry is at entry array pos 1
 
 410 $entries->[0]->{object}->validate_acc_trans;
 
 411 is $entry->{object}->chart->id, "184", 'detects chart by id';
 
 413 ##### detect chart by accno
 
 415 datatype,taxzone_id,currency_id,invnumber,customer,taxincluded,archart
 
 416 datatype,amount,accno,taxkey
 
 417 "Rechnung",4,1,"invoice by chart accno","Test Customer",f,1400
 
 418 "AccTransaction",159.48,8400,3
 
 420 $entries = test_import($file);
 
 421 $entry = $entries->[1];
 
 422 $entries->[0]->{object}->validate_acc_trans;
 
 423 is $entry->{object}->chart->accno, "8400", 'detects chart by accno';
 
 425 ##### detect chart isn't an ar_chart
 
 427 datatype,taxzone_id,currency_id,invnumber,customer,taxincluded,archart
 
 428 datatype,amount,accno,taxkey
 
 429 "Rechnung",4,1,"invoice by chart accno","Test Customer",f,1400
 
 430 "AccTransaction",159.48,1400,3
 
 432 $entries = test_import($file);
 
 433 $entry = $entries->[1];
 
 434 $entries->[0]->{object}->validate_acc_trans;
 
 435 is $entry->{errors}->[0], 'Error: chart isn\'t an ar_amount chart', 'detects valid chart that is not an ar_amount chart';
 
 439 datatype,taxzone_id,currency_id,invnumber,customer,archart
 
 440 datatype,amount,accno
 
 441 "Rechnung",4,1,"invoice missing taxkey chart accno","Test Customer",1400
 
 442 "AccTransaction",159.48,8400
 
 444 $entries = test_import($file);
 
 445 $entry = $entries->[1];
 
 446 is $entry->{errors}->[0], 'Error: taxkey missing', 'detects missing taxkey (DATEV Steuerschlüssel)';
 
 450 datatype,taxzone_id,currency_id,invnumber,customer,archart
 
 451 datatype,amount,accno,taxkey
 
 452 "Rechnung",4,1,"invoice illegal taxkey","Test Customer",1400
 
 453 "AccTransaction",4,8400,123
 
 455 $entries = test_import($file);
 
 456 $entry = $entries->[1];
 
 457 is $entry->{errors}->[0], 'Error: invalid taxkey', 'detects invalid taxkey (DATEV Steuerschlüssel)';
 
 461 datatype,customer_id,taxzone_id,currency_id,invnumber,archart
 
 462 datatype,accno,amount,taxkey
 
 463 "Rechnung",960,4,1,"invoice by taxkey",1400
 
 464 "AccTransaction",8400,4,3
 
 467 $entries = test_import($file);
 
 468 $entry = $entries->[1];
 
 469 is $entry->{object}->taxkey, 3, 'detects taxkey';
 
 473 datatype,customer_id,taxzone_id,currency_id,invnumber,archart,taxincluded
 
 474 datatype,accno,amount,taxkey,projectnumber
 
 475 "Rechnung",960,4,1,"invoice with acc_trans project",1400,f
 
 476 "AccTransaction",8400,159.48,3,P1
 
 479 $entries = test_import($file);
 
 480 $entry = $entries->[1];
 
 481 # die Dumper($entries->[0]->{errors}) if scalar @{$entries->[0]->{errors}};
 
 482 is $entry->{object}->project->projectnumber, 'P1', 'detects acc_trans project';
 
 486 datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart,transdate,duedate,globalprojectnumber,department
 
 487 datatype,accno,amount,taxkey,projectnumber
 
 488 "Rechnung",960,4,1,"invoice various",t,1400,21.04.2016,30.04.2016,P1,Department 1
 
 489 "AccTransaction",8400,119,3,P1
 
 490 "AccTransaction",8300,107,2,P1
 
 491 "AccTransaction",8200,100,0,P1
 
 494 $entries = test_import($file);
 
 495 $entry = $entries->[0];
 
 496 $entry->{object}->validate_acc_trans;
 
 497 is $entry->{object}->duedate->to_kivitendo,      '30.04.2016',    'duedate';
 
 498 is $entry->{object}->transdate->to_kivitendo,    '21.04.2016',    'transdate';
 
 499 is $entry->{object}->globalproject->description, 'Project X',     'project';
 
 500 is $entry->{object}->department->description,    'Department 1',  'department';
 
 501 # 8300 is third entry after 8400 and tax for 8400
 
 502 is $::form->round_amount($entry->{object}->transactions->[2]->amount),     '100',        '8300 net amount: 100';
 
 503 is $::form->round_amount($entry->{object}->transactions->[2]->taxkey),     '2',          '8300 has taxkey 2';
 
 504 is $::form->round_amount($entry->{object}->transactions->[2]->project_id), $project->id, 'AccTrans project';
 
 508 datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart,transdate,duedate,globalprojectnumber,department
 
 509 datatype,accno,amount,taxkey,projectnumber
 
 510 "Rechnung",960,4,1,"invoice various 1",t,1400,21.04.2016,30.04.2016,P1,Department 1
 
 511 "AccTransaction",8400,119,3,P1
 
 512 "AccTransaction",8300,107,2,P1
 
 513 "AccTransaction",8200,100,0,P1
 
 514 "Rechnung",960,4,1,"invoice various 2",t,1400,21.04.2016,30.04.2016,P1,Department 1
 
 515 "AccTransaction",8400,119,3,P1
 
 516 "AccTransaction",8300,107,2,P1
 
 517 "AccTransaction",8200,100,0,P1
 
 520 $entries = test_import($file);
 
 521 $entry = $entries->[0];
 
 522 $entry->{object}->validate_acc_trans;
 
 523 is $entry->{object}->duedate->to_kivitendo,      '30.04.2016',    'duedate';
 
 524 is $entry->{info_data}->{amount}, '326', "First invoice amount displayed in info data";
 
 525 is $entries->[4]->{info_data}->{amount}, '326', "Second invoice amount displayed in info data";
 
 527 # multiple entries, taxincluded = f
 
 529 datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart
 
 530 datatype,accno,amount,taxkey
 
 531 "Rechnung",960,4,1,"invoice 4 acc_trans",f,1400
 
 532 "AccTransaction",8400,39.87,3
 
 533 "AccTransaction",8400,39.87,3
 
 534 "AccTransaction",8400,39.87,3
 
 535 "AccTransaction",8400,39.87,3
 
 536 "Rechnung",960,4,1,"invoice 4 acc_trans 2",f,1400
 
 537 "AccTransaction",8400,39.87,3
 
 538 "AccTransaction",8400,39.87,3
 
 539 "AccTransaction",8400,39.87,3
 
 540 "AccTransaction",8400,39.87,3
 
 541 "Rechnung",960,4,1,"invoice 4 acc_trans 3",f,1400
 
 542 "AccTransaction",8400,39.87,3
 
 543 "AccTransaction",8400,39.87,3
 
 544 "AccTransaction",8400,39.87,3
 
 545 "AccTransaction",8400,39.87,3
 
 546 "Rechnung",960,4,1,"invoice 4 acc_trans 4",f,1448
 
 547 "AccTransaction",8400,39.87,3
 
 548 "AccTransaction",8400,39.87,3
 
 549 "AccTransaction",8400,39.87,3
 
 550 "AccTransaction",8400,39.87,3
 
 552 $entries = test_import($file);
 
 555 foreach my $entry ( @$entries ) {
 
 556   next unless $entry->{object}->isa('SL::DB::Invoice');
 
 558   is scalar @{$entry->{object}->transactions}, 9, "invoice $i: 'invoice 4 acc_trans' has 9 acc_trans entries";
 
 559   $entry->{object}->validate_acc_trans;
 
 562 ##### missing acc_trans
 
 564 datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart,transdate,duedate,globalprojectnumber,department
 
 565 datatype,accno,amount,taxkey,projectnumber
 
 566 "Rechnung",960,4,1,"invoice acc_trans missing",t,1400,21.04.2016,30.04.2016,P1,Department 1
 
 567 "Rechnung",960,4,1,"invoice various a",t,1400,21.04.2016,30.04.2016,P1,Department 1
 
 568 "AccTransaction",8400,119,3,P1
 
 569 "AccTransaction",8300,107,2,P1
 
 572 $entries = test_import($file);
 
 573 $entry = $entries->[0];
 
 574 is $entry->{errors}->[0], "Error: ar transaction doesn't validate", 'detects invalid ar, maybe acc_trans entry missing';
 
 576 my $number_of_imported_invoices = SL::DB::Manager::Invoice->get_all_count;
 
 577 is $number_of_imported_invoices, 19, 'All invoices saved';
 
 579 #### taxkey differs from active_taxkey
 
 581 datatype,customer_id,taxzone_id,currency_id,invnumber,taxincluded,archart
 
 582 datatype,accno,amount,taxkey
 
 583 "Rechnung",960,4,1,"invoice 1 tax included no amounts",t,1400
 
 584 "AccTransaction",8400,189.78,2
 
 587 $entries = test_import($file);
 
 588 $entry = $entries->[0];
 
 589 $entry->{object}->validate_acc_trans(debug => 0);
 
 591 clear_up(); # remove all data at end of tests
 
 596   SL::DB::Manager::AccTransaction->delete_all(all => 1);
 
 597   SL::DB::Manager::Invoice->delete_all       (all => 1);
 
 598   SL::DB::Manager::Customer->delete_all      (all => 1);
 
 599   SL::DB::Manager::Project->delete_all       (all => 1);
 
 600   SL::DB::Manager::Department->delete_all    (all => 1);
 
 608 # set emacs to perl mode