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