Nach Ändern der Währung im Verkauf und Einkauf Erneuern auslösen.
[kivitendo-erp.git] / bin / mozilla / oe.pl
index ad25e83..ac3451d 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;
 
@@ -181,7 +181,8 @@ sub edit {
 
   my ($language_id, $printer_id);
   if ($form->{print_and_save}) {
-    $form->{action}   = "print";
+    $form->{action}   = "dispatcher";
+    $form->{action_print}   = "1";
     $form->{resubmit} = 1;
     $language_id = $form->{language_id};
     $printer_id = $form->{printer_id};
@@ -222,7 +223,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{features}->{webdav};
   $form->{jsscript} = 1;
 
   my $editing = $form->{id};
@@ -238,14 +239,14 @@ sub order_links {
 
   $form->{"$form->{vc}_id"} ||= $form->{"all_$form->{vc}"}->[0]->{id} if $form->{"all_$form->{vc}"};
 
-  $form->backup_vars(qw(payment_id language_id taxzone_id salesman_id taxincluded cp_id intnotes));
+  $form->backup_vars(qw(payment_id language_id taxzone_id salesman_id taxincluded cp_id intnotes shipto_id));
   $form->{shipto} = 1 if $form->{id};
 
   # get customer / vendor
   IR->get_vendor(\%myconfig, \%$form)   if $form->{type} =~ /(purchase_order|request_quotation)/;
   IS->get_customer(\%myconfig, \%$form) if $form->{type} =~ /sales_(order|quotation)/;
 
-  $form->restore_vars(qw(payment_id language_id taxzone_id intnotes cp_id));
+  $form->restore_vars(qw(payment_id language_id taxzone_id intnotes cp_id shipto_id));
   $form->restore_vars(qw(taxincluded)) if $form->{id};
   $form->restore_vars(qw(salesman_id)) if $editing;
   $form->{forex}       = $form->{exchangerate};
@@ -283,6 +284,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"});
   }
 
@@ -296,12 +298,12 @@ sub form_header {
   my $form     = $main::form;
   my %myconfig = %main::myconfig;
   my $locale   = $main::locale;
-  my $cgi      = $main::cgi;
+  my $cgi      = $::request->{cgi};
 
   check_oe_access();
 
   # Container for template variables. Unfortunately this has to be
-  # visible in form_footer too, so my at package level and not here.
+  # visible in form_footer too, so package local level and not my here.
   %TMPL_VAR = ();
 
   $form->{defaultcurrency} = $form->get_default_currency(\%myconfig);
@@ -359,7 +361,9 @@ sub form_header {
   $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"},
-                                                      '-values' => \@values, '-labels' => \%labels)) if scalar @values;
+                                                      '-values' => \@values, '-labels' => \%labels,
+                                                      '-onchange' => "document.getElementById('update_button').click();"
+                                     )) if scalar @values;
   push @custom_hiddens, "forex";
   push @custom_hiddens, "exchangerate" if $form->{forex};
 
@@ -387,14 +391,31 @@ sub form_header {
     }
   }
 
-  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')"
-          :                                                      "";
+  my $onload = "";
+  if ($form->{resubmit} && ($form->{format} eq "html")) {
+      $onload  = "window.open('about:blank','Beleg'); document.oe.target = 'Beleg';";
+      $onload .= "document.do.submit();";
+  } elsif ($form->{resubmit}) {
+    # emulate click for resubmitting actions
+    $onload  = "document.oe.${_}.click(); " for grep { /^action_/ } keys %$form;
+    $onload .= "document.oe.submit();";
+  } elsif ($creditwarning) {
+    $onload = "alert('$credittext')";
+  }
 
-  $onload .= qq|;setupDateFormat('|. $myconfig{dateformat} .qq|', '|. $locale->text("Falsches Datumsformat!") .qq|')|;
-  $onload .= qq|;setupPoints('|.   $myconfig{numberformat} .qq|', '|. $locale->text("wrongformat") .qq|')|;
   $TMPL_VAR{onload} = $onload;
+  $TMPL_VAR{dateformat}          = $myconfig{dateformat};
+  $TMPL_VAR{numberformat}        = $myconfig{numberformat};
+
+  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>|;
@@ -407,7 +428,7 @@ sub form_header {
         title creditlimit creditremaining tradediscount business
         max_dunning_level dunning_amount shiptoname shiptostreet shiptozipcode
         shiptocity shiptocountry shiptocontact shiptophone shiptofax
-        shiptodepartment_1 shiptodepartment_2 shiptoemail
+        shiptodepartment_1 shiptodepartment_2 shiptoemail shiptocp_gender
         message email subject cc bcc taxpart taxservice taxaccounts cursor_fokus),
         @custom_hiddens,
         map { $_.'_rate', $_.'_description' } split / /, $form->{taxaccounts} ];  # deleted: discount
