Part Controller - falschen Code aus kivi.Order.js wieder entfernt
[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::Common;
13 use SL::DB::Helper::Mappings;
14 use SL::DB;
15 use SL::DBUtils qw(do_query);
16 use SL::Form;
17 use SL::MoreCommon qw(restore_form save_form);
18
19 use strict;
20
21 sub build_std_url {
22   $main::lxdebug->enter_sub(2);
23
24   my $form     = $main::form;
25
26   my $script = $form->{script};
27
28   my @parts;
29
30   foreach my $key (@_) {
31     next unless ($key);
32
33     if ($key =~ /(.*?)=(.*)/) {
34       if ($1 eq 'script') {
35         $script = $2;
36       } else {
37         push @parts, $key;
38       }
39
40     } else {
41       foreach my $var ($form->flatten_variables($key)) {
42         push @parts, E($var->{key}) . '=' . E($var->{value});
43       }
44     }
45   }
46
47   my $url = "${script}?" . join('&', @parts);
48
49   $main::lxdebug->leave_sub(2);
50
51   return $url;
52 }
53
54 # -------------------------------------------------------------------------
55
56 sub select_part {
57   $main::lxdebug->enter_sub();
58
59   my ($callback_sub, @parts) = @_;
60
61   my $form     = $main::form;
62   my $locale   = $main::locale;
63
64   my $remap_parts_id = 0;
65   if (defined($parts[0]->{parts_id}) && !defined($parts[0]->{id})) {
66     $remap_parts_id = 1;
67     map { $_->{id} = $_->{parts_id}; } @parts;
68   }
69
70   my $remap_partnumber = 0;
71   if (defined($parts[0]->{partnumber}) && !defined($parts[0]->{number})) {
72     $remap_partnumber = 1;
73     map { $_->{number} = $_->{partnumber}; } @parts;
74   }
75
76   my $has_charge = 0;
77   if (defined($parts[0]->{chargenumber})) {
78     $has_charge = 1;
79     map { $_->{has_charge} = 1; } @parts;
80   }
81   my $has_bestbefore = 0;
82   if (defined($parts[0]->{bestbefore})) {
83     $has_bestbefore = 1;
84     map { $_->{has_bestbefore} = 1; } @parts;
85   }
86   my $has_ean = 0;
87   if (defined($parts[0]->{ean})) {
88     $has_ean = 1;
89     map { $_->{has_ean} = 1; } @parts;
90   }
91
92   my $old_form = save_form();
93
94   $form->header();
95   print $form->parse_html_template("generic/select_part",
96                                    { "PARTS"            => \@parts,
97                                      "old_form"         => $old_form,
98                                      "title"            => $locale->text("Select a part"),
99                                      "nextsub"          => "select_part_internal",
100                                      "callback_sub"     => $callback_sub,
101                                      "has_charge"       => $has_charge,
102                                      "has_bestbefore"   => $has_bestbefore,
103                                      "has_ean"          => $has_ean,
104                                      "remap_parts_id"   => $remap_parts_id,
105                                      "remap_partnumber" => $remap_partnumber });
106
107   $main::lxdebug->leave_sub();
108 }
109
110 sub select_part_internal {
111   $main::lxdebug->enter_sub();
112
113   my $form     = $main::form;
114
115   my ($new_item, $callback_sub);
116
117   my $re = "^new_.*_$form->{selection}\$";
118
119   foreach (grep /$re/, keys %{ $form }) {
120     my $new_key           =  $_;
121     $new_key              =~ s/^new_//;
122     $new_key              =~ s/_\d+$//;
123     $new_item->{$new_key} =  $form->{$_};
124   }
125
126   if ($form->{remap_parts_id}) {
127     $new_item->{parts_id} = $new_item->{id};
128     delete $new_item->{id};
129   }
130
131   if ($form->{remap_partnumber}) {
132     $new_item->{partnumber} = $new_item->{number};
133     delete $new_item->{number};
134   }
135
136   $callback_sub = $form->{callback_sub};
137
138   restore_form($form->{old_form});
139
140   call_sub($callback_sub, $new_item);
141
142   $main::lxdebug->leave_sub();
143 }
144
145 sub part_selection_internal {
146   $main::lxdebug->enter_sub();
147
148   my $form     = $main::form;
149   my %myconfig = %main::myconfig;
150   my $locale   = $main::locale;
151
152   my $order_by  = "description";
153   $order_by  = $form->{"order_by"} if (defined($form->{"order_by"}));
154   my $order_dir = 1;
155   $order_dir = $form->{"order_dir"} if (defined($form->{"order_dir"}));
156
157   my %options;
158
159   foreach my $opt (split m/:/, $form->{options}) {
160     if ($opt =~ /=/) {
161       my ($key, $value) = split m/=/, $opt, 2;
162       $options{$key} = $value;
163
164     } else {
165       $options{$opt} = 1;
166     }
167   }
168
169   map { $form->{$_} = $options{$_} if ($options{$_}) } qw(no_services no_assemblies assemblies click_button);
170
171   my $parts = Common->retrieve_parts(\%myconfig, $form, $order_by, $order_dir);
172
173   if (0 == scalar(@{$parts})) {
174     $form->show_generic_information($locale->text("No part was found matching the search parameters."));
175   } elsif (1 == scalar(@{$parts})) {
176     $::request->{layout}->add_javascripts_inline("part_selected('1')");
177   }
178
179   map { $parts->[$_]->{selected} = $_ ? 0 : 1; } (0..$#{$parts});
180
181   my $callback = build_std_url('action=part_selection_internal', qw(partnumber description input_partnumber input_description input_partsid),
182                                grep({ /^[fl]_/ } keys %{ $form }));
183
184   my @header_sort  = qw(partnumber description);
185   my %header_title = ( "partnumber"  => $locale->text("Part Number"),
186                        "description" => $locale->text("Part Description"),
187                        );
188
189   my @header =
190     map(+{ "column_title" => $header_title{$_},
191            "column"       => $_,
192            "callback"     => $callback . "order_by=${_}&order_dir=" . ($order_by eq $_ ? 1 - $order_dir : $order_dir),
193          },
194         @header_sort);
195
196   $form->{formname} ||= 'Form';
197
198   $form->{title} = $locale->text("Select a part");
199   $form->header(no_layout => 1);
200   print $form->parse_html_template("generic/part_selection", { "HEADER" => \@header,
201                                                                "PARTS"  => $parts, });
202
203   $main::lxdebug->leave_sub();
204 }
205
206 # -------------------------------------------------------------------------
207
208 sub delivery_customer_selection {
209   $main::lxdebug->enter_sub();
210
211   my $form     = $main::form;
212   my %myconfig = %main::myconfig;
213   my $locale   = $main::locale;
214
215   my $order_by = "name";
216   $order_by = $form->{"order_by"} if (defined($form->{"order_by"}));
217   my $order_dir = 1;
218   $order_dir = $form->{"order_dir"} if (defined($form->{"order_dir"}));
219
220   my $delivery = Common->retrieve_delivery_customer(\%myconfig, $form, $order_by, $order_dir);
221   map({ $delivery->[$_]->{"selected"} = $_ ? 0 : 1; } (0..$#{$delivery}));
222
223   if (0 == scalar(@{$delivery})) {
224     $form->show_generic_information($locale->text("No Customer was found matching the search parameters."));
225   } elsif (1 == scalar(@{$delivery})) {
226     $::request->{layout}->add_javascripts_inline("customer_selected('1')");
227   }
228
229   my $callback = "$form->{script}?action=delivery_customer_selection&";
230   map({ $callback .= "$_=" . $form->escape($form->{$_}) . "&" }
231       (qw(name input_name input_id), grep({ /^[fl]_/ } keys %$form)));
232
233   my @header_sort = qw(name customernumber address);
234   my %header_title = ( "name" => $locale->text("Name"),
235                        "customernumber" => $locale->text("Customer Number"),
236                        "address" => $locale->text("Address"),
237                      );
238
239   my @header =
240     map(+{ "column_title" => $header_title{$_},
241            "column" => $_,
242            "callback" => $callback . "order_by=${_}&order_dir=" . ($order_by eq $_ ? 1 - $order_dir : $order_dir),
243          },
244         @header_sort);
245
246   $form->{"title"} = $locale->text("Select a Customer");
247   $form->header(no_layout => 1);
248   print $form->parse_html_template("generic/select_delivery_customer", { "HEADER"   => \@header,
249                                                                          "DELIVERY" => $delivery, });
250
251   $main::lxdebug->leave_sub();
252 }
253
254 # -------------------------------------------------------------------------
255
256 sub vendor_selection {
257   $main::lxdebug->enter_sub();
258
259   my $form     = $main::form;
260   my %myconfig = %main::myconfig;
261   my $locale   = $main::locale;
262
263   my $order_by = "name";
264   $order_by = $form->{"order_by"} if (defined($form->{"order_by"}));
265   my $order_dir = 1;
266   $order_dir = $form->{"order_dir"} if (defined($form->{"order_dir"}));
267
268   my $vendor = Common->retrieve_vendor(\%myconfig, $form, $order_by, $order_dir);
269   map({ $vendor->[$_]->{"selected"} = $_ ? 0 : 1; } (0..$#{$vendor}));
270
271   if (0 == scalar(@{$vendor})) {
272     $form->show_generic_information($locale->text("No Vendor was found matching the search parameters."));
273   } elsif (1 == scalar(@{$vendor})) {
274     $::request->{layout}->add_javascripts_inline("vendor_selected('1')");
275   }
276
277   my $callback = "$form->{script}?action=vendor_selection&";
278   map({ $callback .= "$_=" . $form->escape($form->{$_}) . "&" }
279       (qw(name input_name input_id), grep({ /^[fl]_/ } keys %$form)));
280
281   my @header_sort = qw(name customernumber address);
282   my %header_title = ( "name" => $locale->text("Name"),
283                        "customernumber" => $locale->text("Customer Number"),
284                        "address" => $locale->text("Address"),
285                      );
286
287   my @header =
288     map(+{ "column_title" => $header_title{$_},
289            "column" => $_,
290            "callback" => $callback . "order_by=${_}&order_dir=" . ($order_by eq $_ ? 1 - $order_dir : $order_dir),
291          },
292         @header_sort);
293
294   $form->{"title"} = $locale->text("Select a Customer");
295   $form->header(no_layout => 1);
296   print $form->parse_html_template("generic/select_vendor", { "HEADER" => \@header,
297                                                               "VENDOR" => $vendor, });
298
299   $main::lxdebug->leave_sub();
300 }
301
302 # -------------------------------------------------------------------------
303
304 sub calculate_qty {
305   $main::lxdebug->enter_sub();
306
307   my $form     = $main::form;
308   my $locale   = $main::locale;
309
310   $form->{formel} =~ s/\r\n//g;
311
312   my ($variable_string, $formel) = split /###/,$form->{formel};
313   my @variable;
314
315   foreach my $item (split m/;/, $variable_string) {
316     next unless $item =~ m/^ \s* (\w+) \s* = \s* (\w+) \s* (\w+) \s* $/x;
317     push @variable, {
318       description => $1,
319       name        => $2,
320       unit        => $3,
321     };
322   }
323
324   my @header_sort = qw(variable value unit);
325   my %header_title = (
326     variable => $locale->text("Variable"),
327     value    => $locale->text("Value"),
328     unit     => $locale->text("Unit"),
329   );
330   my @header = map +{
331     column_title => $header_title{$_},
332     column       => $_,
333   }, @header_sort;
334
335   $form->{formel} = $formel;
336   $form->{title}  = $locale->text("Please enter values");
337   $form->header(no_layout => 1);
338   print $form->parse_html_template("generic/calculate_qty", { "HEADER"    => \@header,
339                                                               "VARIABLES" => \@variable, });
340
341   $main::lxdebug->leave_sub();
342 }
343
344 # -------------------------------------------------------------------------
345
346 sub H {
347   return $main::locale->quote_special_chars('HTML', $_[0]);
348 }
349
350 sub Q {
351   return $main::locale->quote_special_chars('URL@HTML', $_[0]);
352 }
353
354 sub E {
355   return $main::form->escape($_[0]);
356 }
357
358 sub NTI {
359   my ($element) = @_;
360
361   $element =~ s/tabindex\s*=\s*"\d+"//;
362   return $element;
363 }
364
365 sub format_dates {
366   return $::form->format_dates(@_);
367 }
368
369 sub reformat_numbers {
370   return $::form->reformat_numbers(@_);
371 }
372
373 # -------------------------------------------------------------------------
374
375 sub show_history {
376   $main::lxdebug->enter_sub();
377
378   my $form     = $main::form;
379   my %myconfig = %main::myconfig;
380   my $locale   = $main::locale;
381
382   my $dbh = $form->dbconnect(\%myconfig);
383   my ($sort, $sortby) = split(/\-\-/, $form->{order});
384   $sort =~ s/.*\.(.*)/$1/;
385
386   $form->{title} = $locale->text("History");
387   $form->header(no_layout => 1);
388
389   my $callback = build_std_url(qw(action longdescription trans_id_type input_name));
390   my $restriction;
391   if ( $form->{trans_id_type} eq 'glid' ) {
392     $restriction = "AND ( snumbers LIKE 'invnumber%' OR what_done LIKE '%Buchungsnummer%' OR snumbers LIKE 'gltransaction%' ) ";
393   } elsif ( $form->{trans_id_type} eq 'id' ) {
394     $restriction = " AND ( snumbers NOT LIKE 'invnumber_%' AND snumbers NOT LIKE 'gltransaction%' AND (what_done NOT LIKE '%Buchungsnummer%' OR what_done IS null))";
395   } else {
396     $restriction = '';
397   };
398
399   print $form->parse_html_template( "common/show_history", {
400     "DATEN"        => $form->get_history($dbh,$form->{input_name},$restriction,$form->{order}),
401     "SUCCESS"      => ($form->get_history($dbh,$form->{input_name}) ne "0"),
402     uc($sort)      => 1,
403     uc($sort)."BY" => $sortby,
404     callback       => $callback,
405   } );
406
407   $dbh->disconnect();
408   $main::lxdebug->leave_sub();
409 }
410
411 # -------------------------------------------------------------------------
412
413 sub call_sub {
414   $main::lxdebug->enter_sub();
415
416   my $name = shift;
417
418   my $form     = $main::form;
419   my $locale   = $main::locale;
420
421   if (!$name) {
422     $form->error($locale->text("Trying to call a sub without a name"));
423   }
424
425   $name =~ s/[^a-zA-Z0-9_]//g;
426
427   if (!defined(&{ $name })) {
428     $form->error(sprintf($locale->text("Attempt to call an undefined sub named '%s'"), $name));
429   }
430
431   {
432     no strict "refs";
433     &{ $name }(@_);
434   }
435
436   $main::lxdebug->leave_sub();
437 }
438
439 # -------------------------------------------------------------------------
440
441 sub show_vc_details {
442   $main::lxdebug->enter_sub();
443
444   my $form     = $main::form;
445   my %myconfig = %main::myconfig;
446   my $locale   = $main::locale;
447
448   $form->{vc} = $form->{vc} eq "customer" ? "customer" : "vendor";
449   $form->isblank("vc_id",
450                  $form->{vc} eq "customer" ?
451                  $locale->text("No customer has been selected yet.") :
452                  $locale->text("No vendor has been selected yet."));
453
454   Common->get_vc_details(\%myconfig, $form, $form->{vc}, $form->{vc_id});
455   $form->{discount_as_percent} = $form->format_amount(\%::myconfig, $form->parse_amount(\%::myconfig, $form->{discount}) * 100, 2);
456
457   $form->{title} = $form->{vc} eq "customer" ?
458     $locale->text("Customer details") : $locale->text("Vendor details");
459   $form->header(no_layout => 1);
460   print $form->parse_html_template("common/show_vc_details", { "is_customer" => $form->{vc} eq "customer" });
461
462   $main::lxdebug->leave_sub();
463 }
464
465 # -------------------------------------------------------------------------
466
467 sub retrieve_partunits {
468   $main::lxdebug->enter_sub();
469
470   my $form     = $main::form;
471
472   my @part_ids = grep { $_ } map { $form->{"id_${_}"} } (1..$form->{rowcount});
473
474   if (@part_ids) {
475     my %partunits = IO->retrieve_partunits('part_ids' => \@part_ids);
476
477     foreach my $i (1..$form->{rowcount}) {
478       next unless ($form->{"id_${i}"});
479       $form->{"partunit_${i}"} = $partunits{$form->{"id_${i}"}};
480     }
481   }
482
483   $main::lxdebug->leave_sub();
484 }
485
486 # -------------------------------------------------------------------------
487
488 sub mark_as_paid_common {
489   $main::lxdebug->enter_sub();
490
491   my ($myconfig, $db_name) = @_;
492
493   my $form     = $main::form;
494   my $locale   = $main::locale;
495
496   if($form->{mark_as_paid}) {
497     SL::DB->client->with_transaction(sub {
498       my $dbh ||= SL::DB->client->dbh;
499       my $query = qq|UPDATE $db_name SET paid = amount, datepaid = current_date WHERE id = ?|;
500       do_query($form, $dbh, $query, $form->{id});
501       1;
502     }) or do { $::form->error(SL::DB->client->error) };
503     $form->redirect($locale->text("Marked as paid"));
504
505   } else {
506     my $referer = $ENV{HTTP_REFERER};
507     my $script;
508     my $callback;
509     if ($referer =~ /action/) {
510       $referer =~ /^(.*)\?action\=[^\&]*(\&.*)$/;
511       $script = $1;
512       $callback = $2;
513     } elsif ($referer =~ /RESTORE_FORM_FROM_SESSION_ID/){
514       $referer =~ /^(.*)\?RESTORE_FORM_FROM_SESSION_ID\=(.*)$/;
515       $script = $1;
516       $callback = "";
517     } else {
518       $script = $referer;
519       $callback = "";
520     }
521     $referer = $script . "?action=mark_as_paid&mark_as_paid=1&id=$form->{id}" . $callback;
522     $form->header();
523     print qq|<p><b>|.$locale->text('Mark as paid?').qq|</b></p>|;
524     print qq|<input type="button" value="|.$locale->text('yes').qq|" onclick="document.location.href='|.$referer.qq|'">&nbsp;|;
525     print qq|<input type="button" value="|.$locale->text('no').qq|" onclick="javascript:history.back();">|;
526   }
527
528   $main::lxdebug->leave_sub();
529 }
530
531 sub cov_selection_internal {
532   $main::lxdebug->enter_sub();
533
534   my $form     = $main::form;
535   my %myconfig = %main::myconfig;
536   my $locale   = $main::locale;
537
538   my $order_by = "name";
539   $order_by = $form->{"order_by"} if (defined($form->{"order_by"}));
540   my $order_dir = 1;
541   $order_dir = $form->{"order_dir"} if (defined($form->{"order_dir"}));
542
543   my $type = $form->{"is_vendor"} ? $locale->text("vendor") : $locale->text("customer");
544
545   my $covs = Common->retrieve_customers_or_vendors(\%myconfig, $form, $order_by, $order_dir, $form->{"is_vendor"}, $form->{"allow_both"});
546   map({ $covs->[$_]->{"selected"} = $_ ? 0 : 1; } (0..$#{$covs}));
547
548   if (0 == scalar(@{$covs})) {
549     $form->show_generic_information(sprintf($locale->text("No %s was found matching the search parameters."), $type));
550   } elsif (1 == scalar(@{$covs})) {
551     $::request->{layout}->add_javascripts_inline("cov_selected('1')");
552   }
553
554   my $callback = "$form->{script}?action=cov_selection_internal&";
555   map({ $callback .= "$_=" . $form->escape($form->{$_}) . "&" }
556       (qw(name input_name input_id is_vendor allow_both), grep({ /^[fl]_/ } keys %$form)));
557
558   my @header_sort = qw(name address contact);
559   my %header_title = ( "name" => $locale->text("Name"),
560                        "address" => $locale->text("Address"),
561                        "contact" => $locale->text("Contact"),
562                        );
563
564   my @header =
565     map(+{ "column_title" => $header_title{$_},
566            "column" => $_,
567            "callback" => $callback . "order_by=${_}&order_dir=" . ($order_by eq $_ ? 1 - $order_dir : $order_dir),
568          },
569         @header_sort);
570
571   foreach my $cov (@{ $covs }) {
572     $cov->{address} = "$cov->{street}, $cov->{zipcode} $cov->{city}";
573     $cov->{address} =~ s{^,}{}x;
574     $cov->{address} =~ s{\ +}{\ }gx;
575
576     $cov->{contact} = join " ", map { $cov->{$_} } qw(cp_gender cp_title cp_givenname cp_name);
577     $cov->{contact} =~ s{\ +}{\ }gx;
578   }
579
580   $form->{"title"} = $form->{is_vendor} ? $locale->text("Select a vendor") : $locale->text("Select a customer");
581   $form->header();
582   print($form->parse_html_template("generic/cov_selection", { "HEADER" => \@header,
583                                                               "COVS" => $covs, }));
584
585   $main::lxdebug->leave_sub();
586 }
587
588
589 # Functions to call add routines beneath different reports
590
591 sub sales_invoice {
592   $main::lxdebug->enter_sub();
593
594   print $::form->redirect_header('is.pl?action=add&type=invoice');
595
596   $main::lxdebug->leave_sub();
597 }
598
599 sub ar_transaction {
600   $main::lxdebug->enter_sub();
601
602   print $::form->redirect_header('ar.pl?action=add');
603
604   $main::lxdebug->leave_sub();
605 }
606
607 sub vendor_invoice {
608   $main::lxdebug->enter_sub();
609
610   print $::form->redirect_header('ir.pl?action=add&type=invoice');
611
612   $main::lxdebug->leave_sub();
613 }
614
615 sub ap_transaction {
616   $main::lxdebug->enter_sub();
617
618   print $::form->redirect_header('ap.pl?action=add');
619
620   $main::lxdebug->leave_sub();
621 }
622
623 sub gl_transaction {
624   $main::lxdebug->enter_sub();
625
626   print $::form->redirect_header('gl.pl?action=add');
627
628   $main::lxdebug->leave_sub();
629 }
630
631 sub db {
632   goto &SL::DB::Helper::Mappings::db;
633 }
634
635 1;