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