SimpleSystemSetting: Umstellung von »Abteilungen«
[kivitendo-erp.git] / SL / Controller / SimpleSystemSetting.pm
1 package SL::Controller::SimpleSystemSetting;
2
3 use strict;
4 use utf8;
5
6 use parent qw(SL::Controller::Base);
7
8 use SL::Helper::Flash;
9 use SL::Locale::String;
10 use SL::DB::Default;
11 use SL::System::Process;
12
13 use Rose::Object::MakeMethods::Generic (
14   scalar                  => [ qw(type config) ],
15   'scalar --get_set_init' => [ qw(defaults object all_objects class manager_class list_attributes list_url supports_reordering) ],
16 );
17
18 __PACKAGE__->run_before('check_type_and_auth');
19 __PACKAGE__->run_before('setup_javascript', only => [ qw(add create edit update delete) ]);
20
21 # Make locales.pl happy: $self->render("simple_system_setting/_default_form")
22
23 my %supported_types = (
24   bank_account => {
25     # Make locales.pl happy: $self->render("simple_system_setting/_bank_account_form")
26     class  => 'BankAccount',
27     titles => {
28       list => t8('Bank accounts'),
29       add  => t8('Add bank account'),
30       edit => t8('Edit bank account'),
31     },
32     list_attributes => [
33       { method => 'name',                                      title => t8('Name'), },
34       { method => 'iban',                                      title => t8('IBAN'), },
35       { method => 'bank',                                      title => t8('Bank'), },
36       { method => 'bank_code',                                 title => t8('Bank code'), },
37       { method => 'bic',                                       title => t8('BIC'), },
38       { method => 'reconciliation_starting_date_as_date',      title => t8('Date'),    align => 'right' },
39       { method => 'reconciliation_starting_balance_as_number', title => t8('Balance'), align => 'right' },
40     ],
41   },
42
43   department => {
44     class  => 'Department',
45     titles => {
46       list => t8('Departments'),
47       add  => t8('Add department'),
48       edit => t8('Edit department'),
49     },
50   },
51
52   part_classification => {
53     # Make locales.pl happy: $self->render("simple_system_setting/_part_classification_form")
54     class  => 'PartClassification',
55     titles => {
56       list => t8('Part classifications'),
57       add  => t8('Add part classification'),
58       edit => t8('Edit part classification'),
59     },
60     list_attributes => [
61       { title => t8('Description'),       formatter => sub { t8($_[0]->description) } },
62       { title => t8('Type abbreviation'), formatter => sub { t8($_[0]->abbreviation) } },
63       { title => t8('Used for Purchase'), formatter => sub { $_[0]->used_for_purchase ? t8('yes') : t8('no') } },
64       { title => t8('Used for Sale'),     formatter => sub { $_[0]->used_for_sale     ? t8('yes') : t8('no') } },
65       { title => t8('Report separately'), formatter => sub { $_[0]->report_separate   ? t8('yes') : t8('no') } },
66     ],
67   },
68
69   parts_group => {
70     # Make locales.pl happy: $self->render("simple_system_setting/_parts_group_form")
71     class  => 'PartsGroup',
72     titles => {
73       list => t8('Partsgroups'),
74       add  => t8('Add partsgroup'),
75       edit => t8('Edit partsgroup'),
76     },
77     list_attributes => [
78       { method => 'partsgroup', title => t8('Description') },
79       { method => 'obsolete',   title => t8('Obsolete'), formatter => sub { $_[0]->obsolete ? t8('yes') : t8('no') } },
80     ],
81   },
82
83   price_factor => {
84     # Make locales.pl happy: $self->render("simple_system_setting/_price_factor_form")
85     class  => 'PriceFactor',
86     titles => {
87       list => t8('Price Factors'),
88       add  => t8('Add Price Factor'),
89       edit => t8('Edit Price Factor'),
90     },
91     list_attributes => [
92       { method => 'description',      title => t8('Description') },
93       { method => 'factor_as_number', title => t8('Factor'), align => 'right' },
94     ],
95   },
96
97   pricegroup => {
98     # Make locales.pl happy: $self->render("simple_system_setting/_pricegroup_form")
99     class  => 'Pricegroup',
100     titles => {
101       list => t8('Pricegroups'),
102       add  => t8('Add pricegroup'),
103       edit => t8('Edit pricegroup'),
104     },
105     list_attributes => [
106       { method => 'pricegroup', title => t8('Description') },
107       { method => 'obsolete',   title => t8('Obsolete'), formatter => sub { $_[0]->obsolete ? t8('yes') : t8('no') } },
108     ],
109   },
110 );
111
112 my @default_list_attributes = (
113   { method => 'description', title => t8('Description') },
114 );
115
116 #
117 # actions
118 #
119
120 sub action_list {
121   my ($self) = @_;
122
123   $self->render('simple_system_setting/list', title => $self->config->{titles}->{list});
124 }
125
126 sub action_new {
127   my ($self) = @_;
128
129   $self->object($self->class->new);
130   $self->render_form(title => $self->config->{titles}->{add});
131 }
132
133 sub action_edit {
134   my ($self) = @_;
135
136   $self->render_form(title => $self->config->{titles}->{edit});
137 }
138
139 sub action_create {
140   my ($self) = @_;
141
142   $self->object($self->class->new);
143   $self->create_or_update;
144 }
145
146 sub action_update {
147   my ($self) = @_;
148
149   $self->create_or_update;
150 }
151
152 sub action_delete {
153   my ($self) = @_;
154
155   if ($self->object->can('orphaned') && !$self->object->orphaned) {
156     flash_later('error', t8('The object is in use and cannot be deleted.'));
157
158   } elsif ( eval { $self->object->delete; 1; } ) {
159     flash_later('info',  t8('The object has been deleted.'));
160
161   } else {
162     flash_later('error', t8('The object is in use and cannot be deleted.'));
163   }
164
165   $self->redirect_to($self->list_url);
166 }
167
168 sub action_reorder {
169   my ($self) = @_;
170
171   $self->class->reorder_list(@{ $::form->{object_id} || [] });
172   $self->render(\'', { type => 'json' });
173 }
174
175 #
176 # filters
177 #
178
179 sub check_type_and_auth {
180   my ($self) = @_;
181
182   $self->type($::form->{type});
183   $self->config($supported_types{$self->type}) || die "Unsupported type";
184
185   $::auth->assert($self->config->{auth} || 'config');
186
187   my $pm = (map { s{::}{/}g; "${_}.pm" } $self->class)[0];
188   require $pm;
189
190   my $setup = "setup_" . $self->type;
191   $self->$setup if $self->can($setup);
192
193   1;
194 }
195
196 sub setup_javascript {
197   $::request->layout->use_javascript("${_}.js") for qw(ckeditor/ckeditor ckeditor/adapters/jquery);
198 }
199
200 sub init_class               { "SL::DB::"          . $_[0]->config->{class}                  }
201 sub init_manager_class       { "SL::DB::Manager::" . $_[0]->config->{class}                  }
202 sub init_object              { $_[0]->class->new(id => $::form->{id})->load                  }
203 sub init_all_objects         { $_[0]->manager_class->get_all_sorted                          }
204 sub init_list_url            { $_[0]->url_for(action => 'list', type => $_[0]->type)         }
205 sub init_supports_reordering { $_[0]->class->new->can('reorder_list')                        }
206 sub init_defaults            { SL::DB::Default->get                                          }
207
208 sub init_list_attributes {
209   my ($self) = @_;
210
211   my $method = "list_attributes_" . $self->type;
212
213   return $self->$method if $self->can($method);
214   return $self->config->{list_attributes} // \@default_list_attributes;
215 }
216
217 #
218 # helpers
219 #
220
221 sub create_or_update {
222   my ($self) = @_;
223   my $is_new = !$self->object->id;
224
225   my $params = delete($::form->{object}) || { };
226
227   $self->object->assign_attributes(%{ $params });
228
229   my @errors;
230
231   push @errors, $self->object->validate if $self->object->can('validate');
232
233   if (@errors) {
234     flash('error', @errors);
235     return $self->render_form(title => $self->config->{titles}->{$is_new ? 'add' : 'edit'});
236   }
237
238   $self->object->save;
239
240   flash_later('info', $is_new ? t8('The object has been created.') : t8('The object has been saved.'));
241
242   $self->redirect_to($self->list_url);
243 }
244
245 sub render_form {
246   my ($self, %params) = @_;
247
248   my $sub_form_template = SL::System::Process->exe_dir . '/templates/webpages/simple_system_setting/_' . $self->type . '_form.html';
249
250   $self->render(
251     'simple_system_setting/form',
252     %params,
253     sub_form_template => (-f $sub_form_template ? $self->type : 'default'),
254   );
255 }
256
257 #
258 # type-specific helper functions
259 #
260
261 1;
262
263 __END__
264
265 =encoding utf-8
266
267 =head1 NAME
268
269 SL::Controller::SimpleSystemSettings — a common CRUD controller for
270 various settings in the "System" menu
271
272 =head1 AUTHOR
273
274 Moritz Bunkus <m.bunkus@linet-services.de>
275
276 =cut