1 use Test::More tests => 40;
8 use Support::TestSetup;
11 use Rose::DB::Object::Helpers qw(forget_related);
13 use SL::DB::BackgroundJob;
14 use SL::DB::DeliveryOrder;
16 use_ok 'SL::BackgroundJob::ConvertTimeRecordings';
18 use SL::Dev::ALL qw(:ALL);
20 Support::TestSetup::login();
23 foreach (qw(TimeRecording OrderItem Order DeliveryOrder Project Part Customer RecordLink)) {
24 "SL::DB::Manager::${_}"->delete_all(all => 1);
26 SL::DB::Manager::Employee->delete_all(where => [ '!login' => 'unittests' ]);
29 ########################################
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');
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;
46 # sales order with globalproject_id
47 my $sales_order = create_sales_order(
49 customer => $customer,
50 globalproject => $project,
52 orderitems => [ create_order_item(part => $part, qty => 3, sellprice => 70), ]
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,
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,
73 project_id => $project->id,
74 from_date => '01.01.2021',
75 to_date => '30.04.2021',
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);
82 is_deeply($job->{job_errors}, [], 'no errros');
83 like($ret, qr{^Number of delivery orders created: 1}, 'one delivery order created');
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');
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');
94 # reload order and orderitems to get changes to deliverd and ship
95 Rose::DB::Object::Helpers::forget_related($sales_order, 'orderitems');
98 ok($sales_order->delivered, 'related order is delivered');
99 is($sales_order->items->[0]->ship*1, 3, 'ship in related order');
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;
112 $sales_order = create_sales_order(
114 customer => $customer,
115 globalproject => $project,
117 orderitems => [ create_order_item(part => $part, qty => 180, unit => 'min', sellprice => 70), ]
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,
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,
136 # two time recordings, one order linked with project_id
139 project_id => $project->id,
140 from_date => '01.04.2021',
141 to_date => '30.04.2021',
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);
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');
153 # reload order and orderitems to get changes to deliverd and ship
154 Rose::DB::Object::Helpers::forget_related($sales_order, 'orderitems');
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');
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;
171 $sales_order = create_sales_order(
173 customer => $customer,
174 globalproject => $project,
176 orderitems => [ create_order_item(part => $part, qty => 2, unit => 'Std', sellprice => 70), ]
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,
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,
195 # two time recordings, one order linked with project_id
198 project_id => $project->id,
199 from_date => '01.04.2021',
200 to_date => '30.04.2021',
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);
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');
212 # reload order and orderitems to get changes to deliverd and ship
213 Rose::DB::Object::Helpers::forget_related($sales_order, 'orderitems');
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');
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;
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,
236 push @time_recordings, new_time_recording(
237 date => DateTime->new(year => 2021, month => 4, day => 19),
241 customer => $customer,
247 from_date => '01.04.2021',
248 to_date => '30.04.2021',
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);
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');
262 ########################################
263 # time recording, linked with order_id
264 ########################################
265 $part = new_service(partnumber => 'Serv1', unit => 'Std')->save;
266 $customer = new_customer()->save;
268 # sales order with globalproject_id
269 $sales_order = create_sales_order(
271 customer => $customer,
273 orderitems => [ create_order_item(part => $part, qty => 3, sellprice => 70), ]
276 @time_recordings = ();
277 push @time_recordings, new_time_recording(
278 start_time => DateTime->new(year => 2021, month => 4, day => 19, hour => 10, minute => 5),
279 end_time => DateTime->new(year => 2021, month => 4, day => 19, hour => 11, minute => 5),
280 customer => $customer,
281 order => $sales_order,
287 from_date => '01.04.2021',
288 to_date => '30.04.2021',
289 customernumbers => [$customer->number],
291 $db_obj = SL::DB::BackgroundJob->new();
292 $db_obj->set_data(%data);
293 $job = SL::BackgroundJob::ConvertTimeRecordings->new;
294 $ret = $job->run($db_obj);
296 is_deeply($job->{job_errors}, [], 'no errros');
297 like($ret, qr{^Number of delivery orders created: 1}, 'linked by order_id: one delivery order created');
299 $linked_dos = $sales_order->linked_records(to => 'DeliveryOrder');
300 is(scalar @$linked_dos, 1, 'linked by order_id: one delivery order linked to order');
302 $linked_items = $sales_order->items->[0]->linked_records(to => 'DeliveryOrderItem');
303 is(scalar @$linked_items, 1, 'linked by order_id: one delivery order item linked to order item');
304 is($linked_items->[0]->qty*1, 1, 'linked by order_id: qty in delivery order');
305 is($linked_items->[0]->base_qty*1, 1, 'linked by order_id: base_qty in delivery order');
307 # reload order and orderitems to get changes to deliverd and ship
308 Rose::DB::Object::Helpers::forget_related($sales_order, 'orderitems');
311 is($sales_order->items->[0]->ship*1, 1, 'linked by order_id: ship in related order');
316 ########################################
318 ########################################
319 $part = new_service(partnumber => 'Serv1', unit => 'Std')->save;
320 $customer = new_customer()->save;
322 $sales_order = create_sales_order(
324 customer => $customer,
326 orderitems => [ create_order_item(part => $part, qty => 3, sellprice => 70), ]
329 @time_recordings = ();
330 push @time_recordings, new_time_recording(
331 start_time => DateTime->new(year => 2021, month => 4, day => 19, hour => 10, minute => 0),
332 end_time => DateTime->new(year => 2021, month => 4, day => 19, hour => 10, minute => 6),
333 customer => $customer,
334 order => $sales_order,
339 from_date => '01.01.2021',
340 to_date => '30.04.2021',
344 $db_obj = SL::DB::BackgroundJob->new();
345 $db_obj->set_data(%data);
346 $job = SL::BackgroundJob::ConvertTimeRecordings->new;
347 $ret = $job->run($db_obj);
349 $linked_dos = $sales_order->linked_records(to => 'DeliveryOrder');
350 $linked_items = $sales_order->items->[0]->linked_records(to => 'DeliveryOrderItem');
351 is($linked_items->[0]->qty*1, 0.25, 'rounding to quarter hour: qty in delivery order');
352 is($linked_items->[0]->base_qty*1, 0.25, 'rounding to quarter hour: base_qty in delivery order');
354 # reload order and orderitems to get changes to deliverd and ship
355 Rose::DB::Object::Helpers::forget_related($sales_order, 'orderitems');
358 is($sales_order->items->[0]->ship*1, 0.25, 'rounding to quarter hour: ship in related order');
363 ########################################
365 ########################################
366 $part = new_service(partnumber => 'Serv1', unit => 'Std')->save;
367 $customer = new_customer()->save;
369 $sales_order = create_sales_order(
371 customer => $customer,
373 orderitems => [ create_order_item(part => $part, qty => 3, sellprice => 70), ]
376 @time_recordings = ();
377 push @time_recordings, new_time_recording(
378 start_time => DateTime->new(year => 2021, month => 4, day => 19, hour => 10, minute => 0),
379 end_time => DateTime->new(year => 2021, month => 4, day => 19, hour => 10, minute => 6),
380 customer => $customer,
381 order => $sales_order,
386 from_date => '01.01.2021',
387 to_date => '30.04.2021',
391 $db_obj = SL::DB::BackgroundJob->new();
392 $db_obj->set_data(%data);
393 $job = SL::BackgroundJob::ConvertTimeRecordings->new;
394 $ret = $job->run($db_obj);
396 $linked_dos = $sales_order->linked_records(to => 'DeliveryOrder');
397 $linked_items = $sales_order->items->[0]->linked_records(to => 'DeliveryOrderItem');
398 is($linked_items->[0]->qty*1, 0.1, 'no rounding: qty in delivery order');
399 is($linked_items->[0]->base_qty*1, 0.1, 'no rounding: base_qty in delivery order');
401 # reload order and orderitems to get changes to deliverd and ship
402 Rose::DB::Object::Helpers::forget_related($sales_order, 'orderitems');
405 is($sales_order->items->[0]->ship*1, 0.1, 'no rounding: ship in related order');
410 ########################################
411 # are wrong params detected?
412 ########################################
414 from_date => 'x01.04.2021',
416 $db_obj = SL::DB::BackgroundJob->new();
417 $db_obj->set_data(%data);
418 $job = SL::BackgroundJob::ConvertTimeRecordings->new;
421 eval { $ret = $job->run($db_obj); 1; } or do {$err_msg = $@};
422 ok($err_msg =~ '^Cannot convert date from string', 'wrong date string detected');
426 $customer = new_customer()->save;
428 customernumbers => ['a fantasy', $customer->number],
431 $db_obj = SL::DB::BackgroundJob->new();
432 $db_obj->set_data(%data);
433 $job = SL::BackgroundJob::ConvertTimeRecordings->new;
436 eval { $ret = $job->run($db_obj); 1; } or do {$err_msg = $@};
437 ok($err_msg =~ '^Not all customer numbers are valid', 'wrong customer number detected');
442 customernumbers => '123',
445 $db_obj = SL::DB::BackgroundJob->new();
446 $db_obj->set_data(%data);
447 $job = SL::BackgroundJob::ConvertTimeRecordings->new;
450 eval { $ret = $job->run($db_obj); 1; } or do {$err_msg = $@};
451 ok($err_msg =~ '^Customer numbers must be given in an array', 'wrong customer number data type detected');
459 $db_obj = SL::DB::BackgroundJob->new();
460 $db_obj->set_data(%data);
461 $job = SL::BackgroundJob::ConvertTimeRecordings->new;
464 eval { $ret = $job->run($db_obj); 1; } or do {$err_msg = $@};
465 ok($err_msg =~ '^No valid part found by given part id', 'invalid part id detected');
469 $part = new_service(partnumber => 'Serv1', unit => 'Std', obsolete => 1)->save;
471 part_id => $part->id,
474 $db_obj = SL::DB::BackgroundJob->new();
475 $db_obj->set_data(%data);
476 $job = SL::BackgroundJob::ConvertTimeRecordings->new;
479 eval { $ret = $job->run($db_obj); 1; } or do {$err_msg = $@};
480 ok($err_msg =~ '^No valid part found by given part id', 'obsolete part detected');
488 $db_obj = SL::DB::BackgroundJob->new();
489 $db_obj->set_data(%data);
490 $job = SL::BackgroundJob::ConvertTimeRecordings->new;
493 eval { $ret = $job->run($db_obj); 1; } or do {$err_msg = $@};
494 ok($err_msg =~ '^No valid project found by given project id', 'invalid project id detected');
498 $project = create_project(projectnumber => 'p1', description => 'Project 1', valid => 0)->save;
500 project_id => $project->id,
503 $db_obj = SL::DB::BackgroundJob->new();
504 $db_obj->set_data(%data);
505 $job = SL::BackgroundJob::ConvertTimeRecordings->new;
508 eval { $ret = $job->run($db_obj); 1; } or do {$err_msg = $@};
509 ok($err_msg =~ '^No valid project found by given project id', 'invalid project detected');
516 ########################################
518 $::locale = $old_locale;
524 # set emacs to perl mode