1 package SL::BackgroundJob::UpdateExchangerates;
6 use parent qw(SL::BackgroundJob::Base);
8 use SL::DB::Exchangerate;
11 use Rose::Object::MakeMethods::Generic (
12 scalar => [ qw(worker) ],
17 my $self_or_class = shift;
19 my $package = ref($self_or_class) || $self_or_class;
20 $package =~ s/SL::BackgroundJob:://;
22 my $cron_spec = ('35 4 * * *'); # every day at 4:35 am
31 my %params = (cron_spec => $cron_spec,
34 package_name => $package,
37 my $job = SL::DB::Manager::BackgroundJob->find_by(package_name => $params{package_name});
39 $job = SL::DB::BackgroundJob->new(%params)->update_next_run_at;
41 $job->assign_attributes(%params)->update_next_run_at;
48 my ($self, $db_obj) = @_;
50 my $params = $db_obj->data_as_hash;
52 return $::locale->text('Parameter module must be given.') if !$params->{module};
54 # instanciate worker for given module
57 my $worker_class = 'SL::BackgroundJob::UpdateExchangerates::' . $params->{module};
58 eval "require $worker_class";
59 $self->worker($worker_class->new(options => $params->{options}));
62 $error = $::locale->text('Could not load class #1 (#2): "#3"', $params->{module}, 'SL/BackgroundJob/UpdateExchangerates', $@);
64 return $error if $error;
66 my $default_currency = SL::DB::Currency->new(id => $::instance_conf->get_currency_id)->load;
67 my $transdate = DateTime->today_local;
70 # collect currencies that should be updated
71 foreach my $currency (@{SL::DB::Manager::Currency->get_all_sorted}) {
72 next if $currency->id == $default_currency->id;
74 my $exrate = SL::DB::Manager::Exchangerate->find_by(transdate => $transdate, currency_id => $currency->id);
77 push @rates_to_update, {from => $default_currency,
80 push @rates_to_update, {from => $default_currency,
87 push @rates_to_update, {from => $default_currency,
92 push @rates_to_update, {from => $default_currency,
98 return "updated: 0" if scalar @rates_to_update == 0;
101 $self->worker->update_rates(\@rates_to_update);
105 foreach my $rate (@rates_to_update) {
106 my $exrate = SL::DB::Manager::Exchangerate->find_by_or_create(transdate => $transdate, currency_id => $rate->{to}->id);
108 next if !$exrate; # should not happen
111 $exrate->transdate($transdate) if !$exrate->transdate;
112 $exrate->currency($rate->{to}) if !$exrate->currency;
114 my $method = $rate->{dir};
115 if (!$exrate->$method) {
116 $exrate->$method($rate->{rate});
118 push @updated, $rate->{to}->name . " ($method: " . $rate->{rate} . ")";
123 return "updated: " . scalar @updated . ': ' . join ', ', @updated;
136 SL::BackgroundJob::UpdateExchangerates - Background job for updating the
137 exchange rates for currencies
141 This background job can update all exchange rates for currencies if the rates
142 are not already present for the current date.
143 A worker module must be given as data to the job (see documentation at
144 SL::BackgroundJob::UpdateExchangerates::Base and
145 SL::BackgroundJob::UpdateExchangerates::* as examples).
146 The worker will be used to get the actual rates from some kind of service.
147 Options to the worker can be given as data to the background job:
149 module: FromOpenexchangerates
157 Better error handling / error notification
161 Bernd Bleßmann E<lt>bernd@kivitendo-premium.deE<gt>