Merge branch 'after-262'
[kivitendo-erp.git] / bin / mozilla / oe.pl
index 5965bf5..97cc388 100644 (file)
@@ -41,6 +41,7 @@ use SL::IS;
 use SL::MoreCommon qw(ary_diff);
 use SL::PE;
 use SL::ReportGenerator;
+use List::MoreUtils qw(any none);
 use List::Util qw(max reduce sum);
 use Data::Dumper;
 
@@ -50,8 +51,7 @@ require "bin/mozilla/reportgenerator.pl";
 
 use strict;
 
-my $print_post;
-my %TMPL_VAR;
+our %TMPL_VAR;
 
 1;
 
@@ -222,7 +222,7 @@ sub order_links {
   $form->all_vc(\%myconfig, $form->{vc}, ($form->{vc} eq 'customer') ? "AR" : "AP");
 
   # retrieve order/quotation
-  $form->{webdav}   = $main::webdav;
+  $form->{webdav}   = $::lx_office_conf{system}->{webdav};
   $form->{jsscript} = 1;
 
   my $editing = $form->{id};
@@ -283,6 +283,7 @@ sub prepare_order {
     $form->{"reqdate_$i"} ||= $form->{"deliverydate_$i"};
     $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"});
   }
 
@@ -300,8 +301,9 @@ sub form_header {
 
   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);
 
@@ -395,6 +397,16 @@ sub form_header {
   $onload .= qq|;setupPoints('|.   $myconfig{numberformat} .qq|', '|. $locale->text("wrongformat") .qq|')|;
   $TMPL_VAR{onload} = $onload;
 
+  if ($form->{type} eq 'sales_order') {
+    if (!$form->{periodic_invoices_config}) {
+      $form->{periodic_invoices_status} = $locale->text('not configured');
+
+    } else {
+      my $config                        = YAML::Load($form->{periodic_invoices_config});
+      $form->{periodic_invoices_status} = $config->{active} ? $locale->text('active') : $locale->text('inactive');
+    }
+  }
+
   $form->{javascript} .= qq|<script type="text/javascript" src="js/show_form_details.js"></script>|;
   $form->{javascript} .= qq|<script type="text/javascript" src="js/show_history.js"></script>|;
   $form->{javascript} .= qq|<script type="text/javascript" src="js/show_vc_details.js"></script>|;
@@ -452,10 +464,10 @@ sub form_footer {
         $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> |;
       }
     }
 
@@ -470,14 +482,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> |;
       }
     }
   }
