]> wagnertech.de Git - mfinanz.git/blobdiff - SL/BackgroundJob/ConvertTimeRecordings.pm
Zeiterfassung: Parameter f. Konvertierung in params übergeben
[mfinanz.git] / SL / BackgroundJob / ConvertTimeRecordings.pm
index 8f6a32949f38913d0060a35a6866ba75b3107c94..dbbf12c1a249e412bd06d318ea7e2fd1d6778576 100644 (file)
@@ -9,13 +9,27 @@ use SL::DB::TimeRecording;
 
 use SL::Locale::String qw(t8);
 
+use Carp;
 use DateTime;
 use Try::Tiny;
 
 sub create_job {
   $_[0]->create_standard_job('7 3 1 * *'); # every first day of month at 03:07
 }
-
+use Rose::Object::MakeMethods::Generic (
+ 'scalar --get_set_init' => [ qw(rounding link_project) ],
+);
+
+# valid parameters -> better as class members with rose generic set/get
+my %valid_params = (
+              from_date => '',
+              to_date   => '',
+              customernumbers => '',
+              part_id => '',
+              rounding => 1,
+              link_project => 0,
+              project_id => '',
+             );
 
 #
 # If job does not throw an error,
@@ -31,7 +45,19 @@ sub run {
   $data = $db_obj->data_as_hash if $db_obj;
 
   $self->{$_} = [] for qw(job_errors);
+
+  # check user input param names
+  foreach my $param (keys %{ $data }) {
+    die "Not a valid parameter: $param" unless exists $valid_params{$param};
+  }
+
+  # TODO check user input param values - (defaults are assigned later)
+  # 1- If there are any customer numbers check if they refer to valid customers
+  #    otherwise croak and do nothing
+  # 2 .. n Same applies for other params if used at all (rounding -> 0|1  link_project -> 0|1)
+
   # from/to date from data. Defaults to begining and end of last month.
+  # TODO get/set see above
   my $from_date;
   my $to_date;
   # handle errors with a catch handler
@@ -53,14 +79,20 @@ sub run {
                                                                                  or => [booked => 0, booked => undef],
                                                                                  %customer_where],
                                                                 with_objects => ['customer']);
+
+  # no time recordings at all ? -> better exit here before iterating a empty hash
+  # return undef or message unless ref $time_recordings->[0] eq SL::DB::Manager::TimeRecording;
+
   my %time_recordings_by_customer_id;
   push @{ $time_recordings_by_customer_id{$_->customer_id} }, $_ for @$time_recordings;
 
+  my %convert_params = map { $_ => $data->{$_} } qw(rounding link_project part_id project_id);
+
   my @donumbers;
   foreach my $customer_id (keys %time_recordings_by_customer_id) {
     my $do;
     if (!eval {
-      $do = SL::DB::DeliveryOrder->new_from_time_recordings($time_recordings_by_customer_id{$customer_id});
+      $do = SL::DB::DeliveryOrder->new_from_time_recordings($time_recordings_by_customer_id{$customer_id}, %convert_params);
       1;
     }) {
       $::lxdebug->message(LXDebug->WARN(),
@@ -93,12 +125,23 @@ sub run {
   # die if errors exists
   if (@{ $self->{job_errors} }) {
     $msg  .= ' ' . t8('The following errors occurred:');
+    $msg  .= ' ';
     $msg  .= join "\n", @{ $self->{job_errors} };
-    die $msg;
+    die $msg . "\n";
   }
   return $msg;
 }
 
+# inits
+
+sub init_rounding {
+  1
+}
+
+sub init_link_project {
+  0
+}
+
 1;
 
 # possible data
@@ -125,6 +168,8 @@ C<SL::DB::DeliveryOrder-E<gt>new_from_time_recordings>).
 =head1 CONFIGURATION
 
 Some data can be provided to configure this backgroung job.
+If there is user data and it cannot be validated the background job
+returns a error messages.
 
 =over 4
 
@@ -156,6 +201,45 @@ Example (format depends on your settings):
 
 customernumbers: [c1,22332,334343]
 
+=item C<part_id>
+
+The part id of a time based service which should be used to
+book the times. If not set the clients config defaults is used.
+
+=item C<rounding>
+
+If set the 0 no rounding of the times will be done otherwise
+the times will be rounded up to th full quarters of an hour,
+ie. 0.25h 0.5h 0.75h 1.25h ...
+Defaults to rounding true (1).
+
+=item C<link_project>
+
+If set the job tries to find a previous Order with the current
+customer and project number and tries to do as much automatic
+workflow processing as the UI.
+Defaults to off. If set to true (1) the job will fail if there
+is no Sales Orders which qualifies as a predecessor.
+Conditions for a predeccesor:
+
+ * Global project_id must match time_recording.project_id OR data.project_id
+ * Customer name must match time_recording.customer_id OR data.customernumbers
+ * The sales order must have at least one or more time related services
+ * The Project needs to be valid and active
+
+The job doesn't care if the Sales Order is already delivered or closed.
+If the sales order is overdelivered some organisational stuff needs to be done.
+The sales order may also already be closed, ie the amount is fully billed, but
+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<project_id>
+
+Use this project_id instead of the project_id in the time recordings.
+
 =back
 
 =head1 AUTHOR