Bugfix zu Bug 789: Ansprechpartner zeigen jetzt auch den Vornamen an
[kivitendo-erp.git] / bin / mozilla / oe.pl
index a89de30..f6b5686 100644 (file)
 
 use POSIX qw(strftime);
 
+use SL::FU;
 use SL::OE;
 use SL::IR;
 use SL::IS;
 use SL::PE;
 use SL::ReportGenerator;
-use List::Util qw(max reduce);
+use List::Util qw(max reduce sum);
 
 require "bin/mozilla/io.pl";
 require "bin/mozilla/arap.pl";
@@ -59,9 +60,25 @@ require "bin/mozilla/reportgenerator.pl";
 # $locale->text('Workflow request_quotation');
 # $locale->text('Workflow sales_quotation');
 
+my $oe_access_map = {
+  'sales_order'       => 'sales_order_edit',
+  'purchase_order'    => 'purchase_order_edit',
+  'request_quotation' => 'request_quotation_edit',
+  'sales_quotation'   => 'sales_quotation_edit',
+};
+
+sub check_oe_access {
+  my $right   = $oe_access_map->{$form->{type}};
+  $right    ||= 'DOES_NOT_EXIST';
+
+  $auth->assert($right);
+}
+
 sub set_headings {
   $lxdebug->enter_sub();
 
+  check_oe_access();
+
   my ($action) = @_;
 
   if ($form->{type} eq 'purchase_order') {
@@ -99,10 +116,12 @@ sub set_headings {
 sub add {
   $lxdebug->enter_sub();
 
+  check_oe_access();
+
   set_headings("add");
 
   $form->{callback} =
-    "$form->{script}?action=add&type=$form->{type}&vc=$form->{vc}&login=$form->{login}&password=$form->{password}"
+    "$form->{script}?action=add&type=$form->{type}&vc=$form->{vc}"
     unless $form->{callback};
 
   &order_links;
@@ -114,6 +133,9 @@ sub add {
 
 sub edit {
   $lxdebug->enter_sub();
+
+  check_oe_access();
+
   # show history button
   $form->{javascript} = qq|<script type="text/javascript" src="js/show_history.js"></script>|;
   #/show hhistory button
@@ -161,6 +183,9 @@ sub edit {
 
 sub order_links {
   $lxdebug->enter_sub();
+
+  check_oe_access();
+
   # get customer/vendor
   $form->all_vc(\%myconfig, $form->{vc}, ($form->{vc} eq 'customer') ? "AR" : "AP");
 
@@ -279,6 +304,9 @@ sub order_links {
 
 sub prepare_order {
   $lxdebug->enter_sub();
+
+  check_oe_access();
+
   $form->{formname} = $form->{type} unless $form->{formname};
 
   my $i = 0;
@@ -291,7 +319,6 @@ sub prepare_order {
     $form->{"discount_$i"}  = $form->format_amount(\%myconfig, $form->{"discount_$i"} * ($form->{id} ? 100 : 1));
     $form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"});
     $form->{"qty_$i"}       = $form->format_amount(\%myconfig, $form->{"qty_$i"});
-    map { $form->{"${_}_$i"} =~ s/\"/&quot;/g } qw(partnumber description unit);
   }
 
   $lxdebug->leave_sub();
@@ -301,6 +328,8 @@ sub form_header {
   $lxdebug->enter_sub();
   my @custom_hiddens;
 
+  check_oe_access();
+
   # Container for template variables. Unfortunately this has to be visible in form_footer too, so not my.
   our %TMPL_VAR = ();
 
@@ -367,65 +396,18 @@ sub form_header {
                                         limit => $myconfig{vclimit} + 1 },
                    "price_factors" => "ALL_PRICE_FACTORS");
 
-  # contacts
-  @values = ("", map { $_->{cp_id} } @{ $form->{ALL_CONTACTS} });
-  %labels = map { $_->{cp_id} => $_->{"cp_name"} . ($_->{cp_abteilung} ? " ($_->{cp_abteilung})" : "") } @{ $form->{ALL_CONTACTS} };
-  $TMPL_VAR{contact} = NTI($cgi->popup_menu('-name' => 'cp_id', '-values' => \@values, '-style' => 'width: 250px',
-                                            '-labels' => \%labels, '-default' => $form->{"cp_id"})) if scalar @values > 1;
+  # label subs
+  $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 { $_[0]->{"cp_name"} . ($_[0]->{cp_abteilung} ? " ($_[0]->{cp_abteilung})" : "") };
 
   # vendor/customer
-  @values = map { "$_->{name}--$_->{id}" } @{ $form->{uc "all_$form->{vc}s" } };
-  %labels = map { +"$_->{name}--$_->{id}" => $_->{name} } @{ $form->{uc "all_$form->{vc}s" } };
+  $TMPL_VAR{vc_keys} = sub { "$_[0]->{name}--$_[0]->{id}" };
+  $TMPL_VAR{vclimit} = $myconfig{vclimit};
+  $TMPL_VAR{vc_select} = "customer_or_vendor_selection_window('$form->{vc}', '', @{[ $form->{vc} eq 'vendor' ? 1 : 0 ]}, 0)";
   push @custom_hiddens, "$form->{vc}_id";
   push @custom_hiddens, "old$form->{vc}";
   push @custom_hiddens, "select$form->{vc}";
-  $TMPL_VAR{vc} = sprintf qq|<th align="right">%s</th><td>%s<input type="button" value="?" onclick="show_vc_details('$form->{vc}')"></td>|,
-       $locale->text(ucfirst $form->{vc}), 
-       ($myconfig{vclimit} <=  scalar(@values)) 
-        ? $cgi->textfield(-value => H($form->{"old$form->{vc}"} =~ /^(.*)\-\-.*$/), -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, '-style' => 'width: 250px'));
-
-  # payments (for footer)
-  @values = ("", map { $_->{id} } @{ $form->{ALL_PAYMENTS} });
-  %labels = map { $_->{id} => $_->{description} } @{ $form->{ALL_PAYMENTS} };
-  $TMPL_VAR{payments} = NTI($cgi->popup_menu('-name' => 'payment_id', '-values' => \@values, '-style' => 'width: 250px',
-                                             '-labels' => \%labels, '-default' => $form->{payment_id}));
-
-  # shipto
-  @values = ("", map { $_->{shipto_id} } @{ $form->{ALL_SHIPTO} });
-  $TMPL_VAR{ALL_SHIPTO} = $form->{ALL_SHIPTO};
-  for my $item ( @{ $TMPL_VAR{ALL_SHIPTO} }) {
-     $item->{label} = join "; ", grep { $_ } map { $item->{"shipto${_}" } } qw(name department_1 street city);
-  }
-  %labels = map { my $item=$_; $_->{shipto_id} => join "; ", grep { $_ } map { $item->{"shipto${_}" } } qw(name department_1 street city) } @{ $form->{ALL_SHIPTO} };
-  $TMPL_VAR{shipto} = NTI($cgi->popup_menu('-name' => 'shipto_id', '-values' => \@values, '-style' => 'width: 250px',
-                                           '-labels' => \%labels, '-default' => $form->{"shipto_id"})) if scalar @values > 1;
-
-  # projects
-  @values = ("", map { $_->{id} } @{ $form->{ALL_PROJECTS} });
-  %labels = map { $_->{id} => $_->{projectnumber} } @{ $form->{ALL_PROJECTS} };
-  $TMPL_VAR{globalprojectnumber} = NTI($cgi->popup_menu('-name' => 'globalproject_id', '-values' => \@values,
-                                                        '-labels' => \%labels, '-default' => $form->{"globalproject_id"}));
-  
-  # salesmen
-  @values = map { $_->{id} } @{ $form->{ALL_SALESMEN} };
-  %labels = map { $_->{id} => ($_->{name} || $_->{login}) } @{ $form->{ALL_SALESMEN} };
-  $TMPL_VAR{salesmen} = NTI($cgi->popup_menu('-name' => 'salesman_id', '-default' => $form->{"salesman_id"} ? $form->{"salesman_id"} : $form->{"employee_id"},
-                                             '-values' => \@values, '-labels' => \%labels)) if $form->{type} =~ /^sales_/ && scalar @values;
-
-  # employees
-  @values = map { $_->{id} } @{ $form->{ALL_EMPLOYEES} };
-  %labels = map { $_->{id} => $_->{name} || $_->{login} } @{ $form->{ALL_EMPLOYEES} };
-  $TMPL_VAR{employee} = NTI($cgi->popup_menu('-name' => 'employee_id', '-default' => $form->{"employee_id"},
-                                             '-values' => \@values, '-labels' => \%labels));
-
-  # taxzone
-  @values = map { $_->{id} } @{ $form->{ALL_TAXZONES} };
-  %labels = map { $_->{id} => $_->{description} } @{ $form->{ALL_TAXZONES} };
-  $TMPL_VAR{taxzone} = NTI($cgi->popup_menu('-name' => 'taxzone_id', '-default' => $form->{"taxzone_id"},
-                                            '-values' => \@values, '-labels' => \%labels, '-style' => 'width: 250px'));
 
   # currencies and exchangerate
   @values = map { $_ } @{ $form->{ALL_CURRENCIES} };
@@ -449,6 +431,19 @@ sub form_header {
 
   $credittext = $locale->text('Credit Limit exceeded!!!');
 
+  my $follow_up_vc                =  $form->{ $form->{vc} eq 'customer' ? 'customer' : 'vendor' };
+  $follow_up_vc                   =~ s/--.*?//;
+  $TMPL_VAR{follow_up_trans_info} =  ($form->{type} =~ /_quotation$/ ? $form->{quonumber} : $form->{ordnumber}) . " ($follow_up_vc)";
+
+  if ($form->{id}) {
+    my $follow_ups = FU->follow_ups('trans_id' => $form->{id});
+
+    if (scalar @{ $follow_ups }) {
+      $TMPL_VAR{num_follow_ups}     = scalar                    @{ $follow_ups };
+      $TMPL_VAR{num_due_follow_ups} = sum map { $_->{due} * 1 } @{ $follow_ups };
+    }
+  }
+
   $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')"
@@ -457,7 +452,7 @@ sub form_header {
   $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;
-  
+
   $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>|;
@@ -484,7 +479,7 @@ sub form_header {
      is_pur_ord      => scalar ($form->{type} =~ /purchase_order$/),
   );
 
-  print $form->parse_html_template2("oe/orders_header", { %TMPL_VAR });
+  print $form->parse_html_template("oe/orders_header", { %TMPL_VAR });
 
   $lxdebug->leave_sub();
 }
@@ -492,6 +487,8 @@ sub form_header {
 sub form_footer {
   $lxdebug->enter_sub();
 
+  check_oe_access();
+
   $form->{invtotal} = $form->{invsubtotal};
 
   $rows    = max 2, $form->numtextrows($form->{notes}, 25, 8);
@@ -541,7 +538,7 @@ sub form_footer {
 
   $form->{oldinvtotal} = $form->{invtotal};
 
-  print $form->parse_html_template2("oe/orders_footer", {
+  print $form->parse_html_template("oe/orders_footer", {
      %TMPL_VAR,
      webdav          => $webdav,
      print_options   => print_options(inline => 1),
@@ -557,9 +554,11 @@ sub update {
   
   my ($recursive_call) = shift;
 
+  check_oe_access();
+
   set_headings($form->{"id"} ? "edit" : "add");
 
-  map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(exchangerate creditlimit creditremaining) unless $recursive_call;
+  map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(exchangerate) unless $recursive_call;
   $form->{update} = 1;
       
   $payment_id = $form->{payment_id} if $form->{payment_id};
@@ -670,6 +669,8 @@ sub update {
 sub search {
   $lxdebug->enter_sub();
 
+  check_oe_access();
+
   if ($form->{type} eq 'purchase_order') {
     $form->{title} = $locale->text('Purchase Orders');
     $form->{vc}    = 'vendor';
@@ -872,6 +873,8 @@ $employee_block
              <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>
@@ -911,8 +914,6 @@ $jsscript
 
 <br>
 <input type=hidden name=nextsub value=orders>
-<input type=hidden name=login value=$form->{login}>
-<input type=hidden name=password value=$form->{password}>
 <input type=hidden name=vc value=$form->{vc}>
 <input type=hidden name=type value=$form->{type}>
 
@@ -948,6 +949,8 @@ sub create_subtotal_row {
 sub orders {
   $lxdebug->enter_sub();
 
+  check_oe_access();
+
   $ordnumber = ($form->{type} =~ /_order$/) ? "ordnumber" : "quonumber";
 
   ($form->{ $form->{vc} }, $form->{"${form->{vc}}_id"}) = split(/--/, $form->{ $form->{vc} });
@@ -1026,7 +1029,7 @@ sub orders {
     'transaction_description' => { 'text' => $locale->text('Transaction description'), },
     'open'                    => { 'text' => $locale->text('Open'), },
     'delivered'               => { 'text' => $locale->text('Delivered'), },
-    'marge_total'                   => { 'text' => $locale->text('Ertrag'), },
+    'marge_total'             => { 'text' => $locale->text('Ertrag'), },
     'marge_percent'           => { 'text' => $locale->text('Ertrag prozentual'), }
   );
 
@@ -1042,53 +1045,28 @@ sub orders {
 
   $report->set_columns(%column_defs);
   $report->set_column_order(@columns);
-
   $report->set_export_options('orders', @hidden_variables);
-
   $report->set_sort_indicator($form->{sort}, 1);
 
   my @options;
-  if ($form->{customer}) {
-    push @options, $locale->text('Customer') . " : $form->{customer}";
-  }
-  if ($form->{vendor}) {
-    push @options, $locale->text('Vendor') . " : $form->{vendor}";
-  }
-  if ($form->{department}) {
-    ($department) = split /--/, $form->{department};
-    push @options, $locale->text('Department') . " : $department";
-  }
-  if ($form->{ordnumber}) {
-    push @options, $locale->text('Order Number') . " : $form->{ordnumber}";
-  }
-  if ($form->{notes}) {
-    push @options, $locale->text('Notes') . " : $form->{notes}";
-  }
-  if ($form->{transaction_description}) {
-    push @options, $locale->text('Transaction description') . " : $form->{transaction_description}";
-  }
-  if ($form->{transdatefrom}) {
-    push @options, $locale->text('From') . "&nbsp;" . $locale->date(\%myconfig, $form->{transdatefrom}, 1);
-  }
-  if ($form->{transdateto}) {
-    push @options, $locale->text('Bis') . "&nbsp;" . $locale->date(\%myconfig, $form->{transdateto}, 1);
-  }
-  if ($form->{open}) {
-    push @options, $locale->text('Open');
-  }
-  if ($form->{closed}) {
-    push @options, $locale->text('Closed');
-  }
-  if ($form->{delivered}) {
-    push @options, $locale->text('Delivered');
-  }
-  if ($form->{notdelivered}) {
-    push @options, $locale->text('Not delivered');
-  }
+
+  push @options, $locale->text('Customer') . " : $form->{customer}"                                       if $form->{customer};
+  push @options, $locale->text('Vendor') . " : $form->{vendor}"                                           if $form->{vendor};
+  ($department) = split /--/, $form->{department};
+  push @options, $locale->text('Department') . " : $department"                                           if $form->{department};
+  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};
+  push @options, $locale->text('Open')                                                                    if $form->{open};
+  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};
 
   $report->set_options('top_info_text'        => join("\n", @options),
-                       'raw_top_info_text'    => $form->parse_html_template2('oe/orders_top'),
-                       'raw_bottom_info_text' => $form->parse_html_template2('oe/orders_bottom', { 'SHOW_CONTINUE_BUTTON' => $allow_multiple_orders }),
+                       'raw_top_info_text'    => $form->parse_html_template('oe/orders_top'),
+                       'raw_bottom_info_text' => $form->parse_html_template('oe/orders_bottom', { 'SHOW_CONTINUE_BUTTON' => $allow_multiple_orders }),
                        'output_format'        => 'HTML',
                        'title'                => $form->{title},
                        'attachment_basename'  => $attachment_basename . strftime('_%Y%m%d', localtime time),
@@ -1168,6 +1146,8 @@ sub orders {
 sub check_delivered_flag {
   $lxdebug->enter_sub();
 
+  check_oe_access();
+
   if (($form->{type} ne 'sales_order') && ($form->{type} ne 'purchase_order')) {
     return $lxdebug->leave_sub();
   }
@@ -1194,6 +1174,8 @@ sub check_delivered_flag {
 sub save_and_close {
   $lxdebug->enter_sub();
 
+  check_oe_access();
+
   $form->{defaultcurrency} = $form->get_default_currency(\%myconfig);
 
   if ($form->{type} =~ /_order$/) {
@@ -1293,6 +1275,8 @@ sub save_and_close {
 sub save {
   $lxdebug->enter_sub();
 
+  check_oe_access();
+
   $form->{defaultcurrency} = $form->get_default_currency(\%myconfig);
 
 
@@ -1394,6 +1378,8 @@ sub save {
 sub delete {
   $lxdebug->enter_sub();
 
+  check_oe_access();
+
   $form->header;
 
   if ($form->{type} =~ /_order$/) {
@@ -1414,6 +1400,7 @@ sub delete {
   map { delete $form->{$_} } qw(action header);
 
   foreach $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|;
   }
@@ -1440,6 +1427,8 @@ sub delete {
 sub delete_order_quotation {
   $lxdebug->enter_sub();
 
+  check_oe_access();
+
   if ($form->{type} =~ /_order$/) {
     $msg = $locale->text('Order deleted!');
     $err = $locale->text('Cannot delete order!');
@@ -1466,6 +1455,9 @@ sub delete_order_quotation {
 sub invoice {
   $lxdebug->enter_sub();
 
+  check_oe_access();
+  $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};
 
@@ -1575,9 +1567,6 @@ sub invoice {
 
   map { $form->{"select$_"} = "" } ($form->{vc}, currency);
 
-  map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) }
-    qw(creditlimit creditremaining);
-
   $currency = $form->{currency};
   &invoice_links;
 
@@ -1630,6 +1619,9 @@ sub invoice {
 
 sub backorder_exchangerate {
   $lxdebug->enter_sub();
+
+  check_oe_access();
+
   my ($orddate, $buysell) = @_;
 
   $form->header;
@@ -1644,6 +1636,7 @@ sub backorder_exchangerate {
   map { delete $form->{$_} } qw(action header exchangerate);
 
   foreach $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|;
   }
@@ -1652,9 +1645,6 @@ sub backorder_exchangerate {
 
   print qq|
 
-<input type=hidden name=login value=$form->{login}>
-<input type=hidden name=password value=$form->{password}>
-
 <input type=hidden name=exchangeratedate value=$orddate>
 <input type=hidden name=buysell value=$buysell>
 
@@ -1780,6 +1770,8 @@ sub create_backorder {
 sub save_as_new {
   $lxdebug->enter_sub();
 
+  check_oe_access();
+
   $form->{saveasnew} = 1;
   $form->{closed}    = 0;
   map { delete $form->{$_} } qw(printed emailed queued);
@@ -1802,6 +1794,8 @@ sub save_as_new {
 sub check_for_direct_delivery_yes {
   $lxdebug->enter_sub();
 
+  check_oe_access();
+
   $form->{direct_delivery_checked} = 1;
   delete @{$form}{grep /^shipto/, keys %{ $form }};
   map { s/^CFDD_//; $form->{$_} = $form->{"CFDD_${_}"} } grep /^CFDD_/, keys %{ $form };
@@ -1813,6 +1807,8 @@ sub check_for_direct_delivery_yes {
 sub check_for_direct_delivery_no {
   $lxdebug->enter_sub();
 
+  check_oe_access();
+
   $form->{direct_delivery_checked} = 1;
   delete @{$form}{grep /^shipto/, keys %{ $form }};
   purchase_order();
@@ -1823,6 +1819,8 @@ sub check_for_direct_delivery_no {
 sub check_for_direct_delivery {
   $lxdebug->enter_sub();
 
+  check_oe_access();
+
   if ($form->{direct_delivery_checked}
       || (!$form->{shiptoname} && !$form->{shiptostreet} && !$form->{shipto_id})) {
     $lxdebug->leave_sub();
@@ -1837,10 +1835,10 @@ sub check_for_direct_delivery {
   }
 
   delete $form->{action};
-  $form->{VARIABLES} = [ map { { "key" => $_, "value" => $form->{$_} } } grep { ref $_ eq "" } keys %{ $form } ];
+  $form->{VARIABLES} = [ map { { "key" => $_, "value" => $form->{$_} } } grep { ($_ ne 'login') && ($_ ne 'password') && (ref $_ eq "") } keys %{ $form } ];
 
   $form->header();
-  print $form->parse_html_template2("oe/check_for_direct_delivery");
+  print $form->parse_html_template("oe/check_for_direct_delivery");
 
   $lxdebug->leave_sub();
 
@@ -1850,6 +1848,9 @@ sub check_for_direct_delivery {
 sub purchase_order {
   $lxdebug->enter_sub();
 
+  check_oe_access();
+  $auth->assert('purchase_order_edit');
+
   if ($form->{type} eq 'sales_order') {
     check_for_direct_delivery();
   }
@@ -1877,6 +1878,9 @@ sub purchase_order {
 sub sales_order {
   $lxdebug->enter_sub();
 
+  check_oe_access();
+  $auth->assert('sales_order_edit');
+
   if (   $form->{type} eq 'sales_quotation'
       || $form->{type} eq 'request_quotation') {
     OE->close_order(\%myconfig, $form);
@@ -1900,6 +1904,9 @@ sub sales_order {
 sub poso {
   $lxdebug->enter_sub();
 
+  check_oe_access();
+  $auth->assert('purchase_order_edit | sales_order_edit');
+
   $form->{transdate} = $form->current_date(\%myconfig);
   delete $form->{duedate};
 
@@ -1929,17 +1936,63 @@ sub poso {
       qw(partnumber description unit);
   }
 
-  map { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, 0, "0") }
-    qw(creditlimit creditremaining);
-
   &update;
 
   $lxdebug->leave_sub();
 }
 
+sub delivery_order {
+  $lxdebug->enter_sub();
+
+  if ($form->{type} =~ /^sales/) {
+    $auth->assert('sales_delivery_order_edit');
+
+    $form->{vc}    = 'customer';
+    $form->{type}  = 'sales_delivery_order';
+
+  } else {
+    $auth->assert('purchase_delivery_order_edit');
+
+    $form->{vc}    = 'vendor';
+    $form->{type}  = 'purchase_delivery_order';
+  }
+
+  require "bin/mozilla/do.pl";
+
+  $form->{cp_id}           *= 1;
+  $form->{transdate}        = $form->current_date(\%myconfig);
+  delete $form->{duedate};
+
+  $form->{closed}           = 0;
+
+  $form->{old_employee_id}  = $form->{employee_id};
+  $form->{old_salesman_id}  = $form->{salesman_id};
+
+  # reset
+  map { delete $form->{$_} } qw(id subject message cc bcc printed emailed queued creditlimit creditremaining discount tradediscount oldinvtotal);
+
+  for $i (1 .. $form->{rowcount}) {
+    map { $form->{"${_}_${i}"} = $form->parse_amount(\%myconfig, $form->{"${_}_${i}"}) if ($form->{"${_}_${i}"}) } qw(ship qty sellprice listprice basefactor);
+  }
+
+  my %old_values = map { $_ => $form->{$_} } qw(customer_id oldcustomer customer vendor_id oldvendor vendor);
+
+  order_links();
+
+  prepare_order();
+
+  map { $form->{$_} = $old_values{$_} if ($old_values{$_}) } keys %old_values;
+
+  update();
+
+  $lxdebug->leave_sub();
+}
+
 sub e_mail {
   $lxdebug->enter_sub();
 
+  check_oe_access();
+
   $form->{print_and_save} = 1;
 
   $print_post = 1;
@@ -1948,10 +2001,7 @@ sub e_mail {
 
   save();
 
-  my %saved_vars;
-  map({ $saved_vars{$_} = $form->{$_}; } qw(id ordnumber quonumber));
-  restore_form($saved_form);
-  map({ $form->{$_} = $saved_vars{$_}; } qw(id ordnumber quonumber));
+  restore_form($saved_form, 0, qw(id ordnumber quonumber));
 
   edit_e_mail();
 
@@ -1972,6 +2022,10 @@ sub no {
 sub display_form {
   $lxdebug->enter_sub();
 
+  check_oe_access();
+
+  retrieve_partunits() if ($form->{type} =~ /_delivery_order$/);
+
   $form->{"taxaccounts"} =~ s/\s*$//;
   $form->{"taxaccounts"} =~ s/^\s*//;
   foreach my $accno (split(/\s*/, $form->{"taxaccounts"})) {
@@ -2000,212 +2054,21 @@ sub display_form {
   $lxdebug->leave_sub();
 }
 
-sub display_row {
+sub report_for_todo_list {
   $lxdebug->enter_sub();
-  my $numrows = shift;
-
-  # column_index
-  my @header_sort = qw(runningnumber partnumber description ship qty unit sellprice_pg sellprice discount linetotal);
-  my @HEADER = (
-    {  id => 'runningnumber', width => 5,     value => $locale->text('No.'),                  display => 1, },
-    {  id => 'partnumber',    width => 12,    value => $locale->text('Number'),               display => 1, },
-    {  id => 'description',   width => 30,    value => $locale->text('Part Description'),     display => 1, },
-    {  id => 'ship',          width => 5,     value => ($form->{type} eq 'purchase_order' ? $locale->text('Ship rcvd') : $locale->text('Ship')),                 
-       display => $form->{type} =~ /sales_order/ || ($form->{type} =~ /purchase_order/ && !($lizenzen && $form->{vc} eq "customer")) , },
-    {  id => 'qty',           width => 5,     value => $locale->text('Qty'),                  display => 1, },
-    {  id => 'unit',          width => 5,     value => $locale->text('Unit'),                 display => 1, },
-    {  id => 'license',       width => 10,    value => $locale->text('License'),              display => 0, },
-    {  id => 'serialnr',      width => 10,    value => $locale->text('Serial No.'),           display => 0, },
-    {  id => 'projectnr',     width => 10,    value => $locale->text('Project'),              display => 0, },
-    {  id => 'sellprice',     width => 15,    value => $locale->text('Price'),                display => 1, },
-    {  id => 'sellprice_pg',  width => 15,    value => $locale->text('Pricegroup'),           display => $form->{type} =~ /^sales_/,  },
-    {  id => 'discount',      width => 5,     value => $locale->text('Discount'),             display => $form->{vc} eq 'customer', },
-    {  id => 'linetotal',     width => 10,    value => $locale->text('Extended'),             display => 1, },
-    {  id => 'bin',           width => 10,    value => $locale->text('Bin'),                  display => 0, },
-  ); 
-  my @column_index = map { $_->{id} } grep { $_->{display} } @HEADER;
-
-  # cache units
-  my $dimension_units = AM->retrieve_units(\%myconfig, $form, "dimension");
-  my $service_units   = AM->retrieve_units(\%myconfig, $form, "service");
-  my $all_units       = AM->retrieve_units(\%myconfig, $form);
-
-  my $colspan = scalar @column_index;
-
-  $form->{invsubtotal} = 0;
-  map { $form->{"${_}_base"} = 0 } (split(/ /, $form->{taxaccounts}));
-
-  # about details 
-  $myconfig{show_form_details} = 1                            unless (defined($myconfig{show_form_details}));
-  $form->{show_details}        = $myconfig{show_form_details} unless (defined($form->{show_details}));
-  # /about details
-
-  # translations, unused commented out
-#  $runningnumber = $locale->text('No.');
-  $deliverydate  = $locale->text('Delivery Date');
-  $serialnumber  = $locale->text('Serial No.');
-  $projectnumber = $locale->text('Project');
-#  $partsgroup    = $locale->text('Group');
-  $reqdate       = $locale->text('Reqdate');
-  $deliverydate  = $locale->text('Required by');
-
-  # special alignings
-  my %align = map { $_ => 'right' } qw(qty ship right sellprice_pg discount linetotal);
-
-  $form->{marge_total}           = 0;
-  $form->{sellprice_total}       = 0;
-  $form->{lastcost_total}        = 0;
-  my %projectnumber_labels = ();
-  my @projectnumber_values = ("");
-
-  foreach my $item (@{ $form->{"ALL_PROJECTS"} }) {
-    push(@projectnumber_values, $item->{"id"});
-    $projectnumber_labels{$item->{"id"}} = $item->{"projectnumber"};
-  }
-
-  # rows
-  for $i (1 .. $numrows) {
-
-    # undo formatting
-    map { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } qw(qty ship discount sellprice price_new price_old) unless ($form->{simple_save});
-
-# unit begin
-    $form->{"unit_old_$i"}      ||= $form->{"unit_$i"};
-    $form->{"selected_unit_$i"} ||= $form->{"unit_$i"};
-
-    my $local_units = $form->{"inventory_accno_$i"} || $form->{"assembly_$i"} ? $dimension_units 
-                    : $form->{"id_$i"}                                        ? $service_units 
-                    :                                                           $all_units;
-    if (   !$local_units->{$form->{"selected_unit_$i"}}                                          # Die ausgewaehlte Einheit ist fuer diesen Artikel nicht gueltig
-        || !AM->convert_unit($form->{"selected_unit_$i"}, $form->{"unit_old_$i"}, $all_units)) { # (z.B. Dimensionseinheit war ausgewaehlt, es handelt sich aber
-      $form->{"unit_old_$i"} = $form->{"selected_unit_$i"} = $form->{"unit_$i"};                 # um eine Dienstleistung). Dann keinerlei Umrechnung vornehmen.
-    }
-    # adjust prices by unit, ignore if pricegroup changed
-    if ((!$form->{"prices_$i"}) || ($form->{"new_pricegroup_$i"} == $form->{"old_pricegroup_$i"})) {
-        $form->{"sellprice_$i"} *= AM->convert_unit($form->{"selected_unit_$i"}, $form->{"unit_old_$i"}, $all_units) || 1;
-        $form->{"unit_old_$i"}   = $form->{"selected_unit_$i"};
-    }
-    my $this_unit = $form->{"unit_$i"};
-    $this_unit    = $form->{"selected_unit_$i"} if AM->convert_unit($this_unit, $form->{"selected_unit_$i"}, $all_units);
-    $this_unit  ||= "kg";
-
-    $column_data{"unit"} = AM->unit_select_html($local_units, "unit_$i", $this_unit, $form->{"id_$i"} ? $form->{"unit_$i"} : undef);
-# / unit ending
-
-    $form->{"sellprice_$i"} =~ /\.(\d+)/;
-    $decimalplaces = max 2, length $1;
-
-    $discount  = $form->round_amount($form->{"sellprice_$i"} * $form->{"discount_$i"} / 100, $decimalplaces);
-    $linetotal = $form->round_amount($form->{"sellprice_$i"} - $discount, $decimalplaces);
-    $linetotal = $form->round_amount($linetotal * $form->{"qty_$i"}, 2);
-
-    # convert " to &quot;
-    map { $form->{"${_}_$i"} =~ s/\"/&quot;/g } qw(partnumber description unit unit_old);
-
-    $column_data{runningnumber} = $cgi->textfield(-name => "runningnumber_$i", -size => 5,  -value => $i);    # HuT
-    $column_data{partnumber}    = $cgi->textfield(-name => "partnumber_$i",    -size => 12, -value => $form->{"partnumber_$i"});
-    $column_data{description} = ((($rows = $form->numtextrows($form->{"description_$i"}, 30, 6)) > 1) # if description is too large, use a textbox instead
-                                ? $cgi->textarea( -name => "description_$i", -default => H($form->{"description_$i"}), -rows => $rows, -columns => 30)
-                                : $cgi->textfield(-name => "description_$i",   -size => 30, -value => $form->quote($form->{"description_$i"})))
-                                . $cgi->button(-value => $locale->text('L'), -onClick => "set_longdescription_window('longdescription_$i')");
-
-    $form->{"qty_$i"} =~ /\.(\d+)/;
-    my $qty_dec = length $1;
-
-    $column_data{qty}  = $cgi->textfield(-name => "qty_$i", -size => 5, -value => $form->format_amount(\%myconfig, $form->{"qty_$i"}, $qty_dec));
-    $column_data{qty} .= $cgi->button(-onclick => "calculate_qty_selection_window('qty_$i','alu_$i', 'formel_$i', $i)", -value => $locale->text('*/'))
-                       . $cgi->hidden(-name => "formel_$i", -value => $form->{"formel_$i"}) . $cgi->hidden("-name" => "alu_$i", "-value" => $form->{"alu_$i"})
-      if $form->{"formel_$i"};
-    $column_data{ship} = $cgi->textfield(-name => "ship_$i", -size => 5, -value => $form->format_amount(\%myconfig, $form->{"ship_$i"}));
-
-    # build in drop down list for pricesgroups
-    if ($form->{"prices_$i"}) {
-      $column_data{sellprice_pg} = qq|<select name="sellprice_pg_$i">$form->{"prices_$i"}</select>|;
-      $column_data{sellprice}    = $cgi->textfield(-name => "sellprice_$i", -size => 10, -onBlur => 'check_right_number_format(this)', -value =>
-                                   (($form->{"new_pricegroup_$i"} != $form->{"old_pricegroup_$i"})
-                                      ? $form->format_amount(\%myconfig, $form->{"price_new_$i"}, $decimalplaces)
-                                      : $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces)));
-    } else {
-      # for last row and report
-      # set pricegroup drop down list from report menu
-      if ($form->{"sellprice_$i"} != 0) {
-        $form->{"pricegroup_old_$i"} = $form->{"pricegroup_id_$i"};
-        my $default_option           = $form->{"sellprice_$i"}.'--'.$form->{"pricegroup_id_$i"};
-        $column_data{sellprice_pg}   = NTI($cgi->popup_menu("sellpricepg_$i", [ $default_option ], $default_option, { $default_option => $form->{"pricegroup_$i"} || '' }));
-      } else {
-        $column_data{sellprice_pg} = qq|&nbsp;|;
-      }
-      $column_data{sellprice} = $cgi->textfield(-name => "sellprice_$i", -size => 10, -onBlur => "check_right_number_format(this)", -value =>
-                                                $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces));
-    }
-    $column_data{discount}    = $cgi->textfield(-name => "discount_$i", -size => 3, -value => $form->format_amount(\%myconfig, $form->{"discount_$i"}));
-    $column_data{linetotal}   = $form->format_amount(\%myconfig, $linetotal, 2);
-    $column_data{bin}         = $form->{"bin_$i"};
-
-    my @ROW1 = map { value => $column_data{$_}, align => $align{$_} }, @column_index;
-
-    # second row
-    my @ROW2 = ();
-    push @ROW2, { value => qq|<b>$serialnumber</b> <input name="serialnumber_$i" size="15" value="$form->{"serialnumber_$i"}">| } 
-      if $form->{type} !~ /_quotation/;
-    push @ROW2, { value => qq|<b>$projectnumber</b> | . NTI($cgi->popup_menu('-name'  => "project_id_$i",        '-values'  => \@projectnumber_values,
-                                                                             '-labels' => \%projectnumber_labels, '-default' => $form->{"project_id_$i"})) };
-    push @ROW2, { value => qq|<b>$reqdate</b> <input name="reqdate_$i" size="11" onBlur="check_right_date_format(this)" value="$form->{"reqdate_$i"}">| }
-      if $form->{type} =~ /order/;
-    push @ROW2, { value => sprintf qq|<b>%s</b>&nbsp;<input type="checkbox" name="subtotal_$i" value="1" %s>|, 
-                   $locale->text('Subtotal'), $form->{"subtotal_$i"} ? 'checked' : '' };
-
-# begin marge calculations
-    my $marge_color;
-    my $real_sellprice = $form->{"sellprice_$i"} - $discount;
-
-    $form->{"lastcost_$i"} *= 1;
-    $form->{"marge_percent_$i"} = 0;
-
-    if ($real_sellprice && ($form->{"qty_$i"} * 1)) {
-      $form->{"marge_percent_$i"}     = ($real_sellprice - $form->{"lastcost_$i"}) * 100 / $real_sellprice;
-      $myconfig{marge_percent_warn} ||= 15;
-      $marge_color                    = 'color="#ff0000"' if $form->{"id_$i"} && ($form->{"marge_percent_$i"} < (1 * $myconfig{marge_percent_warn}));
-    }
 
-    my $marge_adjust_credit_note = $form->{type} eq 'credit_note' ? -1 : 1;
-    $form->{"marge_absolut_$i"}  = ($real_sellprice - $form->{"lastcost_$i"}) * $form->{"qty_$i"} * $marge_adjust_credit_note;
-    $form->{"marge_total"}      += $form->{"marge_absolut_$i"};
-    $form->{"lastcost_total"}   += $form->{"lastcost_$i"} * $form->{"qty_$i"};
-    $form->{"sellprice_total"}  += $real_sellprice * $form->{"qty_$i"};
-
-    map { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, 2) } qw(marge_absolut marge_percent);
-
-    push @ROW2, { value => sprintf qq|<font %s><b>%s</b> %s &nbsp;%s%% </font> &nbsp;<b>%s</b> %s &nbsp;<b>%s</b> %s|,
-                   $marge_color, $locale->text('Ertrag'),$form->{"marge_absolut_$i"}, $form->{"marge_percent_$i"},
-                   $locale->text('LP'), $form->format_amount(\%myconfig, $form->{"listprice_$i"}, 2),
-                   $locale->text('EK'), $form->format_amount(\%myconfig, $form->{"lastcost_$i"}, 2) }
-      if $form->{"id_$i"} && $form->{type} =~ /^sales_/;
-# / marge calculations ending
-
-    my @HIDDENS = map { value => $_}, (
-          $cgi->hidden("-name" => "unit_old_$i", "-value" => $form->{"selected_unit_$i"}),
-          $cgi->hidden("-name" => "price_new_$i", "-value" => $form->format_amount(\%myconfig, $form->{"price_new_$i"})),
-          map { ($cgi->hidden("-name" => $_, "-value" => $form->{$_})); } map { $_."_$i" } 
-            qw(orderitems_id bo pricegroup_old price_old id inventory_accno bin partsgroup partnotes
-               income_accno expense_accno listprice assembly taxaccounts ordnumber transdate cusordnumber
-               longdescription basefactor marge_absolut marge_percent lastcost)
-    );
-
-    map { $form->{"${_}_base"} += $linetotal } (split(/ /, $form->{"taxaccounts_$i"}));
+  my $quotations = OE->transactions_for_todo_list();
+  my $content;
 
-    $form->{invsubtotal} += $linetotal;
+  if (@{ $quotations }) {
+    my $edit_url = build_std_url('script=oe.pl', 'action=edit', 'type=sales_quotation', 'vc=customer');
 
-    push @ROWS, { ROW1 => \@ROW1, ROW2 => \@ROW2, HIDDENS => \@HIDDENS, colspan => $colspan, };
-  }
-
-  print $form->parse_html_template2('oe/sales_order', { ROWS   => \@ROWS,
-                                                        HEADER => \@HEADER,
-                                                      });
-
-  if (0 != ($form->{sellprice_total} * 1)) {
-    $form->{marge_percent} = ($form->{sellprice_total} - $form->{lastcost_total}) / $form->{sellprice_total} * 100;
+    $content     = $form->parse_html_template('oe/report_for_todo_list', { 'QUOTATIONS' => $quotations,
+                                                                           'edit_url'   => $edit_url });
   }
 
   $lxdebug->leave_sub();
+
+  return $content;
 }
+