]> wagnertech.de Git - mfinanz.git/blob - SL/Controller/CsvImport/Helper/Consistency.pm
restart apache2 in postinst
[mfinanz.git] / SL / Controller / CsvImport / Helper / Consistency.pm
1 package SL::Controller::CsvImport::Helper::Consistency;
2
3 use strict;
4
5 use Data::Dumper;
6 use SL::DB::Default;
7 use SL::DB::Currency;
8 use SL::DB::TaxZone;
9 use SL::DB::Pricegroup;
10 use SL::DB::Project;
11 use SL::DB::Department;
12
13 use SL::Helper::Csv::Error;
14
15 use parent qw(Exporter);
16 our @EXPORT = qw(check_currency check_taxzone check_pricegroup check_project check_department check_customer_vendor handle_salesman handle_employee);
17
18 #
19 # public functions
20 #
21
22 sub check_currency {
23   my ($self, $entry, %params) = @_;
24
25   my $object = $entry->{object};
26
27   # Check whether or not currency ID is valid.
28   if ($object->currency_id && ! _currencies_by($self)->{id}->{ $object->currency_id }) {
29     push @{ $entry->{errors} }, $::locale->text('Error: Invalid currency');
30     return 0;
31   }
32
33   # Map name to ID if given.
34   if (!$object->currency_id && $entry->{raw_data}->{currency}) {
35     my $currency = _currencies_by($self)->{name}->{  $entry->{raw_data}->{currency} };
36     if (!$currency) {
37       push @{ $entry->{errors} }, $::locale->text('Error: Invalid currency');
38       return 0;
39     }
40
41     $object->currency_id($currency->id);
42
43     # register currency_id for method copying later
44     $self->clone_methods->{currency_id} = 1;
45   }
46
47   # Set default currency if none was given and take_default is true.
48   $object->currency_id(_default_currency_id($self)) if !$object->currency_id and $params{take_default};
49
50   $entry->{raw_data}->{currency_id} = $object->currency_id;
51
52   return 1;
53 }
54
55 sub check_taxzone {
56   my ($self, $entry, %params) = @_;
57
58   my $object = $entry->{object};
59
60   # Check whether the CSV contains the parameters taxzone_id or taxzone, and
61   # check them for validity.
62   # If one of them was given, but is invalid, return an error
63
64   # If neither was given:
65   # a) if param take_default was set, use the taxzone_id from the profile
66   #    (customer/vendor import)
67   # b) if param take_default was not set, do nothing, return without error, and
68   #    taxzone_id may be set later by other means (order import uses cv settings)
69
70
71   # if $object->taxzone_id is defined (from CSV line), check if it is valid
72   if ($object->taxzone_id && ! _taxzones_by($self)->{id}->{ $object->taxzone_id }) {
73     push @{ $entry->{errors} }, $::locale->text('Error: Invalid tax zone');
74     return 0;
75   }
76
77   # if there was no taxzone_id in CSV, but a taxzone entry, check if it is a
78   # valid taxzone and set the id
79   if (!$object->taxzone_id && $entry->{raw_data}->{taxzone}) {
80     my $taxzone = _taxzones_by($self)->{description}->{ $entry->{raw_data}->{taxzone} };
81     if (!$taxzone) {
82       push @{ $entry->{errors} }, $::locale->text('Error: Invalid tax zone');
83       return 0;
84     }
85
86     $object->taxzone_id($taxzone->id);
87   }
88
89   # The take_default option should only be used for the customer/vendor case,
90   # as the default for imported orders is the taxzone according to the customer
91   # or vendor
92   # if neither taxzone_id nor taxzone were defined, use the default taxzone as
93   # defined from the import settings (a default/fallback taxzone that is to be
94   # used will always be selected)
95
96   if (!$object->taxzone_id && $params{take_default}) {
97     # my $default_id = $self->settings->{'default_taxzone'};
98     my $default_id = $self->controller->profile->get('default_taxzone');
99     $default_id ||= _default_taxzone_id($self);
100     $object->taxzone_id($default_id);
101     # check if default taxzone_id is valid just to be sure
102     if (! _taxzones_by($self)->{id}->{ $object->taxzone_id }) {
103       push @{ $entry->{errors} }, $::locale->text('Error with default taxzone');
104       return 0;
105     }
106   };
107
108   # for the order import at this stage $object->taxzone_id may still not be
109   # defined, in this case the customer/vendor taxzone will be used later
110   if ( defined $object->taxzone_id ) {
111     $entry->{info_data}->{taxzone} = _taxzones_by($self)->{id}->{ $object->taxzone_id }->description;
112   };
113
114   return 1;
115 }
116
117 sub check_pricegroup {
118   my ($self, $entry) = @_;
119
120   my $object = $entry->{object};
121
122   # Check whether or not pricegroup ID is valid.
123   if ($object->pricegroup_id && !_pricegroups_by($self)->{id}->{ $object->pricegroup_id }) {
124     push @{ $entry->{errors} }, $::locale->text('Error: Invalid price group');
125     return 0;
126   }
127
128   # Map pricegroup to ID if given.
129   if (!$object->pricegroup_id && $entry->{raw_data}->{pricegroup}) {
130     my $pricegroup = _pricegroups_by($self)->{pricegroup}->{ $entry->{raw_data}->{pricegroup} };
131     if (!$pricegroup) {
132       push @{ $entry->{errors} }, $::locale->text('Error: Invalid price group');
133       return 0;
134     }
135
136     $object->pricegroup_id($pricegroup->id);
137   }
138
139   return 1;
140 }
141
142 sub check_project {
143   my ($self, $entry, %params) = @_;
144
145   my $id_column          = ($params{global} ? 'global' : '') . 'project_id';
146   my $number_column      = ($params{global} ? 'global' : '') . 'projectnumber';
147   my $description_column = ($params{global} ? 'global' : '') . 'project';
148
149   my $object = $entry->{object};
150
151   # Check whether or not project ID is valid.
152   if ($object->$id_column) {
153     if (! _projects_by($self)->{id}->{ $object->$id_column }) {
154       push @{ $entry->{errors} }, $::locale->text('Error: Invalid project');
155       return 0;
156     } else {
157       $entry->{info_data}->{$number_column} = _projects_by($self)->{id}->{ $object->$id_column }->description;
158     };
159   }
160
161   my $proj;
162   # Map number to ID if given.
163   if (!$object->$id_column && $entry->{raw_data}->{$number_column}) {
164     $proj = _projects_by($self)->{projectnumber}->{ $entry->{raw_data}->{$number_column} };
165     if (!$proj) {
166       push @{ $entry->{errors} }, $::locale->text('Error: Invalid project');
167       return 0;
168     }
169
170     $object->$id_column($proj->id);
171   }
172
173   # Map description to ID if given.
174   if (!$object->$id_column && $entry->{raw_data}->{$description_column}) {
175     $proj = _projects_by($self)->{description}->{ $entry->{raw_data}->{$description_column} };
176     if (!$proj) {
177       push @{ $entry->{errors} }, $::locale->text('Error: Invalid project');
178       return 0;
179     }
180
181     $object->$id_column($proj->id);
182   }
183
184   if ( $proj ) {
185     $entry->{info_data}->{"$description_column"} = $proj->description;
186     $entry->{info_data}->{"$number_column"}      = $proj->projectnumber;
187   };
188
189   return 1;
190 }
191
192 sub check_department {
193   my ($self, $entry) = @_;
194
195   my $object = $entry->{object};
196
197   # Check whether or not department ID was assigned and is valid.
198   if ($object->department_id) {
199     if (!_departments_by($self)->{id}->{ $object->department_id }) {
200       push @{ $entry->{errors} }, $::locale->text('Error: Invalid department');
201       return 0;
202     } else {
203       # add department description as well, more feedback for user
204       $entry->{info_data}->{department} = _departments_by($self)->{id}->{ $object->department_id }->description;
205     };
206   }
207
208   # Map department description to ID if given.
209   if (!$object->department_id && $entry->{raw_data}->{department}) {
210     $entry->{info_data}->{department} = $entry->{raw_data}->{department};
211     my $dep = _departments_by($self)->{description}->{ $entry->{raw_data}->{department} };
212     if (!$dep) {
213       push @{ $entry->{errors} }, $::locale->text('Error: Invalid department');
214       return 0;
215     }
216     $entry->{info_data}->{department} = $dep->description;
217     $object->department_id($dep->id);
218   }
219
220   return 1;
221 }
222
223 # ToDo: salesman by name
224 sub handle_salesman {
225   my ($self, $entry) = @_;
226
227   my $object = $entry->{object};
228   my $vc_obj;
229   $vc_obj    = SL::DB::Customer->new(id => $object->customer_id)->load if $object->can('customer') && $object->customer_id;
230   $vc_obj    = SL::DB::Vendor->new(id   => $object->vendor_id)->load   if (!$vc_obj && $object->can('vendor') && $object->vendor_id);
231
232   # salesman from customer/vendor or login if not given
233   if (!$object->salesman) {
234     if ($vc_obj && $vc_obj->salesman_id) {
235       $object->salesman(SL::DB::Manager::Employee->find_by(id => $vc_obj->salesman_id));
236     } else {
237       $object->salesman(SL::DB::Manager::Employee->current);
238     }
239   }
240 }
241
242 # ToDo: employee by name
243 sub handle_employee {
244   my ($self, $entry) = @_;
245
246   my $object = $entry->{object};
247
248   # employee from front end if not given
249   if (!$object->employee_id) {
250     $object->employee_id($self->controller->{employee_id});
251   }
252   # employee from login if not given
253   if (!$object->employee_id) {
254     $object->employee_id(SL::DB::Manager::Employee->current->id) if SL::DB::Manager::Employee->current;
255   }
256 }
257
258
259
260 #
261 # private functions
262 #
263
264 sub _currencies_by {
265   my ($self) = @_;
266
267   return { map { my $col = $_; ( $col => { map { ( $_->$col => $_ ) } @{ _all_currencies($self) } } ) } qw(id name) };
268 }
269
270 sub _all_currencies {
271   my ($self) = @_;
272
273   return SL::DB::Manager::Currency->get_all;
274 }
275
276 sub _default_currency_id {
277   my ($self) = @_;
278
279   return SL::DB::Default->get->currency_id;
280 }
281
282 sub _default_taxzone_id {
283   my ($self) = @_;
284
285   return SL::DB::Manager::TaxZone->get_all_sorted(query => [ obsolete => 0 ])->[0]->id;
286 }
287
288 sub _departments_by {
289   my ($self) = @_;
290
291   my $all_departments = SL::DB::Manager::Department->get_all;
292   return { map { my $col = $_; ( $col => { map { ( $_->$col => $_ ) } @{ $all_departments } } ) } qw(id description) };
293 }
294
295 sub _pricegroups_by {
296   my ($self) = @_;
297
298   my $all_pricegroups = SL::DB::Manager::Pricegroup->get_all;
299   return { map { my $col = $_; ( $col => { map { ( $_->$col => $_ ) } @{ $all_pricegroups } } ) } qw(id pricegroup) };
300 }
301
302 sub _projects_by {
303   my ($self) = @_;
304
305   my $all_projects = SL::DB::Manager::Project->get_all;
306   return { map { my $col = $_; ( $col => { map { ( $_->$col => $_ ) } @{ $all_projects } } ) } qw(id projectnumber description) };
307 }
308
309 sub _taxzones_by {
310   my ($self) = @_;
311
312   return { map { my $col = $_; ( $col => { map { ( $_->$col => $_ ) } @{ _all_taxzones($self) } } ) } qw(id description) };
313 }
314
315 sub _all_taxzones {
316   my ($self) = @_;
317
318   return SL::DB::Manager::TaxZone->get_all_sorted(query => [ obsolete => 0 ]);
319 }
320
321 1;