Merge branch 'b-3.6.1' of ../kivitendo-erp_20220811
[kivitendo-erp.git] / t / controllers / project / project_linked_records.t
1 use strict;
2 use Test::More;
3
4 use lib 't';
5 use Support::TestSetup;
6 use Carp;
7 use Test::Exception;
8 use SL::Dev::ALL qw(:ALL);
9 use SL::DB::Part;
10 use SL::DB::Order;
11 use SL::DB::Customer;
12 use SL::DB::Vendor;
13 use SL::DB::Chart;
14 use SL::Controller::Project;
15 use DateTime;
16
17 use utf8;
18
19 Support::TestSetup::login();
20
21 clear_up();
22
23 my $vendor   = new_vendor()->save;
24 my $customer = new_customer()->save;
25 my $project  = create_project(projectnumber => 'p1', description => 'Project 1');
26
27 my $part1 = new_part(   partnumber => 'T4254')->save;
28 my $part2 = new_service(partnumber => 'Serv1')->save;
29
30 # sales order with globalproject_id and item project_ids
31 my $sales_order = create_sales_order(
32   save             => 1,
33   customer         => $customer,
34   globalproject_id => $project->id,
35   taxincluded      => 0,
36   orderitems       => [ create_order_item(part => $part1, qty =>  3, sellprice => 70, project_id => $project->id),
37                         create_order_item(part => $part2, qty => 10, sellprice => 50, project_id => $project->id),
38                       ]
39 );
40
41 # sales order with no globalproject_id but item project_ids
42 my $sales_order2 = create_sales_order(
43   save             => 1,
44   customer         => $customer,
45   taxincluded      => 0,
46   orderitems       => [ create_order_item(part => $part1, qty =>  3, sellprice => 70, project_id => $project->id),
47                         create_order_item(part => $part2, qty => 10, sellprice => 50),
48                       ]
49 );
50
51 # purchase order with globalproject_id and item project_ids
52 my $purchase_order = create_purchase_order(
53   save             => 1,
54   vendor           => $vendor,
55   globalproject_id => $project->id,
56   taxincluded      => 0,
57   orderitems       => [ create_order_item(part => $part1, qty =>  3, sellprice => 70, project_id => $project->id),
58                         create_order_item(part => $part2, qty => 10, sellprice => 50, project_id => $project->id),
59                       ]
60 );
61
62 # sales_invoice with globalproject_id, and all items with project_id
63 my $sales_invoice = create_sales_invoice(
64   customer         => $customer,
65   globalproject_id => $project->id,
66   taxincluded      => 0,
67   invoiceitems     => [ create_invoice_item(part => $part1, qty =>  3, sellprice => 70, project_id => $project->id),
68                         create_invoice_item(part => $part2, qty => 10, sellprice => 50, project_id => $project->id),
69                       ]
70 );
71
72 # sales_invoice with globalproject_id, but none of the items has a project_id
73 my $sales_invoice2 = create_sales_invoice(
74   customer         => $customer,
75   globalproject_id => $project->id,
76   taxincluded      => 0,
77   invoiceitems     => [ create_invoice_item(part => $part1, qty =>  3, sellprice => 70),
78                         create_invoice_item(part => $part2, qty => 10, sellprice => 50),
79                       ]
80 );
81
82 # one of the invoice items has the project id, but there is no globalproject_id
83 my $sales_invoice4 = create_sales_invoice(
84   customer         => $customer,
85   taxincluded      => 0,
86   invoiceitems     => [ create_invoice_item(part => $part1, qty =>  3, sellprice => 70),
87                         create_invoice_item(part => $part2, qty => 10, sellprice => 50, project_id => $project->id),
88                       ]
89 );
90
91 my $today = DateTime->today;
92 my $expense_chart_porto = SL::DB::Manager::Chart->find_by(description => 'Porto');
93 my $income_chart        = SL::DB::Manager::Chart->find_by(accno => 8400);
94 my $tax_9 = SL::DB::Manager::Tax->find_by(taxkey => 9, rate => 0.19) || die "No tax";
95 my $tax_3 = SL::DB::Manager::Tax->find_by(taxkey => 3, rate => 0.19) || die "No tax";
96
97 # create an ar_transaction manually, with globalproject_id and acc_trans project_ids
98 my $ar_transaction = SL::DB::Invoice->new(
99       invoice          => 0,
100       invnumber        => 'test ar_transaction globalproject_id',
101       amount           => 119,
102       netamount        => 100,
103       transdate        => $today,
104       taxincluded      => 0,
105       customer_id      => $customer->id,
106       taxzone_id       => $customer->taxzone_id,
107       currency_id      => $::instance_conf->get_currency_id,
108       transactions     => [],
109       notes            => 'test ar_transaction globalproject_id',
110       globalproject_id => $project->id,
111 );
112 $ar_transaction->add_ar_amount_row(
113     amount     => $ar_transaction->netamount,
114     chart      => $income_chart,
115     tax_id     => $tax_3->id,
116     project_id => $project->id,
117 );
118 my $ar_chart = SL::DB::Manager::Chart->find_by( accno => '1400' ); # Forderungen
119 $ar_transaction->create_ar_row(chart => $ar_chart);
120 $ar_transaction->save;
121
122 # create an ap_transaction manually, with globalproject_id and acc_trans project_ids
123 my $ap_transaction = SL::DB::PurchaseInvoice->new(
124       invoice          => 0,
125       invnumber        => 'test ap_transaction globalproject_id',
126       amount           => 119,
127       netamount        => 100,
128       transdate        => $today,
129       taxincluded      => 0,
130       vendor_id        => $vendor->id,
131       taxzone_id       => $vendor->taxzone_id,
132       currency_id      => $::instance_conf->get_currency_id,
133       transactions     => [],
134       notes            => 'test ap_transaction globalproject_id',
135       globalproject_id => $project->id,
136 );
137 $ap_transaction->add_ap_amount_row(
138     amount     => $ap_transaction->netamount,
139     chart      => $expense_chart_porto,
140     tax_id     => $tax_9->id,
141     project_id => $project->id,
142 );
143 my $ap_chart = SL::DB::Manager::Chart->find_by( accno => '1600' ); # Verbindlichkeiten
144 $ap_transaction->create_ap_row(chart => $ap_chart);
145 $ap_transaction->save;
146
147 # create an ap_transaction manually, with no globalproject_id but acc_trans project_ids
148 my $ap_transaction2 = SL::DB::PurchaseInvoice->new(
149       invoice          => 0,
150       invnumber        => 'test ap_transaction no globalproject_id',
151       amount           => 119,
152       netamount        => 100,
153       transdate        => $today,
154       taxincluded      => 0,
155       vendor_id        => $vendor->id,
156       taxzone_id       => $vendor->taxzone_id,
157       currency_id      => $::instance_conf->get_currency_id,
158       transactions     => [],
159       notes            => 'test ap_transaction no globalproject_id',
160 );
161 $ap_transaction2->add_ap_amount_row(
162     amount     => $ap_transaction2->netamount,
163     chart      => $expense_chart_porto,
164     tax_id     => $tax_9->id,
165     project_id => $project->id,
166 );
167 $ap_chart = SL::DB::Manager::Chart->find_by( accno => '1600' ); # Verbindlichkeiten
168 $ap_transaction2->create_ap_row(chart => $ap_chart);
169 $ap_transaction2->save;
170
171 my $expense_chart = SL::DB::Manager::Chart->find_by(accno => '4660'); # Reisekosten
172 my $cash_chart    = SL::DB::Manager::Chart->find_by(accno => '1000'); # Kasse
173 my $tax_chart     = SL::DB::Manager::Chart->find_by(accno => '1576'); # Vorsteuer
174
175 my @acc_trans;
176 push(@acc_trans, SL::DB::AccTransaction->new(
177                                       chart_id   => $expense_chart->id,
178                                       chart_link => $expense_chart->link,
179                                       amount     => -84.03,
180                                       transdate  => $today,
181                                       source     => '',
182                                       taxkey     => 9,
183                                       tax_id     => $tax_9->id,
184                                       project_id => $project->id,
185 ));
186 push(@acc_trans, SL::DB::AccTransaction->new(
187                                       chart_id   => $tax_chart->id,
188                                       chart_link => $tax_chart->link,
189                                       amount     => -15.97,
190                                       transdate  => $today,
191                                       source     => '',
192                                       taxkey     => 9,
193                                       tax_id     => $tax_9->id,
194                                       project_id => $project->id,
195 ));
196 push(@acc_trans, SL::DB::AccTransaction->new(
197                                       chart_id   => $cash_chart->id,
198                                       chart_link => $cash_chart->link,
199                                       amount     => 100,
200                                       transdate  => $today,
201                                       source     => '',
202                                       taxkey     => 0,
203                                       tax_id     => 0,
204 ));
205
206 my $gl_transaction = SL::DB::GLTransaction->new(
207   reference      => "reise",
208   description    => "reise",
209   transdate      => $today,
210   gldate         => $today,
211   employee_id    => SL::DB::Manager::Employee->current->id,
212   taxincluded    => 1,
213   type           => undef,
214   ob_transaction => 0,
215   cb_transaction => 0,
216   storno         => 0,
217   storno_id      => undef,
218   transactions   => \@acc_trans,
219 )->save;
220
221 my $controller = SL::Controller::Project->new;
222 $::form->{id} = $project->id;
223 $controller->load_project;
224 is( scalar @{$controller->linked_records}, 10, "found all records that have a link to the project");
225
226 clear_up();
227
228 done_testing;
229
230 sub clear_up {
231   foreach (qw(OrderItem Order InvoiceItem Invoice PurchaseInvoice Part GLTransaction AccTransaction PurchaseInvoice Project Vendor Customer)) {
232     "SL::DB::Manager::${_}"->delete_all(all => 1);
233   }
234 }
235
236 1