Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 3bdd1cc0

Von Bernd Bleßmann vor mehr als 3 Jahren hinzugefügt

  • ID 3bdd1cc002af6dd1c0687adf12b1d13db1de073a
  • Vorgänger e7cbe943
  • Nachfolger a43aa9ac

Zeiterfassung: Konvertierung: Refoctored -> zentrale Prüfung der Parameter

Unterschiede anzeigen:

SL/BackgroundJob/ConvertTimeRecordings.pm
18 18
  $_[0]->create_standard_job('7 3 1 * *'); # every first day of month at 03:07
19 19
}
20 20
use Rose::Object::MakeMethods::Generic (
21
 'scalar'                => [ qw(data) ],
22
 'scalar --get_set_init' => [ qw(rounding link_order) ],
21
 'scalar'                => [ qw(params) ],
23 22
);
24 23

  
25
# valid parameters -> better as class members with rose generic set/get
26
my %valid_params = (
27
              from_date => '',
28
              to_date   => '',
29
              customernumbers => '',
30
              part_id => '',
31
              rounding => 1,
32
              link_order => 0,
33
              project_id => '',
34
             );
35

  
36 24
#
37 25
# If job does not throw an error,
38 26
# success in background_job_histories is 'success'.
......
43 31
sub run {
44 32
  my ($self, $db_obj) = @_;
45 33

  
46
  $self->data($db_obj->data_as_hash) if $db_obj;
34
  $self->initialize_params($db_obj->data_as_hash) if $db_obj;
47 35

  
48 36
  $self->{$_} = [] for qw(job_errors);
49 37

  
50
  # check user input param names
51
  foreach my $param (keys %{ $self->data }) {
52
    die "Not a valid parameter: $param" unless exists $valid_params{$param};
53
  }
54

  
55
  # TODO check user input param values - (defaults are assigned later)
56
  # 1- If there are any customer numbers check if they refer to valid customers
57
  #    otherwise croak and do nothing
58
  # 2 .. n Same applies for other params if used at all (rounding -> 0|1  link_order -> 0|1)
59

  
60
  # from/to date from data. Defaults to begining and end of last month.
61
  # TODO get/set see above
62
  my $from_date;
63
  my $to_date;
64
  $from_date   = DateTime->from_kivitendo($self->data->{from_date}) if $self->data->{from_date};
65
  $to_date     = DateTime->from_kivitendo($self->data->{to_date})   if $self->data->{to_date};
66

  
67
  # DateTime->from_kivitendo returns undef if the string cannot be parsed. Therefore test the result if it shopuld have been parsed.
68
  die 'Cannot convert date from string "' . $self->data->{from_date} . '"' if $self->data->{from_date} && !$from_date;
69
  die 'Cannot convert date to string "'   . $self->data->{to_date}   . '"' if $self->data->{to_date}   && !$to_date;
70

  
71
  $from_date ||= DateTime->new( day => 1,    month => DateTime->today_local->month, year => DateTime->today_local->year)->subtract(months => 1);
72
  $to_date   ||= DateTime->last_day_of_month(month => DateTime->today_local->month, year => DateTime->today_local->year)->subtract(months => 1);
73

  
74
  $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)
75

  
76 38
  my %customer_where;
77
  %customer_where = ('customer.customernumber' => $self->data->{customernumbers}) if 'ARRAY' eq ref $self->data->{customernumbers};
39
  %customer_where = ('customer_id' => $self->params->{customer_ids}) if scalar @{ $self->params->{customer_ids} };
78 40

  
79
  my $time_recordings = SL::DB::Manager::TimeRecording->get_all(where        => [date => { ge_lt => [ $from_date, $to_date ]},
41
  my $time_recordings = SL::DB::Manager::TimeRecording->get_all(where        => [date => { ge_lt => [ $self->params->{from_date}, $self->params->{to_date} ]},
80 42
                                                                                 or   => [booked => 0, booked => undef],
81 43
                                                                                 '!duration' => 0,
82 44
                                                                                 '!duration' => undef,
83
                                                                                 %customer_where],
84
                                                                with_objects => ['customer']);
45
                                                                                 %customer_where]);
85 46

  
86 47
  # no time recordings at all ? -> better exit here before iterating a empty hash
87 48
  # return undef or message unless ref $time_recordings->[0] eq SL::DB::Manager::TimeRecording;
88 49

  
89 50
  my @donumbers;
