7e16a1772a2753168d70cab732c308042e9fe04e
[kivitendo-erp.git] / SL / Controller / BackgroundJob.pm
1 package SL::Controller::BackgroundJob;
2
3 use strict;
4
5 use parent qw(SL::Controller::Base);
6
7 use SL::BackgroundJob::Base;
8 use SL::Controller::Helper::GetModels;
9 use SL::DB::BackgroundJob;
10 use SL::Helper::Flash;
11 use SL::Locale::String;
12 use SL::System::TaskServer;
13
14 use Rose::Object::MakeMethods::Generic
15 (
16   'scalar --get_set_init' => [ qw(task_server back_to models background_job) ],
17 );
18
19 __PACKAGE__->run_before('check_auth');
20 __PACKAGE__->run_before('check_task_server');
21
22 #
23 # actions
24 #
25
26 sub action_list {
27   my ($self) = @_;
28
29   $self->setup_list_action_bar;
30   $self->render('background_job/list',
31                 title           => $::locale->text('Background jobs'),
32                 BACKGROUND_JOBS => $self->models->get,
33                 MODELS          => $self->models);
34 }
35
36 sub action_new {
37   my ($self) = @_;
38
39   $self->background_job(SL::DB::BackgroundJob->new(cron_spec => '* * * * *',  package_name => 'Test')) unless $self->background_job;
40   $self->setup_form_action_bar;
41   $self->render('background_job/form',
42                 title       => $::locale->text('Create a new background job'),
43                 JOB_CLASSES => [ SL::BackgroundJob::Base->get_known_job_classes ]);
44 }
45
46 sub action_edit {
47   my ($self) = @_;
48
49   $self->setup_form_action_bar;
50   $self->render('background_job/form',
51                 title       => $::locale->text('Edit background job'),
52                 JOB_CLASSES => [ SL::BackgroundJob::Base->get_known_job_classes ]);
53 }
54
55 sub action_edit_as_new {
56   my ($self) = @_;
57
58   delete $::form->{background_job}->{id};
59   $self->background_job(SL::DB::BackgroundJob->new(%{ $::form->{background_job} }));
60   $self->action_new;
61 }
62
63 sub action_show {
64   my ($self) = @_;
65
66   if ($::request->type eq 'json') {
67     $self->render(\ SL::JSON::to_json($self->background_job->as_tree), { type => 'json' });
68   } else {
69     $self->action_edit;
70   }
71 }
72
73 sub action_create {
74   my ($self) = @_;
75
76   $self->background_job(SL::DB::BackgroundJob->new);
77   $self->create_or_update;
78 }
79
80 sub action_update {
81   my ($self) = @_;
82   $self->create_or_update;
83 }
84
85 sub action_destroy {
86   my ($self) = @_;
87
88   if (eval { $self->background_job->delete; 1; }) {
89     flash_later('info',  $::locale->text('The background job has been deleted.'));
90   } else {
91     flash_later('error', $::locale->text('The background job could not be destroyed.'));
92   }
93
94   $self->redirect_to($self->back_to);
95 }
96
97 sub action_save_and_execute {
98   my ($self) = @_;
99
100   $self->background_job(SL::DB::BackgroundJob->new) if !$self->background_job;
101   return unless $self->create_or_update;
102   $self->action_execute;
103 }
104
105 sub action_execute {
106   my ($self) = @_;
107
108   my $history = $self->background_job->run;
109   if ($history->status eq 'success') {
110     flash_later('info', $::locale->text('The background job was executed successfully.'));
111   } else {
112     flash_later('error', $::locale->text('There was an error executing the background job.'));
113   }
114
115   $self->redirect_to(controller => 'BackgroundJobHistory',
116                      action     => 'show',
117                      id         => $history->id,
118                      back_to    => $self->url_for(action => 'edit', id => $self->background_job->id));
119 }
120
121 #
122 # filters
123 #
124
125 sub check_auth {
126   $::auth->assert('admin');
127 }
128
129 #
130 # helpers
131 #
132
133 sub create_or_update {
134   my $self   = shift;
135   my $return = shift;
136   my $is_new = !$self->background_job->id;
137   my $params = delete($::form->{background_job}) || { };
138
139   $self->background_job->assign_attributes(%{ $params });
140
141   my @errors = $self->background_job->validate;
142
143   if (@errors) {
144     flash('error', @errors);
145     $self->render('background_job/form', title => $is_new ? $::locale->text('Create a new background job') : $::locale->text('Edit background job'));
146     return;
147   }
148
149   $self->background_job->update_next_run_at;
150   $self->background_job->save;
151
152   flash_later('info', $is_new ? $::locale->text('The background job has been created.') : $::locale->text('The background job has been saved.'));
153   return if $return;
154
155   $self->redirect_to($self->back_to);
156 }
157
158 sub init_background_job {
159   return $::form->{id} ? SL::DB::BackgroundJob->new(id => $::form->{id})->load : undef;
160 }
161
162 sub init_task_server {
163   return SL::System::TaskServer->new;
164 }
165
166 sub check_task_server {
167   my ($self) = @_;
168   flash('warning', $::locale->text('The task server does not appear to be running.')) if !$self->task_server->is_running;
169 }
170
171 sub init_back_to {
172   my ($self) = @_;
173   return $::form->{back_to} || $self->url_for(action => 'list');
174 }
175
176 sub init_models {
177   SL::Controller::Helper::GetModels->new(
178     controller => $_[0],
179     filtered => 0,
180     sorted => {
181       package_name => t8('Package name'),
182       type         => t8('Execution type'),
183       active       => t8('Active'),
184       cron_spec    => t8('Execution schedule'),
185       last_run_at  => t8('Last run at'),
186       next_run_at  => t8('Next run at'),
187     },
188     query => [
189       package_name => [ SL::BackgroundJob::Base->get_known_job_classes ],
190     ],
191   );
192 }
193
194 sub setup_list_action_bar {
195   my ($self) = @_;
196
197   for my $bar ($::request->layout->get('actionbar')) {
198     $bar->add(
199       link => [
200         t8('Add'),
201         link      => $self->url_for(action => 'new'),
202         accesskey => 'enter',
203       ],
204       link => [
205         t8('Server control'),
206         link => $self->url_for(controller => 'TaskServer', action => 'show'),
207       ],
208       link => [
209         t8('Job history'),
210         link => $self->url_for(controller => 'BackgroundJobHistory', action => 'list'),
211       ],
212     );
213   }
214 }
215
216 sub setup_form_action_bar {
217   my ($self) = @_;
218
219   my $is_new = !$self->background_job->id;
220
221   for my $bar ($::request->layout->get('actionbar')) {
222     $bar->add(
223       combobox => [
224         action => [
225           t8('Save'),
226           submit    => [ '#form', { action => 'BackgroundJob/' . ($is_new ? 'create' : 'update') } ],
227           accesskey => 'enter',
228         ],
229         action => [
230           t8('Save and execute'),
231           submit => [ '#form', { action => 'BackgroundJob/save_and_execute' } ],
232         ],
233         action => [
234           t8('Use as new'),
235           submit   => [ '#form', { action => 'BackgroundJob/edit_as_new' } ],
236           disabled => $is_new ? t8('The object has not been saved yet.') : undef,
237         ],
238       ], # end of combobox "Save"
239
240       action => [
241         t8('Delete'),
242         submit   => [ '#form', { action => 'BackgroundJob/destroy' } ],
243         confirm  => t8('Do you really want to delete this object?'),
244         disabled => $is_new ? t8('This object has not been saved yet.') : undef,
245       ],
246
247       link => [
248         t8('Abort'),
249         link => $self->url_for(action => 'list'),
250       ],
251
252       link => [
253         t8('Job history'),
254         link     => $self->url_for(controller => 'BackgroundJobHistory', action => 'list', 'filter.package_name:substr::ilike' => $self->background_job->package_name),
255         disabled => $is_new ? t8('This object has not been saved yet.') : undef,
256       ],
257     );
258   }
259 }
260
261 1;