Merge pull request #1 from freiphone/patch-1
[kivitendo-erp.git] / t / bank / bank_transactions.t
index b5e5cad..fd97575 100644 (file)
@@ -1,4 +1,4 @@
-use Test::More;
+use Test::More tests => 105;
 
 use strict;
 
@@ -46,19 +46,38 @@ sub clear_up {
   SL::DB::Manager::Currency->delete_all(where => [ name => 'CUR' ]);
 };
 
+sub save_btcontroller_to_string {
+  my $output;
+  open(my $outputFH, '>', \$output) or die;
+  my $oldFH = select $outputFH;
+
+  my $bt_controller = SL::Controller::BankTransaction->new;
+  $bt_controller->action_save_invoices;
+
+  select $oldFH;
+  close $outputFH;
+  return $output;
+}
 
 # starting test:
 Support::TestSetup::login();
 
+clear_up();
 reset_state(); # initialise customers/vendors/bank/currency/...
 
 test1();
+
 test_overpayment_with_partialpayment();
 test_overpayment();
 test_skonto_exact();
 test_two_invoices();
 test_partial_payment();
 test_credit_note();
+test_ap_transaction();
+test_neg_ap_transaction();
+test_ap_payment_transaction();
+test_ap_payment_part_transaction();
+test_neg_sales_invoice();
 
 # remove all created data at end of test
 clear_up();
@@ -103,6 +122,7 @@ sub reset_state {
     bank                      => 'Geizkasse',
     bank_code                 => 'G1235',
     depositor                 => 'Test Customer',
+    customernumber            => 'CUST1704',
   )->save;
 
   $payment_terms = SL::Dev::Payment::create_payment_terms;
@@ -116,6 +136,7 @@ sub reset_state {
     bank           => 'Geizkasse',
     bank_code      => 'G1235',
     depositor      => 'Test Vendor',
+    vendornumber   => 'VEND1704',
   )->save;
 
   $ar_chart        = SL::DB::Manager::Chart->find_by( accno => '1400' ); # Forderungen
@@ -166,20 +187,22 @@ sub test_ar_transaction {
 
 sub test_ap_transaction {
   my (%params) = @_;
+  my $testname = 'test_ap_transaction';
+
   my $netamount = 100;
   my $amount    = $::form->round_amount($netamount * 1.19,2);
   my $invoice   = SL::DB::PurchaseInvoice->new(
-      invoice      => 0,
-      invnumber    => $params{invnumber} || 'test_ap_transaction',
-      amount       => $amount,
-      netamount    => $netamount,
-      transdate    => $transdate1,
-      taxincluded  => 0,
-      vendor_id    => $vendor->id,
-      taxzone_id   => $vendor->taxzone_id,
-      currency_id  => $currency_id,
-      transactions => [],
-      notes        => 'test_ap_transaction',
+    invoice      => 0,
+    invnumber    => $params{invnumber} || $testname,
+    amount       => $amount,
+    netamount    => $netamount,
+    transdate    => $transdate1,
+    taxincluded  => 0,
+    vendor_id    => $vendor->id,
+    taxzone_id   => $vendor->taxzone_id,
+    currency_id  => $currency_id,
+    transactions => [],
+    notes        => 'test_ap_transaction',
   );
   $invoice->add_ap_amount_row(
     amount     => $invoice->netamount,
@@ -190,10 +213,10 @@ sub test_ap_transaction {
   $invoice->create_ap_row(chart => $ap_chart);
   $invoice->save;
 
-  is($invoice->currency_id , $currency_id , 'currency_id has been saved');
-  is($invoice->netamount   , 100          , 'ap amount has been converted');
-  is($invoice->amount      , 119          , 'ap amount has been converted');
-  is($invoice->taxincluded , 0            , 'ap transaction doesn\'t have taxincluded');
+  is($invoice->currency_id , $currency_id , "$testname: currency_id has been saved");
+  is($invoice->netamount   , 100          , "$testname: ap amount has been converted");
+  is($invoice->amount      , 119          , "$testname: ap amount has been converted");
+  is($invoice->taxincluded , 0            , "$testname: ap transaction doesn\'t have taxincluded");
 
   is(SL::DB::Manager::AccTransaction->find_by(chart_id => $ap_amount_chart->id , trans_id => $invoice->id)->amount , '-100.00000' , $ap_amount_chart->accno . ': has been converted for currency');
   is(SL::DB::Manager::AccTransaction->find_by(chart_id => $ap_chart->id        , trans_id => $invoice->id)->amount , '119.00000'  , $ap_chart->accno . ': has been converted for currency');
@@ -212,11 +235,10 @@ sub test1 {
   my $bt = SL::Dev::Payment::create_bank_transaction(record => $ar_transaction) or die "Couldn't create bank_transaction";
 
   $::form->{invoice_ids} = {
-          $bt->id => [ $ar_transaction->id ]
-        };
+    $bt->id => [ $ar_transaction->id ]
+  };
 
-  my $bt_controller = SL::Controller::BankTransaction->new;
-  $bt_controller->action_save_invoices;
+  save_btcontroller_to_string();
 
   $ar_transaction->load;
   $bt->load;
@@ -240,14 +262,13 @@ sub test_skonto_exact {
                                                     ) or die "Couldn't create bank_transaction";
 
   $::form->{invoice_ids} = {
-          $bt->id => [ $ar_transaction->id ]
-        };
+    $bt->id => [ $ar_transaction->id ]
+  };
   $::form->{invoice_skontos} = {
-          $bt->id => [ 'with_skonto_pt' ]
-        };
+    $bt->id => [ 'with_skonto_pt' ]
+  };
 
-  my $bt_controller = SL::Controller::BankTransaction->new;
-  $bt_controller->action_save_invoices;
+  save_btcontroller_to_string();
 
   $ar_transaction->load;
   $bt->load;
@@ -270,12 +291,14 @@ sub test_two_invoices {
                                                      bank_chart_id => $bank->id,
                                                     ) or die "Couldn't create bank_transaction";
 
+  my ($agreement, $rule_matches) = $bt->get_agreement_with_invoice($ar_transaction_1);
+  is($agreement, 16, "points for ar_transaction_1 in test_two_invoices ok");
+
   $::form->{invoice_ids} = {
-          $bt->id => [ $ar_transaction_1->id, $ar_transaction_2->id ]
-        };
+    $bt->id => [ $ar_transaction_1->id, $ar_transaction_2->id ]
+  };
 
-  my $bt_controller = SL::Controller::BankTransaction->new;
-  $bt_controller->action_save_invoices;
+  save_btcontroller_to_string();
 
   $ar_transaction_1->load;
   $ar_transaction_2->load;
@@ -302,11 +325,10 @@ sub test_overpayment {
                                                     ) or die "Couldn't create bank_transaction";
 
   $::form->{invoice_ids} = {
-          $bt->id => [ $ar_transaction->id ]
-        };
+    $bt->id => [ $ar_transaction->id ]
+  };
 