90 51

  
91
  if ($self->data->{link_order}) {
52
  if ($self->params->{link_order}) {
92 53
    my %time_recordings_by_order_id;
93 54
    my %orders_by_order_id;
94 55
    foreach my $tr (@$time_recordings) {
......
119 80
  return $msg;
120 81
}
121 82

  
122
# inits
83
# helper
84
sub initialize_params {
85
  my ($self, $data) = @_;
123 86

  
124
sub init_rounding {
125
  1
126
}
87
  # valid parameters with default values
88
  my %valid_params = (
89
    from_date       => DateTime->new( day => 1,    month => DateTime->today_local->month, year => DateTime->today_local->year)->subtract(months => 1)->to_kivitendo,
90
    to_date         => DateTime->last_day_of_month(month => DateTime->today_local->month, year => DateTime->today_local->year)->subtract(months => 1)->to_kivitendo,
91
    customernumbers => [],
92
    part_id         => undef,
93
    project_id      => undef,
94
    rounding        => 1,
95
    link_order      => 0,
96
  );
97

  
98

  
99
  # check user input param names
100
  foreach my $param (keys %$data) {
101
    die "Not a valid parameter: $param" unless exists $valid_params{$param};
102
  }
103

  
104
  $self->params(
105
    { map { ($_ => $data->{$_} // $valid_params{$_}) } keys %valid_params }
106
  );
127 107

  
128
sub init_link_order {
129
  0
108

  
109
  # convert date from string to object
110
  my $from_date;
111
  my $to_date;
112
  $from_date = DateTime->from_kivitendo($self->params->{from_date});
113
  $to_date   = DateTime->from_kivitendo($self->params->{to_date});
114
  # DateTime->from_kivitendo returns undef if the string cannot be parsed. Therefore test the result.
115
  die 'Cannot convert date from string "' . $self->params->{from_date} . '"' if !$from_date;
116
  die 'Cannot convert date to string "'   . $self->params->{to_date}   . '"' if !$to_date;
117

  
118
  $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)
119

  
120
  $self->params->{from_date} = $from_date;
121
  $self->params->{to_date}   = $to_date;
122

  
123

  
124
  # check if customernumbers are valid
125
  die 'Customer numbers must be given in an array' if 'ARRAY' ne ref $self->params->{customernumbers};
126

  
127
  my $customers = [];
128
  if (scalar @{ $self->params->{customernumbers} }) {
129
    $customers = SL::DB::Manager::Customer->get_all(where => [ customernumber => $self->params->{customernumbers},
130
                                                               or             => [obsolete => undef, obsolete => 0] ]);
131
  }
132
  die 'Not all customer numbers are valid' if scalar @$customers != scalar @{ $self->params->{customernumbers} };
133

  
134
  # return customer ids
135
  $self->params->{customer_ids} = [ map { $_->id } @$customers ];
136

  
137

  
138
  # check part
139
  if ($self->params->{part_id} && !SL::DB::Manager::Part->find_by(id => $self->params->{part_id},
140
                                                                  or => [obsolete => undef, obsolete => 0])) {
141
    die 'No valid part found by given part id';
142
  }
143

  
144

  
145
  # check project
146
  if ($self->params->{project_id} && !SL::DB::Manager::Project->find_by(id => $self->params->{project_id},
147
                                                                        active => 1, valid => 1)) {
148
    die 'No valid project found by given project id';
149
  }
150

  
151
  return $self->params;
130 152
}
131 153

  
132
# helper
133 154
sub convert_without_linking {
134 155
  my ($self, $time_recordings) = @_;
135 156

  
136 157
  my %time_recordings_by_customer_id;
137 158
  push @{ $time_recordings_by_customer_id{$_->customer_id} }, $_ for @$time_recordings;
138 159

  
139
  my %convert_params = map { $_ => $self->data->{$_} } qw(rounding link_order project_id);
140
  $convert_params{default_part_id} = $self->data->{part_id};
160
  my %convert_params = map { $_ => $self->params->{$_} } qw(rounding link_order project_id);
161
  $convert_params{default_part_id} = $self->params->{part_id};
141 162

  
142 163
  my @donumbers;
143 164
  foreach my $customer_id (keys %time_recordings_by_customer_id) {
......
173 194
sub convert_with_linking {
174 195
  my ($self, $time_recordings_by_order_id, $orders_by_order_id) = @_;
175 196

  
176
  my %convert_params = map { $_ => $self->data->{$_} } qw(rounding link_order project_id);
177
  $convert_params{default_part_id} = $self->data->{part_id};
197
  my %convert_params = map { $_ => $self->params->{$_} } qw(rounding link_order project_id);
198
  $convert_params{default_part_id} = $self->params->{part_id};
178 199

  
179 200
  my @donumbers;
180 201
  foreach my $related_order_id (keys %$time_recordings_by_order_id) {
......
241 262
    # check project
242 263
    my $project_id;
243 264
    #$project_id   = $self->overide_project_id;
244
    $project_id   = $self->data->{project_id};
265
    $project_id   = $self->params->{project_id};
245 266
    $project_id ||= $tr->project_id;
246 267
    #$project_id ||= $self->default_project_id;
247 268

  
......
296 317
  #$part_id   = $self->overide_part_id;
297 318
  $part_id ||= $tr->part_id;
298 319
  #$part_id ||= $self->default_part_id;
299
  $part_id ||= $self->data->{part_id};
320
  $part_id ||= $self->params->{part_id};
300 321

  
301 322
  if (!$part_id) {
302 323
    my $err_msg = 'ConvertTimeRecordings: searching related order failed for time recording id ' . $tr->id . ' : no part id';
t/background_job/convert_time_recordings.t
1
use Test::More tests => 28;
1
use Test::More tests => 34;
2 2

  
3 3
use strict;
4 4

  
......
283 283
)->save;
284 284

  
285 285
%data = (
286
  link_order => 1,
287
  from_date  => '01.04.2021',
288
  to_date    => '30.04.2021',
286
  link_order      => 1,
287
  from_date       => '01.04.2021',
288
  to_date         => '30.04.2021',
289
  customernumbers => [$customer->number],
289 290
);
290 291
$db_obj = SL::DB::BackgroundJob->new();
291 292
$db_obj->set_data(%data);
......
316 317
# are wrong params detected?
317 318
########################################
318 319
%data = (
319
  from_date  => 'x01.04.2021',
320
  from_date       => 'x01.04.2021',
320 321
);
321 322
$db_obj = SL::DB::BackgroundJob->new();
322 323
$db_obj->set_data(%data);
......
326 327
eval { $ret = $job->run($db_obj);  1; } or do {$err_msg = $@};
327 328
ok($err_msg =~ '^Cannot convert date from string', 'wrong date string detected');
328 329

  
330
#####
331

  
332
$customer = new_customer()->save;
333
%data = (
334
  customernumbers => ['a fantasy', $customer->number],
335
);
336

  
337
$db_obj = SL::DB::BackgroundJob->new();
338
$db_obj->set_data(%data);
339
$job    = SL::BackgroundJob::ConvertTimeRecordings->new;
340

  
341
$err_msg = '';
342
eval { $ret = $job->run($db_obj);  1; } or do {$err_msg = $@};
343
ok($err_msg =~ '^Not all customer numbers are valid', 'wrong customer number detected');
344

  
345
#####
346

  
347
%data = (
348
  customernumbers => '123',
349
);
350

  
351
$db_obj = SL::DB::BackgroundJob->new();
352
$db_obj->set_data(%data);
353
$job    = SL::BackgroundJob::ConvertTimeRecordings->new;
354

  
355
$err_msg = '';
356
eval { $ret = $job->run($db_obj);  1; } or do {$err_msg = $@};
357
ok($err_msg =~ '^Customer numbers must be given in an array', 'wrong customer number data type detected');
358

  
359
#####
360

  
361
%data = (
362
  part_id => '123',
363
);
364

  
365
$db_obj = SL::DB::BackgroundJob->new();
366
$db_obj->set_data(%data);
367
$job    = SL::BackgroundJob::ConvertTimeRecordings->new;
368

  
369
$err_msg = '';
370
eval { $ret = $job->run($db_obj);  1; } or do {$err_msg = $@};
371
ok($err_msg =~ '^No valid part found by given part id', 'invalid part id detected');
372

  
373
#####
374

  
375
$part = new_service(partnumber => 'Serv1', unit => 'Std', obsolete => 1)->save;
376
%data = (
377
  part_id => $part->id,
378
);
379

  
380
$db_obj = SL::DB::BackgroundJob->new();
381
$db_obj->set_data(%data);
382
$job    = SL::BackgroundJob::ConvertTimeRecordings->new;
383

  
384
$err_msg = '';
385
eval { $ret = $job->run($db_obj);  1; } or do {$err_msg = $@};
386
ok($err_msg =~ '^No valid part found by given part id', 'obsolete part detected');
387

  
388
#####
389

  
390
%data = (
391
  project_id => 123,
392
);
393

  
394
$db_obj = SL::DB::BackgroundJob->new();
395
$db_obj->set_data(%data);
396
$job    = SL::BackgroundJob::ConvertTimeRecordings->new;
397

  
398
$err_msg = '';
399
eval { $ret = $job->run($db_obj);  1; } or do {$err_msg = $@};
400
ok($err_msg =~ '^No valid project found by given project id', 'invalid project id detected');
401

  
402
#####
403

  
404
$project = create_project(projectnumber => 'p1', description => 'Project 1', valid => 0)->save;
405
%data = (
406
  project_id => $project->id,
407
);
408

  
409
$db_obj = SL::DB::BackgroundJob->new();
410
$db_obj->set_data(%data);
411
$job    = SL::BackgroundJob::ConvertTimeRecordings->new;
412

  
413
$err_msg = '';
414
eval { $ret = $job->run($db_obj);  1; } or do {$err_msg = $@};
415
ok($err_msg =~ '^No valid project found by given project id', 'invalid project detected');
416

  
417
#####
418

  
329 419
clear_up();
330 420

  
331 421

  

Auch abrufbar als: Unified diff