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::BankTransaction;
18 use SL::DB::BankTransactionAccTrans;
19 use SL::DB::Buchungsgruppe;
21 use SL::DB::Exchangerate;
29 use SL::DB::BankAccount;
30 use SL::DB::PaymentTerm;
31 use SL::DBUtils qw(selectfirst_array_query);
34 my ($customer, $vendor, $currency_id, @parts, $buchungsgruppe, $buchungsgruppe7, $unit, $employee, $tax, $tax7, $tax_9, $taxzone, $payment_terms,
36 my ($transdate1, $transdate2, $transdate3, $transdate4, $currency, $exchangerate, $exchangerate2, $exchangerate3, $exchangerate4);
37 my ($ar_chart,$bank,$ar_amount_chart, $ap_chart, $ap_amount_chart, $fxloss_chart, $fxgain_chart);
39 my $ap_transaction_counter = 0; # used for generating purchase invnumber
41 Support::TestSetup::login();
45 # test cases: without_skonto
46 test_default_invoice_one_item_19_without_skonto();
47 test_default_invoice_two_items_19_7_tax_with_skonto();
48 test_default_invoice_two_items_19_7_without_skonto();
49 test_default_invoice_two_items_19_7_without_skonto_incomplete_payment();
50 test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments();
51 test_default_ap_transaction_two_charts_19_7_without_skonto();
52 test_default_ap_transaction_two_charts_19_7_tax_partial_unrounded_payment_without_skonto();
53 test_default_invoice_one_item_19_without_skonto_overpaid();
54 test_credit_note_two_items_19_7_tax_tax_not_included();
56 # test cases: difference_as_skonto
57 test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto();
58 test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto_1cent();
59 test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto_2cent();
60 test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto();
61 test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto_1cent();
62 test_default_ap_transaction_two_charts_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto();
64 # test cases: with_skonto_pt
65 test_default_invoice_two_items_19_7_tax_with_skonto_50_50();
66 test_default_invoice_four_items_19_7_tax_with_skonto_4x_25();
67 test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_multiple();
68 test_default_ap_transaction_two_charts_19_7_with_skonto();
69 test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_tax_included();
70 test_default_invoice_two_items_19_7_tax_with_skonto_tax_included();
72 # test payment of ar and ap transactions with currency and tax included/not included
73 # exchangerate = 1.33333
74 test_ar_currency_tax_not_included_and_payment();
75 test_ar_currency_tax_included();
76 test_ap_currency_tax_not_included_and_payment();
77 test_ap_currency_tax_included();
79 test_ar_currency_tax_not_included_and_payment_2(); # exchangerate 0.8
80 test_ar_currency_tax_not_included_and_payment_2_credit_note(); # exchangerate 0.8
82 test_ap_currency_tax_not_included_and_payment_2(); # two exchangerates, with fx_gain_loss
83 test_ap_currency_tax_not_included_and_payment_2_credit_note(); # two exchangerates, with fx_gain_loss
85 is(SL::DB::Manager::Invoice->get_all_count(), 21, "number of invoices at end of tests ok");
87 local $TODO = "currently this test fails because the code writing the invoice is buggy, the calculation of skonto is correct";
88 my ($acc_trans_sum) = selectfirst_array_query($::form, $currency->db->dbh, 'SELECT SUM(amount) FROM acc_trans');
89 is($acc_trans_sum, '0.00000', "sum of all acc_trans at end of all tests is 0");
92 # remove all created data at end of test
99 SL::DB::Manager::InvoiceItem->delete_all(all => 1);
100 SL::DB::Manager::Invoice->delete_all(all => 1);
101 SL::DB::Manager::PurchaseInvoice->delete_all(all => 1);
102 SL::DB::Manager::Part->delete_all(all => 1);
103 SL::DB::Manager::Customer->delete_all(all => 1);
104 SL::DB::Manager::Vendor->delete_all(all => 1);
105 SL::DB::Manager::BankTransactionAccTrans->delete_all(all => 1);
106 SL::DB::Manager::BankTransaction->delete_all(all => 1);
107 SL::DB::Manager::BankAccount->delete_all(all => 1);
108 SL::DB::Manager::PaymentTerm->delete_all(all => 1);
109 SL::DB::Manager::Exchangerate->delete_all(all => 1);
110 SL::DB::Manager::Currency->delete_all(where => [ name => 'CUR' ]);
118 $transdate1 = DateTime->today_local;
119 $transdate1->set_year(2019) if $transdate1->year == 2020; # hardcode for 2019 in 2020, because of tax rate change in Germany
120 $transdate2 = $transdate1->clone->add(days => 1);
121 $transdate3 = $transdate1->clone->add(days => 2);
122 $transdate4 = $transdate1->clone->add(days => 3);
124 $buchungsgruppe = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 19%') || croak "No accounting group";
125 $buchungsgruppe7 = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 7%') || croak "No accounting group for 7\%";
126 $unit = SL::DB::Manager::Unit->find_by(name => 'kg') || croak "No unit";
127 $employee = SL::DB::Manager::Employee->current || croak "No employee";
128 $tax = SL::DB::Manager::Tax->find_by(taxkey => 3, rate => 0.19) || croak "No tax";
129 $tax7 = SL::DB::Manager::Tax->find_by(taxkey => 2, rate => 0.07) || croak "No tax for 7\%";
130 $taxzone = SL::DB::Manager::TaxZone->find_by( description => 'Inland') || croak "No taxzone";
131 $tax_9 = SL::DB::Manager::Tax->find_by(taxkey => 9, rate => 0.19) || croak "No tax";
132 # $tax7 = SL::DB::Manager::Tax->find_by(taxkey => 2, rate => 0.07) || croak "No tax for 7\%";
134 $currency_id = $::instance_conf->get_currency_id;
136 $currency = SL::DB::Currency->new(name => 'CUR')->save;
138 $fxgain_chart = SL::DB::Manager::Chart->find_by(accno => '2660') or die "Can't find fxgain_chart in test";
139 $fxloss_chart = SL::DB::Manager::Chart->find_by(accno => '2150') or die "Can't find fxloss_chart in test";
141 $currency->db->dbh->do('UPDATE defaults SET fxgain_accno_id = ' . $fxgain_chart->id);
142 $currency->db->dbh->do('UPDATE defaults SET fxloss_accno_id = ' . $fxloss_chart->id);
143 $::instance_conf->reload->data;
144 is($fxgain_chart->id, $::instance_conf->get_fxgain_accno_id, "fxgain_chart was updated in defaults");
145 is($fxloss_chart->id, $::instance_conf->get_fxloss_accno_id, "fxloss_chart was updated in defaults");
147 $exchangerate = SL::DB::Exchangerate->new(transdate => $transdate1,
150 currency_id => $currency->id,
152 $exchangerate2 = SL::DB::Exchangerate->new(transdate => $transdate2,
155 currency_id => $currency->id,
157 $exchangerate3 = SL::DB::Exchangerate->new(transdate => $transdate3,
160 currency_id => $currency->id,
162 $exchangerate4 = SL::DB::Exchangerate->new(transdate => $transdate4,
165 currency_id => $currency->id,
168 $customer = new_customer(
169 name => 'Test Customer',
170 currency_id => $currency_id,
171 taxzone_id => $taxzone->id,
174 $bank_account = SL::DB::BankAccount->new(
175 account_number => '123',
180 chart_id => SL::DB::Manager::Chart->find_by( description => 'Bank' )->id,
181 name => SL::DB::Manager::Chart->find_by( description => 'Bank' )->description,
184 $payment_terms = SL::DB::PaymentTerm->new(
185 description => 'payment',
186 description_long => 'payment',
189 percent_skonto => '0.05',
190 auto_calculation => 1,
193 $vendor = new_vendor(
194 name => 'Test Vendor',
195 currency_id => $currency_id,
196 taxzone_id => $taxzone->id,
197 payment_id => $payment_terms->id,
202 push @parts, new_part(
203 partnumber => 'T4254',
204 description => 'Fourty-two fifty-four',
207 buchungsgruppen_id => $buchungsgruppe->id,
212 push @parts, new_part(
213 partnumber => 'T0815',
214 description => 'Zero EIGHT fifteeN @ 7%',
217 buchungsgruppen_id => $buchungsgruppe7->id,
221 push @parts, new_part(
223 description => 'Testware 19%',
226 buchungsgruppen_id => $buchungsgruppe->id,
230 push @parts, new_part(
232 description => 'Testware 7%',
235 buchungsgruppen_id => $buchungsgruppe7->id,
240 $ar_chart = SL::DB::Manager::Chart->find_by( accno => '1400' ); # Forderungen
241 $ap_chart = SL::DB::Manager::Chart->find_by( accno => '1600' ); # Verbindlichkeiten
242 $bank = SL::DB::Manager::Chart->find_by( accno => '1200' ); # Bank
243 $ar_amount_chart = SL::DB::Manager::Chart->find_by( accno => '8400' ); # Erlöse
244 $ap_amount_chart = SL::DB::Manager::Chart->find_by( accno => '3400' ); # Wareneingang 19%
246 $bt = SL::DB::BankTransaction->new(
247 local_bank_account_id => $bank_account->id,
248 transdate => $transdate1,
249 valutadate => $transdate1,
252 currency => $currency,
258 sub new_ap_transaction {
259 $ap_transaction_counter++;
261 my $ap_transaction = create_ap_transaction(
263 invnumber => 'newap ' . $ap_transaction_counter,
267 gldate => $transdate1,
268 taxzone_id => $taxzone->id,
269 transdate => $transdate1,
272 chart => SL::DB::Manager::Chart->find_by(accno => '3400'),
276 chart => SL::DB::Manager::Chart->find_by(accno => '3300'),
282 return $ap_transaction;
285 sub number_of_payments {
288 my $number_of_payments;
290 foreach my $transaction ( @{ $invoice->transactions } ) {
291 if ( $transaction->chart_link =~ /(AR_paid|AP_paid)/ ) {
292 $paid_amount += $transaction->amount ;
293 $number_of_payments++;
296 return ($number_of_payments, $paid_amount);
302 my $total = sum map { $_->amount } @{ $invoice->transactions };
304 return $::form->round_amount($total, 5);
310 sub test_default_invoice_one_item_19_without_skonto {
311 my $title = 'default invoice, one item, 19% tax, without_skonto';
312 my $item = create_invoice_item(part => $parts[0], qty => 2.5);
313 my $invoice = create_sales_invoice(
314 transdate => $transdate1,
316 invoiceitems => [ $item ],
317 payment_id => $payment_terms->id,
320 my $ap_transaction = new_ap_transaction();
323 my %params = ( chart_id => $bank_account->chart_id,
324 transdate => $transdate1,
327 $params{amount} = '6.96';
328 $params{payment_type} = 'without_skonto';
330 $invoice->pay_invoice( %params );
332 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
333 my $total = total_amount($invoice);
335 is($invoice->netamount, 5.85, "${title}: netamount");
336 is($invoice->amount, 6.96, "${title}: amount");
337 is($paid_amount, -6.96, "${title}: paid amount");
338 is($number_of_payments, 1, "${title}: 1 AR_paid booking");
339 is($invoice->paid, 6.96, "${title}: paid");
340 is($total, 0, "${title}: even balance");
344 sub test_default_invoice_one_item_19_without_skonto_overpaid {
345 my $title = 'default invoice, one item, 19% tax, without_skonto';
347 my $item = create_invoice_item(part => $parts[0], qty => 2.5);
348 my $invoice = create_sales_invoice(
350 transdate => $transdate1,
351 invoiceitems => [ $item ],
352 payment_id => $payment_terms->id,
355 my $ap_transaction = new_ap_transaction();
359 my %params = ( chart_id => $bank_account->chart_id,
360 transdate => $transdate1,
363 $params{amount} = '16.96';
364 $params{payment_type} = 'without_skonto';
365 $invoice->pay_invoice( %params );
367 $params{amount} = '-10.00';
368 $invoice->pay_invoice( %params );
370 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
371 my $total = total_amount($invoice);
373 is($invoice->netamount, 5.85, "${title}: netamount");
374 is($invoice->amount, 6.96, "${title}: amount");
375 is($paid_amount, -6.96, "${title}: paid amount");
376 is($number_of_payments, 2, "${title}: 1 AR_paid booking");
377 is($invoice->paid, 6.96, "${title}: paid");
378 is($total, 0, "${title}: even balance");
384 sub test_default_invoice_two_items_19_7_tax_with_skonto {
385 my $title = 'default invoice, two items, 19/7% tax with_skonto_pt';
387 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
388 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
389 my $invoice = create_sales_invoice(
391 transdate => $transdate1,
392 invoiceitems => [ $item1, $item2 ],
393 payment_id => $payment_terms->id,
397 my %params = ( chart_id => $bank_account->chart_id,
398 transdate => $transdate1,
402 $params{payment_type} = 'with_skonto_pt';
403 $params{amount} = $invoice->amount_less_skonto;
405 $invoice->pay_invoice( %params );
407 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
408 my $total = total_amount($invoice);
410 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
411 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
412 is($paid_amount, -19.44, "${title}: paid amount");
413 is($invoice->paid, 19.44, "${title}: paid");
414 is($number_of_payments, 3, "${title}: 3 AR_paid bookings");
415 is($total, 0, "${title}: even balance");
418 sub test_default_invoice_two_items_19_7_tax_with_skonto_tax_included {
419 my $title = 'default invoice, two items, 19/7% tax with_skonto_pt';
421 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
422 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
423 my $invoice = create_sales_invoice(
424 transdate => $transdate1,
426 invoiceitems => [ $item1, $item2 ],
427 payment_id => $payment_terms->id,
431 my %params = ( chart_id => $bank_account->chart_id,
432 transdate => $transdate1,
436 $params{payment_type} = 'with_skonto_pt';
437 $params{amount} = $invoice->amount_less_skonto;
439 $invoice->pay_invoice( %params );
441 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
442 my $total = total_amount($invoice);
444 is($invoice->netamount, 15.82, "${title}: netamount");
445 is($invoice->amount, 17.51, "${title}: amount");
446 is($paid_amount, -17.51, "${title}: paid amount");
447 is($invoice->paid, 17.51, "${title}: paid");
448 is($number_of_payments, 3, "${title}: 3 AR_paid bookings");
451 local $TODO = "currently this test fails because the code writing the invoice is buggy, the calculation of skonto is correct";
452 is($total, 0, "${title}: even balance");
456 # test 3 : two items, without skonto
457 sub test_default_invoice_two_items_19_7_without_skonto {
458 my $title = 'default invoice, two items, 19/7% tax without skonto';
460 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
461 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
462 my $invoice = create_sales_invoice(
463 transdate => $transdate1,
465 invoiceitems => [ $item1, $item2 ],
466 payment_id => $payment_terms->id,
470 my %params = ( chart_id => $bank_account->chart_id,
471 transdate => $transdate1,
474 $params{amount} = '19.44'; # pass full amount
475 $params{payment_type} = 'without_skonto';
477 $invoice->pay_invoice( %params );
479 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
480 my $total = total_amount($invoice);
482 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
483 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
484 is($paid_amount, -19.44, "${title}: paid amount");
485 is($invoice->paid, 19.44, "${title}: paid");
486 is($number_of_payments, 1, "${title}: 1 AR_paid bookings");
487 is($total, 0, "${title}: even balance");
491 sub test_default_invoice_two_items_19_7_without_skonto_incomplete_payment {
492 my $title = 'default invoice, two items, 19/7% tax without skonto incomplete payment';
494 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
495 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
496 my $invoice = create_sales_invoice(
498 transdate => $transdate1,
499 invoiceitems => [ $item1, $item2 ],
500 payment_id => $payment_terms->id,
503 $invoice->pay_invoice( amount => '9.44',
504 payment_type => 'without_skonto',
505 chart_id => $bank_account->chart_id,
506 transdate => $transdate1,
509 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
510 my $total = total_amount($invoice);
512 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
513 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
514 is($paid_amount, -9.44, "${title}: paid amount");
515 is($invoice->paid, 9.44, "${title}: paid");
516 is($number_of_payments, 1, "${title}: 1 AR_paid bookings");
517 is($total, 0, "${title}: even balance");
521 sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments {
522 my $title = 'default invoice, two items, 19/7% tax not included';
524 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
525 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
526 my $invoice = create_sales_invoice(
527 transdate => $transdate1,
529 invoiceitems => [ $item1, $item2 ],
530 payment_id => $payment_terms->id,
533 $invoice->pay_invoice( amount => '9.44',
534 payment_type => 'without_skonto',
535 chart_id => $bank_account->chart_id,
536 transdate => $transdate1,
538 $invoice->pay_invoice( amount => '10.00',
539 chart_id => $bank_account->chart_id,
540 transdate => $transdate1,
543 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
544 my $total = total_amount($invoice);
546 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
547 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
548 is($paid_amount, -19.44, "${title}: paid amount");
549 is($invoice->paid, 19.44, "${title}: paid");
550 is($number_of_payments, 2, "${title}: 2 AR_paid bookings");
551 is($total, 0, "${title}: even balance");
556 sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto {
557 my $title = 'default invoice, two items, 19/7% tax not included';
559 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
560 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
561 my $invoice = create_sales_invoice(
563 transdate => $transdate1,
564 invoiceitems => [ $item1, $item2 ],
565 payment_id => $payment_terms->id,
568 $invoice->pay_invoice( amount => '9.44',
569 payment_type => 'without_skonto',
570 chart_id => $bank_account->chart_id,
571 transdate => $transdate1,
573 $invoice->pay_invoice( amount => '8.73',
574 payment_type => 'without_skonto',
575 chart_id => $bank_account->chart_id,
576 transdate => $transdate1,
578 $invoice->pay_invoice( amount => $invoice->open_amount,
579 payment_type => 'difference_as_skonto',
580 chart_id => $bank_account->chart_id,
581 transdate => $transdate1,
585 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
586 my $total = total_amount($invoice);
588 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
589 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
590 is($paid_amount, -19.44, "${title}: paid amount");
591 is($invoice->paid, 19.44, "${title}: paid");
592 is($number_of_payments, 4, "${title}: 4 AR_paid bookings");
593 is($total, 0, "${title}: even balance");
597 sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto_1cent {
598 my $title = 'default invoice, two items, 19/7% tax not included';
600 # if there is only one cent left there can only be one skonto booking, the
601 # error handling should choose the highest amount, which is the 7% account
602 # (11.66) rather than the 19% account (5.85). The actual tax amount is
603 # higher for the 19% case, though (1.11 compared to 0.82)
605 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
606 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
607 my $invoice = create_sales_invoice(
609 transdate => $transdate1,
610 invoiceitems => [ $item1, $item2 ],
611 payment_id => $payment_terms->id,
614 $invoice->pay_invoice( amount => '19.42',
615 payment_type => 'without_skonto',
616 chart_id => $bank_account->chart_id,
617 transdate => $transdate1,
619 $invoice->pay_invoice( amount => $invoice->open_amount,
620 payment_type => 'difference_as_skonto',
621 chart_id => $bank_account->chart_id,
622 transdate => $transdate1,
626 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
627 my $total = total_amount($invoice);
629 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
630 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
631 is($paid_amount, -19.44, "${title}: paid amount");
632 is($invoice->paid, 19.44, "${title}: paid");
633 is($number_of_payments, 3, "${title}: 2 AR_paid bookings");
634 is($total, 0, "${title}: even balance");
638 sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto_2cent {
639 my $title = 'default invoice, two items, 19/7% tax not included';
641 # if there are two cents left there will be two skonto bookings, 1 cent each
642 my $item1 = create_invoice_item(part => $parts[0], qty => 2.5);
643 my $item2 = create_invoice_item(part => $parts[1], qty => 1.2);
644 my $invoice = create_sales_invoice(
646 transdate => $transdate1,
647 invoiceitems => [ $item1, $item2 ],
648 payment_id => $payment_terms->id,
651 $invoice->pay_invoice( amount => '19.42',
652 payment_type => 'without_skonto',
653 chart_id => $bank_account->chart_id,
654 transdate => $transdate1,
656 $invoice->pay_invoice( amount => $invoice->open_amount,
657 payment_type => 'difference_as_skonto',
658 chart_id => $bank_account->chart_id,
659 transdate => $transdate1,
663 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
664 my $total = total_amount($invoice);
666 is($invoice->netamount, 5.85 + 11.66, "${title}: netamount");
667 is($invoice->amount, 6.96 + 12.48, "${title}: amount");
668 is($paid_amount, -19.44, "${title}: paid amount");
669 is($invoice->paid, 19.44, "${title}: paid");
670 is($number_of_payments, 3, "${title}: 3 AR_paid bookings");
671 is($total, 0, "${title}: even balance");
675 sub test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto {
676 my $title = 'default invoice, one item, 19% tax, without_skonto';
678 my $item = create_invoice_item(part => $parts[0], qty => 2.5);
679 my $invoice = create_sales_invoice(
681 transdate => $transdate1,
682 invoiceitems => [ $item ],
683 payment_id => $payment_terms->id,
687 my %params = ( chart_id => $bank_account->chart_id,
688 transdate => $transdate1,
692 $params{amount} = '2.32';
693 $params{payment_type} = 'without_skonto';
694 $invoice->pay_invoice( %params );
696 $params{amount} = '3.81';
697 $params{payment_type} = 'without_skonto';
698 $invoice->pay_invoice( %params );
700 $params{amount} = $invoice->open_amount; # set amount, otherwise previous 3.81 is used
701 $params{payment_type} = 'difference_as_skonto';
702 $invoice->pay_invoice( %params );
704 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
705 my $total = total_amount($invoice);
707 is($invoice->netamount, 5.85, "${title}: netamount");
708 is($invoice->amount, 6.96, "${title}: amount");
709 is($paid_amount, -6.96, "${title}: paid amount");
710 is($number_of_payments, 3, "${title}: 3 AR_paid booking");
711 is($invoice->paid, 6.96, "${title}: paid");
712 is($total, 0, "${title}: even balance");
716 sub test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto_1cent {
717 my $title = 'default invoice, one item, 19% tax, without_skonto';
719 my $item = create_invoice_item(part => $parts[0], qty => 2.5);
720 my $invoice = create_sales_invoice(
722 transdate => $transdate1,
723 invoiceitems => [ $item ],
724 payment_id => $payment_terms->id,
728 my %params = ( chart_id => $bank_account->chart_id,
729 transdate => $transdate1,
733 $params{amount} = '6.95';
734 $params{payment_type} = 'without_skonto';
735 $invoice->pay_invoice( %params );
737 $params{amount} = $invoice->open_amount; # set amount, otherwise previous value 6.95 is used
738 $params{payment_type} = 'difference_as_skonto';
739 $invoice->pay_invoice( %params );
741 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
742 my $total = total_amount($invoice);
744 is($invoice->netamount, 5.85, "${title}: netamount");
745 is($invoice->amount, 6.96, "${title}: amount");
746 is($paid_amount, -6.96, "${title}: paid amount");
747 is($number_of_payments, 2, "${title}: 3 AR_paid booking");
748 is($invoice->paid, 6.96, "${title}: paid");
749 is($total, 0, "${title}: even balance");
753 # test 3 : two items, without skonto
754 sub test_default_ap_transaction_two_charts_19_7_without_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} = 'without_skonto';
766 $ap_transaction->pay_invoice( %params );
768 my ($number_of_payments, $paid_amount) = number_of_payments($ap_transaction);
769 my $total = total_amount($ap_transaction);
771 is($paid_amount, 226, "${title}: paid amount");
772 is($number_of_payments, 1, "${title}: 1 AP_paid bookings");
773 is($total, 0, "${title}: even balance");
777 sub test_default_ap_transaction_two_charts_19_7_with_skonto {
778 my $title = 'default invoice, two items, 19/7% tax without skonto';
780 my $ap_transaction = new_ap_transaction();
782 my %params = ( chart_id => $bank_account->chart_id,
783 transdate => $transdate1,
787 # $params{amount} = '226'; # pass full amount
788 $params{payment_type} = 'with_skonto_pt';
790 $ap_transaction->payment_terms($ap_transaction->vendor->payment);
791 $ap_transaction->pay_invoice( %params );
793 my ($number_of_payments, $paid_amount) = number_of_payments($ap_transaction);
794 my $total = total_amount($ap_transaction);
796 is($paid_amount, 226, "${title}: paid amount");
797 is($number_of_payments, 3, "${title}: 1 AP_paid bookings");
798 is($total, 0, "${title}: even balance");
802 sub test_default_ap_transaction_two_charts_19_7_tax_partial_unrounded_payment_without_skonto {
803 my $title = 'default ap_transaction, two charts, 19/7% tax multiple payments with final difference as skonto';
805 # check whether unrounded amounts passed via $params{amount} are rounded for without_skonto case
806 my $ap_transaction = new_ap_transaction();
807 $ap_transaction->pay_invoice(
808 amount => ( $ap_transaction->amount / 3 * 2),
809 payment_type => 'without_skonto',
810 chart_id => $bank_account->chart_id,
811 transdate => $transdate1,
813 my ($number_of_payments, $paid_amount) = number_of_payments($ap_transaction);
814 my $total = total_amount($ap_transaction);
816 is($paid_amount, 150.67, "${title}: paid amount");
817 is($number_of_payments, 1, "${title}: 1 AP_paid bookings");
818 is($total, 0, "${title}: even balance");
822 sub test_default_ap_transaction_two_charts_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto {
823 my $title = 'default ap_transaction, two charts, 19/7% tax multiple payments with final difference as skonto';
825 my $ap_transaction = new_ap_transaction();
827 # pay 2/3 and 1/5, leaves 3.83% to be used as Skonto
828 $ap_transaction->pay_invoice(
829 amount => ( $ap_transaction->amount / 3 * 2),
830 payment_type => 'without_skonto',
831 chart_id => $bank_account->chart_id,
832 transdate => $transdate1,
834 $ap_transaction->pay_invoice(
835 amount => ( $ap_transaction->amount / 5 ),
836 payment_type => 'without_skonto',
837 chart_id => $bank_account->chart_id,
838 transdate => $transdate1,
840 $ap_transaction->pay_invoice(
841 payment_type => 'difference_as_skonto',
842 chart_id => $bank_account->chart_id,
843 transdate => $transdate1,
847 my ($number_of_payments, $paid_amount) = number_of_payments($ap_transaction);
848 my $total = total_amount($ap_transaction);
850 is($paid_amount, 226, "${title}: paid amount");
851 is($number_of_payments, 4, "${title}: 1 AP_paid bookings");
852 is($total, 0, "${title}: even balance");
857 sub test_default_invoice_two_items_19_7_tax_with_skonto_50_50 {
858 my $title = 'default invoice, two items, 19/7% tax with_skonto_pt 50/50';
860 my $item1 = create_invoice_item(part => $parts[2], qty => 1);
861 my $item2 = create_invoice_item(part => $parts[3], qty => 1);
862 my $invoice = create_sales_invoice(
864 transdate => $transdate1,
865 invoiceitems => [ $item1, $item2 ],
866 payment_id => $payment_terms->id,
870 my %params = ( chart_id => $bank_account->chart_id,
871 transdate => $transdate1,
875 $params{amount} = $invoice->amount_less_skonto;
876 $params{payment_type} = 'with_skonto_pt';
878 $invoice->pay_invoice( %params );
880 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
881 my $total = total_amount($invoice);
883 is($invoice->netamount, 100, "${title}: netamount");
884 is($invoice->amount, 113, "${title}: amount");
885 is($paid_amount, -113, "${title}: paid amount");
886 is($invoice->paid, 113, "${title}: paid");
887 is($number_of_payments, 3, "${title}: 3 AR_paid bookings");
888 is($total, 0, "${title}: even balance");
892 sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25 {
893 my $title = 'default invoice, four items, 19/7% tax with_skonto_pt 4x25';
895 my $item1 = create_invoice_item(part => $parts[2], qty => 0.5);
896 my $item2 = create_invoice_item(part => $parts[3], qty => 0.5);
897 my $item3 = create_invoice_item(part => $parts[2], qty => 0.5);
898 my $item4 = create_invoice_item(part => $parts[3], qty => 0.5);
899 my $invoice = create_sales_invoice(
901 transdate => $transdate1,
902 invoiceitems => [ $item1, $item2, $item3, $item4 ],
903 payment_id => $payment_terms->id,
907 my %params = ( chart_id => $bank_account->chart_id,
908 transdate => $transdate1,
912 $params{amount} = $invoice->amount_less_skonto;
913 $params{payment_type} = 'with_skonto_pt';
915 $invoice->pay_invoice( %params );
917 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
918 my $total = total_amount($invoice);
920 is($invoice->netamount , 100 , "${title}: netamount");
921 is($invoice->amount , 113 , "${title}: amount");
922 is($paid_amount , -113 , "${title}: paid amount");
923 is($invoice->paid , 113 , "${title}: paid");
924 is($number_of_payments , 3 , "${title}: 3 AR_paid bookings");
925 is($total , 0 , "${title}: even balance");
928 sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_tax_included {
929 my $title = 'default invoice, four items, 19/7% tax with_skonto_pt 4x25';
931 my $item1 = create_invoice_item(part => $parts[2], qty => 0.5);
932 my $item2 = create_invoice_item(part => $parts[3], qty => 0.5);
933 my $item3 = create_invoice_item(part => $parts[2], qty => 0.5);
934 my $item4 = create_invoice_item(part => $parts[3], qty => 0.5);
935 my $invoice = create_sales_invoice(
937 transdate => $transdate1,
938 invoiceitems => [ $item1, $item2, $item3, $item4 ],
939 payment_id => $payment_terms->id,
943 my %params = ( chart_id => $bank_account->chart_id,
944 transdate => $transdate1,
948 $params{amount} = $invoice->amount_less_skonto;
949 $params{payment_type} = 'with_skonto_pt';
951 $invoice->pay_invoice( %params );
953 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
954 my $total = total_amount($invoice);
956 is($invoice->netamount, 88.75, "${title}: netamount");
957 is($invoice->amount, 100, "${title}: amount");
958 is($paid_amount, -100, "${title}: paid amount");
959 is($invoice->paid, 100, "${title}: paid");
960 is($number_of_payments, 3, "${title}: 3 AR_paid bookings");
962 local $TODO = "currently this test fails because the code writing the invoice is buggy, the calculation of skonto is correct";
963 is($total, 0, "${title}: even balance");
967 sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_multiple {
968 my $title = 'default invoice, four items, 19/7% tax with_skonto_pt 4x25';
970 my $item1 = create_invoice_item(part => $parts[2], qty => 0.5);
971 my $item2 = create_invoice_item(part => $parts[3], qty => 0.5);
972 my $item3 = create_invoice_item(part => $parts[2], qty => 0.5);
973 my $item4 = create_invoice_item(part => $parts[3], qty => 0.5);
974 my $invoice = create_sales_invoice(
976 transdate => $transdate1,
977 invoiceitems => [ $item1, $item2, $item3, $item4 ],
978 payment_id => $payment_terms->id,
981 $invoice->pay_invoice( amount => '90',
982 payment_type => 'without_skonto',
983 chart_id => $bank_account->chart_id,
984 transdate => $transdate1,
986 $invoice->pay_invoice( payment_type => 'difference_as_skonto',
987 chart_id => $bank_account->chart_id,
988 transdate => $transdate1,
992 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
993 my $total = total_amount($invoice);
995 is($invoice->netamount, 100, "${title}: netamount");
996 is($invoice->amount, 113, "${title}: amount");
997 is($paid_amount, -113, "${title}: paid amount");
998 is($invoice->paid, 113, "${title}: paid");
999 is($number_of_payments, 3, "${title}: 3 AR_paid bookings");
1000 is($total, 0, "${title}: even balance: this will fail due to rounding error in invoice post, not the skonto");
1003 sub test_ar_currency_tax_not_included_and_payment {
1004 my $title = 'test_ar_currency_tax_not_included_and_payment_2';
1006 my $netamount = $::form->round_amount(75 * $exchangerate->sell,2); # 75 in CUR, 100.00 in EUR
1007 my $amount = $::form->round_amount($netamount * 1.19,2); # 100 in CUR, 119.00 in EUR
1008 my $invoice = SL::DB::Invoice->new(
1011 netamount => $netamount,
1012 transdate => $transdate1,
1014 customer_id => $customer->id,
1015 taxzone_id => $customer->taxzone_id,
1016 currency_id => $currency->id,
1018 notes => 'test_ar_currency_tax_not_included_and_payment',
1020 $invoice->add_ar_amount_row(
1021 amount => $invoice->netamount,
1022 chart => $ar_amount_chart,
1026 $invoice->create_ar_row(chart => $ar_chart);
1029 is(SL::DB::Manager::Invoice->get_all_count(where => [ invoice => 0 ]), 1, 'there is one ar transaction');
1030 is($invoice->currency_id , $currency->id , 'currency_id has been saved');
1031 is($invoice->netamount , 100 , 'ar amount has been converted');
1032 is($invoice->amount , 119 , 'ar amount has been converted');
1033 is($invoice->taxincluded , 0 , 'ar transaction doesn\'t have taxincluded');
1034 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');
1035 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');
1037 $invoice->pay_invoice(chart_id => $bank->id,
1040 transdate => $transdate1->to_kivitendo,
1042 $invoice->pay_invoice(chart_id => $bank->id,
1045 transdate => $transdate1->to_kivitendo,
1047 # $invoice->pay_invoice(chart_id => $bank->id,
1049 # transdate => $transdate2->to_kivitendo,
1051 is(scalar @{$invoice->transactions}, 9, 'ar transaction has 9 transactions (incl. fxtransactions)');
1052 is($invoice->paid, $invoice->amount, 'ar transaction paid = amount in default currency');
1055 sub test_ar_currency_tax_included {
1056 my $title = 'test_ar_currency_tax_included';
1058 # we want the acc_trans amount to be 100
1059 my $amount = $::form->round_amount(75 * $exchangerate->sell * 1.19);
1060 my $netamount = $::form->round_amount($amount / 1.19,2);
1061 my $invoice = SL::DB::Invoice->new(
1065 transdate => $transdate1,
1067 customer_id => $customer->id,
1068 taxzone_id => $customer->taxzone_id,
1069 currency_id => $currency->id,
1070 notes => 'test_ar_currency_tax_included',
1073 $invoice->add_ar_amount_row( # should take care of taxincluded
1074 amount => $invoice->amount, # tax included in local currency
1075 chart => $ar_amount_chart,
1079 $invoice->create_ar_row( chart => $ar_chart );
1081 is(SL::DB::Manager::Invoice->get_all_count(where => [ invoice => 0 ]), 2, 'there are now two ar transactions');
1082 is($invoice->currency_id , $currency->id , 'currency_id has been saved');
1083 is($invoice->amount , $amount , 'amount ok');
1084 is($invoice->netamount , $netamount , 'netamount ok');
1085 is($invoice->taxincluded , 1 , 'ar transaction has taxincluded');
1086 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');
1087 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');
1088 $invoice->pay_invoice(chart_id => $bank->id,
1091 transdate => $transdate1->to_kivitendo,
1096 sub test_ap_currency_tax_not_included_and_payment {
1097 my $title = 'test_ap_currency_tax_not_included_and_payment';
1099 my $netamount = $::form->round_amount(75 * $exchangerate->buy,2); # 75 in CUR, 100.00 in EUR
1100 my $amount = $::form->round_amount($netamount * 1.19,2); # 100 in CUR, 119.00 in EUR
1101 my $invoice = SL::DB::PurchaseInvoice->new(
1103 invnumber => 'test_ap_currency_tax_not_included_and_payment',
1105 netamount => $netamount,
1106 transdate => $transdate1,
1108 vendor_id => $vendor->id,
1109 taxzone_id => $vendor->taxzone_id,
1110 currency_id => $currency->id,
1112 notes => 'test_ap_currency_tax_not_included_and_payment',
1114 $invoice->add_ap_amount_row(
1115 amount => $invoice->netamount,
1116 chart => $ap_amount_chart,
1117 tax_id => $tax_9->id,
1120 $invoice->create_ap_row(chart => $ap_chart);
1123 is($invoice->currency_id, $currency->id, 'currency_id has been saved');
1124 is($invoice->netamount, 100, 'ap amount has been converted');
1125 is($invoice->amount, 119, 'ap amount has been converted');
1126 is($invoice->taxincluded, 0, 'ap transaction doesn\'t have taxincluded');
1127 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');
1128 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');
1130 $invoice->pay_invoice(chart_id => $bank->id,
1133 transdate => $transdate1->to_kivitendo,
1135 $invoice->pay_invoice(chart_id => $bank->id,
1138 transdate => $transdate1->to_kivitendo,
1140 is(scalar @{$invoice->transactions}, 9, 'ap transaction has 9 transactions (incl. fxtransactions)');
1141 is($invoice->paid, $invoice->amount, 'ap transaction paid = amount in default currency');
1144 sub test_ap_currency_tax_included {
1145 my $title = 'test_ap_currency_tax_included';
1147 # we want the acc_trans amount to be 100
1148 my $amount = $::form->round_amount(75 * $exchangerate->buy * 1.19);
1149 my $netamount = $::form->round_amount($amount / 1.19,2);
1150 my $invoice = SL::DB::PurchaseInvoice->new(
1152 amount => 119, #$amount,
1153 netamount => 100, #$netamount,
1154 transdate => $transdate1,
1156 vendor_id => $vendor->id,
1157 taxzone_id => $vendor->taxzone_id,
1158 currency_id => $currency->id,
1159 notes => 'test_ap_currency_tax_included',
1160 invnumber => 'test_ap_currency_tax_included',
1163 $invoice->add_ap_amount_row( # should take care of taxincluded
1164 amount => $invoice->amount, # tax included in local currency
1165 chart => $ap_amount_chart,
1166 tax_id => $tax_9->id,
1169 $invoice->create_ap_row( chart => $ap_chart );
1171 is($invoice->currency_id , $currency->id , 'currency_id has been saved');
1172 is($invoice->amount , $amount , 'amount ok');
1173 is($invoice->netamount , $netamount , 'netamount ok');
1174 is($invoice->taxincluded , 1 , 'ap transaction has taxincluded');
1175 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');
1176 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');
1178 $invoice->pay_invoice(chart_id => $bank->id,
1181 transdate => $transdate1->to_kivitendo,
1186 sub test_ar_currency_tax_not_included_and_payment_2 {
1187 my $title = 'test_ar_currency_tax_not_included_and_payment_2';
1189 my $netamount = $::form->round_amount(125 * $exchangerate2->sell,2); # 125.00 in CUR, 100.00 in EUR
1190 my $amount = $::form->round_amount($netamount * 1.19,2); # 148.75 in CUR, 119.00 in EUR
1191 my $invoice = SL::DB::Invoice->new(
1194 netamount => $netamount,
1195 transdate => $transdate2,
1197 customer_id => $customer->id,
1198 taxzone_id => $customer->taxzone_id,
1199 currency_id => $currency->id,
1201 notes => 'test_ar_currency_tax_not_included_and_payment 0.8',
1202 invnumber => 'test_ar_currency_tax_not_included_and_payment 0.8',
1204 $invoice->add_ar_amount_row(
1205 amount => $invoice->netamount,
1206 chart => $ar_amount_chart,
1210 $invoice->create_ar_row(chart => $ar_chart);
1213 is($invoice->currency_id , $currency->id , "$title: currency_id has been saved");
1214 is($invoice->netamount , 100 , "$title: ar amount has been converted");
1215 is($invoice->amount , 119 , "$title: ar amount has been converted");
1216 is($invoice->taxincluded , 0 , "$title: ar transaction doesn\"t have taxincluded");
1217 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");
1218 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');
1220 $invoice->pay_invoice(chart_id => $bank->id,
1223 transdate => $transdate2->to_kivitendo,
1225 $invoice->pay_invoice(chart_id => $bank->id,
1228 transdate => $transdate3->to_kivitendo,
1230 $invoice->pay_invoice(chart_id => $bank->id,
1233 transdate => $transdate4->to_kivitendo,
1235 # $invoice->pay_invoice(chart_id => $bank->id,
1237 # transdate => $transdate2->to_kivitendo,
1239 my $fx_transactions = SL::DB::Manager::AccTransaction->get_all(where => [ trans_id => $invoice->id, fx_transaction => 1 ], sort_by => ('acc_trans_id'));
1240 is(scalar @{$fx_transactions}, 3, "$title: ar transaction has 3 fx transactions");
1241 is($fx_transactions->[0]->amount, '24.69000', "$title fx transactions 1: 123.45-(123.45*0.8) = 24.69");
1243 is(scalar @{$invoice->transactions}, 14, "$title ar transaction has 14 transactions (incl. fxtransactions and fx_gain)");
1244 is($invoice->paid, $invoice->amount, "$title ar transaction paid = amount in default currency");
1247 sub test_ar_currency_tax_not_included_and_payment_2_credit_note {
1248 my $title = 'test_ar_currency_tax_not_included_and_payment_2_credit_note';
1250 my $netamount = $::form->round_amount(-125 * $exchangerate2->sell,2); # 125.00 in CUR, 100.00 in EUR
1251 my $amount = $::form->round_amount($netamount * 1.19,2); # 148.75 in CUR, 119.00 in EUR
1252 my $invoice = SL::DB::Invoice->new(
1255 netamount => $netamount,
1256 transdate => $transdate2,
1258 customer_id => $customer->id,
1259 taxzone_id => $customer->taxzone_id,
1260 currency_id => $currency->id,
1262 notes => 'test_ar_currency_tax_not_included_and_payment credit note 0.8',
1263 invnumber => 'test_ar_currency_tax_not_included_and_payment credit note 0.8',
1265 $invoice->add_ar_amount_row(
1266 amount => $invoice->netamount,
1267 chart => $ar_amount_chart,
1271 $invoice->create_ar_row(chart => $ar_chart);
1274 is($invoice->currency_id , $currency->id , 'currency_id has been saved');
1275 is($invoice->netamount , -100 , 'ar amount has been converted');
1276 is($invoice->amount , -119 , 'ar amount has been converted');
1277 is($invoice->taxincluded , 0 , 'ar transaction doesn\'t have taxincluded');
1278 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');
1279 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');
1281 $invoice->pay_invoice(chart_id => $bank->id,
1284 transdate => $transdate2->to_kivitendo,
1286 $invoice->pay_invoice(chart_id => $bank->id,
1289 transdate => $transdate2->to_kivitendo,
1291 my $fx_transactions = SL::DB::Manager::AccTransaction->get_all(where => [ trans_id => $invoice->id, fx_transaction => 1 ], sort_by => ('acc_trans_id'));
1292 is(scalar @{$fx_transactions}, 2, 'ar transaction has 2 fx transactions');
1293 is($fx_transactions->[0]->amount, '-24.69000', 'fx transactions 1: 123.45-(123.45*0.8) = 24.69');
1295 is(scalar @{$invoice->transactions}, 9, 'ar transaction has 9 transactions (incl. fxtransactions)');
1296 is($invoice->paid, $invoice->amount, 'ar transaction paid = amount in default currency');
1299 sub test_ap_currency_tax_not_included_and_payment_2 {
1300 my $title = 'test_ap_currency_tax_not_included_and_payment_2';
1302 my $netamount = $::form->round_amount(125 * $exchangerate2->sell,2); # 125.00 in CUR, 100.00 in EUR
1303 my $amount = $::form->round_amount($netamount * 1.19,2); # 148.75 in CUR, 119.00 in EUR
1304 my $invoice = SL::DB::PurchaseInvoice->new(
1307 netamount => $netamount,
1308 transdate => $transdate2,
1310 vendor_id => $vendor->id,
1311 taxzone_id => $vendor->taxzone_id,
1312 currency_id => $currency->id,
1314 notes => 'test_ap_currency_tax_not_included_and_payment_2 0.8 + 1.33333',
1315 invnumber => 'test_ap_currency_tax_not_included_and_payment_2 0.8 + 1.33333',
1317 $invoice->add_ap_amount_row(
1318 amount => $invoice->netamount,
1319 chart => $ap_amount_chart,
1320 tax_id => $tax_9->id,
1323 $invoice->create_ap_row(chart => $ap_chart);
1326 is($invoice->currency_id , $currency->id , "$title: currency_id has been saved");
1327 is($invoice->netamount , 100 , "$title: ap amount has been converted");
1328 is($invoice->amount , 119 , "$title: ap amount has been converted");
1329 is($invoice->taxincluded , 0 , "$title: ap transaction doesn\'t have taxincluded");
1330 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');
1331 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');
1333 $invoice->pay_invoice(chart_id => $bank->id,
1336 transdate => $transdate2->to_kivitendo,
1338 $invoice->pay_invoice(chart_id => $bank->id,
1341 transdate => $transdate3->to_kivitendo,
1343 $invoice->pay_invoice(chart_id => $bank->id,
1346 transdate => $transdate4->to_kivitendo,
1348 my $fx_transactions = SL::DB::Manager::AccTransaction->get_all(where => [ trans_id => $invoice->id, fx_transaction => 1 ], sort_by => ('acc_trans_id'));
1349 is(scalar @{$fx_transactions}, 3, "$title: ap transaction has 3 fx transactions");
1350 is($fx_transactions->[0]->amount, '-2.00000', "$title: fx transaction 1: 10.00-( 10.00*0.80000) = 2.00000");
1351 is($fx_transactions->[1]->amount, '68.59000', "$title: fx transaction 2: 123.45-(123.45*1.55557) = -68.58511");
1352 is($fx_transactions->[2]->amount, '-3.40000', "$title: fx transaction 3: 15.30-(15.30 *0.77777) = 3.40012");
1354 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'));
1355 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'));
1356 is($fx_gain_transactions->[0]->amount, '0.34000', "$title: fx gain amount ok");
1357 is($fx_loss_transactions->[0]->amount, '-93.28000', "$title: fx loss amount ok");
1359 is(scalar @{$invoice->transactions}, 14, "$title: ap transaction has 14 transactions (incl. fxtransactions and gain_loss)");
1360 is($invoice->paid, $invoice->amount, "$title: ap transaction paid = amount in default currency");
1361 is(total_amount($invoice), 0, "$title: even balance");
1364 sub test_ap_currency_tax_not_included_and_payment_2_credit_note {
1365 my $title = 'test_ap_currency_tax_not_included_and_payment_2_credit_note';
1367 my $netamount = $::form->round_amount(-125 * $exchangerate2->sell,2); # 125.00 in CUR, 100.00 in EUR
1368 my $amount = $::form->round_amount($netamount * 1.19,2); # 148.75 in CUR, 119.00 in EUR
1369 my $invoice = SL::DB::PurchaseInvoice->new(
1372 netamount => $netamount,
1373 transdate => $transdate2,
1375 vendor_id => $vendor->id,
1376 taxzone_id => $vendor->taxzone_id,
1377 currency_id => $currency->id,
1379 notes => 'test_ap_currency_tax_not_included_and_payment credit note 0.8 + 1.33333',
1380 invnumber => 'test_ap_currency_tax_not_included_and_payment credit note 0.8 + 1.33333',
1382 $invoice->add_ap_amount_row(
1383 amount => $invoice->netamount,
1384 chart => $ap_amount_chart,
1385 tax_id => $tax_9->id,
1388 $invoice->create_ap_row(chart => $ap_chart);
1391 is($invoice->currency_id , $currency->id , "$title: currency_id has been saved");
1392 is($invoice->netamount , -100 , "$title: ap amount has been converted");
1393 is($invoice->amount , -119 , "$title: ap amount has been converted");
1394 is($invoice->taxincluded , 0 , "$title: ap transaction doesn\'t have taxincluded");
1395 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');
1396 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');
1398 $invoice->pay_invoice(chart_id => $bank->id,
1401 transdate => $transdate2->to_kivitendo,
1403 $invoice->pay_invoice(chart_id => $bank->id,
1406 transdate => $transdate3->to_kivitendo,
1408 $invoice->pay_invoice(chart_id => $bank->id,
1411 transdate => $transdate4->to_kivitendo,
1413 my $fx_transactions = SL::DB::Manager::AccTransaction->get_all(where => [ trans_id => $invoice->id, fx_transaction => 1 ], sort_by => ('acc_trans_id'));
1414 is(scalar @{$fx_transactions}, 3, "$title: ap transaction has 3 fx transactions");
1415 is($fx_transactions->[0]->amount, '2.00000', "$title: fx transaction 1: 10.00-( 10.00*0.80000) = 2.00000");
1416 is($fx_transactions->[1]->amount, '-68.59000', "$title: fx transaction 2: 123.45-(123.45*1.55557) = -68.58511");
1417 is($fx_transactions->[2]->amount, '3.40000', "$title: fx transaction 3: 15.30-(15.30 *0.77777) = 3.40012");
1419 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'));
1420 is($fx_gain_loss_transactions->[0]->amount, '93.28000', "$title: fx gain loss amount ok");
1422 is(scalar @{$invoice->transactions}, 14, "$title: ap transaction has 14 transactions (incl. fxtransactions and gain_loss)");
1423 is($invoice->paid, $invoice->amount, "$title: ap transaction paid = amount in default currency");
1424 is(total_amount($invoice), 0, "$title: even balance");
1427 sub test_credit_note_two_items_19_7_tax_tax_not_included {
1428 my $title = 'test_credit_note_two_items_19_7_tax_tax_not_included';
1430 my $item1 = create_invoice_item(part => $parts[0], qty => 5);
1431 my $item2 = create_invoice_item(part => $parts[1], qty => 3);
1432 my $invoice = create_credit_note(
1434 transdate => $transdate1,
1436 invoiceitems => [ $item1, $item2 ],
1440 my %params = ( chart_id => $bank_account->chart_id,
1441 transdate => $transdate1,
1444 $params{amount} = $invoice->amount,
1446 $invoice->pay_invoice( %params );
1448 my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
1449 my $total = total_amount($invoice);
1451 is($invoice->netamount, -40.84, "${title}: netamount");
1452 is($invoice->amount, -45.10, "${title}: amount");
1453 is($paid_amount, 45.10, "${title}: paid amount according to acc_trans is positive (Haben)");
1454 is($invoice->paid, -45.10, "${title}: paid");
1455 is($number_of_payments, 1, "${title}: 1 AR_paid bookings");
1456 is($total, 0, "${title}: even balance");