@@ -442,8 +463,8 @@ sub form_footer {
   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>| . H($form->{notes}) . qq|</textarea>|;
-  $TMPL_VAR{intnotes} = qq|<textarea name=intnotes rows=$introws cols=35 wrap=soft>| . H($form->{intnotes}) . qq|</textarea>|;
+  $TMPL_VAR{notes}    = qq|<textarea name=notes rows="$rows" cols="25">| . H($form->{notes}) . qq|</textarea>|;
+  $TMPL_VAR{intnotes} = qq|<textarea name=intnotes rows="$introws" cols="35">| . H($form->{intnotes}) . qq|</textarea>|;
 
   if (!$form->{taxincluded}) {
 
@@ -487,7 +508,7 @@ sub form_footer {
 
   print $form->parse_html_template("oe/form_footer", {
      %TMPL_VAR,
-     webdav          => $main::webdav,
+     webdav          => $::lx_office_conf{features}->{webdav},
      print_options   => print_options(inline => 1),
      label_edit      => $locale->text("Edit the $form->{type}"),
      label_workflow  => $locale->text("Workflow $form->{type}"),
@@ -505,15 +526,13 @@ sub form_footer {
 sub update {
   $main::lxdebug->enter_sub();
 
-  my ($recursive_call) = shift;
+  my ($recursive_call) = @_;
 
   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;
@@ -540,10 +559,13 @@ sub update {
     &check_form;
   } else {
 
+    my $mode;
     if ($form->{type} =~ /^sales/) {
       IS->retrieve_item(\%myconfig, \%$form);
+      $mode = 'IS';
     } else {
       IR->retrieve_item(\%myconfig, \%$form);
+      $mode = 'IR';
     }
 
     my $rows = scalar @{ $form->{item_list} };
@@ -554,13 +576,15 @@ sub update {
     # 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->parse_amount(\%myconfig, $form->{"qty_$i"}));
 
       if ($rows > 1) {
 
-        &select_item;
-        exit;
+        select_item(mode => $mode);
+        ::end_of_request();
 
       } else {
 
@@ -599,6 +623,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
@@ -688,7 +713,7 @@ sub search {
 
   print $form->parse_html_template('oe/search', {
     %myconfig,
-    is_order => $form->{type} =~ /_order/,
+    is_order => scalar($form->{type} =~ /_order/),
   });
 
   $main::lxdebug->leave_sub();
@@ -721,7 +746,7 @@ sub orders {
   my $form     = $main::form;
   my %myconfig = %main::myconfig;
   my $locale   = $main::locale;
-  my $cgi      = $main::cgi;
+  my $cgi      = $::request->{cgi};
 
   check_oe_access();
 
@@ -744,7 +769,8 @@ sub orders {
     "salesman",
     "shipvia",                 "globalprojectnumber",
     "transaction_description", "open",
-    "delivered", "marge_total", "marge_percent",
+    "delivered",               "periodic_invoices",
+    "marge_total",             "marge_percent",
     "vcnumber",                "ustid",
     "country",
   );
@@ -755,8 +781,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') {
@@ -783,7 +810,7 @@ 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 projectnumber project_id);
+                                                        reqdatefrom reqdateto projectnumber project_id periodic_invoices_active periodic_invoices_inactive);
 
   my $href = build_std_url('action=orders', grep { $form->{$_} } @hidden_variables);
 
@@ -811,6 +838,7 @@ sub orders {
     '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)) {
@@ -852,6 +880,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'),
@@ -861,6 +890,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}";
@@ -880,9 +910,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;
@@ -1006,7 +1037,7 @@ sub save_and_close {
       $form->{payment_id} = $payment_id;
     }
     &update;
-    exit;
+    ::end_of_request();
   }
 
   $form->{id} = 0 if $form->{saveasnew};
@@ -1060,7 +1091,7 @@ sub save_and_close {
   if(!exists $form->{addition}) {
     $form->{snumbers} = qq|ordnumber_| . $form->{ordnumber};
     $form->{addition} = "SAVED";
-    $form->save_history($form->dbconnect(\%myconfig));
+    $form->save_history;
   }
   # /saving the history
 
@@ -1115,7 +1146,7 @@ sub save {
       $form->{payment_id} = $payment_id;
     }
     &update;
-    exit;
+    ::end_of_request();
   }
 
   $form->{id} = 0 if $form->{saveasnew};
@@ -1168,7 +1199,7 @@ sub save {
   if(!exists $form->{addition}) {
     $form->{snumbers} = qq|ordnumber_| . $form->{ordnumber};
     $form->{addition} = "SAVED";
-    $form->save_history($form->dbconnect(\%myconfig));
+    $form->save_history;
   }
   # /saving the history
 
@@ -1176,62 +1207,34 @@ 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();
 }
 
 sub delete {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-  my $locale   = $main::locale;
+  $::lxdebug->enter_sub;
 
   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';
-  } else {
-    $msg = $locale->text('Are you sure you want to delete Quotation Number');
-    $ordnumber = 'quonumber';
-  }
-
-  print qq|
-<body>
-
-<form method=post action=$form->{script}>
-|;
+  $::form->header;
 
   # delete action variable
-  map { delete $form->{$_} } qw(action header);
+  delete $::form->{$_} for qw(action header);
 
-  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|;
+  my @hiddens;
+  for my $key (keys %$::form) {
+    next if $key eq 'login' || $key eq 'password' || '' ne ref $::form->{$key};
+    push @hiddens, { key => $key, value => $::form->{$key} };
   }
 
-  print qq|
-<h2 class=confirm>| . $locale->text('Confirm!') . qq|</h2>
-
-<h4>$msg $form->{$ordnumber}</h4>
-<p>
-<input type="hidden" name="yes_nextsub" value="delete_order_quotation">
-<input name=action class=submit type=submit value="|
-    . $locale->text('Yes') . qq|">
-<button class=submit type=button onclick="history.back()">|
-    . $locale->text('No') . qq|</button>
-</form>
+  print $::form->parse_html_template('oe/delete', {
+    hiddens => \@hiddens,
+    is_order => scalar($::form->{type} =~ /_order$/),
+  });
 
-</body>
-</html>
-|;
 
-  $main::lxdebug->leave_sub();
+  $::lxdebug->leave_sub;
 }
 
 sub delete_order_quotation {
@@ -1251,16 +1254,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->save_history;
     }
     # /saving the history
     $form->info($msg);
-    exit();
+    ::end_of_request();
   }
   $form->error($err);
 
@@ -1300,13 +1303,16 @@ sub invoice {
     $form->{quodate}      = $form->{transdate};
   }
 
-  my $payment_id = $form->{payment_id} 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})) {
     $form->{payment_id} = $payment_id if $form->{payment_id} eq "";
     &update;
-    exit;
+    ::end_of_request();
   }
 
   $form->{cp_id} *= 1;
@@ -1329,7 +1335,7 @@ sub invoice {
 
     if (!$exchangerate) {
       &backorder_exchangerate($orddate, $buysell);
-      exit;
+      ::end_of_request();
     }
   }
 
@@ -1409,12 +1415,12 @@ sub invoice {
     $dec_qty = length $dec_qty;
     $form->{"qty_$i"} =
       $form->format_amount(\%myconfig, $form->{"qty_$i"}, $dec_qty);
-
-    map { $form->{"${_}_$i"} =~ s/\"/&quot;/g }
-      qw(partnumber description unit);
-
   }
 
+  #  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();
@@ -1677,7 +1683,7 @@ sub check_for_direct_delivery {
 
   $main::lxdebug->leave_sub();
 
-  exit 0;
+  ::end_of_request();
 }
 
 sub purchase_order {
@@ -1761,10 +1767,12 @@ sub poso {
   # reset
   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 purchase_order was generated from sales_order, use  lastcost_$i as sellprice_$i
+  # also reset discounts
   if ( $form->{sales_order_to_purchase_order} ) {
     for my $i (1 .. $form->{rowcount}) {
       $form->{"sellprice_${i}"} = $form->format_amount(\%myconfig,$form->{"lastcost_${i}"});
+      $form->{"discount_${i}"}  = 0;
     };
   };
 
@@ -1788,12 +1796,6 @@ sub poso {
   };
 
   &prepare_order;
-
-  # format amounts
-  for my $i (1 .. $form->{rowcount} - 1) {
-    map { $form->{"${_}_$i"} =~ s/\"/&quot;/g } qw(partnumber description unit);
-  }
-
   &update;
 
   $main::lxdebug->leave_sub();
@@ -1835,10 +1837,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();
 
@@ -1860,8 +1862,6 @@ sub e_mail {
 
   $form->{print_and_save} = 1;
 
-  $print_post = 1;
-
   my $saved_form = save_form();
 
   save();
@@ -1901,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 ($main::webdav);
+  Common::webdav_folder($form);
 
   &form_header;
 
@@ -1942,3 +1940,77 @@ 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}"}) {
+      call_sub($action);
+      return;
+    }
+  }
+
+  $::form->error($::locale->text('No action defined.'));
+}