Paymenthelper kann Fremdwährung mit Steuer inkl. und exkl.
[kivitendo-erp.git] / t / db_helper / payment.t
1 use Test::More;
2
3 use strict;
4
5 use lib 't';
6 use utf8;
7
8 use Carp;
9 use Support::TestSetup;
10 use Test::Exception;
11 use List::Util qw(sum);
12
13 use SL::DB::Buchungsgruppe;
14 use SL::DB::Currency;
15 use SL::DB::Exchangerate;
16 use SL::DB::Customer;
17 use SL::DB::Vendor;
18 use SL::DB::Employee;
19 use SL::DB::Invoice;
20 use SL::DB::Part;
21 use SL::DB::Unit;
22 use SL::DB::TaxZone;
23 use SL::DB::BankAccount;
24 use SL::DB::PaymentTerm;
25 use Data::Dumper;
26
27 my ($customer, $vendor, $currency_id, @parts, $buchungsgruppe, $buchungsgruppe7, $unit, $employee, $tax, $tax7, $tax_9, $taxzone, $payment_terms, $bank_account);
28 my ($transdate, $transdate2, $currency, $exchangerate, $exchangerate2);
29 my ($ar_chart,$bank,$ar_amount_chart, $ap_chart, $ap_amount_chart);
30
31 my $ALWAYS_RESET = 1;
32
33 my $reset_state_counter = 0;
34
35 my $purchase_invoice_counter = 0; # used for generating purchase invnumber
36
37 sub clear_up {
38   SL::DB::Manager::InvoiceItem->delete_all(all => 1);
39   SL::DB::Manager::Invoice->delete_all(all => 1);
40   SL::DB::Manager::PurchaseInvoice->delete_all(all => 1);
41   SL::DB::Manager::Part->delete_all(all => 1);
42   SL::DB::Manager::Customer->delete_all(all => 1);
43   SL::DB::Manager::Vendor->delete_all(all => 1);
44   SL::DB::Manager::BankAccount->delete_all(all => 1);
45   SL::DB::Manager::PaymentTerm->delete_all(all => 1);
46   SL::DB::Manager::Exchangerate->delete_all(all => 1);
47   SL::DB::Manager::Currency->delete_all(where => [ name => 'CUR' ]);
48 };
49
50 sub reset_state {
51   my %params = @_;
52
53   return if $reset_state_counter;
54
55   $params{$_} ||= {} for qw(buchungsgruppe unit customer part tax vendor);
56
57   clear_up();
58
59   $transdate  = DateTime->today;
60   $transdate2 = DateTime->today->add(days => 1);
61
62   $buchungsgruppe  = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 19%', %{ $params{buchungsgruppe} }) || croak "No accounting group";
63   $buchungsgruppe7 = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 7%')                                || croak "No accounting group for 7\%";
64   $unit            = SL::DB::Manager::Unit->find_by(name => 'kg', %{ $params{unit} })                                      || croak "No unit";
65   $employee        = SL::DB::Manager::Employee->current                                                                    || croak "No employee";
66   $tax             = SL::DB::Manager::Tax->find_by(taxkey => 3, rate => 0.19, %{ $params{tax} })                           || croak "No tax";
67   $tax7            = SL::DB::Manager::Tax->find_by(taxkey => 2, rate => 0.07)                                              || croak "No tax for 7\%";
68   $taxzone         = SL::DB::Manager::TaxZone->find_by( description => 'Inland')                                           || croak "No taxzone";
69   $tax_9           = SL::DB::Manager::Tax->find_by(taxkey => 9, rate => 0.19, %{ $params{tax} })                           || croak "No tax";
70   # $tax7            = SL::DB::Manager::Tax->find_by(taxkey => 2, rate => 0.07)                                              || croak "No tax for 7\%";
71
72   $currency_id     = $::instance_conf->get_currency_id;
73
74   $currency = SL::DB::Currency->new(name => 'CUR')->save;
75   $exchangerate  = SL::DB::Exchangerate->new(transdate   => $transdate,
76                                              buy         => '1.33333',
77                                              sell        => '1.33333',
78                                              currency_id => $currency->id,
79                                             )->save;
80   $exchangerate2 = SL::DB::Exchangerate->new(transdate   => $transdate2,
81                                              buy         => '1.55555',
82                                              sell        => '1.55555',
83                                              currency_id => $currency->id,
84                                             )->save;
85
86   $customer     = SL::DB::Customer->new(
87     name        => 'Test Customer',
88     currency_id => $currency_id,
89     taxzone_id  => $taxzone->id,
90     %{ $params{customer} }
91   )->save;
92
93   $bank_account     =  SL::DB::BankAccount->new(
94     account_number  => '123',
95     bank_code       => '123',
96     iban            => '123',
97     bic             => '123',
98     bank            => '123',
99     chart_id        => SL::DB::Manager::Chart->find_by( description => 'Bank' )->id,
100     name            => SL::DB::Manager::Chart->find_by( description => 'Bank' )->description,
101   )->save;
102
103   $payment_terms     =  SL::DB::PaymentTerm->new(
104     description      => 'payment',
105     description_long => 'payment',
106     terms_netto      => '30',
107     terms_skonto     => '5',
108     percent_skonto   => '0.05',
109     auto_calculation => 1,
110   )->save;
111
112   $vendor       = SL::DB::Vendor->new(
113     name        => 'Test Vendor',
114     currency_id => $currency_id,
115     taxzone_id  => $taxzone->id,
116     payment_id  => $payment_terms->id,
117     %{ $params{vendor} }
118   )->save;
119
120
121   @parts = ();
122   push @parts, SL::DB::Part->new(
123     partnumber         => 'T4254',
124     description        => 'Fourty-two fifty-four',
125     lastcost           => 1.93,
126     sellprice          => 2.34,
127     buchungsgruppen_id => $buchungsgruppe->id,
128     unit               => $unit->name,
129     %{ $params{part1} }
130   )->save;
131
132   push @parts, SL::DB::Part->new(
133     partnumber         => 'T0815',
134     description        => 'Zero EIGHT fifteeN @ 7%',
135     lastcost           => 5.473,
136     sellprice          => 9.714,
137     buchungsgruppen_id => $buchungsgruppe7->id,
138     unit               => $unit->name,
139     %{ $params{part2} }
140   )->save;
141   push @parts, SL::DB::Part->new(
142     partnumber         => '19%',
143     description        => 'Testware 19%',
144     lastcost           => 0,
145     sellprice          => 50,
146     buchungsgruppen_id => $buchungsgruppe->id,
147     unit               => $unit->name,
148     %{ $params{part3} }
149   )->save;
150   push @parts, SL::DB::Part->new(
151     partnumber         => '7%',
152     description        => 'Testware 7%',
153     lastcost           => 0,
154     sellprice          => 50,
155     buchungsgruppen_id => $buchungsgruppe7->id,
156     unit               => $unit->name,
157     %{ $params{part4} }
158   )->save;
159
160   $ar_chart        = SL::DB::Manager::Chart->find_by( accno => '1400' ); # Forderungen
161   $ap_chart        = SL::DB::Manager::Chart->find_by( accno => '1600' ); # Verbindlichkeiten
162   $bank            = SL::DB::Manager::Chart->find_by( accno => '1200' ); # Bank
163   $ar_amount_chart = SL::DB::Manager::Chart->find_by( accno => '8400' ); # Erlöse
164   $ap_amount_chart = SL::DB::Manager::Chart->find_by( accno => '3400' ); # Wareneingang 19%
165
166   $reset_state_counter++;
167 }
168
169 sub new_invoice {
170   my %params  = @_;
171
172   return SL::DB::Invoice->new(
173     customer_id => $customer->id,
174     currency_id => $currency_id,
175     employee_id => $employee->id,
176     salesman_id => $employee->id,
177     gldate      => DateTime->today_local->to_kivitendo,
178     taxzone_id  => $taxzone->id,
179     transdate   => DateTime->today_local->to_kivitendo,
180     invoice     => 1,
181     type        => 'invoice',
182     %params,
183   );
184
185 }
186
187 sub new_purchase_invoice {
188   # my %params  = @_;
189   # manually create a Kreditorenbuchung from scratch, ap + acc_trans bookings, as no helper exists yet, like $invoice->post.
190   # arap-Booking must come last in the acc_trans order
191   $purchase_invoice_counter++;
192
193   my $purchase_invoice = SL::DB::PurchaseInvoice->new(
194     vendor_id   => $vendor->id,
195     invnumber   => 'newap ' . $purchase_invoice_counter ,
196     currency_id => $currency_id,
197     employee_id => $employee->id,
198     gldate      => DateTime->today_local->to_kivitendo,
199     taxzone_id  => $taxzone->id,
200     transdate   => DateTime->today_local->to_kivitendo,
201     invoice     => 0,
202     type        => 'invoice',
203     taxincluded => 0,
204     amount      => '226',
205     netamount   => '200',
206     paid        => '0',
207     # %params,
208   )->save;
209
210   my $expense_chart  = SL::DB::Manager::Chart->find_by(accno => '3400');
211   my $expense_chart_booking= SL::DB::AccTransaction->new(
212                                         trans_id   => $purchase_invoice->id,
213                                         chart_id   => $expense_chart->id,
214                                         chart_link => $expense_chart->link,
215                                         amount     => '-100',
216                                         transdate  => $transdate,
217                                         source     => '',
218                                         taxkey     => 9,
219                                         tax_id     => SL::DB::Manager::Tax->find_by(taxkey => 9)->id);
220   $expense_chart_booking->save;
221
222   my $tax_chart  = SL::DB::Manager::Chart->find_by(accno => '1576');
223   my $tax_chart_booking= SL::DB::AccTransaction->new(
224                                         trans_id   => $purchase_invoice->id,
225                                         chart_id   => $tax_chart->id,
226                                         chart_link => $tax_chart->link,
227                                         amount     => '-19',
228                                         transdate  => $transdate,
229                                         source     => '',
230                                         taxkey     => 0,
231                                         tax_id     => SL::DB::Manager::Tax->find_by(taxkey => 9)->id);
232   $tax_chart_booking->save;
233   $expense_chart  = SL::DB::Manager::Chart->find_by(accno => '3300');
234   $expense_chart_booking= SL::DB::AccTransaction->new(
235                                         trans_id   => $purchase_invoice->id,
236                                         chart_id   => $expense_chart->id,
237                                         chart_link => $expense_chart->link,
238                                         amount     => '-100',
239                                         transdate  => $transdate,
240                                         source     => '',
241                                         taxkey     => 8,
242                                         tax_id     => SL::DB::Manager::Tax->find_by(taxkey => 8)->id);
243   $expense_chart_booking->save;
244
245
246   $tax_chart  = SL::DB::Manager::Chart->find_by(accno => '1571');
247   $tax_chart_booking= SL::DB::AccTransaction->new(
248                                          trans_id   => $purchase_invoice->id,
249                                          chart_id   => $tax_chart->id,
250                                          chart_link => $tax_chart->link,
251                                          amount     => '-7',
252                                          transdate  => $transdate,
253                                          source     => '',
254                                          taxkey     => 0,
255                                          tax_id     => SL::DB::Manager::Tax->find_by(taxkey => 8)->id);
256   $tax_chart_booking->save;
257   my $arap_chart  = SL::DB::Manager::Chart->find_by(accno => '1600');
258   my $arap_booking= SL::DB::AccTransaction->new(trans_id   => $purchase_invoice->id,
259                                                 chart_id   => $arap_chart->id,
260                                                 chart_link => $arap_chart->link,
261                                                 amount     => '226',
262                                                 transdate  => $transdate,
263                                                 source     => '',
264                                                 taxkey     => 0,
265                                                 tax_id     => SL::DB::Manager::Tax->find_by(taxkey => 0)->id);
266   $arap_booking->save;
267
268   return $purchase_invoice;
269 }
270
271 sub new_item {
272   my (%params) = @_;
273
274   my $part = delete($params{part}) || $parts[0];
275
276   return SL::DB::InvoiceItem->new(
277     parts_id    => $part->id,
278     lastcost    => $part->lastcost,
279     sellprice   => $part->sellprice,
280     description => $part->description,
281     unit        => $part->unit,
282     %params,
283   );
284 }
285
286 sub number_of_payments {
287   my $invoice = shift;
288
289   my $number_of_payments;
290   my $paid_amount;
291   foreach my $transaction ( @{ $invoice->transactions } ) {
292     if ( $transaction->chart_link =~ /(AR_paid|AP_paid)/ ) {
293       $paid_amount += $transaction->amount ;
294       $number_of_payments++;
295     };
296   };
297   return ($number_of_payments, $paid_amount);
298 };
299
300 sub total_amount {
301   my $invoice = shift;
302
303   my $total = sum map { $_->amount } @{ $invoice->transactions };
304
305   return $::form->round_amount($total, 5);
306
307 };
308
309
310 # test 1
311 sub test_default_invoice_one_item_19_without_skonto() {
312   reset_state() if $ALWAYS_RESET;
313
314   my $item    = new_item(qty => 2.5);
315   my $invoice = new_invoice(
316     taxincluded  => 0,
317     invoiceitems => [ $item ],
318     payment_id   => $payment_terms->id,
319   );
320   $invoice->post;
321
322   my $purchase_invoice = new_purchase_invoice();
323
324
325   # default values
326   my %params = ( chart_id => $bank_account->chart_id,
327                  transdate => DateTime->today_local->to_kivitendo
328                );
329
330   $params{amount} = '6.96';
331   $params{payment_type} = 'without_skonto';
332
333   $invoice->pay_invoice( %params );
334
335   my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
336   my $total = total_amount($invoice);
337
338   my $title = 'default invoice, one item, 19% tax, without_skonto';
339
340   is($invoice->netamount,   5.85,      "${title}: netamount");
341   is($invoice->amount,      6.96,      "${title}: amount");
342   is($paid_amount,         -6.96,      "${title}: paid amount");
343   is($number_of_payments,      1,      "${title}: 1 AR_paid booking");
344   is($invoice->paid,        6.96,      "${title}: paid");
345   is($total,                   0,      "${title}: even balance");
346
347 }
348
349 sub test_default_invoice_one_item_19_without_skonto_overpaid() {
350   reset_state() if $ALWAYS_RESET;
351
352   my $item    = new_item(qty => 2.5);
353   my $invoice = new_invoice(
354     taxincluded  => 0,
355     invoiceitems => [ $item ],
356     payment_id   => $payment_terms->id,
357   );
358   $invoice->post;
359
360   my $purchase_invoice = new_purchase_invoice();
361
362
363   # default values
364   my %params = ( chart_id => $bank_account->chart_id,
365                  transdate => DateTime->today_local->to_kivitendo
366                );
367
368   $params{amount} = '16.96';
369   $params{payment_type} = 'without_skonto';
370   $invoice->pay_invoice( %params );
371
372   $params{amount} = '-10.00';
373   $invoice->pay_invoice( %params );
374
375   my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
376   my $total = total_amount($invoice);
377
378   my $title = 'default invoice, one item, 19% tax, without_skonto';
379
380   is($invoice->netamount,   5.85,      "${title}: netamount");
381   is($invoice->amount,      6.96,      "${title}: amount");
382   is($paid_amount,         -6.96,      "${title}: paid amount");
383   is($number_of_payments,      2,      "${title}: 1 AR_paid booking");
384   is($invoice->paid,        6.96,      "${title}: paid");
385   is($total,                   0,      "${title}: even balance");
386
387 }
388
389
390 # test 2
391 sub test_default_invoice_two_items_19_7_tax_with_skonto() {
392   reset_state() if $ALWAYS_RESET;
393
394   my $item1   = new_item(qty => 2.5);
395   my $item2   = new_item(qty => 1.2, part => $parts[1]);
396   my $invoice = new_invoice(
397     taxincluded  => 0,
398     invoiceitems => [ $item1, $item2 ],
399     payment_id  => $payment_terms->id,
400   );
401   $invoice->post;
402
403   # default values
404   my %params = ( chart_id => $bank_account->chart_id,
405                  transdate => DateTime->today_local->to_kivitendo
406                );
407
408   $params{payment_type} = 'with_skonto_pt';
409   $params{amount}       = $invoice->amount_less_skonto;
410
411   $invoice->pay_invoice( %params );
412
413   my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
414   my $total = total_amount($invoice);
415
416   my $title = 'default invoice, two items, 19/7% tax with_skonto_pt';
417
418   is($invoice->netamount,  5.85 + 11.66,   "${title}: netamount");
419   is($invoice->amount,     6.96 + 12.48,   "${title}: amount");
420   is($paid_amount,               -19.44,   "${title}: paid amount");
421   is($invoice->paid,              19.44,   "${title}: paid");
422   is($number_of_payments,             3,   "${title}: 3 AR_paid bookings");
423   is($total,                          0,   "${title}: even balance");
424 }
425
426 sub test_default_invoice_two_items_19_7_tax_with_skonto_tax_included() {
427   reset_state() if $ALWAYS_RESET;
428
429   my $item1   = new_item(qty => 2.5);
430   my $item2   = new_item(qty => 1.2, part => $parts[1]);
431   my $invoice = new_invoice(
432     taxincluded  => 1,
433     invoiceitems => [ $item1, $item2 ],
434     payment_id  => $payment_terms->id,
435   );
436   $invoice->post;
437
438   # default values
439   my %params = ( chart_id => $bank_account->chart_id,
440                  transdate => DateTime->today_local->to_kivitendo
441                );
442
443   $params{payment_type} = 'with_skonto_pt';
444   $params{amount}       = $invoice->amount_less_skonto;
445
446   $invoice->pay_invoice( %params );
447
448   my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
449   my $total = total_amount($invoice);
450
451   my $title = 'default invoice, two items, 19/7% tax with_skonto_pt';
452
453   is($invoice->netamount,         15.82,   "${title}: netamount");
454   is($invoice->amount,            17.51,   "${title}: amount");
455   is($paid_amount,               -17.51,   "${title}: paid amount");
456   is($invoice->paid,              17.51,   "${title}: paid");
457   is($number_of_payments,             3,   "${title}: 3 AR_paid bookings");
458   { local $TODO = "currently this test fails because the code writing the invoice is buggy, the calculation of skonto is correct";
459   is($total,                          0,   "${title}: even balance");
460   }
461 }
462
463 # test 3 : two items, without skonto
464 sub test_default_invoice_two_items_19_7_without_skonto() {
465   reset_state() if $ALWAYS_RESET;
466
467   my $item1   = new_item(qty => 2.5);
468   my $item2   = new_item(qty => 1.2, part => $parts[1]);
469   my $invoice = new_invoice(
470     taxincluded  => 0,
471     invoiceitems => [ $item1, $item2 ],
472     payment_id  => $payment_terms->id,
473   );
474   $invoice->post;
475
476   # default values
477   my %params = ( chart_id => $bank_account->chart_id,
478                  transdate => DateTime->today_local->to_kivitendo
479                );
480
481   $params{amount} = '19.44'; # pass full amount
482   $params{payment_type} = 'without_skonto';
483
484   $invoice->pay_invoice( %params );
485
486   my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
487   my $total = total_amount($invoice);
488
489   my $title = 'default invoice, two items, 19/7% tax without skonto';
490
491   is($invoice->netamount,     5.85 + 11.66,     "${title}: netamount");
492   is($invoice->amount,        6.96 + 12.48,     "${title}: amount");
493   is($paid_amount,                  -19.44,     "${title}: paid amount");
494   is($invoice->paid,                 19.44,     "${title}: paid");
495   is($number_of_payments,                1,     "${title}: 1 AR_paid bookings");
496   is($total,                             0,     "${title}: even balance");
497 }
498
499 # test 4
500 sub test_default_invoice_two_items_19_7_without_skonto_incomplete_payment() {
501   reset_state() if $ALWAYS_RESET;
502
503   my $item1   = new_item(qty => 2.5);
504   my $item2   = new_item(qty => 1.2, part => $parts[1]);
505   my $invoice = new_invoice(
506     taxincluded  => 0,
507     invoiceitems => [ $item1, $item2 ],
508     payment_id  => $payment_terms->id,
509   );
510   $invoice->post;
511
512   $invoice->pay_invoice( amount       => '9.44',
513                          payment_type => 'without_skonto',
514                          chart_id     => $bank_account->chart_id,
515                          transdate    => DateTime->today_local->to_kivitendo,
516                        );
517
518   my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
519   my $total = total_amount($invoice);
520
521   my $title = 'default invoice, two items, 19/7% tax without skonto incomplete payment';
522
523   is($invoice->netamount,        5.85 + 11.66,     "${title}: netamount");
524   is($invoice->amount,           6.96 + 12.48,     "${title}: amount");
525   is($paid_amount,              -9.44,             "${title}: paid amount");
526   is($invoice->paid,             9.44,            "${title}: paid");
527   is($number_of_payments,   1,                "${title}: 1 AR_paid bookings");
528   is($total,                    0,                "${title}: even balance");
529 }
530
531 # test 5
532 sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments() {
533   reset_state() if $ALWAYS_RESET;
534
535   my $item1   = new_item(qty => 2.5);
536   my $item2   = new_item(qty => 1.2, part => $parts[1]);
537   my $invoice = new_invoice(
538     taxincluded  => 0,
539     invoiceitems => [ $item1, $item2 ],
540     payment_id  => $payment_terms->id,
541   );
542   $invoice->post;
543
544   $invoice->pay_invoice( amount       => '9.44',
545                          payment_type => 'without_skonto',
546                          chart_id     => $bank_account->chart_id,
547                          transdate    => DateTime->today_local->to_kivitendo
548                        );
549   $invoice->pay_invoice( amount       => '10.00',
550                          chart_id     => $bank_account->chart_id,
551                          transdate    => DateTime->today_local->to_kivitendo
552                        );
553
554   my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
555   my $total = total_amount($invoice);
556
557   my $title = 'default invoice, two items, 19/7% tax not included';
558
559   is($invoice->netamount,        5.85 + 11.66,     "${title}: netamount");
560   is($invoice->amount,           6.96 + 12.48,     "${title}: amount");
561   is($paid_amount,                     -19.44,     "${title}: paid amount");
562   is($invoice->paid,                    19.44,     "${title}: paid");
563   is($number_of_payments,                   2,     "${title}: 2 AR_paid bookings");
564   is($total,                                0,     "${title}: even balance");
565
566 }
567
568 # test 6
569 sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto() {
570   reset_state() if $ALWAYS_RESET;
571
572   my $item1   = new_item(qty => 2.5);
573   my $item2   = new_item(qty => 1.2, part => $parts[1]);
574   my $invoice = new_invoice(
575     taxincluded  => 0,
576     invoiceitems => [ $item1, $item2 ],
577     payment_id  => $payment_terms->id,
578   );
579   $invoice->post;
580
581   $invoice->pay_invoice( amount       => '9.44',
582                          payment_type => 'without_skonto',
583                          chart_id     => $bank_account->chart_id,
584                          transdate    => DateTime->today_local->to_kivitendo
585                        );
586   $invoice->pay_invoice( amount       => '8.73',
587                          payment_type => 'without_skonto',
588                          chart_id     => $bank_account->chart_id,
589                          transdate    => DateTime->today_local->to_kivitendo
590                        );
591   $invoice->pay_invoice( amount       => $invoice->open_amount,
592                          payment_type => 'difference_as_skonto',
593                          chart_id     => $bank_account->chart_id,
594                          transdate    => DateTime->today_local->to_kivitendo
595                        );
596
597   my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
598   my $total = total_amount($invoice);
599
600   my $title = 'default invoice, two items, 19/7% tax not included';
601
602   is($invoice->netamount,        5.85 + 11.66,     "${title}: netamount");
603   is($invoice->amount,           6.96 + 12.48,     "${title}: amount");
604   is($paid_amount,                     -19.44,     "${title}: paid amount");
605   is($invoice->paid,                    19.44,     "${title}: paid");
606   is($number_of_payments,                   4,     "${title}: 4 AR_paid bookings");
607   is($total,                                0,     "${title}: even balance");
608
609 }
610
611 sub  test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto_1cent() {
612   reset_state() if $ALWAYS_RESET;
613
614   # if there is only one cent left there can only be one skonto booking, the
615   # error handling should choose the highest amount, which is the 7% account
616   # (11.66) rather than the 19% account (5.85).  The actual tax amount is
617   # higher for the 19% case, though (1.11 compared to 0.82)
618
619   my $item1   = new_item(qty => 2.5);
620   my $item2   = new_item(qty => 1.2, part => $parts[1]);
621   my $invoice = new_invoice(
622     taxincluded  => 0,
623     invoiceitems => [ $item1, $item2 ],
624     payment_id  => $payment_terms->id,
625   );
626   $invoice->post;
627
628   $invoice->pay_invoice( amount       => '19.42',
629                          payment_type => 'without_skonto',
630                          chart_id     => $bank_account->chart_id,
631                          transdate    => DateTime->today_local->to_kivitendo
632                        );
633   $invoice->pay_invoice( amount       => $invoice->open_amount,
634                          payment_type => 'difference_as_skonto',
635                          chart_id     => $bank_account->chart_id,
636                          transdate    => DateTime->today_local->to_kivitendo
637                        );
638
639   my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
640   my $total = total_amount($invoice);
641
642   my $title = 'default invoice, two items, 19/7% tax not included';
643
644   is($invoice->netamount,        5.85 + 11.66,     "${title}: netamount");
645   is($invoice->amount,           6.96 + 12.48,     "${title}: amount");
646   is($paid_amount,                     -19.44,     "${title}: paid amount");
647   is($invoice->paid,                    19.44,     "${title}: paid");
648   is($number_of_payments,                   3,     "${title}: 2 AR_paid bookings");
649   is($total,                                0,     "${title}: even balance");
650
651 }
652
653 sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto_2cent() {
654   reset_state() if $ALWAYS_RESET;
655
656   # if there are two cents left there will be two skonto bookings, 1 cent each
657   my $item1   = new_item(qty => 2.5);
658   my $item2   = new_item(qty => 1.2, part => $parts[1]);
659   my $invoice = new_invoice(
660     taxincluded  => 0,
661     invoiceitems => [ $item1, $item2 ],
662     payment_id  => $payment_terms->id,
663   );
664   $invoice->post;
665
666   $invoice->pay_invoice( amount       => '19.42',
667                          payment_type => 'without_skonto',
668                          chart_id     => $bank_account->chart_id,
669                          transdate    => DateTime->today_local->to_kivitendo
670                        );
671   $invoice->pay_invoice( amount       => $invoice->open_amount,
672                          payment_type => 'difference_as_skonto',
673                          chart_id     => $bank_account->chart_id,
674                          transdate    => DateTime->today_local->to_kivitendo
675                        );
676
677   my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
678   my $total = total_amount($invoice);
679
680   my $title = 'default invoice, two items, 19/7% tax not included';
681
682   is($invoice->netamount,        5.85 + 11.66,     "${title}: netamount");
683   is($invoice->amount,           6.96 + 12.48,     "${title}: amount");
684   is($paid_amount,                     -19.44,     "${title}: paid amount");
685   is($invoice->paid,                    19.44,     "${title}: paid");
686   is($number_of_payments,                   3,     "${title}: 3 AR_paid bookings");
687   is($total,                                0,     "${title}: even balance");
688
689 }
690
691 sub test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto() {
692   reset_state() if $ALWAYS_RESET;
693
694   my $item    = new_item(qty => 2.5);
695   my $invoice = new_invoice(
696     taxincluded  => 0,
697     invoiceitems => [ $item ],
698     payment_id   => $payment_terms->id,
699   );
700   $invoice->post;
701
702   # default values
703   my %params = ( chart_id  => $bank_account->chart_id,
704                  transdate => DateTime->today_local->to_kivitendo
705                );
706
707   $params{amount}       = '2.32';
708   $params{payment_type} = 'without_skonto';
709   $invoice->pay_invoice( %params );
710
711   $params{amount}       = '3.81';
712   $params{payment_type} = 'without_skonto';
713   $invoice->pay_invoice( %params );
714
715   $params{amount}       = $invoice->open_amount; # set amount, otherwise previous 3.81 is used
716   $params{payment_type} = 'difference_as_skonto';
717   $invoice->pay_invoice( %params );
718
719   my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
720   my $total = total_amount($invoice);
721
722   my $title = 'default invoice, one item, 19% tax, without_skonto';
723
724   is($invoice->netamount,       5.85,     "${title}: netamount");
725   is($invoice->amount,          6.96,     "${title}: amount");
726   is($paid_amount,             -6.96,     "${title}: paid amount");
727   is($number_of_payments,          3,     "${title}: 3 AR_paid booking");
728   is($invoice->paid,            6.96,     "${title}: paid");
729   is($total,                       0,     "${title}: even balance");
730
731 }
732
733 sub test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto_1cent() {
734   reset_state() if $ALWAYS_RESET;
735
736   my $item    = new_item(qty => 2.5);
737   my $invoice = new_invoice(
738     taxincluded  => 0,
739     invoiceitems => [ $item ],
740     payment_id   => $payment_terms->id,
741   );
742   $invoice->post;
743
744   # default values
745   my %params = ( chart_id  => $bank_account->chart_id,
746                  transdate => DateTime->today_local->to_kivitendo
747                );
748
749   $params{amount}       = '6.95';
750   $params{payment_type} = 'without_skonto';
751   $invoice->pay_invoice( %params );
752
753   $params{amount}       = $invoice->open_amount; # set amount, otherwise previous value 6.95 is used
754   $params{payment_type} = 'difference_as_skonto';
755   $invoice->pay_invoice( %params );
756
757   my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
758   my $total = total_amount($invoice);
759
760   my $title = 'default invoice, one item, 19% tax, without_skonto';
761
762   is($invoice->netamount,       5.85,     "${title}: netamount");
763   is($invoice->amount,          6.96,     "${title}: amount");
764   is($paid_amount,             -6.96,     "${title}: paid amount");
765   is($number_of_payments,          2,     "${title}: 3 AR_paid booking");
766   is($invoice->paid,            6.96,     "${title}: paid");
767   is($total,                       0,     "${title}: even balance");
768
769 }
770
771 # test 3 : two items, without skonto
772 sub test_default_purchase_invoice_two_charts_19_7_without_skonto() {
773   reset_state() if $ALWAYS_RESET;
774
775   my $purchase_invoice = new_purchase_invoice();
776
777   my %params = ( chart_id => $bank_account->chart_id,
778                  transdate => DateTime->today_local->to_kivitendo
779                );
780
781   $params{amount} = '226'; # pass full amount
782   $params{payment_type} = 'without_skonto';
783
784   $purchase_invoice->pay_invoice( %params );
785
786   my ($number_of_payments, $paid_amount) = number_of_payments($purchase_invoice);
787   my $total = total_amount($purchase_invoice);
788
789   my $title = 'default invoice, two items, 19/7% tax without skonto';
790
791   is($paid_amount,         226,     "${title}: paid amount");
792   is($number_of_payments,    1,     "${title}: 1 AP_paid bookings");
793   is($total,                 0,     "${title}: even balance");
794
795 }
796
797 sub test_default_purchase_invoice_two_charts_19_7_with_skonto() {
798   reset_state() if $ALWAYS_RESET;
799
800   my $purchase_invoice = new_purchase_invoice();
801
802   my %params = ( chart_id => $bank_account->chart_id,
803                  transdate => DateTime->today_local->to_kivitendo
804                );
805
806   # $params{amount} = '226'; # pass full amount
807   $params{payment_type} = 'with_skonto_pt';
808
809   $purchase_invoice->pay_invoice( %params );
810
811   my ($number_of_payments, $paid_amount) = number_of_payments($purchase_invoice);
812   my $total = total_amount($purchase_invoice);
813
814   my $title = 'default invoice, two items, 19/7% tax without skonto';
815
816   is($paid_amount,         226,     "${title}: paid amount");
817   is($number_of_payments,    3,     "${title}: 1 AP_paid bookings");
818   is($total,                 0,     "${title}: even balance");
819
820 }
821
822 sub test_default_purchase_invoice_two_charts_19_7_tax_partial_unrounded_payment_without_skonto() {
823   # check whether unrounded amounts passed via $params{amount} are rounded for without_skonto case
824   reset_state() if $ALWAYS_RESET;
825   my $purchase_invoice = new_purchase_invoice();
826   $purchase_invoice->pay_invoice(
827                           amount       => ( $purchase_invoice->amount / 3 * 2),
828                           payment_type => 'without_skonto',
829                           chart_id     => $bank_account->chart_id,
830                           transdate    => DateTime->today_local->to_kivitendo
831                          );
832   my ($number_of_payments, $paid_amount) = number_of_payments($purchase_invoice);
833   my $total = total_amount($purchase_invoice);
834
835   my $title = 'default purchase_invoice, two charts, 19/7% tax multiple payments with final difference as skonto';
836
837   is($paid_amount,         150.67,   "${title}: paid amount");
838   is($number_of_payments,       1,   "${title}: 1 AP_paid bookings");
839   is($total,                    0,   "${title}: even balance");
840 };
841
842
843 sub test_default_purchase_invoice_two_charts_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto() {
844   reset_state() if $ALWAYS_RESET;
845
846   my $purchase_invoice = new_purchase_invoice();
847
848   # pay 2/3 and 1/5, leaves 3.83% to be used as Skonto
849   $purchase_invoice->pay_invoice(
850                           amount       => ( $purchase_invoice->amount / 3 * 2),
851                           payment_type => 'without_skonto',
852                           chart_id     => $bank_account->chart_id,
853                           transdate    => DateTime->today_local->to_kivitendo
854                          );
855   $purchase_invoice->pay_invoice(
856                           amount       => ( $purchase_invoice->amount / 5 ),
857                           payment_type => 'without_skonto',
858                           chart_id     => $bank_account->chart_id,
859                           transdate    => DateTime->today_local->to_kivitendo
860                          );
861   $purchase_invoice->pay_invoice(
862                           payment_type => 'difference_as_skonto',
863                           chart_id     => $bank_account->chart_id,
864                           transdate    => DateTime->today_local->to_kivitendo
865                          );
866
867   my ($number_of_payments, $paid_amount) = number_of_payments($purchase_invoice);
868   my $total = total_amount($purchase_invoice);
869
870   my $title = 'default purchase_invoice, two charts, 19/7% tax multiple payments with final difference as skonto';
871
872   is($paid_amount,         226, "${title}: paid amount");
873   is($number_of_payments,    4, "${title}: 1 AP_paid bookings");
874   is($total,                 0, "${title}: even balance");
875
876 }
877
878 # test
879 sub test_default_invoice_two_items_19_7_tax_with_skonto_50_50() {
880   reset_state() if $ALWAYS_RESET;
881
882   my $item1   = new_item(qty => 1, part => $parts[2]);
883   my $item2   = new_item(qty => 1, part => $parts[3]);
884   my $invoice = new_invoice(
885     taxincluded  => 0,
886     invoiceitems => [ $item1, $item2 ],
887     payment_id  => $payment_terms->id,
888   );
889   $invoice->post;
890
891   # default values
892   my %params = ( chart_id => $bank_account->chart_id,
893                  transdate => DateTime->today_local->to_kivitendo
894                );
895
896   $params{amount} = $invoice->amount_less_skonto;
897   $params{payment_type} = 'with_skonto_pt';
898
899   $invoice->pay_invoice( %params );
900
901   my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
902   my $total = total_amount($invoice);
903
904   my $title = 'default invoice, two items, 19/7% tax with_skonto_pt 50/50';
905
906   is($invoice->netamount,        100,     "${title}: netamount");
907   is($invoice->amount,           113,     "${title}: amount");
908   is($paid_amount,              -113,     "${title}: paid amount");
909   is($invoice->paid,             113,     "${title}: paid");
910   is($number_of_payments,          3,     "${title}: 3 AR_paid bookings");
911   is($total,                       0,     "${title}: even balance");
912 }
913
914 # test
915 sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25() {
916   reset_state() if $ALWAYS_RESET;
917
918   my $item1   = new_item(qty => 0.5, part => $parts[2]);
919   my $item2   = new_item(qty => 0.5, part => $parts[3]);
920   my $item3   = new_item(qty => 0.5, part => $parts[2]);
921   my $item4   = new_item(qty => 0.5, part => $parts[3]);
922   my $invoice = new_invoice(
923     taxincluded  => 0,
924     invoiceitems => [ $item1, $item2, $item3, $item4 ],
925     payment_id  => $payment_terms->id,
926   );
927   $invoice->post;
928
929   # default values
930   my %params = ( chart_id => $bank_account->chart_id,
931                  transdate => DateTime->today_local->to_kivitendo
932                );
933
934   $params{amount} = $invoice->amount_less_skonto;
935   $params{payment_type} = 'with_skonto_pt';
936
937   $invoice->pay_invoice( %params );
938
939   my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
940   my $total = total_amount($invoice);
941
942   my $title = 'default invoice, four items, 19/7% tax with_skonto_pt 4x25';
943
944   is($invoice->netamount , 100  , "${title}: netamount");
945   is($invoice->amount    , 113  , "${title}: amount");
946   is($paid_amount        , -113 , "${title}: paid amount");
947   is($invoice->paid      , 113  , "${title}: paid");
948   is($number_of_payments , 3    , "${title}: 3 AR_paid bookings");
949   is($total              , 0    , "${title}: even balance");
950 }
951
952 sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_tax_included() {
953   reset_state() if $ALWAYS_RESET;
954
955   my $item1   = new_item(qty => 0.5, part => $parts[2]);
956   my $item2   = new_item(qty => 0.5, part => $parts[3]);
957   my $item3   = new_item(qty => 0.5, part => $parts[2]);
958   my $item4   = new_item(qty => 0.5, part => $parts[3]);
959   my $invoice = new_invoice(
960     taxincluded  => 1,
961     invoiceitems => [ $item1, $item2, $item3, $item4 ],
962     payment_id  => $payment_terms->id,
963   );
964   $invoice->post;
965
966   # default values
967   my %params = ( chart_id => $bank_account->chart_id,
968                  transdate => DateTime->today_local->to_kivitendo
969                );
970
971   $params{amount} = $invoice->amount_less_skonto;
972   $params{payment_type} = 'with_skonto_pt';
973
974   $invoice->pay_invoice( %params );
975
976   my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
977   my $total = total_amount($invoice);
978
979   my $title = 'default invoice, four items, 19/7% tax with_skonto_pt 4x25';
980
981   is($invoice->netamount,   88.75,    "${title}: netamount");
982   is($invoice->amount,        100,    "${title}: amount");
983   is($paid_amount,           -100,    "${title}: paid amount");
984   is($invoice->paid,          100,    "${title}: paid");
985   is($number_of_payments,       3,    "${title}: 3 AR_paid bookings");
986   { local $TODO = "currently this test fails because the code writing the invoice is buggy, the calculation of skonto is correct";
987   is($total,                    0,    "${title}: even balance");
988   }
989 }
990
991 sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_multiple() {
992   reset_state() if $ALWAYS_RESET;
993
994   my $item1   = new_item(qty => 0.5, part => $parts[2]);
995   my $item2   = new_item(qty => 0.5, part => $parts[3]);
996   my $item3   = new_item(qty => 0.5, part => $parts[2]);
997   my $item4   = new_item(qty => 0.5, part => $parts[3]);
998   my $invoice = new_invoice(
999     taxincluded  => 0,
1000     invoiceitems => [ $item1, $item2, $item3, $item4 ],
1001     payment_id  => $payment_terms->id,
1002   );
1003   $invoice->post;
1004
1005   $invoice->pay_invoice( amount       => '90',
1006                          payment_type => 'without_skonto',
1007                          chart_id     => $bank_account->chart_id,
1008                          transdate => DateTime->today_local->to_kivitendo
1009                        );
1010   $invoice->pay_invoice( payment_type => 'difference_as_skonto',
1011                          chart_id     => $bank_account->chart_id,
1012                          transdate    => DateTime->today_local->to_kivitendo
1013                        );
1014
1015   my ($number_of_payments, $paid_amount) = number_of_payments($invoice);
1016   my $total = total_amount($invoice);
1017
1018   my $title = 'default invoice, four items, 19/7% tax with_skonto_pt 4x25';
1019
1020   is($invoice->netamount,  100,     "${title}: netamount");
1021   is($invoice->amount,     113,     "${title}: amount");
1022   is($paid_amount,        -113,     "${title}: paid amount");
1023   is($invoice->paid,       113,     "${title}: paid");
1024   is($number_of_payments,    3,     "${title}: 3 AR_paid bookings");
1025   is($total,                 0,     "${title}: even balance: this will fail due to rounding error in invoice post, not the skonto");
1026 }
1027
1028 sub test_ar_currency_tax_not_included_and_payment {
1029   my $netamount = $::form->round_amount(75 * $exchangerate->sell,2); #  75 in CUR, 100.00 in EUR
1030   my $amount    = $::form->round_amount($netamount * 1.19,2);        # 100 in CUR, 119.00 in EUR
1031   my $invoice   = SL::DB::Invoice->new(
1032       invoice      => 0,
1033       amount       => $amount,
1034       netamount    => $netamount,
1035       transdate    => $transdate,
1036       taxincluded  => 0,
1037       customer_id  => $customer->id,
1038       taxzone_id   => $customer->taxzone_id,
1039       currency_id  => $currency->id,
1040       transactions => [],
1041       notes        => 'test_ar_currency_tax_not_included_and_payment',
1042   );
1043   $invoice->add_ar_amount_row(
1044     amount     => $invoice->netamount,
1045     chart      => $ar_amount_chart,
1046     tax_id     => $tax->id,
1047   );
1048
1049   $invoice->create_ar_row(chart => $ar_chart);
1050   $invoice->save;
1051
1052   is(SL::DB::Manager::Invoice->get_all_count(where => [ invoice => 0 ]), 1, 'there is one ar transaction');
1053   is($invoice->currency_id , $currency->id , 'currency_id has been saved');
1054   is($invoice->netamount   , 100           , 'ar amount has been converted');
1055   is($invoice->amount      , 119           , 'ar amount has been converted');
1056   is($invoice->taxincluded ,   0           , 'ar transaction doesn\'t have 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
1060   $invoice->pay_invoice(chart_id   => $bank->id,
1061                         amount     => 50,
1062                         currency   => 'CUR',
1063                         transdate  => $transdate->to_kivitendo,
1064                        );
1065   $invoice->pay_invoice(chart_id   => $bank->id,
1066                         amount     => 39.25,
1067                         currency   => 'CUR',
1068                         transdate  => $transdate->to_kivitendo,
1069                        );
1070   # $invoice->pay_invoice(chart_id   => $bank->id,
1071   #                       amount     => 30,
1072   #                       transdate  => $transdate2->to_kivitendo,
1073   #                      );
1074   is(scalar @{$invoice->transactions}, 9, 'ar transaction has 9 transactions (incl. fxtransactions)');
1075   is($invoice->paid, $invoice->amount, 'ar transaction paid = amount in default currency');
1076 };
1077
1078 sub test_ar_currency_tax_included {
1079   # we want the acc_trans amount to be 100
1080   my $amount    = $::form->round_amount(75 * $exchangerate->sell * 1.19);
1081   my $netamount = $::form->round_amount($amount / 1.19,2);
1082   my $invoice = SL::DB::Invoice->new(
1083       invoice      => 0,
1084       amount       => 119, #$amount,
1085       netamount    => 100, #$netamount,
1086       transdate    => $transdate,
1087       taxincluded  => 1,
1088       customer_id  => $customer->id,
1089       taxzone_id   => $customer->taxzone_id,
1090       currency_id  => $currency->id,
1091       notes        => 'test_ar_currency_tax_included',
1092       transactions => [],
1093   );
1094   $invoice->add_ar_amount_row( # should take care of taxincluded
1095     amount     => $invoice->amount, # tax included in local currency
1096     chart      => $ar_amount_chart,
1097     tax_id     => $tax->id,
1098   );
1099
1100   $invoice->create_ar_row( chart => $ar_chart );
1101   $invoice->save;
1102   is(SL::DB::Manager::Invoice->get_all_count(where => [ invoice => 0 ]), 2, 'there are now two ar transactions');
1103   is($invoice->currency_id , $currency->id , 'currency_id has been saved');
1104   is($invoice->amount      , $amount       , 'amount ok');
1105   is($invoice->netamount   , $netamount    , 'netamount ok');
1106   is($invoice->taxincluded , 1             , 'ar transaction has taxincluded');
1107   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');
1108   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');
1109   $invoice->pay_invoice(chart_id   => $bank->id,
1110                         amount     => 89.25,
1111                         currency   => 'CUR',
1112                         transdate  => $transdate->to_kivitendo,
1113                        );
1114
1115 };
1116
1117 sub test_ap_currency_tax_not_included_and_payment {
1118   my $netamount = $::form->round_amount(75 * $exchangerate->sell,2); #  75 in CUR, 100.00 in EUR
1119   my $amount    = $::form->round_amount($netamount * 1.19,2);        # 100 in CUR, 119.00 in EUR
1120   my $invoice   = SL::DB::PurchaseInvoice->new(
1121       invoice      => 0,
1122       invnumber    => 'test_ap_currency_tax_not_included_and_payment',
1123       amount       => $amount,
1124       netamount    => $netamount,
1125       transdate    => $transdate,
1126       taxincluded  => 0,
1127       vendor_id    => $vendor->id,
1128       taxzone_id   => $vendor->taxzone_id,
1129       currency_id  => $currency->id,
1130       transactions => [],
1131       notes        => 'test_ap_currency_tax_not_included_and_payment',
1132   );
1133   $invoice->add_ap_amount_row(
1134     amount     => $invoice->netamount,
1135     chart      => $ap_amount_chart,
1136     tax_id     => $tax_9->id,
1137   );
1138
1139   $invoice->create_ap_row(chart => $ap_chart);
1140   $invoice->save;
1141
1142   is($invoice->currency_id, $currency->id, 'currency_id has been saved');
1143   is($invoice->netamount, 100, 'ap amount has been converted');
1144   is($invoice->amount, 119, 'ap amount has been converted');
1145   is($invoice->taxincluded, 0, 'ap transaction doesn\'t have 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');
1148
1149   $invoice->pay_invoice(chart_id   => $bank->id,
1150                         amount     => 50,
1151                         currency   => 'CUR',
1152                         transdate  => $transdate->to_kivitendo,
1153                        );
1154   $invoice->pay_invoice(chart_id   => $bank->id,
1155                         amount     => 39.25,
1156                         currency   => 'CUR',
1157                         transdate  => $transdate->to_kivitendo,
1158                        );
1159   # $invoice->pay_invoice(chart_id   => $bank->id,
1160   #                       amount     => 30,
1161   #                       transdate  => $transdate2->to_kivitendo,
1162   #                      );
1163   is(scalar @{$invoice->transactions}, 9, 'ap transaction has 9 transactions (incl. fxtransactions)');
1164   is($invoice->paid, $invoice->amount, 'ap transaction paid = amount in default currency');
1165 };
1166
1167 sub test_ap_currency_tax_included {
1168   # we want the acc_trans amount to be 100
1169   my $amount    = $::form->round_amount(75 * $exchangerate->sell * 1.19);
1170   my $netamount = $::form->round_amount($amount / 1.19,2);
1171   my $invoice = SL::DB::PurchaseInvoice->new(
1172       invoice      => 0,
1173       amount       => 119, #$amount,
1174       netamount    => 100, #$netamount,
1175       transdate    => $transdate,
1176       taxincluded  => 1,
1177       vendor_id    => $vendor->id,
1178       taxzone_id   => $vendor->taxzone_id,
1179       currency_id  => $currency->id,
1180       notes        => 'test_ap_currency_tax_included',
1181       invnumber    => 'test_ap_currency_tax_included',
1182       transactions => [],
1183   );
1184   $invoice->add_ap_amount_row( # should take care of taxincluded
1185     amount     => $invoice->amount, # tax included in local currency
1186     chart      => $ap_amount_chart,
1187     tax_id     => $tax_9->id,
1188   );
1189
1190   $invoice->create_ap_row( chart => $ap_chart );
1191   $invoice->save;
1192   is($invoice->currency_id , $currency->id , 'currency_id has been saved');
1193   is($invoice->amount      , $amount       , 'amount ok');
1194   is($invoice->netamount   , $netamount    , 'netamount ok');
1195   is($invoice->taxincluded , 1             , 'ap transaction has taxincluded');
1196   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');
1197   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');
1198
1199   $invoice->pay_invoice(chart_id   => $bank->id,
1200                         amount     => 89.25,
1201                         currency   => 'CUR',
1202                         transdate  => $transdate->to_kivitendo,
1203                        );
1204
1205 };
1206
1207 Support::TestSetup::login();
1208  # die;
1209
1210 # test cases: without_skonto
1211  test_default_invoice_one_item_19_without_skonto();
1212  test_default_invoice_two_items_19_7_tax_with_skonto();
1213  test_default_invoice_two_items_19_7_without_skonto();
1214  test_default_invoice_two_items_19_7_without_skonto_incomplete_payment();
1215  test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments();
1216  test_default_purchase_invoice_two_charts_19_7_without_skonto();
1217  test_default_purchase_invoice_two_charts_19_7_tax_partial_unrounded_payment_without_skonto();
1218  test_default_invoice_one_item_19_without_skonto_overpaid();
1219
1220 # test cases: difference_as_skonto
1221  test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto();
1222  test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto_1cent();
1223  test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto_2cent();
1224  test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto();
1225  test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto_1cent();
1226  test_default_purchase_invoice_two_charts_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto();
1227
1228 # test cases: with_skonto_pt
1229  test_default_invoice_two_items_19_7_tax_with_skonto_50_50();
1230  test_default_invoice_four_items_19_7_tax_with_skonto_4x_25();
1231  test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_multiple();
1232  test_default_purchase_invoice_two_charts_19_7_with_skonto();
1233  test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_tax_included();
1234  test_default_invoice_two_items_19_7_tax_with_skonto_tax_included();
1235
1236 # test payment of ar and ap transactions with currency and tax included/not included
1237  test_ar_currency_tax_not_included_and_payment();
1238  test_ar_currency_tax_included();
1239  test_ap_currency_tax_not_included_and_payment();
1240  test_ap_currency_tax_included();
1241
1242 # remove all created data at end of test
1243 clear_up();
1244
1245 done_testing();
1246
1247 1;