Zeiterfassung: Unit-Test Eintrag mit Datum/Dauer
[kivitendo-erp.git] / t / background_job / convert_time_recordings.t
1 use Test::More tests => 20;
2
3 use strict;
4
5 use lib 't';
6 use utf8;
7
8 use Support::TestSetup;
9 use Test::Exception;
10 use DateTime;
11 use Rose::DB::Object::Helpers qw(forget_related);
12
13 use SL::DB::BackgroundJob;
14 use SL::DB::DeliveryOrder;
15
16 use_ok 'SL::BackgroundJob::ConvertTimeRecordings';
17
18 use SL::Dev::ALL qw(:ALL);
19
20 Support::TestSetup::login();
21
22 sub clear_up {
23   foreach (qw(OrderItem Order DeliveryOrder TimeRecording Project Part Customer RecordLink)) {
24     "SL::DB::Manager::${_}"->delete_all(all => 1);
25   }
26   SL::DB::Manager::Employee->delete_all(where => [ '!login' => 'unittests' ]);
27 };
28
29 ########################################
30
31 $::myconfig{numberformat} = '1000.00';
32 my $old_locale = $::locale;
33 # set locale to en so we can match errors
34 $::locale = Locale->new('en');
35
36
37 clear_up();
38
39 ########################################
40 # two time recordings, one order linked with project_id
41 ########################################
42 my $part     = new_service(partnumber => 'Serv1', unit => 'Std')->save;
43 my $project  = create_project(projectnumber => 'p1', description => 'Project 1');
44 my $customer = new_customer()->save;
45
46 # sales order with globalproject_id
47 my $sales_order = create_sales_order(
48   save             => 1,
49   customer         => $customer,
50   globalproject    => $project,
51   taxincluded      => 0,
52   orderitems       => [ create_order_item(part => $part, qty => 3, sellprice => 70), ]
53 );
54
55 my @time_recordings;
56 push @time_recordings, new_time_recording(
57   start_time => DateTime->new(year => 2021, month =>  4, day => 19, hour => 10, minute =>  5),
58   end_time   => DateTime->new(year => 2021, month =>  4, day => 19, hour => 11, minute =>  5),
59   customer   => $customer,
60   project    => $project,
61   part       => $part,
62 )->save;
63 push @time_recordings, new_time_recording(
64   start_time => DateTime->new(year => 2021, month =>  4, day => 19, hour => 12, minute =>  5),
65   end_time   => DateTime->new(year => 2021, month =>  4, day => 19, hour => 14, minute =>  5),
66   customer   => $customer,
67   project    => $project,
68   part       => $part,
69 )->save;
70
71 my %data   = (
72   link_project => 1,
73   project_id   => $project->id,
74   from_date    => '01.04.2021',
75   to_date      => '30.04.2021',
76 );
77 my $db_obj = SL::DB::BackgroundJob->new();
78 $db_obj->set_data(%data);
79 my $job    = SL::BackgroundJob::ConvertTimeRecordings->new;
80 my $ret    = $job->run($db_obj);
81
82 is_deeply($job->{job_errors}, [], 'no errros');
83 like($ret, qr{^Number of delivery orders created: 1}, 'one delivery order created');
84
85 my $linked_dos = $sales_order->linked_records(to => 'DeliveryOrder');
86 is(scalar @$linked_dos, 1, 'one delivery order linked to order');
87 is($linked_dos->[0]->globalproject_id, $sales_order->globalproject_id, 'project ids match');
88
89 my $linked_items = $sales_order->items->[0]->linked_records(to => 'DeliveryOrderItem');
90 is(scalar @$linked_items, 1, 'one delivery order item linked to order item');
91 is($linked_items->[0]->qty*1, 3, 'qty in delivery order');
92 is($linked_items->[0]->base_qty*1, 3, 'base_qty in delivery order');
93
94 # reload order and orderitems to get changes to deliverd and ship
95 Rose::DB::Object::Helpers::forget_related($sales_order, 'orderitems');
96 $sales_order->load;
97
98 ok($sales_order->delivered, 'related order is delivered');
99 is($sales_order->items->[0]->ship*1, 3, 'ship in related order');
100
101 clear_up();
102
103
104 ########################################
105 # two time recordings, one order linked with project_id
106 # unit in order is 'min', but part is 'Std'
107 ########################################
108 $part     = new_service(partnumber => 'Serv1', unit => 'Std')->save;
109 $project  = create_project(projectnumber => 'p1', description => 'Project 1');
110 $customer = new_customer()->save;
111
112 $sales_order = create_sales_order(
113   save             => 1,
114   customer         => $customer,
115   globalproject    => $project,
116   taxincluded      => 0,
117   orderitems       => [ create_order_item(part => $part, qty => 180, unit => 'min', sellprice => 70), ]
118 );
119
120 @time_recordings = ();
121 push @time_recordings, new_time_recording(
122   start_time => DateTime->new(year => 2021, month =>  4, day => 19, hour => 10, minute => 10),
123   end_time   => DateTime->new(year => 2021, month =>  4, day => 19, hour => 11, minute => 10),
124   customer   => $customer,
125   project    => $project,
126   part       => $part,
127 )->save;
128 push @time_recordings, new_time_recording(
129   start_time => DateTime->new(year => 2021, month =>  4, day => 19, hour => 12, minute => 10),
130   end_time   => DateTime->new(year => 2021, month =>  4, day => 19, hour => 14, minute => 10),
131   customer   => $customer,
132   project    => $project,
133   part       => $part,
134 )->save;
135
136 # two time recordings, one order linked with project_id
137 %data = (
138   link_project => 1,
139   project_id   => $project->id,
140   from_date    => '01.04.2021',
141   to_date      => '30.04.2021',
142 );
143 $db_obj = SL::DB::BackgroundJob->new();
144 $db_obj->set_data(%data);
145 $job    = SL::BackgroundJob::ConvertTimeRecordings->new;
146 $ret    = $job->run($db_obj);
147
148 $linked_dos = $sales_order->linked_records(to => 'DeliveryOrder');
149 $linked_items = $sales_order->items->[0]->linked_records(to => 'DeliveryOrderItem');
150 is($linked_items->[0]->qty*1, 3, 'different units: qty in delivery order');
151 is($linked_items->[0]->base_qty*1, 3, 'different units: base_qty in delivery order');
152
153 # reload order and orderitems to get changes to deliverd and ship
154 Rose::DB::Object::Helpers::forget_related($sales_order, 'orderitems');
155 $sales_order->load;
156
157 ok($sales_order->delivered, 'different units: related order is delivered');
158 is($sales_order->items->[0]->ship*1, 180, 'different units: ship in related order');
159
160 clear_up();
161
162
163 ########################################
164 # two time recordings, one order linked with project_id
165 # unit in order is 'Std', but part is 'min'
166 ########################################
167 $part     = new_service(partnumber => 'Serv1', unit => 'min')->save;
168 $project  = create_project(projectnumber => 'p1', description => 'Project 1');
169 $customer = new_customer()->save;
170
171 $sales_order = create_sales_order(
172   save             => 1,
173   customer         => $customer,
174   globalproject    => $project,
175   taxincluded      => 0,
176   orderitems       => [ create_order_item(part => $part, qty => 2, unit => 'Std', sellprice => 70), ]
177 );
178
179 @time_recordings = ();
180 push @time_recordings, new_time_recording(
181   start_time => DateTime->new(year => 2021, month =>  4, day => 19, hour => 10, minute => 10),
182   end_time   => DateTime->new(year => 2021, month =>  4, day => 19, hour => 11, minute => 10),
183   customer   => $customer,
184   project    => $project,
185   part       => $part,
186 )->save;
187 push @time_recordings, new_time_recording(
188   start_time => DateTime->new(year => 2021, month =>  4, day => 19, hour => 12, minute => 10),
189   end_time   => DateTime->new(year => 2021, month =>  4, day => 19, hour => 13, minute => 10),
190   customer   => $customer,
191   project    => $project,
192   part       => $part,
193 )->save;
194
195 # two time recordings, one order linked with project_id
196 %data = (
197   link_project => 1,
198   project_id   => $project->id,
199   from_date    => '01.04.2021',
200   to_date      => '30.04.2021',
201 );
202 $db_obj = SL::DB::BackgroundJob->new();
203 $db_obj->set_data(%data);
204 $job    = SL::BackgroundJob::ConvertTimeRecordings->new;
205 $ret    = $job->run($db_obj);
206
207 $linked_dos = $sales_order->linked_records(to => 'DeliveryOrder');
208 $linked_items = $sales_order->items->[0]->linked_records(to => 'DeliveryOrderItem');
209 is($linked_items->[0]->qty*1, 2, 'different units 2: qty in delivery order');
210 is($linked_items->[0]->base_qty*1, 120, 'different units 2: base_qty in delivery order');
211
212 # reload order and orderitems to get changes to deliverd and ship
213 Rose::DB::Object::Helpers::forget_related($sales_order, 'orderitems');
214 $sales_order->load;
215
216 ok($sales_order->delivered, 'different units 2: related order is delivered');
217 is($sales_order->items->[0]->ship*1, 2, 'different units 2: ship in related order');
218
219 clear_up();
220
221
222 ########################################
223 # two time recordings, one with start/end one with date/duration
224 ########################################
225 $part     = new_service(partnumber => 'Serv1', unit => 'min')->save;
226 $customer = new_customer()->save;
227
228 @time_recordings = ();
229 push @time_recordings, new_time_recording(
230   start_time => DateTime->new(year => 2021, month =>  4, day => 19, hour => 10, minute => 10),
231   end_time   => DateTime->new(year => 2021, month =>  4, day => 19, hour => 11, minute => 10),
232   customer   => $customer,
233   part       => $part,
234 )->save;
235
236 push @time_recordings, new_time_recording(
237   date       => DateTime->new(year => 2021, month =>  4, day => 19),
238   duration   => 120,
239   start_time => undef,
240   end_time   => undef,
241   customer   => $customer,
242   part       => $part,
243 )->save;
244
245 %data = (
246   link_project => 0,
247   from_date    => '01.04.2021',
248   to_date      => '30.04.2021',
249 );
250 $db_obj = SL::DB::BackgroundJob->new();
251 $db_obj->set_data(%data);
252 $job    = SL::BackgroundJob::ConvertTimeRecordings->new;
253 $ret    = $job->run($db_obj);
254
255 my $dos = SL::DB::Manager::DeliveryOrder->get_all(where => [customer_id => $customer->id]);
256 is($dos->[0]->items->[0]->qty*1, 180/60, 'date/duration and start/end: qty in delivery order');
257 is($dos->[0]->items->[0]->base_qty*1, 180, 'date/duration and start/end2: base_qty in delivery order');
258
259 clear_up();
260
261
262 ########################################
263
264 $::locale = $old_locale;
265
266 1;
267
268 #####
269 # vim: ft=perl
270 # set emacs to perl mode
271 # Local Variables:
272 # mode: perl
273 # End: