Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 40fc9f30

Von Jan Büren vor fast 2 Jahren hinzugefügt

  • ID 40fc9f30ba597e21daab8e4ecc82a34378d780c2
  • Vorgänger 74b68fd8
  • Nachfolger ff087fba

bank_transactions: Neue Wechselkurstestfälle

- negative Debitorenbuchung
- negative Kreditorenbuchung
- Zwei Banktransaktionen (eine wieder rückgängig machen)
- Wechselkursgewinn und Verlusttest
- Prüfung ob Gebühren verbucht werden
- Prüfung ob Fehlermeldung bei Gebühren im Verkauf erscheint

Unterschiede anzeigen:

t/bank/bank_transactions.t
1
use Test::More tests => 297;
1
use Test::More tests => 395;
2 2

  
3 3
use strict;
4 4

  
......
16 16
use SL::DB::Currency;
17 17
use SL::DB::Customer;
18 18
use SL::DB::Default;
19
use SL::DB::Exchangerate;
19 20
use SL::DB::Vendor;
20 21
use SL::DB::Invoice;
21 22
use SL::DB::Unit;
......
31 32
use Data::Dumper;
32 33

  
33 34
my ($customer, $vendor, $currency_id, $unit, $tax, $tax0, $tax7, $tax_9, $payment_terms, $bank_account);
34
my ($currency);
35
my ($currency, $currency_usd, $fxgain_chart, $fxloss_chart);
35 36
my ($ar_chart,$bank,$ar_amount_chart, $ap_chart, $ap_amount_chart);
36 37
my ($ar_transaction, $ap_transaction);
37 38
my ($dt, $dt_5, $dt_10, $year);
......
40 41

  
41 42
  SL::DB::Manager::BankTransactionAccTrans->delete_all(all => 1);
42 43
  SL::DB::Manager::BankTransaction->delete_all(all => 1);
44
  SL::DB::Manager::GLTransaction->delete_all(all => 1);
43 45
  SL::DB::Manager::InvoiceItem->delete_all(all => 1);
44 46
  SL::DB::Manager::InvoiceItem->delete_all(all => 1);
45 47
  SL::DB::Manager::Invoice->delete_all(all => 1);
......
51 53
  SL::DB::Manager::SepaExport->delete_all(all => 1);
52 54
  SL::DB::Manager::BankAccount->delete_all(all => 1);
53 55
  SL::DB::Manager::PaymentTerm->delete_all(all => 1);
56
  SL::DB::Manager::Exchangerate->delete_all(all => 1);
54 57
  SL::DB::Manager::Currency->delete_all(where => [ name => 'CUR' ]);
58
  SL::DB::Manager::Currency->delete_all(where => [ name => 'USD' ]);
55 59
  # SL::DB::Manager::Default->delete_all(all => 1);
56 60
};
57 61

  
......
76 80
clear_up();
77 81
reset_state(); # initialise customers/vendors/bank/currency/...
78 82

  
79
test1();
83
negative_ap_transaction_fx_gain_fees();
84
test_negative_ar_transaction_fx_loss();
85
test_ar_transaction_fx_loss();
86
test_ar_transaction_fx_gain();
87
#test_neg_sales_invoice_fx();
88
negative_ap_transaction_fx_gain_fees_error();
89

  
90
ap_transaction_fx_gain_fees();
91
ap_transaction_fx_gain_fees_two_payments();
92
ap_transaction_fx_loss_fees();
80 93

  
94
test1();
81 95
test_overpayment_with_partialpayment();
82 96
test_overpayment();
83 97
reset_state();
......
97 111
test_full_workflow_ar_multiple_inv_skonto_reconciliate_and_undo();
98 112
reset_state();
99 113
test_sepa_export();
100

  
101 114
reset_state();
102 115
test_bt_rule1();
103 116
reset_state();
......
130 143

  
131 144
  $currency_id     = $::instance_conf->get_currency_id;
132 145

  
146
  $currency_usd    = SL::DB::Currency->new(name => 'USD')->save;
147
  $fxgain_chart = SL::DB::Manager::Chart->find_by(accno => '2660') or die "Can't find fxgain_chart in test";
148
  $fxloss_chart = SL::DB::Manager::Chart->find_by(accno => '2150') or die "Can't find fxloss_chart in test";
149
  $currency_usd->db->dbh->do('UPDATE defaults SET fxgain_accno_id = ' . $fxgain_chart->id);
150
  $currency_usd->db->dbh->do('UPDATE defaults SET fxloss_accno_id = ' . $fxloss_chart->id);
151
  $::instance_conf->reload->data;
152
  is($fxgain_chart->id,  $::instance_conf->get_fxgain_accno_id, "fxgain_chart was updated in defaults");
153
  is($fxloss_chart->id,  $::instance_conf->get_fxloss_accno_id, "fxloss_chart was updated in defaults");
154

  
155

  
156

  
133 157
  $bank_account     =  SL::DB::BankAccount->new(
134 158
    account_number  => '123',
135 159
    bank_code       => '123',
......
720 744
  is($credit_note->amount ,'-844.9' ,"$testname: amount before booking ok");
721 745
  is($credit_note->paid   ,'0'      ,"$testname: paid before booking ok");
722 746
  my $bt            = create_bank_transaction(record        => $credit_note,
723
                                                                amount        => $credit_note->amount,
724
                                                                bank_chart_id => $bank->id,
725
                                                                transdate     => $dt_10,
726
                                                               );
747
                                              amount        => abs($credit_note->amount),
748
                                              bank_chart_id => $bank->id,
749
                                              transdate     => $dt_10,
750
                                             );
727 751
  my ($agreement, $rule_matches) = $bt->get_agreement_with_invoice($credit_note);
728 752
  is($agreement, 14, "points for credit note ok");
