DBConnect Caching: rollback nur bei Handles ohne AutoCommit
[kivitendo-erp.git] / SL / CVar.pm
1 package CVar;
2
3 use strict;
4
5 use List::MoreUtils qw(any);
6 use List::Util qw(first);
7 use Scalar::Util qw(blessed);
8 use Data::Dumper;
9
10 use SL::DBUtils;
11 use SL::MoreCommon qw(listify);
12
13 sub get_configs {
14   $main::lxdebug->enter_sub();
15
16   my $self     = shift;
17   my %params   = @_;
18
19   my $myconfig = \%main::myconfig;
20   my $form     = $main::form;
21
22   my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
23
24   my ($where, @values);
25   if ($params{module}) {
26     $where = 'WHERE module = ?';
27     push @values, $params{module};
28   }
29
30   my $query    = <<SQL;
31     SELECT *, date_trunc('seconds', localtimestamp) AS current_timestamp
32     FROM custom_variable_configs $where ORDER BY sortkey
33 SQL
34
35   $::form->{CVAR_CONFIGS} = {} unless 'HASH' eq ref $::form->{CVAR_CONFIGS};
36   if (!$::form->{CVAR_CONFIGS}->{$params{module}}) {
37     my $configs  = selectall_hashref_query($form, $dbh, $query, @values);
38
39     foreach my $config (@{ $configs }) {
40       if ($config->{type} eq 'select') {
41         $config->{OPTIONS} = [ map { { 'value' => $_ } } split(m/\#\#/, $config->{options}) ];
42
43       } elsif ($config->{type} eq 'number') {
44         $config->{precision} = $1 if ($config->{options} =~ m/precision=(\d+)/i);
45
46       } elsif ($config->{type} eq 'textfield') {
47         $config->{width}  = 30;
48         $config->{height} =  5;
49         $config->{width}  = $1 if ($config->{options} =~ m/width=(\d+)/i);
50         $config->{height} = $1 if ($config->{options} =~ m/height=(\d+)/i);
51
52       } elsif ($config->{type} eq 'text') {
53         $config->{maxlength} = $1 if ($config->{options} =~ m/maxlength=(\d+)/i);
54
55       }
56
57       $self->_unpack_flags($config);
58
59       my $cvar_config = SL::DB::CustomVariableConfig->new(id => $config->{id})->load;
60       @{$config->{'partsgroups'}} = map {$_->id} @{$cvar_config->partsgroups};
61
62     }
63     $::form->{CVAR_CONFIGS}->{$params{module}} = $configs;
64   }
65
66   $main::lxdebug->leave_sub();
67
68   return $::form->{CVAR_CONFIGS}->{$params{module}};
69 }
70
71 sub _unpack_flags {
72   $main::lxdebug->enter_sub();
73
74   my $self   = shift;
75   my $config = shift;
76
77   foreach my $flag (split m/:/, $config->{flags}) {
78     if ($flag =~ m/(.*?)=(.*)/) {
79       $config->{"flag_${1}"}    = $2;
80     } else {
81       $config->{"flag_${flag}"} = 1;
82     }
83   }
84
85   $main::lxdebug->leave_sub();
86 }
87
88 sub get_custom_variables {
89   $main::lxdebug->enter_sub();
90
91   my $self     = shift;
92   my %params   = @_;
93
94   Common::check_params(\%params, qw(module));
95
96   my $myconfig = \%main::myconfig;
97   my $form     = $main::form;
98
99   my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
100
101   my $sub_module = $params{sub_module} ? $params{sub_module} : '';
102
103   my $q_var    =
104     qq|SELECT text_value, timestamp_value, timestamp_value::date AS date_value, number_value, bool_value
105        FROM custom_variables
106        WHERE (config_id = ?) AND (trans_id = ?) AND (sub_module = ?)|;
107   my $h_var    = prepare_query($form, $dbh, $q_var);
108
109   my $custom_variables = $self->get_configs(module => $params{module});
110
111   foreach my $cvar (@{ $custom_variables }) {
112     if ($cvar->{type} eq 'textfield') {
113       $cvar->{width}  = 30;
114       $cvar->{height} =  5;
115
116       $cvar->{width}  = $1 if ($cvar->{options} =~ m/width=(\d+)/i);
117       $cvar->{height} = $1 if ($cvar->{options} =~ m/height=(\d+)/i);
118
119     } elsif ($cvar->{type} eq 'text') {
120       $cvar->{maxlength} = $1 if ($cvar->{options} =~ m/maxlength=(\d+)/i);
121
122     } elsif ($cvar->{type} eq 'number') {
123       $cvar->{precision} = $1 if ($cvar->{options} =~ m/precision=(\d+)/i);
124
125     } elsif ($cvar->{type} eq 'select') {
126       $cvar->{OPTIONS} = [ map { { 'value' => $_ } } split(m/\#\#/, $cvar->{options}) ];
127     }
128
129     my ($act_var, $valid);
130     if ($params{trans_id}) {
131       my @values = (conv_i($cvar->{id}), conv_i($params{trans_id}), $sub_module);
132
133       do_statement($form, $h_var, $q_var, @values);
134       $act_var = $h_var->fetchrow_hashref();
135
136       $valid = $self->get_custom_variables_validity(config_id => $cvar->{id}, trans_id => $params{trans_id});
137     } else {
138       $valid = !$cvar->{flag_defaults_to_invalid};
139     }
140
141     if ($act_var) {
142       $cvar->{value} = $cvar->{type} eq 'date'      ? $act_var->{date_value}
143                      : $cvar->{type} eq 'timestamp' ? $act_var->{timestamp_value}
144                      : $cvar->{type} eq 'number'    ? $act_var->{number_value}
145                      : $cvar->{type} eq 'customer'  ? $act_var->{number_value}
146                      : $cvar->{type} eq 'vendor'    ? $act_var->{number_value}
147                      : $cvar->{type} eq 'part'      ? $act_var->{number_value}
148                      : $cvar->{type} eq 'bool'      ? $act_var->{bool_value}
149                      :                                $act_var->{text_value};
150       $cvar->{valid} = $valid;
151     } else {
152       $cvar->{valid} = $valid // 1;
153
154       if ($cvar->{type} eq 'date') {
155         if ($cvar->{default_value} eq 'NOW') {
156           $cvar->{value} = $cvar->{current_date};
157         } else {
158           $cvar->{value} = $cvar->{default_value};
159         }
160
161       } elsif ($cvar->{type} eq 'timestamp') {
162         if ($cvar->{default_value} eq 'NOW') {
163           $cvar->{value} = $cvar->{current_timestamp};
164         } else {
165           $cvar->{value} = $cvar->{default_value};
166         }
167
168       } elsif ($cvar->{type} eq 'bool') {
169         $cvar->{value} = $cvar->{default_value} * 1;
170
171       } elsif ($cvar->{type} eq 'number') {
172         $cvar->{value} = $cvar->{default_value} * 1 if ($cvar->{default_value} ne '');
173
174       } else {
175         $cvar->{value} = $cvar->{default_value};
176       }
177     }
178
179     if ($cvar->{type} eq 'number') {
180       $cvar->{value} = $form->format_amount($myconfig, $cvar->{value} * 1, $cvar->{precision});
181     } elsif ($cvar->{type} eq 'customer') {
182       require SL::DB::Customer;
183       $cvar->{value} = SL::DB::Manager::Customer->find_by(id => $cvar->{value} * 1);
184     } elsif ($cvar->{type} eq 'vendor') {
185       require SL::DB::Vendor;
186       $cvar->{value} = SL::DB::Manager::Vendor->find_by(id => $cvar->{value} * 1);
187     } elsif ($cvar->{type} eq 'part') {
188       require SL::DB::Part;
189       $cvar->{value} = SL::DB::Manager::Part->find_by(id => $cvar->{value} * 1);
190     }
191   }
192
193   $h_var->finish();
194
195   $main::lxdebug->leave_sub();
196
197   return $custom_variables;
198 }
199
200 sub save_custom_variables {
201   $main::lxdebug->enter_sub();
202
203   my $self     = shift;
204   my %params   = @_;
205
206   Common::check_params(\%params, qw(module trans_id variables));
207
208   my $myconfig = \%main::myconfig;
209   my $form     = $main::form;
210
211   my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
212
213   my @configs  = $params{configs} ? @{ $params{configs} } : grep { $_->{module} eq $params{module} } @{ CVar->get_configs() };
214
215   my $query    =
216     qq|DELETE FROM custom_variables
217        WHERE (trans_id  = ?)
218          AND (config_id IN (SELECT DISTINCT id
219                             FROM custom_variable_configs
220                             WHERE module = ?))|;
221   my @values   = (conv_i($params{trans_id}), $params{module});
222
223   if ($params{sub_module}) {
224     $query .= qq| AND (sub_module = ?)|;
225     push @values, $params{sub_module};
226   }
227
228   do_query($form, $dbh, $query, @values);
229
230   $query  =
231     qq|INSERT INTO custom_variables (config_id, sub_module, trans_id, bool_value, timestamp_value, text_value, number_value)
232        VALUES                       (?,         ?,          ?,        ?,          ?,               ?,          ?)|;
233   my $sth = prepare_query($form, $dbh, $query);
234
235   foreach my $config (@configs) {
236     my @values = (conv_i($config->{id}), "$params{sub_module}", conv_i($params{trans_id}));
237
238     my $value  = $params{variables}->{"$params{name_prefix}cvar_$config->{name}$params{name_postfix}"};
239
240     if (($config->{type} eq 'text') || ($config->{type} eq 'textfield') || ($config->{type} eq 'select')) {
241       push @values, undef, undef, $value, undef;
242
243     } elsif (($config->{type} eq 'date') || ($config->{type} eq 'timestamp')) {
244       push @values, undef, conv_date($value), undef, undef;
245
246     } elsif ($config->{type} eq 'number') {
247       push @values, undef, undef, undef, conv_i($form->parse_amount($myconfig, $value));
248
249     } elsif ($config->{type} eq 'bool') {
250       push @values, $value ? 't' : 'f', undef, undef, undef;
251     } elsif (any { $config->{type} eq $_ } qw(customer vendor part)) {
252       push @values, undef, undef, undef, $value * 1;
253     }
254
255     do_statement($form, $sth, $query, @values);
256
257     if ($params{save_validity}) {
258       my $valid_index = "$params{name_prefix}cvar_$config->{name}$params{name_postfix}_valid";
259       $self->save_custom_variables_validity(trans_id  => $params{trans_id},
260                                             config_id => $config->{id},
261                                             validity  => ($params{variables}{$valid_index} || $params{always_valid} ? 1 : 0)
262                                            );
263     }
264   }
265
266   $sth->finish();
267
268   $dbh->commit() unless $params{dbh};
269
270   $main::lxdebug->leave_sub();
271 }
272
273 sub render_inputs {
274   $main::lxdebug->enter_sub(2);
275
276   my $self     = shift;
277   my %params   = @_;
278
279   Common::check_params(\%params, qw(variables));
280
281   my $myconfig = \%main::myconfig;
282   my $form     = $main::form;
283
284   my %options  = ( name_prefix           => "$params{name_prefix}",
285                    name_postfix          => "$params{name_postfix}",
286                    hide_non_editable     => $params{hide_non_editable},
287                    show_disabled_message => $params{show_disabled_message},
288                  );
289
290   # should this cvar be filtered by partsgroups?
291   foreach my $var (@{ $params{variables} }) {
292     if ($var->{flag_partsgroup_filter}) {
293       if (!$params{partsgroup_id} || (!grep {$params{partsgroup_id} == $_} @{ $var->{partsgroups} })) {
294         $var->{partsgroup_filtered} = 1;
295       }
296     }
297
298     $var->{HTML_CODE} = $form->parse_html_template('amcvar/render_inputs',     { var => $var, %options });
299     $var->{VALID_BOX} = $form->parse_html_template('amcvar/render_checkboxes', { var => $var, %options });
300   }
301
302   $main::lxdebug->leave_sub(2);
303 }
304
305 sub render_search_options {
306   $main::lxdebug->enter_sub();
307
308   my $self     = shift;
309   my %params   = @_;
310
311   Common::check_params(\%params, qw(variables));
312
313   my $myconfig = \%main::myconfig;
314   my $form     = $main::form;
315
316   $params{hidden_cvar_filters} = $myconfig->{hide_cvar_search_options};
317
318   $params{include_prefix}   = 'l_' unless defined($params{include_prefix});
319   $params{include_value}  ||= '1';
320   $params{filter_prefix}  ||= '';
321
322   my $filter  = $form->parse_html_template('amcvar/search_filter',  \%params);
323   my $include = $form->parse_html_template('amcvar/search_include', \%params);
324
325   $main::lxdebug->leave_sub();
326
327   return ($filter, $include);
328 }
329
330 sub build_filter_query {
331   $main::lxdebug->enter_sub();
332
333   my $self     = shift;
334   my %params   = @_;
335
336   Common::check_params(\%params, qw(module trans_id_field filter));
337
338   my $myconfig = \%main::myconfig;
339   my $form     = $main::form;
340
341   my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
342
343   my $configs  = $self->get_configs(%params);
344
345   my (@where, @values);
346
347   foreach my $config (@{ $configs }) {
348     next unless ($config->{searchable});
349
350     my $name = "cvar_$config->{name}";
351
352     my (@sub_values, @sub_where, $not);
353
354     if (($config->{type} eq 'text') || ($config->{type} eq 'textfield')) {
355       next unless ($params{filter}->{$name});
356
357       push @sub_where,  qq|cvar.text_value ILIKE ?|;
358       push @sub_values, '%' . $params{filter}->{$name} . '%'
359
360     } elsif ($config->{type} eq 'select') {
361       next unless ($params{filter}->{$name});
362
363       push @sub_where,  qq|cvar.text_value = ?|;
364       push @sub_values, $params{filter}->{$name};
365
366     } elsif (($config->{type} eq 'date') || ($config->{type} eq 'timestamp')) {
367       my $name_from = "${name}_from";
368       my $name_to   = "${name}_to";
369
370       if ($params{filter}->{$name_from}) {
371         push @sub_where,  qq|cvar.timestamp_value >= ?|;
372         push @sub_values, conv_date($params{filter}->{$name_from});
373       }
374
375       if ($params{filter}->{$name_to}) {
376         push @sub_where,  qq|cvar.timestamp_value <= ?|;
377         push @sub_values, conv_date($params{filter}->{$name_to});
378       }
379
380     } elsif ($config->{type} eq 'number') {
381       next if ($params{filter}->{$name} eq '');
382
383       my $f_op = $params{filter}->{"${name}_qtyop"};
384
385       my $op;
386       if ($f_op eq '==') {
387         $op  = '=';
388
389       } elsif ($f_op eq '=/=') {
390         $not = 'NOT';
391         $op  = '<>';
392
393       } elsif ($f_op eq '<') {
394         $not = 'NOT';
395         $op  = '>=';
396
397       } elsif ($f_op eq '<=') {
398         $not = 'NOT';
399         $op  = '>';
400
401       } elsif (($f_op eq '>') || ($f_op eq '>=')) {
402         $op  = $f_op;
403
404       } else {
405         $op  = '=';
406       }
407
408       push @sub_where,  qq|cvar.number_value $op ?|;
409       push @sub_values, $form->parse_amount($myconfig, $params{filter}->{$name});
410
411     } elsif ($config->{type} eq 'bool') {
412       next unless ($params{filter}->{$name});
413
414       $not = 'NOT' if ($params{filter}->{$name} eq 'no');
415       push @sub_where,  qq|COALESCE(cvar.bool_value, false) = TRUE|;
416     } elsif (any { $config->{type} eq $_ } qw(customer vendor)) {
417       next unless $params{filter}->{$name};
418
419       my $table = $config->{type};
420       push @sub_where, qq|cvar.number_value * 1 IN (SELECT id FROM $table WHERE name ILIKE ?)|;
421       push @sub_values, "%$params{filter}->{$name}%";
422     } elsif ($config->{type} eq 'part') {
423       next unless $params{filter}->{$name};
424
425       push @sub_where, qq|cvar.number_value * 1 IN (SELECT id FROM parts WHERE partnumber ILIKE ?)|;
426       push @sub_values, "%$params{filter}->{$name}%";
427     }
428
429     if (@sub_where) {
430       add_token(\@sub_where, \@sub_values, col => 'cvar.sub_module', val => $params{sub_module} || '');
431
432       push @where,
433         qq|$not EXISTS(
434              SELECT cvar.id
435              FROM custom_variables cvar
436              LEFT JOIN custom_variable_configs cvarcfg ON (cvar.config_id = cvarcfg.id)
437              WHERE (cvarcfg.module = ?)
438                AND (cvarcfg.id     = ?)
439                AND (cvar.trans_id  = $params{trans_id_field})
440                AND | . join(' AND ', map { "($_)" } @sub_where) . qq|)|;
441       push @values, $params{module}, conv_i($config->{id}), @sub_values;
442     }
443   }
444
445   my $query = join ' AND ', @where;
446
447   $main::lxdebug->leave_sub();
448
449   return ($query, @values);
450 }
451
452 sub add_custom_variables_to_report {
453   $main::lxdebug->enter_sub();
454
455   my $self      = shift;
456   my %params    = @_;
457
458   Common::check_params(\%params, qw(module trans_id_field column_defs data configs));
459
460   my $myconfig  = \%main::myconfig;
461   my $form      = $main::form;
462   my $locale    = $main::locale;
463
464   my $dbh       = $params{dbh} || $form->get_standard_dbh($myconfig);
465
466   my $configs   = [ grep { $_->{includeable} && $params{column_defs}->{"cvar_$_->{name}"}->{visible} } @{ $params{configs} } ];
467
468   if (!scalar(@{ $params{data} }) || ! scalar(@{ $configs })) {
469     $main::lxdebug->leave_sub();
470     return;
471   }
472
473   # allow sub_module to be a coderef or a fixed value
474   if (ref $params{sub_module} ne 'CODE') {
475     my $sub_module = "$params{sub_module}";
476     $params{sub_module} = sub { $sub_module };
477   }
478
479   my %cfg_map   = map { $_->{id} => $_ } @{ $configs };
480   my @cfg_ids   = keys %cfg_map;
481
482   my $query     =
483     qq|SELECT text_value, timestamp_value, timestamp_value::date AS date_value, number_value, bool_value, config_id
484        FROM custom_variables
485        WHERE (config_id IN (| . join(', ', ('?') x scalar(@cfg_ids)) . qq|))
486          AND (trans_id = ?)
487          AND (sub_module = ?)|;
488   my $sth       = prepare_query($form, $dbh, $query);
489
490   foreach my $row (@{ $params{data} }) {
491     do_statement($form, $sth, $query, @cfg_ids, conv_i($row->{$params{trans_id_field}}), $params{sub_module}->($row));
492
493     while (my $ref = $sth->fetchrow_hashref()) {
494       my $cfg = $cfg_map{$ref->{config_id}};
495
496       $row->{"cvar_$cfg->{name}"} =
497           $cfg->{type} eq 'date'      ? $ref->{date_value}
498         : $cfg->{type} eq 'timestamp' ? $ref->{timestamp_value}
499         : $cfg->{type} eq 'number'    ? $form->format_amount($myconfig, $ref->{number_value} * 1, $cfg->{precision})
500         : $cfg->{type} eq 'customer'  ? (SL::DB::Manager::Customer->find_by(id => 1*$ref->{number_value}) || SL::DB::Customer->new)->name
501         : $cfg->{type} eq 'vendor'    ? (SL::DB::Manager::Vendor->find_by(id => 1*$ref->{number_value})   || SL::DB::Vendor->new)->name
502         : $cfg->{type} eq 'part'      ? (SL::DB::Manager::Part->find_by(id => 1*$ref->{number_value})     || SL::DB::Part->new)->partnumber
503         : $cfg->{type} eq 'bool'      ? ($ref->{bool_value} ? $locale->text('Yes') : $locale->text('No'))
504         :                               $ref->{text_value};
505     }
506   }
507
508   $sth->finish();
509
510   $main::lxdebug->leave_sub();
511 }
512
513 sub get_field_format_list {
514   $main::lxdebug->enter_sub();
515
516   my $self          = shift;
517   my %params        = @_;
518
519   Common::check_params(\%params, qw(module));
520
521   my $myconfig      = \%main::myconfig;
522   my $form          = $main::form;
523
524   my $dbh           = $params{dbh} || $form->get_standard_dbh($myconfig);
525
526   my $configs       = $self->get_configs(%params);
527
528   my $date_fields   = [];
529   my $number_fields = {};
530
531   foreach my $config (@{ $configs }) {
532     my $name = "$params{prefix}cvar_$config->{name}";
533
534     if ($config->{type} eq 'date') {
535       push @{ $date_fields }, $name;
536
537     } elsif ($config->{type} eq 'number') {
538       $number_fields->{$config->{precision}} ||= [];
539       push @{ $number_fields->{$config->{precision}} }, $name;
540     }
541   }
542
543   $main::lxdebug->leave_sub();
544
545   return ($date_fields, $number_fields);
546 }
547
548 sub save_custom_variables_validity {
549   $main::lxdebug->enter_sub();
550
551   my $self     = shift;
552   my %params   = @_;
553
554   Common::check_params(\%params, qw(config_id trans_id validity));
555
556   my $myconfig = \%main::myconfig;
557   my $form     = $main::form;
558
559   my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
560
561   my (@where, @values);
562   add_token(\@where, \@values, col => "config_id", val => $params{config_id}, esc => \&conv_i);
563   add_token(\@where, \@values, col => "trans_id",  val => $params{trans_id},  esc => \&conv_i);
564
565   my $where = scalar @where ? "WHERE " . join ' AND ', @where : '';
566   my $query = qq|DELETE FROM custom_variables_validity $where|;
567
568   do_query($form, $dbh, $query, @values);
569
570   $query  =
571     qq|INSERT INTO custom_variables_validity (config_id, trans_id)
572        VALUES                                (?,         ?       )|;
573   my $sth = prepare_query($form, $dbh, $query);
574
575   unless ($params{validity}) {
576     foreach my $config_id (listify($params{config_id})) {
577       foreach my $trans_id (listify($params{trans_id})) {
578         do_statement($form, $sth, $query, conv_i($config_id), conv_i($trans_id));
579       }
580     }
581   }
582
583   $sth->finish();
584
585   $dbh->commit() unless $params{dbh};
586
587   $main::lxdebug->leave_sub();
588 }
589
590 sub get_custom_variables_validity {
591   $main::lxdebug->enter_sub(2);
592
593   my $self     = shift;
594   my %params   = @_;
595
596   Common::check_params(\%params, qw(config_id trans_id));
597
598   my $myconfig = \%main::myconfig;
599   my $form     = $main::form;
600
601   my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
602
603   my $query    = qq|SELECT id FROM custom_variables_validity WHERE config_id = ? AND trans_id = ? LIMIT 1|;
604
605   my ($invalid) = selectfirst_array_query($form, $dbh, $query, conv_i($params{config_id}), conv_i($params{trans_id}));
606
607   $main::lxdebug->leave_sub(2);
608
609   return !$invalid;
610 }
611
612 sub custom_variables_validity_by_trans_id {
613   $main::lxdebug->enter_sub(2);
614
615   my $self     = shift;
616   my %params   = @_;
617
618   return sub { 0 } unless $params{trans_id};
619
620   my $myconfig = \%main::myconfig;
621   my $form     = $main::form;
622
623   my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
624
625   my $query    = qq|SELECT DISTINCT config_id FROM custom_variables_validity WHERE trans_id = ?|;
626
627   my %invalids = map { +($_->{config_id} => 1) } selectall_hashref_query($form, $dbh, $query, $params{trans_id});
628
629   $main::lxdebug->leave_sub(2);
630
631   return sub { !$invalids{+shift} };
632 }
633
634 sub parse {
635   my ($self, $value, $config) = @_;
636
637   return $::form->parse_amount(\%::myconfig, $value)          if $config->{type} eq 'number';
638   return DateTime->from_lxoffice($value)                      if $config->{type} eq 'date';
639   return !ref $value ? SL::DB::Manager::Customer->find_by(id => $value * 1) : $value  if $config->{type} eq 'customer';
640   return !ref $value ? SL::DB::Manager::Vendor->find_by(id => $value * 1)   : $value  if $config->{type} eq 'vendor';
641   return !ref $value ? SL::DB::Manager::Part->find_by(id => $value * 1)     : $value  if $config->{type} eq 'part';
642   return $value;
643 }
644
645 sub format_to_template {
646   my ($self, $value, $config) = @_;
647   # stupid template expects everything formated. except objects
648   # do not use outside of print routines for legacy templates
649
650   return $::form->format_amount(\%::myconfig, $value) if $config->{type} eq 'number';
651   return $value->to_lxoffice if $config->{type} eq 'date' && blessed $value && $value->can('to_lxoffice');
652   return $value;
653 }
654
655 sub get_non_editable_ic_cvars {
656   $main::lxdebug->enter_sub(2);
657   my $self     = shift;
658   my %params   = @_;
659
660   Common::check_params(\%params, qw(form dbh row sub_module may_converted_from));
661   my $form               = $params{form};
662   my $dbh                = $params{dbh};
663   my $row                = $params{row};
664   my $sub_module         = $params{sub_module};
665   my $may_converted_from = $params{may_converted_from};
666
667   my $cvars;
668   if (! $form->{"${sub_module}_id_${row}"}) {
669     my $conv_from = 0;
670     foreach (@{ $may_converted_from }) {
671       if ($form->{"converted_from_${_}_id_$row"}) {
672         $cvars = CVar->get_custom_variables(dbh        => $dbh,
673                                             module     => 'IC',
674                                             sub_module => $_,
675                                             trans_id   => $form->{"converted_from_${_}_id_$row"},
676                                            );
677         $conv_from = 1;
678         last;
679       }
680     }
681     # get values for CVars from master data for new items
682     if (!$conv_from) {
683       $cvars = CVar->get_custom_variables(dbh      => $dbh,
684                                           module   => 'IC',
685                                           trans_id => $form->{"id_$row"},
686                                          );
687     }
688   } else {
689     # get values for CVars from custom_variables for existing items
690     $cvars = CVar->get_custom_variables(dbh        => $dbh,
691                                         module     => 'IC',
692                                         sub_module => $sub_module,
693                                         trans_id   => $form->{"${sub_module}_id_${row}"},
694                                        );
695   }
696   # map only non-editable CVars to form
697   foreach (@{ $cvars }) {
698     next if $_->{flag_editable};
699     $form->{"ic_cvar_$_->{name}_$row"} = $_->{value}
700   }
701
702   $main::lxdebug->leave_sub(2);
703 }
704
705 1;
706
707 __END__
708
709 =head1 NAME
710
711 SL::CVar.pm - Custom Variables module
712
713 =head1 SYNOPSIS
714
715   # dealing with configs
716
717   my $all_configs = CVar->get_configs()
718
719   # dealing with custom vars
720
721   CVar->get_custom_variables(module => 'ic')
722
723 =head2 VALIDITY
724
725 Suppose the following scenario:
726
727 You have a lot of parts in your database, and a set of properties cofigured. Now not every part has every of these properties, some combinations will just make no sense. In order to clean up your inputs a bit, you want to mark certain combinations as invalid, blocking them from modification and possibly display.
728
729 Validity is assumed. If you modify validity, you actually save B<invalidity>.
730 Invalidity is saved as a function of config_id, and the trans_id
731
732 In the naive way, disable an attribute for a specific id (simple)
733
734 =cut