-  my $bt_controller = SL::Controller::BankTransaction->new;
-  $bt_controller->action_save_invoices;
+  save_btcontroller_to_string();
 
   $ar_transaction->load;
   $bt->load;
@@ -338,16 +360,14 @@ sub test_overpayment_with_partialpayment {
                                                       ) or die "Couldn't create bank_transaction";
 
   $::form->{invoice_ids} = {
-          $bt_1->id => [ $ar_transaction->id ]
-        };
-  my $bt_controller_1 = SL::Controller::BankTransaction->new;
-  $bt_controller_1->action_save_invoices;
+    $bt_1->id => [ $ar_transaction->id ]
+  };
+  save_btcontroller_to_string();
 
   $::form->{invoice_ids} = {
-          $bt_2->id => [ $ar_transaction->id ]
-        };
-  my $bt_controller_2 = SL::Controller::BankTransaction->new;
-  $bt_controller_2->action_save_invoices;
+    $bt_2->id => [ $ar_transaction->id ]
+  };
+  save_btcontroller_to_string();
 
   $ar_transaction->load;
   $bt_1->load;
@@ -372,11 +392,10 @@ sub test_partial_payment {
                                                     ) or die "Couldn't create bank_transaction";
 
   $::form->{invoice_ids} = {
-          $bt->id => [ $ar_transaction->id ]
-        };
+    $bt->id => [ $ar_transaction->id ]
+  };
 
-  my $bt_controller = SL::Controller::BankTransaction->new;
-  $bt_controller->action_save_invoices;
+  save_btcontroller_to_string();
 
   $ar_transaction->load;
   $bt->load;
