Preisgruppen verbessert
[kivitendo-erp.git] / bin / mozilla / oe.pl
index 322706a..0e469d8 100644 (file)
@@ -38,14 +38,20 @@ use SL::FU;
 use SL::OE;
 use SL::IR;
 use SL::IS;
+use SL::MoreCommon qw(ary_diff);
 use SL::PE;
 use SL::ReportGenerator;
 use List::Util qw(max reduce sum);
+use Data::Dumper;
 
 require "bin/mozilla/io.pl";
 require "bin/mozilla/arap.pl";
 require "bin/mozilla/reportgenerator.pl";
 
+use strict;
+
+our %TMPL_VAR;
+
 1;
 
 # end of main
@@ -69,14 +75,19 @@ my $oe_access_map = {
 };
 
 sub check_oe_access {
+  my $form     = $main::form;
+
   my $right   = $oe_access_map->{$form->{type}};
   $right    ||= 'DOES_NOT_EXIST';
 
-  $auth->assert($right);
+  $main::auth->assert($right);
 }
 
 sub set_headings {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+  my $locale   = $main::locale;
 
   check_oe_access();
 
@@ -111,11 +122,13 @@ sub set_headings {
     $form->{vc}      = 'customer';
   }
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub add {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
 
   check_oe_access();
 
@@ -129,11 +142,13 @@ sub add {
   &prepare_order;
   &display_form;
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub edit {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
 
   check_oe_access();
 
@@ -147,21 +162,23 @@ sub edit {
 
   # editing without stuff to edit? try adding it first
   if ($form->{rowcount} && !$form->{print_and_save}) {
+    my $id;
     map { $id++ if $form->{"multi_id_$_"} } (1 .. $form->{rowcount});
     if (!$id) {
 
       # reset rowcount
       undef $form->{rowcount};
       &add;
-      $lxdebug->leave_sub();
+      $main::lxdebug->leave_sub();
       return;
     }
   } elsif (!$form->{id}) {
     &add;
-    $lxdebug->leave_sub();
+    $main::lxdebug->leave_sub();
     return;
   }
 
+  my ($language_id, $printer_id);
   if ($form->{print_and_save}) {
     $form->{action}   = "print";
     $form->{resubmit} = 1;
@@ -174,7 +191,7 @@ sub edit {
   &order_links;
 
   $form->{rowcount} = 0;
-  foreach $ref (@{ $form->{form_details} }) {
+  foreach my $ref (@{ $form->{form_details} }) {
     $form->{rowcount}++;
     map { $form->{"${_}_$form->{rowcount}"} = $ref->{$_} } keys %{$ref};
   }
@@ -188,11 +205,15 @@ sub edit {
 
   &display_form;
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub order_links {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
+  my $locale   = $main::locale;
 
   check_oe_access();
 
@@ -200,7 +221,7 @@ sub order_links {
   $form->all_vc(\%myconfig, $form->{vc}, ($form->{vc} eq 'customer') ? "AR" : "AP");
 
   # retrieve order/quotation
-  $form->{webdav}   = $webdav;
+  $form->{webdav}   = $main::webdav;
   $form->{jsscript} = 1;
 
   my $editing = $form->{id};
@@ -230,65 +251,66 @@ sub order_links {
   $form->{employee}    = "$form->{employee}--$form->{employee_id}";
 
   # build vendor/customer drop down comatibility... don't ask
-  if (@{ $form->{"all_$form->{vc}"} }) {
+  if (@{ $form->{"all_$form->{vc}"} || [] }) {
     $form->{"select$form->{vc}"} = 1;
     $form->{$form->{vc}}         = qq|$form->{$form->{vc}}--$form->{"$form->{vc}_id"}|;
   }
 
   $form->{"old$form->{vc}"}  = $form->{$form->{vc}};
-  $form->{"old$form->{vc}"} .= qq|--$form->{"$form->{vc}_id"}| unless ($form->{"old$form->{vc}"} =~ m/--\d+$/);
 
-  $lxdebug->leave_sub();
+  if ($form->{"old$form->{vc}"} !~ m/--\d+$/ && $form->{"$form->{vc}_id"}) {
+    $form->{"old$form->{vc}"} .= qq|--$form->{"$form->{vc}_id"}|
+  }
+
+  $main::lxdebug->leave_sub();
 }
 
 sub prepare_order {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
 
   check_oe_access();
 
   $form->{formname} ||= $form->{type};
 
+  # format discounts if values come from db. either as single id, or as a collective order
+  my $format_discounts = $form->{id} || $form->{convert_from_oe_ids};
+
   for my $i (1 .. $form->{rowcount}) {
     $form->{"reqdate_$i"} ||= $form->{"deliverydate_$i"};
-    $form->{"discount_$i"}  = $form->format_amount(\%myconfig, $form->{"discount_$i"} * ($form->{id} ? 100 : 1));
+    $form->{"discount_$i"}  = $form->format_amount(\%myconfig, $form->{"discount_$i"} * ($format_discounts ? 100 : 1));
     $form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"});
+    $form->{"lastcost_$i"}  = $form->format_amount(\%myconfig, $form->{"lastcost_$i"});
     $form->{"qty_$i"}       = $form->format_amount(\%myconfig, $form->{"qty_$i"});
   }
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub form_header {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
   my @custom_hiddens;
 
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
+  my $locale   = $main::locale;
+  my $cgi      = $main::cgi;
+
   check_oe_access();
 
-  # Container for template variables. Unfortunately this has to be visible in form_footer too, so not my.
-  our %TMPL_VAR = ();
+  # Container for template variables. Unfortunately this has to be
+  # visible in form_footer too, so package local level and not my here.
+  %TMPL_VAR = ();
 
   $form->{defaultcurrency} = $form->get_default_currency(\%myconfig);
 
   $form->{employee_id} = $form->{old_employee_id} if $form->{old_employee_id};
   $form->{salesman_id} = $form->{old_salesman_id} if $form->{old_salesman_id};
 
-  map { $form->{$_} = H($form->{$_}) }
-    qw(shippingpoint shipvia notes intnotes shiptoname
-       shiptostreet shiptozipcode shiptocity shiptocountry shiptocontact
-       shiptophone shiptofax shiptodepartment_1 shiptodepartment_2);
   # use JavaScript Calendar or not
   $form->{jsscript} = 1;
-  $TMPL_VAR{button1} = qq|
-     <td nowrap><input name=transdate id=transdate size=11 title="$myconfig{dateformat}" value="$form->{transdate}" onBlur=\"check_right_date_format(this)\">
-      <input type=button name=transdate id="trigger1" value=| . $locale->text('button') . qq|></td>
-    |;
-  $TMPL_VAR{button2} = qq|
-     <td nowrap width="13"><input name=reqdate id=reqdate size=11 title="$myconfig{dateformat}" value="$form->{reqdate}" onBlur=\"check_right_date_format(this)\">
-      <input type=button name=reqdate name=reqdate id="trigger2" value=| . $locale->text('button') . qq|></td>
-   |;
-  #write Trigger
-  $TMPL_VAR{jsscript} = Form->write_trigger(\%myconfig, "2", "transdate", "BL", "trigger1", "reqdate", "BL", "trigger2");
 
   # openclosed checkboxes
   my @tmp;
@@ -298,18 +320,7 @@ sub form_header {
                         $form->{"closed"}    ? "checked" : "",  $locale->text('Closed')    if $form->{id};
   $TMPL_VAR{openclosed} = sprintf qq|<tr><td colspan=%d align=center>%s</td></tr>\n|, 2 * scalar @tmp, join "\n", @tmp if @tmp;
 
-  # set option selected
-  foreach $item ($form->{vc}, 'currency', 'department', ($form->{vc} eq "customer" ? 'customer' : 'vendor')) {
-    $form->{"select$item"} =~ s/ selected//;
-    $form->{"select$item"} =~ s/option>\Q$form->{$item}\E/option selected>$form->{$item}/;
-  }
-
-  #quote select[customer|vendor] Bug 133
-  $form->{"select$form->{vc}"} = $form->quote($form->{"select$form->{vc}"});
-
-  #substitute \n and \r to \s (bug 543)
-  $form->{"select$form->{vc}"} =~ s/[\n\r]/&nbsp;/g;
-  
+  # project ids
   my @old_project_ids = ($form->{"globalproject_id"}, grep { $_ } map { $form->{"project_id_$_"} } 1..$form->{"rowcount"});
 
   my $vc = $form->{vc} eq "customer" ? "customers" : "vendors";
@@ -332,7 +343,7 @@ sub form_header {
   $TMPL_VAR{sales_employee_labels} = sub { $_[0]->{name} || $_[0]->{login} };
   $TMPL_VAR{shipto_labels}         = sub { join "; ", grep { $_ } map { $_[0]->{"shipto${_}" } } qw(name department_1 street city) };
   $TMPL_VAR{contact_labels}        = sub { join(', ', $_[0]->{"cp_name"}, $_[0]->{"cp_givenname"}) . ($_[0]->{cp_abteilung} ? " ($_[0]->{cp_abteilung})" : "") };
-  $TMPL_VAR{department_labels}     = sub { "$_[0]->{description}--$_[0]->{id}" }; 
+  $TMPL_VAR{department_labels}     = sub { "$_[0]->{description}--$_[0]->{id}" };
 
   # vendor/customer
   $TMPL_VAR{vc_keys} = sub { "$_[0]->{name}--$_[0]->{id}" };
@@ -343,8 +354,8 @@ sub form_header {
   push @custom_hiddens, "select$form->{vc}";
 
   # currencies and exchangerate
-  @values = map { $_ } @{ $form->{ALL_CURRENCIES} };
-  %labels = map { $_ => $_ } @{ $form->{ALL_CURRENCIES} };
+  my @values = map { $_ } @{ $form->{ALL_CURRENCIES} };
+  my %labels = map { $_ => $_ } @{ $form->{ALL_CURRENCIES} };
   $form->{currency}            = $form->{defaultcurrency} unless $form->{currency};
   $TMPL_VAR{show_exchangerate} = $form->{currency} ne $form->{defaultcurrency};
   $TMPL_VAR{currencies}        = NTI($cgi->popup_menu('-name' => 'currency', '-default' => $form->{"currency"},
@@ -353,19 +364,18 @@ sub form_header {
   push @custom_hiddens, "exchangerate" if $form->{forex};
 
   # credit remaining
-  $creditwarning = (($form->{creditlimit} != 0) && ($form->{creditremaining} < 0) && !$form->{update}) ? 1 : 0;
+  my $creditwarning = (($form->{creditlimit} != 0) && ($form->{creditremaining} < 0) && !$form->{update}) ? 1 : 0;
   $TMPL_VAR{is_credit_remaining_negativ} = ($form->{creditremaining} =~ /-/) ? "0" : "1";
-  
+
   # business
   $TMPL_VAR{business_label} = ($form->{vc} eq "customer" ? $locale->text('Customer type') : $locale->text('Vendor type'));
 
-  push @custom_hiddens, "ordnumber"      if $form->{type} =~ /_quotation$/;
   push @custom_hiddens, "customer_klass" if $form->{vc} eq 'customer';
 
-  $credittext = $locale->text('Credit Limit exceeded!!!');
+  my $credittext = $locale->text('Credit Limit exceeded!!!');
 
   my $follow_up_vc                =  $form->{ $form->{vc} eq 'customer' ? 'customer' : 'vendor' };
-  $follow_up_vc                   =~ s/--.*?//;
+  $follow_up_vc                   =~ s/--\d*\s*$//;
   $TMPL_VAR{follow_up_trans_info} =  ($form->{type} =~ /_quotation$/ ? $form->{quonumber} : $form->{ordnumber}) . " ($follow_up_vc)";
 
   if ($form->{id}) {
@@ -377,10 +387,10 @@ sub form_header {
     }
   }
 
-  $onload = ($form->{resubmit} && ($form->{format} eq "html")) ? "window.open('about:blank','Beleg'); document.oe.target = 'Beleg';document.oe.submit()"
+  my $onload = ($form->{resubmit} && ($form->{format} eq "html")) ? "window.open('about:blank','Beleg'); document.oe.target = 'Beleg';document.oe.submit()"
           : ($form->{resubmit})                                ? "document.oe.submit()"
           : ($creditwarning)                                   ? "alert('$credittext')"
-          :                                                      "focus()";
+          :                                                      "";
 
   $onload .= qq|;setupDateFormat('|. $myconfig{dateformat} .qq|', '|. $locale->text("Falsches Datumsformat!") .qq|')|;
   $onload .= qq|;setupPoints('|.   $myconfig{numberformat} .qq|', '|. $locale->text("wrongformat") .qq|')|;
@@ -414,42 +424,46 @@ sub form_header {
 
   print $form->parse_html_template("oe/form_header", { %TMPL_VAR });
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub form_footer {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
+  my $locale   = $main::locale;
 
   check_oe_access();
 
   $form->{invtotal} = $form->{invsubtotal};
 
-  $rows    = max 2, $form->numtextrows($form->{notes}, 25, 8);
-  $introws = max 2, $form->numtextrows($form->{intnotes}, 35, 8);
+  my $rows    = max 2, $form->numtextrows($form->{notes}, 25, 8);
+  my $introws = max 2, $form->numtextrows($form->{intnotes}, 35, 8);
   $rows    = max $rows, $introws;
 
-  $TMPL_VAR{notes} = qq|<textarea name=notes rows=$rows cols=25 wrap=soft>$form->{notes}</textarea>|;
-  $TMPL_VAR{intnotes} = qq|<textarea name=intnotes rows=$rows cols=35 wrap=soft>$form->{intnotes}</textarea>|;
+  $TMPL_VAR{notes}    = qq|<textarea name=notes rows=$rows cols=25 wrap=soft>| . H($form->{notes}) . qq|</textarea>|;
+  $TMPL_VAR{intnotes} = qq|<textarea name=intnotes rows=$introws cols=35 wrap=soft>| . H($form->{intnotes}) . qq|</textarea>|;
 
   if (!$form->{taxincluded}) {
 
-    foreach $item (split / /, $form->{taxaccounts}) {
+    foreach my $item (split / /, $form->{taxaccounts}) {
       if ($form->{"${item}_base"}) {
         $form->{invtotal} += $form->{"${item}_total"} = $form->round_amount( $form->{"${item}_base"} * $form->{"${item}_rate"}, 2);
         $form->{"${item}_total"} = $form->format_amount(\%myconfig, $form->{"${item}_total"}, 2);
 
         $TMPL_VAR{tax} .= qq|
-             <tr>
-               <th align=right>$form->{"${item}_description"}&nbsp;| . $form->{"${item}_rate"} * 100 .qq|%</th>
-               <td align=right>$form->{"${item}_total"}</td>
-             </tr> |;
+              <tr>
+                <th align=right>$form->{"${item}_description"}&nbsp;| . $form->{"${item}_rate"} * 100 .qq|%</th>
+                <td align=right>$form->{"${item}_total"}</td>
+              </tr> |;
       }
     }
 
-    $form->{invsubtotal} = $form->format_amount(\%myconfig, $form->{invsubtotal}, 2, 0);
+#    $form->{invsubtotal} = $form->format_amount(\%myconfig, $form->{invsubtotal}, 2, 0); # template does this
 
   } else {
-    foreach $item (split / /, $form->{taxaccounts}) {
+    foreach my $item (split / /, $form->{taxaccounts}) {
       if ($form->{"${item}_base"}) {
         $form->{"${item}_total"} = $form->round_amount( ($form->{"${item}_base"} * $form->{"${item}_rate"} / (1 + $form->{"${item}_rate"})), 2);
         $form->{"${item}_netto"} = $form->round_amount( ($form->{"${item}_base"} - $form->{"${item}_total"}), 2);
@@ -457,14 +471,14 @@ sub form_footer {
         $form->{"${item}_netto"} = $form->format_amount(\%myconfig, $form->{"${item}_netto"}, 2);
 
         $TMPL_VAR{tax} .= qq|
-             <tr>
-               <th align=right>Enthaltene $form->{"${item}_description"}&nbsp;| . $form->{"${item}_rate"} * 100 .qq|%</th>
-               <td align=right>$form->{"${item}_total"}</td>
-             </tr>
-             <tr>
-               <th align=right>Nettobetrag</th>
-               <td align=right>$form->{"${item}_netto"}</td>
-             </tr> |;
+              <tr>
+                <th align=right>Enthaltene $form->{"${item}_description"}&nbsp;| . $form->{"${item}_rate"} * 100 .qq|%</th>
+                <td align=right>$form->{"${item}_total"}</td>
+              </tr>
+              <tr>
+                <th align=right>Nettobetrag</th>
+                <td align=right>$form->{"${item}_netto"}</td>
+              </tr> |;
       }
     }
   }
@@ -473,50 +487,57 @@ sub form_footer {
 
   print $form->parse_html_template("oe/form_footer", {
      %TMPL_VAR,
-     webdav          => $webdav,
+     webdav          => $main::webdav,
      print_options   => print_options(inline => 1),
      label_edit      => $locale->text("Edit the $form->{type}"),
      label_workflow  => $locale->text("Workflow $form->{type}"),
+     is_sales        => scalar ($form->{type} =~ /^sales_/),              # these vars are exported, so that the template
+     is_order        => scalar ($form->{type} =~ /_order$/),              # may determine what to show
+     is_sales_quo    => scalar ($form->{type} =~ /sales_quotation$/),
+     is_req_quo      => scalar ($form->{type} =~ /request_quotation$/),
+     is_sales_ord    => scalar ($form->{type} =~ /sales_order$/),
+     is_pur_ord      => scalar ($form->{type} =~ /purchase_order$/),
   });
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub update {
-  $lxdebug->enter_sub();
-  
+  $main::lxdebug->enter_sub();
+
   my ($recursive_call) = shift;
 
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
+
   check_oe_access();
 
+#  $main::lxdebug->message(0, Dumper($form));
+
   set_headings($form->{"id"} ? "edit" : "add");
 
   map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(exchangerate) unless $recursive_call;
   $form->{update} = 1;
-      
-  $payment_id = $form->{payment_id} if $form->{payment_id};
-  
+
   &check_name($form->{vc});
-  
-  $form->{payment_id} = $payment_id if $form->{payment_id} eq "";
-  
-  $buysell              = 'buy';
+
+  my $buysell           = 'buy';
   $buysell              = 'sell' if ($form->{vc} eq 'vendor');
   $form->{forex}        = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{transdate}, $buysell);
   $form->{exchangerate} = $form->{forex} if $form->{forex};
 
-  $exchangerate = $form->{exchangerate} || 1;
+  my $exchangerate = $form->{exchangerate} || 1;
 
 ##################### process items ######################################
   # for pricegroups
-  $i = $form->{rowcount};
+  my $i = $form->{rowcount};
   if (   ($form->{"partnumber_$i"} eq "")
       && ($form->{"description_$i"} eq "")
       && ($form->{"partsgroup_$i"}  eq "")) {
 
     $form->{creditremaining} += ($form->{oldinvtotal} - $form->{oldtotalpaid});
-    &check_form;
 
+    &check_form;
   } else {
 
     if ($form->{type} =~ /^sales/) {
@@ -527,28 +548,43 @@ sub update {
 
     my $rows = scalar @{ $form->{item_list} };
 
-    $form->{"discount_$i"} = $form->format_amount(\%myconfig, $form->{discount} * 100);
+    # hier ist das problem fuer bug 817 $form->{discount} wird nicht durchgeschliffen
+    # ferner fallunterscheidung fuer verkauf oder einkauf s.a. bug 736 jb 04.05.2009
+    # select discount as vendor_discount from vendor ||
+    # select discount as customer_discount from customer
+    $form->{"discount_$i"} = $form->format_amount(\%myconfig, $form->{"$form->{vc}_discount"} * 100);
+
+    $form->{"lastcost_$i"} = $form->parse_amount(\%myconfig, $form->{"lastcost_$i"});
 
     if ($rows) {
-      $form->{"qty_$i"} = 1 unless ($form->{"qty_$i"});
+      $form->{"qty_$i"} = 1 unless ($form->parse_amount(\%myconfig, $form->{"qty_$i"}));
 
       if ($rows > 1) {
 
         &select_item;
-        exit;
+        ::end_of_request();
 
       } else {
 
-        $sellprice             = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"});
-        $form->{"discount_$i"} = 0 if $form->{"not_discountable_$i"};
+        my $sellprice             = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"});
+        # hier werden parts (Artikeleigenschaften) aus item_list (retrieve_item aus IS.pm)
+        # (item wahrscheinlich synonym für parts) entsprechend in die form geschrieben ...
+
+        # Wäre dieses Mapping nicht besser in retrieve_items aufgehoben?
+        #(Eine Funktion bekommt Daten -> ARBEIT -> Rückgabe DATEN)
+        #  Das quot sieht doch auch nach Überarbeitung aus ... (hmm retrieve_items gibt es in IS und IR)
         map { $form->{item_list}[$i]{$_} =~ s/\"/&quot;/g }    qw(partnumber description unit);
         map { $form->{"${_}_$i"} = $form->{item_list}[0]{$_} } keys %{ $form->{item_list}[0] };
+
+        # ... deswegen muss die prüfung, ob es sich um einen nicht rabattierfähigen artikel handelt später erfolgen (Bug 1136)
+        $form->{"discount_$i"} = 0 if $form->{"not_discountable_$i"};
         $form->{payment_id} = $form->{"part_payment_id_$i"} if $form->{"part_payment_id_$i"} ne "";
 
         $form->{"marge_price_factor_$i"} = $form->{item_list}->[0]->{price_factor};
 
         ($sellprice || $form->{"sellprice_$i"}) =~ /\.(\d+)/;
-        $decimalplaces = max 2, length $1;
+        my $dec_qty       = length $1;
+        my $decimalplaces = max 2, $dec_qty;
 
         if ($sellprice) {
           $form->{"sellprice_$i"} = $sellprice;
@@ -557,7 +593,7 @@ sub update {
           $form->{"sellprice_$i"} /= $exchangerate;   # if there is an exchange rate adjust sellprice
         }
 
-        $amount = $form->{"sellprice_$i"} * $form->{"qty_$i"} * (1 - $form->{"discount_$i"} / 100);
+        my $amount = $form->{"sellprice_$i"} * $form->{"qty_$i"} * (1 - $form->{"discount_$i"} / 100);
         map { $form->{"${_}_base"} = 0 }                                 split / /, $form->{taxaccounts};
         map { $form->{"${_}_base"} += $amount }                          split / /, $form->{"taxaccounts_$i"};
         map { $amount += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } split / /, $form->{taxaccounts} if !$form->{taxincluded};
@@ -565,6 +601,7 @@ sub update {
         $form->{creditremaining} -= $amount;
 
         $form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
+        $form->{"lastcost_$i"}  = $form->format_amount(\%myconfig, $form->{"lastcost_$i"}, $decimalplaces);
         $form->{"qty_$i"}       = $form->format_amount(\%myconfig, $form->{"qty_$i"}, $dec_qty);
 
         # get pricegroups for parts
@@ -596,276 +633,78 @@ sub update {
 ##################### process items ######################################
 
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub search {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
+  my $locale   = $main::locale;
 
   check_oe_access();
 
   if ($form->{type} eq 'purchase_order') {
-    $form->{title} = $locale->text('Purchase Orders');
-    $form->{vc}    = 'vendor';
-    $ordlabel      = $locale->text('Order Number');
-    $ordnumber     = 'ordnumber';
-    $employee      = $locale->text('Employee');
-  }
-
-  if ($form->{type} eq 'request_quotation') {
-    $form->{title} = $locale->text('Request for Quotations');
-    $form->{vc}    = 'vendor';
-    $ordlabel      = $locale->text('RFQ Number');
-    $ordnumber     = 'quonumber';
-    $employee      = $locale->text('Employee');
-  }
+    $form->{vc}        = 'vendor';
+    $form->{ordnrname} = 'ordnumber';
+    $form->{title}     = $locale->text('Purchase Orders');
+    $form->{ordlabel}  = $locale->text('Order Number');
+
+  } elsif ($form->{type} eq 'request_quotation') {
+    $form->{vc}        = 'vendor';
+    $form->{ordnrname} = 'quonumber';
+    $form->{title}     = $locale->text('Request for Quotations');
+    $form->{ordlabel}  = $locale->text('RFQ Number');
+
+  } elsif ($form->{type} eq 'sales_order') {
+    $form->{vc}        = 'customer';
+    $form->{ordnrname} = 'ordnumber';
+    $form->{title}     = $locale->text('Sales Orders');
+    $form->{ordlabel}  = $locale->text('Order Number');
+
+  } elsif ($form->{type} eq 'sales_quotation') {
+    $form->{vc}        = 'customer';
+    $form->{ordnrname} = 'quonumber';
+    $form->{title}     = $locale->text('Quotations');
+    $form->{ordlabel}  = $locale->text('Quotation Number');
 
-  if ($form->{type} eq 'sales_order') {
-    $form->{title} = $locale->text('Sales Orders');
-    $form->{vc}    = 'customer';
-    $ordlabel      = $locale->text('Order Number');
-    $ordnumber     = 'ordnumber';
-    $employee      = $locale->text('Employee');
-  }
-
-  if ($form->{type} eq 'sales_quotation') {
-    $form->{title} = $locale->text('Quotations');
-    $form->{vc}    = 'customer';
-    $ordlabel      = $locale->text('Quotation Number');
-    $ordnumber     = 'quonumber';
-    $employee      = $locale->text('Employee');
-  }
-
-  # setup vendor / customer selection
-  $form->all_vc(\%myconfig, $form->{vc},
-                ($form->{vc} eq 'customer') ? "AR" : "AP");
-
-  # departments
-  if (@{ $form->{all_departments} }) {
-    $form->{selectdepartment} = "<option>\n";
-
-    map {
-      $form->{selectdepartment} .=
-        "<option>$_->{description}--$_->{id}</option>\n"
-    } (@{ $form->{all_departments} });
-  }
-
-  $department = qq|
-        <tr>
-         <th align=right nowrap>| . $locale->text('Department') . qq|</th>
-         <td colspan=3><select name=department>$form->{selectdepartment}</select></td>
-       </tr>
-| if $form->{selectdepartment};
-
-  my $delivered;
-  if (($form->{"type"} eq "sales_order") ||
-      ($form->{"type"} eq "purchase_order")) {
-    $delivered = qq|
-        <tr>
-          <td><input name="notdelivered" id="notdelivered" class="checkbox" type="checkbox" value="1" checked>
-            <label for="notdelivered">|. $locale->text('Not delivered') . qq|</label></td>
-          <td><input name="delivered" id="delivered" class="checkbox" type="checkbox" value="1" checked>
-            <label for="delivered">| . $locale->text('Delivered') . qq|</label></td>
-        </tr>
-|;
+  } else {
+    $form->show_generic_error($locale->text('oe.pl::search called with unknown type'), back_button => 1);
   }
 
-  # use JavaScript Calendar or not
-  $form->{jsscript} = 1;
-  $jsscript = "";
-
-  $button1 = qq|
-     <td><input name=transdatefrom id=transdatefrom size=11 title="$myconfig{dateformat}" onBlur=\"check_right_date_format(this)\">
-     <input type=button name=transdatefrom id="trigger3" value=|
-    . $locale->text('button') . qq|></td>
-    |;
-  $button2 = qq|
-     <td><input name=transdateto id=transdateto size=11 title="$myconfig{dateformat}" onBlur=\"check_right_date_format(this)\">
-     <input type=button name=transdateto name=transdateto id="trigger4" value=|
-    . $locale->text('button') . qq|></td>
-   |;
-
-  #write Trigger
-  $jsscript =
-    Form->write_trigger(\%myconfig, "2", "transdatefrom", "BR", "trigger3",
-                        "transdateto", "BL", "trigger4");
-
-  my $vc = $form->{vc} eq "customer" ? "customers" : "vendors";
-
-  $form->get_lists("projects"  => { "key" => "ALL_PROJECTS",
-                                    "all" => 1 },
-                   "employees" => "ALL_EMPLOYEES",
-                   "salesmen"  => "ALL_SALESMEN",
-                   $vc         => "ALL_" . uc($vc)
-                  );
-
-  my %labels = ();
-  my @values = ("");
-  foreach my $item (@{ $form->{"ALL_PROJECTS"} }) {
-    push(@values, $item->{"id"});
-    $labels{$item->{"id"}} = $item->{"projectnumber"};
-  }
-  my $projectnumber =
-    NTI($cgi->popup_menu('-name' => 'project_id', '-values' => \@values,
-                         '-labels' => \%labels));
-
-  #employees
-  %labels = ();
-  @values = ("");
-  foreach my $item (@{ $form->{"ALL_EMPLOYEES"} }) {
-    push(@values, $item->{"id"});
-    $labels{$item->{"id"}} = $item->{"name"} ne "" ? $item->{"name"} : $item->{"login"};
-  }
-  
-  #salesmen
-  my %labels_salesmen = ();
-  my @values_salesmen = ('');
-  foreach my $item (@{ $form->{"ALL_SALESMEN"} }) {
-    push(@values_salesmen, $item->{"id"});
-    $labels_salesmen{$item->{"id"}} = $item->{"name"} ne "" ? $item->{"name"} : $item->{"login"};
-  }
-
-  my $employee_block = qq|
-    <tr>
-      <th align="right">| . $locale->text('Employee') . qq|</th>
-      <td>| .  NTI($cgi->popup_menu('-name'   => 'employee_id', '-values' => \@values, '-labels' => \%labels)) . qq|</td>
-    </tr>
-    <tr>
-      <th align="right">| . $locale->text('Salesman') . qq|</th>
-      <td>| .
-        NTI($cgi->popup_menu('-name'   => 'salesman_id',
-                             '-values' => \@values_salesmen,
-                             '-labels' => \%labels_salesmen)) . qq|
-      </td>
-    </tr>|;
-
-  %labels = ();
-  @values = ("");
-
-  foreach my $item (@{ $form->{($form->{vc} eq "customer" ? "ALL_CUSTOMERS" : "ALL_VENDORS")}}) {
-    push(@values, $item->{name}.qq|--|.$item->{"id"});
-    $labels{$item->{name}.qq|--|.$item->{"id"}} = $item->{"name"};
-  }
-
-  my $vc_label = $form->{vc} eq "customer" ? $locale->text('Customer') : $locale->text('Vendor');
-  $vc =
-    $myconfig{vclimit} <=  scalar(@values)
-    ? qq|<input type="text" value="| . H(($form->{"old$form->{vc}"} =~ /^(.*)\-\-.*$/)) . qq|" name="$form->{vc}">| 
-    : NTI($cgi->popup_menu('-name' => "$form->{vc}",
-                           '-default' => $form->{"old$form->{vc}"},
-                           '-onChange' => 'document.getElementById(\'update_button\').click();',
-                           '-values' => \@values,
-                           '-labels' => \%labels));
-  $form->header;
-
-  print qq|
-<body>
-
-<form method=post action=$form->{script}>
-
-<table width=100%>
-  <tr>
-    <th class=listtop>$form->{title}</th>
-  </tr>
-  <tr height="5"></tr>
-  <tr>
-    <td>
-      <table>
-        <tr>
-          <th align=right>$vc_label</th>
-          <td colspan=3>$vc</td>
-        </tr>
-$department
-        <tr>
-          <th align=right>$ordlabel</th>
-          <td colspan=3><input name="$ordnumber" size=20></td>
-        </tr>
-$employee_block
-        <tr>
-          <th align="right">| . $locale->text('Transaction description') . qq|</th>
-          <td colspan="3"><input name="transaction_description" size=20></td>
-        </tr>
-        <tr>
-          <th align="right">| . $locale->text("Project Number") . qq|</th>
-          <td colspan="3">$projectnumber</td>
-        </tr>
-        <tr>
-          <th align=right>| . $locale->text('From') . qq|</th> $button1
-          <th align=right>| . $locale->text('Bis') . qq|</th> $button2
-        </tr>
-        <input type=hidden name=sort value=transdate>
-        <tr>
-          <th align=right>| . $locale->text('Include in Report') . qq|</th>
-          <td colspan=5>
-           <table>
-        <tr>
-          <td><input type="checkbox" name="open" value="1" id="open" checked> <label for="open">| . $locale->text("Open") . qq|</td>
-          <td><input type="checkbox" name="closed" value="1" id="closed"> <label for="closed">| . $locale->text("Closed") . qq|</td>
-        </tr>
-        $delivered
-             <tr>
-               <td><input name="l_id" class=checkbox type=checkbox value=Y> | . $locale->text('ID') . qq|</td>
-               <td><input name="l_$ordnumber" class=checkbox type=checkbox value=Y checked> $ordlabel</td>
-             </tr>
-             <tr>
-               <td><input name="l_transdate" class=checkbox type=checkbox value=Y checked> | . $locale->text('Date') . qq|</td>
-               <td><input name="l_reqdate" class=checkbox type=checkbox value=Y checked> | . $locale->text('Required by') . qq|</td>
-             </tr>
-             <tr>
-               <td><input name="l_name" class=checkbox type=checkbox value=Y checked> $vc_label</td>
-               <td><input name="l_employee" class=checkbox type=checkbox value=Y checked> $employee</td>
-               
-               <td><input name="l_shipvia" class=checkbox type=checkbox value=Y> | . $locale->text('Ship via') . qq|</td>
-             </tr>
-             <tr>
-               <td><input name="l_netamount" class=checkbox type=checkbox value=Y> | . $locale->text('Amount') . qq|</td>
-               <td><input name="l_tax" class=checkbox type=checkbox value=Y> | . $locale->text('Tax') . qq|</td>
-               <td><input name="l_amount" class=checkbox type=checkbox value=Y checked> | . $locale->text('Total') . qq|</td>
-             </tr>
-             <tr>
-               <td><input name="l_marge_total" class=checkbox type=checkbox value=Y> | .             $locale->text('Ertrag') . qq|</td>
-               <td><input name="l_marge_percent" class=checkbox type=checkbox value=Y> | .             $locale->text('Ertrag prozentual') . qq|</td>
-             </tr>
-             <tr>
-          <td><input name="l_globalprojectnumber" class=checkbox type=checkbox value=Y> | . $locale->text('Project Number') . qq|</td>
-          <td><input name="l_transaction_description" class=checkbox type=checkbox value=Y> | . $locale->text('Transaction description') . qq|</td>
-             </tr>
-             <tr>
-               <td><input name="l_subtotal" class=checkbox type=checkbox value=Y> | . $locale->text('Subtotal') . qq|</td>
-                <td><input name="l_salesman" class="checkbox" type="checkbox" value="Y"> | . $locale->text('Salesman') . qq|</td>
-             </tr>
-           </table>
-          </td>
-        </tr>
-      </table>
-    </td>
-  </tr>
-  <tr><td colspan=4><hr size=3 noshade></td></tr>
-</table>
-
-$jsscript
-
-<br>
-<input type=hidden name=nextsub value=orders>
-<input type=hidden name=vc value=$form->{vc}>
-<input type=hidden name=type value=$form->{type}>
+  # setup vendor / customer data
+  $form->all_vc(\%myconfig, $form->{vc}, ($form->{vc} eq 'customer') ? "AR" : "AP");
+  $form->get_lists("projects"     => { "key" => "ALL_PROJECTS", "all" => 1 },
+                   "employees"    => "ALL_EMPLOYEES",
+                   "salesmen"     => "ALL_SALESMEN",
+                   "departments"  => "ALL_DEPARTMENTS",
+                   "$form->{vc}s" => "ALL_VC");
+
+  # constants and subs for template
+  $form->{jsscript}        = 1;
+  $form->{employee_labels} = sub { $_[0]->{"name"} || $_[0]->{"login"} };
+  $form->{vc_keys}         = sub { "$_[0]->{name}--$_[0]->{id}" };
+  $form->{salesman_labels} = $form->{employee_labels};
 
-<input class=submit type=submit name=action value="|
-    . $locale->text('Continue') . qq|">
-</form>
+  $form->header();
 
-</body>
-</html>
-|;
+  print $form->parse_html_template('oe/search', {
+    %myconfig,
+    is_order => $form->{type} =~ /_order/,
+  });
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub create_subtotal_row {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
 
   my ($totals, $columns, $column_alignment, $subtotal_columns, $class) = @_;
 
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
+
   my $row = { map { $_ => { 'data' => '', 'class' => $class, 'align' => $column_alignment->{$_}, } } @{ $columns } };
 
   map { $row->{$_}->{data} = $form->format_amount(\%myconfig, $totals->{$_}, 2) } @{ $subtotal_columns };
@@ -874,19 +713,24 @@ sub create_subtotal_row {
 
   map { $totals->{$_} = 0 } @{ $subtotal_columns };
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 
   return $row;
 }
 
 sub orders {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
+  my $locale   = $main::locale;
+  my $cgi      = $main::cgi;
 
   check_oe_access();
 
-  $ordnumber = ($form->{type} =~ /_order$/) ? "ordnumber" : "quonumber";
+  my $ordnumber = ($form->{type} =~ /_order$/) ? "ordnumber" : "quonumber";
 
-  ($form->{ $form->{vc} }, $form->{"${form->{vc}}_id"}) = split(/--/, $form->{ $form->{vc} });
+  ($form->{ $form->{vc} }, $form->{"$form->{vc}_id"}) = split(/--/, $form->{ $form->{vc} });
 
   report_generator_set_default_sort('transdate', 1);
 
@@ -903,7 +747,9 @@ sub orders {
     "salesman",
     "shipvia",                 "globalprojectnumber",
     "transaction_description", "open",
-    "delivered", "marge_total", "marge_percent"
+    "delivered", "marge_total", "marge_percent",
+    "vcnumber",                "ustid",
+    "country",
   );
 
   # only show checkboxes if gotten here via sales_order form.
@@ -939,14 +785,15 @@ sub orders {
 
   my @hidden_variables = map { "l_${_}" } @columns;
   push @hidden_variables, "l_subtotal", $form->{vc}, qw(l_closed l_notdelivered open closed delivered notdelivered ordnumber quonumber
-                                                        transaction_description transdatefrom transdateto type vc employee_id salesman_id);
+                                                        transaction_description transdatefrom transdateto type vc employee_id salesman_id
+                                                        reqdatefrom reqdateto projectnumber project_id);
 
   my $href = build_std_url('action=orders', grep { $form->{$_} } @hidden_variables);
 
   my %column_defs = (
     'ids'                     => { 'text' => '', },
     'transdate'               => { 'text' => $locale->text('Date'), },
-    'reqdate'                 => { 'text' => $locale->text('Required by'), },
+    'reqdate'                 => { 'text' => $form->{type} =~ /_order/ ? $locale->text('Required by') : $locale->text('Valid until') },
     'id'                      => { 'text' => $locale->text('ID'), },
     'ordnumber'               => { 'text' => $locale->text('Order'), },
     'quonumber'               => { 'text' => $form->{type} eq "request_quotation" ? $locale->text('RFQ') : $locale->text('Quotation'), },
@@ -963,10 +810,13 @@ sub orders {
     'open'                    => { 'text' => $locale->text('Open'), },
     'delivered'               => { 'text' => $locale->text('Delivered'), },
     'marge_total'             => { 'text' => $locale->text('Ertrag'), },
-    'marge_percent'           => { 'text' => $locale->text('Ertrag prozentual'), }
+    'marge_percent'           => { 'text' => $locale->text('Ertrag prozentual'), },
+    'vcnumber'                => { 'text' => $form->{vc} eq 'customer' ? $locale->text('Customer Number') : $locale->text('Vendor Number'), },
+    'country'                 => { 'text' => $locale->text('Country'), },
+    'ustid'                   => { 'text' => $locale->text('USt-IdNr.'), },
   );
 
-  foreach my $name (qw(id transdate reqdate quonumber ordnumber name employee salesman shipvia)) {
+  foreach my $name (qw(id transdate reqdate quonumber ordnumber name employee salesman shipvia transaction_description)) {
     my $sortdir                 = $form->{sort} eq $name ? 1 - $form->{sortdir} : $form->{sortdir};
     $column_defs{$name}->{link} = $href . "&sort=$name&sortdir=$sortdir";
   }
@@ -979,7 +829,7 @@ sub orders {
 
   $report->set_columns(%column_defs);
   $report->set_column_order(@columns);
-  $report->set_export_options('orders', @hidden_variables);
+  $report->set_export_options('orders', @hidden_variables, qw(sort sortdir));
   $report->set_sort_indicator($form->{sort}, $form->{sortdir});
 
   my @options;
@@ -991,8 +841,16 @@ sub orders {
   push @options, $locale->text('Order Number')            . " : $form->{ordnumber}"                       if $form->{ordnumber};
   push @options, $locale->text('Notes')                   . " : $form->{notes}"                           if $form->{notes};
   push @options, $locale->text('Transaction description') . " : $form->{transaction_description}"         if $form->{transaction_description};
-  push @options, $locale->text('From') . "&nbsp;" . $locale->date(\%myconfig, $form->{transdatefrom}, 1)  if $form->{transdatefrom};
-  push @options, $locale->text('Bis')  . "&nbsp;" . $locale->date(\%myconfig, $form->{transdateto},   1)  if $form->{transdateto};
+  if ( $form->{transdatefrom} or $form->{transdateto} ) {
+    push @options, $locale->text('Order Date');
+    push @options, $locale->text('From') . " " . $locale->date(\%myconfig, $form->{transdatefrom}, 1)     if $form->{transdatefrom};
+    push @options, $locale->text('Bis')  . " " . $locale->date(\%myconfig, $form->{transdateto},   1)     if $form->{transdateto};
+  };
+  if ( $form->{reqdatefrom} or $form->{reqdateto} ) {
+    push @options, $locale->text('Delivery Date');
+    push @options, $locale->text('From') . " " . $locale->date(\%myconfig, $form->{reqdatefrom}, 1)       if $form->{reqdatefrom};
+    push @options, $locale->text('Bis')  . " " . $locale->date(\%myconfig, $form->{reqdateto},   1)       if $form->{reqdateto};
+  };
   push @options, $locale->text('Open')                                                                    if $form->{open};
   push @options, $locale->text('Closed')                                                                  if $form->{closed};
   push @options, $locale->text('Delivered')                                                               if $form->{delivered};
@@ -1006,12 +864,13 @@ sub orders {
                        'attachment_basename'  => $attachment_basename . strftime('_%Y%m%d', localtime time),
     );
   $report->set_options_from_form();
+  $locale->set_numberformat_wo_thousands_separator(\%myconfig) if lc($report->{options}->{output_format}) eq 'csv';
 
   # add sort and escape callback, this one we use for the add sub
   $form->{callback} = $href .= "&sort=$form->{sort}";
 
   # escape callback for href
-  $callback = $form->escape($href);
+  my $callback = $form->escape($href);
 
   my @subtotal_columns = qw(netamount amount marge_total marge_percent);
 
@@ -1022,7 +881,7 @@ sub orders {
 
   my $edit_url = build_std_url('action=edit', 'type', 'vc');
 
-  foreach $oe (@{ $form->{OE} }) {
+  foreach my $oe (@{ $form->{OE} }) {
     map { $oe->{$_} *= $oe->{exchangerate} } @subtotal_columns;
 
     $oe->{tax}       = $oe->{amount} - $oe->{netamount};
@@ -1074,16 +933,19 @@ sub orders {
 
   $report->generate_with_headers();
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub check_delivered_flag {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
 
   check_oe_access();
 
   if (($form->{type} ne 'sales_order') && ($form->{type} ne 'purchase_order')) {
-    return $lxdebug->leave_sub();
+    return $main::lxdebug->leave_sub();
   }
 
   my $all_delivered = 0;
@@ -1102,11 +964,15 @@ sub check_delivered_flag {
 
   $form->{delivered} = 1 if $all_delivered;
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub save_and_close {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
+  my $locale   = $main::locale;
 
   check_oe_access();
 
@@ -1122,7 +988,7 @@ sub save_and_close {
   $form->{$idx} =~ s/^\s*//g;
   $form->{$idx} =~ s/\s*$//g;
 
-  $msg = ucfirst $form->{vc};
+  my $msg = ucfirst $form->{vc};
   $form->isblank($form->{vc}, $locale->text($msg . " missing!"));
 
   # $locale->text('Customer missing!');
@@ -1132,22 +998,24 @@ sub save_and_close {
     if ($form->{currency} ne $form->{defaultcurrency});
 
   &validate_items;
-  
-  if($form->{payment_id}) { 
+
+  my $payment_id;
+  if($form->{payment_id}) {
     $payment_id = $form->{payment_id};
   }
-  
+
   # if the name changed get new values
   if (&check_name($form->{vc})) {
-    if($form->{payment_id} eq "") { 
+    if($form->{payment_id} eq "") {
       $form->{payment_id} = $payment_id;
     }
     &update;
-    exit;
+    ::end_of_request();
   }
 
   $form->{id} = 0 if $form->{saveasnew};
 
+  my ($numberfld, $ordnumber, $err);
   # this is for the internal notes section for the [email] Subject
   if ($form->{type} =~ /_order$/) {
     if ($form->{type} eq 'sales_order') {
@@ -1195,19 +1063,23 @@ sub save_and_close {
   # saving the history
   if(!exists $form->{addition}) {
     $form->{snumbers} = qq|ordnumber_| . $form->{ordnumber};
-       $form->{addition} = "SAVED";
-       $form->save_history($form->dbconnect(\%myconfig));
+    $form->{addition} = "SAVED";
+    $form->save_history;
   }
   # /saving the history
 
   $form->redirect($form->{label} . " $form->{$ordnumber} " .
                   $locale->text('saved!'));
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub save {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
+  my $locale   = $main::locale;
 
   check_oe_access();
 
@@ -1224,7 +1096,7 @@ sub save {
   $form->{$idx} =~ s/^\s*//g;
   $form->{$idx} =~ s/\s*$//g;
 
-  $msg = ucfirst $form->{vc};
+  my $msg = ucfirst $form->{vc};
   $form->isblank($form->{vc}, $locale->text($msg . " missing!"));
 
   # $locale->text('Customer missing!');
@@ -1233,23 +1105,27 @@ sub save {
   $form->isblank("exchangerate", $locale->text('Exchangerate missing!'))
     if ($form->{currency} ne $form->{defaultcurrency});
 
+  remove_emptied_rows();
   &validate_items;
-  
-  if($form->{payment_id}) { 
+
+  my $payment_id;
+  if($form->{payment_id}) {
     $payment_id = $form->{payment_id};
   }
-  
+
   # if the name changed get new values
   if (&check_name($form->{vc})) {
-    if($form->{payment_id} eq "") { 
+    if($form->{payment_id} eq "") {
       $form->{payment_id} = $payment_id;
     }
     &update;
-    exit;
+    ::end_of_request();
   }
 
   $form->{id} = 0 if $form->{saveasnew};
 
+  my ($numberfld, $ordnumber, $err);
+
   # this is for the internal notes section for the [email] Subject
   if ($form->{type} =~ /_order$/) {
     if ($form->{type} eq 'sales_order') {
@@ -1295,27 +1171,31 @@ sub save {
   # saving the history
   if(!exists $form->{addition}) {
     $form->{snumbers} = qq|ordnumber_| . $form->{ordnumber};
-       $form->{addition} = "SAVED";
-       $form->save_history($form->dbconnect(\%myconfig));
+    $form->{addition} = "SAVED";
+    $form->save_history;
   }
-  # /saving the history 
+  # /saving the history
 
   $form->{simple_save} = 1;
   if(!$form->{print_and_save}) {
-    set_headings("edit");
-    &update;
-    exit;
+    delete @{$form}{ary_diff([keys %{ $form }], [qw(login stylesheet id script type cursor_fokus)])};
+    edit();
+    ::end_of_request();
   }
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub delete {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+  my $locale   = $main::locale;
 
   check_oe_access();
 
   $form->header;
 
+  my ($msg, $ordnumber);
   if ($form->{type} =~ /_order$/) {
     $msg       = $locale->text('Are you sure you want to delete Order Number');
     $ordnumber = 'ordnumber';
@@ -1333,7 +1213,7 @@ sub delete {
   # delete action variable
   map { delete $form->{$_} } qw(action header);
 
-  foreach $key (keys %$form) {
+  foreach my $key (keys %$form) {
     next if (($key eq 'login') || ($key eq 'password') || ('' ne ref $form->{$key}));
     $form->{$key} =~ s/\"/&quot;/g;
     print qq|<input type=hidden name=$key value="$form->{$key}">\n|;
@@ -1355,14 +1235,19 @@ sub delete {
 </html>
 |;
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub delete_order_quotation {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
+  my $locale   = $main::locale;
 
   check_oe_access();
 
+  my ($msg, $err);
   if ($form->{type} =~ /_order$/) {
     $msg = $locale->text('Order deleted!');
     $err = $locale->text('Cannot delete order!');
@@ -1370,30 +1255,35 @@ sub delete_order_quotation {
     $msg = $locale->text('Quotation deleted!');
     $err = $locale->text('Cannot delete quotation!');
   }
-  if (OE->delete(\%myconfig, \%$form, $spool)){
+  if (OE->delete(\%myconfig, \%$form, $main::spool)){
     # saving the history
     if(!exists $form->{addition}) {
       $form->{snumbers} = qq|ordnumber_| . $form->{ordnumber};
-         $form->{addition} = "DELETED";
-         $form->save_history($form->dbconnect(\%myconfig));
+      $form->{addition} = "DELETED";
+      $form->save_history;
     }
-    # /saving the history 
+    # /saving the history
     $form->info($msg);
-    exit();
+    ::end_of_request();
   }
   $form->error($err);
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub invoice {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
+  my $locale   = $main::locale;
 
   check_oe_access();
-  $auth->assert($form->{type} eq 'purchase_order' || $form->{type} eq 'request_quotation' ? 'vendor_invoice_edit' : 'invoice_edit');
+  $main::auth->assert($form->{type} eq 'purchase_order' || $form->{type} eq 'request_quotation' ? 'vendor_invoice_edit' : 'invoice_edit');
 
-  $form->{old_employee_id} = $form->{employee_id};
   $form->{old_salesman_id} = $form->{salesman_id};
+  $form->get_employee();
+
 
   if ($form->{type} =~ /_order$/) {
 
@@ -1413,24 +1303,25 @@ sub invoice {
     $form->{ordnumber}    = "";
     $form->{quodate}      = $form->{transdate};
   }
-  
-  $payment_id = $form->{payment_id} if $form->{payment_id};
-  
+
+  my $payment_id = $form->{payment_id} if $form->{payment_id};
+
   # if the name changed get new values
   if (&check_name($form->{vc})) {
     $form->{payment_id} = $payment_id if $form->{payment_id} eq "";
     &update;
-    exit;
+    ::end_of_request();
   }
 
   $form->{cp_id} *= 1;
 
-  for $i (1 .. $form->{rowcount}) {
+  for my $i (1 .. $form->{rowcount}) {
     for (qw(ship qty sellprice listprice basefactor)) {
       $form->{"${_}_${i}"} = $form->parse_amount(\%myconfig, $form->{"${_}_${i}"}) if $form->{"${_}_${i}"};
     }
   }
 
+  my ($buysell, $orddate, $exchangerate);
   if (   $form->{type} =~ /_order/
       && $form->{currency} ne $form->{defaultcurrency}) {
 
@@ -1442,22 +1333,10 @@ sub invoice {
 
     if (!$exchangerate) {
       &backorder_exchangerate($orddate, $buysell);
-      exit;
+      ::end_of_request();
     }
   }
 
-  # close orders/quotations
-  $form->{closed} = 1;
-
-  # save order if one ordnumber has been given
-  # if not it's most likely a collective order, which can't be saved back
-  # so they just have to be closed
-  if (($form->{ordnumber} ne '') || ($form->{quonumber} ne '')) {
-    OE->close_order(\%myconfig, \%$form) if ($form->{id});
-  } else {
-    OE->close_orders(\%myconfig, \%$form);
-  }
-
   $form->{convert_from_oe_ids} = $form->{id};
   $form->{transdate}           = $form->{invdate} = $form->current_date(\%myconfig);
   $form->{duedate}             = $form->current_date(\%myconfig, $form->{invdate}, $form->{terms} * 1);
@@ -1472,6 +1351,7 @@ sub invoice {
     &create_backorder;
   }
 
+  my ($script);
   if (   $form->{type} eq 'purchase_order'
       || $form->{type} eq 'request_quotation') {
     $form->{title}  = $locale->text('Add Vendor Invoice');
@@ -1480,7 +1360,7 @@ sub invoice {
     $buysell        = 'sell';
   }
 
-  if (   $form->{type} eq 'sales_order' 
+  if (   $form->{type} eq 'sales_order'
       || $form->{type} eq 'sales_quotation') {
     $form->{title}  = $locale->text('Add Sales Invoice');
     $form->{script} = 'is.pl';
@@ -1494,13 +1374,14 @@ sub invoice {
   $form->{type} = "invoice";
 
   # locale messages
-  $locale = new Locale "$myconfig{countrycode}", "$script";
+  $main::locale = new Locale "$myconfig{countrycode}", "$script";
+  $locale = $main::locale;
 
   require "bin/mozilla/$form->{script}";
 
-  map { $form->{"select$_"} = "" } ($form->{vc}, currency);
+  map { $form->{"select$_"} = "" } ($form->{vc}, "currency");
 
-  $currency = $form->{currency};
+  my $currency = $form->{currency};
   &invoice_links;
 
   $form->{currency}     = $currency;
@@ -1512,13 +1393,13 @@ sub invoice {
   &prepare_invoice;
 
   # format amounts
-  for $i (1 .. $form->{rowcount}) {
+  for my $i (1 .. $form->{rowcount}) {
     $form->{"discount_$i"} =
       $form->format_amount(\%myconfig, $form->{"discount_$i"});
 
-    ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/);
+    my ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/);
     $dec           = length $dec;
-    $decimalplaces = ($dec > 2) ? $dec : 2;
+    my $decimalplaces = ($dec > 2) ? $dec : 2;
 
     # copy delivery date from reqdate for order -> invoice conversion
     $form->{"deliverydate_$i"} = $form->{"reqdate_$i"}
@@ -1538,13 +1419,20 @@ sub invoice {
 
   }
 
+  #  show pricegroup in newly loaded invoice when creating invoice from quotation/order
+  IS->get_pricegroups_for_parts(\%myconfig, \%$form);
+  set_pricegroup($_) for 1 .. $form->{rowcount};
+
   &display_form;
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub backorder_exchangerate {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+  my $locale   = $main::locale;
 
   check_oe_access();
 
@@ -1561,7 +1449,7 @@ sub backorder_exchangerate {
   # delete action variable
   map { delete $form->{$_} } qw(action header exchangerate);
 
-  foreach $key (keys %$form) {
+  foreach my $key (keys %$form) {
     next if (($key eq 'login') || ($key eq 'password') || ('' ne ref $form->{$key}));
     $form->{$key} =~ s/\"/&quot;/g;
     print qq|<input type=hidden name=$key value="$form->{$key}">\n|;
@@ -1581,16 +1469,16 @@ sub backorder_exchangerate {
     <td>
       <table>
         <tr>
-         <th align=right>| . $locale->text('Currency') . qq|</th>
-         <td>$form->{currency}</td>
-       </tr>
-       <tr>
-         <th align=right>| . $locale->text('Date') . qq|</th>
-         <td>$orddate</td>
-       </tr>
+          <th align=right>| . $locale->text('Currency') . qq|</th>
+          <td>$form->{currency}</td>
+        </tr>
+        <tr>
+          <th align=right>| . $locale->text('Date') . qq|</th>
+          <td>$orddate</td>
+        </tr>
         <tr>
-         <th align=right>| . $locale->text('Exchangerate') . qq|</th>
-         <td><input name=exchangerate size=11></td>
+          <th align=right>| . $locale->text('Exchangerate') . qq|</th>
+          <td><input name=exchangerate size=11></td>
         </tr>
       </table>
     </td>
@@ -1611,11 +1499,15 @@ sub backorder_exchangerate {
 </html>
 |;
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub save_exchangerate {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
+  my $locale   = $main::locale;
 
   $form->isblank("exchangerate", $locale->text('Exchangerate missing!'));
   $form->{exchangerate} =
@@ -1626,20 +1518,26 @@ sub save_exchangerate {
 
   &invoice;
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub create_backorder {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
 
   $form->{shipped} = 1;
 
   # figure out if we need to create a backorder
   # items aren't saved if qty != 0
 
-  for $i (1 .. $form->{rowcount}) {
-    $totalqty  += $qty  = $form->{"qty_$i"};
-    $totalship += $ship = $form->{"ship_$i"};
+  my ($totalqty, $totalship);
+  for my $i (1 .. $form->{rowcount}) {
+    my $qty  = $form->{"qty_$i"};
+    my $ship = $form->{"ship_$i"};
+    $totalqty  += $qty;
+    $totalship += $ship;
 
     $form->{"qty_$i"} = $qty - $ship;
   }
@@ -1657,11 +1555,11 @@ sub create_backorder {
     return;
   }
 
-  @flds = (
+  my @flds = (
     qw(partnumber description qty ship unit sellprice discount id inventory_accno bin income_accno expense_accno listprice assembly taxaccounts partsgroup)
   );
 
-  for $i (1 .. $form->{rowcount}) {
+  for my $i (1 .. $form->{rowcount}) {
     map {
       $form->{"${_}_$i"} =
         $form->format_amount(\%myconfig, $form->{"${_}_$i"})
@@ -1673,15 +1571,15 @@ sub create_backorder {
   OE->save(\%myconfig, \%$form);
 
   # rebuild rows for invoice
-  @a     = ();
-  $count = 0;
+  my @a     = ();
+  my $count = 0;
 
-  for $i (1 .. $form->{rowcount}) {
+  for my $i (1 .. $form->{rowcount}) {
     $form->{"qty_$i"} = $form->{"ship_$i"};
 
     if ($form->{"qty_$i"}) {
       push @a, {};
-      $j = $#a;
+      my $j = $#a;
       map { $a[$j]->{$_} = $form->{"${_}_$i"} } @flds;
       $count++;
     }
@@ -1690,17 +1588,18 @@ sub create_backorder {
   $form->redo_rows(\@flds, \@a, $count, $form->{rowcount});
   $form->{rowcount} = $count;
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub save_as_new {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
 
   check_oe_access();
 
   $form->{saveasnew} = 1;
-  $form->{closed}    = 0;
-  map { delete $form->{$_} } qw(printed emailed queued);
+  map { delete $form->{$_} } qw(printed emailed queued delivered closed);
 
   # Let Lx-Office assign a new order number if the user hasn't changed the
   # previous one. If it has been changed manually then use it as-is.
@@ -1712,13 +1611,26 @@ sub save_as_new {
     delete($form->{$idx});
   }
 
+  # clear reqdate unless changed
+  if ($form->{reqdate} && $form->{id}) {
+    my $saved_order = OE->retrieve_simple(id => $form->{id});
+    if ($saved_order && $saved_order->{reqdate} eq $form->{reqdate}) {
+      delete $form->{reqdate};
+    }
+  }
+
+  # update employee
+  $form->get_employee();
+
   &save;
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub check_for_direct_delivery_yes {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
 
   check_oe_access();
 
@@ -1727,11 +1639,13 @@ sub check_for_direct_delivery_yes {
   map { s/^CFDD_//; $form->{$_} = $form->{"CFDD_${_}"} } grep /^CFDD_/, keys %{ $form };
   $form->{shipto} = 1;
   purchase_order();
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub check_for_direct_delivery_no {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
 
   check_oe_access();
 
@@ -1739,17 +1653,20 @@ sub check_for_direct_delivery_no {
   delete @{$form}{grep /^shipto/, keys %{ $form }};
   purchase_order();
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub check_for_direct_delivery {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
 
   check_oe_access();
 
   if ($form->{direct_delivery_checked}
       || (!$form->{shiptoname} && !$form->{shiptostreet} && !$form->{shipto_id})) {
-    $lxdebug->leave_sub();
+    $main::lxdebug->leave_sub();
     return;
   }
 
@@ -1766,26 +1683,26 @@ sub check_for_direct_delivery {
   $form->header();
   print $form->parse_html_template("oe/check_for_direct_delivery");
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 
-  exit 0;
+  ::end_of_request();
 }
 
 sub purchase_order {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+  my $locale   = $main::locale;
 
   check_oe_access();
-  $auth->assert('purchase_order_edit');
+  $main::auth->assert('purchase_order_edit');
 
+  $form->{sales_order_to_purchase_order} = 0;
   if ($form->{type} eq 'sales_order') {
+    $form->{sales_order_to_purchase_order} = 1;
     check_for_direct_delivery();
   }
 
-  if (   $form->{type} eq 'sales_quotation'
-      || $form->{type} eq 'request_quotation') {
-    OE->close_order(\%myconfig, \%$form);
-  }
-
   if ($form->{type} =~ /^sales_/) {
     delete($form->{ordnumber});
   }
@@ -1796,21 +1713,23 @@ sub purchase_order {
   $form->{vc}    = "vendor";
   $form->{type}  = "purchase_order";
 
+  $form->get_employee();
+
   &poso;
 
-  $lxdebug->leave_sub();
+  delete $form->{sales_order_to_purchase_order};
+
+  $main::lxdebug->leave_sub();
 }
 
 sub sales_order {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
 
-  check_oe_access();
-  $auth->assert('sales_order_edit');
+  my $form     = $main::form;
+  my $locale   = $main::locale;
 
-  if (   $form->{type} eq 'sales_quotation'
-      || $form->{type} eq 'request_quotation') {
-    OE->close_order(\%myconfig, $form);
-  }
+  check_oe_access();
+  $main::auth->assert('sales_order_edit');
 
   if ($form->{type} eq "purchase_order") {
     delete($form->{ordnumber});
@@ -1822,16 +1741,21 @@ sub sales_order {
   $form->{vc}     = "customer";
   $form->{type}   = "sales_order";
 
+  $form->get_employee();
+
   &poso;
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub poso {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
 
   check_oe_access();
-  $auth->assert('purchase_order_edit | sales_order_edit');
+  $main::auth->assert('purchase_order_edit | sales_order_edit');
 
   $form->{transdate} = $form->current_date(\%myconfig);
   delete $form->{duedate};
@@ -1843,10 +1767,17 @@ sub poso {
   $form->{old_salesman_id}     = $form->{salesman_id};
 
   # reset
-  map { delete $form->{$_} } qw(id subject message cc bcc printed emailed queued customer vendor creditlimit creditremaining discount tradediscount oldinvtotal delivered);
+  map { delete $form->{$_} } qw(id subject message cc bcc printed emailed queued customer vendor creditlimit creditremaining discount tradediscount oldinvtotal delivered ordnumber);
 
-  for $i (1 .. $form->{rowcount}) {
-    map { $form->{"${_}_${i}"} = $form->parse_amount(\%myconfig, $form->{"${_}_${i}"}) if ($form->{"${_}_${i}"}) } qw(ship qty sellprice listprice basefactor);
+  # if purchase_order was generated from sales_order, use  lastcost_$i as sellprice_$i
+  if ( $form->{sales_order_to_purchase_order} ) {
+    for my $i (1 .. $form->{rowcount}) {
+      $form->{"sellprice_${i}"} = $form->format_amount(\%myconfig,$form->{"lastcost_${i}"});
+    };
+  };
+
+  for my $i (1 .. $form->{rowcount}) {
+    map { $form->{"${_}_${i}"} = $form->parse_amount(\%myconfig, $form->{"${_}_${i}"}) if ($form->{"${_}_${i}"}) } qw(ship qty sellprice listprice basefactor discount);
   }
 
   my %saved_vars = map { $_ => $form->{$_} } grep { $form->{$_} } qw(currency);
@@ -1855,36 +1786,45 @@ sub poso {
 
   map { $form->{$_} = $saved_vars{$_} } keys %saved_vars;
 
-  &prepare_order;
-
-  # format amounts
-  for $i (1 .. $form->{rowcount} - 1) {
-    map { $form->{"${_}_$i"} =~ s/\"/&quot;/g } qw(partnumber description unit);
-  }
+  # prepare_order assumes that the discount is in db-notation (0.05) and not user-notation (5)
+  # and therefore multiplies the values by 100 in the case of reading from db or making an order
+  # from several quotation, so we convert this back into percent-notation for the user interface by multiplying with 0.01
+  # ergänzung 03.10.2010 muss vor prepare_order passieren (s.a. Svens Kommentar zu Bug 1017)
+  # das parse_amount wird oben schon ausgeführt, deswegen an dieser stelle raus (wichtig: kommawerte bei discount testen)
+  for my $i (1 .. $form->{rowcount}) {
+    $form->{"discount_$i"} /=100;
+  };
 
+  &prepare_order;
   &update;
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub delivery_order {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
 
   if ($form->{type} =~ /^sales/) {
-    $auth->assert('sales_delivery_order_edit');
+    $main::auth->assert('sales_delivery_order_edit');
 
     $form->{vc}    = 'customer';
     $form->{type}  = 'sales_delivery_order';
 
   } else {
-    $auth->assert('purchase_delivery_order_edit');
+    $main::auth->assert('purchase_delivery_order_edit');
 
     $form->{vc}    = 'vendor';
     $form->{type}  = 'purchase_delivery_order';
   }
 
+  $form->get_employee();
+
   require "bin/mozilla/do.pl";
 
+  $form->{script}               = 'do.pl';
   $form->{cp_id}               *= 1;
   $form->{convert_from_oe_ids}  = $form->{id};
   $form->{transdate}            = $form->current_date(\%myconfig);
@@ -1896,11 +1836,11 @@ sub delivery_order {
   # reset
   delete @{$form}{qw(id subject message cc bcc printed emailed queued creditlimit creditremaining discount tradediscount oldinvtotal closed delivered)};
 
-  for $i (1 .. $form->{rowcount}) {
-    map { $form->{"${_}_${i}"} = $form->parse_amount(\%myconfig, $form->{"${_}_${i}"}) if ($form->{"${_}_${i}"}) } qw(ship qty sellprice listprice basefactor);
+  for my $i (1 .. $form->{rowcount}) {
+    map { $form->{"${_}_${i}"} = $form->parse_amount(\%myconfig, $form->{"${_}_${i}"}) if ($form->{"${_}_${i}"}) } qw(ship qty sellprice listprice lastcost basefactor discount);
   }
 
-  my %old_values = map { $_ => $form->{$_} } qw(customer_id oldcustomer customer vendor_id oldvendor vendor);
+  my %old_values = map { $_ => $form->{$_} } qw(customer_id oldcustomer customer vendor_id oldvendor vendor shipto_id);
 
   order_links();
 
@@ -1910,18 +1850,18 @@ sub delivery_order {
 
   update();
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub e_mail {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
 
   check_oe_access();
 
   $form->{print_and_save} = 1;
 
-  $print_post = 1;
-
   my $saved_form = save_form();
 
   save();
@@ -1930,22 +1870,25 @@ sub e_mail {
 
   edit_e_mail();
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub yes {
-  call_sub($form->{yes_nextsub});
+  call_sub($main::form->{yes_nextsub});
 }
 
 sub no {
-  call_sub($form->{no_nextsub});
+  call_sub($main::form->{no_nextsub});
 }
 
 ######################################################################################################
 # IO ENTKOPPLUNG
 # ###############################################################################################
 sub display_form {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
 
   check_oe_access();
 
@@ -1958,16 +1901,14 @@ sub display_form {
   }
   $form->{"taxaccounts"} = "";
 
-  for my $i (1 .. $form->{"rowcount"}) {
-    IC->retrieve_accounts(\%myconfig, $form, $form->{"id_$i"}, $i, 1) if $form->{"id_$i"};
-  }
+  IC->retrieve_accounts(\%myconfig, $form, map { $_ => $form->{"id_$_"} } 1 .. $form->{rowcount});
 
   $form->{rowcount}++;
   $form->{"project_id_$form->{rowcount}"} = $form->{globalproject_id};
 
   $form->language_payment(\%myconfig);
 
-  Common::webdav_folder($form) if ($webdav);
+  Common::webdav_folder($form) if ($main::webdav);
 
   &form_header;
 
@@ -1976,24 +1917,40 @@ sub display_form {
 
   &form_footer;
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 }
 
 sub report_for_todo_list {
-  $lxdebug->enter_sub();
+  $main::lxdebug->enter_sub();
+
+  my $form     = $main::form;
 
   my $quotations = OE->transactions_for_todo_list();
   my $content;
 
   if (@{ $quotations }) {
-    my $edit_url = build_std_url('script=oe.pl', 'action=edit', 'type=sales_quotation', 'vc=customer');
+    my $edit_url = build_std_url('script=oe.pl', 'action=edit');
 
     $content     = $form->parse_html_template('oe/report_for_todo_list', { 'QUOTATIONS' => $quotations,
                                                                            'edit_url'   => $edit_url });
   }
 
-  $lxdebug->leave_sub();
+  $main::lxdebug->leave_sub();
 
   return $content;
 }
 
+sub dispatcher {
+  my $form     = $main::form;
+  my $locale   = $main::locale;
+
+  foreach my $action (qw(delete delivery_order e_mail invoice print purchase_order purchase_order quotation
+                         request_for_quotation sales_order sales_order save save_and_close save_as_new ship_to update)) {
+    if ($form->{"action_${action}"}) {
+      call_sub($action);
+      return;
+    }
+  }
+
+  $form->error($locale->text('No action defined.'));
+}