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_local;
114 $transdate1->set_year(2019) if $transdate1->year == 2020; # hardcode for 2019 in 2020, because of tax rate change in Germany
115 $transdate2 = $transdate1->clone->add(days => 1);
116 $transdate3 = $transdate1->clone->add(days => 2);
117 $transdate4 = $transdate1->clone->add(days => 3);
119 $buchungsgruppe = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 19%') || croak "No accounting group";
120 $buchungsgruppe7 = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 7%') || croak "No accounting group for 7\%";
121 $unit = SL::DB::Manager::Unit->find_by(name => 'kg') || croak "No unit";
122 $employee = SL::DB::Manager::Employee->current || croak "No employee";
123 $tax = SL::DB::Manager::Tax->find_by(taxkey => 3, rate => 0.19) || croak "No tax";
124 $tax7 = SL::DB::Manager::Tax->find_by(taxkey => 2, rate => 0.07) || croak "No tax for 7\%";
125 $taxzone = SL::DB::Manager::TaxZone->find_by( description => 'Inland') || croak "No taxzone";
126 $tax_9 = SL::DB::Manager::Tax->find_by(taxkey => 9, rate => 0.19) || croak "No tax";
127 # $tax7 = SL::DB::Manager::Tax->find_by(taxkey => 2, rate => 0.07) || croak "No tax for 7\%";
129 $currency_id = $::instance_conf->get_currency_id;
131 $currency = SL::DB::Currency->new(name => 'CUR')->save;
133 $fxgain_chart = SL::DB::Manager::Chart->find_by(accno => '2660') or die "Can't find fxgain_chart in test";
134 $fxloss_chart = SL::DB::Manager::Chart->find_by(accno => '2150') or die "Can't find fxloss_chart in test";
136 $currency->db->dbh->do('UPDATE defaults SET fxgain_accno_id = ' . $fxgain_chart->id);
137 $currency->db->dbh->do('UPDATE defaults SET fxloss_accno_id = ' . $fxloss_chart->id);
138 $::instance_conf->reload->data;
139 is($fxgain_chart->id, $::instance_conf->get_fxgain_accno_id, "fxgain_chart was updated in defaults");
140 is($fxloss_chart->id, $::instance_conf->get_fxloss_accno_id, "fxloss_chart was updated in defaults");
142 $exchangerate = SL::DB::Exchangerate->new(transdate => $transdate1,
145 currency_id => $currency->id,
147 $exchangerate2 = SL::DB::Exchangerate->new(transdate => $transdate2,
150 currency_id => $currency->id,
152 $exchangerate3 = SL::DB::Exchangerate->new(transdate => $transdate3,
155 currency_id => $currency->id,
157 $exchangerate4 = SL::DB::Exchangerate->new(transdate => $transdate4,
160 currency_id => $currency->id,
163 $customer = new_customer(
164 name => 'Test Customer',
165 currency_id => $currency_id,
166 taxzone_id => $taxzone->id,
169 $bank_account = SL::DB::BankAccount->new(
170 account_number => '123',
175 chart_id => SL::DB::Manager::Chart->find_by( description => 'Bank' )->id,
176 name => SL::DB::Manager::Chart->find_by( description => 'Bank' )->description,
179 $payment_terms = SL::DB::PaymentTerm->new(
180 description => 'payment',
181 description_long => 'payment',
184 percent_skonto => '0.05',
185 auto_calculation => 1,
188 $vendor = new_vendor(
189 name => 'Test Vendor',
190 currency_id => $currency_id,
191 taxzone_id => $taxzone->id,
192 payment_id => $payment_terms->id,
197 push @parts, new_part(
198 partnumber => 'T4254',
199 description => 'Fourty-two fifty-four',
202 buchungsgruppen_id => $buchungsgruppe->id,
207 push @parts, new_part(
208 partnumber => 'T0815',
209 description => 'Zero EIGHT fifteeN @ 7%',
212 buchungsgruppen_id => $buchungsgruppe7->id,
216 push @parts, new_part(
218 description => 'Testware 19%',
221 buchungsgruppen_id => $buchungsgruppe->id,
225 push @parts, new_part(
227 description => 'Testware 7%',
230 buchungsgruppen_id => $buchungsgruppe7->id,
235 $ar_chart = SL::DB::Manager::Chart->find_by( accno => '1400' ); # Forderungen
236 $ap_chart = SL::DB::Manager::Chart->find_by( accno => '1600' ); # Verbindlichkeiten
237 $bank = SL::DB::Manager::Chart->find_by( accno => '1200' ); # Bank
238 $ar_amount_chart = SL::DB::Manager::Chart->find_by( accno => '8400' ); # Erlöse
239 $ap_amount_chart = SL::DB::Manager::Chart->find_by( accno => '3400' ); # Wareneingang 19%
242 sub new_ap_transaction {
243 $ap_transaction_counter++;
245 my $ap_transaction = create_ap_transaction(
247 invnumber => 'newap ' . $ap_transaction_counter,
251 gldate => $transdate1,
252 taxzone_id => $taxzone->id,
253 transdate => $transdate1,
256 chart => SL::DB::Manager::Chart->find_by(accno => '3400'),
260 chart => SL::DB::Manager::Chart->find_by(accno => '3300'),
266 return $ap_transaction;
269 sub number_of_payments {
272 my $number_of_payments;
274 foreach my $transaction ( @{ $invoice->transactions } ) {
275 if ( $transaction->chart_link =~ /(AR_paid|AP_paid)/ ) {
276 $paid_amount += $transaction->amount ;
277 $number_of_payments++;
280 return ($number_of_payments, $paid_amount);
286 my $total = sum map { $_->amount } @{ $invoice->transactions };
288 return $::form->round_amount($total, 5);
294 sub test_default_invoice_one_item_19_without_skonto {
295 my $title = 'default invoice, one item, 19% tax, without_skonto';
296 my $item = create_invoice_item(part => $parts[0], qty => 2.5);
297 my $invoice = create_sales_invoice(
298 transdate => $transdate1,
300 invoiceitems => [ $item ],
301 payment_id => $payment_terms->id,
304 my $ap_transaction = new_ap_transaction();
307 my %params = ( chart_id => $bank_account->chart_id,
308 transdate => $transdate1,
311 $params{amount} = '6.96';
312 $params{payment_type} = 'without_skonto';
314 $invoice->pay_invoice( %params );
316 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
317 my $total = total_amount($invoice);
319 is($invoice->netamount, 5.85, "${title}: netamount");
320 is($invoice->amount, 6.96, "${title}: amount");
321 is($paid_amount, -6.96, "${title}: paid amount");
322 is($number_of_payments, 1, "${title}: 1 AR_paid booking");
323 is($invoice->paid, 6.96, "${title}: paid");
324 is($total, 0, "${title}: even balance");
328 sub test_default_invoice_one_item_19_without_skonto_overpaid {
329 my $title = 'default invoice, one item, 19% tax, without_skonto';
331 my $item = create_invoice_item(part => $parts[0], qty => 2.5);
332 my $invoice = create_sales_invoice(
334 transdate => $transdate1,
335 invoiceitems => [ $item ],
336 payment_id => $payment_terms->id,
339 my $ap_transaction = new_ap_transaction();
343 my %params = ( chart_id => $bank_account->chart_id,
344 transdate => $transdate1,
347 $params{amount} = '16.96';
348 $params{payment_type} = 'without_skonto';
349 $invoice->pay_invoice( %params );
351 $params{amount} = '-10.00';
352 $invoice->pay_invoice( %params );
354 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
355 my $total = total_amount($invoice);
357 is($invoice->netamount, 5.85, "${title}: netamount");
358 is($invoice->amount, 6.96, "${title}: amount");
359 is($paid_amount, -6.96, "${title}: paid amount");
360 is($number_of_payments, 2, "${title}: 1 AR_paid booking");
361 is($invoice->paid, 6.96, "${title}: paid");
362 is($total, 0, "${title}: even balance");
368 sub test_default_invoice_two_items_19_7_tax_with_skonto {
369 my $title = 'default invoice, two items, 19/7% tax with_skonto_pt';
371 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
372 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
373 my $invoice = create_sales_invoice(
375 transdate => $transdate1,
376 invoiceitems => [ $item1, $item2 ],
377 payment_id => $payment_terms->id,
381 my %params = ( chart_id => $bank_account->chart_id,
382 transdate => $transdate1,
385 $params{payment_type} = 'with_skonto_pt';
386 $params{amount} = $invoice->amount_less_skonto;
388 $invoice->pay_invoice( %params );
390 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
391 my $total = total_amount($invoice);
393 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
394 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
395 is($paid_amount, -19.44, "${title}: paid amount");
396 is($invoice->paid, 19.44, "${title}: paid");
397 is($number_of_payments, 3, "${title}: 3 AR_paid bookings");
398 is($total, 0, "${title}: even balance");
401 sub test_default_invoice_two_items_19_7_tax_with_skonto_tax_included {
402 my $title = 'default invoice, two items, 19/7% tax with_skonto_pt';
404 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
405 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
406 my $invoice = create_sales_invoice(
407 transdate => $transdate1,
409 invoiceitems => [ $item1, $item2 ],
410 payment_id => $payment_terms->id,
414 my %params = ( chart_id => $bank_account->chart_id,
415 transdate => $transdate1,
418 $params{payment_type} = 'with_skonto_pt';
419 $params{amount} = $invoice->amount_less_skonto;
421 $invoice->pay_invoice( %params );
423 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
424 my $total = total_amount($invoice);
426 is($invoice->netamount, 15.82, "${title}: netamount");
427 is($invoice->amount, 17.51, "${title}: amount");
428 is($paid_amount, -17.51, "${title}: paid amount");
429 is($invoice->paid, 17.51, "${title}: paid");
430 is($number_of_payments, 3, "${title}: 3 AR_paid bookings");
433 local $TODO = "currently this test fails because the code writing the invoice is buggy, the calculation of skonto is correct";
434 is($total, 0, "${title}: even balance");
438 # test 3 : two items, without skonto
439 sub test_default_invoice_two_items_19_7_without_skonto {
440 my $title = 'default invoice, two items, 19/7% tax without skonto';
442 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
443 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
444 my $invoice = create_sales_invoice(
445 transdate => $transdate1,
447 invoiceitems => [ $item1, $item2 ],
448 payment_id => $payment_terms->id,
452 my %params = ( chart_id => $bank_account->chart_id,
453 transdate => $transdate1,
456 $params{amount} = '19.44'; # pass full amount
457 $params{payment_type} = 'without_skonto';
459 $invoice->pay_invoice( %params );
461 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
462 my $total = total_amount($invoice);
464 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
465 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
466 is($paid_amount, -19.44, "${title}: paid amount");
467 is($invoice->paid, 19.44, "${title}: paid");
468 is($number_of_payments, 1, "${title}: 1 AR_paid bookings");
469 is($total, 0, "${title}: even balance");
473 sub test_default_invoice_two_items_19_7_without_skonto_incomplete_payment {
474 my $title = 'default invoice, two items, 19/7% tax without skonto incomplete payment';
476 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
477 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
478 my $invoice = create_sales_invoice(
480 transdate => $transdate1,
481 invoiceitems => [ $item1, $item2 ],
482 payment_id => $payment_terms->id,
485 $invoice->pay_invoice( amount => '9.44',
486 payment_type => 'without_skonto',
487 chart_id => $bank_account->chart_id,
488 transdate => $transdate1,
491 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
492 my $total = total_amount($invoice);
494 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
495 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
496 is($paid_amount, -9.44, "${title}: paid amount");
497 is($invoice->paid, 9.44, "${title}: paid");
498 is($number_of_payments, 1, "${title}: 1 AR_paid bookings");
499 is($total, 0, "${title}: even balance");
503 sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments {
504 my $title = 'default invoice, two items, 19/7% tax not included';
506 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
507 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
508 my $invoice = create_sales_invoice(
509 transdate => $transdate1,
511 invoiceitems => [ $item1, $item2 ],
512 payment_id => $payment_terms->id,
515 $invoice->pay_invoice( amount => '9.44',
516 payment_type => 'without_skonto',
517 chart_id => $bank_account->chart_id,
518 transdate => $transdate1,
520 $invoice->pay_invoice( amount => '10.00',
521 chart_id => $bank_account->chart_id,
522 transdate => $transdate1,
525 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
526 my $total = total_amount($invoice);
528 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
529 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
530 is($paid_amount, -19.44, "${title}: paid amount");
531 is($invoice->paid, 19.44, "${title}: paid");
532 is($number_of_payments, 2, "${title}: 2 AR_paid bookings");
533 is($total, 0, "${title}: even balance");
538 sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto {
539 my $title = 'default invoice, two items, 19/7% tax not included';
541 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
542 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
543 my $invoice = create_sales_invoice(
545 transdate => $transdate1,
546 invoiceitems => [ $item1, $item2 ],
547 payment_id => $payment_terms->id,
550 $invoice->pay_invoice( amount => '9.44',
551 payment_type => 'without_skonto',
552 chart_id => $bank_account->chart_id,
553 transdate => $transdate1,
555 $invoice->pay_invoice( amount => '8.73',
556 payment_type => 'without_skonto',
557 chart_id => $bank_account->chart_id,
558 transdate => $transdate1,
560 $invoice->pay_invoice( amount => $invoice->open_amount,
561 payment_type => 'difference_as_skonto',
562 chart_id => $bank_account->chart_id,
563 transdate => $transdate1,
566 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
567 my $total = total_amount($invoice);
569 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
570 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
571 is($paid_amount, -19.44, "${title}: paid amount");
572 is($invoice->paid, 19.44, "${title}: paid");
573 is($number_of_payments, 4, "${title}: 4 AR_paid bookings");
574 is($total, 0, "${title}: even balance");
578 sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto_1cent {
579 my $title = 'default invoice, two items, 19/7% tax not included';
581 # if there is only one cent left there can only be one skonto booking, the
582 # error handling should choose the highest amount, which is the 7% account
583 # (11.66) rather than the 19% account (5.85). The actual tax amount is
584 # higher for the 19% case, though (1.11 compared to 0.82)
586 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
587 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
588 my $invoice = create_sales_invoice(
590 transdate => $transdate1,
591 invoiceitems => [ $item1, $item2 ],
592 payment_id => $payment_terms->id,
595 $invoice->pay_invoice( amount => '19.42',
596 payment_type => 'without_skonto',
597 chart_id => $bank_account->chart_id,
598 transdate => $transdate1,
600 $invoice->pay_invoice( amount => $invoice->open_amount,
601 payment_type => 'difference_as_skonto',
602 chart_id => $bank_account->chart_id,
603 transdate => $transdate1,
606 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
607 my $total = total_amount($invoice);
609 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
610 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
611 is($paid_amount, -19.44, "${title}: paid amount");
612 is($invoice->paid, 19.44, "${title}: paid");
613 is($number_of_payments, 3, "${title}: 2 AR_paid bookings");
614 is($total, 0, "${title}: even balance");
618 sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto_2cent {
619 my $title = 'default invoice, two items, 19/7% tax not included';
621 # if there are two cents left there will be two skonto bookings, 1 cent each
622 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
623 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
624 my $invoice = create_sales_invoice(
626 transdate => $transdate1,
627 invoiceitems => [ $item1, $item2 ],
628 payment_id => $payment_terms->id,
631 $invoice->pay_invoice( amount => '19.42',
632 payment_type => 'without_skonto',
633 chart_id => $bank_account->chart_id,
634 transdate => $transdate1,
636 $invoice->pay_invoice( amount => $invoice->open_amount,
637 payment_type => 'difference_as_skonto',
638 chart_id => $bank_account->chart_id,
639 transdate => $transdate1,
642 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
643 my $total = total_amount($invoice);
645 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
646 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
647 is($paid_amount, -19.44, "${title}: paid amount");
648 is($invoice->paid, 19.44, "${title}: paid");
649 is($number_of_payments, 3, "${title}: 3 AR_paid bookings");
650 is($total, 0, "${title}: even balance");
654 sub test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto {
655 my $title = 'default invoice, one item, 19% tax, without_skonto';
657 my $item = create_invoice_item(part => $parts[0], qty => 2.5);
658 my $invoice = create_sales_invoice(
660 transdate => $transdate1,
661 invoiceitems => [ $item ],
662 payment_id => $payment_terms->id,
666 my %params = ( chart_id => $bank_account->chart_id,
667 transdate => $transdate1,
670 $params{amount} = '2.32';
671 $params{payment_type} = 'without_skonto';
672 $invoice->pay_invoice( %params );
674 $params{amount} = '3.81';
675 $params{payment_type} = 'without_skonto';
676 $invoice->pay_invoice( %params );
678 $params{amount} = $invoice->open_amount; # set amount, otherwise previous 3.81 is used
679 $params{payment_type} = 'difference_as_skonto';
680 $invoice->pay_invoice( %params );
682 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
683 my $total = total_amount($invoice);
685 is($invoice->netamount, 5.85, "${title}: netamount");
686 is($invoice->amount, 6.96, "${title}: amount");
687 is($paid_amount, -6.96, "${title}: paid amount");
688 is($number_of_payments, 3, "${title}: 3 AR_paid booking");
689 is($invoice->paid, 6.96, "${title}: paid");
690 is($total, 0, "${title}: even balance");
694 sub test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto_1cent {
695 my $title = 'default invoice, one item, 19% tax, without_skonto';
697 my $item = create_invoice_item(part => $parts[0], qty => 2.5);
698 my $invoice = create_sales_invoice(
700 transdate => $transdate1,
701 invoiceitems => [ $item ],
702 payment_id => $payment_terms->id,
706 my %params = ( chart_id => $bank_account->chart_id,
707 transdate => $transdate1,
710 $params{amount} = '6.95';
711 $params{payment_type} = 'without_skonto';
712 $invoice->pay_invoice( %params );
714 $params{amount} = $invoice->open_amount; # set amount, otherwise previous value 6.95 is used
715 $params{payment_type} = 'difference_as_skonto';
716 $invoice->pay_invoice( %params );
718 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
719 my $total = total_amount($invoice);
721 is($invoice->netamount, 5.85, "${title}: netamount");
722 is($invoice->amount, 6.96, "${title}: amount");
723 is($paid_amount, -6.96, "${title}: paid amount");
724 is($number_of_payments, 2, "${title}: 3 AR_paid booking");
725 is($invoice->paid, 6.96, "${title}: paid");
726 is($total, 0, "${title}: even balance");
730 # test 3 : two items, without skonto
731 sub test_default_ap_transaction_two_charts_19_7_without_skonto {
732 my $title = 'default invoice, two items, 19/7% tax without skonto';
734 my $ap_transaction = new_ap_transaction();
736 my %params = ( chart_id => $bank_account->chart_id,
737 transdate => $transdate1,
740 $params{amount} = '226'; # pass full amount
741 $params{payment_type} = 'without_skonto';
743 $ap_transaction->pay_invoice( %params );
745 my ($number_of_payments, $paid_amount) = number_of_payments($ap_transaction);
746 my $total = total_amount($ap_transaction);
748 is($paid_amount, 226, "${title}: paid amount");
749 is($number_of_payments, 1, "${title}: 1 AP_paid bookings");
750 is($total, 0, "${title}: even balance");
754 sub test_default_ap_transaction_two_charts_19_7_with_skonto {
755 my $title = 'default invoice, two items, 19/7% tax without skonto';
757 my $ap_transaction = new_ap_transaction();
759 my %params = ( chart_id => $bank_account->chart_id,
760 transdate => $transdate1,
763 # $params{amount} = '226'; # pass full amount
764 $params{payment_type} = 'with_skonto_pt';
766 $ap_transaction->payment_terms($ap_transaction->vendor->payment);
767 $ap_transaction->pay_invoice( %params );
769 my ($number_of_payments, $paid_amount) = number_of_payments($ap_transaction);
770 my $total = total_amount($ap_transaction);
772 is($paid_amount, 226, "${title}: paid amount");
773 is($number_of_payments, 3, "${title}: 1 AP_paid bookings");
774 is($total, 0, "${title}: even balance");
778 sub test_default_ap_transaction_two_charts_19_7_tax_partial_unrounded_payment_without_skonto {
779 my $title = 'default ap_transaction, two charts, 19/7% tax multiple payments with final difference as skonto';
781 # check whether unrounded amounts passed via $params{amount} are rounded for without_skonto case
782 my $ap_transaction = new_ap_transaction();
783 $ap_transaction->pay_invoice(
784 amount => ( $ap_transaction->amount / 3 * 2),
785 payment_type => 'without_skonto',
786 chart_id => $bank_account->chart_id,
787 transdate => $transdate1,
789 my ($number_of_payments, $paid_amount) = number_of_payments($ap_transaction);
790 my $total = total_amount($ap_transaction);
792 is($paid_amount, 150.67, "${title}: paid amount");
793 is($number_of_payments, 1, "${title}: 1 AP_paid bookings");
794 is($total, 0, "${title}: even balance");
798 sub test_default_ap_transaction_two_charts_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto {
799 my $title = 'default ap_transaction, two charts, 19/7% tax multiple payments with final difference as skonto';
801 my $ap_transaction = new_ap_transaction();
803 # pay 2/3 and 1/5, leaves 3.83% to be used as Skonto
804 $ap_transaction->pay_invoice(
805 amount => ( $ap_transaction->amount / 3 * 2),
806 payment_type => 'without_skonto',
807 chart_id => $bank_account->chart_id,
808 transdate => $transdate1,
810 $ap_transaction->pay_invoice(
811 amount => ( $ap_transaction->amount / 5 ),
812 payment_type => 'without_skonto',
813 chart_id => $bank_account->chart_id,
814 transdate => $transdate1,
816 $ap_transaction->pay_invoice(
817 payment_type => 'difference_as_skonto',
818 chart_id => $bank_account->chart_id,
819 transdate => $transdate1,
822 my ($number_of_payments, $paid_amount) = number_of_payments($ap_transaction);
823 my $total = total_amount($ap_transaction);
825 is($paid_amount, 226, "${title}: paid amount");
826 is($number_of_payments, 4, "${title}: 1 AP_paid bookings");
827 is($total, 0, "${title}: even balance");
832 sub test_default_invoice_two_items_19_7_tax_with_skonto_50_50 {
833 my $title = 'default invoice, two items, 19/7% tax with_skonto_pt 50/50';
835 my $item1 = create_invoice_item(part => $parts[2], qty => 1);
836 my $item2 = create_invoice_item(part => $parts[3], qty => 1);
837 my $invoice = create_sales_invoice(
839 transdate => $transdate1,
840 invoiceitems => [ $item1, $item2 ],
841 payment_id => $payment_terms->id,
845 my %params = ( chart_id => $bank_account->chart_id,
846 transdate => $transdate1,
849 $params{amount} = $invoice->amount_less_skonto;
850 $params{payment_type} = 'with_skonto_pt';
852 $invoice->pay_invoice( %params );
854 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
855 my $total = total_amount($invoice);
857 is($invoice->netamount, 100, "${title}: netamount");
858 is($invoice->amount, 113, "${title}: amount");
859 is($paid_amount, -113, "${title}: paid amount");
860 is($invoice->paid, 113, "${title}: paid");
861 is($number_of_payments, 3, "${title}: 3 AR_paid bookings");
862 is($total, 0, "${title}: even balance");
866 sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25 {
867 my $title = 'default invoice, four items, 19/7% tax with_skonto_pt 4x25';
869 my $item1 = create_invoice_item(part => $parts[2], qty => 0.5);
870 my $item2 = create_invoice_item(part => $parts[3], qty => 0.5);
871 my $item3 = create_invoice_item(part => $parts[2], qty => 0.5);
872 my $item4 = create_invoice_item(part => $parts[3], qty => 0.5);
873 my $invoice = create_sales_invoice(
875 transdate => $transdate1,
876 invoiceitems => [ $item1, $item2, $item3, $item4 ],
877 payment_id => $payment_terms->id,
881 my %params = ( chart_id => $bank_account->chart_id,
882 transdate => $transdate1,
885 $params{amount} = $invoice->amount_less_skonto;
886 $params{payment_type} = 'with_skonto_pt';
888 $invoice->pay_invoice( %params );
890 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
891 my $total = total_amount($invoice);
893 is($invoice->netamount , 100 , "${title}: netamount");
894 is($invoice->amount , 113 , "${title}: amount");
895 is($paid_amount , -113 , "${title}: paid amount");
896 is($invoice->paid , 113 , "${title}: paid");
897 is($number_of_payments , 3 , "${title}: 3 AR_paid bookings");
898 is($total , 0 , "${title}: even balance");
901 sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_tax_included {
902 my $title = 'default invoice, four items, 19/7% tax with_skonto_pt 4x25';
904 my $item1 = create_invoice_item(part => $parts[2], qty => 0.5);
905 my $item2 = create_invoice_item(part => $parts[3], qty => 0.5);
906 my $item3 = create_invoice_item(part => $parts[2], qty => 0.5);
907 my $item4 = create_invoice_item(part => $parts[3], qty => 0.5);
908 my $invoice = create_sales_invoice(
910 transdate => $transdate1,
911 invoiceitems => [ $item1, $item2, $item3, $item4 ],
912 payment_id => $payment_terms->id,
916 my %params = ( chart_id => $bank_account->chart_id,
917 transdate => $transdate1,
920 $params{amount} = $invoice->amount_less_skonto;
921 $params{payment_type} = 'with_skonto_pt';
923 $invoice->pay_invoice( %params );
925 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
926 my $total = total_amount($invoice);
928 is($invoice->netamount, 88.75, "${title}: netamount");
929 is($invoice->amount, 100, "${title}: amount");
930 is($paid_amount, -100, "${title}: paid amount");
931 is($invoice->paid, 100, "${title}: paid");
932 is($number_of_payments, 3, "${title}: 3 AR_paid bookings");
934 local $TODO = "currently this test fails because the code writing the invoice is buggy, the calculation of skonto is correct";
935 is($total, 0, "${title}: even balance");
939 sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_multiple {
940 my $title = 'default invoice, four items, 19/7% tax with_skonto_pt 4x25';
942 my $item1 = create_invoice_item(part => $parts[2], qty => 0.5);
943 my $item2 = create_invoice_item(part => $parts[3], qty => 0.5);
944 my $item3 = create_invoice_item(part => $parts[2], qty => 0.5);
945 my $item4 = create_invoice_item(part => $parts[3], qty => 0.5);
946 my $invoice = create_sales_invoice(
948 transdate => $transdate1,
949 invoiceitems => [ $item1, $item2, $item3, $item4 ],
950 payment_id => $payment_terms->id,
953 $invoice->pay_invoice( amount => '90',
954 payment_type => 'without_skonto',
955 chart_id => $bank_account->chart_id,
956 transdate => $transdate1,
958 $invoice->pay_invoice( payment_type => 'difference_as_skonto',
959 chart_id => $bank_account->chart_id,
960 transdate => $transdate1,
963 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
964 my $total = total_amount($invoice);
966 is($invoice->netamount, 100, "${title}: netamount");
967 is($invoice->amount, 113, "${title}: amount");
968 is($paid_amount, -113, "${title}: paid amount");
969 is($invoice->paid, 113, "${title}: paid");
970 is($number_of_payments, 3, "${title}: 3 AR_paid bookings");
971 is($total, 0, "${title}: even balance: this will fail due to rounding error in invoice post, not the skonto");
974 sub test_ar_currency_tax_not_included_and_payment {
975 my $title = 'test_ar_currency_tax_not_included_and_payment_2';
977 my $netamount = $::form->round_amount(75 * $exchangerate->sell,2); # 75 in CUR, 100.00 in EUR
978 my $amount = $::form->round_amount($netamount * 1.19,2); # 100 in CUR, 119.00 in EUR
979 my $invoice = SL::DB::Invoice->new(
982 netamount => $netamount,
983 transdate => $transdate1,
985 customer_id => $customer->id,
986 taxzone_id => $customer->taxzone_id,
987 currency_id => $currency->id,
989 notes => 'test_ar_currency_tax_not_included_and_payment',
991 $invoice->add_ar_amount_row(
992 amount => $invoice->netamount,
993 chart => $ar_amount_chart,
997 $invoice->create_ar_row(chart => $ar_chart);
1000 is(SL::DB::Manager::Invoice->get_all_count(where => [ invoice => 0 ]), 1, 'there is one ar transaction');
1001 is($invoice->currency_id , $currency->id , 'currency_id has been saved');
1002 is($invoice->netamount , 100 , 'ar amount has been converted');
1003 is($invoice->amount , 119 , 'ar amount has been converted');
1004 is($invoice->taxincluded , 0 , 'ar transaction doesn\'t have taxincluded');
1005 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');
1006 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');
1008 $invoice->pay_invoice(chart_id => $bank->id,
1011 transdate => $transdate1->to_kivitendo,
1013 $invoice->pay_invoice(chart_id => $bank->id,
1016 transdate => $transdate1->to_kivitendo,
1018 # $invoice->pay_invoice(chart_id => $bank->id,
1020 # transdate => $transdate2->to_kivitendo,
1022 is(scalar @{$invoice->transactions}, 9, 'ar transaction has 9 transactions (incl. fxtransactions)');
1023 is($invoice->paid, $invoice->amount, 'ar transaction paid = amount in default currency');
1026 sub test_ar_currency_tax_included {
1027 my $title = 'test_ar_currency_tax_included';
1029 # we want the acc_trans amount to be 100
1030 my $amount = $::form->round_amount(75 * $exchangerate->sell * 1.19);
1031 my $netamount = $::form->round_amount($amount / 1.19,2);
1032 my $invoice = SL::DB::Invoice->new(
1036 transdate => $transdate1,
1038 customer_id => $customer->id,
1039 taxzone_id => $customer->taxzone_id,
1040 currency_id => $currency->id,
1041 notes => 'test_ar_currency_tax_included',
1044 $invoice->add_ar_amount_row( # should take care of taxincluded
1045 amount => $invoice->amount, # tax included in local currency
1046 chart => $ar_amount_chart,
1050 $invoice->create_ar_row( chart => $ar_chart );
1052 is(SL::DB::Manager::Invoice->get_all_count(where => [ invoice => 0 ]), 2, 'there are now two ar transactions');
1053 is($invoice->currency_id , $currency->id , 'currency_id has been saved');
1054 is($invoice->amount , $amount , 'amount ok');
1055 is($invoice->netamount , $netamount , 'netamount ok');
1056 is($invoice->taxincluded , 1 , 'ar transaction has taxincluded');
1057 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');
1058 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');
1059 $invoice->pay_invoice(chart_id => $bank->id,
1062 transdate => $transdate1->to_kivitendo,
1067 sub test_ap_currency_tax_not_included_and_payment {
1068 my $title = 'test_ap_currency_tax_not_included_and_payment';
1070 my $netamount = $::form->round_amount(75 * $exchangerate->buy,2); # 75 in CUR, 100.00 in EUR
1071 my $amount = $::form->round_amount($netamount * 1.19,2); # 100 in CUR, 119.00 in EUR
1072 my $invoice = SL::DB::PurchaseInvoice->new(
1074 invnumber => 'test_ap_currency_tax_not_included_and_payment',
1076 netamount => $netamount,
1077 transdate => $transdate1,
1079 vendor_id => $vendor->id,
1080 taxzone_id => $vendor->taxzone_id,
1081 currency_id => $currency->id,
1083 notes => 'test_ap_currency_tax_not_included_and_payment',
1085 $invoice->add_ap_amount_row(
1086 amount => $invoice->netamount,
1087 chart => $ap_amount_chart,
1088 tax_id => $tax_9->id,
1091 $invoice->create_ap_row(chart => $ap_chart);
1094 is($invoice->currency_id, $currency->id, 'currency_id has been saved');
1095 is($invoice->netamount, 100, 'ap amount has been converted');
1096 is($invoice->amount, 119, 'ap amount has been converted');
1097 is($invoice->taxincluded, 0, 'ap transaction doesn\'t have taxincluded');
1098 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');
1099 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');
1101 $invoice->pay_invoice(chart_id => $bank->id,
1104 transdate => $transdate1->to_kivitendo,
1106 $invoice->pay_invoice(chart_id => $bank->id,
1109 transdate => $transdate1->to_kivitendo,
1111 is(scalar @{$invoice->transactions}, 9, 'ap transaction has 9 transactions (incl. fxtransactions)');
1112 is($invoice->paid, $invoice->amount, 'ap transaction paid = amount in default currency');
1115 sub test_ap_currency_tax_included {
1116 my $title = 'test_ap_currency_tax_included';
1118 # we want the acc_trans amount to be 100
1119 my $amount = $::form->round_amount(75 * $exchangerate->buy * 1.19);
1120 my $netamount = $::form->round_amount($amount / 1.19,2);
1121 my $invoice = SL::DB::PurchaseInvoice->new(
1123 amount => 119, #$amount,
1124 netamount => 100, #$netamount,
1125 transdate => $transdate1,
1127 vendor_id => $vendor->id,
1128 taxzone_id => $vendor->taxzone_id,
1129 currency_id => $currency->id,
1130 notes => 'test_ap_currency_tax_included',
1131 invnumber => 'test_ap_currency_tax_included',
1134 $invoice->add_ap_amount_row( # should take care of taxincluded
1135 amount => $invoice->amount, # tax included in local currency
1136 chart => $ap_amount_chart,
1137 tax_id => $tax_9->id,
1140 $invoice->create_ap_row( chart => $ap_chart );
1142 is($invoice->currency_id , $currency->id , 'currency_id has been saved');
1143 is($invoice->amount , $amount , 'amount ok');
1144 is($invoice->netamount , $netamount , 'netamount ok');
1145 is($invoice->taxincluded , 1 , 'ap transaction has taxincluded');
1146 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');
1147 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');
1149 $invoice->pay_invoice(chart_id => $bank->id,
1152 transdate => $transdate1->to_kivitendo,
1157 sub test_ar_currency_tax_not_included_and_payment_2 {
1158 my $title = 'test_ar_currency_tax_not_included_and_payment_2';
1160 my $netamount = $::form->round_amount(125 * $exchangerate2->sell,2); # 125.00 in CUR, 100.00 in EUR
1161 my $amount = $::form->round_amount($netamount * 1.19,2); # 148.75 in CUR, 119.00 in EUR
1162 my $invoice = SL::DB::Invoice->new(
1165 netamount => $netamount,
1166 transdate => $transdate2,
1168 customer_id => $customer->id,
1169 taxzone_id => $customer->taxzone_id,
1170 currency_id => $currency->id,
1172 notes => 'test_ar_currency_tax_not_included_and_payment 0.8',
1173 invnumber => 'test_ar_currency_tax_not_included_and_payment 0.8',
1175 $invoice->add_ar_amount_row(
1176 amount => $invoice->netamount,
1177 chart => $ar_amount_chart,
1181 $invoice->create_ar_row(chart => $ar_chart);
1184 is($invoice->currency_id , $currency->id , "$title: currency_id has been saved");
1185 is($invoice->netamount , 100 , "$title: ar amount has been converted");
1186 is($invoice->amount , 119 , "$title: ar amount has been converted");
1187 is($invoice->taxincluded , 0 , "$title: ar transaction doesn\"t have taxincluded");
1188 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");
1189 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');
1191 $invoice->pay_invoice(chart_id => $bank->id,
1194 transdate => $transdate2->to_kivitendo,
1196 $invoice->pay_invoice(chart_id => $bank->id,
1199 transdate => $transdate3->to_kivitendo,
1201 $invoice->pay_invoice(chart_id => $bank->id,
1204 transdate => $transdate4->to_kivitendo,
1206 # $invoice->pay_invoice(chart_id => $bank->id,
1208 # transdate => $transdate2->to_kivitendo,
1210 my $fx_transactions = SL::DB::Manager::AccTransaction->get_all(where => [ trans_id => $invoice->id, fx_transaction => 1 ], sort_by => ('acc_trans_id'));
1211 is(scalar @{$fx_transactions}, 3, "$title: ar transaction has 3 fx transactions");
1212 is($fx_transactions->[0]->amount, '24.69000', "$title fx transactions 1: 123.45-(123.45*0.8) = 24.69");
1214 is(scalar @{$invoice->transactions}, 14, "$title ar transaction has 14 transactions (incl. fxtransactions and fx_gain)");
1215 is($invoice->paid, $invoice->amount, "$title ar transaction paid = amount in default currency");
1218 sub test_ar_currency_tax_not_included_and_payment_2_credit_note {
1219 my $title = 'test_ar_currency_tax_not_included_and_payment_2_credit_note';
1221 my $netamount = $::form->round_amount(-125 * $exchangerate2->sell,2); # 125.00 in CUR, 100.00 in EUR
1222 my $amount = $::form->round_amount($netamount * 1.19,2); # 148.75 in CUR, 119.00 in EUR
1223 my $invoice = SL::DB::Invoice->new(
1226 netamount => $netamount,
1227 transdate => $transdate2,
1229 customer_id => $customer->id,
1230 taxzone_id => $customer->taxzone_id,
1231 currency_id => $currency->id,
1233 notes => 'test_ar_currency_tax_not_included_and_payment credit note 0.8',
1234 invnumber => 'test_ar_currency_tax_not_included_and_payment credit note 0.8',
1236 $invoice->add_ar_amount_row(
1237 amount => $invoice->netamount,
1238 chart => $ar_amount_chart,
1242 $invoice->create_ar_row(chart => $ar_chart);
1245 is($invoice->currency_id , $currency->id , 'currency_id has been saved');
1246 is($invoice->netamount , -100 , 'ar amount has been converted');
1247 is($invoice->amount , -119 , 'ar amount has been converted');
1248 is($invoice->taxincluded , 0 , 'ar transaction doesn\'t have taxincluded');
1249 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');
1250 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');
1252 $invoice->pay_invoice(chart_id => $bank->id,
1255 transdate => $transdate2->to_kivitendo,
1257 $invoice->pay_invoice(chart_id => $bank->id,
1260 transdate => $transdate2->to_kivitendo,
1262 my $fx_transactions = SL::DB::Manager::AccTransaction->get_all(where => [ trans_id => $invoice->id, fx_transaction => 1 ], sort_by => ('acc_trans_id'));
1263 is(scalar @{$fx_transactions}, 2, 'ar transaction has 2 fx transactions');
1264 is($fx_transactions->[0]->amount, '-24.69000', 'fx transactions 1: 123.45-(123.45*0.8) = 24.69');
1266 is(scalar @{$invoice->transactions}, 9, 'ar transaction has 9 transactions (incl. fxtransactions)');
1267 is($invoice->paid, $invoice->amount, 'ar transaction paid = amount in default currency');
1270 sub test_ap_currency_tax_not_included_and_payment_2 {
1271 my $title = 'test_ap_currency_tax_not_included_and_payment_2';
1273 my $netamount = $::form->round_amount(125 * $exchangerate2->sell,2); # 125.00 in CUR, 100.00 in EUR
1274 my $amount = $::form->round_amount($netamount * 1.19,2); # 148.75 in CUR, 119.00 in EUR
1275 my $invoice = SL::DB::PurchaseInvoice->new(
1278 netamount => $netamount,
1279 transdate => $transdate2,
1281 vendor_id => $vendor->id,
1282 taxzone_id => $vendor->taxzone_id,
1283 currency_id => $currency->id,
1285 notes => 'test_ap_currency_tax_not_included_and_payment_2 0.8 + 1.33333',
1286 invnumber => 'test_ap_currency_tax_not_included_and_payment_2 0.8 + 1.33333',
1288 $invoice->add_ap_amount_row(
1289 amount => $invoice->netamount,
1290 chart => $ap_amount_chart,
1291 tax_id => $tax_9->id,
1294 $invoice->create_ap_row(chart => $ap_chart);
1297 is($invoice->currency_id , $currency->id , "$title: currency_id has been saved");
1298 is($invoice->netamount , 100 , "$title: ap amount has been converted");
1299 is($invoice->amount , 119 , "$title: ap amount has been converted");
1300 is($invoice->taxincluded , 0 , "$title: ap transaction doesn\'t have taxincluded");
1301 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');
1302 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');
1304 $invoice->pay_invoice(chart_id => $bank->id,
1307 transdate => $transdate2->to_kivitendo,
1309 $invoice->pay_invoice(chart_id => $bank->id,
1312 transdate => $transdate3->to_kivitendo,
1314 $invoice->pay_invoice(chart_id => $bank->id,
1317 transdate => $transdate4->to_kivitendo,
1319 my $fx_transactions = SL::DB::Manager::AccTransaction->get_all(where => [ trans_id => $invoice->id, fx_transaction => 1 ], sort_by => ('acc_trans_id'));
1320 is(scalar @{$fx_transactions}, 3, "$title: ap transaction has 3 fx transactions");
1321 is($fx_transactions->[0]->amount, '-2.00000', "$title: fx transaction 1: 10.00-( 10.00*0.80000) = 2.00000");
1322 is($fx_transactions->[1]->amount, '68.59000', "$title: fx transaction 2: 123.45-(123.45*1.55557) = -68.58511");
1323 is($fx_transactions->[2]->amount, '-3.40000', "$title: fx transaction 3: 15.30-(15.30 *0.77777) = 3.40012");
1325 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'));
1326 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'));
1327 is($fx_gain_transactions->[0]->amount, '0.34000', "$title: fx gain amount ok");
1328 is($fx_loss_transactions->[0]->amount, '-93.28000', "$title: fx loss amount ok");
1330 is(scalar @{$invoice->transactions}, 14, "$title: ap transaction has 14 transactions (incl. fxtransactions and gain_loss)");
1331 is($invoice->paid, $invoice->amount, "$title: ap transaction paid = amount in default currency");
1332 is(total_amount($invoice), 0, "$title: even balance");
1335 sub test_ap_currency_tax_not_included_and_payment_2_credit_note {
1336 my $title = 'test_ap_currency_tax_not_included_and_payment_2_credit_note';
1338 my $netamount = $::form->round_amount(-125 * $exchangerate2->sell,2); # 125.00 in CUR, 100.00 in EUR
1339 my $amount = $::form->round_amount($netamount * 1.19,2); # 148.75 in CUR, 119.00 in EUR
1340 my $invoice = SL::DB::PurchaseInvoice->new(
1343 netamount => $netamount,
1344 transdate => $transdate2,
1346 vendor_id => $vendor->id,
1347 taxzone_id => $vendor->taxzone_id,
1348 currency_id => $currency->id,
1350 notes => 'test_ap_currency_tax_not_included_and_payment credit note 0.8 + 1.33333',
1351 invnumber => 'test_ap_currency_tax_not_included_and_payment credit note 0.8 + 1.33333',
1353 $invoice->add_ap_amount_row(
1354 amount => $invoice->netamount,
1355 chart => $ap_amount_chart,
1356 tax_id => $tax_9->id,
1359 $invoice->create_ap_row(chart => $ap_chart);
1362 is($invoice->currency_id , $currency->id , "$title: currency_id has been saved");
1363 is($invoice->netamount , -100 , "$title: ap amount has been converted");
1364 is($invoice->amount , -119 , "$title: ap amount has been converted");
1365 is($invoice->taxincluded , 0 , "$title: ap transaction doesn\'t have taxincluded");
1366 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');
1367 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');
1369 $invoice->pay_invoice(chart_id => $bank->id,
1372 transdate => $transdate2->to_kivitendo,
1374 $invoice->pay_invoice(chart_id => $bank->id,
1377 transdate => $transdate3->to_kivitendo,
1379 $invoice->pay_invoice(chart_id => $bank->id,
1382 transdate => $transdate4->to_kivitendo,
1384 my $fx_transactions = SL::DB::Manager::AccTransaction->get_all(where => [ trans_id => $invoice->id, fx_transaction => 1 ], sort_by => ('acc_trans_id'));
1385 is(scalar @{$fx_transactions}, 3, "$title: ap transaction has 3 fx transactions");
1386 is($fx_transactions->[0]->amount, '2.00000', "$title: fx transaction 1: 10.00-( 10.00*0.80000) = 2.00000");
1387 is($fx_transactions->[1]->amount, '-68.59000', "$title: fx transaction 2: 123.45-(123.45*1.55557) = -68.58511");
1388 is($fx_transactions->[2]->amount, '3.40000', "$title: fx transaction 3: 15.30-(15.30 *0.77777) = 3.40012");
1390 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'));
1391 is($fx_gain_loss_transactions->[0]->amount, '93.28000', "$title: fx gain loss amount ok");
1393 is(scalar @{$invoice->transactions}, 14, "$title: ap transaction has 14 transactions (incl. fxtransactions and gain_loss)");
1394 is($invoice->paid, $invoice->amount, "$title: ap transaction paid = amount in default currency");
1395 is(total_amount($invoice), 0, "$title: even balance");
1398 sub test_credit_note_two_items_19_7_tax_tax_not_included {
1399 my $title = 'test_credit_note_two_items_19_7_tax_tax_not_included';
1401 my $item1 = create_invoice_item(part => $parts[0], qty => 5);
1402 my $item2 = create_invoice_item(part => $parts[1], qty => 3);
1403 my $invoice = create_credit_note(
1405 transdate => $transdate1,
1407 invoiceitems => [ $item1, $item2 ],
1411 my %params = ( chart_id => $bank_account->chart_id,
1412 transdate => $transdate1,
1415 $params{amount} = $invoice->amount,
1417 $invoice->pay_invoice( %params );
1419 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
1420 my $total = total_amount($invoice);
1422 is($invoice->netamount, -40.84, "${title}: netamount");
1423 is($invoice->amount, -45.10, "${title}: amount");
1424 is($paid_amount, 45.10, "${title}: paid amount according to acc_trans is positive (Haben)");
1425 is($invoice->paid, -45.10, "${title}: paid");
1426 is($number_of_payments, 1, "${title}: 1 AR_paid bookings");
1427 is($total, 0, "${title}: even balance");