@@ -410,11 +429,10 @@ sub test_credit_note {
   is($rule_matches, 'remote_account_number(3) exact_amount(4) wrong_sign(-1) depositor_matches(2) remote_name(2) payment_within_30_days(1) datebonus14(2) ', "rules_matches for credit note ok");
 
   $::form->{invoice_ids} = {
-          $bt->id => [ $credit_note->id ]
+    $bt->id => [ $credit_note->id ]
   };
 
-  my $bt_controller = SL::Controller::BankTransaction->new;
-  $bt_controller->action_save_invoices;
+  save_btcontroller_to_string();
 
   $credit_note->load;
   $bt->load;
@@ -423,4 +441,219 @@ sub test_credit_note {
   is($credit_note->paid     , '-844.90000', "$testname: paid ok");
 }
 
+sub test_neg_ap_transaction {
+  my (%params) = @_;
+  my $testname = 'test_neg_ap_transaction';
+  my $netamount = -20;
+  my $amount    = $::form->round_amount($netamount * 1.19,2);
+  my $invoice   = SL::DB::PurchaseInvoice->new(
+    invoice      => 0,
+    invnumber    => $params{invnumber} || 'test_neg_ap_transaction',
+    amount       => $amount,
+    netamount    => $netamount,
+    transdate    => $transdate1,
+    taxincluded  => 0,
+    vendor_id    => $vendor->id,
+    taxzone_id   => $vendor->taxzone_id,
+    currency_id  => $currency_id,
+    transactions => [],
+    notes        => 'test_neg_ap_transaction',
+  );
+  $invoice->add_ap_amount_row(
+    amount     => $invoice->netamount,
+    chart      => $ap_amount_chart,
+    tax_id     => $tax_9->id,
+  );
+
+  $invoice->create_ap_row(chart => $ap_chart);
+  $invoice->save;
+
+  is($invoice->netamount, -20  , "$testname: netamount ok");
+  is($invoice->amount   , -23.8, "$testname: amount ok");
+
+  my $bt            = SL::Dev::Payment::create_bank_transaction(record        => $invoice,
+                                                                amount        => $invoice->amount,
+                                                                bank_chart_id => $bank->id,
+                                                                transdate     => DateTime->today->add(days => 10),
+                                                               );
+  my ($agreement, $rule_matches) = $bt->get_agreement_with_invoice($invoice);
+  is($agreement, 15, "points for negative ap transaction ok");
+
+  $::form->{invoice_ids} = {
+    $bt->id => [ $invoice->id ]
+  };
+
+  save_btcontroller_to_string();
+
+  $invoice->load;
+  $bt->load;
+
+  is($invoice->amount   , '-23.80000', "$testname: amount ok");
+  is($invoice->netamount, '-20.00000', "$testname: netamount ok");
+  is($invoice->paid     , '-23.80000', "$testname: paid ok");
+  is($bt->invoice_amount, '23.80000', "$testname: bt invoice amount for ap was assigned");
+
+  return $invoice;
+};
+
+sub test_ap_payment_transaction {
+  my (%params) = @_;
+  my $testname = 'test_ap_payment_transaction';
+  my $netamount = 115;
+  my $amount    = $::form->round_amount($netamount * 1.19,2);
+  my $invoice   = SL::DB::PurchaseInvoice->new(
+    invoice      => 0,
+    invnumber    => $params{invnumber} || $testname,
+    amount       => $amount,
+    netamount    => $netamount,
+    transdate    => $transdate1,
+    taxincluded  => 0,
+    vendor_id    => $vendor->id,
+    taxzone_id   => $vendor->taxzone_id,
+    currency_id  => $currency_id,
+    transactions => [],
+    notes        => $testname,
+  );
+  $invoice->add_ap_amount_row(
+    amount     => $invoice->netamount,
+    chart      => $ap_amount_chart,
+    tax_id     => $tax_9->id,
+  );
+
+  $invoice->create_ap_row(chart => $ap_chart);
+  $invoice->save;
+
+  is($invoice->netamount, 115  , "$testname: netamount ok");
+  is($invoice->amount   , 136.85, "$testname: amount ok");
+
+  my $bt            = SL::Dev::Payment::create_bank_transaction(record        => $invoice,
+                                                                amount        => $invoice->amount,
+                                                                bank_chart_id => $bank->id,
+                                                                transdate     => DateTime->today->add(days => 10),
+                                                               );
+  $::form->{invoice_ids} = {
+    $bt->id => [ $invoice->id ]
+  };
+
+  save_btcontroller_to_string();
+
+  $invoice->load;
+  $bt->load;
+
+  is($invoice->amount   , '136.85000', "$testname: amount ok");
+  is($invoice->netamount, '115.00000', "$testname: netamount ok");
+  is($bt->amount, '-136.85000', "$testname: bt amount ok");
+  is($invoice->paid     , '136.85000', "$testname: paid ok");
+  is($bt->invoice_amount, '-136.85000', "$testname: bt invoice amount for ap was assigned");
+
+  return $invoice;
+};
+
+sub test_ap_payment_part_transaction {
+  my (%params) = @_;
+  my $testname = 'test_ap_payment_p_transaction';
+  my $netamount = 115;
+  my $amount    = $::form->round_amount($netamount * 1.19,2);
+  my $invoice   = SL::DB::PurchaseInvoice->new(
+    invoice      => 0,
+    invnumber    => $params{invnumber} || $testname,
+    amount       => $amount,
+    netamount    => $netamount,
+    transdate    => $transdate1,
+    taxincluded  => 0,
+    vendor_id    => $vendor->id,
+    taxzone_id   => $vendor->taxzone_id,
+    currency_id  => $currency_id,
+    transactions => [],
+    notes        => $testname,
+  );
+  $invoice->add_ap_amount_row(
+    amount     => $invoice->netamount,
+    chart      => $ap_amount_chart,
+    tax_id     => $tax_9->id,
+  );
+
+  $invoice->create_ap_row(chart => $ap_chart);
+  $invoice->save;
+
+  is($invoice->netamount, 115  , "$testname: netamount ok");
+  is($invoice->amount   , 136.85, "$testname: amount ok");
+
+  my $bt            = SL::Dev::Payment::create_bank_transaction(record        => $invoice,
+                                                                amount        => $invoice->amount-100,
+                                                                bank_chart_id => $bank->id,
+                                                                transdate     => DateTime->today->add(days => 10),
+                                                               );
+  $::form->{invoice_ids} = {
+    $bt->id => [ $invoice->id ]
+  };
+
+  save_btcontroller_to_string();
+
+  $invoice->load;
+  $bt->load;
+
+  is($invoice->amount   , '136.85000', "$testname: amount ok");
+  is($invoice->netamount, '115.00000', "$testname: netamount ok");
+  is($bt->amount,         '-36.85000', "$testname: bt amount ok");
+  is($invoice->paid     ,  '36.85000', "$testname: paid ok");
+  is($bt->invoice_amount, '-36.85000', "$testname: bt invoice amount for ap was assigned");
+
+  my $bt2           = SL::Dev::Payment::create_bank_transaction(record        => $invoice,
+                                                                amount        => 100,
+                                                                bank_chart_id => $bank->id,
+                                                                transdate     => DateTime->today->add(days => 10),
+                                                               );
+  $::form->{invoice_ids} = {
+    $bt2->id => [ $invoice->id ]
+  };
+
+  save_btcontroller_to_string();
+  $invoice->load;
+  $bt2->load;
+
+  is($invoice->amount   , '136.85000', "$testname: amount ok");
+  is($invoice->netamount, '115.00000', "$testname: netamount ok");
+  is($bt2->amount,        '-100.00000',"$testname: bt amount ok");
+  is($invoice->paid     , '136.85000', "$testname: paid ok");
+  is($bt2->invoice_amount,'-100.00000', "$testname: bt invoice amount for ap was assigned");
+
+  return $invoice;
+};
+
+sub test_neg_sales_invoice {
+
+  my $testname = 'test_neg_sales_invoice';
+
+  my $part1 = SL::Dev::Part::create_part(   partnumber => 'Funkenhaube öhm')->save;
+  my $part2 = SL::Dev::Part::create_service(partnumber => 'Service-Pauschale Pasch!')->save;
+
+  my $neg_sales_inv = SL::Dev::Record::create_sales_invoice(
+    invnumber    => '20172201',
+    customer     => $customer,
+    taxincluded  => 0,
+    invoiceitems => [ SL::Dev::Record::create_invoice_item(part => $part1, qty =>  3, sellprice => 70),
+                      SL::Dev::Record::create_invoice_item(part => $part2, qty => 10, sellprice => -50),
+                    ]
+  );
+  my $bt            = SL::Dev::Payment::create_bank_transaction(record        => $neg_sales_inv,
+                                                                amount        => $neg_sales_inv->amount,
+                                                                bank_chart_id => $bank->id,
+                                                                transdate     => DateTime->today,
+                                                               );
+  $::form->{invoice_ids} = {
+    $bt->id => [ $neg_sales_inv->id ]
+  };
+
+  save_btcontroller_to_string();
+
+  $neg_sales_inv->load;
+  $bt->load;
+  is($neg_sales_inv->amount   , '-345.10000', "$testname: amount ok");
+  is($neg_sales_inv->netamount, '-290.00000', "$testname: netamount ok");
+  is($neg_sales_inv->paid     , '-345.10000', "$testname: paid ok");
+  is($bt->amount              , '-345.10000', "$testname: bt amount ok");
+  is($bt->invoice_amount      , '-345.10000', "$testname: bt invoice_amount ok");
+}
+
 1;