From af81f05f3519e304f29a28b7fe34cce3689c073f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bernd=20Ble=C3=9Fmann?= Date: Mon, 3 May 2021 13:24:41 +0200 Subject: [PATCH] Zeiterfassung: Konvertierung: geliefert/gelieferte Mengen in Auftrag anpassen --- SL/BackgroundJob/ConvertTimeRecordings.pm | 12 +- SL/DB/DeliveryOrder.pm | 13 +- t/background_job/convert_time_recordings.t | 142 ++++++++++++++++++++- 3 files changed, 153 insertions(+), 14 deletions(-) diff --git a/SL/BackgroundJob/ConvertTimeRecordings.pm b/SL/BackgroundJob/ConvertTimeRecordings.pm index ffc2bae2c..906c8dba4 100644 --- a/SL/BackgroundJob/ConvertTimeRecordings.pm +++ b/SL/BackgroundJob/ConvertTimeRecordings.pm @@ -211,8 +211,11 @@ sub convert_with_linking { } } + # update delivered and item's ship for related order my $helper = SL::Helper::ShippedQty->new->calculate($related_order)->write_to_objects; - $related_order->update_attributes(delivered => $related_order->{delivered}); + $related_order->delivered($related_order->{delivered}); + $_->ship($_->{shipped_qty}) for @{$related_order->items}; + $related_order->save(cascade => 1); 1; })) { @@ -287,9 +290,10 @@ sub get_order_for_time_recording { return; } - my $orders = SL::DB::Manager::Order->get_all(where => [customer_id => $tr->customer_id, - or => [quotation => undef, quotation => 0], - globalproject_id => $project_id, ]); + my $orders = SL::DB::Manager::Order->get_all(where => [customer_id => $tr->customer_id, + or => [quotation => undef, quotation => 0], + globalproject_id => $project_id, ], + with_objects => ['orderitems']); my @matching_orders; foreach my $order (@$orders) { if (any { $_->parts_id == $part_id } @{ $order->items_sorted }) { diff --git a/SL/DB/DeliveryOrder.pm b/SL/DB/DeliveryOrder.pm index 30db8e627..8bb89bd86 100644 --- a/SL/DB/DeliveryOrder.pm +++ b/SL/DB/DeliveryOrder.pm @@ -20,7 +20,7 @@ use SL::DB::Unit; use SL::Helper::Number qw(_format_total _round_total); use List::Util qw(first); -use List::MoreUtils qw(any); +use List::MoreUtils qw(any pairwise); use Math::Round qw(nhimult); __PACKAGE__->meta->add_relationship(orderitems => { type => 'one to many', @@ -264,17 +264,20 @@ sub new_from_time_recordings { if ($params{related_order}) { # collect suitable items in related order my @items_to_use; + my @new_attributes; foreach my $item (@items) { my $item_to_use = first {$item->parts_id == $_->parts_id} @{ $params{related_order}->items_sorted }; die "no suitable item found in related order" if !$item_to_use; my %new_attributes; - $new_attributes{$_} = $item->$_ for qw(qty unit_obj longdescription); - $item_to_use->assign_attributes(%new_attributes); - push @items_to_use, $item_to_use; + $new_attributes{$_} = $item->$_ for qw(qty base_qty unit_obj longdescription); + push @items_to_use, $item_to_use; + push @new_attributes, \%new_attributes; } - $delivery_order = SL::DB::DeliveryOrder->new_from($params{related_order}, items => \@items_to_use, %params); + + $delivery_order = $class->new_from($params{related_order}, items => \@items_to_use, %params); + pairwise { $a->assign_attributes( %$b) } @{$delivery_order->items}, @new_attributes; } else { my %args = ( diff --git a/t/background_job/convert_time_recordings.t b/t/background_job/convert_time_recordings.t index 3ba2c9a93..d08c03d3a 100644 --- a/t/background_job/convert_time_recordings.t +++ b/t/background_job/convert_time_recordings.t @@ -1,4 +1,4 @@ -use Test::More tests => 7; +use Test::More tests => 18; use strict; @@ -8,6 +8,7 @@ use utf8; use Support::TestSetup; use Test::Exception; use DateTime; +use Rose::DB::Object::Helpers qw(forget_related); use SL::DB::BackgroundJob; @@ -34,6 +35,9 @@ $::locale = Locale->new('en'); clear_up(); +######################################## +# two time recordings, one order linked with project_id +######################################## my $part = new_service(partnumber => 'Serv1', unit => 'Std')->save; my $project = create_project(projectnumber => 'p1', description => 'Project 1'); my $customer = new_customer()->save; @@ -50,20 +54,19 @@ my $sales_order = create_sales_order( my @time_recordings; push @time_recordings, new_time_recording( start_time => DateTime->new(year => 2021, month => 4, day => 19, hour => 10, minute => 5), - end_time => DateTime->new(year => 2021, month => 4, day => 19, hour => 11, minute => 10), + end_time => DateTime->new(year => 2021, month => 4, day => 19, hour => 11, minute => 5), customer => $customer, project => $project, part => $part, )->save; push @time_recordings, new_time_recording( start_time => DateTime->new(year => 2021, month => 4, day => 19, hour => 12, minute => 5), - end_time => DateTime->new(year => 2021, month => 4, day => 19, hour => 14, minute => 10), + end_time => DateTime->new(year => 2021, month => 4, day => 19, hour => 14, minute => 5), customer => $customer, project => $project, part => $part, )->save; -# two time recordings, one order linked with project_id my %data = ( link_project => 1, project_id => $project->id, @@ -84,10 +87,139 @@ is($linked_dos->[0]->globalproject_id, $sales_order->globalproject_id, 'project my $linked_items = $sales_order->items->[0]->linked_records(to => 'DeliveryOrderItem'); is(scalar @$linked_items, 1, 'one delivery order item linked to order item'); -is($linked_items->[0]->qty*1, 3.16, 'qty in delivery order'); +is($linked_items->[0]->qty*1, 3, 'qty in delivery order'); +is($linked_items->[0]->base_qty*1, 3, 'base_qty in delivery order'); + +# reload order and orderitems to get changes to deliverd and ship +Rose::DB::Object::Helpers::forget_related($sales_order, 'orderitems'); +$sales_order->load; + +ok($sales_order->delivered, 'related order is delivered'); +is($sales_order->items->[0]->ship*1, 3, 'ship in related order'); + +clear_up(); + + +######################################## +# two time recordings, one order linked with project_id +# unit in order is 'min', but part is 'Std' +######################################## +$part = new_service(partnumber => 'Serv1', unit => 'Std')->save; +$project = create_project(projectnumber => 'p1', description => 'Project 1'); +$customer = new_customer()->save; + +$sales_order = create_sales_order( + save => 1, + customer => $customer, + globalproject => $project, + taxincluded => 0, + orderitems => [ create_order_item(part => $part, qty => 180, unit => 'min', sellprice => 70), ] +); + +@time_recordings = (); +push @time_recordings, new_time_recording( + start_time => DateTime->new(year => 2021, month => 4, day => 19, hour => 10, minute => 10), + end_time => DateTime->new(year => 2021, month => 4, day => 19, hour => 11, minute => 10), + customer => $customer, + project => $project, + part => $part, +)->save; +push @time_recordings, new_time_recording( + start_time => DateTime->new(year => 2021, month => 4, day => 19, hour => 12, minute => 10), + end_time => DateTime->new(year => 2021, month => 4, day => 19, hour => 14, minute => 10), + customer => $customer, + project => $project, + part => $part, +)->save; + +# two time recordings, one order linked with project_id +%data = ( + link_project => 1, + project_id => $project->id, + from_date => '01.04.2021', + to_date => '30.04.2021', +); +$db_obj = SL::DB::BackgroundJob->new(); +$db_obj->set_data(%data); +$job = SL::BackgroundJob::ConvertTimeRecordings->new; +$ret = $job->run($db_obj); + +$linked_dos = $sales_order->linked_records(to => 'DeliveryOrder'); +$linked_items = $sales_order->items->[0]->linked_records(to => 'DeliveryOrderItem'); +is($linked_items->[0]->qty*1, 3, 'different units: qty in delivery order'); +is($linked_items->[0]->base_qty*1, 3, 'different units: base_qty in delivery order'); + +# reload order and orderitems to get changes to deliverd and ship +Rose::DB::Object::Helpers::forget_related($sales_order, 'orderitems'); +$sales_order->load; + +ok($sales_order->delivered, 'different units: related order is delivered'); +is($sales_order->items->[0]->ship*1, 180, 'different units: ship in related order'); + +clear_up(); + + +######################################## +# two time recordings, one order linked with project_id +# unit in order is 'Std', but part is 'min' +######################################## +$part = new_service(partnumber => 'Serv1', unit => 'min')->save; +$project = create_project(projectnumber => 'p1', description => 'Project 1'); +$customer = new_customer()->save; + +$sales_order = create_sales_order( + save => 1, + customer => $customer, + globalproject => $project, + taxincluded => 0, + orderitems => [ create_order_item(part => $part, qty => 2, unit => 'Std', sellprice => 70), ] +); + +@time_recordings = (); +push @time_recordings, new_time_recording( + start_time => DateTime->new(year => 2021, month => 4, day => 19, hour => 10, minute => 10), + end_time => DateTime->new(year => 2021, month => 4, day => 19, hour => 11, minute => 10), + customer => $customer, + project => $project, + part => $part, +)->save; +push @time_recordings, new_time_recording( + start_time => DateTime->new(year => 2021, month => 4, day => 19, hour => 12, minute => 10), + end_time => DateTime->new(year => 2021, month => 4, day => 19, hour => 13, minute => 10), + customer => $customer, + project => $project, + part => $part, +)->save; + +# two time recordings, one order linked with project_id +%data = ( + link_project => 1, + project_id => $project->id, + from_date => '01.04.2021', + to_date => '30.04.2021', +); +$db_obj = SL::DB::BackgroundJob->new(); +$db_obj->set_data(%data); +$job = SL::BackgroundJob::ConvertTimeRecordings->new; +$ret = $job->run($db_obj); + +$linked_dos = $sales_order->linked_records(to => 'DeliveryOrder'); +$linked_items = $sales_order->items->[0]->linked_records(to => 'DeliveryOrderItem'); +is($linked_items->[0]->qty*1, 2, 'different units 2: qty in delivery order'); +is($linked_items->[0]->base_qty*1, 120, 'different units 2: base_qty in delivery order'); + +# reload order and orderitems to get changes to deliverd and ship +Rose::DB::Object::Helpers::forget_related($sales_order, 'orderitems'); +$sales_order->load; + +ok($sales_order->delivered, 'different units 2: related order is delivered'); +is($sales_order->items->[0]->ship*1, 2, 'different units 2: ship in related order'); clear_up(); + +######################################## + $::locale = $old_locale; 1; -- 2.20.1