X-Git-Url: http://wagnertech.de/gitweb/gitweb.cgi/mfinanz.git/blobdiff_plain/459b3c8dd86d8aa35e5b2cdff0e3e8c42216a7e3..f217d072d76183bc07723dcc29503b732bd2022d:/SL/BackgroundJob/ConvertTimeRecordings.pm diff --git a/SL/BackgroundJob/ConvertTimeRecordings.pm b/SL/BackgroundJob/ConvertTimeRecordings.pm index 75c09ad34..8f90d40b9 100644 --- a/SL/BackgroundJob/ConvertTimeRecordings.pm +++ b/SL/BackgroundJob/ConvertTimeRecordings.pm @@ -13,7 +13,7 @@ use SL::Locale::String qw(t8); use DateTime; use List::Util qw(any); - +use Try::Tiny; sub create_job { $_[0]->create_standard_job('7 3 1 * *'); # every first day of month at 03:07 } @@ -85,13 +85,15 @@ sub initialize_params { # valid parameters with default values my %valid_params = ( - from_date => DateTime->new( day => 1, month => DateTime->today_local->month, year => DateTime->today_local->year)->subtract(months => 1)->to_kivitendo, - to_date => DateTime->last_day_of_month(month => DateTime->today_local->month, year => DateTime->today_local->year)->subtract(months => 1)->to_kivitendo, - customernumbers => [], - part_id => undef, - project_id => undef, - rounding => 1, - link_order => 0, + from_date => DateTime->new( day => 1, month => DateTime->today_local->month, year => DateTime->today_local->year)->subtract(months => 1)->to_kivitendo, + to_date => DateTime->last_day_of_month(month => DateTime->today_local->month, year => DateTime->today_local->year)->subtract(months => 1)->to_kivitendo, + customernumbers => [], + override_part_id => undef, + default_part_id => undef, + override_project_id => undef, + default_project_id => undef, + rounding => 1, + link_order => 0, ); @@ -107,13 +109,24 @@ sub initialize_params { # convert date from string to object - my $from_date; - my $to_date; - $from_date = DateTime->from_kivitendo($self->params->{from_date}); - $to_date = DateTime->from_kivitendo($self->params->{to_date}); - # DateTime->from_kivitendo returns undef if the string cannot be parsed. Therefore test the result. - die 'Cannot convert date from string "' . $self->params->{from_date} . '"' if !$from_date; - die 'Cannot convert date to string "' . $self->params->{to_date} . '"' if !$to_date; + my ($from_date, $to_date); + try { + if ($self->params->{from_date}) { + $from_date = DateTime->from_kivitendo($self->params->{from_date}); + # no undef and no other type. + die unless ref $from_date eq 'DateTime'; + } + if ($self->params->{to_date}) { + $to_date = DateTime->from_kivitendo($self->params->{to_date}); + # no undef and no other type. + die unless ref $to_date eq 'DateTime'; + } + } catch { + die t8("Cannot convert date.") ."\n" . + t8("Input from string: #1", $self->params->{from_date}) . "\n" . + t8("Input to string: #1", $self->params->{to_date}) . "\n" . + t8("Details: #1", $_); + }; $to_date->add(days => 1); # to get all from the to_date, because of the time part (15.12.2020 23.59 > 15.12.2020) @@ -136,16 +149,24 @@ sub initialize_params { # check part - if ($self->params->{part_id} && !SL::DB::Manager::Part->find_by(id => $self->params->{part_id}, - or => [obsolete => undef, obsolete => 0])) { - die 'No valid part found by given part id'; + if ($self->params->{override_part_id} && !SL::DB::Manager::Part->find_by(id => $self->params->{override_part_id}, + or => [obsolete => undef, obsolete => 0])) { + die 'No valid part found by given override part id'; + } + if ($self->params->{default_part_id} && !SL::DB::Manager::Part->find_by(id => $self->params->{default_part_id}, + or => [obsolete => undef, obsolete => 0])) { + die 'No valid part found by given default part id'; } # check project - if ($self->params->{project_id} && !SL::DB::Manager::Project->find_by(id => $self->params->{project_id}, - active => 1, valid => 1)) { - die 'No valid project found by given project id'; + if ($self->params->{override_project_id} && !SL::DB::Manager::Project->find_by(id => $self->params->{override_project_id}, + active => 1, valid => 1)) { + die 'No valid project found by given override project id'; + } + if ($self->params->{default_project_id} && !SL::DB::Manager::Project->find_by(id => $self->params->{default_project_id}, + active => 1, valid => 1)) { + die 'No valid project found by given default project id'; } return $self->params; @@ -158,8 +179,9 @@ sub convert_without_linking { push @{ $time_recordings_by_customer_id{$_->customer_id} }, $_ for @$time_recordings; my %convert_params = ( - rounding => $self->params->{rounding}, - default_part_id => $self->params->{part_id}, + rounding => $self->params->{rounding}, + override_part_id => $self->params->{override_part_id}, + default_part_id => $self->params->{default_part_id}, ); my @donumbers; @@ -193,7 +215,8 @@ sub convert_with_linking { my %convert_params = ( rounding => $self->params->{rounding}, - default_part_id => $self->params->{part_id}, + override_part_id => $self->params->{override_part_id}, + default_part_id => $self->params->{default_part_id}, ); my @donumbers; @@ -212,24 +235,6 @@ sub convert_with_linking { $do->save; $_->update_attributes(booked => 1) for @{$time_recordings_by_order_id->{$related_order_id}}; - $related_order->link_to_record($do); - - # TODO extend link_to_record for items, otherwise long-term no d.r.y. - foreach my $item (@{ $do->items }) { - foreach (qw(orderitems)) { - if ($item->{"converted_from_${_}_id"}) { - die unless $item->{id}; - RecordLinks->create_links('mode' => 'ids', - 'from_table' => $_, - 'from_ids' => $item->{"converted_from_${_}_id"}, - 'to_table' => 'delivery_order_items', - 'to_id' => $item->{id}, - ) || die; - delete $item->{"converted_from_${_}_id"}; - } - } - } - # update delivered and item's ship for related order my $helper = SL::Helper::ShippedQty->new->calculate($related_order)->write_to_objects; $related_order->delivered($related_order->{delivered}); @@ -257,10 +262,9 @@ sub get_order_for_time_recording { if (!$tr->order_id) { # check project my $project_id; - #$project_id = $self->override_project_id; - $project_id = $self->params->{project_id}; + $project_id = $self->params->{override_project_id}; $project_id ||= $tr->project_id; - #$project_id ||= $self->default_project_id; + $project_id ||= $self->params->{default_project_id}; if (!$project_id) { $self->log_error('searching related order failed for time recording id ' . $tr->id . ' : no project id'); @@ -283,7 +287,7 @@ sub get_order_for_time_recording { } $orders = SL::DB::Manager::Order->get_all(where => [customer_id => $tr->customer_id, - or => [quotation => undef, quotation => 0], + record_type => 'sales_order', globalproject_id => $project_id, ], with_objects => ['orderitems']); @@ -300,10 +304,9 @@ sub get_order_for_time_recording { # check part my $part_id; - #$part_id = $self->override_part_id; + $part_id = $self->params->{override_part_id}; $part_id ||= $tr->part_id; - #$part_id ||= $self->default_part_id; - $part_id ||= $self->params->{part_id}; + $part_id ||= $self->params->{default_part_id}; if (!$part_id) { $self->log_error('searching related order failed for time recording id ' . $tr->id . ' : no part id'); @@ -339,7 +342,7 @@ sub get_order_for_time_recording { return; } - if ($tr->project_id && $tr->project_id != ($matching_order->globalproject_id || 0)) { + if ($tr->project_id && !$self->params->{override_project_id} && $tr->project_id != ($matching_order->globalproject_id || 0)) { $self->log_error('searching related order failed for time recording id ' . $tr->id . ' : project of order does not match project of time recording'); return; } @@ -415,7 +418,13 @@ collected. customernumbers: [c1,22332,334343] -=item C +=item C + +The part id of a time based service which should be used to +book the times instead of the parts which are set in the time +recordings. + +=item C The part id of a time based service which should be used to book the times if no part is set in the time recording entry. @@ -452,9 +461,15 @@ the services are not yet fully delivered (simple case: 'Payment in advance'). Hint: take a look or extend the job CloseProjectsBelongingToClosedSalesOrder for further automatisation of your organisational needs. -=item C +=item C + +Use this project id instead of the project id in the time recordings to find +a related order. This is only used if C is true. + +=item C -Use this project_id instead of the project_id in the time recordings. +Use this project id if no project id is set in the time recording +entry. This is only used if C is true. =back @@ -468,17 +483,6 @@ Add parameters to give part and project not with their ids, but with their numbers. E.g. (default_/override_)part_number, (default_/override_)project_number. -=item * part and project parameters override and default - -In the moment, the part id given as parameter is used as the default value. -This means, it will be used if there is no part in the time recvording entry. - -The project id given is used as override parameter. It overrides the project -given in the time recording entry. - -To solve this, there should be parameters named override_part_id, -default_part_id, override_project_id and default_project_id. - =back