@@ -486,7 +498,7 @@ sub form_footer {
 
   print $form->parse_html_template("oe/form_footer", {
      %TMPL_VAR,
-     webdav          => $main::webdav,
+     webdav          => $::lx_office_conf{system}->{webdav},
      print_options   => print_options(inline => 1),
      label_edit      => $locale->text("Edit the $form->{type}"),
      label_workflow  => $locale->text("Workflow $form->{type}"),
@@ -518,12 +530,8 @@ sub update {
   map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(exchangerate) unless $recursive_call;
   $form->{update} = 1;
 
-  my $payment_id = $form->{payment_id} if $form->{payment_id};
-
   &check_name($form->{vc});
 
-  $form->{payment_id} = $payment_id if $form->{payment_id} eq "";
-
   my $buysell           = 'buy';
   $buysell              = 'sell' if ($form->{vc} eq 'vendor');
   $form->{forex}        = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{transdate}, $buysell);
@@ -552,18 +560,20 @@ sub update {
     my $rows = scalar @{ $form->{item_list} };
 
     # 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
+    # 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 {
 
@@ -602,6 +612,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
@@ -689,7 +700,10 @@ sub search {
 
   $form->header();
 
-  print $form->parse_html_template('oe/search', { %myconfig });
+  print $form->parse_html_template('oe/search', {
+    %myconfig,
+    is_order => $form->{type} =~ /_order/,
+  });
 
   $main::lxdebug->leave_sub();
 }
@@ -744,8 +758,10 @@ sub orders {
     "salesman",
     "shipvia",                 "globalprojectnumber",
     "transaction_description", "open",
-    "delivered", "marge_total", "marge_percent",
-    "country",                 "ustid",
+    "delivered",               "periodic_invoices",
+    "marge_total",             "marge_percent",
+    "vcnumber",                "ustid",
+    "country",
   );
 
   # only show checkboxes if gotten here via sales_order form.
@@ -754,8 +770,9 @@ sub orders {
     unshift @columns, "ids";
   }
 
-  $form->{l_open}      = $form->{l_closed} = "Y" if ($form->{open}      && $form->{closed});
-  $form->{l_delivered} = "Y"                     if ($form->{delivered} && $form->{notdelivered});
+  $form->{l_open}              = $form->{l_closed} = "Y" if ($form->{open}      && $form->{closed});
+  $form->{l_delivered}         = "Y"                     if ($form->{delivered} && $form->{notdelivered});
+  $form->{l_periodic_invoices} = "Y"                     if ($form->{periodic_invoices_active} && $form->{periodic_invoices_inactive});
 
   my $attachment_basename;
   if ($form->{vc} eq 'vendor') {
@@ -782,14 +799,14 @@ 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
-                                                        reqdatefrom reqdateto);
+                                                        reqdatefrom reqdateto projectnumber project_id periodic_invoices_active periodic_invoices_inactive);
 
   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'), },
@@ -807,8 +824,10 @@ sub orders {
     'delivered'               => { 'text' => $locale->text('Delivered'), },
     'marge_total'             => { 'text' => $locale->text('Ertrag'), },
     '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.'), },
+    'periodic_invoices'       => { 'text' => $locale->text('Per. Inv.'), },
   );
 
   foreach my $name (qw(id transdate reqdate quonumber ordnumber name employee salesman shipvia transaction_description)) {
@@ -850,6 +869,7 @@ sub orders {
   push @options, $locale->text('Closed')                                                                  if $form->{closed};
   push @options, $locale->text('Delivered')                                                               if $form->{delivered};
   push @options, $locale->text('Not delivered')                                                           if $form->{notdelivered};
+  push @options, $locale->text('Periodic invoices active')                                                if $form->{periodic_invoices_actibe};
 
   $report->set_options('top_info_text'        => join("\n", @options),
                        'raw_top_info_text'    => $form->parse_html_template('oe/orders_top'),
@@ -859,6 +879,7 @@ 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}";
@@ -878,9 +899,10 @@ sub orders {
   foreach my $oe (@{ $form->{OE} }) {
     map { $oe->{$_} *= $oe->{exchangerate} } @subtotal_columns;
 
-    $oe->{tax}       = $oe->{amount} - $oe->{netamount};
-    $oe->{open}      = $oe->{closed}    ? $locale->text('No')  : $locale->text('Yes');
-    $oe->{delivered} = $oe->{delivered} ? $locale->text('Yes') : $locale->text('No');
+    $oe->{tax}               = $oe->{amount} - $oe->{netamount};
+    $oe->{open}              = $oe->{closed}            ? $locale->text('No')  : $locale->text('Yes');
+    $oe->{delivered}         = $oe->{delivered}         ? $locale->text('Yes') : $locale->text('No');
+    $oe->{periodic_invoices} = $oe->{periodic_invoices} ? $locale->text('On')  : $locale->text('Off');
 
     map { $subtotals{$_} += $oe->{$_};
           $totals{$_}    += $oe->{$_} } @subtotal_columns;
@@ -1004,7 +1026,7 @@ sub save_and_close {
       $form->{payment_id} = $payment_id;
     }
     &update;
-    exit;
+    ::end_of_request();
   }
 
   $form->{id} = 0 if $form->{saveasnew};
@@ -1057,8 +1079,8 @@ 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
 
@@ -1099,6 +1121,7 @@ sub save {
   $form->isblank("exchangerate", $locale->text('Exchangerate missing!'))
     if ($form->{currency} ne $form->{defaultcurrency});
 
+  remove_emptied_rows();
   &validate_items;
 
   my $payment_id;
@@ -1112,7 +1135,7 @@ sub save {
       $form->{payment_id} = $payment_id;
     }
     &update;
-    exit;
+    ::end_of_request();
   }
 
   $form->{id} = 0 if $form->{saveasnew};
@@ -1164,8 +1187,8 @@ 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
 
@@ -1173,7 +1196,7 @@ sub save {
   if(!$form->{print_and_save}) {
     delete @{$form}{ary_diff([keys %{ $form }], [qw(login stylesheet id script type cursor_fokus)])};
     edit();
-    exit;
+    ::end_of_request();
   }
   $main::lxdebug->leave_sub();
 }
@@ -1248,16 +1271,16 @@ sub delete_order_quotation {
     $msg = $locale->text('Quotation deleted!');
     $err = $locale->text('Cannot delete quotation!');
   }
-  if (OE->delete(\%myconfig, \%$form, $main::spool)){
+  if (OE->delete(\%myconfig, \%$form)){
     # 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
     $form->info($msg);
-    exit();
+    ::end_of_request();
   }
   $form->error($err);
 
@@ -1303,7 +1326,7 @@ sub invoice {
   if (&check_name($form->{vc})) {
     $form->{payment_id} = $payment_id if $form->{payment_id} eq "";
     &update;
-    exit;
+    ::end_of_request();
   }
 
   $form->{cp_id} *= 1;
@@ -1326,7 +1349,7 @@ sub invoice {
 
     if (!$exchangerate) {
       &backorder_exchangerate($orddate, $buysell);
-      exit;
+      ::end_of_request();
     }
   }
 
@@ -1367,7 +1390,8 @@ 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}";
 
@@ -1411,6 +1435,10 @@ 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;
 
   $main::lxdebug->leave_sub();
@@ -1457,16 +1485,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>
@@ -1673,7 +1701,7 @@ sub check_for_direct_delivery {
 
   $main::lxdebug->leave_sub();
 
-  exit 0;
+  ::end_of_request();
 }
 
 sub purchase_order {
@@ -1685,7 +1713,9 @@ sub purchase_order {
   check_oe_access();
   $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();
   }
 
@@ -1703,6 +1733,8 @@ sub purchase_order {
 
   &poso;
 
+  delete $form->{sales_order_to_purchase_order};
+
   $main::lxdebug->leave_sub();
 }
 
@@ -1751,8 +1783,14 @@ 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
-                                ordnumber);
+  map { delete $form->{$_} } qw(id subject message cc bcc printed emailed queued customer vendor creditlimit creditremaining discount tradediscount oldinvtotal delivered ordnumber);
+
+  # 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);
@@ -1764,19 +1802,16 @@ sub poso {
 
   map { $form->{$_} = $saved_vars{$_} } keys %saved_vars;
 
-  &prepare_order;
-
   # 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
+  # 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"}  = $form->format_amount(\%myconfig, $form->{"discount_$i"} * 0.01);
+    $form->{"discount_$i"} /=100;
   };
 
-  # format amounts
-  for my $i (1 .. $form->{rowcount} - 1) {
-    map { $form->{"${_}_$i"} =~ s/\"/&quot;/g } qw(partnumber description unit);
-  }
-
+  &prepare_order;
   &update;
 
   $main::lxdebug->leave_sub();
@@ -1818,10 +1853,10 @@ sub delivery_order {
   delete @{$form}{qw(id subject message cc bcc printed emailed queued creditlimit creditremaining discount tradediscount oldinvtotal closed delivered)};
 
   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);
+    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();
 
@@ -1843,8 +1878,6 @@ sub e_mail {
 
   $form->{print_and_save} = 1;
 
-  $print_post = 1;
-
   my $saved_form = save_form();
 
   save();
@@ -1884,16 +1917,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 ($main::webdav);
+  Common::webdav_folder($form);
 
   &form_header;
 
@@ -1925,3 +1956,78 @@ sub report_for_todo_list {
   return $content;
 }
 
+sub edit_periodic_invoices_config {
+  $::lxdebug->enter_sub();
+
+  $::form->{type} = 'sales_order';
+
+  check_oe_access();
+
+  my $config;
+  $config = YAML::Load($::form->{periodic_invoices_config}) if $::form->{periodic_invoices_config};
+
+  if ('HASH' ne ref $config) {
+    $config =  { periodicity             => 'y',
+                 start_date_as_date      => $::form->{transdate},
+                 extend_automatically_by => 12,
+                 active                  => 1,
+               };
+  }
+
+  $config->{periodicity} = 'm' if none { $_ eq $config->{periodicity} } qw(m q y);
+
+  $::form->get_lists(printers => "ALL_PRINTERS",
+                     charts   => { key       => 'ALL_CHARTS',
+                                   transdate => 'current_date' });
+
+  $::form->{AR}    = [ grep { $_->{link} =~ m/(?:^|:)AR(?::|$)/ } @{ $::form->{ALL_CHARTS} } ];
+  $::form->{title} = $::locale->text('Edit the configuration for periodic invoices');
+
+  $::form->header();
+  print $::form->parse_html_template('oe/edit_periodic_invoices_config', $config);
+
+  $::lxdebug->leave_sub();
+}
+
+sub save_periodic_invoices_config {
+  $::lxdebug->enter_sub();
+
+  $::form->{type} = 'sales_order';
+
+  check_oe_access();
+
+  $::form->isblank('start_date_as_date', $::locale->text('The start date is missing.'));
+
+  my $config = { active                  => $::form->{active}     ? 1 : 0,
+                 terminated              => $::form->{terminated} ? 1 : 0,
+                 periodicity             => (any { $_ eq $::form->{periodicity} } qw(m q y)) ? $::form->{periodicity} : 'm',
+                 start_date_as_date      => $::form->{start_date_as_date},
+                 end_date_as_date        => $::form->{end_date_as_date},
+                 print                   => $::form->{print} ? 1 : 0,
+                 printer_id              => $::form->{print} ? $::form->{printer_id} * 1 : undef,
+                 copies                  => $::form->{copies} * 1 ? $::form->{copies} : 1,
+                 extend_automatically_by => $::form->{extend_automatically_by} * 1 || undef,
+                 ar_chart_id             => $::form->{ar_chart_id} * 1,
+               };
+
+  $::form->{periodic_invoices_config} = YAML::Dump($config);
+
+  $::form->{title} = $::locale->text('Edit the configuration for periodic invoices');
+  $::form->header;
+  print $::form->parse_html_template('oe/save_periodic_invoices_config', $config);
+
+  $::lxdebug->leave_sub();
+}
+
+sub dispatcher {
+  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}"}) {
+      $::form->{dispatched_action} = $action;
+      call_sub($action);
+      return;
+    }
+  }
+
+  $::form->error($::locale->text('No action defined.'));
+}