Eine Funktion zum "sicheren" Aufrufen von Unterfunktionen eingebaut, damit &{ $form...
[kivitendo-erp.git] / bin / mozilla / common.pl
1 #=====================================================================
2 # LX-Office ERP
3 # Copyright (C) 2004
4 # Based on SQL-Ledger Version 2.1.9
5 # Web http://www.lx-office.org
6 ######################################################################
7 #
8 # Stuff that can be used from other modules
9 #
10 ######################################################################
11
12 use SL::Form;
13 use YAML;
14
15 use SL::Common;
16
17 sub save_form {
18   $lxdebug->enter_sub();
19
20   my $old_form = YAML::Dump($form);
21   $old_form =~ s|!|!!|g;
22   $old_form =~ s|\n|!n|g;
23   $old_form =~ s|\r|!r|g;
24
25   $lxdebug->leave_sub();
26
27   return $old_form;
28 }
29
30 sub restore_form {
31   $lxdebug->enter_sub();
32
33   my ($old_form, $no_delete) = @_;
34
35   map({ delete($form->{$_}); } keys(%{$form})) unless ($no_delete);
36   $old_form =~ s|!r|\r|g;
37   $old_form =~ s|!n|\n|g;
38   $old_form =~ s|!!|!|g;
39   my $new_form = YAML::Load($old_form);
40   map({ $form->{$_} = $new_form->{$_}; } keys(%{$new_form}));
41
42   $lxdebug->leave_sub();
43 }
44
45 sub build_std_url {
46   $lxdebug->enter_sub();
47
48   my $url = "$form->{script}?";
49   my $first = 1;
50   foreach my $key ((qw(login password path), @_)) {
51     next unless ($key);
52     $url .= "&" unless ($first);
53     $first = 0;
54
55     if ($key =~ /=/) {
56       $url .= $key;
57     } else {
58       $url .= "${key}=" . E($form->{$key});
59     }
60   }
61
62   $lxdebug->leave_sub();
63
64   return $url;
65 }
66
67 sub select_employee {
68   $lxdebug->enter_sub();
69
70   my ($callback_sub, @employees) = @_;
71
72   if (0 == scalar(@employees)) {
73     @employees = SystemBrace->get_all_employees(\%myconfig, $form);
74   }
75
76   my $old_form = save_form();
77
78   $form->header();
79   print($form->parse_html_template("generic/select_employee",
80                                    { "EMPLOYEES" => \@employees,
81                                      "old_form" => $old_form,
82                                      "title" => $locale->text("Select an employee"),
83                                      "nextsub" => "select_employee_internal",
84                                      "callback_sub" => $callback_sub }));
85
86   $lxdebug->leave_sub();
87 }
88
89 sub select_employee_internal {
90   $lxdebug->enter_sub();
91
92   my ($new_id, $new_name, $callback_sub);
93
94   my $new_id = $form->{"new_id_" . $form->{"selection"}};
95   my $new_name = $form->{"new_name_" . $form->{"selection"}};
96   my $callback_sub = $form->{"callback_sub"};
97
98   restore_form($form->{"old_form"});
99
100   call_sub($callback_sub, $new_id, $new_name);
101
102   $lxdebug->leave_sub();
103 }
104
105 sub select_part {
106   $lxdebug->enter_sub();
107
108   my ($callback_sub, @parts) = @_;
109
110   my $remap_parts_id = 0;
111   if (defined($parts[0]->{"parts_id"}) && !defined($parts[0]->{"id"})) {
112     $remap_parts_id = 1;
113     map({ $_->{"id"} = $_->{"parts_id"}; } @parts);
114   }
115
116   my $remap_partnumber = 0;
117   if (defined($parts[0]->{"partnumber"}) && !defined($parts[0]->{"number"})) {
118     $remap_partnumber = 1;
119     map({ $_->{"number"} = $_->{"partnumber"}; } @parts);
120   }
121
122   my $has_charge = 0;
123   if (defined($parts[0]->{"chargenumber"})) {
124     $has_charge = 1;
125     map({ $_->{"has_charge"} = 1; } @parts);
126   }
127
128   my $old_form = save_form();
129
130   $form->header();
131   print($form->parse_html_template("generic/select_part",
132                                    { "PARTS" => \@parts,
133                                      "old_form" => $old_form,
134                                      "title" => $locale->text("Select a part"),
135                                      "nextsub" => "select_part_internal",
136                                      "callback_sub" => $callback_sub,
137                                      "has_charge" => $has_charge,
138                                      "remap_parts_id" => $remap_parts_id,
139                                      "remap_partnumber" => $remap_partnumber }));
140
141   $lxdebug->leave_sub();
142 }
143
144 sub select_part_internal {
145   $lxdebug->enter_sub();
146
147   my ($new_item, $callback_sub);
148
149   my $re = "^new_.*_" . $form->{"selection"};
150   map({
151     my $key = $_;
152     $key =~ s/^new_//;
153     $key =~ s/_\d+$//;
154     $new_item->{$key} = $form->{$_};
155   } grep(/$re/, keys(%{$form})));
156
157   if ($form->{"remap_parts_id"}) {
158     $new_item->{"parts_id"} = $new_item->{"id"};
159     delete($new_item->{"id"});
160   }
161   if ($form->{"remap_partnumber"}) {
162     $new_item->{"partnumber"} = $new_item->{"number"};
163     delete($new_item->{"number"});
164   }
165
166   my $callback_sub = $form->{"callback_sub"};
167
168   restore_form($form->{"old_form"});
169
170   call_sub($callback_sub, $new_item);
171
172   $lxdebug->leave_sub();
173 }
174
175 sub part_selection_internal {
176   $lxdebug->enter_sub();
177
178   $order_by = "description";
179   $order_by = $form->{"order_by"} if (defined($form->{"order_by"}));
180   $order_dir = 1;
181   $order_dir = $form->{"order_dir"} if (defined($form->{"order_dir"}));
182
183   $parts = Common->retrieve_parts(\%myconfig, $form, $order_by, $order_dir);
184   map({ $parts->[$_]->{"selected"} = $_ ? 0 : 1; } (0..$#{$parts}));
185   if (0 == scalar(@{$parts})) {
186     $form->show_generic_information($locale->text("No part was found matching the search parameters."));
187   } elsif (1 == scalar(@{$parts})) {
188     $onload = "part_selected('1')";
189   }
190
191   my $callback = "$form->{script}?action=part_selection_internal&";
192   map({ $callback .= "$_=" . $form->escape($form->{$_}) . "&" }
193       (qw(login path password partnumber description input_partnumber input_description input_partsid), grep({ /^[fl]_/ } keys %$form)));
194
195   my @header_sort = qw(partnumber description);
196   my %header_title = ( "partnumber" => $locale->text("Part Number"),
197                        "description" => $locale->text("Part description"),
198                        );
199
200   my @header =
201     map(+{ "column_title" => $header_title{$_},
202            "column" => $_,
203            "callback" => $callback . "order_by=${_}&order_dir=" . ($order_by eq $_ ? 1 - $order_dir : $order_dir),
204          },
205         @header_sort);
206
207   $form->{"title"} = $locale->text("Select a part");
208   $form->header();
209   print($form->parse_html_template("generic/part_selection", { "HEADER" => \@header,
210                                                                "PARTS" => $parts,
211                                                                "onload" => $onload }));
212
213   $lxdebug->leave_sub();
214 }
215
216 sub project_selection_internal {
217   $lxdebug->enter_sub();
218
219   $order_by = "description";
220   $order_by = $form->{"order_by"} if (defined($form->{"order_by"}));
221   $order_dir = 1;
222   $order_dir = $form->{"order_dir"} if (defined($form->{"order_dir"}));
223
224   $projects = Common->retrieve_projects(\%myconfig, $form, $order_by, $order_dir);
225   map({ $projects->[$_]->{"selected"} = $_ ? 0 : 1; } (0..$#{$projects}));
226   if (0 == scalar(@{$projects})) {
227     $form->show_generic_information($locale->text("No project was found matching the search parameters."));
228   } elsif (1 == scalar(@{$projects})) {
229     $onload = "project_selected('1')";
230   }
231
232   my $callback = "$form->{script}?action=project_selection_internal&";
233   map({ $callback .= "$_=" . $form->escape($form->{$_}) . "&" }
234       (qw(login path password projectnumber description input_projectnumber input_description input_project_id), grep({ /^[fl]_/ } keys %$form)));
235
236   my @header_sort = qw(projectnumber description);
237   my %header_title = ( "projectnumber" => $locale->text("Project Number"),
238                        "description" => $locale->text("Project description"),
239                        );
240
241   my @header =
242     map(+{ "column_title" => $header_title{$_},
243            "column" => $_,
244            "callback" => $callback . "order_by=${_}&order_dir=" . ($order_by eq $_ ? 1 - $order_dir : $order_dir),
245          },
246         @header_sort);
247
248   $form->{"title"} = $locale->text("Select a project");
249   $form->header();
250   print($form->parse_html_template("generic/project_selection", { "HEADER" => \@header,
251                                                                   "PROJECTS" => $projects,
252                                                                   "onload" => $onload }));
253
254   $lxdebug->leave_sub();
255 }
256
257 sub employee_selection_internal {
258   $lxdebug->enter_sub();
259
260   $order_by = "name";
261   $order_by = $form->{"order_by"} if (defined($form->{"order_by"}));
262   $order_dir = 1;
263   $order_dir = $form->{"order_dir"} if (defined($form->{"order_dir"}));
264
265   $employees = Common->retrieve_employees(\%myconfig, $form, $order_by, $order_dir);
266   map({ $employees->[$_]->{"selected"} = $_ ? 0 : 1; } (0..$#{$employees}));
267   if (0 == scalar(@{$employees})) {
268     $form->show_generic_information($locale->text("No employee was found matching the search parameters."));
269   } elsif (1 == scalar(@{$employees})) {
270     $onload = "employee_selected('1')";
271   }
272
273   my $callback = "$form->{script}?action=employee_selection_internal&";
274   map({ $callback .= "$_=" . $form->escape($form->{$_}) . "&" }
275       (qw(login path password name input_name input_id), grep({ /^[fl]_/ } keys %$form)));
276
277   my @header_sort = qw(name);
278   my %header_title = ( "name" => $locale->text("Name"),
279                        );
280
281   my @header =
282     map(+{ "column_title" => $header_title{$_},
283            "column" => $_,
284            "callback" => $callback . "order_by=${_}&order_dir=" . ($order_by eq $_ ? 1 - $order_dir : $order_dir),
285          },
286         @header_sort);
287
288   $form->{"title"} = $locale->text("Select an employee");
289   $form->header();
290   print($form->parse_html_template("generic/employee_selection", { "HEADER" => \@header,
291                                                                    "EMPLOYEES" => $employees,
292                                                                    "onload" => $onload }));
293
294   $lxdebug->leave_sub();
295 }
296
297 sub delivery_customer_selection {
298   $lxdebug->enter_sub();
299
300   $order_by = "name";
301   $order_by = $form->{"order_by"} if (defined($form->{"order_by"}));
302   $order_dir = 1;
303   $order_dir = $form->{"order_dir"} if (defined($form->{"order_dir"}));
304
305   $delivery = Common->retrieve_delivery_customer(\%myconfig, $form, $order_by, $order_dir);
306   map({ $delivery->[$_]->{"selected"} = $_ ? 0 : 1; } (0..$#{$delivery}));
307   if (0 == scalar(@{$delivery})) {
308     $form->show_generic_information($locale->text("No Customer was found matching the search parameters."));
309   } elsif (1 == scalar(@{$delivery})) {
310     $onload = "customer_selected('1')";
311   }
312
313   my $callback = "$form->{script}?action=delivery_customer_selection&";
314   map({ $callback .= "$_=" . $form->escape($form->{$_}) . "&" }
315       (qw(login path password name input_name input_id), grep({ /^[fl]_/ } keys %$form)));
316
317   my @header_sort = qw(name customernumber address);
318   my %header_title = ( "name" => $locale->text("Name"),
319                        "customernumber" => $locale->text("Customer Number"),
320                        "address" => $locale->text("Address"),
321                      );
322
323   my @header =
324     map(+{ "column_title" => $header_title{$_},
325            "column" => $_,
326            "callback" => $callback . "order_by=${_}&order_dir=" . ($order_by eq $_ ? 1 - $order_dir : $order_dir),
327          },
328         @header_sort);
329
330   $form->{"title"} = $locale->text("Select a Customer");
331   $form->header();
332   print($form->parse_html_template("generic/select_delivery_customer", { "HEADER" => \@header,
333                                                                    "DELIVERY" => $delivery,
334                                                                    "onload" => $onload }));
335
336   $lxdebug->leave_sub();
337 }
338
339 sub vendor_selection {
340   $lxdebug->enter_sub();
341
342   $order_by = "name";
343   $order_by = $form->{"order_by"} if (defined($form->{"order_by"}));
344   $order_dir = 1;
345   $order_dir = $form->{"order_dir"} if (defined($form->{"order_dir"}));
346
347   $vendor = Common->retrieve_vendor(\%myconfig, $form, $order_by, $order_dir);
348   map({ $vendor->[$_]->{"selected"} = $_ ? 0 : 1; } (0..$#{$vendor}));
349   if (0 == scalar(@{$vendor})) {
350     $form->show_generic_information($locale->text("No Vendor was found matching the search parameters."));
351   } elsif (1 == scalar(@{$vendor})) {
352     $onload = "vendor_selected('1')";
353   }
354
355   my $callback = "$form->{script}?action=vendor_selection&";
356   map({ $callback .= "$_=" . $form->escape($form->{$_}) . "&" }
357       (qw(login path password name input_name input_id), grep({ /^[fl]_/ } keys %$form)));
358
359   my @header_sort = qw(name customernumber address);
360   my %header_title = ( "name" => $locale->text("Name"),
361                        "customernumber" => $locale->text("Customer Number"),
362                        "address" => $locale->text("Address"),
363                      );
364
365   my @header =
366     map(+{ "column_title" => $header_title{$_},
367            "column" => $_,
368            "callback" => $callback . "order_by=${_}&order_dir=" . ($order_by eq $_ ? 1 - $order_dir : $order_dir),
369          },
370         @header_sort);
371
372   $form->{"title"} = $locale->text("Select a Customer");
373   $form->header();
374   print($form->parse_html_template("generic/select_vendor", { "HEADER" => \@header,
375                                                                    "VENDOR" => $vendor,
376                                                                    "onload" => $onload }));
377
378   $lxdebug->leave_sub();
379 }
380
381 sub calculate_qty {
382   $lxdebug->enter_sub();
383
384   my @variable_sort = ();
385   my %variable_list = ();
386   my $unit_list = ();
387   $form->{formel} =~ s/\r\n//g;
388
389   my ($variable_string, $formel) = split /###/,$form->{formel};
390
391
392   split /;/, $variable_string;
393   foreach $item (@_) {
394     my($name, $valueunit) = split /=/,$item;
395     my($value, $unit) = split / /, $valueunit;
396
397     push(@variable_sort, $value);
398     $variable_list{$value} = $name;
399     $unit_list{$value} = $unit;
400   }
401
402   my @header_sort = qw(variable value unit);
403   my %header_title = ( "variable" => $locale->text("Variable"),
404                        "value" => $locale->text("Value"),
405                        "unit" => $locale->text("Unit"),
406                      );
407
408   my @variable = map(+{ "description" => $variable_list{$_},
409                         "name" => $_,
410                         "unit" => $unit_list{$_} }, @variable_sort);
411
412   my @header =
413     map(+{ "column_title" => $header_title{$_},
414            "column" => $_,
415          },
416         @header_sort);
417   $form->{formel} = $formel; 
418   $form->{"title"} = $locale->text("Please enter values");
419   $form->header();
420   print($form->parse_html_template("generic/calculate_qty", { "HEADER" => \@header,
421                                                                    "VARIABLES" => \@variable,
422                                                                    "onload" => $onload }));
423
424   $lxdebug->leave_sub();
425 }
426
427 sub set_longdescription {
428   $lxdebug->enter_sub();
429
430
431   my $callback = "$form->{script}?action=set_longdescription&";
432   map({ $callback .= "$_=" . $form->escape($form->{$_}) . "&" }
433       (qw(login path password name input_name input_id), grep({ /^[fl]_/ } keys %$form)));
434
435   $form->{"title"} = $locale->text("Enter longdescription");
436   $form->header();
437   print($form->parse_html_template("generic/set_longdescription"));
438
439   $lxdebug->leave_sub();
440 }
441
442 sub H {
443   return $form->quote_html($_[0]);
444 }
445
446 sub Q {
447   return $form->quote($_[0]);
448 }
449
450 sub E {
451   return $form->escape($_[0]);
452 }
453
454 sub NTI {
455   my ($element) = @_;
456
457   $element =~ s/tabindex\s*=\s*"\d+"//;
458   return $element;
459 }
460
461 sub format_dates {
462   $lxdebug->enter_sub();
463
464   my ($dateformat, $longformat, @indices) = @_;
465
466   $dateformat = $myconfig{"dateformat"} unless ($dateformat);
467
468   foreach my $idx (@indices) {
469     next unless (defined($form->{$idx}));
470
471     if (!ref($form->{$idx})) {
472       $form->{$idx} = $locale->reformat_date(\%myconfig, $form->{$idx},
473                                              $dateformat, $longformat);
474
475     } elsif (ref($form->{$idx}) eq "ARRAY") {
476       for (my $i = 0; $i < scalar(@{$form->{$idx}}); $i++) {
477         $form->{$idx}->[$i] =
478           $locale->reformat_date(\%myconfig, $form->{$idx}->[$i],
479                                  $dateformat, $longformat);
480       }
481     }
482   }
483
484   $lxdebug->leave_sub();
485 }
486
487 sub reformat_numbers {
488   $lxdebug->enter_sub();
489
490   my ($numberformat, $places, @indices) = @_;
491
492   return $lxdebug->leave_sub()
493     if (!$numberformat || ($numberformat eq $myconfig{"numberformat"}));
494
495   foreach my $idx (@indices) {
496     next unless (defined($form->{$idx}));
497
498     if (!ref($form->{$idx})) {
499       $form->{$idx} = $form->parse_amount(\%myconfig, $form->{$idx});
500
501     } elsif (ref($form->{$idx}) eq "ARRAY") {
502       for (my $i = 0; $i < scalar(@{$form->{$idx}}); $i++) {
503         $form->{$idx}->[$i] =
504           $form->parse_amount(\%myconfig, $form->{$idx}->[$i]);
505       }
506     }
507   }
508
509   my $saved_numberformat = $myconfig{"numberformat"};
510   $myconfig{"numberformat"} = $numberformat;
511
512   foreach my $idx (@indices) {
513     next unless (defined($form->{$idx}));
514
515     if (!ref($form->{$idx})) {
516       $form->{$idx} = $form->format_amount(\%myconfig, $form->{$idx}, $places);
517
518     } elsif (ref($form->{$idx}) eq "ARRAY") {
519       for (my $i = 0; $i < scalar(@{$form->{$idx}}); $i++) {
520         $form->{$idx}->[$i] =
521           $form->format_amount(\%myconfig, $form->{$idx}->[$i], $places);
522       }
523     }
524   }
525
526   $myconfig{"numberformat"} = $saved_numberformat;
527
528   $lxdebug->leave_sub();
529 }
530
531 sub show_history {
532         $lxdebug->enter_sub();
533         my $dbh = $form->dbconnect(\%myconfig);
534         
535         $form->{title} = $locale->text("History");
536     $form->header();
537     print $form->parse_html_template( "common/show_history", {
538         "DATEN" => $form->get_history($dbh,$form->{input_name}),
539         "SUCCESS" => ($form->get_history($dbh,$form->{input_name}) ne "0")
540         } );
541         
542         $dbh->disconnect();
543         $lxdebug->leave_sub();  
544 }
545
546 sub call_sub {
547   $lxdebug->enter_sub();
548
549   my $name = shift;
550
551   if (!$name) {
552     $form->error($locale->text("Trying to call a sub without a name"));
553   }
554
555   $name =~ s/[^a-zA-Z0-9_]//g;
556
557   if (!defined(&{ $name })) {
558     $form->error(sprintf($locale->text("Attempt to call an undefined sub named '%s'"), $name));
559   }
560
561   &{ $name }(@_);
562
563   $lxdebug->leave_sub();
564 }
565
566 1;