8 use Support::TestSetup;
11 use SL::Dev::ALL qw(:ALL);
13 use SL::Controller::CsvImport;
15 use_ok 'SL::Controller::CsvImport::APTransaction';
17 use SL::DB::AccTransaction;
18 use SL::DB::Buchungsgruppe;
26 my ($vendor, $currency_id, $employee, $taxzone, $project, $department);
27 my ($transdate, $transdate_string);
30 SL::DB::Manager::AccTransaction->delete_all (all => 1);
31 SL::DB::Manager::PurchaseInvoice->delete_all(all => 1);
32 SL::DB::Manager::Vendor->delete_all (all => 1);
33 SL::DB::Manager::Project->delete_all (all => 1);
34 SL::DB::Manager::Department->delete_all (all => 1);
41 $transdate = DateTime->today_local;
42 $transdate->set_year(2019) if $transdate->year == 2020; # hardcode for 2019 in 2020, because of tax rate change in Germany
43 $transdate_string = $transdate->to_kivitendo;
45 $params{$_} ||= {} for qw(buchungsgruppe vendor tax);
48 $employee = SL::DB::Manager::Employee->current || croak "No employee";
49 $taxzone = SL::DB::Manager::TaxZone->find_by( description => 'Inland') || croak "No taxzone";
50 $currency_id = $::instance_conf->get_currency_id;
53 currency_id => $currency_id,
54 taxzone_id => $taxzone->id,
58 $project = SL::DB::Project->new(
59 projectnumber => 'P1',
60 description => 'Project X',
61 project_type => SL::DB::Manager::ProjectType->find_by(description => 'Standard'),
62 project_status => SL::DB::Manager::ProjectStatus->find_by(name => 'running'),
65 $department = SL::DB::Department->new(
66 description => 'Department 1',
70 Support::TestSetup::login();
72 reset_state(vendor => {vendornumber => 2});
78 my $controller = SL::Controller::CsvImport->new(
79 type => 'ap_transactions'
81 $controller->load_default_profile;
82 $controller->profile->set(
86 numberformat => $::myconfig{numberformat},
87 duplicates => 'check_db',
88 duplicates_vendor_and_invnumber => 1,
91 my $csv_aptransactions_import = SL::Controller::CsvImport::APTransaction->new(
92 settings => {'ap_column' => 'Rechnung',
93 'transaction_column' => 'AccTransaction',
94 'max_amount_diff' => 0.02
96 controller => $controller,
100 $csv_aptransactions_import->run(test => 0);
102 # don't try and save objects that have errors
103 $csv_aptransactions_import->save_objects unless scalar @{$csv_aptransactions_import->controller->data->[0]->{errors}};
105 return $csv_aptransactions_import->controller->data;
108 ##### manually create an ap transaction from scratch, testing the methods
109 $::myconfig{numberformat} = '1000.00';
110 $::myconfig{dateformat} = 'dd.mm.yyyy';
111 my $old_locale = $::locale;
112 # set locale to en so we can match errors
113 $::locale = Locale->new('en');
117 my $ap = SL::DB::PurchaseInvoice->new(
119 invnumber => 'manual invoice',
120 taxzone_id => $taxzone->id,
121 currency_id => $currency_id,
123 vendor_id => $vendor->id,
124 transdate => $transdate,
125 employee_id => SL::DB::Manager::Employee->current->id,
129 my $tax9 = SL::DB::Manager::Tax->find_by(rate => 0.19, taxkey => 9) || die "can't find tax with taxkey 9";
130 my $income_chart = SL::DB::Manager::Chart->find_by(accno => '3400') || die "can't find expense chart";
132 $ap->add_ap_amount_row(
134 chart => $income_chart,
138 $ap->recalculate_amounts; # set amount and netamount from transactions
139 is $ap->amount, '10', 'amount of manual invoice is 10';
140 is $ap->netamount, '8.4', 'netamount of manual invoice is 10';
142 $ap->create_ap_row( chart => SL::DB::Manager::Chart->find_by(accno => '1600', link => 'AP') );
143 my $result = $ap->validate_acc_trans();
144 is $result, 1, 'manual $ap validates';
147 is ${ $ap->transactions }[0]->chart->accno, '3400', 'assigned expense chart after save ok';
148 is ${ $ap->transactions }[2]->chart->accno, '1600', 'assigned payable chart after save ok';
149 is scalar @{$ap->transactions}, 3, 'manual invoice has 3 acc_trans entries';
151 $ap->pay_invoice( chart_id => SL::DB::Manager::Chart->find_by(accno => '1200')->id, # bank
152 amount => $ap->open_amount,
153 transdate => $transdate,
154 payment_type => 'without_skonto', # default if not specified
156 $result = $ap->validate_acc_trans();
157 is $result, 1, 'manual invoice validates after payment';
160 reset_state(vendor => {vendornumber => 2});
162 my ($entries, $entry, $file);
163 my $saved_invoices = 0;
165 # starting test of csv imports
166 # to debug errors in certain tests, run after test_import:
167 # $::lxdebug->dump(0, "entry 0 errors: ", $entry->{errors}->[0]);
170 datatype,vendornumber,currency_id,invnumber,taxincluded,apchart,transdate
171 datatype,accno,amount,taxkey
172 "Rechnung",2,1,"invoice 1",f,1600,"$transdate_string"
173 "AccTransaction",3400,159.48,9
175 $entries = test_import($file);
176 is $entries->[0]->{errors}->[0], undef, 'basic test: no errors in ap row';
177 is $entries->[1]->{errors}->[0], undef, 'basic test: no errors in acc_trans row';
179 $entry = $entries->[0];
180 is $entry->{object}->validate_acc_trans, 1, 'basic test: acc_trans validates';
181 is $entry->{object}->invnumber, 'invoice 1', 'basic test: invnumber ok';
182 is $entry->{object}->vendor_id, $vendor->id, 'basic test: vendor_id ok';
183 is scalar @{$entry->{object}->transactions}, 3, 'basic test: invoice 1 has 3 acc_trans entries';
184 is $::form->round_amount($entry->{object}->transactions->[0]->amount, 2), -159.48, 'basic test: invoice 1 ap amount is -159.48';
185 is $entry->{object}->direct_debit, '0', 'basic test: no direct debit';
186 is $entry->{object}->taxincluded, '0', 'basic test: taxincluded is false';
187 is $entry->{object}->amount, '189.78', 'basic test: ap amount tax not included is 189.78';
188 is $entry->{object}->netamount, '159.48', 'basic test: ap netamount tax not included is 159.48';
192 ##### test for duplicate invnumber for same vendor
194 datatype,vendornumber,currency_id,invnumber,taxincluded,apchart,transdate
195 datatype,accno,amount,taxkey
196 "Rechnung",2,1,"invoice 1",f,1600,"$transdate_string"
197 "AccTransaction",3400,159.48,9
200 $entries = test_import($file);
201 $entry = $entries->[0];
202 is $entry->{errors}->[0], 'Duplicate in database', 'detects duplicate invnumer for same vendor';
204 ##### test for duplicate invnumber for different vendor
205 my $different_vendor = new_vendor(
206 name => 'anderer Testlieferant',
207 currency_id => $currency_id,
208 taxzone_id => $taxzone->id,
213 datatype,vendornumber,currency_id,invnumber,taxincluded,apchart,transdate
214 datatype,accno,amount,taxkey
215 "Rechnung",777,1,"invoice 1",f,1600,"$transdate_string"
216 "AccTransaction",3400,159.48,9
219 $entries = test_import($file);
220 is $entries->[0]->{errors}->[0], undef, 'duplicate invnumber, different vendor: no errors in ap row';
221 is $entries->[1]->{errors}->[0], undef, 'duplicate invnumber, different vendor: no errors in acc_trans row';
223 $entry = $entries->[0];
224 is $entry->{object}->invnumber, 'invoice 1', 'duplicate invnumber, different vendor: invnumber ok';
225 is $entry->{object}->vendor_id, $different_vendor->id, 'duplicate invnumber, different vendor: vendor_id ok';
229 ##### test for no invnumber given
231 datatype,vendornumber,currency_id,taxincluded,apchart,transdate
232 datatype,accno,amount,taxkey
233 "Rechnung",2,1,f,1600,"$transdate_string"
234 "AccTransaction",3400,159.48,9
237 $entries = test_import($file);
238 $entry = $entries->[0];
239 $entry->{object}->validate_acc_trans;
240 is $entry->{errors}->[0], 'Error: Invoice Number missing', 'detects missing invnubmer';
243 ##### basic test without amounts in Rechnung, only specified in AccTransaction
245 datatype,vendornumber,currency_id,invnumber,taxincluded,apchart,transdate
246 datatype,accno,amount,taxkey
247 "Rechnung",2,1,"invoice 1 no amounts",f,1600,"$transdate_string"
248 "AccTransaction",3400,159.48,9
250 $entries = test_import($file);
251 is $entries->[0]->{errors}->[0], undef, 'basic test no amounts: no errors in ap row';
252 is $entries->[1]->{errors}->[0], undef, 'basic test no amounts: no errors in acc_trans row';
254 $entry = $entries->[0];
255 is $entry->{object}->validate_acc_trans, 1, 'basic test no amounts: acc_trans validates';
256 is $entry->{object}->invnumber, 'invoice 1 no amounts', 'basic test no amounts: invnumber ok';
257 is $entry->{object}->vendor_id, $vendor->id, 'basic test no amounts: vendor_id ok';
258 is scalar @{$entry->{object}->transactions}, 3, 'basic test no amounts: invoice 1 has 3 acc_trans entries';
259 is $::form->round_amount($entry->{object}->amount, 2), '189.78', 'basic test no amounts: not taxincluded ap amount';
260 is $::form->round_amount($entry->{object}->transactions->[0]->amount, 2), '-159.48', 'basic test no amounts: not taxincluded acc_trans netamount';
261 is $::form->round_amount($entry->{object}->netamount, 2), 159.48, 'basic test no amounts: invoice 1 ap netamount is 159.48';
265 ##### basic test: credit_note
267 datatype,vendornumber,currency_id,invnumber,taxincluded,apchart,transdate
268 datatype,accno,amount,taxkey
269 "Rechnung",2,1,"credit note",f,1600,"$transdate_string"
270 "AccTransaction",3400,-159.48,9
272 $entries = test_import($file);
273 is $entries->[0]->{errors}->[0], undef, 'basic test: credit_note: no errors in ap row';
274 is $entries->[1]->{errors}->[0], undef, 'basic test: credit_note: no errors in acc_trans row';
276 $entry = $entries->[0];
277 is $entry->{object}->validate_acc_trans, 1, 'basic test: credit_note: acc_trans validates';
278 is $entry->{object}->invnumber, 'credit note', 'basic test: credit_note: invnumber ok';
279 is scalar @{$entry->{object}->transactions}, 3, 'basic test: credit_note: credit note has 3 acc_trans entries';
280 is $::form->round_amount($entry->{object}->amount, 2), '-189.78', 'basic test: credit_note: taxincluded ap amount';
281 is $::form->round_amount($entry->{object}->netamount, 2), '-159.48', 'basic test: credit_note: taxincluded ap net amount';
282 is $::form->round_amount($entry->{object}->transactions->[0]->amount, 2), 159.48, 'credit note ap amount is 159.48';
286 #### verify_amount differs: max_amount_diff = 0.02, 189.80 is ok, 189.81 is not
288 datatype,vendornumber,verify_amount,verify_netamount,currency_id,invnumber,taxincluded,apchart,transdate
289 datatype,accno,amount,taxkey
290 "Rechnung",2,189.81,159.48,1,"invoice amounts differing",f,1600,"$transdate_string"
291 "AccTransaction",3400,159.48,9
293 $entries = test_import($file);
295 $entry = $entries->[0];
296 is $entry->{errors}->[0], 'Amounts differ too much', 'detects verify_amount differences';
300 datatype,vendornumber,currency_id,invnumber,taxincluded,direct_debit,apchart,transdate
301 datatype,accno,amount,taxkey
302 "Rechnung",2,1,"invoice with direct debit",f,t,1600,"$transdate_string"
303 "AccTransaction",3400,159.48,9
306 $entries = test_import($file);
307 is $entries->[0]->{errors}->[0], undef, 'direct debit: no errors in ap row';
308 is $entries->[1]->{errors}->[0], undef, 'direct debit: no errors in acc_trans row';
310 $entry = $entries->[0];
311 is $entry->{object}->validate_acc_trans, 1, 'direct debit: acc_trans validates';
312 is $entry->{object}->direct_debit, '1', 'direct debit';
318 datatype,vendornumber,currency_id,invnumber,taxincluded,apchart,transdate
319 datatype,accno,amount,taxkey
320 "Rechnung",2,1,"invoice 1 tax included no amounts",t,1600,"$transdate_string"
321 "AccTransaction",3400,189.78,9
324 $entries = test_import($file);
325 $entry = $entries->[0];
327 is $entry->{errors}->[0], undef, 'tax included: no errors in ap row';
328 is $entry->{errors}->[1], undef, 'tax included: no errors in acc_trans row';
330 is $entry->{object}->validate_acc_trans, 1, 'tax included: acc_trans validates';
332 is $entry->{object}->taxincluded, '1', 'tax included: taxincluded is true';
333 is $::form->round_amount($entry->{object}->amount, 2), '189.78', 'tax included: ap amount';
334 is $::form->round_amount($entry->{object}->netamount, 2), '159.48', 'tax included: ap net amount';
335 is $::form->round_amount($entry->{object}->transactions->[0]->amount, 2), '-159.48', 'tax included: acc_trans netamount';
339 #### multiple tax included
341 datatype,vendornumber,currency_id,invnumber,taxincluded,apchart,transdate
342 datatype,accno,amount,taxkey
343 "Rechnung",2,1,"invoice multiple tax included",t,1600,"$transdate_string"
344 "AccTransaction",3400,94.89,9
345 "AccTransaction",3400,94.89,9
348 $entries = test_import($file);
349 is $entries->[0]->{errors}->[0], undef, 'multiple tax included: no errors in ap row';
350 is $entries->[1]->{errors}->[0], undef, 'multiple tax included: no errors in 1. acc_trans row';
351 is $entries->[2]->{errors}->[0], undef, 'multiple tax included: no errors in 2. acc_trans row';
353 $entry = $entries->[0];
354 is $entry->{object}->validate_acc_trans, 1, 'multiple tax included: acc_trans validates';
356 is $::form->round_amount($entry->{object}->amount, 2), '189.78', 'multiple tax included: ap amount';
357 is $::form->round_amount($entry->{object}->netamount, 2), '159.48', 'multiple tax included: ap netamount';
358 is $::form->round_amount($entry->{object}->transactions->[0]->amount, 2), '-79.74', 'multiple tax included: amount';
359 is $::form->round_amount($entry->{object}->transactions->[1]->amount, 2), '-15.15', 'multiple tax included: tax';
363 # different payable chart
365 datatype,vendornumber,currency_id,invnumber,taxincluded,apchart
366 datatype,accno,amount,taxkey
367 "Rechnung",2,1,"invoice mit apchart 1605",f,1605
368 "AccTransaction",3400,159.48,9
371 $entries = test_import($file);
372 is $entries->[0]->{errors}->[0], undef, 'different payable chart: no errors in ap row';
373 is $entries->[1]->{errors}->[0], undef, 'different payable chart: no errors in acc_trans row';
375 $entry = $entries->[0];
376 is $entry->{object}->validate_acc_trans, 1, 'different payable chart: acc_trans validates';
377 is $entry->{object}->transactions->[2]->chart->accno, '1605', 'different payable chart: apchart set to 1605';
383 datatype,currency_id,invnumber,taxincluded,apchart
384 datatype,accno,amount,taxkey
385 "Rechnung",1,"invoice missing vendor",f,1600
386 "AccTransaction",3400,159.48,9
389 $entries = test_import($file);
390 $entry = $entries->[0];
391 is $entry->{errors}->[0], 'Error: Vendor missing', 'detects missing vendor';
395 datatype,vendor,currency_id,invnumber,taxincluded,apchart
396 datatype,accno,amount,taxkey
397 "Rechnung","Testlieferant",1,"invoice vendor name",f,1600
398 "AccTransaction",3400,159.48,9
401 $entries = test_import($file);
402 is $entries->[0]->{errors}->[0], undef, 'vendor by name: no errors in ap row';
403 is $entries->[1]->{errors}->[0], undef, 'vendor by name: no errors in acc_trans row';
405 $entry = $entries->[0];
406 is $entry->{object}->validate_acc_trans, 1, 'vendor by name: acc_trans validates';
407 is $entry->{object}->vendor->name, "Testlieferant", 'detects vendor by name';
411 ##### detect missing chart
413 datatype,currency_id,invnumber,vendor,apchart
414 datatype,amount,taxkey
415 "Rechnung",1,"invoice missing chart","Testlieferant",1600
419 $entries = test_import($file);
421 $entry = $entries->[1];
422 is $entry->{errors}->[0], 'Error: chart missing', 'detects missing chart (chart_id or accno)';
424 ##### detect illegal chart by accno
426 datatype,currency_id,invnumber,vendor,apchart
427 datatype,accno,amount,taxkey
428 "Rechnung",1,"invoice illegal chart accno","Testlieferant",1600
429 "AccTransaction",9999,4,9
432 $entries = test_import($file);
434 $entry = $entries->[1];
435 is $entry->{errors}->[0], 'Error: invalid chart (accno)', 'detects invalid chart (chart_id or accno)';
437 # ##### detect illegal apchart
439 datatype,currency_id,invnumber,vendor,taxincluded,apchart
440 datatype,accno,amount,taxkey
441 "Rechnung",1,"invoice illegal apchart","Testlieferant",f,11600
442 "AccTransaction",3400,159.48,9
445 $entries = test_import($file);
447 $entry = $entries->[0];
448 is $entry->{errors}->[0], "Error: can't find ap chart with accno 11600", 'detects illegal payable chart (apchart)';
450 ##### detect chart by id
452 datatype,currency_id,invnumber,vendor,taxincluded,apchart
453 datatype,amount,chart_id,taxkey
454 "Rechnung",1,"invoice chart_id","Testlieferant",f,1600
455 "AccTransaction",159.48,37,9
458 $entries = test_import($file);
459 is $entries->[0]->{errors}->[0], undef, 'detect chart by id: no errors in ap row';
460 is $entries->[1]->{errors}->[0], undef, 'detect chart by id: no errors in acc_trans row';
462 $entry = $entries->[0];
463 is $entry->{object}->validate_acc_trans, 1, 'detect chart by id: acc_trans validates';
465 $entry = $entries->[1]; # acc_trans entry is at entry array pos 1
466 is $entry->{object}->chart->id, "37", 'detects chart by id';
470 ##### detect chart by accno
472 datatype,currency_id,invnumber,vendor,taxincluded,apchart
473 datatype,amount,accno,taxkey
474 "Rechnung",1,"invoice by chart accno","Testlieferant",f,1600
475 "AccTransaction",159.48,3400,9
478 $entries = test_import($file);
479 is $entries->[0]->{errors}->[0], undef, 'detect chart by accno: no errors in ap row';
480 is $entries->[1]->{errors}->[0], undef, 'detect chart by accno: no errors in acc_trans row';
482 $entry = $entries->[0];
483 is $entry->{object}->validate_acc_trans, 1, 'detect chart by accno: acc_trans validates';
485 $entry = $entries->[1];
486 is $entry->{object}->chart->accno, "3400", 'detects chart by accno';
490 ##### detect chart isn't an ap_chart
492 datatype,currency_id,invnumber,vendor,taxincluded,apchart
493 datatype,amount,accno,taxkey
494 "Rechnung",1,"invoice by chart accno","Testlieferant",f,1600
495 "AccTransaction",159.48,1600,9
498 $entries = test_import($file);
500 $entry = $entries->[1];
501 is $entry->{errors}->[0], 'Error: chart isn\'t an ap_amount chart', 'detects valid chart that is not an ap_amount chart';
505 datatype,currency_id,invnumber,vendor,apchart
506 datatype,amount,accno
507 "Rechnung",1,"invoice missing taxkey chart accno","Testlieferant",1600
508 "AccTransaction",159.48,3400
511 $entries = test_import($file);
513 $entry = $entries->[1];
514 is $entry->{errors}->[0], 'Error: taxkey missing', 'detects missing taxkey (DATEV Steuerschlüssel)';
518 datatype,currency_id,invnumber,vendor,apchart
519 datatype,amount,accno,taxkey
520 "Rechnung",1,"invoice illegal taxkey","Testlieferant",1600
521 "AccTransaction",4,3400,123
524 $entries = test_import($file);
526 $entry = $entries->[1];
527 is $entry->{errors}->[0], 'Error: invalid taxkey', 'detects invalid taxkey (DATEV Steuerschlüssel)';
531 datatype,vendornumber,currency_id,invnumber,apchart,taxincluded
532 datatype,accno,amount,taxkey
533 "Rechnung",2,1,"invoice by taxkey",1600,1
534 "AccTransaction",3400,4,9
537 $entries = test_import($file);
538 is $entries->[0]->{errors}->[0], undef, 'taxkey: no errors in ap row';
539 is $entries->[1]->{errors}->[0], undef, 'taxkey: no errors in acc_trans row';
541 $entry = $entries->[1];
542 is $entry->{object}->taxkey, 9, 'detects taxkey';
548 datatype,vendornumber,currency_id,invnumber,apchart,taxincluded
549 datatype,accno,amount,taxkey,projectnumber
550 "Rechnung",2,1,"invoice with acc_trans project",1600,f
551 "AccTransaction",3400,159.48,9,P1
554 $entries = test_import($file);
555 is $entries->[0]->{errors}->[0], undef, 'acc_trans project: no errors in ap row';
556 is $entries->[1]->{errors}->[0], undef, 'acc_trans project: no errors in acc_trans row';
558 $entry = $entries->[1];
559 is $entry->{object}->project->projectnumber, 'P1', 'detects acc_trans project';
565 datatype,vendornumber,currency_id,invnumber,taxincluded,apchart,transdate,duedate,globalprojectnumber,department
566 datatype,accno,amount,taxkey,projectnumber
567 "Rechnung",2,1,"invoice various",t,1600,21.04.2016,30.04.2016,P1,Department 1
568 "AccTransaction",3400,119,9,P1
569 "AccTransaction",3300,107,8,P1
570 "AccTransaction",3559,100,0,P1
573 $entries = test_import($file);
574 is $entries->[0]->{errors}->[0], undef, 'various tests: errors in ap row';
575 is $entries->[1]->{errors}->[0], undef, 'various tests: no errors in 1. acc_trans row';
576 is $entries->[2]->{errors}->[0], undef, 'various tests: no errors in 2. acc_trans row';
577 is $entries->[3]->{errors}->[0], undef, 'various tests: no errors in 3. acc_trans row';
579 $entry = $entries->[0];
580 is $entry->{object}->validate_acc_trans, 1, 'various tests: acc_trans validates';
582 is $entry->{object}->duedate->to_kivitendo, '30.04.2016', 'various tests: duedate';
583 is $entry->{object}->transdate->to_kivitendo, '21.04.2016', 'various tests: transdate';
584 is $entry->{object}->globalproject->description, 'Project X', 'various tests: project';
585 is $entry->{object}->department->description, 'Department 1', 'various tests: department';
586 # 3300 is third entry after 3400 and tax for 3400
587 is $::form->round_amount($entry->{object}->transactions->[2]->amount), '-100', '3300 net amount: -100';
588 is $entry->{object}->transactions->[2]->taxkey, '8', '3300 has taxkey 8';
589 is $entry->{object}->transactions->[2]->project_id, $project->id, 'AccTrans project';
595 datatype,vendornumber,currency_id,invnumber,taxincluded,apchart,transdate,duedate,globalprojectnumber,department
596 datatype,accno,amount,taxkey,projectnumber
597 "Rechnung",2,1,"invoice various 1",t,1600,21.04.2016,30.04.2016,P1,Department 1
598 "AccTransaction",3400,119,9,P1
599 "AccTransaction",3300,107,8,P1
600 "AccTransaction",3559,100,0,P1
601 "Rechnung",2,1,"invoice various 2",t,1600,21.04.2016,30.04.2016,P1,Department 1
602 "AccTransaction",3400,119,9,P1
603 "AccTransaction",3400,107,8,P1
604 "AccTransaction",3559,100,0,P1
607 $entries = test_import($file);
608 is $entries->[0]->{errors}->[0], undef, 'ap amount test: no errors in 1. ap row';
609 is $entries->[1]->{errors}->[0], undef, 'ap amount test: no errors in 1. acc_trans row (ap row 1)';
610 is $entries->[2]->{errors}->[0], undef, 'ap amount test: no errors in 2. acc_trans row (ap row 1)';
611 is $entries->[3]->{errors}->[0], undef, 'ap amount test: no errors in 3. acc_trans row (ap row 1)';
612 is $entries->[4]->{errors}->[0], undef, 'ap amount test: no errors in 2. ap row';
613 is $entries->[5]->{errors}->[0], undef, 'ap amount test: no errors in 1. acc_trans row (ap row 2)';
614 is $entries->[6]->{errors}->[0], undef, 'ap amount test: no errors in 2. acc_trans row (ap row 2)';
615 is $entries->[7]->{errors}->[0], undef, 'ap amount test: no errors in 3. acc_trans row (ap row 2)';
617 $entry = $entries->[0];
618 is $entry->{object}->validate_acc_trans, 1, 'ap amount test: acc_trans validates';
619 is $entry->{object}->duedate->to_kivitendo, '30.04.2016', 'duedate';
620 is $entry->{info_data}->{calc_amount}, '326.00', "First calculated invoice amount displayed in info data";
621 $entry = $entries->[4];
622 is $entry->{info_data}->{calc_amount}, '326.00', "Second calculated invoice amount displayed in info data";
627 # multiple entries, taxincluded = f
629 datatype,vendornumber,currency_id,invnumber,taxincluded,apchart
630 datatype,accno,amount,taxkey
631 "Rechnung",2,1,"invoice 4 acc_trans",f,1600
632 "AccTransaction",3400,39.87,9
633 "AccTransaction",3400,39.87,9
634 "AccTransaction",3400,39.87,9
635 "AccTransaction",3400,39.87,9
636 "Rechnung",2,1,"invoice 4 acc_trans 2",f,1600
637 "AccTransaction",3400,39.87,9
638 "AccTransaction",3400,39.87,9
639 "AccTransaction",3400,39.87,9
640 "AccTransaction",3400,39.87,9
641 "Rechnung",2,1,"invoice 4 acc_trans 3",f,1600
642 "AccTransaction",3400,39.87,9
643 "AccTransaction",3400,39.87,9
644 "AccTransaction",3400,39.87,9
645 "AccTransaction",3400,39.87,9
646 "Rechnung",2,1,"invoice 4 acc_trans 4",f,1605
647 "AccTransaction",3400,39.87,9
648 "AccTransaction",3400,39.87,9
649 "AccTransaction",3400,39.87,9
650 "AccTransaction",3400,39.87,9
653 $entries = test_import($file);
656 foreach my $entry ( @$entries ) {
657 next unless $entry->{object}->isa('SL::DB::PurchaseInvoice');
659 is scalar @{$entry->{object}->transactions}, 9, "multiple entries: invoice $i: 'acc_trans' has 9 acc_trans entries";
660 $entry->{object}->validate_acc_trans;
661 is $entry->{object}->validate_acc_trans, 1, "multiple entries: invoice $i: 'acc_trans validates'";
669 ##### missing acc_trans
671 datatype,vendornumber,currency_id,invnumber,taxincluded,apchart,transdate,duedate,globalprojectnumber,department
672 datatype,accno,amount,taxkey,projectnumber
673 "Rechnung",2,1,"invoice acc_trans missing",t,1600,21.04.2016,30.04.2016,P1,Department 1
674 "Rechnung",2,1,"invoice various a",t,1600,21.04.2016,30.04.2016,P1,Department 1
675 "AccTransaction",3400,119,9,P1
676 "AccTransaction",3300,107,8,P1
679 $entries = test_import($file);
681 $entry = $entries->[0];
682 is $entry->{errors}->[0], "Error: ap transaction doesn't validate", 'detects invalid ap, maybe acc_trans entry missing';
684 ##### taxkey differs from active_taxkey
686 datatype,vendornumber,currency_id,invnumber,taxincluded,apchart
687 datatype,accno,amount,taxkey
688 "Rechnung",2,1,"invoice 2 tax included no amounts",t,1600
689 "AccTransaction",3400,189.78,8
692 $entries = test_import($file);
693 is $entries->[0]->{errors}->[0], undef, 'taxkey differs from active_taxkey: no errors in ap row';
694 is $entries->[1]->{errors}->[0], undef, 'taxkey differs from active_taxkey: no errors in acc_trans row';
696 $entry = $entries->[0];
697 is $entry->{object}->transactions->[1]->taxkey, '8', 'taxkey differs from active_taxkey';
701 ##### verify amounts, error only once
703 datatype,vendornumber,currency_id,invnumber,taxincluded,apchart,verify_netamount,verify_amount
704 datatype,accno,amount,taxkey
705 "Rechnung",2,1,"first invoice",f,1600,39.87,47.44
706 "AccTransaction",3400,39.87,9
707 "Rechnung",2,1,"second invoice",f,1600,39.78,78.39
708 "AccTransaction",3400,39.87,9
711 $entries = test_import($file);
713 $entry = $entries->[0];
714 is $entry->{errors}->[0], undef, 'verify amounts, error only once: no error in first invoice';
716 $entry = $entries->[2];
717 is $entry->{errors}->[0], "Amounts differ too much", 'verify amounts, error only once: amount differs';
718 is $entry->{errors}->[1], "Net amounts differ too much", 'verify amounts, error only once: netamount differs';
719 is $entry->{errors}->[2], undef, 'verify amounts, error only once: nothing else';
724 my $number_of_imported_invoices = SL::DB::Manager::PurchaseInvoice->get_all_count;
725 is $number_of_imported_invoices, $saved_invoices, 'All invoices saved';
728 clear_up(); # remove all data at end of tests
737 # set emacs to perl mode