]> wagnertech.de Git - mfinanz.git/blob - t/fxtransaction/ap_transactions.t
date error in mapping
[mfinanz.git] / t / fxtransaction / ap_transactions.t
1 use strict;
2
3 use lib 't';
4
5 use Test::More;
6
7 use SL::Controller::BankTransaction;
8 use SL::DB::AccTransaction;
9 use SL::DB::BankTransaction;
10 use SL::DB::BankTransactionAccTrans;
11 use SL::DB::Chart;
12 use SL::DB::Currency;
13 use SL::DB::Employee;
14 use SL::DB::Exchangerate;
15 use SL::DB::InvoiceItem;
16 use SL::DB::PurchaseInvoice;
17 use SL::DB::TaxZone;
18 use SL::DB::ValidityToken;
19 use SL::Dev::CustomerVendor qw(:ALL);
20 use SL::Dev::Part qw(:ALL);
21 use SL::Dev::Payment qw(:ALL);
22 use SL::Form;
23 use SL::Helper::Number qw(_format_number);
24 use SL::InstanceConfiguration;
25
26 use HTML::Query;
27 use Support::TestSetup;
28 use Support::Integration;
29
30 my $part;
31 my $vendor;
32 my $usd;
33 my $taxzone;
34 my $fxgain;
35 my $fxloss;
36 my $payment_terms;
37 my $dt;
38
39 sub reset_db {
40   SL::DB::Manager::BankTransactionAccTrans->delete_all(all => 1);
41   SL::DB::Manager::BankTransaction->delete_all(all => 1);
42   SL::DB::Manager::AccTransaction->delete_all(all => 1);
43   SL::DB::Manager::InvoiceItem->delete_all(all => 1);
44   SL::DB::Manager::PurchaseInvoice->delete_all(all => 1);
45   SL::DB::Manager::Exchangerate->delete_all(all => 1);
46   $usd->delete;
47   $vendor->delete;
48   $part->delete;
49   $payment_terms->delete;
50 }
51
52 sub init_db {
53   SL::DB::Manager::Exchangerate->delete_all(all => 1);
54   $vendor = new_vendor->save;
55   $part   = new_part->save;
56   $usd    = SL::DB::Manager::Currency->find_by(name => 'USD') // SL::DB::Currency->new(name => 'USD')->save;
57   $taxzone = SL::DB::Manager::TaxZone->find_by( description => 'Inland');
58   $fxgain = SL::DB::Manager::Chart->find_by(accno => '2660');
59   $fxloss = SL::DB::Manager::Chart->find_by(accno => '2150');
60   $payment_terms = create_payment_terms();
61   $dt    = DateTime->new(year => 1999, month => 1, day => 12);
62
63
64   SL::DB::Default->get->update_attributes(
65     fxgain_accno_id => $fxgain->id,
66     fxloss_accno_id => $fxloss->id,
67   )->load;
68   # reload
69   $::instance_conf = SL::InstanceConfiguration->new;
70
71 }
72
73 ######## main test code #######
74
75 Support::TestSetup::login();
76 Support::Integration::setup();
77 init_db();
78
79 {
80   my $description = "simple purchase invoice";
81   #   vendor 1
82   #   part 1
83   my $currency = 'USD';
84   my $exchangerate = 2.5;
85   my $payment_exchangerate = 1.5;
86
87   my %form;
88
89   # make new invoice
90   my ($out, $err, @ret) = make_request('ir', 'add', type => 'invoice');
91   is $ret[0], 1, "new purchase invoice";
92   %form = form_from_html($out);
93
94   # set invnumber and currency
95   $form{invnumber}    = $description;
96   $form{currency}     = $currency;
97
98   # update
99   ($out, $err, @ret) = make_request('ir', 'update', %form);
100   is $ret[0], 1, "update purchase invoice with currency";
101   %form = form_from_html($out);
102
103   # set part and exchangerate
104   $form{exchangerate} = _format_number($exchangerate, -2);
105   $form{partnumber_1} = $part->partnumber;
106
107   # update
108   ($out, $err, @ret) = make_request('ir', 'update', %form);
109   is $ret[0], 1, "update purchase invoice with part and exchangerate";
110   %form = form_from_html($out);
111
112   # now set par, exchangerate and payments - this will cause the part to be loaded with the lastcost translated into USD
113   $form{paid_1}           = _format_number($part->lastcost / $exchangerate, -2);  # lastcost = 5€ = 2$
114   $form{exchangerate_1}   = _format_number($payment_exchangerate, -2);
115
116   ($out, $err, @ret) = make_request('ir', 'post', %form);
117   is $ret[0], 1, "posting '$description' does not generate error";
118   warn $err if $err;
119   ok $out =~ /ir\.pl\?action=edit&id=(\d+)/, "posting '$description' returns redirect to id";
120   my $id = $1;
121
122   ($out, $err, @ret) = make_request('ir', 'edit', id => $id );
123   is $ret[0], 1, "'$description' did not cause an error";
124   warn $err if $err;
125
126   my $q = HTML::Query->new(text => $out);
127   is $q->query('input[name=paid_1]')->size, 1, "out '$description' contains paid_1";
128   is $q->query('input[name=paid_1]')->first->attr('value'), '2,00', "out '$description' paid_1 is 2,00 (the dollar amount, not the internal 5.00€)";
129
130   is $q->query('#ui-tabs-basic-data tr.invtotal th')->first->as_text, 'Summe', "'$description' - total present";
131   is $q->query('#ui-tabs-basic-data tr.invtotal td')->first->as_text, '2,38', "'$description' - total should be 2.00 * 1.19 = 2.38";
132   is $q->query('#ui-tabs-basic-data input[name=oldtotalpaid]')->first->attr('value'), '2', "'$description' - totalpaid should be 2,00 in dollar, not the internal value";
133 };
134
135 {
136   my $description = "ap transaction from redmine #563";
137   #   20 on 4710 Verpackungsmaterial
138   #   20 payment on 1000 kasse
139   my $currency             = 'USD';
140   my $exchangerate         = 1.1;
141   my $payment_exchangerate = 1.3;
142   my $chart                = SL::DB::Manager::Chart->find_by(accno => '4710');
143   my %form;
144
145   # make new ap transaction
146   my ($out, $err, @ret) = make_request('ap', 'add');
147   is $ret[0], 1, "new ap transaction";
148   %form = form_from_html($out);
149
150   # set chart, amount, currency, invnumber
151   $form{AP_amount_chart_id_1} = $chart->id;
152   $form{amount_1}             = 20;
153   $form{currency}             = 'USD';
154   $form{invnumber} = $description;
155
156   # make new ap transaction
157   ($out, $err, @ret) = make_request('ap', 'update', %form);
158   is $ret[0], 1, "update ap transaction with currency";
159   %form = form_from_html($out);
160
161   # add exchangerate and payments
162   $form{paid_1}                = 20;
163   $form{exchangerate}    = _format_number($exchangerate, -2);
164   $form{exchangerate_1}   = _format_number($payment_exchangerate, -2);
165
166   ($out, $err, @ret) = make_request('ap', 'post', %form);
167   is $ret[0], 1, "posting '$description' did not cause an error";
168
169   my $invoice = SL::DB::Manager::PurchaseInvoice->find_by(invnumber => $description);
170   ok $invoice, "posting '$description' can be found in the database";
171
172   ($out, $err, @ret) = make_request('ap', 'edit', id => $invoice->id);
173   is $ret[0], 1, "loading '$description' did not cause an error";
174   warn $err if $err;
175
176   my $q = HTML::Query->new(text => $out);
177   is $q->query('input[name=paid_1]')->size, 1, "out '$description' contains paid_1";
178   is $q->query('input[name=paid_1]')->first->attr('value'), '20,00', "out '$description' paid_1 is 20 (the dollar amount, not the internal amount)";
179 }
180
181 {
182   my $testname     = 'ap_transaction_fx_gain_fees';
183   my $usd_amount   = 83300;
184   my $fx_rate      = 2;
185   my $fx_rate_bank = 1.75;
186   my $eur_amount   = $usd_amount * $fx_rate;
187
188   my $netamount     = $eur_amount;
189   my $amount        = $eur_amount;
190   my $buysell       = 'sell';
191   my $eur_payment   = $usd_amount * $fx_rate_bank;
192   my $usd_payment   = $eur_payment / $fx_rate_bank; # for rounding issues
193
194   my $bank              = SL::DB::Manager::Chart->find_by(description => 'Bank');
195   my $bank_account = SL::DB::Manager::BankAccount->find_by(chart_id => $bank->id) // SL::DB::BankAccount->new(
196     account_number => '123',
197     bank_code      => '123',
198     iban           => '123',
199     bic            => '123',
200     bank           => '123',
201     chart_id       => $bank->id,
202     name           => $bank->description,
203   )->save;
204
205   my $ex = SL::DB::Manager::Exchangerate->find_by(currency_id => $usd->id, transdate => $dt)
206         ||              SL::DB::Exchangerate->new(currency_id => $usd->id, transdate   => $dt);
207   $ex->update_attributes($buysell => $fx_rate);
208
209   my $ap_chart = SL::DB::Manager::Chart->get_first(query => [ link => 'AP' ], sort_by => 'accno');
210   my $ap_amount_chart = SL::DB::Manager::Chart->get_first(query => [ link => 'AP_amount' ], sort_by => 'accno');
211   my $invoice   = SL::DB::PurchaseInvoice->new(
212     invoice      => 0,
213     invnumber    => $testname,
214     amount       => $amount,
215     netamount    => $netamount,
216     transdate    => $dt,
217     taxincluded  => 0,
218     vendor_id    => $vendor->id,
219     taxzone_id   => $vendor->taxzone_id,
220     currency_id  => $usd->id,
221     transactions => [],
222     notes        => 'ap_transaction_fx',
223   );
224   $invoice->add_ap_amount_row(
225     amount     => $netamount,
226     chart      => $ap_amount_chart,
227     tax_id     => 0,
228   );
229
230   $invoice->create_ap_row(chart => $ap_chart);
231   $invoice->save;
232   my $ap_transaction_fx = $invoice;
233
234   # check exchangerate
235   is($ap_transaction_fx->currency->name   , 'USD'     , "$testname: USD currency");
236   is($ap_transaction_fx->get_exchangerate , '2.00000' , "$testname: fx rate record");
237   my $bt = create_bank_transaction(record        => $ap_transaction_fx,
238                                    bank_chart_id => $bank->id,
239                                    transdate     => $dt,
240                                    valutadate    => $dt,
241                                    amount        => $eur_payment,
242                                    exchangerate  => $fx_rate_bank,
243                                   ) or die "Couldn't create bank_transaction";
244
245   local $::form = Form->new;
246   $::form->{invoice_ids} = {
247     $bt->id => [ $ap_transaction_fx->id ]
248   };
249   $::form->{"book_fx_bank_fees_" . $bt->id . "_" . $ap_transaction_fx->id}  = 1;
250   $::form->{"exchangerate_"      . $bt->id . "_" . $ap_transaction_fx->id}  = "1,75"; # will be parsed
251   $::form->{"currency_id_"       . $bt->id . "_" . $ap_transaction_fx->id}  = $usd->id;
252
253   my ($stdout, $stderr, @result);
254   {
255     open(my $out_fh, '>', \$stdout) or die;
256     open(my $err_fh, '>', \$stderr) or die;
257
258     local *STDOUT = $out_fh;
259     local *STDERR = $err_fh;
260     my $bt_controller = SL::Controller::BankTransaction->new;
261     @result = $bt_controller->action_save_invoices;
262   };
263   ok !$stderr, "ap_transaction '$testname' can be booked with BackTransaction controller";
264
265   $invoice = SL::DB::Manager::PurchaseInvoice->find_by(invnumber => $testname);
266
267   # now load with old code
268   my ($out, $err, @ret) = make_request('ap', 'edit', id => $invoice->id);
269   is $ret[0], 1, "loading '$testname' did not cause an error";
270   warn $err if $err;
271
272   my $q = HTML::Query->new(text => $out);
273   is $q->query('input[name=paid_1]')->size, 1, "out '$testname' contains paid_1";
274   is $q->query('input[name=paid_1]')->first->attr('value'), _format_number($usd_payment, -2), "out '$testname' paid_1 is $usd_payment (the dollar amount, not the internal amount)";
275 }
276
277 reset_db();
278 done_testing();
279
280 1;