Kosmetikmerge aus Revisionen 5187, 5191, 5193, 5194, 5218, 5219, 5222, 5228, 5229
[kivitendo-erp.git] / bin / mozilla / oe.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 # SQL-Ledger, Accounting
9 # Copyright (c) 1998-2003
10 #
11 #  Author: Dieter Simader
12 #   Email: dsimader@sql-ledger.org
13 #     Web: http://www.sql-ledger.org
14 #
15 #
16 # This program is free software; you can redistribute it and/or modify
17 # it under the terms of the GNU General Public License as published by
18 # the Free Software Foundation; either version 2 of the License, or
19 # (at your option) any later version.
20 #
21 # This program is distributed in the hope that it will be useful,
22 # but WITHOUT ANY WARRANTY; without even the implied warranty of
23 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 # GNU General Public License for more details.
25 # You should have received a copy of the GNU General Public License
26 # along with this program; if not, write to the Free Software
27 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #======================================================================
29 #
30 # Order entry module
31 # Quotation module
32 #======================================================================
33
34 use POSIX qw(strftime);
35
36 use SL::OE;
37 use SL::IR;
38 use SL::IS;
39 use SL::PE;
40 use SL::ReportGenerator;
41 use List::Util qw(max);
42
43 require "bin/mozilla/io.pl";
44 require "bin/mozilla/arap.pl";
45 require "bin/mozilla/reportgenerator.pl";
46
47 1;
48
49 # end of main
50
51 # For locales.pl:
52 # $locale->text('Edit the purchase_order');
53 # $locale->text('Edit the sales_order');
54 # $locale->text('Edit the request_quotation');
55 # $locale->text('Edit the sales_quotation');
56
57 # $locale->text('Workflow purchase_order');
58 # $locale->text('Workflow sales_order');
59 # $locale->text('Workflow request_quotation');
60 # $locale->text('Workflow sales_quotation');
61
62 sub set_headings {
63   $lxdebug->enter_sub();
64
65   my ($action) = @_;
66
67   if ($form->{type} eq 'purchase_order') {
68     $form->{title}   = $action eq "edit" ?
69       $locale->text('Edit Purchase Order') :
70       $locale->text('Add Purchase Order');
71     $form->{heading} = $locale->text('Purchase Order');
72     $form->{vc}      = 'vendor';
73   }
74   if ($form->{type} eq 'sales_order') {
75     $form->{title}   = $action eq "edit" ?
76       $locale->text('Edit Sales Order') :
77       $locale->text('Add Sales Order');
78     $form->{heading} = $locale->text('Sales Order');
79     $form->{vc}      = 'customer';
80   }
81   if ($form->{type} eq 'request_quotation') {
82     $form->{title}   = $action eq "edit" ?
83       $locale->text('Edit Request for Quotation') :
84       $locale->text('Add Request for Quotation');
85     $form->{heading} = $locale->text('Request for Quotation');
86     $form->{vc}      = 'vendor';
87   }
88   if ($form->{type} eq 'sales_quotation') {
89     $form->{title}   = $action eq "edit" ?
90       $locale->text('Edit Quotation') :
91       $locale->text('Add Quotation');
92     $form->{heading} = $locale->text('Quotation');
93     $form->{vc}      = 'customer';
94   }
95
96   $lxdebug->leave_sub();
97 }
98
99 sub add {
100   $lxdebug->enter_sub();
101
102   set_headings("add");
103
104   $form->{callback} =
105     "$form->{script}?action=add&type=$form->{type}&vc=$form->{vc}&login=$form->{login}&password=$form->{password}"
106     unless $form->{callback};
107
108   &order_links;
109   &prepare_order;
110   &display_form;
111
112   $lxdebug->leave_sub();
113 }
114
115 sub edit {
116   $lxdebug->enter_sub();
117   # show history button
118   $form->{javascript} = qq|<script type="text/javascript" src="js/show_history.js"></script>|;
119   #/show hhistory button
120
121   $form->{simple_save} = 0;
122
123   set_headings("edit");
124
125   # editing without stuff to edit? try adding it first
126   if ($form->{rowcount} && !$form->{print_and_save}) {
127     map { $id++ if $form->{"multi_id_$_"} } (1 .. $form->{rowcount});
128     if (!$id) {
129
130       # reset rowcount
131       undef $form->{rowcount};
132       &add;
133       $lxdebug->leave_sub();
134       return;
135     }
136   } elsif (!$form->{id}) {
137     &add;
138     $lxdebug->leave_sub();
139     return;
140   }
141
142   if ($form->{print_and_save}) {
143     $form->{action}   = "print";
144     $form->{resubmit} = 1;
145     $language_id = $form->{language_id};
146     $printer_id = $form->{printer_id};
147   }
148
149   set_headings("edit");
150
151   &order_links;
152   &prepare_order;
153   if ($form->{print_and_save}) {
154     $form->{language_id} = $language_id;
155     $form->{printer_id} = $printer_id;
156   }
157   &display_form;
158
159   $lxdebug->leave_sub();
160 }
161
162 sub order_links {
163   $lxdebug->enter_sub();
164   # get customer/vendor
165   $form->all_vc(\%myconfig, $form->{vc},
166                 ($form->{vc} eq 'customer') ? "AR" : "AP");
167
168   # retrieve order/quotation
169   $form->{webdav}   = $webdav;
170   $form->{jsscript} = 1;
171
172   my $editing = $form->{id};
173
174   OE->retrieve(\%myconfig, \%$form);
175
176   if ($form->{payment_id}) {
177     $payment_id = $form->{payment_id};
178   }
179   if ($form->{language_id}) {
180     $language_id = $form->{language_id};
181   }
182   if ($form->{taxzone_id}) {
183     $taxzone_id = $form->{taxzone_id};
184   }
185
186   $salesman_id = $form->{salesman_id} if ($editing);
187
188
189   # if multiple rowcounts (== collective order) then check if the
190   # there were more than one customer (in that case OE::retrieve removes
191   # the content from the field)
192   if (   $form->{rowcount}
193       && $form->{type} eq 'sales_order'
194       && defined $form->{customer}
195       && $form->{customer} eq '') {
196
197     #    $main::lxdebug->message(0, "Detected Edit order with concurrent customers");
198     $form->error(
199                  $locale->text(
200                    'Collective Orders only work for orders from one customer!')
201     );
202   }
203
204   $taxincluded = $form->{taxincluded};
205   $form->{shipto} = 1 if $form->{id};
206
207   if ($form->{"all_$form->{vc}"}) {
208     unless ($form->{"$form->{vc}_id"}) {
209       $form->{"$form->{vc}_id"} = $form->{"all_$form->{vc}"}->[0]->{id};
210     }
211   }
212
213   $cp_id    = $form->{cp_id};
214   $intnotes = $form->{intnotes};
215
216   # get customer / vendor
217   if ($form->{type} =~ /(purchase_order|request_quotation)/) {
218     IR->get_vendor(\%myconfig, \%$form);
219
220     #quote all_vendor Bug 133
221     foreach $ref (@{ $form->{all_vendor} }) {
222       $ref->{name} = $form->quote($ref->{name});
223     }
224
225   }
226   if ($form->{type} =~ /sales_(order|quotation)/) {
227     IS->get_customer(\%myconfig, \%$form);
228
229     #quote all_vendor Bug 133
230     foreach $ref (@{ $form->{all_customer} }) {
231       $ref->{name} = $form->quote($ref->{name});
232     }
233
234   }
235   $form->{cp_id} = $cp_id;
236
237   if ($payment_id) {
238     $form->{payment_id} = $payment_id;
239   }
240   if ($language_id) {
241     $form->{language_id} = $language_id;
242   }
243   if ($taxzone_id) {
244     $form->{taxzone_id} = $taxzone_id;
245   }
246   $form->{intnotes} = $intnotes if $intnotes;
247   ($form->{ $form->{vc} }) = split /--/, $form->{ $form->{vc} };
248   $form->{"old$form->{vc}"} =
249     qq|$form->{$form->{vc}}--$form->{"$form->{vc}_id"}|;
250
251   # build the popup menus
252   if (@{ $form->{"all_$form->{vc}"} }) {
253     $form->{ $form->{vc} } =
254       qq|$form->{$form->{vc}}--$form->{"$form->{vc}_id"}|;
255     map { $form->{"select$form->{vc}"} .=
256 "<option>$_->{name}--$_->{id}</option>\n" }
257       (@{ $form->{"all_$form->{vc}"} });
258   }
259
260   $form->{taxincluded} = $taxincluded if ($form->{id});
261
262   # departments
263   if (@{ $form->{all_departments} }) {
264     $form->{selectdepartment} = "<option>\n";
265     $form->{department}       = "$form->{department}--$form->{department_id}";
266
267     map {
268       $form->{selectdepartment} .=
269         "<option>$_->{description}--$_->{id}</option>\n"
270     } (@{ $form->{all_departments} });
271   }
272
273   $form->{employee} = "$form->{employee}--$form->{employee_id}";
274
275   # forex
276   $form->{forex} = $form->{exchangerate};
277
278   $form->{salesman_id} = $salesman_id if ($editing);
279
280   $lxdebug->leave_sub();
281 }
282
283 sub prepare_order {
284   $lxdebug->enter_sub();
285   $form->{formname} = $form->{type} unless $form->{formname};
286
287   my $i = 0;
288   foreach $ref (@{ $form->{form_details} }) {
289     $form->{rowcount} = ++$i;
290
291     map { $form->{"${_}_$i"} = $ref->{$_} } keys %{$ref};
292   }
293   for my $i (1 .. $form->{rowcount}) {
294     if ($form->{id}) {
295       $form->{"discount_$i"} =
296         $form->format_amount(\%myconfig, $form->{"discount_$i"} * 100);
297     } else {
298       $form->{"discount_$i"} =
299         $form->format_amount(\%myconfig, $form->{"discount_$i"});
300     }
301     ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/);
302     $dec           = length $dec;
303     $decimalplaces = ($dec > 2) ? $dec : 2;
304
305     # copy reqdate from deliverydate for invoice -> order conversion
306     $form->{"reqdate_$i"} = $form->{"deliverydate_$i"}
307       unless $form->{"reqdate_$i"};
308
309     $form->{"sellprice_$i"} =
310       $form->format_amount(\%myconfig, $form->{"sellprice_$i"},
311                            $decimalplaces);
312
313     (my $dec_qty) = ($form->{"qty_$i"} =~ /\.(\d+)/);
314     $dec_qty = length $dec_qty;
315     $form->{"qty_$i"} =
316       $form->format_amount(\%myconfig, $form->{"qty_$i"}, $dec_qty);
317
318     map { $form->{"${_}_$i"} =~ s/\"/&quot;/g }
319       qw(partnumber description unit);
320   }
321
322   $lxdebug->leave_sub();
323 }
324
325 sub form_header {
326   $lxdebug->enter_sub();
327
328   my $checkedclosed    = $form->{"closed"}    ? "checked" : "";
329   my $checkeddelivered = $form->{"delivered"} ? "checked" : "";
330
331   $form->{employee_id} = $form->{old_employee_id} if $form->{old_employee_id};
332   $form->{salesman_id} = $form->{old_salesman_id} if $form->{old_salesman_id};
333
334   $form->{defaultcurrency} = $form->get_default_currency(\%myconfig);
335
336   $form->{employee_id} = $form->{old_employee_id} if $form->{old_employee_id};
337   $form->{salesman_id} = $form->{old_salesman_id} if $form->{old_salesman_id};
338
339   map { $form->{$_} =~ s/\"/&quot;/g }
340     qw(ordnumber quonumber shippingpoint shipvia notes intnotes shiptoname
341        shiptostreet shiptozipcode shiptocity shiptocountry shiptocontact
342        shiptophone shiptofax shiptodepartment_1 shiptodepartment_2);
343
344   # use JavaScript Calendar or not
345   $form->{jsscript} = 1;
346   $jsscript = "";
347
348   $button1 = qq|
349      <td><input name=transdate id=transdate size=11 title="$myconfig{dateformat}" value="$form->{transdate}" onBlur=\"check_right_date_format(this)\">
350       <input type=button name=transdate id="trigger1" value=|
351     . $locale->text('button') . qq|></td>
352     |;
353   $button2 = qq|
354      <td width="13"><input name=reqdate id=reqdate size=11 title="$myconfig{dateformat}" value="$form->{reqdate}" onBlur=\"check_right_date_format(this)\">
355       <input type=button name=reqdate name=reqdate id="trigger2" value=|
356     . $locale->text('button') . qq|></td>
357    |;
358
359   #write Trigger
360   $jsscript = Form->write_trigger(\%myconfig, "2", "transdate", "BL", "trigger1", "reqdate", "BL", "trigger2");
361
362   my @tmp;
363
364   if (($form->{"type"} eq "sales_order") ||
365       ($form->{"type"} eq "purchase_order")) {
366     push(@tmp, qq|<input name="delivered" id="delivered" type="checkbox" class="checkbox" value="1" $checkeddelivered>
367                   <label for="delivered">| . $locale->text('Delivered') . qq|</label>|);
368   }
369
370   if ($form->{id}) {
371     push(@tmp, qq|<input name="closed" id="closed" type="checkbox" class="checkbox" value="1" $checkedclosed>
372                   <label for="closed">| . $locale->text('Closed') . qq|</label>|);
373   }
374
375   if (@tmp) {
376     $openclosed .= qq|<tr>
377                         <td colspan=| . (2 * scalar(@tmp)) . qq| align=center>| . join("\n", @tmp) . qq|
378                         </td>
379                       </tr>\n|;
380   }
381
382   # set option selected
383   foreach $item ($form->{vc}, currency, department, ($form->{vc} eq "customer" ? customer : vendor)) {
384     $form->{"select$item"} =~ s/ selected//;
385     $form->{"select$item"} =~ s/option>\Q$form->{$item}\E/option selected>$form->{$item}/;
386   }
387
388   #quote select[customer|vendor] Bug 133
389   $form->{"select$form->{vc}"} = $form->quote($form->{"select$form->{vc}"});
390
391   #substitute \n and \r to \s (bug 543)
392   $form->{"select$form->{vc}"} =~ s/[\n\r]/&nbsp;/g;
393   
394   my @old_project_ids = ($form->{"globalproject_id"});
395   map({ push(@old_project_ids, $form->{"project_id_$_"})
396           if ($form->{"project_id_$_"}); } (1..$form->{"rowcount"}));
397
398   my $vc = $form->{vc} eq "customer" ? "customers" : "vendors";
399   $form->get_lists("contacts"   => "ALL_CONTACTS",
400                    "shipto"     => "ALL_SHIPTO",
401                    "projects"   => {
402                      "key"      => "ALL_PROJECTS",
403                      "all"      => 0,
404                      "old_id"   => \@old_project_ids
405                    },
406                    "employees"  => "ALL_EMPLOYEES",
407                    "salesmen"   => "ALL_SALESMEN",
408                    "taxzones"   => "ALL_TAXZONES",
409                    "payments"   => "ALL_PAYMENTS",
410                    "currencies" => "ALL_CURRENCIES",
411                    $vc          => "ALL_" . uc($vc));
412
413   my %labels;
414   my @values = (undef);
415   foreach my $item (@{ $form->{"ALL_CONTACTS"} }) {
416     push(@values, $item->{"cp_id"});
417     $labels{$item->{"cp_id"}} = $item->{"cp_name"} . ($item->{"cp_abteilung"} ? " ($item->{cp_abteilung})" : "");
418   }
419
420   my $contact;
421   if (scalar @values > 1) {
422     $contact = qq|
423     <tr>
424       <th align="right">| . $locale->text('Contact Person') . qq|</th>
425       <td>| .
426       NTI($cgi->popup_menu('-name' => 'cp_id', '-values' => \@values, '-style' => 'width: 250px',
427                            '-labels' => \%labels, '-default' => $form->{"cp_id"}))
428       . qq|
429       </td>
430     </tr>|;
431   }
432
433   %labels = ();
434   @values = ();
435
436   foreach my $item (@{ $form->{($form->{vc} eq "customer" ? "ALL_CUSTOMERS" : "ALL_VENDORS")}}) {
437     push(@values, $item->{"name"}.qq|--|.$item->{"id"});
438     $labels{$item->{"name"}.qq|--|.$item->{"id"}} = $item->{name};
439   }
440
441   $vc = qq|
442       <input type="hidden" name="$form->{vc}_id" value="| . H($form->{"$form->{vc}_id"}) . qq|">
443       <input type="hidden" name="old$form->{vc}" value="| . H($form->{"old$form->{vc}"}) . qq|">
444       <th align="right">| . $locale->text(ucfirst($form->{vc})) . qq|</th>
445       <td>| . 
446         (($myconfig{vclimit} <=  scalar(@values)) 
447               ? qq|<input type="text" value="| . H(($form->{"old$form->{vc}"} =~ /^(.*)\-\-.*$/)) . qq|" name="$form->{vc}">| 
448               : (NTI($cgi->popup_menu('-name' => "$form->{vc}", '-default' => $form->{"old$form->{vc}"}, 
449                              '-onChange' => 'document.getElementById(\'update_button\').click();',
450                              '-values' => \@values, '-labels' => \%labels, '-style' => 'width: 250px')))) . qq|
451         <input type="button" value="?" onclick="show_vc_details('$form->{vc}')">
452       </td><input type=hidden name="select$form->{vc}" value="| .
453     Q($form->{"select$form->{vc}"}) . qq|">|;
454
455   %labels = ();
456   @values = ("");
457   foreach my $item (@{ $form->{"ALL_PAYMENTS"} }) {
458     push(@values, $item->{"id"});
459     $labels{$item->{"id"}} = $item->{"description"};
460   }
461   
462   $payments = qq|
463     <th align="right">| . $locale->text('Payment Terms') . qq|</th>
464     <td>| .
465     NTI($cgi->popup_menu('-name' => 'payment_id', '-values' => \@values, '-style' => 'width: 250px',
466                          '-labels' => \%labels, '-default' => $form->{payment_id}))
467     . qq|</td>|;
468
469   %labels = ();
470   @values = ("");
471   foreach my $item (@{ $form->{"ALL_SHIPTO"} }) {
472     push(@values, $item->{"shipto_id"});
473     $labels{$item->{"shipto_id"}} = join "; ", grep { $_ } map { $item->{"shipto${_}" } } qw(name department_1 street city);
474   }
475
476   my $shipto;
477   if (scalar @values > 1) {
478     $shipto = qq|
479     <tr>
480       <th align="right">| . $locale->text('Shipping Address') . qq|</th>
481       <td>| .
482       NTI($cgi->popup_menu('-name' => 'shipto_id', '-values' => \@values, '-style' => 'width: 250px',
483                            '-labels' => \%labels, '-default' => $form->{"shipto_id"}))
484     . qq|</td>|;
485   }
486
487   %labels = ();
488   @values = ("");
489   foreach my $item (@{ $form->{"ALL_PROJECTS"} }) {
490     push(@values, $item->{"id"});
491     $labels{$item->{"id"}} = $item->{"projectnumber"};
492   }
493   my $globalprojectnumber = NTI($cgi->popup_menu('-name' => 'globalproject_id', '-values' => \@values,
494                                                  '-labels' => \%labels,
495                                                  '-default' => $form->{"globalproject_id"}));
496   
497   my $salesmen = "";
498   %labels = ();
499   @values = ();
500   if ($form->{type} =~ /^sales_/) {
501     foreach my $item (@{ $form->{"ALL_SALESMEN"} }) {
502       push(@values, $item->{"id"});
503       $labels{$item->{"id"}} = ($item->{"name"} ne "" ? $item->{"name"} : $item->{"login"});
504     }
505     $salesmen =
506       qq|<tr>
507           <th align="right">| . $locale->text('Salesman') . qq|</th>
508           <td>| .
509       NTI($cgi->popup_menu('-name' => 'salesman_id', '-default' => $form->{"salesman_id"} ? $form->{"salesman_id"} : $form->{"employee_id"},
510                            '-values' => \@values, '-labels' => \%labels))
511       . qq|</td>
512          </tr>|;
513   }
514
515   %labels = ();
516   @values = ();
517   foreach my $item (@{ $form->{"ALL_EMPLOYEES"} }) {
518     push(@values, $item->{"id"});
519     $labels{$item->{"id"}} = $item->{"name"} ne "" ? $item->{"name"} : $item->{"login"};
520   }
521
522   my $employee = qq|
523     <tr>
524       <th align="right">| . $locale->text('Employee') . qq|</th>
525       <td>| .
526         NTI($cgi->popup_menu('-name' => 'employee_id', '-default' => $form->{"employee_id"},
527                              '-values' => \@values, '-labels' => \%labels)) . qq|
528       </td>
529     </tr>|;
530
531   %labels = ();
532   @values = ();
533   foreach my $item (@{ $form->{"ALL_TAXZONES"} }) {
534     push(@values, $item->{"id"});
535     $labels{$item->{"id"}} = $item->{"description"};
536   }
537
538   $taxzone = qq|
539     <tr>
540       <th align="right">| . $locale->text('Steuersatz') . qq|</th>
541       <td>| .
542         NTI($cgi->popup_menu('-name' => 'taxzone_id', '-default' => $form->{"taxzone_id"},
543                              '-values' => \@values, '-labels' => \%labels, '-style' => 'width: 250px')) . qq|
544       </td>
545     </tr>|;
546
547   %labels = ();
548   @values = ();
549   my $i = 0;
550   foreach my $item (@{ $form->{"ALL_CURRENCIES"} }) {
551     push(@values, $item);
552     $labels{$item} = $item;
553   }
554
555   $form->{currency} = $form->{defaultcurrency} unless $form->{currency};
556   my $currencies;
557   if (scalar @values) {
558     $currencies = qq|
559     <tr>
560       <th align="right">| . $locale->text('Currency') . qq|</th>
561       <td>| .
562         NTI($cgi->popup_menu('-name' => 'currency', '-default' => $form->{"currency"},
563                              '-values' => \@values, '-labels' => \%labels)) . qq|
564       </td>
565     </tr>|;
566   }
567
568   $form->{exchangerate} = $form->format_amount(\%myconfig, $form->{exchangerate});
569   $form->{exchangerate} = "" unless $form->{exchangerate};
570
571   $creditwarning = (($form->{creditlimit} != 0) && ($form->{creditremaining} < 0) && !$form->{update}) ? 1 : 0;
572
573   $form->{creditlimit}     = $form->format_amount(\%myconfig, $form->{creditlimit}, 0, "0");
574   $form->{creditremaining} = $form->format_amount(\%myconfig, $form->{creditremaining}, 0, "0");
575
576   $exchangerate = qq|\n<input type=hidden name=forex value=$form->{forex}>\n|;
577
578   if ($form->{currency} ne $form->{defaultcurrency}) {
579     if ($form->{forex}) {
580       $exchangerate .=
581           qq|<th align=right>| . $locale->text('Exchangerate')
582         . qq|</th><td>$form->{exchangerate}</td>
583       <input type=hidden name=exchangerate value=$form->{exchangerate}>
584 |;
585     } else {
586       $exchangerate .=
587           qq|<th align=right>| . $locale->text('Exchangerate')
588         . qq|</th><td><input name=exchangerate size=10 value=$form->{exchangerate}></td>|;
589     }
590   }
591
592   if ($form->{business}) {
593     $business = qq|
594               <tr>
595           <th align="right">| . ($form->{vc} eq "customer" ? $locale->text('Customer type') : $locale->text('Vendor type')) . qq|</th>
596           <td>$form->{business}; | . $locale->text('Trade Discount') . qq| |
597       . $form->format_amount(\%myconfig, $form->{tradediscount} * 100)
598       . qq| %</td>
599         </tr>
600 |;
601   }
602
603   if ($form->{max_dunning_level}) {
604     $dunning = qq|
605       <tr>
606         <th align="right">| . $locale->text('Max. Dunning Level') . qq|:</th>
607         <td>
608           <b>$form->{max_dunning_level}</b>;
609           | . $locale->text('Dunning Amount') . qq|: <b>|
610         . $form->format_amount(\%myconfig, $form->{dunning_amount},2)
611         . qq|</b>
612         </td>
613       </tr>
614 |;
615   }
616
617   if ($form->{type} !~ /_quotation$/) {
618     $ordnumber = qq|
619               <tr>
620                 <th width=70% align=right nowrap>| . $locale->text('Order Number') . qq|</th>
621                 <td><input name=ordnumber size=11 value="$form->{ordnumber}"></td>
622               </tr>
623               <tr>
624                 <th width=70% align=right nowrap>|
625       . $locale->text('Quotation Number') . qq|</th>
626                 <td><input name=quonumber size=11 value="$form->{quonumber}"></td>
627               </tr>
628               <tr>
629                 <th width=70% align=right nowrap>|
630       . $locale->text('Customer Order Number') . qq|</th>
631                 <td><input name=cusordnumber size=11 value="$form->{cusordnumber}"></td>
632               </tr>
633               <tr>
634                 <th align=right nowrap>| . $locale->text('Order Date') . qq|</th>
635                 $button1
636
637               </tr>
638               <tr>
639                 <th align=right nowrap=true>| . $locale->text('Required by') . qq|</th>
640                 $button2
641               </tr>
642 |;
643
644     $n = ($form->{creditremaining} =~ /-/) ? "0" : "1";
645
646     $creditremaining = qq|
647         $shipto
648         <tr>
649           <td align="right">| . $locale->text('Credit Limit') . qq|</td>
650           <td>$form->{creditlimit}; | . $locale->text('Remaining') . qq| <span class="plus$n">$form->{creditremaining}</span></td>
651         </tr>
652               </tr>
653 |;
654   } else {
655     $reqlabel = ($form->{type} eq 'sales_quotation') ? $locale->text('Valid until') : $locale->text('Required by');
656     if ($form->{type} eq 'sales_quotation') {
657       $ordnumber = qq|
658               <tr>
659                 <th width=70% align=right nowrap>|
660         . $locale->text('Quotation Number') . qq|</th>
661                 <td><input name=quonumber size=11 value="$form->{quonumber}"></td>
662                 <input type=hidden name=ordnumber value="$form->{ordnumber}">
663               </tr>
664 |;
665     } else {
666       $ordnumber = qq|
667               <tr>
668                 <th width=70% align=right nowrap>| . $locale->text('RFQ Number') . qq|</th>
669                 <td><input name=quonumber size=11 value="$form->{quonumber}"></td>
670                 <input type=hidden name=ordnumber value="$form->{ordnumber}">
671               </tr>
672 |;
673
674     }
675
676     $ordnumber      .= qq| <tr> <th align=right nowrap>| . $locale->text('Quotation Date') . qq|</th> $button1 </tr>
677                            <tr> <th align=right nowrap=true>$reqlabel</th> $button2 </tr>\n|;
678     $creditremaining = qq| <tr> <td colspan=4></td> $shipto </tr>|;
679   }
680
681   $department = qq|
682               <tr>
683                 <th align="right" nowrap>| . $locale->text('Department') . qq|</th>
684                 <td colspan=3><select name=department style="width: 250px">$form->{selectdepartment}</select>
685                 <input type=hidden name=selectdepartment value="$form->{selectdepartment}">
686                 </td>
687               </tr> | if $form->{selectdepartment};
688
689   if ($form->{type} eq 'sales_order') {
690     $employee .= qq|\n<input type="hidden" name="customer_klass" value="$form->{customer_klass}">| if $form->{selectemployee};
691   } else {
692     $employee .= qq|\n<input type="hidden" name="customer_klass" value="$form->{customer_klass}">|;
693   }
694
695   $credittext = $locale->text('Credit Limit exceeded!!!');
696
697   $onload = ($form->{resubmit} && ($form->{format} eq "html")) ? "window.open('about:blank','Beleg'); document.oe.target = 'Beleg';document.oe.submit()"
698           : ($form->{resubmit})                                ? "document.oe.submit()"
699           : ($creditwarning)                                   ? "alert('$credittext')"
700           :                                                      "focus()";
701
702   $onload .= qq|;setupDateFormat('|. $myconfig{dateformat} .qq|', '|. $locale->text("Falsches Datumsformat!") .qq|')|;
703   $onload .= qq|;setupPoints('|.   $myconfig{numberformat} .qq|', '|. $locale->text("wrongformat") .qq|')|;
704   
705   $form->{javascript} .= qq|<script type="text/javascript" src="js/show_form_details.js"></script>|;
706   $form->{javascript} .= qq|<script type="text/javascript" src="js/show_history.js"></script>|;
707   $form->{javascript} .= qq|<script type="text/javascript" src="js/show_vc_details.js"></script>|;
708
709   $form->header;
710
711   print qq|
712 <body onLoad="$onload">
713
714 <form method=post name=oe action=$form->{script}>
715
716  <script type="text/javascript" src="js/common.js"></script>
717  <script type="text/javascript" src="js/delivery_customer_selection.js"></script>
718  <script type="text/javascript" src="js/vendor_selection.js"></script>
719  <script type="text/javascript" src="js/calculate_qty.js"></script>
720 |;
721
722   $form->hide_form(qw(id action type vc formname media format proforma queued printed emailed
723                       title discount creditlimit creditremaining tradediscount business
724                       max_dunning_level dunning_amount shiptoname shiptostreet shiptozipcode
725                       shiptocity shiptocountry shiptocontact shiptophone shiptofax 
726                       shiptodepartment_1 shiptodepartment_2 shiptoemail 
727                       message email subject cc bcc taxpart taxservice taxaccounts), 
728                       map { $_.'_rate', $_.'_description' } split / /, $form->{taxaccounts} );
729   print qq|
730
731 <table width=100%>
732   <tr class=listtop>
733     <th class=listtop>$form->{title}</th>
734   </tr>
735   <tr height="5"></tr>
736   <tr>
737     <td>
738       <table width="100%">
739         <tr valign=top>
740           <td>
741             <table width=100%>
742               <tr>
743         $vc
744         $contact
745               $creditremaining
746               $business
747               $dunning
748               $taxzone
749               $department
750               <tr>
751                 $currencies
752                 $exchangerate
753               </tr>
754               <tr>
755                 <th align=right>| . $locale->text('Shipping Point') . qq|</th>
756                 <td colspan=3><input name=shippingpoint size=35 value="$form->{shippingpoint}"></td>
757               </tr>
758               <tr>
759                 <th align=right>| . $locale->text('Ship via') . qq|</th>
760                 <td colspan=3><input name=shipvia size=35 value="$form->{shipvia}"></td>
761               </tr>
762               <tr>
763                 <th align="right">| . $locale->text('Transaction description') . qq|</th>
764                 <td colspan="3"><input name="transaction_description" size="35" value="| . H($form->{transaction_description}) . qq|"></td>
765               </tr>|;
766 #              <tr>
767 #                 <td colspan=4>
768 #                   <table>
769 #                     <tr>
770 #                       <td colspan=2>
771 #                         <button type="button" onclick="delivery_customer_selection_window('delivery_customer_string','delivery_customer_id')">| . $locale->text('Choose Customer') . qq|</button>
772 #                       </td>
773 #                       <td colspan=2><input type=hidden name=delivery_customer_id value="$form->{delivery_customer_id}">
774 #                       <input size=45 id=delivery_customer_string name=delivery_customer_string value="$form->{delivery_customer_string}"></td>
775 #                     </tr>
776 #                     <tr>
777 #                       <td colspan=2>
778 #                         <button type="button" onclick="vendor_selection_window('delivery_vendor_string','delivery_vendor_id')">| . $locale->text('Choose Vendor') . qq|</button>
779 #                       </td>
780 #                       <td colspan=2><input type=hidden name=delivery_vendor_id value="$form->{delivery_vendor_id}">
781 #                       <input size=45 id=vendor_string name=delivery_vendor_string value="$form->{delivery_vendor_string}"></td>
782 #                     </tr>
783 #                   </table>
784 #                 </td>
785 #               </tr>
786 print qq|           </table>
787           </td>
788           <td align=right>
789             <table>
790               $openclosed
791               $employee
792         $salesmen
793               $ordnumber
794               <tr>
795           <th width="70%" align="right" nowrap>| . $locale->text('Project Number') . qq|</th>
796           <td>$globalprojectnumber</td>
797               </tr>
798             </table>
799           </td>
800         </tr>
801       </table>
802     </td>
803   </tr>
804
805 $jsscript
806
807 |;
808
809   $lxdebug->leave_sub();
810 }
811
812 sub form_footer {
813   $lxdebug->enter_sub();
814
815   $form->{invtotal} = $form->{invsubtotal};
816
817   if (($rows = $form->numtextrows($form->{notes}, 25, 8)) < 2) {
818     $rows = 2;
819   }
820   if (($introws = $form->numtextrows($form->{intnotes}, 35, 8)) < 2) {
821     $introws = 2;
822   }
823   $rows = ($rows > $introws) ? $rows : $introws;
824   $notes =
825     qq|<textarea name=notes rows=$rows cols=25 wrap=soft>$form->{notes}</textarea>|;
826   $intnotes =
827     qq|<textarea name=intnotes rows=$rows cols=35 wrap=soft>$form->{intnotes}</textarea>|;
828
829   $form->{taxincluded} = ($form->{taxincluded}) ? "checked" : "";
830
831   $taxincluded = "";
832   if ($form->{taxaccounts}) {
833     $taxincluded = qq|
834               <input name=taxincluded class=checkbox type=checkbox value=1 $form->{taxincluded}> <b>|
835       . $locale->text('Tax Included') . qq|</b><br><br>
836 |;
837   }
838
839   if (!$form->{taxincluded}) {
840
841     foreach $item (split / /, $form->{taxaccounts}) {
842       if ($form->{"${item}_base"}) {
843         $form->{invtotal} += $form->{"${item}_total"} =
844           $form->round_amount(
845                              $form->{"${item}_base"} * $form->{"${item}_rate"},
846                              2);
847         $form->{"${item}_total"} =
848           $form->format_amount(\%myconfig, $form->{"${item}_total"}, 2);
849
850         $tax .= qq|
851               <tr>
852                 <th align=right>$form->{"${item}_description"}&nbsp;|
853                                     . $form->{"${item}_rate"} * 100 .qq|%</th>
854                 <td align=right>$form->{"${item}_total"}</td>
855               </tr>
856 |;
857       }
858     }
859
860     $form->{invsubtotal} =
861       $form->format_amount(\%myconfig, $form->{invsubtotal}, 2, 0);
862
863     $subtotal = qq|
864               <tr>
865                 <th align=right>| . $locale->text('Subtotal') . qq|</th>
866                 <td align=right>$form->{invsubtotal}</td>
867               </tr>
868 |;
869
870   }
871
872   if ($form->{taxincluded}) {
873     foreach $item (split / /, $form->{taxaccounts}) {
874       if ($form->{"${item}_base"}) {
875         $form->{"${item}_total"} =
876           $form->round_amount(
877                            ($form->{"${item}_base"} * $form->{"${item}_rate"} /
878                               (1 + $form->{"${item}_rate"})
879                            ),
880                            2);
881         $form->{"${item}_netto"} =
882           $form->round_amount(
883                           ($form->{"${item}_base"} - $form->{"${item}_total"}),
884                           2);
885         $form->{"${item}_total"} =
886           $form->format_amount(\%myconfig, $form->{"${item}_total"}, 2);
887         $form->{"${item}_netto"} =
888           $form->format_amount(\%myconfig, $form->{"${item}_netto"}, 2);
889
890         $tax .= qq|
891               <tr>
892                 <th align=right>Enthaltene $form->{"${item}_description"}&nbsp;|
893                                     . $form->{"${item}_rate"} * 100 .qq|%</th>
894                 <td align=right>$form->{"${item}_total"}</td>
895               </tr>
896               <tr>
897                 <th align=right>Nettobetrag</th>
898                 <td align=right>$form->{"${item}_netto"}</td>
899               </tr>
900 |;
901       }
902     }
903
904   }
905
906   $form->{oldinvtotal} = $form->{invtotal};
907   $form->{invtotal}    =
908     $form->format_amount(\%myconfig, $form->{invtotal}, 2, 0);
909
910   print qq|
911   <tr>
912     <td>
913       <table width=100%>
914         <tr valign=bottom>
915           <td>
916             <table>
917               <tr>
918                 <th align=left>| . $locale->text('Notes') . qq|</th>
919                 <th align=left>| . $locale->text('Internal Notes') . qq|</th>
920               </tr>
921               <tr valign=top>
922                 <td>$notes</td>
923                 <td>$intnotes</td>
924               </tr>
925           <tr>
926     $payments
927             </tr>
928       </table>
929           </td>
930           <td>
931             <table>
932 |;
933
934   if ($form->{type} =~ /^sales_/) {
935     print qq|
936             <tr>
937               <th  align=left>| . $locale->text('Ertrag') . qq|</th>
938               <td>| .  $form->format_amount(\%myconfig, $form->{marge_total}, 2, 0) . qq|</td>
939             </tr>
940             <tr>
941               <th  align=left>| . $locale->text('Ertrag prozentual') . qq|</th>
942               <td>| .  $form->format_amount(\%myconfig, $form->{marge_percent}, 2, 0) . qq| %</td>
943             </tr>
944 |;
945   }
946
947   print qq|
948             <input type=hidden name="marge_total" value="$form->{"marge_total"}">
949             <input type=hidden name="marge_percent" value="$form->{"marge_percent"}">
950             </table>
951           </td>
952           <td align=right>
953             $taxincluded
954             <table>
955               $subtotal
956               $tax
957               <tr>
958                 <th align=right>| . $locale->text('Total') . qq|</th>
959                 <td align=right>$form->{invtotal}</td>
960               </tr>
961             </table>
962           </td>
963         </tr>
964       </table>
965     </td>
966   </tr>
967 <input type=hidden name=oldinvtotal value=$form->{oldinvtotal}>
968 <input type=hidden name=oldtotalpaid value=$totalpaid>
969   <tr>
970     <td><hr size=3 noshade></td>
971   </tr>
972 |;
973
974   if ($webdav) {
975     $webdav_list = qq|
976
977   <tr>
978     <th class=listtop align=left>Dokumente im Webdav-Repository</th>
979   </tr>
980     <table width=100%>
981       <td align=left width=30%><b>Dateiname</b></td>
982       <td align=left width=70%><b>Webdavlink</b></td>
983 |;
984     foreach $file (@{ $form->{WEBDAV} }) {
985       $webdav_list .= qq|
986       <tr>
987         <td align="left">$file->{name}</td>
988         <td align="left"><a href="$file->{link}">$file->{type}</a></td>
989       </tr>
990 |;
991     }
992     $webdav_list .= qq|
993     </table>
994   </tr>
995   <tr>
996     <td><hr size=3 noshade></td>
997   </tr>
998 |;
999
1000     print $webdav_list;
1001   }
1002
1003   print qq|
1004   <tr>
1005     <td>
1006 |;
1007   print_options();
1008
1009   print qq|
1010     </td>
1011   </tr>
1012 </table>
1013
1014 | . $locale->text("Edit the $form->{type}") . qq|<br>
1015 <input class=submit type=submit name=action id=update_button value="|
1016     . $locale->text('Update') . qq|">
1017 <input class=submit type=submit name=action value="|
1018     . $locale->text('Ship to') . qq|">
1019 <input class=submit type=submit name=action value="|
1020     . $locale->text('Print') . qq|">
1021 <input class=submit type=submit name=action value="|
1022     . $locale->text('E-mail') . qq|">
1023 <input class=submit type=submit name=action value="|
1024     . $locale->text('Save') . qq|">
1025 <input class=submit type=submit name=action value="|
1026     . $locale->text('Save and Close') . qq|">
1027 |;
1028
1029   if (($form->{id})) {
1030     print qq|
1031         <input type="button" class="submit" onclick="set_history_window(|
1032         . Q($form->{id})
1033         . qq|);" name="history" id="history" value="|
1034         . $locale->text('history')
1035         . qq|">
1036
1037 <br>| . $locale->text("Workflow $form->{type}") . qq|<br>
1038 <input class=submit type=submit name=action value="|
1039       . $locale->text('Save as new') . qq|">
1040 <input class=submit type=submit name=action value="|
1041       . $locale->text('Delete') . qq|">|;
1042     if (($form->{type} =~ /sales_quotation$/)) {
1043       print qq|
1044 <input class=submit type=submit name=action value="|
1045         . $locale->text('Sales Order') . qq|">|;
1046     }
1047     if ($form->{type} =~ /request_quotation$/) {
1048       print qq|
1049 <input class=submit type=submit name=action value="|
1050         . $locale->text('Purchase Order') . qq|">|;
1051     }
1052     print qq|
1053 <input class=submit type=submit name=action value="|
1054       . $locale->text('Invoice') . qq|">
1055 |;
1056
1057     if ($form->{type} =~ /sales_order$/) {
1058       print qq|
1059 <br>$form->{heading} als neue Vorlage verwenden f&uuml;r<br>
1060 <input class=submit type=submit name=action value="|
1061         . $locale->text('Purchase Order') . qq|">
1062 <input class=submit type=submit name=action value="|
1063         . $locale->text('Quotation') . qq|">
1064 |;
1065
1066     } elsif ($form->{type} =~ /purchase_order$/) {
1067       print qq|
1068 <br>$form->{heading} als neue Vorlage verwenden f&uuml;r<br>
1069 <input class=submit type=submit name=action value="|
1070         . $locale->text('Sales Order') . qq|">
1071 <input class=submit type=submit name=action value="|
1072         . $locale->text('Request for Quotation') . qq|">
1073 |;
1074
1075     } else {
1076       print qq|
1077 <br>$form->{heading} als neue Vorlage verwenden f&uuml;r<br>
1078 <input class=submit type=submit name=action value="|
1079         . $locale->text('Order') . qq|">
1080 |;
1081     }
1082   }
1083
1084   $form->hide_form("saved_xyznumber");
1085
1086   print qq|
1087
1088 <input type=hidden name=rowcount value=$form->{rowcount}>
1089
1090 <input name=callback type=hidden value="$form->{callback}">
1091
1092 <input type=hidden name=login value=$form->{login}>
1093 <input type=hidden name=password value=$form->{password}>
1094
1095 </form>
1096
1097 </body>
1098 </html>
1099 |;
1100   $lxdebug->leave_sub();
1101 }
1102
1103 sub update {
1104   $lxdebug->enter_sub();
1105
1106   set_headings($form->{"id"} ? "edit" : "add");
1107
1108   map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(exchangerate creditlimit creditremaining);
1109   $form->{update} = 1;
1110       
1111   $payment_id = $form->{payment_id} if $form->{payment_id};
1112   
1113   &check_name($form->{vc});
1114   
1115   $form->{payment_id} = $payment_id if $form->{payment_id} eq "";
1116   
1117   $buysell              = 'buy';
1118   $buysell              = 'sell' if ($form->{vc} eq 'vendor');
1119   $form->{exchangerate} = $exchangerate if 
1120     $form->{forex} = $exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{transdate}, $buysell);
1121
1122   # for pricegroups
1123   $i = $form->{rowcount};
1124
1125   $exchangerate = $form->{exchangerate} || 1;
1126
1127   if (   ($form->{"partnumber_$i"} eq "")
1128       && ($form->{"description_$i"} eq "")
1129       && ($form->{"partsgroup_$i"}  eq "")) {
1130
1131     $form->{creditremaining} += ($form->{oldinvtotal} - $form->{oldtotalpaid});
1132     &check_form;
1133
1134   } else {
1135
1136     if (   $form->{type} eq 'purchase_order'
1137         || $form->{type} eq 'request_quotation') {
1138       IR->retrieve_item(\%myconfig, \%$form);
1139     }
1140     if (   $form->{type} eq 'sales_order' 
1141         || $form->{type} eq 'sales_quotation') {
1142       IS->retrieve_item(\%myconfig, \%$form);
1143     }
1144
1145     my $rows = scalar @{ $form->{item_list} };
1146
1147     $form->{"discount_$i"} = $form->format_amount(\%myconfig, $form->{discount} * 100);
1148
1149     if ($rows) {
1150       $form->{"qty_$i"} = 1 unless ($form->{"qty_$i"});
1151
1152       if ($rows > 1) {
1153
1154         &select_item;
1155         exit;
1156
1157       } else {
1158
1159         $sellprice             = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"});
1160         $form->{"discount_$i"} = 0 if $form->{"not_discountable_$i"};
1161         map { $form->{item_list}[$i]{$_} =~ s/\"/&quot;/g }    qw(partnumber description unit);
1162         map { $form->{"${_}_$i"} = $form->{item_list}[0]{$_} } keys %{ $form->{item_list}[0] };
1163         $form->{payment_id} = $form->{"part_payment_id_$i"} if $form->{"part_payment_id_$i"} ne "";
1164
1165         ($sellprice || $form->{"sellprice_$i"}) =~ /\.(\d+)/;
1166         $decimalplaces = max 2, length $1;
1167
1168         if ($sellprice) {
1169           $form->{"sellprice_$i"} = $sellprice;
1170         } else {
1171           $form->{"sellprice_$i"} *= (1 - $form->{tradediscount});
1172           $form->{"sellprice_$i"} /= $exchangerate;   # if there is an exchange rate adjust sellprice
1173         }
1174
1175         $amount = $form->{"sellprice_$i"} * $form->{"qty_$i"} * (1 - $form->{"discount_$i"} / 100);
1176         map { $form->{"${_}_base"} = 0 }                                 split / /, $form->{taxaccounts};
1177         map { $form->{"${_}_base"} += $amount }                          split / /, $form->{"taxaccounts_$i"};
1178         map { $amount += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } split / /, $form->{taxaccounts} if !$form->{taxincluded};
1179
1180         $form->{creditremaining} -= $amount;
1181
1182         $form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
1183         $form->{"qty_$i"}       = $form->format_amount(\%myconfig, $form->{"qty_$i"}, $dec_qty);
1184
1185         # get pricegroups for parts
1186         IS->get_pricegroups_for_parts(\%myconfig, \%$form);
1187
1188         # build up html code for prices_$i
1189         &set_pricegroup($i);
1190       }
1191
1192       &display_form;
1193
1194     } else {
1195
1196       # ok, so this is a new part
1197       # ask if it is a part or service item
1198
1199       if (   $form->{"partsgroup_$i"}
1200           && ($form->{"partsnumber_$i"} eq "")
1201           && ($form->{"description_$i"} eq "")) {
1202         $form->{rowcount}--;
1203         $form->{"discount_$i"} = "";
1204         display_form();
1205
1206       } else {
1207         $form->{"id_$i"}   = 0;
1208         new_item();
1209       }
1210     }
1211   }
1212
1213   $lxdebug->leave_sub();
1214 }
1215
1216 sub search {
1217   $lxdebug->enter_sub();
1218
1219   if ($form->{type} eq 'purchase_order') {
1220     $form->{title} = $locale->text('Purchase Orders');
1221     $form->{vc}    = 'vendor';
1222     $ordlabel      = $locale->text('Order Number');
1223     $ordnumber     = 'ordnumber';
1224     $employee      = $locale->text('Employee');
1225   }
1226
1227   if ($form->{type} eq 'request_quotation') {
1228     $form->{title} = $locale->text('Request for Quotations');
1229     $form->{vc}    = 'vendor';
1230     $ordlabel      = $locale->text('RFQ Number');
1231     $ordnumber     = 'quonumber';
1232     $employee      = $locale->text('Employee');
1233   }
1234
1235   if ($form->{type} eq 'sales_order') {
1236     $form->{title} = $locale->text('Sales Orders');
1237     $form->{vc}    = 'customer';
1238     $ordlabel      = $locale->text('Order Number');
1239     $ordnumber     = 'ordnumber';
1240     $employee      = $locale->text('Employee');
1241   }
1242
1243   if ($form->{type} eq 'sales_quotation') {
1244     $form->{title} = $locale->text('Quotations');
1245     $form->{vc}    = 'customer';
1246     $ordlabel      = $locale->text('Quotation Number');
1247     $ordnumber     = 'quonumber';
1248     $employee      = $locale->text('Employee');
1249   }
1250
1251   # setup vendor / customer selection
1252   $form->all_vc(\%myconfig, $form->{vc},
1253                 ($form->{vc} eq 'customer') ? "AR" : "AP");
1254
1255   # departments
1256   if (@{ $form->{all_departments} }) {
1257     $form->{selectdepartment} = "<option>\n";
1258
1259     map {
1260       $form->{selectdepartment} .=
1261         "<option>$_->{description}--$_->{id}</option>\n"
1262     } (@{ $form->{all_departments} });
1263   }
1264
1265   $department = qq|
1266         <tr>
1267           <th align=right nowrap>| . $locale->text('Department') . qq|</th>
1268           <td colspan=3><select name=department>$form->{selectdepartment}</select></td>
1269         </tr>
1270 | if $form->{selectdepartment};
1271
1272   my $delivered;
1273   if (($form->{"type"} eq "sales_order") ||
1274       ($form->{"type"} eq "purchase_order")) {
1275     $delivered = qq|
1276         <tr>
1277           <td><input name="notdelivered" id="notdelivered" class="checkbox" type="checkbox" value="1" checked>
1278             <label for="notdelivered">|. $locale->text('Not delivered') . qq|</label></td>
1279           <td><input name="delivered" id="delivered" class="checkbox" type="checkbox" value="1" checked>
1280             <label for="delivered">| . $locale->text('Delivered') . qq|</label></td>
1281         </tr>
1282 |;
1283   }
1284
1285   # use JavaScript Calendar or not
1286   $form->{jsscript} = 1;
1287   $jsscript = "";
1288
1289   $button1 = qq|
1290      <td><input name=transdatefrom id=transdatefrom size=11 title="$myconfig{dateformat}" onBlur=\"check_right_date_format(this)\">
1291      <input type=button name=transdatefrom id="trigger3" value=|
1292     . $locale->text('button') . qq|></td>
1293     |;
1294   $button2 = qq|
1295      <td><input name=transdateto id=transdateto size=11 title="$myconfig{dateformat}" onBlur=\"check_right_date_format(this)\">
1296      <input type=button name=transdateto name=transdateto id="trigger4" value=|
1297     . $locale->text('button') . qq|></td>
1298    |;
1299
1300   #write Trigger
1301   $jsscript =
1302     Form->write_trigger(\%myconfig, "2", "transdatefrom", "BR", "trigger3",
1303                         "transdateto", "BL", "trigger4");
1304
1305   my $vc = $form->{vc} eq "customer" ? "customers" : "vendors";
1306
1307   $form->get_lists("projects" => { "key" => "ALL_PROJECTS",
1308                                    "all" => 1 },
1309                    "employees" => "ALL_EMPLOYEES",
1310                    $vc => "ALL_" . uc($vc));
1311
1312   my %labels = ();
1313   my @values = ("");
1314   foreach my $item (@{ $form->{"ALL_PROJECTS"} }) {
1315     push(@values, $item->{"id"});
1316     $labels{$item->{"id"}} = $item->{"projectnumber"};
1317   }
1318   my $projectnumber =
1319     NTI($cgi->popup_menu('-name' => 'project_id', '-values' => \@values,
1320                          '-labels' => \%labels));
1321
1322   #employees
1323   %labels = ();
1324   @values = ("");
1325   foreach my $item (@{ $form->{"ALL_EMPLOYEES"} }) {
1326     push(@values, $item->{"id"});
1327     $labels{$item->{"id"}} = $item->{"name"} ne "" ? $item->{"name"} : $item->{"login"};
1328   }
1329
1330   my $employee_block = qq|
1331     <tr>
1332       <th align="right">| . $locale->text('Employee') . qq|</th>
1333       <td>| .
1334         NTI($cgi->popup_menu('-name'   => 'employee_id',
1335                              '-values' => \@values,
1336                              '-labels' => \%labels)) . qq|
1337       </td>
1338     </tr>|;
1339
1340   %labels = ();
1341   @values = ("");
1342
1343   foreach my $item (@{ $form->{($form->{vc} eq "customer" ? "ALL_CUSTOMERS" : "ALL_VENDORS")}}) {
1344     push(@values, $item->{name}.qq|--|.$item->{"id"});
1345     $labels{$item->{name}.qq|--|.$item->{"id"}} = $item->{"name"};
1346   }
1347
1348   my $vc_label = $form->{vc} eq "customer" ? $locale->text('Customer') : $locale->text('Vendor');
1349   $vc =
1350     $myconfig{vclimit} <=  scalar(@values)
1351     ? qq|<input type="text" value="| . H(($form->{"old$form->{vc}"} =~ /^(.*)\-\-.*$/)) . qq|" name="$form->{vc}">| 
1352     : NTI($cgi->popup_menu('-name' => "$form->{vc}",
1353                            '-default' => $form->{"old$form->{vc}"},
1354                            '-onChange' => 'document.getElementById(\'update_button\').click();',
1355                            '-values' => \@values,
1356                            '-labels' => \%labels));
1357   $form->header;
1358
1359   print qq|
1360 <body>
1361
1362 <form method=post action=$form->{script}>
1363
1364 <table width=100%>
1365   <tr>
1366     <th class=listtop>$form->{title}</th>
1367   </tr>
1368   <tr height="5"></tr>
1369   <tr>
1370     <td>
1371       <table>
1372         <tr>
1373           <th align=right>$vc_label</th>
1374           <td colspan=3>$vc</td>
1375         </tr>
1376         $department
1377         <tr>
1378           <th align=right>$ordlabel</th>
1379           <td colspan=3><input name="$ordnumber" size=20></td>
1380         </tr>
1381   $employee_block
1382         <tr>
1383           <th align="right">| . $locale->text('Transaction description') . qq|</th>
1384           <td colspan="3"><input name="transaction_description" size=20></td>
1385         </tr>
1386         <tr>
1387           <th align="right">| . $locale->text("Project Number") . qq|</th>
1388           <td colspan="3">$projectnumber</td>
1389         </tr>
1390         <tr>
1391           <th align=right>| . $locale->text('From') . qq|</th>
1392           $button1
1393           <th align=right>| . $locale->text('Bis') . qq|</th>
1394           $button2
1395         </tr>
1396         <input type=hidden name=sort value=transdate>
1397         <tr>
1398           <th align=right>| . $locale->text('Include in Report') . qq|</th>
1399           <td colspan=5>
1400             <table>
1401         <tr>
1402           <td><input type="checkbox" name="open" value="1" id="open" checked>
1403             <label for="open">| . $locale->text("Open") . qq|</td>
1404           <td><input type="checkbox" name="closed" value="1" id="closed">
1405             <label for="closed">| . $locale->text("Closed") . qq|</td>
1406         </tr>
1407         $delivered
1408               <tr>
1409                 <td><input name="l_id" class=checkbox type=checkbox value=Y>
1410                 | . $locale->text('ID') . qq|</td>
1411                 <td><input name="l_$ordnumber" class=checkbox type=checkbox value=Y checked> $ordlabel</td>
1412                 <td><input name="l_transdate" class=checkbox type=checkbox value=Y checked> |
1413     . $locale->text('Date') . qq|</td>
1414                 <td><input name="l_reqdate" class=checkbox type=checkbox value=Y checked> |
1415     . $locale->text('Required by') . qq|</td>
1416               </tr>
1417               <tr>
1418                 <td><input name="l_name" class=checkbox type=checkbox value=Y checked> $vc_label</td>
1419                 <td><input name="l_employee" class=checkbox type=checkbox value=Y checked> $employee</td>
1420                 <td><input name="l_shipvia" class=checkbox type=checkbox value=Y> |
1421     . $locale->text('Ship via') . qq|</td>
1422               </tr>
1423               <tr>
1424                 <td><input name="l_netamount" class=checkbox type=checkbox value=Y> |
1425     . $locale->text('Amount') . qq|</td>
1426                 <td><input name="l_tax" class=checkbox type=checkbox value=Y> |
1427     . $locale->text('Tax') . qq|</td>
1428                 <td><input name="l_amount" class=checkbox type=checkbox value=Y checked> |
1429     . $locale->text('Total') . qq|</td>
1430               </tr>
1431               <tr>
1432                 <td><input name="l_marge_total" class=checkbox type=checkbox value=Y> |
1433     .             $locale->text('Ertrag') . qq|</td>
1434                 <td><input name="l_marge_percent" class=checkbox type=checkbox value=Y> |
1435     .             $locale->text('Ertrag prozentual') . qq|</td>
1436               </tr>
1437               <tr>
1438           <td><input name="l_globalprojectnumber" class=checkbox type=checkbox value=Y> |
1439           . $locale->text('Project Number') . qq|</td>
1440           <td><input name="l_transaction_description" class=checkbox type=checkbox value=Y> |
1441           . $locale->text('Transaction description') . qq|</td>
1442               </tr>
1443               <tr>
1444                 <td><input name="l_subtotal" class=checkbox type=checkbox value=Y> |
1445     . $locale->text('Subtotal') . qq|</td>
1446               </tr>
1447             </table>
1448           </td>
1449         </tr>
1450       </table>
1451     </td>
1452   </tr>
1453   <tr><td colspan=4><hr size=3 noshade></td></tr>
1454 </table>
1455
1456 $jsscript
1457
1458 <br>
1459 <input type=hidden name=nextsub value=orders>
1460 <input type=hidden name=login value=$form->{login}>
1461 <input type=hidden name=password value=$form->{password}>
1462 <input type=hidden name=vc value=$form->{vc}>
1463 <input type=hidden name=type value=$form->{type}>
1464
1465 <input class=submit type=submit name=action value="|
1466     . $locale->text('Continue') . qq|">
1467 </form>
1468
1469 </body>
1470 </html>
1471 |;
1472
1473   $lxdebug->leave_sub();
1474 }
1475
1476 sub create_subtotal_row {
1477   $lxdebug->enter_sub();
1478
1479   my ($totals, $columns, $column_alignment, $subtotal_columns, $class) = @_;
1480
1481   my $row = { map { $_ => { 'data' => '', 'class' => $class, 'align' => $column_alignment->{$_}, } } @{ $columns } };
1482
1483   map { $row->{$_}->{data} = $form->format_amount(\%myconfig, $totals->{$_}, 2) } @{ $subtotal_columns };
1484
1485   $row->{tax}->{data} = $form->format_amount(\%myconfig, $totals->{amount} - $totals->{netamount}, 2);
1486
1487   map { $totals->{$_} = 0 } @{ $subtotal_columns };
1488
1489   $lxdebug->leave_sub();
1490
1491   return $row;
1492 }
1493
1494 sub orders {
1495   $lxdebug->enter_sub();
1496
1497   $ordnumber = ($form->{type} =~ /_order$/) ? "ordnumber" : "quonumber";
1498
1499   ($form->{ $form->{vc} }, $form->{"${form->{vc}}_id"}) = split(/--/, $form->{ $form->{vc} });
1500
1501   $form->{sort} ||= 'transdate';
1502
1503   OE->transactions(\%myconfig, \%$form);
1504
1505   $form->{rowcount} = scalar @{ $form->{OE} };
1506
1507   my @columns = (
1508     "transdate",               "reqdate",
1509     "id",                      $ordnumber,
1510     "name",                    "netamount",
1511     "tax",                     "amount",
1512     "curr",                    "employee",
1513     "shipvia",                 "globalprojectnumber",
1514     "transaction_description", "open",
1515     "delivered", "marge_total", "marge_percent"
1516   );
1517
1518   # only show checkboxes if gotten here via sales_order form.
1519   my $allow_multiple_orders = $form->{type} eq 'sales_order';
1520   if ($allow_multiple_orders) {
1521     unshift @columns, "ids";
1522   }
1523
1524   $form->{l_open}      = $form->{l_closed} = "Y" if ($form->{open}      && $form->{closed});
1525   $form->{l_delivered} = "Y"                     if ($form->{delivered} && $form->{notdelivered});
1526
1527   my $attachment_basename;
1528   if ($form->{vc} eq 'vendor') {
1529     if ($form->{type} eq 'purchase_order') {
1530       $form->{title}       = $locale->text('Purchase Orders');
1531       $attachment_basename = $locale->text('purchase_order_list');
1532     } else {
1533       $form->{title}       = $locale->text('Request for Quotations');
1534       $attachment_basename = $locale->text('rfq_list');
1535     }
1536
1537   } else {
1538     if ($form->{type} eq 'sales_order') {
1539       $form->{title}       = $locale->text('Sales Orders');
1540       $attachment_basename = $locale->text('sales_order_list');
1541     } else {
1542       $form->{title}       = $locale->text('Quotations');
1543       $attachment_basename = $locale->text('quotation_list');
1544     }
1545   }
1546
1547   my $report = SL::ReportGenerator->new(\%myconfig, $form);
1548
1549   my @hidden_variables = map { "l_${_}" } @columns;
1550   push @hidden_variables, "l_subtotal", $form->{vc}, qw(l_closed l_notdelivered open closed delivered notdelivered ordnumber quonumber
1551                                                         transaction_description transdatefrom transdateto type vc employee_id);
1552
1553   my $href = build_std_url('action=orders', grep { $form->{$_} } @hidden_variables);
1554
1555   my %column_defs = (
1556     'ids'                     => { 'text' => '', },
1557     'transdate'               => { 'text' => $locale->text('Date'), },
1558     'reqdate'                 => { 'text' => $locale->text('Required by'), },
1559     'id'                      => { 'text' => $locale->text('ID'), },
1560     'ordnumber'               => { 'text' => $locale->text('Order'), },
1561     'quonumber'               => { 'text' => $form->{type} eq "request_quotation" ? $locale->text('RFQ') : $locale->text('Quotation'), },
1562     'name'                    => { 'text' => $form->{vc} eq 'customer' ? $locale->text('Customer') : $locale->text('Vendor'), },
1563     'netamount'               => { 'text' => $locale->text('Amount'), },
1564     'tax'                     => { 'text' => $locale->text('Tax'), },
1565     'amount'                  => { 'text' => $locale->text('Total'), },
1566     'curr'                    => { 'text' => $locale->text('Curr'), },
1567     'employee'                => { 'text' => $locale->text('Salesperson'), },
1568     'shipvia'                 => { 'text' => $locale->text('Ship via'), },
1569     'globalprojectnumber'     => { 'text' => $locale->text('Project Number'), },
1570     'transaction_description' => { 'text' => $locale->text('Transaction description'), },
1571     'open'                    => { 'text' => $locale->text('Open'), },
1572     'delivered'               => { 'text' => $locale->text('Delivered'), },
1573     'marge_total'                   => { 'text' => $locale->text('Ertrag'), },
1574     'marge_percent'           => { 'text' => $locale->text('Ertrag prozentual'), }
1575   );
1576
1577   foreach my $name (qw(id transdate reqdate quonumber ordnumber name employee shipvia)) {
1578     $column_defs{$name}->{link} = $href . "&sort=$name";
1579   }
1580
1581   my %column_alignment = map { $_ => 'right' } qw(netamount tax amount curr);
1582
1583   $form->{"l_type"} = "Y";
1584   map { $column_defs{$_}->{visible} = $form->{"l_${_}"} ? 1 : 0 } @columns;
1585   $column_defs{ids}->{visible} = $allow_multiple_orders ? 'HTML' : 0;
1586
1587   $report->set_columns(%column_defs);
1588   $report->set_column_order(@columns);
1589
1590   $report->set_export_options('orders', @hidden_variables);
1591
1592   $report->set_sort_indicator($form->{sort}, 1);
1593
1594   my @options;
1595   if ($form->{customer}) {
1596     push @options, $locale->text('Customer') . " : $form->{customer}";
1597   }
1598   if ($form->{vendor}) {
1599     push @options, $locale->text('Vendor') . " : $form->{vendor}";
1600   }
1601   if ($form->{department}) {
1602     ($department) = split /--/, $form->{department};
1603     push @options, $locale->text('Department') . " : $department";
1604   }
1605   if ($form->{ordnumber}) {
1606     push @options, $locale->text('Order Number') . " : $form->{ordnumber}";
1607   }
1608   if ($form->{notes}) {
1609     push @options, $locale->text('Notes') . " : $form->{notes}";
1610   }
1611   if ($form->{transaction_description}) {
1612     push @options, $locale->text('Transaction description') . " : $form->{transaction_description}";
1613   }
1614   if ($form->{transdatefrom}) {
1615     push @options, $locale->text('From') . "&nbsp;" . $locale->date(\%myconfig, $form->{transdatefrom}, 1);
1616   }
1617   if ($form->{transdateto}) {
1618     push @options, $locale->text('Bis') . "&nbsp;" . $locale->date(\%myconfig, $form->{transdateto}, 1);
1619   }
1620   if ($form->{open}) {
1621     push @options, $locale->text('Open');
1622   }
1623   if ($form->{closed}) {
1624     push @options, $locale->text('Closed');
1625   }
1626   if ($form->{delivered}) {
1627     push @options, $locale->text('Delivered');
1628   }
1629   if ($form->{notdelivered}) {
1630     push @options, $locale->text('Not delivered');
1631   }
1632
1633   $report->set_options('top_info_text'        => join("\n", @options),
1634                        'raw_top_info_text'    => $form->parse_html_template('oe/orders_top'),
1635                        'raw_bottom_info_text' => $form->parse_html_template('oe/orders_bottom', { 'SHOW_CONTINUE_BUTTON' => $allow_multiple_orders }),
1636                        'output_format'        => 'HTML',
1637                        'title'                => $form->{title},
1638                        'attachment_basename'  => $attachment_basename . strftime('_%Y%m%d', localtime time),
1639     );
1640   $report->set_options_from_form();
1641
1642   # add sort and escape callback, this one we use for the add sub
1643   $form->{callback} = $href .= "&sort=$form->{sort}";
1644
1645   # escape callback for href
1646   $callback = $form->escape($href);
1647
1648   my @subtotal_columns = qw(netamount amount marge_total marge_percent);
1649
1650   my %totals    = map { $_ => 0 } @subtotal_columns;
1651   my %subtotals = map { $_ => 0 } @subtotal_columns;
1652
1653   my $idx = 0;
1654
1655   my $edit_url = build_std_url('action=edit', 'type', 'vc');
1656
1657   foreach $oe (@{ $form->{OE} }) {
1658     map { $oe->{$_} *= $oe->{exchangerate} } @subtotal_columns;
1659
1660     $oe->{tax}       = $oe->{amount} - $oe->{netamount};
1661     $oe->{open}      = $oe->{closed}    ? $locale->text('No')  : $locale->text('Yes');
1662     $oe->{delivered} = $oe->{delivered} ? $locale->text('Yes') : $locale->text('No');
1663
1664     map { $subtotals{$_} += $oe->{$_};
1665           $totals{$_}    += $oe->{$_} } @subtotal_columns;
1666
1667     $subtotals{marge_percent} = $subtotals{netamount} ? ($subtotals{marge_total} * 100 / $subtotals{netamount}) : 0;
1668     $totals{marge_percent}    = $totals{netamount}    ? ($totals{marge_total}    * 100 / $totals{netamount}   ) : 0;
1669
1670     map { $oe->{$_} = $form->format_amount(\%myconfig, $oe->{$_}, 2) } qw(netamount tax amount marge_total marge_percent);
1671
1672     my $row = { };
1673
1674     foreach my $column (@columns) {
1675       next if ($column eq 'ids');
1676       $row->{$column} = {
1677         'data'  => $oe->{$column},
1678         'align' => $column_alignment{$column},
1679       };
1680     }
1681
1682     $row->{ids} = {
1683       'raw_data' =>   $cgi->hidden('-name' => "trans_id_${idx}", '-value' => $oe->{id})
1684                     . $cgi->checkbox('-name' => "multi_id_${idx}", '-value' => 1, '-label' => ''),
1685       'valign'   => 'center',
1686       'align'    => 'center',
1687     };
1688
1689     $row->{$ordnumber}->{link} = $edit_url . "&id=" . E($oe->{id}) . "&callback=${callback}";
1690
1691     my $row_set = [ $row ];
1692
1693     if (($form->{l_subtotal} eq 'Y')
1694         && (($idx == (scalar @{ $form->{OE} } - 1))
1695             || ($oe->{ $form->{sort} } ne $form->{OE}->[$idx + 1]->{ $form->{sort} }))) {
1696       push @{ $row_set }, create_subtotal_row(\%subtotals, \@columns, \%column_alignment, \@subtotal_columns, 'listsubtotal');
1697     }
1698
1699     $report->add_data($row_set);
1700
1701     $idx++;
1702   }
1703
1704   $report->add_separator();
1705   $report->add_data(create_subtotal_row(\%totals, \@columns, \%column_alignment, \@subtotal_columns, 'listtotal'));
1706
1707   $report->generate_with_headers();
1708
1709   $lxdebug->leave_sub();
1710 }
1711
1712 sub check_delivered_flag {
1713   $lxdebug->enter_sub();
1714
1715   if (($form->{type} ne 'sales_order') && ($form->{type} ne 'purchase_order')) {
1716     return $lxdebug->leave_sub();
1717   }
1718
1719   my $all_delivered = 0;
1720
1721   foreach my $i (1 .. $form->{rowcount}) {
1722     next if (!$form->{"id_$i"});
1723
1724     if ($form->parse_amount(\%myconfig, $form->{"qty_$i"}) == $form->parse_amount(\%myconfig, $form->{"ship_$i"})) {
1725       $all_delivered = 1;
1726       next;
1727     }
1728
1729     $all_delivered = 0;
1730     last;
1731   }
1732
1733   $form->{delivered} = 1 if $all_delivered;
1734
1735   $lxdebug->leave_sub();
1736 }
1737
1738 sub save_and_close {
1739   $lxdebug->enter_sub();
1740
1741   $form->{defaultcurrency} = $form->get_default_currency(\%myconfig);
1742
1743   if ($form->{type} =~ /_order$/) {
1744     $form->isblank("transdate", $locale->text('Order Date missing!'));
1745   } else {
1746     $form->isblank("transdate", $locale->text('Quotation Date missing!'));
1747   }
1748
1749   my $idx = $form->{type} =~ /_quotation$/ ? "quonumber" : "ordnumber";
1750   $form->{$idx} =~ s/^\s*//g;
1751   $form->{$idx} =~ s/\s*$//g;
1752
1753   $msg = ucfirst $form->{vc};
1754   $form->isblank($form->{vc}, $locale->text($msg . " missing!"));
1755
1756   # $locale->text('Customer missing!');
1757   # $locale->text('Vendor missing!');
1758
1759   $form->isblank("exchangerate", $locale->text('Exchangerate missing!'))
1760     if ($form->{currency} ne $form->{defaultcurrency});
1761
1762   &validate_items;
1763   
1764   if($form->{payment_id}) { 
1765     $payment_id = $form->{payment_id};
1766   }
1767   
1768   # if the name changed get new values
1769   if (&check_name($form->{vc})) {
1770     if($form->{payment_id} eq "") { 
1771       $form->{payment_id} = $payment_id;
1772     }
1773     &update;
1774     exit;
1775   }
1776
1777   $form->{id} = 0 if $form->{saveasnew};
1778
1779   # this is for the internal notes section for the [email] Subject
1780   if ($form->{type} =~ /_order$/) {
1781     if ($form->{type} eq 'sales_order') {
1782       $form->{label} = $locale->text('Sales Order');
1783
1784       $numberfld = "sonumber";
1785       $ordnumber = "ordnumber";
1786     } else {
1787       $form->{label} = $locale->text('Purchase Order');
1788
1789       $numberfld = "ponumber";
1790       $ordnumber = "ordnumber";
1791     }
1792
1793     $err = $locale->text('Cannot save order!');
1794
1795     check_delivered_flag();
1796
1797   } else {
1798     if ($form->{type} eq 'sales_quotation') {
1799       $form->{label} = $locale->text('Quotation');
1800
1801       $numberfld = "sqnumber";
1802       $ordnumber = "quonumber";
1803     } else {
1804       $form->{label} = $locale->text('Request for Quotation');
1805
1806       $numberfld = "rfqnumber";
1807       $ordnumber = "quonumber";
1808     }
1809
1810     $err = $locale->text('Cannot save quotation!');
1811
1812   }
1813
1814   # get new number in sequence if no number is given or if saveasnew was requested
1815   if (!$form->{$ordnumber} || $form->{saveasnew}) {
1816     $form->{$ordnumber} = $form->update_defaults(\%myconfig, $numberfld);
1817   }
1818
1819   relink_accounts();
1820
1821   $form->error($err) if (!OE->save(\%myconfig, \%$form));
1822
1823   # saving the history
1824   if(!exists $form->{addition}) {
1825     $form->{snumbers} = qq|ordnumber_| . $form->{ordnumber};
1826         $form->{addition} = "SAVED";
1827         $form->save_history($form->dbconnect(\%myconfig));
1828   }
1829   # /saving the history
1830
1831   $form->redirect($form->{label} . " $form->{$ordnumber} " .
1832                   $locale->text('saved!'));
1833
1834   $lxdebug->leave_sub();
1835 }
1836
1837 sub save {
1838   $lxdebug->enter_sub();
1839
1840   $form->{defaultcurrency} = $form->get_default_currency(\%myconfig);
1841
1842
1843   if ($form->{type} =~ /_order$/) {
1844     $form->isblank("transdate", $locale->text('Order Date missing!'));
1845   } else {
1846     $form->isblank("transdate", $locale->text('Quotation Date missing!'));
1847   }
1848
1849   my $idx = $form->{type} =~ /_quotation$/ ? "quonumber" : "ordnumber";
1850   $form->{$idx} =~ s/^\s*//g;
1851   $form->{$idx} =~ s/\s*$//g;
1852
1853   $msg = ucfirst $form->{vc};
1854   $form->isblank($form->{vc}, $locale->text($msg . " missing!"));
1855
1856   # $locale->text('Customer missing!');
1857   # $locale->text('Vendor missing!');
1858
1859   $form->isblank("exchangerate", $locale->text('Exchangerate missing!'))
1860     if ($form->{currency} ne $form->{defaultcurrency});
1861
1862   &validate_items;
1863   
1864   if($form->{payment_id}) { 
1865     $payment_id = $form->{payment_id};
1866   }
1867   
1868   # if the name changed get new values
1869   if (&check_name($form->{vc})) {
1870     if($form->{payment_id} eq "") { 
1871       $form->{payment_id} = $payment_id;
1872     }
1873     &update;
1874     exit;
1875   }
1876
1877   $form->{id} = 0 if $form->{saveasnew};
1878
1879   # this is for the internal notes section for the [email] Subject
1880   if ($form->{type} =~ /_order$/) {
1881     if ($form->{type} eq 'sales_order') {
1882       $form->{label} = $locale->text('Sales Order');
1883
1884       $numberfld = "sonumber";
1885       $ordnumber = "ordnumber";
1886     } else {
1887       $form->{label} = $locale->text('Purchase Order');
1888
1889       $numberfld = "ponumber";
1890       $ordnumber = "ordnumber";
1891     }
1892
1893     $err = $locale->text('Cannot save order!');
1894
1895     check_delivered_flag();
1896
1897   } else {
1898     if ($form->{type} eq 'sales_quotation') {
1899       $form->{label} = $locale->text('Quotation');
1900
1901       $numberfld = "sqnumber";
1902       $ordnumber = "quonumber";
1903     } else {
1904       $form->{label} = $locale->text('Request for Quotation');
1905
1906       $numberfld = "rfqnumber";
1907       $ordnumber = "quonumber";
1908     }
1909
1910     $err = $locale->text('Cannot save quotation!');
1911
1912   }
1913
1914   $form->{$ordnumber} = $form->update_defaults(\%myconfig, $numberfld)
1915     unless $form->{$ordnumber};
1916
1917   relink_accounts();
1918
1919   OE->save(\%myconfig, \%$form);
1920
1921   # saving the history
1922   if(!exists $form->{addition}) {
1923     $form->{snumbers} = qq|ordnumber_| . $form->{ordnumber};
1924         $form->{addition} = "SAVED";
1925         $form->save_history($form->dbconnect(\%myconfig));
1926   }
1927   # /saving the history 
1928
1929   $form->{simple_save} = 1;
1930   if(!$form->{print_and_save}) {
1931     set_headings("edit");
1932     &update;
1933     exit;
1934   }
1935   $lxdebug->leave_sub();
1936 }
1937
1938 sub delete {
1939   $lxdebug->enter_sub();
1940
1941   $form->header;
1942
1943   if ($form->{type} =~ /_order$/) {
1944     $msg       = $locale->text('Are you sure you want to delete Order Number');
1945     $ordnumber = 'ordnumber';
1946   } else {
1947     $msg = $locale->text('Are you sure you want to delete Quotation Number');
1948     $ordnumber = 'quonumber';
1949   }
1950
1951   print qq|
1952 <body>
1953
1954 <form method=post action=$form->{script}>
1955 |;
1956
1957   # delete action variable
1958   map { delete $form->{$_} } qw(action header);
1959
1960   foreach $key (keys %$form) {
1961     $form->{$key} =~ s/\"/&quot;/g;
1962     print qq|<input type=hidden name=$key value="$form->{$key}">\n|;
1963   }
1964
1965   print qq|
1966 <h2 class=confirm>| . $locale->text('Confirm!') . qq|</h2>
1967
1968 <h4>$msg $form->{$ordnumber}</h4>
1969 <p>
1970 <input type="hidden" name="yes_nextsub" value="delete_order_quotation">
1971 <input name=action class=submit type=submit value="|
1972     . $locale->text('Yes') . qq|">
1973 <button class=submit type=button onclick="history.back()">|
1974     . $locale->text('No') . qq|</button>
1975 </form>
1976
1977 </body>
1978 </html>
1979 |;
1980
1981   $lxdebug->leave_sub();
1982 }
1983
1984 sub delete_order_quotation {
1985   $lxdebug->enter_sub();
1986
1987   if ($form->{type} =~ /_order$/) {
1988     $msg = $locale->text('Order deleted!');
1989     $err = $locale->text('Cannot delete order!');
1990   } else {
1991     $msg = $locale->text('Quotation deleted!');
1992     $err = $locale->text('Cannot delete quotation!');
1993   }
1994   if (OE->delete(\%myconfig, \%$form, $spool)){
1995     # saving the history
1996     if(!exists $form->{addition}) {
1997       $form->{snumbers} = qq|ordnumber_| . $form->{ordnumber};
1998           $form->{addition} = "DELETED";
1999           $form->save_history($form->dbconnect(\%myconfig));
2000     }
2001     # /saving the history 
2002     $form->info($msg);
2003     exit();
2004   }
2005   $form->error($err);
2006
2007   $lxdebug->leave_sub();
2008 }
2009
2010 sub invoice {
2011   $lxdebug->enter_sub();
2012
2013   $form->{old_employee_id} = $form->{employee_id};
2014   $form->{old_salesman_id} = $form->{salesman_id};
2015
2016   if ($form->{type} =~ /_order$/) {
2017
2018     # these checks only apply if the items don't bring their own ordnumbers/transdates.
2019     # The if clause ensures that by searching for empty ordnumber_#/transdate_# fields.
2020     $form->isblank("ordnumber", $locale->text('Order Number missing!'))
2021       if (+{ map { $form->{"ordnumber_$_"}, 1 } (1 .. $form->{rowcount} - 1) }->{''});
2022     $form->isblank("transdate", $locale->text('Order Date missing!'))
2023       if (+{ map { $form->{"transdate_$_"}, 1 } (1 .. $form->{rowcount} - 1) }->{''});
2024
2025     # also copy deliverydate from the order
2026     $form->{deliverydate} = $form->{reqdate} if $form->{reqdate};
2027     $form->{orddate}      = $form->{transdate};
2028   } else {
2029     $form->isblank("quonumber", $locale->text('Quotation Number missing!'));
2030     $form->isblank("transdate", $locale->text('Quotation Date missing!'));
2031     $form->{ordnumber}    = "";
2032     $form->{quodate}      = $form->{transdate};
2033   }
2034   
2035   $payment_id = $form->{payment_id} if $form->{payment_id};
2036   
2037   # if the name changed get new values
2038   if (&check_name($form->{vc})) {
2039     $form->{payment_id} = $payment_id if $form->{payment_id} eq "";
2040     &update;
2041     exit;
2042   }
2043
2044   $form->{cp_id} *= 1;
2045
2046   for $i (1 .. $form->{rowcount}) {
2047     for (qw(ship qty sellprice listprice basefactor)) {
2048       $form->{"${_}_${i}"} = $form->parse_amount(\%myconfig, $form->{"${_}_${i}"}) if $form->{"${_}_${i}"};
2049     }
2050   }
2051
2052   if (   $form->{type} =~ /_order/
2053       && $form->{currency} ne $form->{defaultcurrency}) {
2054
2055     # check if we need a new exchangerate
2056     $buysell = ($form->{type} eq 'sales_order') ? "buy" : "sell";
2057
2058     $orddate      = $form->current_date(\%myconfig);
2059     $exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $orddate, $buysell);
2060
2061     if (!$exchangerate) {
2062       &backorder_exchangerate($orddate, $buysell);
2063       exit;
2064     }
2065   }
2066
2067   # close orders/quotations
2068   $form->{closed} = 1;
2069
2070   # save order if one ordnumber has been given
2071   # if not it's most likely a collective order, which can't be saved back
2072   # so they just have to be closed
2073   if (($form->{ordnumber} ne '') || ($form->{quonumber} ne '')) {
2074     OE->close_order(\%myconfig, \%$form) if ($form->{id});
2075   } else {
2076     OE->close_orders(\%myconfig, \%$form);
2077   }
2078
2079   $form->{transdate} = $form->{invdate} = $form->current_date(\%myconfig);
2080   $form->{duedate}   = $form->current_date(\%myconfig, $form->{invdate}, $form->{terms} * 1);
2081
2082   $form->{id}     = '';
2083   $form->{closed} = 0;
2084   $form->{rowcount}--;
2085   $form->{shipto} = 1;
2086
2087   $form->{defaultcurrency} = $form->get_default_currency(\%myconfig);
2088
2089   if ($form->{type} =~ /_order$/) {
2090     $form->{exchangerate} = $exchangerate;
2091     &create_backorder;
2092   }
2093
2094   if (   $form->{type} eq 'purchase_order'
2095       || $form->{type} eq 'request_quotation') {
2096     $form->{title}  = $locale->text('Add Vendor Invoice');
2097     $form->{script} = 'ir.pl';
2098     $script         = "ir";
2099     $buysell        = 'sell';
2100   }
2101
2102   if (   $form->{type} eq 'sales_order' 
2103       || $form->{type} eq 'sales_quotation') {
2104     $form->{title}  = $locale->text('Add Sales Invoice');
2105     $form->{script} = 'is.pl';
2106     $script         = "is";
2107     $buysell        = 'buy';
2108   }
2109
2110   # bo creates the id, reset it
2111   map { delete $form->{$_} } qw(id subject message cc bcc printed emailed queued);
2112   $form->{ $form->{vc} } =~ s/--.*//g;
2113   $form->{type} = "invoice";
2114
2115   # locale messages
2116   $locale = new Locale "$myconfig{countrycode}", "$script";
2117
2118   require "bin/mozilla/$form->{script}";
2119
2120   map { $form->{"select$_"} = "" } ($form->{vc}, currency);
2121
2122   map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) }
2123     qw(creditlimit creditremaining);
2124
2125   $currency = $form->{currency};
2126   &invoice_links;
2127
2128   $form->{currency}     = $currency;
2129   $form->{exchangerate} = "";
2130   $form->{forex}        = "";
2131   $form->{exchangerate} = $exchangerate
2132     if (
2133         $form->{forex} = (
2134                     $exchangerate =
2135                       $form->check_exchangerate(
2136                       \%myconfig, $form->{currency}, $form->{invdate}, $buysell
2137                       )));
2138
2139   $form->{creditremaining} -= ($form->{oldinvtotal} - $form->{ordtotal});
2140
2141   &prepare_invoice;
2142
2143   # format amounts
2144   for $i (1 .. $form->{rowcount}) {
2145     $form->{"discount_$i"} =
2146       $form->format_amount(\%myconfig, $form->{"discount_$i"});
2147
2148     ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/);
2149     $dec           = length $dec;
2150     $decimalplaces = ($dec > 2) ? $dec : 2;
2151
2152     # copy delivery date from reqdate for order -> invoice conversion
2153     $form->{"deliverydate_$i"} = $form->{"reqdate_$i"}
2154       unless $form->{"deliverydate_$i"};
2155
2156     $form->{"sellprice_$i"} =
2157       $form->format_amount(\%myconfig, $form->{"sellprice_$i"},
2158                            $decimalplaces);
2159
2160     (my $dec_qty) = ($form->{"qty_$i"} =~ /\.(\d+)/);
2161     $dec_qty = length $dec_qty;
2162     $form->{"qty_$i"} =
2163       $form->format_amount(\%myconfig, $form->{"qty_$i"}, $dec_qty);
2164
2165     map { $form->{"${_}_$i"} =~ s/\"/&quot;/g }
2166       qw(partnumber description unit);
2167
2168   }
2169
2170   &display_form;
2171
2172   $lxdebug->leave_sub();
2173 }
2174
2175 sub backorder_exchangerate {
2176   $lxdebug->enter_sub();
2177   my ($orddate, $buysell) = @_;
2178
2179   $form->header;
2180
2181   print qq|
2182 <body>
2183
2184 <form method=post action=$form->{script}>
2185 |;
2186
2187   # delete action variable
2188   map { delete $form->{$_} } qw(action header exchangerate);
2189
2190   foreach $key (keys %$form) {
2191     $form->{$key} =~ s/\"/&quot;/g;
2192     print qq|<input type=hidden name=$key value="$form->{$key}">\n|;
2193   }
2194
2195   $form->{title} = $locale->text('Add Exchangerate');
2196
2197   print qq|
2198
2199 <input type=hidden name=login value=$form->{login}>
2200 <input type=hidden name=password value=$form->{password}>
2201
2202 <input type=hidden name=exchangeratedate value=$orddate>
2203 <input type=hidden name=buysell value=$buysell>
2204
2205 <table width=100%>
2206   <tr><th class=listtop>$form->{title}</th></tr>
2207   <tr height="5"></tr>
2208   <tr>
2209     <td>
2210       <table>
2211         <tr>
2212           <th align=right>| . $locale->text('Currency') . qq|</th>
2213           <td>$form->{currency}</td>
2214         </tr>
2215         <tr>
2216           <th align=right>| . $locale->text('Date') . qq|</th>
2217           <td>$orddate</td>
2218         </tr>
2219         <tr>
2220           <th align=right>| . $locale->text('Exchangerate') . qq|</th>
2221           <td><input name=exchangerate size=11></td>
2222         </tr>
2223       </table>
2224     </td>
2225   </tr>
2226 </table>
2227
2228 <hr size=3 noshade>
2229
2230 <br>
2231 <input type=hidden name=nextsub value=save_exchangerate>
2232
2233 <input name=action class=submit type=submit value="|
2234     . $locale->text('Continue') . qq|">
2235
2236 </form>
2237
2238 </body>
2239 </html>
2240 |;
2241
2242   $lxdebug->leave_sub();
2243 }
2244
2245 sub save_exchangerate {
2246   $lxdebug->enter_sub();
2247
2248   $form->isblank("exchangerate", $locale->text('Exchangerate missing!'));
2249   $form->{exchangerate} =
2250     $form->parse_amount(\%myconfig, $form->{exchangerate});
2251   $form->save_exchangerate(\%myconfig, $form->{currency},
2252                            $form->{exchangeratedate},
2253                            $form->{exchangerate}, $form->{buysell});
2254
2255   &invoice;
2256
2257   $lxdebug->leave_sub();
2258 }
2259
2260 sub create_backorder {
2261   $lxdebug->enter_sub();
2262
2263   $form->{shipped} = 1;
2264
2265   # figure out if we need to create a backorder
2266   # items aren't saved if qty != 0
2267
2268   for $i (1 .. $form->{rowcount}) {
2269     $totalqty  += $qty  = $form->{"qty_$i"};
2270     $totalship += $ship = $form->{"ship_$i"};
2271
2272     $form->{"qty_$i"} = $qty - $ship;
2273   }
2274
2275   if ($totalship == 0) {
2276     map { $form->{"ship_$_"} = $form->{"qty_$_"} } (1 .. $form->{rowcount});
2277     $form->{ordtotal} = 0;
2278     $form->{shipped}  = 0;
2279     return;
2280   }
2281
2282   if ($totalqty == $totalship) {
2283     map { $form->{"qty_$_"} = $form->{"ship_$_"} } (1 .. $form->{rowcount});
2284     $form->{ordtotal} = 0;
2285     return;
2286   }
2287
2288   @flds = (
2289     qw(partnumber description qty ship unit sellprice discount id inventory_accno bin income_accno expense_accno listprice assembly taxaccounts partsgroup)
2290   );
2291
2292   for $i (1 .. $form->{rowcount}) {
2293     map {
2294       $form->{"${_}_$i"} =
2295         $form->format_amount(\%myconfig, $form->{"${_}_$i"})
2296     } qw(sellprice discount);
2297   }
2298
2299   relink_accounts();
2300
2301   OE->save(\%myconfig, \%$form);
2302
2303   # rebuild rows for invoice
2304   @a     = ();
2305   $count = 0;
2306
2307   for $i (1 .. $form->{rowcount}) {
2308     $form->{"qty_$i"} = $form->{"ship_$i"};
2309
2310     if ($form->{"qty_$i"}) {
2311       push @a, {};
2312       $j = $#a;
2313       map { $a[$j]->{$_} = $form->{"${_}_$i"} } @flds;
2314       $count++;
2315     }
2316   }
2317
2318   $form->redo_rows(\@flds, \@a, $count, $form->{rowcount});
2319   $form->{rowcount} = $count;
2320
2321   $lxdebug->leave_sub();
2322 }
2323
2324 sub save_as_new {
2325   $lxdebug->enter_sub();
2326
2327   $form->{saveasnew} = 1;
2328   $form->{closed}    = 0;
2329   map { delete $form->{$_} } qw(printed emailed queued);
2330
2331   # Let Lx-Office assign a new order number if the user hasn't changed the
2332   # previous one. If it has been changed manually then use it as-is.
2333   my $idx = $form->{type} =~ /_quotation$/ ? "quonumber" : "ordnumber";
2334   $form->{$idx} =~ s/^\s*//g;
2335   $form->{$idx} =~ s/\s*$//g;
2336   if ($form->{saved_xyznumber} &&
2337       ($form->{saved_xyznumber} eq $form->{$idx})) {
2338     delete($form->{$idx});
2339   }
2340
2341   &save;
2342
2343   $lxdebug->leave_sub();
2344 }
2345
2346 sub check_for_direct_delivery_yes {
2347   $lxdebug->enter_sub();
2348
2349   $form->{direct_delivery_checked} = 1;
2350   delete @{$form}{grep /^shipto/, keys %{ $form }};
2351   map { s/^CFDD_//; $form->{$_} = $form->{"CFDD_${_}"} } grep /^CFDD_/, keys %{ $form };
2352   $form->{shipto} = 1;
2353   purchase_order();
2354   $lxdebug->leave_sub();
2355 }
2356
2357 sub check_for_direct_delivery_no {
2358   $lxdebug->enter_sub();
2359
2360   $form->{direct_delivery_checked} = 1;
2361   delete @{$form}{grep /^shipto/, keys %{ $form }};
2362   purchase_order();
2363
2364   $lxdebug->leave_sub();
2365 }
2366
2367 sub check_for_direct_delivery {
2368   $lxdebug->enter_sub();
2369
2370   if ($form->{direct_delivery_checked}
2371       || (!$form->{shiptoname} && !$form->{shiptostreet} && !$form->{shipto_id})) {
2372     $lxdebug->leave_sub();
2373     return;
2374   }
2375
2376   if ($form->{shipto_id}) {
2377     Common->get_shipto_by_id(\%myconfig, $form, $form->{shipto_id}, "CFDD_");
2378
2379   } else {
2380     map { $form->{"CFDD_${_}"} = $form->{$_ } } grep /^shipto/, keys %{ $form };
2381   }
2382
2383   delete $form->{action};
2384   $form->{VARIABLES} = [ map { { "key" => $_, "value" => $form->{$_} } } grep { ref $_ eq "" } keys %{ $form } ];
2385
2386   $form->header();
2387   print $form->parse_html_template("oe/check_for_direct_delivery");
2388
2389   $lxdebug->leave_sub();
2390
2391   exit 0;
2392 }
2393
2394 sub purchase_order {
2395   $lxdebug->enter_sub();
2396
2397   if ($form->{type} eq 'sales_order') {
2398     check_for_direct_delivery();
2399   }
2400
2401   if (   $form->{type} eq 'sales_quotation'
2402       || $form->{type} eq 'request_quotation') {
2403     OE->close_order(\%myconfig, \%$form);
2404   }
2405
2406   if ($form->{type} =~ /^sales_/) {
2407     delete($form->{ordnumber});
2408   }
2409
2410   $form->{cp_id} *= 1;
2411
2412   $form->{title} = $locale->text('Add Purchase Order');
2413   $form->{vc}    = "vendor";
2414   $form->{type}  = "purchase_order";
2415
2416   &poso;
2417
2418   $lxdebug->leave_sub();
2419 }
2420
2421 sub sales_order {
2422   $lxdebug->enter_sub();
2423
2424   if (   $form->{type} eq 'sales_quotation'
2425       || $form->{type} eq 'request_quotation') {
2426     OE->close_order(\%myconfig, $form);
2427   }
2428
2429   if ($form->{type} eq "purchase_order") {
2430     delete($form->{ordnumber});
2431   }
2432
2433   $form->{cp_id} *= 1;
2434
2435   $form->{title} = $locale->text('Add Sales Order');
2436   $form->{vc}    = "customer";
2437   $form->{type}  = "sales_order";
2438
2439   &poso;
2440
2441   $lxdebug->leave_sub();
2442 }
2443
2444 sub poso {
2445   $lxdebug->enter_sub();
2446
2447   $form->{transdate} = $form->current_date(\%myconfig);
2448   delete $form->{duedate};
2449
2450   $form->{closed} = 0;
2451
2452   $form->{old_employee_id} = $form->{employee_id};
2453   $form->{old_salesman_id} = $form->{salesman_id};
2454
2455   # reset
2456   map { delete $form->{$_} }
2457     qw(id subject message cc bcc printed emailed queued customer vendor creditlimit creditremaining discount tradediscount oldinvtotal);
2458
2459   for $i (1 .. $form->{rowcount}) {
2460     map({ $form->{"${_}_${i}"} = $form->parse_amount(\%myconfig,
2461                                                      $form->{"${_}_${i}"})
2462             if ($form->{"${_}_${i}"}) }
2463         qw(ship qty sellprice listprice basefactor));
2464   }
2465
2466   &order_links;
2467
2468   &prepare_order;
2469
2470   # format amounts
2471   for $i (1 .. $form->{rowcount} - 1) {
2472     map { $form->{"${_}_$i"} =~ s/\"/&quot;/g }
2473       qw(partnumber description unit);
2474   }
2475
2476   map { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, 0, "0") }
2477     qw(creditlimit creditremaining);
2478
2479   &update;
2480
2481   $lxdebug->leave_sub();
2482 }
2483
2484 sub e_mail {
2485   $lxdebug->enter_sub();
2486
2487   $form->{print_and_save} = 1;
2488
2489   $print_post = 1;
2490
2491   my $saved_form = save_form();
2492
2493   save();
2494
2495   my %saved_vars;
2496   map({ $saved_vars{$_} = $form->{$_}; } qw(id ordnumber quonumber));
2497   restore_form($saved_form);
2498   map({ $form->{$_} = $saved_vars{$_}; } qw(id ordnumber quonumber));
2499
2500   edit_e_mail();
2501
2502   $lxdebug->leave_sub();
2503 }
2504
2505 sub yes {
2506   call_sub($form->{yes_nextsub});
2507 }
2508
2509 sub no {
2510   call_sub($form->{no_nextsub});
2511 }