+
+ return @donumbers;
+}
+
+sub get_order_for_time_recording {
+ my ($self, $tr) = @_;
+
+ my $orders;
+
+ if (!$tr->order_id) {
+ # check project
+ my $project_id;
+ $project_id = $self->params->{override_project_id};
+ $project_id ||= $tr->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');
+ return;
+ }
+
+ my $project = SL::DB::Project->load_cached($project_id);
+
+ if (!$project) {
+ $self->log_error('searching related order failed for time recording id ' . $tr->id . ' : project not found');
+ return;
+ }
+ if (!$project->active || !$project->valid) {
+ $self->log_error('searching related order failed for time recording id ' . $tr->id . ' : project not active or not valid');
+ return;
+ }
+ if ($project->customer_id && $project->customer_id != $tr->customer_id) {
+ $self->log_error('searching related order failed for time recording id ' . $tr->id . ' : project customer does not match customer of time recording');
+ return;
+ }
+
+ $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']);
+
+ } else {
+ # order_id given
+ my $order = SL::DB::Manager::Order->find_by(id => $tr->order_id);
+ push @$orders, $order if $order;
+ }
+
+ if (!scalar @$orders) {
+ $self->log_error('searching related order failed for time recording id ' . $tr->id . ' : no order found');
+ return;
+ }
+
+ # check part
+ my $part_id;
+ $part_id = $self->params->{override_part_id};
+ $part_id ||= $tr->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');
+ return;
+ }
+ my $part = SL::DB::Part->load_cached($part_id);
+ if (!$part->unit_obj->is_time_based) {
+ $self->log_error('searching related order failed for time recording id ' . $tr->id . ' : part unit is not time based');
+ return;
+ }
+
+ my @matching_orders;
+ foreach my $order (@$orders) {
+ if (any { $_->parts_id == $part_id } @{ $order->items_sorted }) {
+ push @matching_orders, $order;
+ }
+ }
+
+ if (1 != scalar @matching_orders) {
+ $self->log_error('searching related order failed for time recording id ' . $tr->id . ' : no or more than one orders do match');
+ return;
+ }
+
+ my $matching_order = $matching_orders[0];
+
+ if (!$matching_order->is_sales) {
+ $self->log_error('searching related order failed for time recording id ' . $tr->id . ' : found order is not a sales order');
+ return;
+ }
+
+ if ($matching_order->customer_id != $tr->customer_id) {
+ $self->log_error('searching related order failed for time recording id ' . $tr->id . ' : customer of order does not match customer of time recording');
+ return;
+ }
+
+ 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;
+ }
+
+ return $matching_order;
+}
+
+sub log_error {
+ my ($self, $msg) = @_;
+
+ my $dbg = 0;
+
+ push @{ $self->{job_errors} }, $msg;
+ $::lxdebug->message(LXDebug->WARN(), 'ConvertTimeRecordings: ' . $msg) if $dbg;