729 753
  is($rule_matches, 'remote_account_number(3) exact_amount(4) depositor_matches(2) remote_name(2) payment_within_30_days(1) datebonus14(2) ', "rules_matches for credit note ok");
......
774 798
  is($invoice->amount   , -23.8, "$testname: amount ok");
775 799

  
776 800
  my $bt            = create_bank_transaction(record        => $invoice,
777
                                              amount        => $invoice->amount,
801
                                              amount        => abs($invoice->amount),
778 802
                                              bank_chart_id => $bank->id,
779 803
                                              transdate     => $dt_10,
780 804
                                                               );
......
857 881

  
858 882

  
859 883
  my $bt            = create_bank_transaction(record        => $invoice_two,
860
                                              amount        => $invoice_two->amount + $invoice->amount,
884
                                              amount        => abs($invoice_two->amount + $invoice->amount),
861 885
                                              bank_chart_id => $bank->id,
862 886
                                              transdate     => $dt_10,
863 887
                                                               );
......
1274 1298
  is($bt->invoice_amount     , '113.05000' , "$testname: bt invoice amount was assigned");
1275 1299

  
1276 1300
};
1301
sub ap_transaction_fx_gain_fees {
1302

  
1303
  my $testname     = 'ap_transaction_fx_gain_fees';
1304
  my $usd_amount   = 83300;
1305
  my $fx_rate      = 2;
1306
  my $fx_rate_bank = 1.75;
1307
  my $eur_amount   = $usd_amount * $fx_rate;
1308

  
1309
  my $ap_transaction_fx = create_ap_fx_transaction (invnumber   => 'ap transaction fx amount',
1310
                                                    payment_id  => $payment_terms->id,
1311
                                                    fx_rate     => $fx_rate,
1312
                                                    netamount   => $eur_amount,
1313
                                                    invoice_set => 1,
1314
                                                    buysell     => 'sell',
1315
                                                   );
1316
  # check exchangerate
1317
  is($ap_transaction_fx->currency->name   , 'USD'     , "$testname: USD currency");
1318
  is($ap_transaction_fx->get_exchangerate , '2.00000' , "$testname: fx rate record");
1319
  my $bt = create_bank_transaction(record        => $ap_transaction_fx,
1320
                                   bank_chart_id => $bank->id,
1321
                                   transdate     => $dt,
1322
                                   valutadate    => $dt,
1323
                                   amount        => 145949.93,
1324
                                   exchangerate  => $fx_rate_bank,
1325
                                  ) or die "Couldn't create bank_transaction";
1326
#          'exchangerates' => [
1327
#                               '1.75'
1328
#                             ],
1329
#          'book_fx_bank_fees' => [
1330
#                                   '1'
1331
#                                 ],
1332
# book_fx_bank_fees   => [  map { $::form->{"book_fx_bank_fees_${bank_transaction_id}_${_}"} } @{ $invoice_ids } ],
1333

  
1334
  $::form->{invoice_ids} = {
1335
    $bt->id => [ $ap_transaction_fx->id ]
1336
  };
1337
  $::form->{"book_fx_bank_fees_" . $bt->id . "_" . $ap_transaction_fx->id}  = 1;
1338
  $::form->{"exchangerate_"      . $bt->id . "_" . $ap_transaction_fx->id}  = "1,75"; # will be parsed
1339
  $::form->{"currency_id_"       . $bt->id . "_" . $ap_transaction_fx->id}  = $currency_usd->id;
1340

  
1277 1341

  
1342
  my $ret = save_btcontroller_to_string();
1343
  $ap_transaction_fx->load;
1344
  $bt->load;
1345
  is(scalar @{ SL::DB::Manager::BankTransactionAccTrans->get_all(where => [bank_transaction_id => $bt->id ] )},
1346
       5, "$testname 5 acc_trans entries created");
1347

  
1348
  my $gl_fee_booking = SL::DB::Manager::BankTransactionAccTrans->get_all(where => [bank_transaction_id => $bt->id, '!gl_id' => undef ] );
1349
  is(scalar @{ $gl_fee_booking }, 2, 'Two GL acc_trans bookings');
1350

  
1351
  my $gl = SL::DB::Manager::GLTransaction->get_first(where => [ id => $gl_fee_booking->[0]->gl_id ]);
1352
  is (abs($gl->transactions->[0]->amount), '174.93', 'fee abs amount correct');
1353

  
1354
  my $fx_gain_transactions = SL::DB::Manager::AccTransaction->get_all(where =>
1355
                                [ trans_id => $ap_transaction_fx->id, chart_id => $fxgain_chart->id ],
1356
                                  sort_by => ('acc_trans_id'));
1357

  
1358
  is($fx_gain_transactions->[0]->amount,   '20825.00000', "$testname: fx gain amount ok");
1359

  
1360

  
1361
  is($ap_transaction_fx->paid   , '166600.00000' , "$testname: ap transaction skonto was paid");
1362
  is($bt->invoice_amount        , '-145949.93000'   , "$testname: bt invoice amount was assigned");
1363

  
1364
}
1365
sub ap_transaction_fx_gain_fees_two_payments {
1366

  
1367
  my $testname     = 'ap_transaction_fx_gain_fees_two_payments';
1368
  my $usd_amount   = 11901.19;
1369
  my $fx_rate      = 2;
1370
  my $fx_rate_bank = 1.75;
1371
  my $eur_amount   = $usd_amount * $fx_rate;
1372
  my $ap_transaction_fx = create_ap_fx_transaction (invnumber   => 'ap transaction fx amount',
1373
                                                    payment_id  => $payment_terms->id,
1374
                                                    fx_rate     => $fx_rate,
1375
                                                    netamount   => $eur_amount,
1376
                                                    invoice_set => 0,
1377
                                                    buysell     => 'sell',
1378
                                                   );
1379
  # check exchangerate
1380
  is($ap_transaction_fx->currency->name   , 'USD'     , "$testname: USD currency");
1381
  is($ap_transaction_fx->get_exchangerate , '2.00000' , "$testname: fx rate record");
1382
  is($ap_transaction_fx->amount           , 23802.38  , "$testname: record amount");
1383
  is($ap_transaction_fx->paid             , 0         , "$testname: record amount");
1384
  my $bt = create_bank_transaction(record        => $ap_transaction_fx,
1385
                                   bank_chart_id => $bank->id,
1386
                                   transdate     => $dt,
1387
                                   valutadate    => $dt,
1388
                                   amount        => 18698.25,
1389
                                   exchangerate  => $fx_rate_bank,
1390
                                  ) or die "Couldn't create bank_transaction";
1391

  
1392
  is($bt->amount        , '-18698.25'   , "$testname: bt amount ok");
1393

  
1394
  $::form->{invoice_ids} = {
1395
    $bt->id => [ $ap_transaction_fx->id ]
1396
  };
1397
  $::form->{"book_fx_bank_fees_" . $bt->id . "_" . $ap_transaction_fx->id}  = 1;
1398
  $::form->{"exchangerate_"      . $bt->id . "_" . $ap_transaction_fx->id}  = "1,75"; # will be parsed
1399
  $::form->{"currency_id_"       . $bt->id . "_" . $ap_transaction_fx->id}  = $currency_usd->id;
1400

  
1401

  
1402
  my $ret = save_btcontroller_to_string();
1403
  $ap_transaction_fx->load;
1404
  $bt->load;
1405
  is($ap_transaction_fx->get_exchangerate , '2.00000' , "$testname: fx rate record");
1406
  is(scalar @{ SL::DB::Manager::BankTransactionAccTrans->get_all(where => [bank_transaction_id => $bt->id ] )},
1407
       3, "$testname 3 acc_trans entries created");
1408

  
1409
  my $gl_fee_booking = SL::DB::Manager::BankTransactionAccTrans->get_all(where => [bank_transaction_id => $bt->id, '!gl_id' => undef ] );
1410
  is(scalar @{ $gl_fee_booking }, 0, 'Zero GL acc_trans bookings');
1411

  
1412
  my $fx_gain_transactions = SL::DB::Manager::AccTransaction->get_all(where =>
1413
                                [ trans_id => $ap_transaction_fx->id, chart_id => $fxgain_chart->id ],
1414
                                  sort_by => ('acc_trans_id'));
1415

  
1416
  is($fx_gain_transactions->[0]->amount,   '2671.18000', "$testname: fx gain amount ok");
1417

  
1418
  is($ap_transaction_fx->paid, '21369.43000'    , "$testname: ap transaction fx two payment was paid");
1419
  is($bt->invoice_amount     , '-18698.25000'   , "$testname: bt invoice amount was assigned");
1420

  
1421
  my $bt2 = create_bank_transaction(record        => $ap_transaction_fx,
1422
                                    bank_chart_id => $bank->id,
1423
                                    transdate     => $dt,
1424
                                    valutadate    => $dt,
1425
                                    amount        => 1264.20,
1426
                                    exchangerate  => 0.1,
1427
                                   ) or die "Couldn't create bank_transaction";
1428

  
1429
  is($bt2->amount        , '-1264.2'   , "$testname: bt amount ok");
1430

  
1431
  $::form->{invoice_ids} = {
1432
    $bt2->id => [ $ap_transaction_fx->id ]
1433
  };
1434
  $::form->{"book_fx_bank_fees_" . $bt2->id . "_" . $ap_transaction_fx->id}  = 1;
1435
  $::form->{"exchangerate_"      . $bt2->id . "_" . $ap_transaction_fx->id}  = "0,1"; # will be parsed
1436
  $::form->{"currency_id_"       . $bt2->id . "_" . $ap_transaction_fx->id}  = $currency_usd->id;
1437

  
1438

  
1439
  $ret = save_btcontroller_to_string();
1440

  
1441
  $ap_transaction_fx->load;
1442
  $bt2->load;
1443
  is($ap_transaction_fx->get_exchangerate , '2.00000' , "$testname: fx rate record");
1444
  is($ap_transaction_fx->paid             , $ap_transaction_fx->amount , "$testname: paid equals amount");
1445
  is($ap_transaction_fx->get_exchangerate , '2.00000' , "$testname: fx rate record");
1446
  is(scalar @{ SL::DB::Manager::BankTransactionAccTrans->get_all(where => [bank_transaction_id => $bt2->id ] )},
1447
       5, "$testname 5 acc_trans entries created");
1448

  
1449
  my $gl_fee_booking2 = SL::DB::Manager::BankTransactionAccTrans->get_all(where => [bank_transaction_id => $bt2->id, '!gl_id' => undef ] );
1450
  is(scalar @{ $gl_fee_booking2 }, 2, 'Two GL acc_trans bookings');
1451

  
1452
  my $gl = SL::DB::Manager::GLTransaction->get_first(where => [ id => $gl_fee_booking2->[0]->gl_id ]);
1453
  is (abs($gl->transactions->[0]->amount), 1142.55, 'fee2 abs amount correct');
1454

  
1455
  $fx_gain_transactions = SL::DB::Manager::AccTransaction->get_all(where =>
1456
                                [ trans_id => $ap_transaction_fx->id, chart_id => $fxgain_chart->id ],
1457
                                  sort_by => ('acc_trans_id'));
1458

  
1459
  is($fx_gain_transactions->[0]->amount,   '2671.18000' ,"$testname: fx gain 1 amount ok");
1460
  is($fx_gain_transactions->[1]->amount,   '2311.30000' ,"$testname: fx gain 2 amount ok");
1461

  
1462

  
1463
  is($ap_transaction_fx->paid   , $ap_transaction_fx->amount, "$testname: paid equals amount");
1464
  is($bt2->invoice_amount       , '-1264.20000'             , "$testname: bt invoice amount was assigned");
1465

  
1466
  # unlink bank transaction bt2 and reassign
1467
  $::form->{ids} = [ $bt2->id ];
1468
  my $bt_controller = SL::Controller::BankTransaction->new;
1469
  $bt_controller->action_unlink_bank_transaction('testcase' => 1);
1470

  
1471
  $bt2->load;
1472
  $ap_transaction_fx->load;
1473

  
1474
  # and check the cleared state of bt and the acc_transactions
1475
  is($bt2->cleared, '0' , "$testname: bt undo cleared");
1476
  is($bt2->invoice_amount, '0.00000' , "$testname: bt undo invoice amount");
1477

  
1478
  is(scalar @{ SL::DB::Manager::BankTransactionAccTrans->get_all(where => [bank_transaction_id => $bt2->id ] )},
1479
       0, "$testname 0 acc_trans entries there");
1480

  
1481
  $gl_fee_booking = SL::DB::Manager::BankTransactionAccTrans->get_all(where => [bank_transaction_id => $bt2->id, '!gl_id' => undef ] );
1482
  is(scalar @{ $gl_fee_booking }, 0, 'Zero GL acc_trans bookings');
1483

  
1484
  $fx_gain_transactions = SL::DB::Manager::AccTransaction->get_all(where =>
1485
                                [ trans_id => $ap_transaction_fx->id, chart_id => $fxgain_chart->id ],
1486
                                  sort_by => ('acc_trans_id'));
1487

  
1488
  is($fx_gain_transactions->[0]->amount, '2671.18000' , "$testname: fx gain amount ok");
1489
  is($ap_transaction_fx->paid          , '21369.43000', "$testname: ap transaction fx two payment was paid");
1490

  
1491

  
1492
}
1493

  
1494

  
1495
sub ap_transaction_fx_loss_fees {
1496

  
1497
  my $testname     = 'ap_transaction_fx_loss_fees';
1498
  my $usd_amount   = 166600;
1499
  my $fx_rate      = 1.5;
1500
  my $fx_rate_bank = 3;
1501
  my $eur_amount   = $usd_amount * $fx_rate;
1502
  my $ap_transaction_fx = create_ap_fx_transaction (invnumber   => 'ap transaction fx amount',
1503
                                                    payment_id  => $payment_terms->id,
1504
                                                    fx_rate     => $fx_rate,
1505
                                                    netamount   => $eur_amount,
1506
                                                    invoice_set => 1,
1507
                                                    buysell     => 'sell',
1508
                                                   );
1509
  # check exchangerate
1510
  is($ap_transaction_fx->currency->name   , 'USD'     , "$testname: USD currency");
1511
  is($ap_transaction_fx->get_exchangerate , '1.50000' , "$testname: fx rate record");
1512
  my $bt = create_bank_transaction(record        => $ap_transaction_fx,
1513
                                   bank_chart_id => $bank->id,
1514
                                   transdate     => $dt,
1515
                                   valutadate    => $dt,
1516
                                   amount        => 505797.60,
1517
                                   exchangerate  => $fx_rate_bank,
1518
                                  ) or die "Couldn't create bank_transaction";
1519

  
1520
  $::form->{invoice_ids} = {
1521
    $bt->id => [ $ap_transaction_fx->id ]
1522
  };
1523
  $::form->{"book_fx_bank_fees_" . $bt->id . "_" . $ap_transaction_fx->id}  = 1;
1524
  $::form->{"exchangerate_"      . $bt->id . "_" . $ap_transaction_fx->id}  = "3,00"; # will be parsed
1525
  $::form->{"currency_id_"       . $bt->id . "_" . $ap_transaction_fx->id}  = $currency_usd->id;
1526

  
1527

  
1528
  my $ret = save_btcontroller_to_string();
1529
  $ap_transaction_fx->load;
1530
  $bt->load;
1531
  is(scalar @{ SL::DB::Manager::BankTransactionAccTrans->get_all(where => [bank_transaction_id => $bt->id ] )},
1532
       5, "$testname 2 acc_trans entries created");
1533

  
1534
  my $gl_fee_booking = SL::DB::Manager::BankTransactionAccTrans->get_all(where => [bank_transaction_id => $bt->id, '!gl_id' => undef ] );
1535
  is(scalar @{ $gl_fee_booking }, 2, 'One GL Booking');
1536

  
1537
  my $gl = SL::DB::Manager::GLTransaction->get_first(where => [ id => $gl_fee_booking->[0]->gl_id ]);
1538
  is (abs($gl->transactions->[0]->amount), '5997.6', 'fee abs amount correct');
1539

  
1540
  my $fx_loss_transactions = SL::DB::Manager::AccTransaction->get_all(where =>
1541
                                [ trans_id => $ap_transaction_fx->id, chart_id => $fxloss_chart->id ],
1542
                                  sort_by => ('acc_trans_id'));
1543

  
1544
  is($fx_loss_transactions->[0]->amount,   '-249900.00000', "$testname: fx loss amount ok");
1545

  
1546

  
1547
  is($ap_transaction_fx->paid   , $ap_transaction_fx->amount , "$testname: paid equals amount");
1548
  is($ap_transaction_fx->paid   , '249900.00000'             , "$testname: ap transaction was paid");
1549
  is($bt->invoice_amount        , '-505797.60000'            , "$testname: bt invoice amount was assigned");
1550

  
1551
}
1552
sub negative_ap_transaction_fx_gain_fees_error {
1553

  
1554
  my $testname     = 'negative_ap_transaction_fx_gain_fees';
1555
  my $usd_amount   = -890.90;
1556
  my $fx_rate      = 0.545;
1557
  my $fx_rate_bank = 0.499;
1558
  my $eur_amount   = $usd_amount * $fx_rate;
1559
  my $ap_transaction_fx = create_ap_fx_transaction (invnumber   => 'ap transaction fx amount',
1560
                                                    payment_id  => $payment_terms->id,
1561
                                                    fx_rate     => $fx_rate,
1562
                                                    netamount   => $eur_amount,
1563
                                                    invoice_set => 0,
1564
                                                    buysell     => 'sell',
1565
                                                   );
1566
  # check exchangerate
1567
  is($ap_transaction_fx->currency->name   , 'USD'       , "$testname: USD currency");
1568
  is($ap_transaction_fx->get_exchangerate , '0.54500'   , "$testname: fx rate record");
1569
  is($ap_transaction_fx->amount           , $eur_amount , "$testname: negative record amount");
1570
  is($ap_transaction_fx->invoice_type     , "purchase_credit_note" , "$testname: negative record amount");
1571

  
1572
  my $bt = create_bank_transaction(record        => $ap_transaction_fx,
1573
                                   bank_chart_id => $bank->id,
1574
                                   transdate     => $dt,
1575
                                   valutadate    => $dt,
1576
                                   amount        => 4440,
1577
                                   exchangerate  => $fx_rate_bank,
1578
                                  ) or die "Couldn't create bank_transaction";
1579

  
1580
  is($bt->amount           , '4440' , "$testname: positive bt amount");
1581
  $::form->{invoice_ids} = {
1582
    $bt->id => [ $ap_transaction_fx->id ]
1583
  };
1584
  $::form->{"book_fx_bank_fees_" . $bt->id . "_" . $ap_transaction_fx->id}  = 1;
1585
  $::form->{"exchangerate_"      . $bt->id . "_" . $ap_transaction_fx->id}  = "0,499"; # will be parsed
1586
  $::form->{"currency_id_"       . $bt->id . "_" . $ap_transaction_fx->id}  = $currency_usd->id;
1587

  
1588

  
1589
  save_btcontroller_to_string();
1590
  my @bt_errors = @{ $bt_controller->problems };
1591
  is(substr($bt_errors[0]->{message},0,69), 'Bank Fees can only be added for AP transactions or Sales Credit Notes', "$testname: Fehlermeldung ok");
1592
  $bt->load;
1593

  
1594
  is($bt->invoice_amount        , '0.00000'   , "$testname: bt invoice amount is not yet assigned");
1595

  
1596
}
1597
sub negative_ap_transaction_fx_gain_fees {
1598

  
1599
  my $testname     = 'negative_ap_transaction_fx_gain_fees';
1600
  my $usd_amount   = -890.90;
1601
  my $fx_rate      = 0.545;
1602
  my $fx_rate_bank = 0.499;
1603
  my $eur_amount   = $usd_amount * $fx_rate;
1604
  my $ap_transaction_fx = create_ap_fx_transaction (invnumber   => 'ap transaction fx amount',
1605
                                                    payment_id  => $payment_terms->id,
1606
                                                    fx_rate     => $fx_rate,
1607
                                                    netamount   => $eur_amount,
1608
                                                    invoice_set => 0,
1609
                                                    buysell     => 'sell',
1610
                                                   );
1611
  # check exchangerate
1612
  is($ap_transaction_fx->currency->name   , 'USD'       , "$testname: USD currency");
1613
  is($ap_transaction_fx->get_exchangerate , '0.54500'   , "$testname: fx rate record");
1614
  is($ap_transaction_fx->amount           , $eur_amount , "$testname: negative record amount");
1615
  is($ap_transaction_fx->invoice_type     , "purchase_credit_note" , "$testname: negative record amount");
1616

  
1617
  my $bt = create_bank_transaction(record        => $ap_transaction_fx,
1618
                                   bank_chart_id => $bank->id,
1619
                                   transdate     => $dt,
1620
                                   valutadate    => $dt,
1621
                                   amount        => 4440,
1622
                                   exchangerate  => $fx_rate_bank,
1623
                                  ) or die "Couldn't create bank_transaction";
1624

  
1625
  is($bt->amount           , '4440' , "$testname: positive bt amount");
1626
  $::form->{invoice_ids} = {
1627
    $bt->id => [ $ap_transaction_fx->id ]
1628
  };
1629
  $::form->{"exchangerate_"      . $bt->id . "_" . $ap_transaction_fx->id}  = "0,499"; # will be parsed
1630
  $::form->{"currency_id_"       . $bt->id . "_" . $ap_transaction_fx->id}  = $currency_usd->id;
1631

  
1632

  
1633
  save_btcontroller_to_string();
1634

  
1635
  $ap_transaction_fx->load;
1636
  $bt->load;
1637

  
1638
  is(scalar @{ SL::DB::Manager::BankTransactionAccTrans->get_all(where => [bank_transaction_id => $bt->id ] )},
1639
       3, "$testname 5 acc_trans entries created");
1640

  
1641
  my $gl_fee_booking = SL::DB::Manager::BankTransactionAccTrans->get_all(where => [bank_transaction_id => $bt->id, '!gl_id' => undef ] );
1642
  is(scalar @{ $gl_fee_booking }, 0, 'Zero GL acc_trans bookings');
1643

  
1644
  my $fx_loss_transactions = SL::DB::Manager::AccTransaction->get_all(where =>
1645
                                [ trans_id => $ap_transaction_fx->id, chart_id => $fxloss_chart->id ],
1646
                                  sort_by => ('acc_trans_id'));
1647

  
1648
  is($fx_loss_transactions->[0]->amount,   '-40.98000', "$testname: fx loss amount ok");
1649

  
1650

  
1651
  is($ap_transaction_fx->paid   , '-485.54000' , "$testname: ap transaction skonto was paid");
1652
  is($bt->invoice_amount        , '444.56000'  , "$testname: bt invoice amount was assigned");
1653

  
1654
}
1655

  
1656
sub test_neg_sales_invoice_fx {
1657

  
1658
  my $testname = 'test_neg_sales_invoice_fx';
1659

  
1660
  my $part1 = new_part(   partnumber => 'Funkenhaube öhm')->save;
1661
  my $part2 = new_service(partnumber => 'Service-Pauschale Pasch!')->save;
1662

  
1663
  my $ex = SL::DB::Manager::Exchangerate->find_by(currency_id => $currency_usd->id,
1664
                                                  transdate => $dt)
1665
        ||              SL::DB::Exchangerate->new(currency_id => $currency_usd->id,
1666
                                                  transdate   => $dt);
1667
  $ex->update_attributes(buy => 1.772);
1668

  
1669
  my $neg_sales_inv = create_sales_invoice(
1670
    invnumber    => '20222201-USD',
1671
    customer     => $customer,
1672
    taxincluded  => 0,
1673
    currency_id  => $currency_usd->id,
1674
    transdate    => $dt,
1675
    invoiceitems => [ create_invoice_item(part => $part1, qty =>  3, sellprice => 70),
1676
                      create_invoice_item(part => $part2, qty => 10, sellprice => -50),
1677
                    ]
1678
  );
1679
  my $bt            = create_bank_transaction(record        => $neg_sales_inv,
1680
                                              amount        => $neg_sales_inv->amount,
1681
                                              bank_chart_id => $bank->id,
1682
                                              transdate     => $dt,
1683
                                              valutadate    => $dt,
1684
                                              exchangerate  => 2.11,
1685
                                             );
1686

  
1687
  is($neg_sales_inv->amount   , '-611.52000', "$testname: amount ok");
1688
  is($neg_sales_inv->netamount, '-513.88000', "$testname: netamount ok");
1689
  is($neg_sales_inv->currency->name   , 'USD'     , "$testname: USD currency");
1690
  is($neg_sales_inv->get_exchangerate , '1.77200' , "$testname: fx rate record");
1691
  is($bt->exchangerate                , '2.11' , "$testname: bt fx rate record");
1692

  
1693
  $::form->{invoice_ids} = {
1694
    $bt->id => [ $neg_sales_inv->id ]
1695
  };
1696

  
1697
  save_btcontroller_to_string();
1698

  
1699
  $neg_sales_inv->load;
1700
  $bt->load;
1701
  is($neg_sales_inv->paid     , '-611.52000', "$testname: paid ok");
1702
  is($bt->amount              , '-611.52000', "$testname: bt amount ok");
1703
  is($bt->invoice_amount      , '-611.52000', "$testname: bt invoice_amount ok");
1704

  
1705
  my $fx_loss_transactions = SL::DB::Manager::AccTransaction->get_all(where =>
1706
                                [ trans_id => $neg_sales_inv->id, chart_id => $fxloss_chart->id ],
1707
                                  sort_by => ('acc_trans_id'));
1708

  
1709
  is($fx_loss_transactions->[0]->amount,   '-116.64000', "$testname: fx loss amount ok");
1710

  
1711

  
1712

  
1713
}
1714
sub test_negative_ar_transaction_fx_loss {
1715
  my (%params) = @_;
1716
  my $netamount = $::form->round_amount($params{amount}, 2) || 100 * 1.772 * -1;
1717
  my $amount    = $::form->round_amount($netamount * 1.19,2);
1718
  # set exchangerate
1719
  my $ex = SL::DB::Manager::Exchangerate->find_by(currency_id => $currency_usd->id,
1720
                                                  transdate => $dt)
1721
        ||              SL::DB::Exchangerate->new(currency_id => $currency_usd->id,
1722
                                                  transdate   => $dt);
1723
  $ex->update_attributes(buy => 1.772);
1724

  
1725
  my $testname = 'test_negative_ar_transaction_fx_gain';
1726

  
1727
  my $invoice   = SL::DB::Invoice->new(
1728
      invoice      => 0,
1729
      invnumber    => $params{invnumber} || undef, # let it use its own invnumber
1730
      amount       => $amount,
1731
      netamount    => $netamount,
1732
      transdate    => $dt,
1733
      taxincluded  => $params{taxincluded } || 0,
1734
      customer_id  => $customer->id,
1735
      taxzone_id   => $customer->taxzone_id,
1736
      currency_id  => $currency_usd->id,
1737
      transactions => [],
1738
      payment_id   => $params{payment_id} || undef,
1739
      notes        => 'test_ar_transaction',
1740
  );
1741
  $invoice->add_ar_amount_row(
1742
    amount => $invoice->netamount,
1743
    chart  => $ar_amount_chart,
1744
    tax_id => $params{tax_id} || $tax->id,
1745
  );
1746

  
1747
  $invoice->create_ar_row(chart => $ar_chart);
1748
  $invoice->save;
1749

  
1750
  is($invoice->currency_id , $currency_usd->id , 'currency_id has been saved');
1751
  is($invoice->netamount   , '-177.2'          , 'fx ar amount has been converted');
1752
  is($invoice->amount      , '-210.87'         , 'fx ar amount has been converted');
1753
  is($invoice->taxincluded , 0                 , 'fx ar transaction doesn\'t have taxincluded');
1754

  
1755
  my $bt = create_bank_transaction(record        => $invoice,
1756
                                   bank_chart_id => $bank->id,
1757
                                   transdate     => $dt,
1758
                                   valutadate    => $dt,
1759
                                   amount        => (119 + 178.38) * -1,
1760
                                   exchangerate  => 2.499,
1761
                                  ) or die "Couldn't create bank_transaction";
1762

  
1763
  is($bt->amount           , '-297.38' , "$testname: negative bt amount");
1764
  $::form->{invoice_ids} = {
1765
    $bt->id => [ $invoice->id ]
1766
  };
1767
  $::form->{"exchangerate_"      . $bt->id . "_" . $invoice->id}  = "2,499"; # will be parsed
1768
  $::form->{"currency_id_"       . $bt->id . "_" . $invoice->id}  = $currency_usd->id;
1769

  
1770

  
1771
  save_btcontroller_to_string();
1772

  
1773
  $invoice->load;
1774
  $bt->load;
1775

  
1776
  is(scalar @{ SL::DB::Manager::BankTransactionAccTrans->get_all(where => [bank_transaction_id => $bt->id ] )},
1777
       3, "$testname 3 acc_trans entries created");
1778

  
1779
  my $gl_fee_booking = SL::DB::Manager::BankTransactionAccTrans->get_all(where => [bank_transaction_id => $bt->id, '!gl_id' => undef ] );
1780
  is(scalar @{ $gl_fee_booking }, 0, 'Zero GL acc_trans bookings');
1781

  
1782
  my $fx_loss_transactions = SL::DB::Manager::AccTransaction->get_all(where =>
1783
                                [ trans_id => $invoice->id, chart_id => $fxloss_chart->id ],
1784
                                  sort_by => ('acc_trans_id'));
1785

  
1786
  is($fx_loss_transactions->[0]->amount,   '-86.51000', "$testname: fx gain amount ok");
1787

  
1788

  
1789
  is($invoice->paid       , '-210.87000' , "$testname: ar transaction was paid");
1790
  is($bt->invoice_amount  , '-297.38000' , "$testname: bt invoice amount was assigned");
1791
}
1792

  
1793

  
1794

  
1795
sub test_ar_transaction_fx_gain {
1796
  my (%params) = @_;
1797
  my $netamount = $::form->round_amount($params{amount}, 2) || 100 * 1.772;
1798
  my $amount    = $::form->round_amount($netamount * 1.19,2);
1799
  # set exchangerate
1800
  my $ex = SL::DB::Manager::Exchangerate->find_by(currency_id => $currency_usd->id,
1801
                                                  transdate => $dt)
1802
        ||              SL::DB::Exchangerate->new(currency_id => $currency_usd->id,
1803
                                                  transdate   => $dt);
1804
  $ex->update_attributes(buy => 1.772);
1805

  
1806
  my $testname = 'test_ar_transaction';
1807

  
1808
  my $invoice   = SL::DB::Invoice->new(
1809
      invoice      => 0,
1810
      invnumber    => $params{invnumber} || undef, # let it use its own invnumber
1811
      amount       => $amount,
1812
      netamount    => $netamount,
1813
      transdate    => $dt,
1814
      taxincluded  => $params{taxincluded } || 0,
1815
      customer_id  => $customer->id,
1816
      taxzone_id   => $customer->taxzone_id,
1817
      currency_id  => $currency_usd->id,
1818
      transactions => [],
1819
      payment_id   => $params{payment_id} || undef,
1820
      notes        => 'test_ar_transaction',
1821
  );
1822
  $invoice->add_ar_amount_row(
1823
    amount => $invoice->netamount,
1824
    chart  => $ar_amount_chart,
1825
    tax_id => $params{tax_id} || $tax->id,
1826
  );
1827

  
1828
  $invoice->create_ar_row(chart => $ar_chart);
1829
  $invoice->save;
1830

  
1831
  is($invoice->currency_id , $currency_usd->id , 'currency_id has been saved');
1832
  is($invoice->netamount   , '177.2'           , 'fx ar amount has been converted');
1833
  is($invoice->amount      , '210.87'          , 'fx ar amount has been converted');
1834
  is($invoice->taxincluded , 0                 , 'fx ar transaction doesn\'t have taxincluded');
1835

  
1836
  my $bt = create_bank_transaction(record        => $invoice,
1837
                                   bank_chart_id => $bank->id,
1838
                                   transdate     => $dt,
1839
                                   valutadate    => $dt,
1840
                                   amount        => 119 + 178.38,
1841
                                   exchangerate  => 2.499,
1842
                                  ) or die "Couldn't create bank_transaction";
1843

  
1844
  is($bt->amount           , '297.38' , "$testname: positive bt amount");
1845
  $::form->{invoice_ids} = {
1846
    $bt->id => [ $invoice->id ]
1847
  };
1848
  $::form->{"exchangerate_"      . $bt->id . "_" . $invoice->id}  = "2,499"; # will be parsed
1849
  $::form->{"currency_id_"       . $bt->id . "_" . $invoice->id}  = $currency_usd->id;
1850

  
1851

  
1852
  save_btcontroller_to_string();
1853

  
1854
  $invoice->load;
1855
  $bt->load;
1856

  
1857
  is(scalar @{ SL::DB::Manager::BankTransactionAccTrans->get_all(where => [bank_transaction_id => $bt->id ] )},
1858
       3, "$testname 3 acc_trans entries created");
1859

  
1860
  my $gl_fee_booking = SL::DB::Manager::BankTransactionAccTrans->get_all(where => [bank_transaction_id => $bt->id, '!gl_id' => undef ] );
1861
  is(scalar @{ $gl_fee_booking }, 0, 'Zero GL acc_trans bookings');
1862

  
1863
  my $fx_gain_transactions = SL::DB::Manager::AccTransaction->get_all(where =>
1864
                                [ trans_id => $invoice->id, chart_id => $fxgain_chart->id ],
1865
                                  sort_by => ('acc_trans_id'));
1866

  
1867
  is($fx_gain_transactions->[0]->amount,   '86.51000', "$testname: fx gain amount ok");
1868

  
1869

  
1870
  is($invoice->paid       , '210.87000' , "$testname: ar transaction was paid");
1871
  is($bt->invoice_amount  , '297.38000' , "$testname: bt invoice amount was assigned");
1872
}
1873

  
1874
sub test_ar_transaction_fx_loss {
1875
  my (%params) = @_;
1876
  my $netamount = $::form->round_amount($params{amount}, 2) || 100 * 1.772;
1877
  my $amount    = $::form->round_amount($netamount * 1.19,2);
1878
  # set exchangerate
1879
  my $ex = SL::DB::Manager::Exchangerate->find_by(currency_id => $currency_usd->id,
1880
                                                  transdate => $dt)
1881
        ||              SL::DB::Exchangerate->new(currency_id => $currency_usd->id,
1882
                                                  transdate   => $dt);
1883
  $ex->update_attributes(buy => 1.772);
1884

  
1885
  my $testname = 'test_ar_transaction';
1886

  
1887
  my $invoice   = SL::DB::Invoice->new(
1888
      invoice      => 0,
1889
      invnumber    => $params{invnumber} || undef, # let it use its own invnumber
1890
      amount       => $amount,
1891
      netamount    => $netamount,
1892
      transdate    => $dt,
1893
      taxincluded  => $params{taxincluded } || 0,
1894
      customer_id  => $customer->id,
1895
      taxzone_id   => $customer->taxzone_id,
1896
      currency_id  => $currency_usd->id,
1897
      transactions => [],
1898
      payment_id   => $params{payment_id} || undef,
1899
      notes        => 'test_ar_transaction',
1900
  );
1901
  $invoice->add_ar_amount_row(
1902
    amount => $invoice->netamount,
1903
    chart  => $ar_amount_chart,
1904
    tax_id => $params{tax_id} || $tax->id,
1905
  );
1906

  
1907
  $invoice->create_ar_row(chart => $ar_chart);
1908
  $invoice->save;
1909

  
1910
  is($invoice->currency_id , $currency_usd->id , 'currency_id has been saved');
1911
  is($invoice->netamount   , '177.2'           , 'fx ar amount has been converted');
1912
  is($invoice->amount      , '210.87'          , 'fx ar amount has been converted');
1913
  is($invoice->taxincluded , 0                 , 'fx ar transaction doesn\'t have taxincluded');
1914

  
1915
  my $bt = create_bank_transaction(record        => $invoice,
1916
                                   bank_chart_id => $bank->id,
1917
                                   transdate     => $dt,
1918
                                   valutadate    => $dt,
1919
                                   amount        => 210.87,
1920
                                   exchangerate  => 1.499,
1921
                                  ) or die "Couldn't create bank_transaction";
1922

  
1923
  is($bt->amount           , '210.87' , "$testname: positive bt amount");
1924
  $::form->{invoice_ids} = {
1925
    $bt->id => [ $invoice->id ]
1926
  };
1927
  $::form->{"exchangerate_"      . $bt->id . "_" . $invoice->id}  = "1,499"; # will be parsed
1928
  $::form->{"currency_id_"       . $bt->id . "_" . $invoice->id}  = $currency_usd->id;
1929

  
1930

  
1931
  save_btcontroller_to_string();
1932

  
1933
  $invoice->load;
1934
  $bt->load;
1935

  
1936
  is(scalar @{ SL::DB::Manager::BankTransactionAccTrans->get_all(where => [bank_transaction_id => $bt->id ] )},
1937
       3, "$testname 3 acc_trans entries created");
1938

  
1939
  my $gl_fee_booking = SL::DB::Manager::BankTransactionAccTrans->get_all(where => [bank_transaction_id => $bt->id, '!gl_id' => undef ] );
1940
  is(scalar @{ $gl_fee_booking }, 0, 'Zero GL acc_trans bookings');
1941

  
1942
  my $fx_loss_transactions = SL::DB::Manager::AccTransaction->get_all(where =>
1943
                                [ trans_id => $invoice->id, chart_id => $fxloss_chart->id ],
1944
                                  sort_by => ('acc_trans_id'));
1945

  
1946
  is($fx_loss_transactions->[0]->amount,   '-32.49000', "$testname: fx loss amount ok");
1947

  
1948

  
1949
  is($invoice->paid       , '210.87000' , "$testname: ar transaction was paid");
1950
  is($bt->invoice_amount  , '178.38000' , "$testname: bt invoice amount was assigned");
1951
}
1952

  
1953
sub create_ap_fx_transaction {
1954
  my (%params) = @_;
1955

  
1956
  my $netamount     = $params{netamount};
1957
  my $amount        = $params{netamount};
1958
  my $invoice_set   = $params{invoice};
1959
  my $fx_rate       = $params{fx_rate};
1960
  my $buysell       = $params{buysell};
1961

  
1962
  my $ex = SL::DB::Manager::Exchangerate->find_by(currency_id => $currency_usd->id,
1963
                                                  transdate => $dt)
1964
        ||              SL::DB::Exchangerate->new(currency_id => $currency_usd->id,
1965
                                                  transdate   => $dt);
1966
  $ex->update_attributes($buysell => $fx_rate);
1967

  
1968
  my $invoice   = SL::DB::PurchaseInvoice->new(
1969
    invoice      => $invoice_set,
1970
    invnumber    => $params{invnumber} || '27ab',
1971
    amount       => $amount,
1972
    netamount    => $netamount,
1973
    transdate    => $dt,
1974
    taxincluded  => 0,
1975
    vendor_id    => $vendor->id,
1976
    taxzone_id   => $vendor->taxzone_id,
1977
    currency_id  => $currency_usd->id,
1978
    transactions => [],
1979
    notes        => 'ap_transaction_fx',
1980
  );
1981
  $invoice->add_ap_amount_row(
1982
    amount     => $netamount,
1983
    chart      => $ap_amount_chart,
1984
    tax_id     => 0,
1985
  );
1986

  
1987
  $invoice->create_ap_row(chart => $ap_chart);
1988
  $invoice->save;
1989
  return $invoice;
1990
}
1278 1991
1;

Auch abrufbar als: Unified diff