2 use Test::More tests => 197;
10 use Support::TestSetup;
12 use List::Util qw(sum);
14 use SL::Dev::Record qw(create_invoice_item create_sales_invoice create_credit_note create_ap_transaction);
15 use SL::Dev::CustomerVendor qw(new_customer new_vendor);
16 use SL::Dev::Part qw(new_part);
17 use SL::DB::Buchungsgruppe;
19 use SL::DB::Exchangerate;
27 use SL::DB::BankAccount;
28 use SL::DB::PaymentTerm;
29 use SL::DBUtils qw(selectfirst_array_query);
32 my ($customer, $vendor, $currency_id, @parts, $buchungsgruppe, $buchungsgruppe7, $unit, $employee, $tax, $tax7, $tax_9, $taxzone, $payment_terms, $bank_account);
33 my ($transdate1, $transdate2, $transdate3, $transdate4, $currency, $exchangerate, $exchangerate2, $exchangerate3, $exchangerate4);
34 my ($ar_chart,$bank,$ar_amount_chart, $ap_chart, $ap_amount_chart, $fxloss_chart, $fxgain_chart);
36 my $ap_transaction_counter = 0; # used for generating purchase invnumber
38 Support::TestSetup::login();
42 # test cases: without_skonto
43 test_default_invoice_one_item_19_without_skonto();
44 test_default_invoice_two_items_19_7_tax_with_skonto();
45 test_default_invoice_two_items_19_7_without_skonto();
46 test_default_invoice_two_items_19_7_without_skonto_incomplete_payment();
47 test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments();
48 test_default_ap_transaction_two_charts_19_7_without_skonto();
49 test_default_ap_transaction_two_charts_19_7_tax_partial_unrounded_payment_without_skonto();
50 test_default_invoice_one_item_19_without_skonto_overpaid();
51 test_credit_note_two_items_19_7_tax_tax_not_included();
53 # test cases: difference_as_skonto
54 test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto();
55 test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto_1cent();
56 test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto_2cent();
57 test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto();
58 test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto_1cent();
59 test_default_ap_transaction_two_charts_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto();
61 # test cases: with_skonto_pt
62 test_default_invoice_two_items_19_7_tax_with_skonto_50_50();
63 test_default_invoice_four_items_19_7_tax_with_skonto_4x_25();
64 test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_multiple();
65 test_default_ap_transaction_two_charts_19_7_with_skonto();
66 test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_tax_included();
67 test_default_invoice_two_items_19_7_tax_with_skonto_tax_included();
69 # test payment of ar and ap transactions with currency and tax included/not included
70 # exchangerate = 1.33333
71 test_ar_currency_tax_not_included_and_payment();
72 test_ar_currency_tax_included();
73 test_ap_currency_tax_not_included_and_payment();
74 test_ap_currency_tax_included();
76 test_ar_currency_tax_not_included_and_payment_2(); # exchangerate 0.8
77 test_ar_currency_tax_not_included_and_payment_2_credit_note(); # exchangerate 0.8
79 test_ap_currency_tax_not_included_and_payment_2(); # two exchangerates, with fx_gain_loss
80 test_ap_currency_tax_not_included_and_payment_2_credit_note(); # two exchangerates, with fx_gain_loss
82 is(SL::DB::Manager::Invoice->get_all_count(), 21, "number of invoices at end of tests ok");
84 local $TODO = "currently this test fails because the code writing the invoice is buggy, the calculation of skonto is correct";
85 my ($acc_trans_sum) = selectfirst_array_query($::form, $currency->db->dbh, 'SELECT SUM(amount) FROM acc_trans');
86 is($acc_trans_sum, '0.00000', "sum of all acc_trans at end of all tests is 0");
89 # remove all created data at end of test
96 SL::DB::Manager::InvoiceItem->delete_all(all => 1);
97 SL::DB::Manager::Invoice->delete_all(all => 1);
98 SL::DB::Manager::PurchaseInvoice->delete_all(all => 1);
99 SL::DB::Manager::Part->delete_all(all => 1);
100 SL::DB::Manager::Customer->delete_all(all => 1);
101 SL::DB::Manager::Vendor->delete_all(all => 1);
102 SL::DB::Manager::BankAccount->delete_all(all => 1);
103 SL::DB::Manager::PaymentTerm->delete_all(all => 1);
104 SL::DB::Manager::Exchangerate->delete_all(all => 1);
105 SL::DB::Manager::Currency->delete_all(where => [ name => 'CUR' ]);
113 $transdate1 = DateTime->today;
114 $transdate2 = DateTime->today->add(days => 1);
115 $transdate3 = DateTime->today->add(days => 2);
116 $transdate4 = DateTime->today->add(days => 3);
118 $buchungsgruppe = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 19%') || croak "No accounting group";
119 $buchungsgruppe7 = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 7%') || croak "No accounting group for 7\%";
120 $unit = SL::DB::Manager::Unit->find_by(name => 'kg') || croak "No unit";
121 $employee = SL::DB::Manager::Employee->current || croak "No employee";
122 $tax = SL::DB::Manager::Tax->find_by(taxkey => 3, rate => 0.19) || croak "No tax";
123 $tax7 = SL::DB::Manager::Tax->find_by(taxkey => 2, rate => 0.07) || croak "No tax for 7\%";
124 $taxzone = SL::DB::Manager::TaxZone->find_by( description => 'Inland') || croak "No taxzone";
125 $tax_9 = SL::DB::Manager::Tax->find_by(taxkey => 9, rate => 0.19) || croak "No tax";
126 # $tax7 = SL::DB::Manager::Tax->find_by(taxkey => 2, rate => 0.07) || croak "No tax for 7\%";
128 $currency_id = $::instance_conf->get_currency_id;
130 $currency = SL::DB::Currency->new(name => 'CUR')->save;
132 $fxgain_chart = SL::DB::Manager::Chart->find_by(accno => '2660') or die "Can't find fxgain_chart in test";
133 $fxloss_chart = SL::DB::Manager::Chart->find_by(accno => '2150') or die "Can't find fxloss_chart in test";
135 $currency->db->dbh->do('UPDATE defaults SET fxgain_accno_id = ' . $fxgain_chart->id);
136 $currency->db->dbh->do('UPDATE defaults SET fxloss_accno_id = ' . $fxloss_chart->id);
137 $::instance_conf->reload->data;
138 is($fxgain_chart->id, $::instance_conf->get_fxgain_accno_id, "fxgain_chart was updated in defaults");
139 is($fxloss_chart->id, $::instance_conf->get_fxloss_accno_id, "fxloss_chart was updated in defaults");
141 $exchangerate = SL::DB::Exchangerate->new(transdate => $transdate1,
144 currency_id => $currency->id,
146 $exchangerate2 = SL::DB::Exchangerate->new(transdate => $transdate2,
149 currency_id => $currency->id,
151 $exchangerate3 = SL::DB::Exchangerate->new(transdate => $transdate3,
154 currency_id => $currency->id,
156 $exchangerate4 = SL::DB::Exchangerate->new(transdate => $transdate4,
159 currency_id => $currency->id,
162 $customer = new_customer(
163 name => 'Test Customer',
164 currency_id => $currency_id,
165 taxzone_id => $taxzone->id,
168 $bank_account = SL::DB::BankAccount->new(
169 account_number => '123',
174 chart_id => SL::DB::Manager::Chart->find_by( description => 'Bank' )->id,
175 name => SL::DB::Manager::Chart->find_by( description => 'Bank' )->description,
178 $payment_terms = SL::DB::PaymentTerm->new(
179 description => 'payment',
180 description_long => 'payment',
183 percent_skonto => '0.05',
184 auto_calculation => 1,
187 $vendor = new_vendor(
188 name => 'Test Vendor',
189 currency_id => $currency_id,
190 taxzone_id => $taxzone->id,
191 payment_id => $payment_terms->id,
196 push @parts, new_part(
197 partnumber => 'T4254',
198 description => 'Fourty-two fifty-four',
201 buchungsgruppen_id => $buchungsgruppe->id,
206 push @parts, new_part(
207 partnumber => 'T0815',
208 description => 'Zero EIGHT fifteeN @ 7%',
211 buchungsgruppen_id => $buchungsgruppe7->id,
215 push @parts, new_part(
217 description => 'Testware 19%',
220 buchungsgruppen_id => $buchungsgruppe->id,
224 push @parts, new_part(
226 description => 'Testware 7%',
229 buchungsgruppen_id => $buchungsgruppe7->id,
234 $ar_chart = SL::DB::Manager::Chart->find_by( accno => '1400' ); # Forderungen
235 $ap_chart = SL::DB::Manager::Chart->find_by( accno => '1600' ); # Verbindlichkeiten
236 $bank = SL::DB::Manager::Chart->find_by( accno => '1200' ); # Bank
237 $ar_amount_chart = SL::DB::Manager::Chart->find_by( accno => '8400' ); # Erlöse
238 $ap_amount_chart = SL::DB::Manager::Chart->find_by( accno => '3400' ); # Wareneingang 19%
241 sub new_ap_transaction {
242 $ap_transaction_counter++;
244 my $ap_transaction = create_ap_transaction(
246 invnumber => 'newap ' . $ap_transaction_counter,
250 gldate => $transdate1,
251 taxzone_id => $taxzone->id,
252 transdate => $transdate1,
255 chart => SL::DB::Manager::Chart->find_by(accno => '3400'),
259 chart => SL::DB::Manager::Chart->find_by(accno => '3300'),
265 return $ap_transaction;
268 sub number_of_payments {
271 my $number_of_payments;
273 foreach my $transaction ( @{ $invoice->transactions } ) {
274 if ( $transaction->chart_link =~ /(AR_paid|AP_paid)/ ) {
275 $paid_amount += $transaction->amount ;
276 $number_of_payments++;
279 return ($number_of_payments, $paid_amount);
285 my $total = sum map { $_->amount } @{ $invoice->transactions };
287 return $::form->round_amount($total, 5);
293 sub test_default_invoice_one_item_19_without_skonto {
294 my $title = 'default invoice, one item, 19% tax, without_skonto';
295 my $item = create_invoice_item(part => $parts[0], qty => 2.5);
296 my $invoice = create_sales_invoice(
298 invoiceitems => [ $item ],
299 payment_id => $payment_terms->id,
302 my $ap_transaction = new_ap_transaction();
305 my %params = ( chart_id => $bank_account->chart_id,
306 transdate => DateTime->today_local->to_kivitendo
309 $params{amount} = '6.96';
310 $params{payment_type} = 'without_skonto';
312 $invoice->pay_invoice( %params );
314 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
315 my $total = total_amount($invoice);
317 is($invoice->netamount, 5.85, "${title}: netamount");
318 is($invoice->amount, 6.96, "${title}: amount");
319 is($paid_amount, -6.96, "${title}: paid amount");
320 is($number_of_payments, 1, "${title}: 1 AR_paid booking");
321 is($invoice->paid, 6.96, "${title}: paid");
322 is($total, 0, "${title}: even balance");
326 sub test_default_invoice_one_item_19_without_skonto_overpaid {
327 my $title = 'default invoice, one item, 19% tax, without_skonto';
329 my $item = create_invoice_item(part => $parts[0], qty => 2.5);
330 my $invoice = create_sales_invoice(
332 invoiceitems => [ $item ],
333 payment_id => $payment_terms->id,
336 my $ap_transaction = new_ap_transaction();
340 my %params = ( chart_id => $bank_account->chart_id,
341 transdate => DateTime->today_local->to_kivitendo
344 $params{amount} = '16.96';
345 $params{payment_type} = 'without_skonto';
346 $invoice->pay_invoice( %params );
348 $params{amount} = '-10.00';
349 $invoice->pay_invoice( %params );
351 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
352 my $total = total_amount($invoice);
354 is($invoice->netamount, 5.85, "${title}: netamount");
355 is($invoice->amount, 6.96, "${title}: amount");
356 is($paid_amount, -6.96, "${title}: paid amount");
357 is($number_of_payments, 2, "${title}: 1 AR_paid booking");
358 is($invoice->paid, 6.96, "${title}: paid");
359 is($total, 0, "${title}: even balance");
365 sub test_default_invoice_two_items_19_7_tax_with_skonto {
366 my $title = 'default invoice, two items, 19/7% tax with_skonto_pt';
368 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
369 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
370 my $invoice = create_sales_invoice(
372 invoiceitems => [ $item1, $item2 ],
373 payment_id => $payment_terms->id,
377 my %params = ( chart_id => $bank_account->chart_id,
378 transdate => DateTime->today_local->to_kivitendo
381 $params{payment_type} = 'with_skonto_pt';
382 $params{amount} = $invoice->amount_less_skonto;
384 $invoice->pay_invoice( %params );
386 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
387 my $total = total_amount($invoice);
389 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
390 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
391 is($paid_amount, -19.44, "${title}: paid amount");
392 is($invoice->paid, 19.44, "${title}: paid");
393 is($number_of_payments, 3, "${title}: 3 AR_paid bookings");
394 is($total, 0, "${title}: even balance");
397 sub test_default_invoice_two_items_19_7_tax_with_skonto_tax_included {
398 my $title = 'default invoice, two items, 19/7% tax with_skonto_pt';
400 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
401 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
402 my $invoice = create_sales_invoice(
404 invoiceitems => [ $item1, $item2 ],
405 payment_id => $payment_terms->id,
409 my %params = ( chart_id => $bank_account->chart_id,
410 transdate => DateTime->today_local->to_kivitendo
413 $params{payment_type} = 'with_skonto_pt';
414 $params{amount} = $invoice->amount_less_skonto;
416 $invoice->pay_invoice( %params );
418 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
419 my $total = total_amount($invoice);
421 is($invoice->netamount, 15.82, "${title}: netamount");
422 is($invoice->amount, 17.51, "${title}: amount");
423 is($paid_amount, -17.51, "${title}: paid amount");
424 is($invoice->paid, 17.51, "${title}: paid");
425 is($number_of_payments, 3, "${title}: 3 AR_paid bookings");
428 local $TODO = "currently this test fails because the code writing the invoice is buggy, the calculation of skonto is correct";
429 is($total, 0, "${title}: even balance");
433 # test 3 : two items, without skonto
434 sub test_default_invoice_two_items_19_7_without_skonto {
435 my $title = 'default invoice, two items, 19/7% tax without skonto';
437 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
438 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
439 my $invoice = create_sales_invoice(
441 invoiceitems => [ $item1, $item2 ],
442 payment_id => $payment_terms->id,
446 my %params = ( chart_id => $bank_account->chart_id,
447 transdate => DateTime->today_local->to_kivitendo
450 $params{amount} = '19.44'; # pass full amount
451 $params{payment_type} = 'without_skonto';
453 $invoice->pay_invoice( %params );
455 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
456 my $total = total_amount($invoice);
458 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
459 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
460 is($paid_amount, -19.44, "${title}: paid amount");
461 is($invoice->paid, 19.44, "${title}: paid");
462 is($number_of_payments, 1, "${title}: 1 AR_paid bookings");
463 is($total, 0, "${title}: even balance");
467 sub test_default_invoice_two_items_19_7_without_skonto_incomplete_payment {
468 my $title = 'default invoice, two items, 19/7% tax without skonto incomplete payment';
470 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
471 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
472 my $invoice = create_sales_invoice(
474 invoiceitems => [ $item1, $item2 ],
475 payment_id => $payment_terms->id,
478 $invoice->pay_invoice( amount => '9.44',
479 payment_type => 'without_skonto',
480 chart_id => $bank_account->chart_id,
481 transdate => DateTime->today_local->to_kivitendo,
484 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
485 my $total = total_amount($invoice);
487 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
488 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
489 is($paid_amount, -9.44, "${title}: paid amount");
490 is($invoice->paid, 9.44, "${title}: paid");
491 is($number_of_payments, 1, "${title}: 1 AR_paid bookings");
492 is($total, 0, "${title}: even balance");
496 sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments {
497 my $title = 'default invoice, two items, 19/7% tax not included';
499 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
500 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
501 my $invoice = create_sales_invoice(
503 invoiceitems => [ $item1, $item2 ],
504 payment_id => $payment_terms->id,
507 $invoice->pay_invoice( amount => '9.44',
508 payment_type => 'without_skonto',
509 chart_id => $bank_account->chart_id,
510 transdate => DateTime->today_local->to_kivitendo
512 $invoice->pay_invoice( amount => '10.00',
513 chart_id => $bank_account->chart_id,
514 transdate => DateTime->today_local->to_kivitendo
517 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
518 my $total = total_amount($invoice);
520 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
521 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
522 is($paid_amount, -19.44, "${title}: paid amount");
523 is($invoice->paid, 19.44, "${title}: paid");
524 is($number_of_payments, 2, "${title}: 2 AR_paid bookings");
525 is($total, 0, "${title}: even balance");
530 sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto {
531 my $title = 'default invoice, two items, 19/7% tax not included';
533 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
534 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
535 my $invoice = create_sales_invoice(
537 invoiceitems => [ $item1, $item2 ],
538 payment_id => $payment_terms->id,
541 $invoice->pay_invoice( amount => '9.44',
542 payment_type => 'without_skonto',
543 chart_id => $bank_account->chart_id,
544 transdate => DateTime->today_local->to_kivitendo
546 $invoice->pay_invoice( amount => '8.73',
547 payment_type => 'without_skonto',
548 chart_id => $bank_account->chart_id,
549 transdate => DateTime->today_local->to_kivitendo
551 $invoice->pay_invoice( amount => $invoice->open_amount,
552 payment_type => 'difference_as_skonto',
553 chart_id => $bank_account->chart_id,
554 transdate => DateTime->today_local->to_kivitendo
557 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
558 my $total = total_amount($invoice);
560 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
561 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
562 is($paid_amount, -19.44, "${title}: paid amount");
563 is($invoice->paid, 19.44, "${title}: paid");
564 is($number_of_payments, 4, "${title}: 4 AR_paid bookings");
565 is($total, 0, "${title}: even balance");
569 sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto_1cent {
570 my $title = 'default invoice, two items, 19/7% tax not included';
572 # if there is only one cent left there can only be one skonto booking, the
573 # error handling should choose the highest amount, which is the 7% account
574 # (11.66) rather than the 19% account (5.85). The actual tax amount is
575 # higher for the 19% case, though (1.11 compared to 0.82)
577 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
578 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
579 my $invoice = create_sales_invoice(
581 invoiceitems => [ $item1, $item2 ],
582 payment_id => $payment_terms->id,
585 $invoice->pay_invoice( amount => '19.42',
586 payment_type => 'without_skonto',
587 chart_id => $bank_account->chart_id,
588 transdate => DateTime->today_local->to_kivitendo
590 $invoice->pay_invoice( amount => $invoice->open_amount,
591 payment_type => 'difference_as_skonto',
592 chart_id => $bank_account->chart_id,
593 transdate => DateTime->today_local->to_kivitendo
596 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
597 my $total = total_amount($invoice);
599 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
600 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
601 is($paid_amount, -19.44, "${title}: paid amount");
602 is($invoice->paid, 19.44, "${title}: paid");
603 is($number_of_payments, 3, "${title}: 2 AR_paid bookings");
604 is($total, 0, "${title}: even balance");
608 sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto_2cent {
609 my $title = 'default invoice, two items, 19/7% tax not included';
611 # if there are two cents left there will be two skonto bookings, 1 cent each
612 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
613 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
614 my $invoice = create_sales_invoice(
616 invoiceitems => [ $item1, $item2 ],
617 payment_id => $payment_terms->id,
620 $invoice->pay_invoice( amount => '19.42',
621 payment_type => 'without_skonto',
622 chart_id => $bank_account->chart_id,
623 transdate => DateTime->today_local->to_kivitendo
625 $invoice->pay_invoice( amount => $invoice->open_amount,
626 payment_type => 'difference_as_skonto',
627 chart_id => $bank_account->chart_id,
628 transdate => DateTime->today_local->to_kivitendo
631 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
632 my $total = total_amount($invoice);
634 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
635 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
636 is($paid_amount, -19.44, "${title}: paid amount");
637 is($invoice->paid, 19.44, "${title}: paid");
638 is($number_of_payments, 3, "${title}: 3 AR_paid bookings");
639 is($total, 0, "${title}: even balance");
643 sub test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto {
644 my $title = 'default invoice, one item, 19% tax, without_skonto';
646 my $item = create_invoice_item(part => $parts[0], qty => 2.5);
647 my $invoice = create_sales_invoice(
649 invoiceitems => [ $item ],
650 payment_id => $payment_terms->id,
654 my %params = ( chart_id => $bank_account->chart_id,
655 transdate => DateTime->today_local->to_kivitendo
658 $params{amount} = '2.32';
659 $params{payment_type} = 'without_skonto';
660 $invoice->pay_invoice( %params );
662 $params{amount} = '3.81';
663 $params{payment_type} = 'without_skonto';
664 $invoice->pay_invoice( %params );
666 $params{amount} = $invoice->open_amount; # set amount, otherwise previous 3.81 is used
667 $params{payment_type} = 'difference_as_skonto';
668 $invoice->pay_invoice( %params );
670 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
671 my $total = total_amount($invoice);
673 is($invoice->netamount, 5.85, "${title}: netamount");
674 is($invoice->amount, 6.96, "${title}: amount");
675 is($paid_amount, -6.96, "${title}: paid amount");
676 is($number_of_payments, 3, "${title}: 3 AR_paid booking");
677 is($invoice->paid, 6.96, "${title}: paid");
678 is($total, 0, "${title}: even balance");
682 sub test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto_1cent {
683 my $title = 'default invoice, one item, 19% tax, without_skonto';
685 my $item = create_invoice_item(part => $parts[0], qty => 2.5);
686 my $invoice = create_sales_invoice(
688 invoiceitems => [ $item ],
689 payment_id => $payment_terms->id,
693 my %params = ( chart_id => $bank_account->chart_id,
694 transdate => DateTime->today_local->to_kivitendo
697 $params{amount} = '6.95';
698 $params{payment_type} = 'without_skonto';
699 $invoice->pay_invoice( %params );
701 $params{amount} = $invoice->open_amount; # set amount, otherwise previous value 6.95 is used
702 $params{payment_type} = 'difference_as_skonto';
703 $invoice->pay_invoice( %params );
705 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
706 my $total = total_amount($invoice);
708 is($invoice->netamount, 5.85, "${title}: netamount");
709 is($invoice->amount, 6.96, "${title}: amount");
710 is($paid_amount, -6.96, "${title}: paid amount");
711 is($number_of_payments, 2, "${title}: 3 AR_paid booking");
712 is($invoice->paid, 6.96, "${title}: paid");
713 is($total, 0, "${title}: even balance");
717 # test 3 : two items, without skonto
718 sub test_default_ap_transaction_two_charts_19_7_without_skonto {
719 my $title = 'default invoice, two items, 19/7% tax without skonto';
721 my $ap_transaction = new_ap_transaction();
723 my %params = ( chart_id => $bank_account->chart_id,
724 transdate => DateTime->today_local->to_kivitendo
727 $params{amount} = '226'; # pass full amount
728 $params{payment_type} = 'without_skonto';
730 $ap_transaction->pay_invoice( %params );
732 my ($number_of_payments, $paid_amount) = number_of_payments($ap_transaction);
733 my $total = total_amount($ap_transaction);
735 is($paid_amount, 226, "${title}: paid amount");
736 is($number_of_payments, 1, "${title}: 1 AP_paid bookings");
737 is($total, 0, "${title}: even balance");
741 sub test_default_ap_transaction_two_charts_19_7_with_skonto {
742 my $title = 'default invoice, two items, 19/7% tax without skonto';
744 my $ap_transaction = new_ap_transaction();
746 my %params = ( chart_id => $bank_account->chart_id,
747 transdate => DateTime->today_local->to_kivitendo
750 # $params{amount} = '226'; # pass full amount
751 $params{payment_type} = 'with_skonto_pt';
753 $ap_transaction->pay_invoice( %params );
755 my ($number_of_payments, $paid_amount) = number_of_payments($ap_transaction);
756 my $total = total_amount($ap_transaction);
758 is($paid_amount, 226, "${title}: paid amount");
759 is($number_of_payments, 3, "${title}: 1 AP_paid bookings");
760 is($total, 0, "${title}: even balance");
764 sub test_default_ap_transaction_two_charts_19_7_tax_partial_unrounded_payment_without_skonto {
765 my $title = 'default ap_transaction, two charts, 19/7% tax multiple payments with final difference as skonto';
767 # check whether unrounded amounts passed via $params{amount} are rounded for without_skonto case
768 my $ap_transaction = new_ap_transaction();
769 $ap_transaction->pay_invoice(
770 amount => ( $ap_transaction->amount / 3 * 2),
771 payment_type => 'without_skonto',
772 chart_id => $bank_account->chart_id,
773 transdate => DateTime->today_local->to_kivitendo
775 my ($number_of_payments, $paid_amount) = number_of_payments($ap_transaction);
776 my $total = total_amount($ap_transaction);
778 is($paid_amount, 150.67, "${title}: paid amount");
779 is($number_of_payments, 1, "${title}: 1 AP_paid bookings");
780 is($total, 0, "${title}: even balance");
784 sub test_default_ap_transaction_two_charts_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto {
785 my $title = 'default ap_transaction, two charts, 19/7% tax multiple payments with final difference as skonto';
787 my $ap_transaction = new_ap_transaction();
789 # pay 2/3 and 1/5, leaves 3.83% to be used as Skonto
790 $ap_transaction->pay_invoice(
791 amount => ( $ap_transaction->amount / 3 * 2),
792 payment_type => 'without_skonto',
793 chart_id => $bank_account->chart_id,
794 transdate => DateTime->today_local->to_kivitendo
796 $ap_transaction->pay_invoice(
797 amount => ( $ap_transaction->amount / 5 ),
798 payment_type => 'without_skonto',
799 chart_id => $bank_account->chart_id,
800 transdate => DateTime->today_local->to_kivitendo
802 $ap_transaction->pay_invoice(
803 payment_type => 'difference_as_skonto',
804 chart_id => $bank_account->chart_id,
805 transdate => DateTime->today_local->to_kivitendo
808 my ($number_of_payments, $paid_amount) = number_of_payments($ap_transaction);
809 my $total = total_amount($ap_transaction);
811 is($paid_amount, 226, "${title}: paid amount");
812 is($number_of_payments, 4, "${title}: 1 AP_paid bookings");
813 is($total, 0, "${title}: even balance");
818 sub test_default_invoice_two_items_19_7_tax_with_skonto_50_50 {
819 my $title = 'default invoice, two items, 19/7% tax with_skonto_pt 50/50';
821 my $item1 = create_invoice_item(part => $parts[2], qty => 1);
822 my $item2 = create_invoice_item(part => $parts[3], qty => 1);
823 my $invoice = create_sales_invoice(
825 invoiceitems => [ $item1, $item2 ],
826 payment_id => $payment_terms->id,
830 my %params = ( chart_id => $bank_account->chart_id,
831 transdate => DateTime->today_local->to_kivitendo
834 $params{amount} = $invoice->amount_less_skonto;
835 $params{payment_type} = 'with_skonto_pt';
837 $invoice->pay_invoice( %params );
839 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
840 my $total = total_amount($invoice);
842 is($invoice->netamount, 100, "${title}: netamount");
843 is($invoice->amount, 113, "${title}: amount");
844 is($paid_amount, -113, "${title}: paid amount");
845 is($invoice->paid, 113, "${title}: paid");
846 is($number_of_payments, 3, "${title}: 3 AR_paid bookings");
847 is($total, 0, "${title}: even balance");
851 sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25 {
852 my $title = 'default invoice, four items, 19/7% tax with_skonto_pt 4x25';
854 my $item1 = create_invoice_item(part => $parts[2], qty => 0.5);
855 my $item2 = create_invoice_item(part => $parts[3], qty => 0.5);
856 my $item3 = create_invoice_item(part => $parts[2], qty => 0.5);
857 my $item4 = create_invoice_item(part => $parts[3], qty => 0.5);
858 my $invoice = create_sales_invoice(
860 invoiceitems => [ $item1, $item2, $item3, $item4 ],
861 payment_id => $payment_terms->id,
865 my %params = ( chart_id => $bank_account->chart_id,
866 transdate => DateTime->today_local->to_kivitendo
869 $params{amount} = $invoice->amount_less_skonto;
870 $params{payment_type} = 'with_skonto_pt';
872 $invoice->pay_invoice( %params );
874 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
875 my $total = total_amount($invoice);
877 is($invoice->netamount , 100 , "${title}: netamount");
878 is($invoice->amount , 113 , "${title}: amount");
879 is($paid_amount , -113 , "${title}: paid amount");
880 is($invoice->paid , 113 , "${title}: paid");
881 is($number_of_payments , 3 , "${title}: 3 AR_paid bookings");
882 is($total , 0 , "${title}: even balance");
885 sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_tax_included {
886 my $title = 'default invoice, four items, 19/7% tax with_skonto_pt 4x25';
888 my $item1 = create_invoice_item(part => $parts[2], qty => 0.5);
889 my $item2 = create_invoice_item(part => $parts[3], qty => 0.5);
890 my $item3 = create_invoice_item(part => $parts[2], qty => 0.5);
891 my $item4 = create_invoice_item(part => $parts[3], qty => 0.5);
892 my $invoice = create_sales_invoice(
894 invoiceitems => [ $item1, $item2, $item3, $item4 ],
895 payment_id => $payment_terms->id,
899 my %params = ( chart_id => $bank_account->chart_id,
900 transdate => DateTime->today_local->to_kivitendo
903 $params{amount} = $invoice->amount_less_skonto;
904 $params{payment_type} = 'with_skonto_pt';
906 $invoice->pay_invoice( %params );
908 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
909 my $total = total_amount($invoice);
911 is($invoice->netamount, 88.75, "${title}: netamount");
912 is($invoice->amount, 100, "${title}: amount");
913 is($paid_amount, -100, "${title}: paid amount");
914 is($invoice->paid, 100, "${title}: paid");
915 is($number_of_payments, 3, "${title}: 3 AR_paid bookings");
917 local $TODO = "currently this test fails because the code writing the invoice is buggy, the calculation of skonto is correct";
918 is($total, 0, "${title}: even balance");
922 sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_multiple {
923 my $title = 'default invoice, four items, 19/7% tax with_skonto_pt 4x25';
925 my $item1 = create_invoice_item(part => $parts[2], qty => 0.5);
926 my $item2 = create_invoice_item(part => $parts[3], qty => 0.5);
927 my $item3 = create_invoice_item(part => $parts[2], qty => 0.5);
928 my $item4 = create_invoice_item(part => $parts[3], qty => 0.5);
929 my $invoice = create_sales_invoice(
931 invoiceitems => [ $item1, $item2, $item3, $item4 ],
932 payment_id => $payment_terms->id,
935 $invoice->pay_invoice( amount => '90',
936 payment_type => 'without_skonto',
937 chart_id => $bank_account->chart_id,
938 transdate => DateTime->today_local->to_kivitendo
940 $invoice->pay_invoice( payment_type => 'difference_as_skonto',
941 chart_id => $bank_account->chart_id,
942 transdate => DateTime->today_local->to_kivitendo
945 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
946 my $total = total_amount($invoice);
948 is($invoice->netamount, 100, "${title}: netamount");
949 is($invoice->amount, 113, "${title}: amount");
950 is($paid_amount, -113, "${title}: paid amount");
951 is($invoice->paid, 113, "${title}: paid");
952 is($number_of_payments, 3, "${title}: 3 AR_paid bookings");
953 is($total, 0, "${title}: even balance: this will fail due to rounding error in invoice post, not the skonto");
956 sub test_ar_currency_tax_not_included_and_payment {
957 my $title = 'test_ar_currency_tax_not_included_and_payment_2';
959 my $netamount = $::form->round_amount(75 * $exchangerate->sell,2); # 75 in CUR, 100.00 in EUR
960 my $amount = $::form->round_amount($netamount * 1.19,2); # 100 in CUR, 119.00 in EUR
961 my $invoice = SL::DB::Invoice->new(
964 netamount => $netamount,
965 transdate => $transdate1,
967 customer_id => $customer->id,
968 taxzone_id => $customer->taxzone_id,
969 currency_id => $currency->id,
971 notes => 'test_ar_currency_tax_not_included_and_payment',
973 $invoice->add_ar_amount_row(
974 amount => $invoice->netamount,
975 chart => $ar_amount_chart,
979 $invoice->create_ar_row(chart => $ar_chart);
982 is(SL::DB::Manager::Invoice->get_all_count(where => [ invoice => 0 ]), 1, 'there is one ar transaction');
983 is($invoice->currency_id , $currency->id , 'currency_id has been saved');
984 is($invoice->netamount , 100 , 'ar amount has been converted');
985 is($invoice->amount , 119 , 'ar amount has been converted');
986 is($invoice->taxincluded , 0 , 'ar transaction doesn\'t have taxincluded');
987 is(SL::DB::Manager::AccTransaction->find_by(chart_id => $ar_amount_chart->id, trans_id => $invoice->id)->amount, '100.00000', $ar_amount_chart->accno . ': has been converted for currency');
988 is(SL::DB::Manager::AccTransaction->find_by(chart_id => $ar_chart->id, trans_id => $invoice->id)->amount, '-119.00000', $ar_chart->accno . ': has been converted for currency');
990 $invoice->pay_invoice(chart_id => $bank->id,
993 transdate => $transdate1->to_kivitendo,
995 $invoice->pay_invoice(chart_id => $bank->id,
998 transdate => $transdate1->to_kivitendo,
1000 # $invoice->pay_invoice(chart_id => $bank->id,
1002 # transdate => $transdate2->to_kivitendo,
1004 is(scalar @{$invoice->transactions}, 9, 'ar transaction has 9 transactions (incl. fxtransactions)');
1005 is($invoice->paid, $invoice->amount, 'ar transaction paid = amount in default currency');
1008 sub test_ar_currency_tax_included {
1009 my $title = 'test_ar_currency_tax_included';
1011 # we want the acc_trans amount to be 100
1012 my $amount = $::form->round_amount(75 * $exchangerate->sell * 1.19);
1013 my $netamount = $::form->round_amount($amount / 1.19,2);
1014 my $invoice = SL::DB::Invoice->new(
1018 transdate => $transdate1,
1020 customer_id => $customer->id,
1021 taxzone_id => $customer->taxzone_id,
1022 currency_id => $currency->id,
1023 notes => 'test_ar_currency_tax_included',
1026 $invoice->add_ar_amount_row( # should take care of taxincluded
1027 amount => $invoice->amount, # tax included in local currency
1028 chart => $ar_amount_chart,
1032 $invoice->create_ar_row( chart => $ar_chart );
1034 is(SL::DB::Manager::Invoice->get_all_count(where => [ invoice => 0 ]), 2, 'there are now two ar transactions');
1035 is($invoice->currency_id , $currency->id , 'currency_id has been saved');
1036 is($invoice->amount , $amount , 'amount ok');
1037 is($invoice->netamount , $netamount , 'netamount ok');
1038 is($invoice->taxincluded , 1 , 'ar transaction has taxincluded');
1039 is(SL::DB::Manager::AccTransaction->find_by(chart_id => $ar_amount_chart->id, trans_id => $invoice->id)->amount, '100.00000', $ar_amount_chart->accno . ': has been converted for currency');
1040 is(SL::DB::Manager::AccTransaction->find_by(chart_id => $ar_chart->id, trans_id => $invoice->id)->amount, '-119.00000', $ar_chart->accno . ': has been converted for currency');
1041 $invoice->pay_invoice(chart_id => $bank->id,
1044 transdate => $transdate1->to_kivitendo,
1049 sub test_ap_currency_tax_not_included_and_payment {
1050 my $title = 'test_ap_currency_tax_not_included_and_payment';
1052 my $netamount = $::form->round_amount(75 * $exchangerate->buy,2); # 75 in CUR, 100.00 in EUR
1053 my $amount = $::form->round_amount($netamount * 1.19,2); # 100 in CUR, 119.00 in EUR
1054 my $invoice = SL::DB::PurchaseInvoice->new(
1056 invnumber => 'test_ap_currency_tax_not_included_and_payment',
1058 netamount => $netamount,
1059 transdate => $transdate1,
1061 vendor_id => $vendor->id,
1062 taxzone_id => $vendor->taxzone_id,
1063 currency_id => $currency->id,
1065 notes => 'test_ap_currency_tax_not_included_and_payment',
1067 $invoice->add_ap_amount_row(
1068 amount => $invoice->netamount,
1069 chart => $ap_amount_chart,
1070 tax_id => $tax_9->id,
1073 $invoice->create_ap_row(chart => $ap_chart);
1076 is($invoice->currency_id, $currency->id, 'currency_id has been saved');
1077 is($invoice->netamount, 100, 'ap amount has been converted');
1078 is($invoice->amount, 119, 'ap amount has been converted');
1079 is($invoice->taxincluded, 0, 'ap transaction doesn\'t have taxincluded');
1080 is(SL::DB::Manager::AccTransaction->find_by(chart_id => $ap_amount_chart->id, trans_id => $invoice->id)->amount, '-100.00000', $ap_amount_chart->accno . ': has been converted for currency');
1081 is(SL::DB::Manager::AccTransaction->find_by(chart_id => $ap_chart->id, trans_id => $invoice->id)->amount, '119.00000', $ap_chart->accno . ': has been converted for currency');
1083 $invoice->pay_invoice(chart_id => $bank->id,
1086 transdate => $transdate1->to_kivitendo,
1088 $invoice->pay_invoice(chart_id => $bank->id,
1091 transdate => $transdate1->to_kivitendo,
1093 is(scalar @{$invoice->transactions}, 9, 'ap transaction has 9 transactions (incl. fxtransactions)');
1094 is($invoice->paid, $invoice->amount, 'ap transaction paid = amount in default currency');
1097 sub test_ap_currency_tax_included {
1098 my $title = 'test_ap_currency_tax_included';
1100 # we want the acc_trans amount to be 100
1101 my $amount = $::form->round_amount(75 * $exchangerate->buy * 1.19);
1102 my $netamount = $::form->round_amount($amount / 1.19,2);
1103 my $invoice = SL::DB::PurchaseInvoice->new(
1105 amount => 119, #$amount,
1106 netamount => 100, #$netamount,
1107 transdate => $transdate1,
1109 vendor_id => $vendor->id,
1110 taxzone_id => $vendor->taxzone_id,
1111 currency_id => $currency->id,
1112 notes => 'test_ap_currency_tax_included',
1113 invnumber => 'test_ap_currency_tax_included',
1116 $invoice->add_ap_amount_row( # should take care of taxincluded
1117 amount => $invoice->amount, # tax included in local currency
1118 chart => $ap_amount_chart,
1119 tax_id => $tax_9->id,
1122 $invoice->create_ap_row( chart => $ap_chart );
1124 is($invoice->currency_id , $currency->id , 'currency_id has been saved');
1125 is($invoice->amount , $amount , 'amount ok');
1126 is($invoice->netamount , $netamount , 'netamount ok');
1127 is($invoice->taxincluded , 1 , 'ap transaction has taxincluded');
1128 is(SL::DB::Manager::AccTransaction->find_by(chart_id => $ap_amount_chart->id, trans_id => $invoice->id)->amount, '-100.00000', $ap_amount_chart->accno . ': has been converted for currency');
1129 is(SL::DB::Manager::AccTransaction->find_by(chart_id => $ap_chart->id, trans_id => $invoice->id)->amount, '119.00000', $ap_chart->accno . ': has been converted for currency');
1131 $invoice->pay_invoice(chart_id => $bank->id,
1134 transdate => $transdate1->to_kivitendo,
1139 sub test_ar_currency_tax_not_included_and_payment_2 {
1140 my $title = 'test_ar_currency_tax_not_included_and_payment_2';
1142 my $netamount = $::form->round_amount(125 * $exchangerate2->sell,2); # 125.00 in CUR, 100.00 in EUR
1143 my $amount = $::form->round_amount($netamount * 1.19,2); # 148.75 in CUR, 119.00 in EUR
1144 my $invoice = SL::DB::Invoice->new(
1147 netamount => $netamount,
1148 transdate => $transdate2,
1150 customer_id => $customer->id,
1151 taxzone_id => $customer->taxzone_id,
1152 currency_id => $currency->id,
1154 notes => 'test_ar_currency_tax_not_included_and_payment 0.8',
1155 invnumber => 'test_ar_currency_tax_not_included_and_payment 0.8',
1157 $invoice->add_ar_amount_row(
1158 amount => $invoice->netamount,
1159 chart => $ar_amount_chart,
1163 $invoice->create_ar_row(chart => $ar_chart);
1166 is($invoice->currency_id , $currency->id , "$title: currency_id has been saved");
1167 is($invoice->netamount , 100 , "$title: ar amount has been converted");
1168 is($invoice->amount , 119 , "$title: ar amount has been converted");
1169 is($invoice->taxincluded , 0 , "$title: ar transaction doesn\"t have taxincluded");
1170 is(SL::DB::Manager::AccTransaction->find_by(chart_id => $ar_amount_chart->id, trans_id => $invoice->id)->amount, '100.00000', $title . " " . $ar_amount_chart->accno . ": has been converted for currency");
1171 is(SL::DB::Manager::AccTransaction->find_by(chart_id => $ar_chart->id, trans_id => $invoice->id)->amount, '-119.00000', $title . " " . $ar_chart->accno . ': has been converted for currency');
1173 $invoice->pay_invoice(chart_id => $bank->id,
1176 transdate => $transdate2->to_kivitendo,
1178 $invoice->pay_invoice(chart_id => $bank->id,
1181 transdate => $transdate3->to_kivitendo,
1183 $invoice->pay_invoice(chart_id => $bank->id,
1186 transdate => $transdate4->to_kivitendo,
1188 # $invoice->pay_invoice(chart_id => $bank->id,
1190 # transdate => $transdate2->to_kivitendo,
1192 my $fx_transactions = SL::DB::Manager::AccTransaction->get_all(where => [ trans_id => $invoice->id, fx_transaction => 1 ], sort_by => ('acc_trans_id'));
1193 is(scalar @{$fx_transactions}, 3, "$title: ar transaction has 3 fx transactions");
1194 is($fx_transactions->[0]->amount, '24.69000', "$title fx transactions 1: 123.45-(123.45*0.8) = 24.69");
1196 is(scalar @{$invoice->transactions}, 14, "$title ar transaction has 14 transactions (incl. fxtransactions and fx_gain)");
1197 is($invoice->paid, $invoice->amount, "$title ar transaction paid = amount in default currency");
1200 sub test_ar_currency_tax_not_included_and_payment_2_credit_note {
1201 my $title = 'test_ar_currency_tax_not_included_and_payment_2_credit_note';
1203 my $netamount = $::form->round_amount(-125 * $exchangerate2->sell,2); # 125.00 in CUR, 100.00 in EUR
1204 my $amount = $::form->round_amount($netamount * 1.19,2); # 148.75 in CUR, 119.00 in EUR
1205 my $invoice = SL::DB::Invoice->new(
1208 netamount => $netamount,
1209 transdate => $transdate2,
1211 customer_id => $customer->id,
1212 taxzone_id => $customer->taxzone_id,
1213 currency_id => $currency->id,
1215 notes => 'test_ar_currency_tax_not_included_and_payment credit note 0.8',
1216 invnumber => 'test_ar_currency_tax_not_included_and_payment credit note 0.8',
1218 $invoice->add_ar_amount_row(
1219 amount => $invoice->netamount,
1220 chart => $ar_amount_chart,
1224 $invoice->create_ar_row(chart => $ar_chart);
1227 is($invoice->currency_id , $currency->id , 'currency_id has been saved');
1228 is($invoice->netamount , -100 , 'ar amount has been converted');
1229 is($invoice->amount , -119 , 'ar amount has been converted');
1230 is($invoice->taxincluded , 0 , 'ar transaction doesn\'t have taxincluded');
1231 is(SL::DB::Manager::AccTransaction->find_by(chart_id => $ar_amount_chart->id, trans_id => $invoice->id)->amount, '-100.00000', $ar_amount_chart->accno . ': has been converted for currency');
1232 is(SL::DB::Manager::AccTransaction->find_by(chart_id => $ar_chart->id, trans_id => $invoice->id)->amount, '119.00000', $ar_chart->accno . ': has been converted for currency');
1234 $invoice->pay_invoice(chart_id => $bank->id,
1237 transdate => $transdate2->to_kivitendo,
1239 $invoice->pay_invoice(chart_id => $bank->id,
1242 transdate => $transdate2->to_kivitendo,
1244 my $fx_transactions = SL::DB::Manager::AccTransaction->get_all(where => [ trans_id => $invoice->id, fx_transaction => 1 ], sort_by => ('acc_trans_id'));
1245 is(scalar @{$fx_transactions}, 2, 'ar transaction has 2 fx transactions');
1246 is($fx_transactions->[0]->amount, '-24.69000', 'fx transactions 1: 123.45-(123.45*0.8) = 24.69');
1248 is(scalar @{$invoice->transactions}, 9, 'ar transaction has 9 transactions (incl. fxtransactions)');
1249 is($invoice->paid, $invoice->amount, 'ar transaction paid = amount in default currency');
1252 sub test_ap_currency_tax_not_included_and_payment_2 {
1253 my $title = 'test_ap_currency_tax_not_included_and_payment_2';
1255 my $netamount = $::form->round_amount(125 * $exchangerate2->sell,2); # 125.00 in CUR, 100.00 in EUR
1256 my $amount = $::form->round_amount($netamount * 1.19,2); # 148.75 in CUR, 119.00 in EUR
1257 my $invoice = SL::DB::PurchaseInvoice->new(
1260 netamount => $netamount,
1261 transdate => $transdate2,
1263 vendor_id => $vendor->id,
1264 taxzone_id => $vendor->taxzone_id,
1265 currency_id => $currency->id,
1267 notes => 'test_ap_currency_tax_not_included_and_payment_2 0.8 + 1.33333',
1268 invnumber => 'test_ap_currency_tax_not_included_and_payment_2 0.8 + 1.33333',
1270 $invoice->add_ap_amount_row(
1271 amount => $invoice->netamount,
1272 chart => $ap_amount_chart,
1273 tax_id => $tax_9->id,
1276 $invoice->create_ap_row(chart => $ap_chart);
1279 is($invoice->currency_id , $currency->id , "$title: currency_id has been saved");
1280 is($invoice->netamount , 100 , "$title: ap amount has been converted");
1281 is($invoice->amount , 119 , "$title: ap amount has been converted");
1282 is($invoice->taxincluded , 0 , "$title: ap transaction doesn\'t have taxincluded");
1283 is(SL::DB::Manager::AccTransaction->find_by(chart_id => $ap_amount_chart->id, trans_id => $invoice->id)->amount, '-100.00000', $ap_amount_chart->accno . ': has been converted for currency');
1284 is(SL::DB::Manager::AccTransaction->find_by(chart_id => $ap_chart->id, trans_id => $invoice->id)->amount, '119.00000', $ap_chart->accno . ': has been converted for currency');
1286 $invoice->pay_invoice(chart_id => $bank->id,
1289 transdate => $transdate2->to_kivitendo,
1291 $invoice->pay_invoice(chart_id => $bank->id,
1294 transdate => $transdate3->to_kivitendo,
1296 $invoice->pay_invoice(chart_id => $bank->id,
1299 transdate => $transdate4->to_kivitendo,
1301 my $fx_transactions = SL::DB::Manager::AccTransaction->get_all(where => [ trans_id => $invoice->id, fx_transaction => 1 ], sort_by => ('acc_trans_id'));
1302 is(scalar @{$fx_transactions}, 3, "$title: ap transaction has 3 fx transactions");
1303 is($fx_transactions->[0]->amount, '-2.00000', "$title: fx transaction 1: 10.00-( 10.00*0.80000) = 2.00000");
1304 is($fx_transactions->[1]->amount, '68.59000', "$title: fx transaction 2: 123.45-(123.45*1.55557) = -68.58511");
1305 is($fx_transactions->[2]->amount, '-3.40000', "$title: fx transaction 3: 15.30-(15.30 *0.77777) = 3.40012");
1307 my $fx_loss_transactions = SL::DB::Manager::AccTransaction->get_all(where => [ trans_id => $invoice->id, chart_id => $fxloss_chart->id ], sort_by => ('acc_trans_id'));
1308 my $fx_gain_transactions = SL::DB::Manager::AccTransaction->get_all(where => [ trans_id => $invoice->id, chart_id => $fxgain_chart->id ], sort_by => ('acc_trans_id'));
1309 is($fx_gain_transactions->[0]->amount, '0.34000', "$title: fx gain amount ok");
1310 is($fx_loss_transactions->[0]->amount, '-93.28000', "$title: fx loss amount ok");
1312 is(scalar @{$invoice->transactions}, 14, "$title: ap transaction has 14 transactions (incl. fxtransactions and gain_loss)");
1313 is($invoice->paid, $invoice->amount, "$title: ap transaction paid = amount in default currency");
1314 is(total_amount($invoice), 0, "$title: even balance");
1317 sub test_ap_currency_tax_not_included_and_payment_2_credit_note {
1318 my $title = 'test_ap_currency_tax_not_included_and_payment_2_credit_note';
1320 my $netamount = $::form->round_amount(-125 * $exchangerate2->sell,2); # 125.00 in CUR, 100.00 in EUR
1321 my $amount = $::form->round_amount($netamount * 1.19,2); # 148.75 in CUR, 119.00 in EUR
1322 my $invoice = SL::DB::PurchaseInvoice->new(
1325 netamount => $netamount,
1326 transdate => $transdate2,
1328 vendor_id => $vendor->id,
1329 taxzone_id => $vendor->taxzone_id,
1330 currency_id => $currency->id,
1332 notes => 'test_ap_currency_tax_not_included_and_payment credit note 0.8 + 1.33333',
1333 invnumber => 'test_ap_currency_tax_not_included_and_payment credit note 0.8 + 1.33333',
1335 $invoice->add_ap_amount_row(
1336 amount => $invoice->netamount,
1337 chart => $ap_amount_chart,
1338 tax_id => $tax_9->id,
1341 $invoice->create_ap_row(chart => $ap_chart);
1344 is($invoice->currency_id , $currency->id , "$title: currency_id has been saved");
1345 is($invoice->netamount , -100 , "$title: ap amount has been converted");
1346 is($invoice->amount , -119 , "$title: ap amount has been converted");
1347 is($invoice->taxincluded , 0 , "$title: ap transaction doesn\'t have taxincluded");
1348 is(SL::DB::Manager::AccTransaction->find_by(chart_id => $ap_amount_chart->id, trans_id => $invoice->id)->amount, '100.00000', $ap_amount_chart->accno . ': has been converted for currency');
1349 is(SL::DB::Manager::AccTransaction->find_by(chart_id => $ap_chart->id, trans_id => $invoice->id)->amount, '-119.00000', $ap_chart->accno . ': has been converted for currency');
1351 $invoice->pay_invoice(chart_id => $bank->id,
1354 transdate => $transdate2->to_kivitendo,
1356 $invoice->pay_invoice(chart_id => $bank->id,
1359 transdate => $transdate3->to_kivitendo,
1361 $invoice->pay_invoice(chart_id => $bank->id,
1364 transdate => $transdate4->to_kivitendo,
1366 my $fx_transactions = SL::DB::Manager::AccTransaction->get_all(where => [ trans_id => $invoice->id, fx_transaction => 1 ], sort_by => ('acc_trans_id'));
1367 is(scalar @{$fx_transactions}, 3, "$title: ap transaction has 3 fx transactions");
1368 is($fx_transactions->[0]->amount, '2.00000', "$title: fx transaction 1: 10.00-( 10.00*0.80000) = 2.00000");
1369 is($fx_transactions->[1]->amount, '-68.59000', "$title: fx transaction 2: 123.45-(123.45*1.55557) = -68.58511");
1370 is($fx_transactions->[2]->amount, '3.40000', "$title: fx transaction 3: 15.30-(15.30 *0.77777) = 3.40012");
1372 my $fx_gain_loss_transactions = SL::DB::Manager::AccTransaction->get_all(where => [ trans_id => $invoice->id, chart_id => $fxgain_chart->id ], sort_by => ('acc_trans_id'));
1373 is($fx_gain_loss_transactions->[0]->amount, '93.28000', "$title: fx gain loss amount ok");
1375 is(scalar @{$invoice->transactions}, 14, "$title: ap transaction has 14 transactions (incl. fxtransactions and gain_loss)");
1376 is($invoice->paid, $invoice->amount, "$title: ap transaction paid = amount in default currency");
1377 is(total_amount($invoice), 0, "$title: even balance");
1380 sub test_credit_note_two_items_19_7_tax_tax_not_included {
1381 my $title = 'test_credit_note_two_items_19_7_tax_tax_not_included';
1383 my $item1 = create_invoice_item(part => $parts[0], qty => 5);
1384 my $item2 = create_invoice_item(part => $parts[1], qty => 3);
1385 my $invoice = create_credit_note(
1388 invoiceitems => [ $item1, $item2 ],
1392 my %params = ( chart_id => $bank_account->chart_id,
1393 transdate => DateTime->today_local->to_kivitendo,
1396 $params{amount} = $invoice->amount,
1398 $invoice->pay_invoice( %params );
1400 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
1401 my $total = total_amount($invoice);
1403 is($invoice->netamount, -40.84, "${title}: netamount");
1404 is($invoice->amount, -45.10, "${title}: amount");
1405 is($paid_amount, 45.10, "${title}: paid amount according to acc_trans is positive (Haben)");
1406 is($invoice->paid, -45.10, "${title}: paid");
1407 is($number_of_payments, 1, "${title}: 1 AR_paid bookings");
1408 is($total, 0, "${title}: even balance");