From 64fab360c5a719c6cad86df702efcf4e544778cf Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bernd=20Ble=C3=9Fmann?= Date: Tue, 29 Dec 2020 19:24:20 +0100 Subject: [PATCH] Zeiterfassung: Hintergrund-Job zum Umwandeln in Lieferscheine --- SL/BackgroundJob/ALL.pm | 1 + SL/BackgroundJob/ConvertTimeRecordings.pm | 152 ++++++++++++++++++++++ locale/de/all | 1 + locale/en/all | 1 + 4 files changed, 155 insertions(+) create mode 100644 SL/BackgroundJob/ConvertTimeRecordings.pm diff --git a/SL/BackgroundJob/ALL.pm b/SL/BackgroundJob/ALL.pm index 938e62eab..2e637cd1f 100644 --- a/SL/BackgroundJob/ALL.pm +++ b/SL/BackgroundJob/ALL.pm @@ -6,6 +6,7 @@ use SL::BackgroundJob::Base; use SL::BackgroundJob::BackgroundJobCleanup; use SL::BackgroundJob::CleanBackgroundJobHistory; use SL::BackgroundJob::CloseProjectsBelongingToClosedSalesOrders; +use SL::BackgroundJob::ConvertTimeRecordings; use SL::BackgroundJob::CreatePeriodicInvoices; use SL::BackgroundJob::FailedBackgroundJobsReport; diff --git a/SL/BackgroundJob/ConvertTimeRecordings.pm b/SL/BackgroundJob/ConvertTimeRecordings.pm new file mode 100644 index 000000000..6af9ae94a --- /dev/null +++ b/SL/BackgroundJob/ConvertTimeRecordings.pm @@ -0,0 +1,152 @@ +package SL::BackgroundJob::ConvertTimeRecordings; + +use strict; + +use parent qw(SL::BackgroundJob::Base); + +use SL::DB::DeliveryOrder; +use SL::DB::TimeRecording; + +use SL::Locale::String qw(t8); +use DateTime; + +sub create_job { + $_[0]->create_standard_job('7 3 1 * *'); # every first day of month at 03:07 +} + + +# +# If job does not throw an error, +# success in background_job_histories is 'success'. +# It is 'failure' otherwise. +# +# Return value goes to result in background_job_histories. +# +sub run { + my ($self, $db_obj) = @_; + + my $data; + $data = $db_obj->data_as_hash if $db_obj; + + # from/to date from data. Defaults to begining and end of last month. + my $from_date; + my $to_date; + $from_date = DateTime->from_kivitendo($data->{from_date}) if $data->{from_date}; + $to_date = DateTime->from_kivitendo($data->{to_date}) if $data->{to_date}; + $from_date ||= DateTime->new( day => 1, month => DateTime->today_local->month, year => DateTime->today_local->year)->subtract(months => 1); + $to_date ||= DateTime->last_day_of_month(month => DateTime->today_local->month, year => DateTime->today_local->year)->subtract(months => 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) + + my %customer_where; + %customer_where = ('customer.customernumber' => $data->{customernumbers}) if 'ARRAY' eq ref $data->{customernumbers}; + + my $time_recordings = SL::DB::Manager::TimeRecording->get_all(where => [end_time => { ge_lt => [ $from_date, $to_date ]}, + or => [booked => 0, booked => undef], + %customer_where], + with_objects => ['customer']); + my %time_recordings_by_customer_id; + push @{ $time_recordings_by_customer_id{$_->customer_id} }, $_ for @$time_recordings; + + my @donumbers; + my $has_warnings; + 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}); + 1; + }) { + $::lxdebug->message(LXDebug->WARN(), + "ConvertTimeRecordings: creating delivery order failed ($@) for time recording ids " . join ', ', map { $_->id } @{$time_recordings_by_customer_id{$customer_id}}); + $has_warnings = 1; + } + + if ($do) { + if (!SL::DB->client->with_transaction(sub { + $do->save; + $_->update_attributes(booked => 1) for @{$time_recordings_by_customer_id{$customer_id}}; + 1; + })) { + $::lxdebug->message(LXDebug->WARN(), + "ConvertTimeRecordings: saving delivery order failed for time recording ids " . join ', ', map { $_->id } @{$time_recordings_by_customer_id{$customer_id}}); + $has_warnings = 1; + } else { + push @donumbers, $do->donumber; + } + } + } + + my $msg = t8('Number of deliveryorders created:'); + $msg .= ' '; + $msg .= scalar @donumbers; + $msg .= ' ('; + $msg .= join ', ', @donumbers; + $msg .= ').'; + $msg .= ' ' . t8('There are Warnings.') if $has_warnings; + return $msg; +} + +1; + +# possible data +# from_date: 01.12.2020 +# to_date: 15.12.2020 +# customernumbers: [1,2,3] +__END__ + +=pod + +=encoding utf8 + +=head1 NAME + +SL::BackgroundJob::ConvertTimeRecordings - Convert time recording +entries into delivery orders + +=head1 SYNOPSIS + +Get all time recording entries for the given period and customer numbers +and create delivery ordes out of that (using +Cnew_from_time_recordings>). + +=head1 CONFIGURATION + +Some data can be provided to configure this backgroung job. + +=over 4 + +=item C + +The date from which on time recordings should be collected. It defaults +to the first day of the previous month. + +Example (format depends on your settings): + +from_date: 01.12.2020 + +=item C + +The date till which time recordings should be collected. It defaults +to the last day of the previous month. + +Example (format depends on your settings): + +to_date: 15.12.2020 + +=item C + +An array with the customer numbers for which time recordings should +be collected. If not given, time recordings for customers are +collected. This is the default. + +Example (format depends on your settings): + +customernumbers: [c1,22332,334343] + +=back + +=head1 AUTHOR + +Bernd Bleßmann Ebernd@kivitendo-premium.deE + +=cut diff --git a/locale/de/all b/locale/de/all index 616379e41..5332f7055 100755 --- a/locale/de/all +++ b/locale/de/all @@ -3633,6 +3633,7 @@ $self->{texts} = { 'There are #1 unfinished follow-ups of which #2 are due.' => 'Es gibt #1 Wiedervorlage(n), von denen #2 fällig ist/sind.', 'There are Bins defined in your Inventory.' => 'Unter Stammdaten/Waren sind Lagerplätze definiert.', 'There are Bins defined in your master data.' => 'Unter Stammdaten/Waren sind Lagerplätze defininert', + 'There are Warnings.' => 'Es gibt Warnungen.', 'There are bookings to the account 3803 after 01.01.2007. If you didn\'t change this account manually to 19% the bookings are probably incorrect.' => 'Das Konto 3803 wurde nach dem 01.01.2007 bebucht. Falls Sie dieses Konto nicht manuell auf 19% gestellt haben sind die Buchungen wahrscheinlich mit falscher Umsatzsteuer gebucht worden.', 'There are currently no delivery orders, or none matches your filter conditions.' => 'kein Lieferschein vorhanden', 'There are currently no open invoices, or none matches your filter conditions.' => 'Es gibt momentan keine offenen Rechnungen, oder keine erfüllt die Filterkriterien.', diff --git a/locale/en/all b/locale/en/all index e427f3cc5..5d55a8478 100644 --- a/locale/en/all +++ b/locale/en/all @@ -3631,6 +3631,7 @@ $self->{texts} = { 'There are #1 unfinished follow-ups of which #2 are due.' => '', 'There are Bins defined in your Inventory.' => '', 'There are Bins defined in your master data.' => '', + 'There are Warnings.' => '', 'There are bookings to the account 3803 after 01.01.2007. If you didn\'t change this account manually to 19% the bookings are probably incorrect.' => '', 'There are currently no delivery orders, or none matches your filter conditions.' => '', 'There are currently no open invoices, or none matches your filter conditions.' => '', -- 2.20.1