X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=t%2Fdb_helper%2Fpayment.t;h=154e48c290258079f4d5f61ff34bd46780fb5f8b;hb=b293ff8ad52fc76ba0c44783e3982418114d6b08;hp=9eb2d9d77270c7ba1e04799f06703ca80ba5aeda;hpb=98b64fe1e380c232428d63cea0eb5f44b1d1a2c3;p=kivitendo-erp.git diff --git a/t/db_helper/payment.t b/t/db_helper/payment.t index 9eb2d9d77..154e48c29 100644 --- a/t/db_helper/payment.t +++ b/t/db_helper/payment.t @@ -1,4 +1,5 @@ -use Test::More; +use strict; +use Test::More tests => 197; use strict; @@ -10,6 +11,11 @@ use Support::TestSetup; use Test::Exception; use List::Util qw(sum); +use SL::Dev::Record qw(create_invoice_item create_sales_invoice create_credit_note create_ap_transaction); +use SL::Dev::CustomerVendor qw(new_customer new_vendor); +use SL::Dev::Part qw(new_part); +use SL::DB::BankTransaction; +use SL::DB::BankTransactionAccTrans; use SL::DB::Buchungsgruppe; use SL::DB::Currency; use SL::DB::Exchangerate; @@ -25,15 +31,69 @@ use SL::DB::PaymentTerm; use SL::DBUtils qw(selectfirst_array_query); use Data::Dumper; -my ($customer, $vendor, $currency_id, @parts, $buchungsgruppe, $buchungsgruppe7, $unit, $employee, $tax, $tax7, $tax_9, $taxzone, $payment_terms, $bank_account); +my ($customer, $vendor, $currency_id, @parts, $buchungsgruppe, $buchungsgruppe7, $unit, $employee, $tax, $tax7, $tax_9, $taxzone, $payment_terms, + $bank_account, $bt); my ($transdate1, $transdate2, $transdate3, $transdate4, $currency, $exchangerate, $exchangerate2, $exchangerate3, $exchangerate4); my ($ar_chart,$bank,$ar_amount_chart, $ap_chart, $ap_amount_chart, $fxloss_chart, $fxgain_chart); -my $ALWAYS_RESET = 1; +my $ap_transaction_counter = 0; # used for generating purchase invnumber + +Support::TestSetup::login(); + +init_state(); + +# test cases: without_skonto +test_default_invoice_one_item_19_without_skonto(); +test_default_invoice_two_items_19_7_tax_with_skonto(); +test_default_invoice_two_items_19_7_without_skonto(); +test_default_invoice_two_items_19_7_without_skonto_incomplete_payment(); +test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments(); +test_default_ap_transaction_two_charts_19_7_without_skonto(); +test_default_ap_transaction_two_charts_19_7_tax_partial_unrounded_payment_without_skonto(); +test_default_invoice_one_item_19_without_skonto_overpaid(); +test_credit_note_two_items_19_7_tax_tax_not_included(); + +# test cases: free_skonto +test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_free_skonto(); +test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_free_skonto_1cent(); +test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_free_skonto_2cent(); +test_default_invoice_one_item_19_multiple_payment_final_free_skonto(); +test_default_invoice_one_item_19_multiple_payment_final_free_skonto_1cent(); +test_default_ap_transaction_two_charts_19_7_tax_without_skonto_multiple_payments_final_free_skonto(); + +# test cases: with_skonto_pt +test_default_invoice_two_items_19_7_tax_with_skonto_50_50(); +test_default_invoice_four_items_19_7_tax_with_skonto_4x_25(); +test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_multiple(); +test_default_ap_transaction_two_charts_19_7_with_skonto(); +test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_tax_included(); +test_default_invoice_two_items_19_7_tax_with_skonto_tax_included(); + +# test payment of ar and ap transactions with currency and tax included/not included +# exchangerate = 1.33333 +test_ar_currency_tax_not_included_and_payment(); +test_ar_currency_tax_included(); +test_ap_currency_tax_not_included_and_payment(); +test_ap_currency_tax_included(); + +test_ar_currency_tax_not_included_and_payment_2(); # exchangerate 0.8 +test_ar_currency_tax_not_included_and_payment_2_credit_note(); # exchangerate 0.8 + +test_ap_currency_tax_not_included_and_payment_2(); # two exchangerates, with fx_gain_loss +test_ap_currency_tax_not_included_and_payment_2_credit_note(); # two exchangerates, with fx_gain_loss -my $reset_state_counter = 0; +is(SL::DB::Manager::Invoice->get_all_count(), 21, "number of invoices at end of tests ok"); +TODO: { + local $TODO = "currently this test fails because the code writing the invoice is buggy, the calculation of skonto is correct"; + my ($acc_trans_sum) = selectfirst_array_query($::form, $currency->db->dbh, 'SELECT SUM(amount) FROM acc_trans'); + is($acc_trans_sum, '0.00000', "sum of all acc_trans at end of all tests is 0"); +} + +# remove all created data at end of test +clear_up(); + +done_testing(); -my $purchase_invoice_counter = 0; # used for generating purchase invnumber sub clear_up { SL::DB::Manager::InvoiceItem->delete_all(all => 1); @@ -42,35 +102,34 @@ sub clear_up { SL::DB::Manager::Part->delete_all(all => 1); SL::DB::Manager::Customer->delete_all(all => 1); SL::DB::Manager::Vendor->delete_all(all => 1); + SL::DB::Manager::BankTransactionAccTrans->delete_all(all => 1); + SL::DB::Manager::BankTransaction->delete_all(all => 1); SL::DB::Manager::BankAccount->delete_all(all => 1); SL::DB::Manager::PaymentTerm->delete_all(all => 1); SL::DB::Manager::Exchangerate->delete_all(all => 1); SL::DB::Manager::Currency->delete_all(where => [ name => 'CUR' ]); }; -sub reset_state { +sub init_state { my %params = @_; - return if $reset_state_counter; - - $params{$_} ||= {} for qw(buchungsgruppe unit customer part tax vendor); - clear_up(); - $transdate1 = DateTime->today; - $transdate2 = DateTime->today->add(days => 1); - $transdate3 = DateTime->today->add(days => 2); - $transdate4 = DateTime->today->add(days => 3); - - $buchungsgruppe = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 19%', %{ $params{buchungsgruppe} }) || croak "No accounting group"; - $buchungsgruppe7 = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 7%') || croak "No accounting group for 7\%"; - $unit = SL::DB::Manager::Unit->find_by(name => 'kg', %{ $params{unit} }) || croak "No unit"; - $employee = SL::DB::Manager::Employee->current || croak "No employee"; - $tax = SL::DB::Manager::Tax->find_by(taxkey => 3, rate => 0.19, %{ $params{tax} }) || croak "No tax"; - $tax7 = SL::DB::Manager::Tax->find_by(taxkey => 2, rate => 0.07) || croak "No tax for 7\%"; - $taxzone = SL::DB::Manager::TaxZone->find_by( description => 'Inland') || croak "No taxzone"; - $tax_9 = SL::DB::Manager::Tax->find_by(taxkey => 9, rate => 0.19, %{ $params{tax} }) || croak "No tax"; - # $tax7 = SL::DB::Manager::Tax->find_by(taxkey => 2, rate => 0.07) || croak "No tax for 7\%"; + $transdate1 = DateTime->today_local; + $transdate1->set_year(2019) if $transdate1->year == 2020; # hardcode for 2019 in 2020, because of tax rate change in Germany + $transdate2 = $transdate1->clone->add(days => 1); + $transdate3 = $transdate1->clone->add(days => 2); + $transdate4 = $transdate1->clone->add(days => 3); + + $buchungsgruppe = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 19%') || croak "No accounting group"; + $buchungsgruppe7 = SL::DB::Manager::Buchungsgruppe->find_by(description => 'Standard 7%') || croak "No accounting group for 7\%"; + $unit = SL::DB::Manager::Unit->find_by(name => 'kg') || croak "No unit"; + $employee = SL::DB::Manager::Employee->current || croak "No employee"; + $tax = SL::DB::Manager::Tax->find_by(taxkey => 3, rate => 0.19) || croak "No tax"; + $tax7 = SL::DB::Manager::Tax->find_by(taxkey => 2, rate => 0.07) || croak "No tax for 7\%"; + $taxzone = SL::DB::Manager::TaxZone->find_by( description => 'Inland') || croak "No taxzone"; + $tax_9 = SL::DB::Manager::Tax->find_by(taxkey => 9, rate => 0.19) || croak "No tax"; + # $tax7 = SL::DB::Manager::Tax->find_by(taxkey => 2, rate => 0.07) || croak "No tax for 7\%"; $currency_id = $::instance_conf->get_currency_id; @@ -106,11 +165,10 @@ sub reset_state { currency_id => $currency->id, )->save; - $customer = SL::DB::Customer->new( + $customer = new_customer( name => 'Test Customer', currency_id => $currency_id, taxzone_id => $taxzone->id, - %{ $params{customer} } )->save; $bank_account = SL::DB::BankAccount->new( @@ -132,53 +190,48 @@ sub reset_state { auto_calculation => 1, )->save; - $vendor = SL::DB::Vendor->new( + $vendor = new_vendor( name => 'Test Vendor', currency_id => $currency_id, taxzone_id => $taxzone->id, payment_id => $payment_terms->id, - %{ $params{vendor} } )->save; @parts = (); - push @parts, SL::DB::Part->new( + push @parts, new_part( partnumber => 'T4254', description => 'Fourty-two fifty-four', lastcost => 1.93, sellprice => 2.34, - part_type => 'part', buchungsgruppen_id => $buchungsgruppe->id, unit => $unit->name, %{ $params{part1} } )->save; - push @parts, SL::DB::Part->new( + push @parts, new_part( partnumber => 'T0815', description => 'Zero EIGHT fifteeN @ 7%', lastcost => 5.473, sellprice => 9.714, - part_type => 'part', buchungsgruppen_id => $buchungsgruppe7->id, unit => $unit->name, %{ $params{part2} } )->save; - push @parts, SL::DB::Part->new( + push @parts, new_part( partnumber => '19%', description => 'Testware 19%', lastcost => 0, sellprice => 50, - part_type => 'part', buchungsgruppen_id => $buchungsgruppe->id, unit => $unit->name, %{ $params{part3} } )->save; - push @parts, SL::DB::Part->new( + push @parts, new_part( partnumber => '7%', description => 'Testware 7%', lastcost => 0, sellprice => 50, - part_type => 'part', buchungsgruppen_id => $buchungsgruppe7->id, unit => $unit->name, %{ $params{part4} } @@ -190,124 +243,43 @@ sub reset_state { $ar_amount_chart = SL::DB::Manager::Chart->find_by( accno => '8400' ); # Erlöse $ap_amount_chart = SL::DB::Manager::Chart->find_by( accno => '3400' ); # Wareneingang 19% - $reset_state_counter++; -} - -sub new_invoice { - my %params = @_; - - return SL::DB::Invoice->new( - customer_id => $customer->id, - currency_id => $currency_id, - employee_id => $employee->id, - salesman_id => $employee->id, - gldate => $transdate1, - taxzone_id => $taxzone->id, - transdate => $transdate1, - invoice => 1, - type => 'invoice', - %params, + $bt = SL::DB::BankTransaction->new( + local_bank_account_id => $bank_account->id, + transdate => $transdate1, + valutadate => $transdate1, + amount => 27332.32, + purpose => 'dummy', + currency => $currency, ); + $bt->save || die $@; } -sub new_purchase_invoice { - # my %params = @_; - # manually create a Kreditorenbuchung from scratch, ap + acc_trans bookings, as no helper exists yet, like $invoice->post. - # arap-Booking must come last in the acc_trans order - $purchase_invoice_counter++; +sub new_ap_transaction { + $ap_transaction_counter++; - my $purchase_invoice = SL::DB::PurchaseInvoice->new( - vendor_id => $vendor->id, - invnumber => 'newap ' . $purchase_invoice_counter , - currency_id => $currency_id, - employee_id => $employee->id, - gldate => $transdate1, - taxzone_id => $taxzone->id, - transdate => $transdate1, - invoice => 0, - type => 'invoice', + my $ap_transaction = create_ap_transaction( + vendor => $vendor, + invnumber => 'newap ' . $ap_transaction_counter, taxincluded => 0, amount => '226', netamount => '200', - paid => '0', - # %params, - )->save; - - my $expense_chart = SL::DB::Manager::Chart->find_by(accno => '3400'); - my $expense_chart_booking= SL::DB::AccTransaction->new( - trans_id => $purchase_invoice->id, - chart_id => $expense_chart->id, - chart_link => $expense_chart->link, - amount => '-100', - transdate => $transdate1, - source => '', - taxkey => 9, - tax_id => SL::DB::Manager::Tax->find_by(taxkey => 9)->id); - $expense_chart_booking->save; - - my $tax_chart = SL::DB::Manager::Chart->find_by(accno => '1576'); - my $tax_chart_booking= SL::DB::AccTransaction->new( - trans_id => $purchase_invoice->id, - chart_id => $tax_chart->id, - chart_link => $tax_chart->link, - amount => '-19', - transdate => $transdate1, - source => '', - taxkey => 0, - tax_id => SL::DB::Manager::Tax->find_by(taxkey => 9)->id); - $tax_chart_booking->save; - $expense_chart = SL::DB::Manager::Chart->find_by(accno => '3300'); - $expense_chart_booking= SL::DB::AccTransaction->new( - trans_id => $purchase_invoice->id, - chart_id => $expense_chart->id, - chart_link => $expense_chart->link, - amount => '-100', - transdate => $transdate1, - source => '', - taxkey => 8, - tax_id => SL::DB::Manager::Tax->find_by(taxkey => 8)->id); - $expense_chart_booking->save; - - - $tax_chart = SL::DB::Manager::Chart->find_by(accno => '1571'); - $tax_chart_booking= SL::DB::AccTransaction->new( - trans_id => $purchase_invoice->id, - chart_id => $tax_chart->id, - chart_link => $tax_chart->link, - amount => '-7', - transdate => $transdate1, - source => '', - taxkey => 0, - tax_id => SL::DB::Manager::Tax->find_by(taxkey => 8)->id); - $tax_chart_booking->save; - my $arap_chart = SL::DB::Manager::Chart->find_by(accno => '1600'); - my $arap_booking= SL::DB::AccTransaction->new(trans_id => $purchase_invoice->id, - chart_id => $arap_chart->id, - chart_link => $arap_chart->link, - amount => '226', - transdate => $transdate1, - source => '', - taxkey => 0, - tax_id => SL::DB::Manager::Tax->find_by(taxkey => 0)->id); - $arap_booking->save; - - return $purchase_invoice; -} - -sub new_item { - my (%params) = @_; - - my $part = delete($params{part}) || $parts[0]; - - return SL::DB::InvoiceItem->new( - parts_id => $part->id, - lastcost => $part->lastcost, - sellprice => $part->sellprice, - description => $part->description, - unit => $part->unit, - %params, - ); + gldate => $transdate1, + taxzone_id => $taxzone->id, + transdate => $transdate1, + bookings => [ + { + chart => SL::DB::Manager::Chart->find_by(accno => '3400'), + amount => 100, + }, + { + chart => SL::DB::Manager::Chart->find_by(accno => '3300'), + amount => 100, + }, + ], + ); + + return $ap_transaction; } sub number_of_payments { @@ -317,9 +289,9 @@ sub number_of_payments { my $paid_amount; foreach my $transaction ( @{ $invoice->transactions } ) { if ( $transaction->chart_link =~ /(AR_paid|AP_paid)/ ) { - $paid_amount += $transaction->amount ; + $paid_amount += $transaction->amount; $number_of_payments++; - }; + } }; return ($number_of_payments, $paid_amount); }; @@ -335,23 +307,21 @@ sub total_amount { # test 1 -sub test_default_invoice_one_item_19_without_skonto() { - reset_state() if $ALWAYS_RESET; - - my $item = new_item(qty => 2.5); - my $invoice = new_invoice( +sub test_default_invoice_one_item_19_without_skonto { + my $title = 'default invoice, one item, 19% tax, without_skonto'; + my $item = create_invoice_item(part => $parts[0], qty => 2.5); + my $invoice = create_sales_invoice( + transdate => $transdate1, taxincluded => 0, invoiceitems => [ $item ], payment_id => $payment_terms->id, ); - $invoice->post; - - my $purchase_invoice = new_purchase_invoice(); + my $ap_transaction = new_ap_transaction(); # default values my %params = ( chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, ); $params{amount} = '6.96'; @@ -362,8 +332,6 @@ sub test_default_invoice_one_item_19_without_skonto() { my ($number_of_payments, $paid_amount) = number_of_payments($invoice); my $total = total_amount($invoice); - my $title = 'default invoice, one item, 19% tax, without_skonto'; - is($invoice->netamount, 5.85, "${title}: netamount"); is($invoice->amount, 6.96, "${title}: amount"); is($paid_amount, -6.96, "${title}: paid amount"); @@ -373,23 +341,23 @@ sub test_default_invoice_one_item_19_without_skonto() { } -sub test_default_invoice_one_item_19_without_skonto_overpaid() { - reset_state() if $ALWAYS_RESET; +sub test_default_invoice_one_item_19_without_skonto_overpaid { + my $title = 'default invoice, one item, 19% tax, without_skonto'; - my $item = new_item(qty => 2.5); - my $invoice = new_invoice( + my $item = create_invoice_item(part => $parts[0], qty => 2.5); + my $invoice = create_sales_invoice( taxincluded => 0, + transdate => $transdate1, invoiceitems => [ $item ], payment_id => $payment_terms->id, ); - $invoice->post; - my $purchase_invoice = new_purchase_invoice(); + my $ap_transaction = new_ap_transaction(); # default values my %params = ( chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, ); $params{amount} = '16.96'; @@ -402,8 +370,6 @@ sub test_default_invoice_one_item_19_without_skonto_overpaid() { my ($number_of_payments, $paid_amount) = number_of_payments($invoice); my $total = total_amount($invoice); - my $title = 'default invoice, one item, 19% tax, without_skonto'; - is($invoice->netamount, 5.85, "${title}: netamount"); is($invoice->amount, 6.96, "${title}: amount"); is($paid_amount, -6.96, "${title}: paid amount"); @@ -415,21 +381,22 @@ sub test_default_invoice_one_item_19_without_skonto_overpaid() { # test 2 -sub test_default_invoice_two_items_19_7_tax_with_skonto() { - reset_state() if $ALWAYS_RESET; +sub test_default_invoice_two_items_19_7_tax_with_skonto { + my $title = 'default invoice, two items, 19/7% tax with_skonto_pt'; - my $item1 = new_item(qty => 2.5); - my $item2 = new_item(qty => 1.2, part => $parts[1]); - my $invoice = new_invoice( + my $item1 = create_invoice_item(part => $parts[0], qty => 2.5); + my $item2 = create_invoice_item(part => $parts[1], qty => 1.2); + my $invoice = create_sales_invoice( taxincluded => 0, + transdate => $transdate1, invoiceitems => [ $item1, $item2 ], - payment_id => $payment_terms->id, + payment_id => $payment_terms->id, ); - $invoice->post; # default values - my %params = ( chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + my %params = ( chart_id => $bank_account->chart_id, + transdate => $transdate1, + bt_id => $bt->id, ); $params{payment_type} = 'with_skonto_pt'; @@ -440,8 +407,6 @@ sub test_default_invoice_two_items_19_7_tax_with_skonto() { my ($number_of_payments, $paid_amount) = number_of_payments($invoice); my $total = total_amount($invoice); - my $title = 'default invoice, two items, 19/7% tax with_skonto_pt'; - is($invoice->netamount, 5.85 + 11.66, "${title}: netamount"); is($invoice->amount, 6.96 + 12.48, "${title}: amount"); is($paid_amount, -19.44, "${title}: paid amount"); @@ -450,21 +415,22 @@ sub test_default_invoice_two_items_19_7_tax_with_skonto() { is($total, 0, "${title}: even balance"); } -sub test_default_invoice_two_items_19_7_tax_with_skonto_tax_included() { - reset_state() if $ALWAYS_RESET; +sub test_default_invoice_two_items_19_7_tax_with_skonto_tax_included { + my $title = 'default invoice, two items, 19/7% tax with_skonto_pt'; - my $item1 = new_item(qty => 2.5); - my $item2 = new_item(qty => 1.2, part => $parts[1]); - my $invoice = new_invoice( + my $item1 = create_invoice_item(part => $parts[0], qty => 2.5); + my $item2 = create_invoice_item(part => $parts[1], qty => 1.2); + my $invoice = create_sales_invoice( + transdate => $transdate1, taxincluded => 1, invoiceitems => [ $item1, $item2 ], - payment_id => $payment_terms->id, + payment_id => $payment_terms->id, ); - $invoice->post; # default values - my %params = ( chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + my %params = ( chart_id => $bank_account->chart_id, + transdate => $transdate1, + bt_id => $bt->id, ); $params{payment_type} = 'with_skonto_pt'; @@ -475,34 +441,34 @@ sub test_default_invoice_two_items_19_7_tax_with_skonto_tax_included() { my ($number_of_payments, $paid_amount) = number_of_payments($invoice); my $total = total_amount($invoice); - my $title = 'default invoice, two items, 19/7% tax with_skonto_pt'; - is($invoice->netamount, 15.82, "${title}: netamount"); is($invoice->amount, 17.51, "${title}: amount"); is($paid_amount, -17.51, "${title}: paid amount"); is($invoice->paid, 17.51, "${title}: paid"); is($number_of_payments, 3, "${title}: 3 AR_paid bookings"); - { local $TODO = "currently this test fails because the code writing the invoice is buggy, the calculation of skonto is correct"; + +TODO: { + local $TODO = "currently this test fails because the code writing the invoice is buggy, the calculation of skonto is correct"; is($total, 0, "${title}: even balance"); } } # test 3 : two items, without skonto -sub test_default_invoice_two_items_19_7_without_skonto() { - reset_state() if $ALWAYS_RESET; +sub test_default_invoice_two_items_19_7_without_skonto { + my $title = 'default invoice, two items, 19/7% tax without skonto'; - my $item1 = new_item(qty => 2.5); - my $item2 = new_item(qty => 1.2, part => $parts[1]); - my $invoice = new_invoice( + my $item1 = create_invoice_item(part => $parts[0], qty => 2.5); + my $item2 = create_invoice_item(part => $parts[1], qty => 1.2); + my $invoice = create_sales_invoice( + transdate => $transdate1, taxincluded => 0, invoiceitems => [ $item1, $item2 ], - payment_id => $payment_terms->id, + payment_id => $payment_terms->id, ); - $invoice->post; # default values my %params = ( chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, ); $params{amount} = '19.44'; # pass full amount @@ -513,8 +479,6 @@ sub test_default_invoice_two_items_19_7_without_skonto() { my ($number_of_payments, $paid_amount) = number_of_payments($invoice); my $total = total_amount($invoice); - my $title = 'default invoice, two items, 19/7% tax without skonto'; - is($invoice->netamount, 5.85 + 11.66, "${title}: netamount"); is($invoice->amount, 6.96 + 12.48, "${title}: amount"); is($paid_amount, -19.44, "${title}: paid amount"); @@ -524,29 +488,27 @@ sub test_default_invoice_two_items_19_7_without_skonto() { } # test 4 -sub test_default_invoice_two_items_19_7_without_skonto_incomplete_payment() { - reset_state() if $ALWAYS_RESET; +sub test_default_invoice_two_items_19_7_without_skonto_incomplete_payment { + my $title = 'default invoice, two items, 19/7% tax without skonto incomplete payment'; - my $item1 = new_item(qty => 2.5); - my $item2 = new_item(qty => 1.2, part => $parts[1]); - my $invoice = new_invoice( + my $item1 = create_invoice_item(part => $parts[0], qty => 2.5); + my $item2 = create_invoice_item(part => $parts[1], qty => 1.2); + my $invoice = create_sales_invoice( taxincluded => 0, + transdate => $transdate1, invoiceitems => [ $item1, $item2 ], - payment_id => $payment_terms->id, + payment_id => $payment_terms->id, ); - $invoice->post; $invoice->pay_invoice( amount => '9.44', payment_type => 'without_skonto', chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo, + transdate => $transdate1, ); my ($number_of_payments, $paid_amount) = number_of_payments($invoice); my $total = total_amount($invoice); - my $title = 'default invoice, two items, 19/7% tax without skonto incomplete payment'; - is($invoice->netamount, 5.85 + 11.66, "${title}: netamount"); is($invoice->amount, 6.96 + 12.48, "${title}: amount"); is($paid_amount, -9.44, "${title}: paid amount"); @@ -556,33 +518,31 @@ sub test_default_invoice_two_items_19_7_without_skonto_incomplete_payment() { } # test 5 -sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments() { - reset_state() if $ALWAYS_RESET; +sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments { + my $title = 'default invoice, two items, 19/7% tax not included'; - my $item1 = new_item(qty => 2.5); - my $item2 = new_item(qty => 1.2, part => $parts[1]); - my $invoice = new_invoice( + my $item1 = create_invoice_item(part => $parts[0], qty => 2.5); + my $item2 = create_invoice_item(part => $parts[1], qty => 1.2); + my $invoice = create_sales_invoice( + transdate => $transdate1, taxincluded => 0, invoiceitems => [ $item1, $item2 ], - payment_id => $payment_terms->id, + payment_id => $payment_terms->id, ); - $invoice->post; $invoice->pay_invoice( amount => '9.44', payment_type => 'without_skonto', chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, ); $invoice->pay_invoice( amount => '10.00', chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, ); my ($number_of_payments, $paid_amount) = number_of_payments($invoice); my $total = total_amount($invoice); - my $title = 'default invoice, two items, 19/7% tax not included'; - is($invoice->netamount, 5.85 + 11.66, "${title}: netamount"); is($invoice->amount, 6.96 + 12.48, "${title}: amount"); is($paid_amount, -19.44, "${title}: paid amount"); @@ -593,39 +553,43 @@ sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments() { } # test 6 -sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto() { - reset_state() if $ALWAYS_RESET; +sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_free_skonto { + my $title = 'default invoice, two items, 19/7% tax not included'; - my $item1 = new_item(qty => 2.5); - my $item2 = new_item(qty => 1.2, part => $parts[1]); - my $invoice = new_invoice( + my $item1 = create_invoice_item(part => $parts[0], qty => 2.5); + my $item2 = create_invoice_item(part => $parts[1], qty => 1.2); + my $invoice = create_sales_invoice( taxincluded => 0, + transdate => $transdate1, invoiceitems => [ $item1, $item2 ], - payment_id => $payment_terms->id, + payment_id => $payment_terms->id, ); - $invoice->post; $invoice->pay_invoice( amount => '9.44', payment_type => 'without_skonto', chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, ); $invoice->pay_invoice( amount => '8.73', payment_type => 'without_skonto', chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, ); - $invoice->pay_invoice( amount => $invoice->open_amount, - payment_type => 'difference_as_skonto', - chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + # free_skonto does: + # my $open_amount = $payment_type eq 'with_skonto_pt' ? $invoice->amount_less_skonto : $invoice->open_amount; + # $open_amount = abs($open_amount); + # $open_amount -= $free_skonto_amount if ($payment_type eq 'free_skonto'); + + $invoice->pay_invoice( skonto_amount => $invoice->open_amount, + amount => 0, + payment_type => 'free_skonto', + chart_id => $bank_account->chart_id, + transdate => $transdate1, + bt_id => $bt->id, ); my ($number_of_payments, $paid_amount) = number_of_payments($invoice); my $total = total_amount($invoice); - - my $title = 'default invoice, two items, 19/7% tax not included'; - is($invoice->netamount, 5.85 + 11.66, "${title}: netamount"); is($invoice->amount, 6.96 + 12.48, "${title}: amount"); is($paid_amount, -19.44, "${title}: paid amount"); @@ -635,77 +599,77 @@ sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_fin } -sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto_1cent() { - reset_state() if $ALWAYS_RESET; +sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_free_skonto_1cent { + my $title = 'default invoice, two items, 19/7% tax not included'; # if there is only one cent left there can only be one skonto booking, the # error handling should choose the highest amount, which is the 7% account # (11.66) rather than the 19% account (5.85). The actual tax amount is # higher for the 19% case, though (1.11 compared to 0.82) + # + # -> wrong: sub name. two cents are still left. one cent for each tax case. no tax correction - my $item1 = new_item(qty => 2.5); - my $item2 = new_item(qty => 1.2, part => $parts[1]); - my $invoice = new_invoice( + my $item1 = create_invoice_item(part => $parts[0], qty => 2.5); + my $item2 = create_invoice_item(part => $parts[1], qty => 1.2); + my $invoice = create_sales_invoice( taxincluded => 0, + transdate => $transdate1, invoiceitems => [ $item1, $item2 ], - payment_id => $payment_terms->id, + payment_id => $payment_terms->id, ); - $invoice->post; $invoice->pay_invoice( amount => '19.42', payment_type => 'without_skonto', chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, ); - $invoice->pay_invoice( amount => $invoice->open_amount, - payment_type => 'difference_as_skonto', + $invoice->pay_invoice( skonto_amount => $invoice->open_amount, + amount => 0, + payment_type => 'free_skonto', chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, + bt_id => $bt->id, ); - my ($number_of_payments, $paid_amount) = number_of_payments($invoice); my $total = total_amount($invoice); - my $title = 'default invoice, two items, 19/7% tax not included'; - is($invoice->netamount, 5.85 + 11.66, "${title}: netamount"); is($invoice->amount, 6.96 + 12.48, "${title}: amount"); is($paid_amount, -19.44, "${title}: paid amount"); is($invoice->paid, 19.44, "${title}: paid"); - is($number_of_payments, 3, "${title}: 2 AR_paid bookings"); + is($number_of_payments, 3, "${title}: 3 AR_paid bookings"); is($total, 0, "${title}: even balance"); - } -sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto_2cent() { - reset_state() if $ALWAYS_RESET; +sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_free_skonto_2cent { + my $title = 'default invoice, two items, 19/7% tax not included'; # if there are two cents left there will be two skonto bookings, 1 cent each - my $item1 = new_item(qty => 2.5); - my $item2 = new_item(qty => 1.2, part => $parts[1]); - my $invoice = new_invoice( + my $item1 = create_invoice_item(part => $parts[0], qty => 2.5); + my $item2 = create_invoice_item(part => $parts[1], qty => 1.2); + my $invoice = create_sales_invoice( taxincluded => 0, + transdate => $transdate1, invoiceitems => [ $item1, $item2 ], - payment_id => $payment_terms->id, + payment_id => $payment_terms->id, ); - $invoice->post; $invoice->pay_invoice( amount => '19.42', payment_type => 'without_skonto', chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, ); - $invoice->pay_invoice( amount => $invoice->open_amount, - payment_type => 'difference_as_skonto', + $invoice->pay_invoice( skonto_amount => $invoice->open_amount, + amount => 0, + payment_type => 'free_skonto', chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, + bt_id => $bt->id, ); my ($number_of_payments, $paid_amount) = number_of_payments($invoice); my $total = total_amount($invoice); - my $title = 'default invoice, two items, 19/7% tax not included'; - is($invoice->netamount, 5.85 + 11.66, "${title}: netamount"); is($invoice->amount, 6.96 + 12.48, "${title}: amount"); is($paid_amount, -19.44, "${title}: paid amount"); @@ -715,20 +679,21 @@ sub test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_fin } -sub test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto() { - reset_state() if $ALWAYS_RESET; +sub test_default_invoice_one_item_19_multiple_payment_final_free_skonto { + my $title = 'default invoice, one item, 19% tax, without_skonto'; - my $item = new_item(qty => 2.5); - my $invoice = new_invoice( + my $item = create_invoice_item(part => $parts[0], qty => 2.5); + my $invoice = create_sales_invoice( taxincluded => 0, + transdate => $transdate1, invoiceitems => [ $item ], payment_id => $payment_terms->id, ); - $invoice->post; # default values my %params = ( chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, + bt_id => $bt->id, ); $params{amount} = '2.32'; @@ -739,15 +704,14 @@ sub test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto $params{payment_type} = 'without_skonto'; $invoice->pay_invoice( %params ); - $params{amount} = $invoice->open_amount; # set amount, otherwise previous 3.81 is used - $params{payment_type} = 'difference_as_skonto'; + $params{skonto_amount} = $invoice->open_amount; # set amount, otherwise previous 3.81 is used + $params{amount} = 0, + $params{payment_type} = 'free_skonto'; $invoice->pay_invoice( %params ); my ($number_of_payments, $paid_amount) = number_of_payments($invoice); my $total = total_amount($invoice); - my $title = 'default invoice, one item, 19% tax, without_skonto'; - is($invoice->netamount, 5.85, "${title}: netamount"); is($invoice->amount, 6.96, "${title}: amount"); is($paid_amount, -6.96, "${title}: paid amount"); @@ -757,35 +721,35 @@ sub test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto } -sub test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto_1cent() { - reset_state() if $ALWAYS_RESET; +sub test_default_invoice_one_item_19_multiple_payment_final_free_skonto_1cent { + my $title = 'default invoice, one item, 19% tax, without_skonto'; - my $item = new_item(qty => 2.5); - my $invoice = new_invoice( + my $item = create_invoice_item(part => $parts[0], qty => 2.5); + my $invoice = create_sales_invoice( taxincluded => 0, + transdate => $transdate1, invoiceitems => [ $item ], payment_id => $payment_terms->id, ); - $invoice->post; # default values my %params = ( chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, + bt_id => $bt->id, ); $params{amount} = '6.95'; $params{payment_type} = 'without_skonto'; $invoice->pay_invoice( %params ); - $params{amount} = $invoice->open_amount; # set amount, otherwise previous value 6.95 is used - $params{payment_type} = 'difference_as_skonto'; + $params{skonto_amount} = $invoice->open_amount; + $params{amount} = 0, + $params{payment_type} = 'free_skonto'; $invoice->pay_invoice( %params ); my ($number_of_payments, $paid_amount) = number_of_payments($invoice); my $total = total_amount($invoice); - my $title = 'default invoice, one item, 19% tax, without_skonto'; - is($invoice->netamount, 5.85, "${title}: netamount"); is($invoice->amount, 6.96, "${title}: amount"); is($paid_amount, -6.96, "${title}: paid amount"); @@ -796,24 +760,22 @@ sub test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto } # test 3 : two items, without skonto -sub test_default_purchase_invoice_two_charts_19_7_without_skonto() { - reset_state() if $ALWAYS_RESET; +sub test_default_ap_transaction_two_charts_19_7_without_skonto { + my $title = 'default invoice, two items, 19/7% tax without skonto'; - my $purchase_invoice = new_purchase_invoice(); + my $ap_transaction = new_ap_transaction(); my %params = ( chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, ); $params{amount} = '226'; # pass full amount $params{payment_type} = 'without_skonto'; - $purchase_invoice->pay_invoice( %params ); + $ap_transaction->pay_invoice( %params ); - my ($number_of_payments, $paid_amount) = number_of_payments($purchase_invoice); - my $total = total_amount($purchase_invoice); - - my $title = 'default invoice, two items, 19/7% tax without skonto'; + my ($number_of_payments, $paid_amount) = number_of_payments($ap_transaction); + my $total = total_amount($ap_transaction); is($paid_amount, 226, "${title}: paid amount"); is($number_of_payments, 1, "${title}: 1 AP_paid bookings"); @@ -821,24 +783,25 @@ sub test_default_purchase_invoice_two_charts_19_7_without_skonto() { } -sub test_default_purchase_invoice_two_charts_19_7_with_skonto() { - reset_state() if $ALWAYS_RESET; +sub test_default_ap_transaction_two_charts_19_7_with_skonto { + my $title = 'default invoice, two items, 19/7% tax without skonto'; - my $purchase_invoice = new_purchase_invoice(); + my $ap_transaction = new_ap_transaction(); - my %params = ( chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + my %params = ( chart_id => $bank_account->chart_id, + transdate => $transdate1, + bt_id => $bt->id, ); - - # $params{amount} = '226'; # pass full amount + # BankTransaction-Controller __always__ calcs amount: + # my $open_amount = $payment_type eq 'with_skonto_pt' ? $invoice->amount_less_skonto : $invoice->open_amount; + $ap_transaction->payment_terms($ap_transaction->vendor->payment); + $params{amount} = $ap_transaction->amount_less_skonto; # pass calculated skonto amount $params{payment_type} = 'with_skonto_pt'; - $purchase_invoice->pay_invoice( %params ); + $ap_transaction->pay_invoice( %params ); - my ($number_of_payments, $paid_amount) = number_of_payments($purchase_invoice); - my $total = total_amount($purchase_invoice); - - my $title = 'default invoice, two items, 19/7% tax without skonto'; + my ($number_of_payments, $paid_amount) = number_of_payments($ap_transaction); + my $total = total_amount($ap_transaction); is($paid_amount, 226, "${title}: paid amount"); is($number_of_payments, 3, "${title}: 1 AP_paid bookings"); @@ -846,20 +809,19 @@ sub test_default_purchase_invoice_two_charts_19_7_with_skonto() { } -sub test_default_purchase_invoice_two_charts_19_7_tax_partial_unrounded_payment_without_skonto() { +sub test_default_ap_transaction_two_charts_19_7_tax_partial_unrounded_payment_without_skonto { + my $title = 'default ap_transaction, two charts, 19/7% tax multiple payments with final difference as skonto'; + # check whether unrounded amounts passed via $params{amount} are rounded for without_skonto case - reset_state() if $ALWAYS_RESET; - my $purchase_invoice = new_purchase_invoice(); - $purchase_invoice->pay_invoice( - amount => ( $purchase_invoice->amount / 3 * 2), + my $ap_transaction = new_ap_transaction(); + $ap_transaction->pay_invoice( + amount => ( $ap_transaction->amount / 3 * 2), payment_type => 'without_skonto', chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, ); - my ($number_of_payments, $paid_amount) = number_of_payments($purchase_invoice); - my $total = total_amount($purchase_invoice); - - my $title = 'default purchase_invoice, two charts, 19/7% tax multiple payments with final difference as skonto'; + my ($number_of_payments, $paid_amount) = number_of_payments($ap_transaction); + my $total = total_amount($ap_transaction); is($paid_amount, 150.67, "${title}: paid amount"); is($number_of_payments, 1, "${title}: 1 AP_paid bookings"); @@ -867,57 +829,59 @@ sub test_default_purchase_invoice_two_charts_19_7_tax_partial_unrounded_payment_ }; -sub test_default_purchase_invoice_two_charts_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto() { - reset_state() if $ALWAYS_RESET; +sub test_default_ap_transaction_two_charts_19_7_tax_without_skonto_multiple_payments_final_free_skonto { + my $title = 'default ap_transaction, two charts, 19/7% tax multiple payments with final free skonto'; - my $purchase_invoice = new_purchase_invoice(); + my $ap_transaction = new_ap_transaction(); # pay 2/3 and 1/5, leaves 3.83% to be used as Skonto - $purchase_invoice->pay_invoice( - amount => ( $purchase_invoice->amount / 3 * 2), + $ap_transaction->pay_invoice( + amount => ( $ap_transaction->amount / 3 * 2), payment_type => 'without_skonto', chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, ); - $purchase_invoice->pay_invoice( - amount => ( $purchase_invoice->amount / 5 ), + $ap_transaction->pay_invoice( + amount => ( $ap_transaction->amount / 5 ), payment_type => 'without_skonto', chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, ); - $purchase_invoice->pay_invoice( - payment_type => 'difference_as_skonto', + $ap_transaction->pay_invoice( + payment_type => 'free_skonto', + skonto_amount => $ap_transaction->open_amount, + amount => 0, chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, + bt_id => $bt->id, ); - my ($number_of_payments, $paid_amount) = number_of_payments($purchase_invoice); - my $total = total_amount($purchase_invoice); - - my $title = 'default purchase_invoice, two charts, 19/7% tax multiple payments with final difference as skonto'; + my ($number_of_payments, $paid_amount) = number_of_payments($ap_transaction); + my $total = total_amount($ap_transaction); is($paid_amount, 226, "${title}: paid amount"); - is($number_of_payments, 4, "${title}: 1 AP_paid bookings"); + is($number_of_payments, 4, "${title}: 4 AP_paid bookings"); is($total, 0, "${title}: even balance"); } # test -sub test_default_invoice_two_items_19_7_tax_with_skonto_50_50() { - reset_state() if $ALWAYS_RESET; +sub test_default_invoice_two_items_19_7_tax_with_skonto_50_50 { + my $title = 'default invoice, two items, 19/7% tax with_skonto_pt 50/50'; - my $item1 = new_item(qty => 1, part => $parts[2]); - my $item2 = new_item(qty => 1, part => $parts[3]); - my $invoice = new_invoice( + my $item1 = create_invoice_item(part => $parts[2], qty => 1); + my $item2 = create_invoice_item(part => $parts[3], qty => 1); + my $invoice = create_sales_invoice( taxincluded => 0, + transdate => $transdate1, invoiceitems => [ $item1, $item2 ], - payment_id => $payment_terms->id, + payment_id => $payment_terms->id, ); - $invoice->post; # default values my %params = ( chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, + bt_id => $bt->id, ); $params{amount} = $invoice->amount_less_skonto; @@ -928,8 +892,6 @@ sub test_default_invoice_two_items_19_7_tax_with_skonto_50_50() { my ($number_of_payments, $paid_amount) = number_of_payments($invoice); my $total = total_amount($invoice); - my $title = 'default invoice, two items, 19/7% tax with_skonto_pt 50/50'; - is($invoice->netamount, 100, "${title}: netamount"); is($invoice->amount, 113, "${title}: amount"); is($paid_amount, -113, "${title}: paid amount"); @@ -939,23 +901,24 @@ sub test_default_invoice_two_items_19_7_tax_with_skonto_50_50() { } # test -sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25() { - reset_state() if $ALWAYS_RESET; - - my $item1 = new_item(qty => 0.5, part => $parts[2]); - my $item2 = new_item(qty => 0.5, part => $parts[3]); - my $item3 = new_item(qty => 0.5, part => $parts[2]); - my $item4 = new_item(qty => 0.5, part => $parts[3]); - my $invoice = new_invoice( +sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25 { + my $title = 'default invoice, four items, 19/7% tax with_skonto_pt 4x25'; + + my $item1 = create_invoice_item(part => $parts[2], qty => 0.5); + my $item2 = create_invoice_item(part => $parts[3], qty => 0.5); + my $item3 = create_invoice_item(part => $parts[2], qty => 0.5); + my $item4 = create_invoice_item(part => $parts[3], qty => 0.5); + my $invoice = create_sales_invoice( taxincluded => 0, + transdate => $transdate1, invoiceitems => [ $item1, $item2, $item3, $item4 ], - payment_id => $payment_terms->id, + payment_id => $payment_terms->id, ); - $invoice->post; # default values my %params = ( chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, + bt_id => $bt->id, ); $params{amount} = $invoice->amount_less_skonto; @@ -966,8 +929,6 @@ sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25() { my ($number_of_payments, $paid_amount) = number_of_payments($invoice); my $total = total_amount($invoice); - my $title = 'default invoice, four items, 19/7% tax with_skonto_pt 4x25'; - is($invoice->netamount , 100 , "${title}: netamount"); is($invoice->amount , 113 , "${title}: amount"); is($paid_amount , -113 , "${title}: paid amount"); @@ -976,23 +937,24 @@ sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25() { is($total , 0 , "${title}: even balance"); } -sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_tax_included() { - reset_state() if $ALWAYS_RESET; +sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_tax_included { + my $title = 'default invoice, four items, 19/7% tax with_skonto_pt 4x25'; - my $item1 = new_item(qty => 0.5, part => $parts[2]); - my $item2 = new_item(qty => 0.5, part => $parts[3]); - my $item3 = new_item(qty => 0.5, part => $parts[2]); - my $item4 = new_item(qty => 0.5, part => $parts[3]); - my $invoice = new_invoice( + my $item1 = create_invoice_item(part => $parts[2], qty => 0.5); + my $item2 = create_invoice_item(part => $parts[3], qty => 0.5); + my $item3 = create_invoice_item(part => $parts[2], qty => 0.5); + my $item4 = create_invoice_item(part => $parts[3], qty => 0.5); + my $invoice = create_sales_invoice( taxincluded => 1, + transdate => $transdate1, invoiceitems => [ $item1, $item2, $item3, $item4 ], - payment_id => $payment_terms->id, + payment_id => $payment_terms->id, ); - $invoice->post; # default values my %params = ( chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, + bt_id => $bt->id, ); $params{amount} = $invoice->amount_less_skonto; @@ -1003,47 +965,47 @@ sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_tax_included() { my ($number_of_payments, $paid_amount) = number_of_payments($invoice); my $total = total_amount($invoice); - my $title = 'default invoice, four items, 19/7% tax with_skonto_pt 4x25'; - is($invoice->netamount, 88.75, "${title}: netamount"); is($invoice->amount, 100, "${title}: amount"); is($paid_amount, -100, "${title}: paid amount"); is($invoice->paid, 100, "${title}: paid"); is($number_of_payments, 3, "${title}: 3 AR_paid bookings"); - { local $TODO = "currently this test fails because the code writing the invoice is buggy, the calculation of skonto is correct"; +TODO: { + local $TODO = "currently this test fails because the code writing the invoice is buggy, the calculation of skonto is correct"; is($total, 0, "${title}: even balance"); } } -sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_multiple() { - reset_state() if $ALWAYS_RESET; +sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_multiple { + my $title = 'default invoice, four items, 19/7% tax with_skonto_pt 4x25'; - my $item1 = new_item(qty => 0.5, part => $parts[2]); - my $item2 = new_item(qty => 0.5, part => $parts[3]); - my $item3 = new_item(qty => 0.5, part => $parts[2]); - my $item4 = new_item(qty => 0.5, part => $parts[3]); - my $invoice = new_invoice( + my $item1 = create_invoice_item(part => $parts[2], qty => 0.5); + my $item2 = create_invoice_item(part => $parts[3], qty => 0.5); + my $item3 = create_invoice_item(part => $parts[2], qty => 0.5); + my $item4 = create_invoice_item(part => $parts[3], qty => 0.5); + my $invoice = create_sales_invoice( taxincluded => 0, + transdate => $transdate1, invoiceitems => [ $item1, $item2, $item3, $item4 ], - payment_id => $payment_terms->id, + payment_id => $payment_terms->id, ); - $invoice->post; $invoice->pay_invoice( amount => '90', payment_type => 'without_skonto', chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, ); - $invoice->pay_invoice( payment_type => 'difference_as_skonto', + $invoice->pay_invoice( payment_type => 'free_skonto', chart_id => $bank_account->chart_id, - transdate => DateTime->today_local->to_kivitendo + transdate => $transdate1, + bt_id => $bt->id, + skonto_amount => $invoice->open_amount, + amount => 0, ); my ($number_of_payments, $paid_amount) = number_of_payments($invoice); my $total = total_amount($invoice); - my $title = 'default invoice, four items, 19/7% tax with_skonto_pt 4x25'; - is($invoice->netamount, 100, "${title}: netamount"); is($invoice->amount, 113, "${title}: amount"); is($paid_amount, -113, "${title}: paid amount"); @@ -1053,6 +1015,8 @@ sub test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_multiple() { } sub test_ar_currency_tax_not_included_and_payment { + my $title = 'test_ar_currency_tax_not_included_and_payment_2'; + my $netamount = $::form->round_amount(75 * $exchangerate->sell,2); # 75 in CUR, 100.00 in EUR my $amount = $::form->round_amount($netamount * 1.19,2); # 100 in CUR, 119.00 in EUR my $invoice = SL::DB::Invoice->new( @@ -1103,6 +1067,8 @@ sub test_ar_currency_tax_not_included_and_payment { }; sub test_ar_currency_tax_included { + my $title = 'test_ar_currency_tax_included'; + # we want the acc_trans amount to be 100 my $amount = $::form->round_amount(75 * $exchangerate->sell * 1.19); my $netamount = $::form->round_amount($amount / 1.19,2); @@ -1142,6 +1108,8 @@ sub test_ar_currency_tax_included { }; sub test_ap_currency_tax_not_included_and_payment { + my $title = 'test_ap_currency_tax_not_included_and_payment'; + my $netamount = $::form->round_amount(75 * $exchangerate->buy,2); # 75 in CUR, 100.00 in EUR my $amount = $::form->round_amount($netamount * 1.19,2); # 100 in CUR, 119.00 in EUR my $invoice = SL::DB::PurchaseInvoice->new( @@ -1188,6 +1156,8 @@ sub test_ap_currency_tax_not_included_and_payment { }; sub test_ap_currency_tax_included { + my $title = 'test_ap_currency_tax_included'; + # we want the acc_trans amount to be 100 my $amount = $::form->round_amount(75 * $exchangerate->buy * 1.19); my $netamount = $::form->round_amount($amount / 1.19,2); @@ -1229,6 +1199,7 @@ sub test_ap_currency_tax_included { sub test_ar_currency_tax_not_included_and_payment_2 { my $title = 'test_ar_currency_tax_not_included_and_payment_2'; + my $netamount = $::form->round_amount(125 * $exchangerate2->sell,2); # 125.00 in CUR, 100.00 in EUR my $amount = $::form->round_amount($netamount * 1.19,2); # 148.75 in CUR, 119.00 in EUR my $invoice = SL::DB::Invoice->new( @@ -1288,6 +1259,8 @@ sub test_ar_currency_tax_not_included_and_payment_2 { }; sub test_ar_currency_tax_not_included_and_payment_2_credit_note { + my $title = 'test_ar_currency_tax_not_included_and_payment_2_credit_note'; + my $netamount = $::form->round_amount(-125 * $exchangerate2->sell,2); # 125.00 in CUR, 100.00 in EUR my $amount = $::form->round_amount($netamount * 1.19,2); # 148.75 in CUR, 119.00 in EUR my $invoice = SL::DB::Invoice->new( @@ -1339,6 +1312,7 @@ sub test_ar_currency_tax_not_included_and_payment_2_credit_note { sub test_ap_currency_tax_not_included_and_payment_2 { my $title = 'test_ap_currency_tax_not_included_and_payment_2'; + my $netamount = $::form->round_amount(125 * $exchangerate2->sell,2); # 125.00 in CUR, 100.00 in EUR my $amount = $::form->round_amount($netamount * 1.19,2); # 148.75 in CUR, 119.00 in EUR my $invoice = SL::DB::PurchaseInvoice->new( @@ -1403,6 +1377,7 @@ sub test_ap_currency_tax_not_included_and_payment_2 { sub test_ap_currency_tax_not_included_and_payment_2_credit_note { my $title = 'test_ap_currency_tax_not_included_and_payment_2_credit_note'; + my $netamount = $::form->round_amount(-125 * $exchangerate2->sell,2); # 125.00 in CUR, 100.00 in EUR my $amount = $::form->round_amount($netamount * 1.19,2); # 148.75 in CUR, 119.00 in EUR my $invoice = SL::DB::PurchaseInvoice->new( @@ -1463,54 +1438,36 @@ sub test_ap_currency_tax_not_included_and_payment_2_credit_note { is(total_amount($invoice), 0, "$title: even balance"); }; -Support::TestSetup::login(); - -# test cases: without_skonto -test_default_invoice_one_item_19_without_skonto(); -test_default_invoice_two_items_19_7_tax_with_skonto(); -test_default_invoice_two_items_19_7_without_skonto(); -test_default_invoice_two_items_19_7_without_skonto_incomplete_payment(); -test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments(); -test_default_purchase_invoice_two_charts_19_7_without_skonto(); -test_default_purchase_invoice_two_charts_19_7_tax_partial_unrounded_payment_without_skonto(); -test_default_invoice_one_item_19_without_skonto_overpaid(); +sub test_credit_note_two_items_19_7_tax_tax_not_included { + my $title = 'test_credit_note_two_items_19_7_tax_tax_not_included'; -# test cases: difference_as_skonto -test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto(); -test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto_1cent(); -test_default_invoice_two_items_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto_2cent(); -test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto(); -test_default_invoice_one_item_19_multiple_payment_final_difference_as_skonto_1cent(); -test_default_purchase_invoice_two_charts_19_7_tax_without_skonto_multiple_payments_final_difference_as_skonto(); + my $item1 = create_invoice_item(part => $parts[0], qty => 5); + my $item2 = create_invoice_item(part => $parts[1], qty => 3); + my $invoice = create_credit_note( + invnumber => 'cn1', + transdate => $transdate1, + taxincluded => 0, + invoiceitems => [ $item1, $item2 ], + ); -# test cases: with_skonto_pt -test_default_invoice_two_items_19_7_tax_with_skonto_50_50(); -test_default_invoice_four_items_19_7_tax_with_skonto_4x_25(); -test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_multiple(); -test_default_purchase_invoice_two_charts_19_7_with_skonto(); -test_default_invoice_four_items_19_7_tax_with_skonto_4x_25_tax_included(); -test_default_invoice_two_items_19_7_tax_with_skonto_tax_included(); + # default values + my %params = ( chart_id => $bank_account->chart_id, + transdate => $transdate1, + ); -# test payment of ar and ap transactions with currency and tax included/not included -# exchangerate = 1.33333 -test_ar_currency_tax_not_included_and_payment(); -test_ar_currency_tax_included(); -test_ap_currency_tax_not_included_and_payment(); -test_ap_currency_tax_included(); + $params{amount} = $invoice->amount, -test_ar_currency_tax_not_included_and_payment_2(); # exchangerate 0.8 -test_ar_currency_tax_not_included_and_payment_2_credit_note(); # exchangerate 0.8 + $invoice->pay_invoice( %params ); -test_ap_currency_tax_not_included_and_payment_2(); # two exchangerates, with fx_gain_loss -test_ap_currency_tax_not_included_and_payment_2_credit_note(); # two exchangerates, with fx_gain_loss + my ($number_of_payments, $paid_amount) = number_of_payments($invoice); + my $total = total_amount($invoice); -{ local $TODO = "currently this test fails because the code writing the invoice is buggy, the calculation of skonto is correct"; - my ($acc_trans_sum) = selectfirst_array_query($::form, $currency->db->dbh, 'SELECT SUM(amount) FROM acc_trans'); is($acc_trans_sum, '0.00000', "sum of all acc_trans is 0"); + is($invoice->netamount, -40.84, "${title}: netamount"); + is($invoice->amount, -45.10, "${title}: amount"); + is($paid_amount, 45.10, "${title}: paid amount according to acc_trans is positive (Haben)"); + is($invoice->paid, -45.10, "${title}: paid"); + is($number_of_payments, 1, "${title}: 1 AR_paid bookings"); + is($total, 0, "${title}: even balance"); } -# remove all created data at end of test -clear_up(); - -done_testing(); - 1;