$form->{OUT}          = $config->printer->printer_command;
   $form->{OUT_MODE}     = '|-';
 
-  $form->{TEMPLATE_DRIVER_OPTIONS} = {
-    variable_content_types => {
-      longdescription => 'html',
-      partnotes       => 'html',
-      notes           => 'html',
-    },
-  };
+  $form->{TEMPLATE_DRIVER_OPTIONS} = { };
+  $form->{TEMPLATE_DRIVER_OPTIONS}->{variable_content_types} = $form->get_variable_content_types();
 
   $form->prepare_for_printing;
 
 
--- /dev/null
+package SL::BackgroundJob::MassDeliveryOrderPrinting;
+
+use strict;
+use warnings;
+
+use parent qw(SL::BackgroundJob::Base);
+
+use SL::DB::DeliveryOrder;
+use SL::DB::Order;  # origin order to delivery_order
+use SL::DB::Printer;
+use SL::SessionFile;
+use SL::Template;
+use SL::Helper::MassPrintCreatePDF qw(:all);
+use SL::Helper::CreatePDF qw(:all);
+use SL::Helper::File qw(store_pdf append_general_pdf_attachments);
+
+use constant WAITING_FOR_EXECUTION       => 0;
+use constant PRINTING_DELIVERY_ORDERS    => 1;
+use constant DONE                        => 2;
+
+# Data format:
+# my $data             = {
+#   record_ids          => [ 123, 124, 127, ],
+#   printer_id         => 4711,
+#   num_created        => 0,
+#   num_printed        => 0,
+#   printed_ids        => [ 234, 235, ],
+#   conversion_errors  => [ { id => 124, number => 'A981723', message => "Stuff went boom" }, ],
+#   print_errors       => [ { id => 234, number => 'L87123123', message => "Printer is out of coffee" }, ],
+#   pdf_file_name      => 'qweqwe.pdf',
+#   session_id         => $::auth->get_session_id,
+# };
+
+
+sub convert_deliveryorders_to_pdf {
+  my ($self) = @_;
+
+  my $job_obj = $self->{job_obj};
+  my $db      = $job_obj->db;
+
+  $job_obj->set_data(status => PRINTING_DELIVERY_ORDERS())->save;
+  my $data   = $job_obj->data_as_hash;
+
+  my $printer_id = $data->{printer_id};
+  if ( $data->{media} ne 'printer' ) {
+      undef $printer_id;
+      $data->{media} = 'file';
+  }
+  my %variables  = (
+    type         => 'delivery_order',
+    formname     =>  $data->{formname},
+    format       =>  $data->{format},
+    media        =>  $data->{media},
+    printer_id   =>  $printer_id,
+    copies       =>  $data->{copies},
+  );
+
+  my @pdf_file_names;
+  foreach my $delivery_order_id (@{ $data->{record_ids} }) {
+    my $number = $delivery_order_id;
+    my $delivery_order = SL::DB::DeliveryOrder->new(id => $delivery_order_id)->load;
+
+    eval {
+      $number = $delivery_order->donumber;
+
+      my %params = (
+        variables  => \%variables,
+        document   => $delivery_order,
+        return     => 'file_name',
+       );
+
+      push @pdf_file_names, $self->create_massprint_pdf(%params);
+
+      $data->{num_created}++;
+
+      1;
+
+    } or do {
+      push @{ $data->{conversion_errors} }, { id => $delivery_order->id, number => $number, message => $@ };
+    };
+
+    $job_obj->update_attributes(data_as_hash => $data);
+  }
+
+  $self->merge_massprint_pdf(file_names => \@pdf_file_names, type => 'delivery_order' ) if scalar(@pdf_file_names) > 0;
+}
+
+sub run {
+  my ($self, $job_obj) = @_;
+
+  $self->{job_obj}         = $job_obj;
+
+  $self->convert_deliveryorders_to_pdf;
+  $self->print_pdfs;
+
+  my $data       = $job_obj->data_as_hash;
+  $data->{num_printed} =  $data->{num_created};
+  $job_obj->update_attributes(data_as_hash => $data);
+  $job_obj->set_data(status => DONE())->save;
+
+  return 1;
+}
+
+1;
+
 
 use SL::SessionFile;
 use SL::Template;
 use SL::Locale::String qw(t8);
+use SL::Helper::MassPrintCreatePDF qw(:all);
+use SL::Helper::CreatePDF qw(:all);
+use SL::Helper::File qw(store_pdf append_general_pdf_attachments);
 use SL::Webdav;
 
 use constant WAITING_FOR_EXECUTION       => 0;
 use constant CONVERTING_DELIVERY_ORDERS  => 1;
 use constant PRINTING_INVOICES           => 2;
 use constant DONE                        => 3;
+
 # Data format:
 # my $data             = {
 #   record_ids          => [ 123, 124, 127, ],
     my $data   = $job_obj->data_as_hash;
 
     eval {
+      my $invoice;
       my $sales_delivery_order = SL::DB::DeliveryOrder->new(id => $delivery_order_id)->load;
       $number                  = $sales_delivery_order->donumber;
-      my %conversion_params    = $data->{transdate} ? ('attributes' => { transdate => $data->{transdate} }) : ();
-      my $invoice              = $sales_delivery_order->convert_to_invoice(%conversion_params);
 
-      die $db->error if !$invoice;
+      if (!$db->with_transaction(sub {
+        $invoice = $sales_delivery_order->convert_to_invoice(sub { $data->{transdate} ? ('attributes' => { transdate => $data->{transdate} }) :
+                                                                         undef }->() ) || die $db->error;
+        1;
+      })) {
+        die $db->error;
+      }
 
       $data->{num_created}++;
       push @{ $data->{invoice_ids} }, $invoice->id;
   my $db      = $job_obj->db;
 
   $job_obj->set_data(status => PRINTING_INVOICES())->save;
+  my $data = $job_obj->data_as_hash;
 
-  require SL::Controller::MassInvoiceCreatePrint;
-
-  my $printer_id = $job_obj->data_as_hash->{printer_id};
-  my $ctrl       = SL::Controller::MassInvoiceCreatePrint->new;
+  my $printer_id = $data->{printer_id};
+  if ( $data->{media} ne 'printer' ) {
+      undef $printer_id;
+      $data->{media} = 'file';
+  }
   my %variables  = (
     type         => 'invoice',
     formname     => 'invoice',
     format       => 'pdf',
     media        => $printer_id ? 'printer' : 'file',
+    printer_id   => $printer_id,
   );
 
   my @pdf_file_names;
 
   foreach my $invoice (@{ $self->{invoices} }) {
-    my $data = $job_obj->data_as_hash;
 
     eval {
-      my %create_params = (
-        template  => $ctrl->find_template(name => 'invoice', printer_id => $printer_id),
-        variables => Form->new(''),
+      my %params = (
+        variables => \%variables,
         return    => 'file_name',
-        variable_content_types => { longdescription => 'html',
-                                    partnotes       => 'html',
-                                    notes           => 'html',}
+        document  => $invoice,
       );
+      push @pdf_file_names, $self->create_massprint_pdf(%params);
 
+      $data->{num_printed}++;
 
-
-      $create_params{variables}->{$_} = $variables{$_} for keys %variables;
-
-      $invoice->flatten_to_form($create_params{variables}, format_amounts => 1);
-      $create_params{variables}->prepare_for_printing;
-
-      push @pdf_file_names, $ctrl->create_pdf(%create_params);
-
+      # OLD WebDAV Code, may be deleted:
       # copy file to webdav folder
       if ($::instance_conf->get_webdav_documents) {
         my $webdav = SL::Webdav->new(
         }
       }
 
-      $data->{num_printed}++;
-
       1;
 
     } or do {
     $job_obj->update_attributes(data_as_hash => $data);
   }
 
-  if (@pdf_file_names) {
-    my $data = $job_obj->data_as_hash;
-
-    eval {
-      $self->{merged_pdf} = $ctrl->merge_pdfs(file_names => \@pdf_file_names);
-      unlink @pdf_file_names;
-
-      if (!$printer_id) {
-        my $file_name = 'mass_invoice' . $job_obj->id . '.pdf';
-        my $sfile     = SL::SessionFile->new($file_name, mode => 'w', session_id => $data->{session_id});
-        $sfile->fh->print($self->{merged_pdf});
-        $sfile->fh->close;
-
-        $data->{pdf_file_name} = $file_name;
-      }
-
-      1;
-
-    } or do {
-      push @{ $data->{print_errors} }, { message => $@ };
-    };
-
-    $job_obj->update_attributes(data_as_hash => $data);
-  }
-}
-
-sub print_pdfs {
-  my ($self)     = @_;
-
-  my $job_obj         = $self->{job_obj};
-  my $data            = $job_obj->data_as_hash;
-  my $printer_id      = $data->{printer_id};
-  my $copy_printer_id = $data->{copy_printer_id};
-
-  return if !$printer_id;
-
-  my $out;
-
-  foreach  my $local_printer_id ($printer_id, $copy_printer_id) {
-    next unless $local_printer_id;
-    SL::DB::Printer
-      ->new(id => $local_printer_id)
-      ->load
-      ->print_document(content => $self->{merged_pdf});
-  }
-
+  $self->merge_massprint_pdf(file_names => \@pdf_file_names, type => 'invoice' ) if scalar(@pdf_file_names) > 0;
 }
 
 sub run {
 
--- /dev/null
+package SL::Controller::MassDeliveryOrderPrint;
+
+use strict;
+
+use parent qw(SL::Controller::Base);
+
+use File::Slurp ();
+use File::Copy;
+use List::MoreUtils qw(uniq);
+use List::Util qw(first);
+
+use SL::Controller::Helper::GetModels;
+use SL::BackgroundJob::MassDeliveryOrderPrinting;
+use SL::DB::Customer;
+use SL::DB::DeliveryOrder;
+use SL::DB::Order;
+use SL::DB::Part;
+use SL::DB::Printer;
+use SL::Helper::MassPrintCreatePDF qw(:all);
+use SL::Helper::CreatePDF qw(:all);
+use SL::Helper::PrintOptions;
+use SL::Helper::Flash;
+use SL::Locale::String;
+use SL::SessionFile;
+use SL::System::TaskServer;
+
+use Rose::Object::MakeMethods::Generic
+(
+  'scalar --get_set_init' => [ qw(delivery_order_models delivery_order_ids printers filter_summary temp_files) ],
+);
+
+__PACKAGE__->run_before('setup');
+
+#
+# actions
+#
+sub action_list_delivery_orders {
+  my ($self) = @_;
+
+  my $show = ($::form->{noshow}?0:1);
+  delete $::form->{noshow};
+
+  if ($::form->{ids}) {
+    my $key = 'MassDeliveryOrderPrint::ids-' . $::form->{ids};
+    $self->delivery_order_ids($::auth->get_session_value($key) || []);
+    $self->delivery_order_models->add_additional_url_params(ids => $::form->{ids});
+  }
+
+  my %selected_ids = map { +($_ => 1) } @{ $self->delivery_order_ids };
+
+  my $pr = SL::DB::Manager::Printer->find_by(
+      printer_description => $::locale->text("sales_delivery_order_printer"));
+  if ($pr ) {
+      $::form->{printer_id} = $pr->id;
+  }
+  $self->render('mass_delivery_order_print/list_delivery_orders',
+                title        => $::locale->text('Print delivery orders'),
+                nowshow      => $show,
+                print_opt    => $self->print_options(hide_language_id => 1),
+                selected_ids => \%selected_ids);
+}
+
+sub action_mass_mdo_download {
+  my ($self) = @_;
+  my $job    = SL::DB::BackgroundJob->new(id => $::form->{job_id})->load;
+
+  my $sfile  = SL::SessionFile->new($job->data_as_hash->{pdf_file_name}, mode => 'r');
+  die $! if !$sfile->fh;
+
+  my $merged_pdf = do { local $/; my $fh = $sfile->fh; <$fh> };
+  $sfile->fh->close;
+
+  my $file_name =  t8('Sales Delivery Orders') . '-' . DateTime->now_local->strftime('%Y%m%d%H%M%S') . '.pdf';
+  $file_name    =~ s{[^\w\.]+}{_}g;
+
+  return $self->send_file(
+    \$merged_pdf,
+    type => 'application/pdf',
+    name => $file_name,
+  );
+}
+
+sub action_mass_mdo_status {
+  my ($self) = @_;
+  $::lxdebug->enter_sub();
+  eval {
+    my $job = SL::DB::BackgroundJob->new(id => $::form->{job_id})->load;
+    my $html = $self->render('mass_delivery_order_print/_print_status', { output => 0 }, job => $job);
+
+    $self->js->html('#mass_print_dialog', $html);
+    if ( $job->data_as_hash->{status} == SL::BackgroundJob::MassDeliveryOrderPrinting->DONE() ) {
+      foreach my $dorder_id (@{$job->data_as_hash->{record_ids}}) {
+        $self->js->prop('#multi_id_id_'.$dorder_id,'checked',0);
+      }
+      $self->js->prop('#multi_all','checked',0);
+      $self->js->run('kivi.MassDeliveryOrderPrint.massConversionFinished');
+    }
+    1;
+  } or do {
+    $self->js->run('kivi.MassDeliveryOrderPrint.massConversionFinished')
+      ->run('kivi.MassDeliveryOrderPrint.massConversionFinishProcess')
+      ->flash('error', t8('No such job #1 in the database.',$::form->{job_id}));
+  };
+  $self->js->render;
+
+  $::lxdebug->leave_sub();
+}
+
+sub action_mass_mdo_print {
+  my ($self) = @_;
+  $::lxdebug->enter_sub();
+
+  eval {
+    my @do_ids = @{ $::form->{id} || [] };
+    push @do_ids, map { $::form->{"trans_id_$_"} } grep { $::form->{"multi_id_$_"} } (1..$::form->{rowcount});
+
+    my @delivery_orders = map { SL::DB::DeliveryOrder->new(id => $_)->load } @do_ids;
+
+    if (!@delivery_orders) {
+      $self->js->flash('error', t8('No delivery orders have been selected.'));
+    } else {
+      my $job              = SL::DB::BackgroundJob->new(
+        type               => 'once',
+        active             => 1,
+        package_name       => 'MassDeliveryOrderPrinting',
+
+      )->set_data(
+        record_ids         => [ @do_ids ],
+        printer_id         => $::form->{printer_id},
+        formname           => $::form->{formname},
+        format             => $::form->{format},
+        media              => $::form->{media},
+        bothsided          => ($::form->{bothsided}?1:0),
+        copies             => $::form->{copies},
+        status             => SL::BackgroundJob::MassDeliveryOrderPrinting->WAITING_FOR_EXECUTION(),
+        num_created        => 0,
+        num_printed        => 0,
+        printed_ids        => [ ],
+        conversion_errors  => [ ],
+        print_errors       => [ ],
+        session_id         => $::auth->get_session_id,
+
+      )->update_next_run_at;
+
+      SL::System::TaskServer->new->wake_up;
+      my $html = $self->render('mass_delivery_order_print/_print_status', { output => 0 }, job => $job);
+
+      $self->js
+        ->html('#mass_print_dialog', $html)
+        ->run('kivi.MassDeliveryOrderPrint.massConversionPopup')
+        ->run('kivi.MassDeliveryOrderPrint.massConversionStarted');
+    }
+    1;
+  } or do {
+    my $errstr = $@;
+    my $htmlstr = $errstr;
+    $htmlstr =~ s/\n/<br>/g;
+    $self->js->flash('error', t8('Document generating failed. Please check Templates an LateX !'));
+    $self->js->flash_detail('error', $htmlstr);
+  };
+  $self->js->render;
+  $::lxdebug->leave_sub();
+}
+
+sub action_downloadpdf {
+  my ($self) = @_;
+  $::lxdebug->enter_sub();
+  if ( $::form->{filename} ) {
+    my $content = scalar File::Slurp::read_file($::form->{filename});
+    my $file_name = $::form->get_formname_translation($::form->{formname}) .
+      '-' . DateTime->now_local->strftime('%Y%m%d%H%M%S') . '.pdf';
+    $file_name    =~ s{[^\w\.]+}{_}g;
+
+    unlink($::form->{filename});
+
+    return $self->send_file(
+      \$content,
+      type => 'application/pdf',
+      name => $file_name,
+    );
+  } else {
+    flash('error', t8('No filename exists!'));
+  }
+  $::lxdebug->leave_sub();
+}
+
+#
+# filters
+#
+
+sub init_printers { SL::DB::Manager::Printer->get_all_sorted }
+sub init_delivery_order_ids { [] }
+sub init_temp_files { [] }
+
+sub init_delivery_order_models {
+  my ($self)             = @_;
+  my @delivery_order_ids = @{ $self->delivery_order_ids };
+
+  SL::Controller::Helper::GetModels->new(
+    controller   => $_[0],
+    model        => 'DeliveryOrder',
+    (paginated   => 0,) x !!@delivery_order_ids,
+    sorted       => {
+      _default     => {
+        by           => 'reqdate',
+        dir          => 0,
+      },
+      customer     => t8('Customer'),
+      donumber     => t8('Delivery Order Number'),
+      employee     => t8('Employee'),
+      ordnumber    => t8('Order Number'),
+      reqdate      => t8('Delivery Date'),
+      transdate    => t8('Date'),
+    },
+    with_objects => [ qw(customer employee) ],
+    query        => [
+      '!customer_id' => undef,
+      or             => [ closed    => undef, closed    => 0 ],
+      (id            => \@delivery_order_ids) x !!@delivery_order_ids,
+    ],
+  );
+}
+
+sub init_filter_summary {
+  my ($self) =@_;
+  my $filter = $::form->{filter} || { customer => {}, shipto => {}, };
+
+  my @filters;
+  push @filters, t8('Customer')                              . ' ' . $filter->{customer}->{'name:substr::ilike'}     if $filter->{customer}->{'name:substr::ilike'};
+  push @filters, t8('Shipping address (name)')               . ' ' . $filter->{shipto}->{'shiptoname:substr::ilike'} if $filter->{shipto}->{'shiptoname:substr::ilike'};
+  push @filters, t8('Delivery Date') . ' ' . t8('From Date') . ' ' . $filter->{'reqdate:date::ge'}                   if $filter->{'reqdate:date::ge'};
+  push @filters, t8('Delivery Date') . ' ' . t8('To Date')   . ' ' . $filter->{'reqdate:date::le'}                   if $filter->{'reqdate:date::le'};
+
+  return join ', ', @filters;
+}
+
+sub setup {
+  my ($self) = @_;
+  $::auth->assert('sales_delivery_order_edit');
+  $::request->layout->use_javascript("${_}.js")  for qw(kivi.MassDeliveryOrderPrint);
+}
+
+
+sub generate_documents {
+  my ($self, @delivery_orders) = @_;
+
+  my %pdf_params = (
+    'documents'       => \@delivery_orders ,
+    'variables'       => {
+      'type'            => $::form->{type},
+      'formname'        => $::form->{formname},
+      'language_id'     => '',
+      'format'          => 'pdf',
+      'media'           => 'file',
+      'printer_id'      => $::form->{printer_id},
+    });
+
+  my ($temp_fh, $outname) = File::Temp::tempfile(
+    'kivitendo-outfileXXXXXX',
+    SUFFIX => '.pdf',
+    DIR    => $::lx_office_conf{paths}->{userspath},
+    UNLINK => 0,
+  );
+  close $temp_fh;
+
+  my @pdf_file_names = $self->create_pdfs(%pdf_params);
+  my $fcount = scalar(@pdf_file_names);
+  if ( $fcount < 2 ) {
+    copy($pdf_file_names[0],$outname);
+  } else {
+    if ( !$self->merge_pdfs(file_names => \@pdf_file_names, out_path => $outname, bothsided => $::form->{bothsided} )) {
+      $::lxdebug->leave_sub();
+      return 0;
+    }
+  }
+  foreach my $dorder (@delivery_orders) {
+    $self->js->prop('#multi_id_id_'.$dorder->id,'checked',0);
+  }
+  $self->js->prop('#multi_all','checked',0);
+  return $outname;
+}
+
+1;
 
 use SL::DB::DeliveryOrder;
 use SL::DB::Order;
 use SL::DB::Printer;
+use SL::Helper::MassPrintCreatePDF qw(:all);
 use SL::Helper::CreatePDF qw(:all);
 use SL::Helper::Flash;
 use SL::Locale::String;
 use SL::SessionFile;
 use SL::System::TaskServer;
-
 use Rose::Object::MakeMethods::Generic
 (
   'scalar --get_set_init' => [ qw(invoice_models invoice_ids sales_delivery_order_models printers default_printer_id today) ],
     record_ids         => [ map { $_->id } @records[0..$num - 1] ],
     printer_id         => $::form->{printer_id},
     copy_printer_id    => $::form->{copy_printer_id},
+    bothsided          => ($::form->{bothsided}?1:0),
     transdate          => $::form->{transdate},
     status             => SL::BackgroundJob::MassRecordCreationAndPrinting->WAITING_FOR_EXECUTION(),
     num_created        => 0,
   $sfile->fh->close;
 
   my $type      = 'Invoices';
-  my $file_name =  t8($type) . '-' . DateTime->today_local->strftime('%Y%m%d%H%M%S') . '.pdf';
+  my $file_name =  t8($type) . '-' . DateTime->now_local->strftime('%Y%m%d%H%M%S') . '.pdf';
   $file_name    =~ s{[^\w\.]+}{_}g;
 
   return $self->send_file(
 #
 
 sub init_printers { SL::DB::Manager::Printer->get_all_sorted }
+#sub init_att      { require SL::Controller::Attachments; SL::Controller::Attachments->new() }
 sub init_invoice_ids { [] }
 sub init_today         { DateTime->today_local }
 
 # helpers
 #
 
-sub create_pdfs {
-  my ($self, %params) = @_;
-
-  my @pdf_file_names;
-  foreach my $invoice (@{ $params{invoices} }) {
-    my %create_params = (
-      template  => $self->find_template(name => 'invoice', printer_id => $params{printer_id}),
-      variables => Form->new(''),
-      return    => 'file_name',
-      variable_content_types => { longdescription => 'html',
-                                  partnotes       => 'html',
-                                  notes           => 'html',}
-    );
-
-    $create_params{variables}->{$_} = $params{variables}->{$_} for keys %{ $params{variables} };
-
-    $invoice->flatten_to_form($create_params{variables}, format_amounts => 1);
-    $create_params{variables}->prepare_for_printing;
-
-    push @pdf_file_names, $self->create_pdf(%create_params);
-  }
-
-  return @pdf_file_names;
-}
 
 sub download_or_print_documents {
   my ($self, %params) = @_;
 
   eval {
     my %pdf_params = (
-      invoices        => $params{invoices},
-      printer_id      => $params{printer_id},
+      documents       => $params{invoices},
       variables       => {
         type        => 'invoice',
         formname    => 'invoice',
         format      => 'pdf',
         media       => $params{printer_id} ? 'printer' : 'file',
+        printer_id  => $params{printer_id},
       });
 
     @pdf_file_names = $self->create_pdfs(%pdf_params);
     unlink @pdf_file_names;
 
     if (!$params{printer_id}) {
-      my $file_name =  t8("Invoices") . '-' . DateTime->today_local->strftime('%Y%m%d%H%M%S') . '.pdf';
+      my $file_name =  t8("Invoices") . '-' . DateTime->now_local->strftime('%Y%m%d%H%M%S') . '.pdf';
       $file_name    =~ s{[^\w\.]+}{_}g;
 
       return $self->send_file(
 
 
     $idx++;
 
-    $form->{"partsgroup_${idx}"} = $item->part->partsgroup->partsgroup if _has($item->part, 'partsgroup_id');
+    $form->{"std_warehouse_${idx}"} = $item->part->warehouse->description if _has($item->part, 'warehouse_id');
+    $form->{"std_bin_${idx}"}       = $item->part->bin->description       if _has($item->part, 'bin_id');
+    $form->{"partsgroup_${idx}"}    = $item->part->partsgroup->partsgroup if _has($item->part, 'partsgroup_id');
     _copy($item,          $form, "${items_name}_", "_${idx}", 0,               qw(id)) if $items_name;
     # TODO: is part_type correct here? Do we need to set part_type as default?
     _copy($item->part,    $form, '',               "_${idx}", 0,               qw(id partnumber weight part_type));
 
   $main::lxdebug->leave_sub();
 }
 
+sub get_variable_content_types {
+  my %html_variables  = (
+      longdescription => 'html',
+      partnotes       => 'html',
+      notes           => 'html',
+      orignotes       => 'html',
+      notes1          => 'html',
+      notes2          => 'html',
+      notes3          => 'html',
+      notes4          => 'html',
+      header_text     => 'html',
+      footer_text     => 'html',
+  );
+  return \%html_variables;
+}
+
 sub current_date {
   $main::lxdebug->enter_sub();
 
 
 
  $self->store_pdf($self);
 
- $self->append_general_pdf_attachments($self) if ( $ext_for_format eq 'pdf' );
+ $self->append_general_pdf_attachments(filepath => $pdf_filename, type => $form->{type}) if ( $ext_for_format eq 'pdf' );
+
+#It is also used in MassPrint Helper
+# 
 
 =head1 DESCRIPTION
 
 
--- /dev/null
+package SL::Helper::MassPrintCreatePDF;
+
+use strict;
+
+use Exporter 'import';
+our @EXPORT_OK = qw(create_massprint_pdf merge_massprint_pdf create_pdfs print_pdfs);
+our %EXPORT_TAGS = (
+  all => \@EXPORT_OK,
+);
+use SL::Helper::CreatePDF qw(:all);
+use SL::Helper::File qw(store_pdf append_general_pdf_attachments);
+
+sub create_pdfs {
+  my ($self, %params) = @_;
+  my @pdf_file_names;
+  foreach my $document (@{ $params{documents} }) {
+    $params{document} = $document;
+    push @pdf_file_names, $self->create_massprint_pdf(%params);
+  }
+
+  return @pdf_file_names;
+}
+
+sub create_massprint_pdf {
+  my ($self, %params) = @_;
+  my $form = Form->new('');
+  my %create_params = (
+      variables => $form,
+      return    => 'file_name',
+  );
+  ## find_template may return a list !
+  $create_params{template} = $self->find_template(name => $params{variables}->{formname}, printer_id => $params{printer_id});
+  $form->{cwd}= POSIX::getcwd();
+
+  $form->{$_} = $params{variables}->{$_} for keys %{ $params{variables} };
+
+  $create_params{variable_content_types} = $form->get_variable_content_types();
+  $params{document}->flatten_to_form($form, format_amounts => 1);
+  # flatten_to_form sets payment_terms from customer/vendor - we do not want that here
+  # really ??
+  delete $form->{payment_terms} if !$form->{payment_id};
+
+  $form->prepare_for_printing;
+  $form->{attachment_filename} = $form->generate_attachment_filename;
+
+  my $pdf_filename = $self->create_pdf(%create_params);
+
+  if ( $::instance_conf->get_doc_storage && ! $form->{preview}) {
+    $self->append_general_pdf_attachments(filepath => $pdf_filename, type => $form->{type} );
+    $form->{tmpfile} = $pdf_filename;
+    $form->{id}      = $params{document}->id;
+    $self->store_pdf($form);
+  }
+  $form->{id} = $params{document}->id;
+  if ( ! $form->{preview} ) {
+    if ( ref($params{document}) eq 'SL::DB::DeliveryOrder' ) {
+      $form->{snumbers} = "ordnumber_" . $params{document}->donumber;
+    }
+    else {
+      $form->{snumbers} = "unknown";
+    }
+    $form->{addition} = "PRINTED";
+    $form->{what_done} = $::form->{type};
+    $form->save_history;
+  }
+  return $pdf_filename;
+}
+
+sub merge_massprint_pdf {
+  my ($self, %params)     = @_;
+  return unless $params{file_names} && $params{type};
+
+  my $job_obj = $self->{job_obj};
+  my $data    = $job_obj->data_as_hash;
+  my @pdf_file_names = @{$params{file_names}};
+
+  eval {
+    my $file_name = 'mass_'.$params{type}.'_'.$job_obj->id . '.pdf';
+    my $sfile     = SL::SessionFile->new($file_name, mode => 'w', session_id => $data->{session_id});
+    $sfile->fh->close;
+    $data->{pdf_file_name} = $sfile->file_name;
+
+    $self->merge_pdfs(file_names => \@pdf_file_names, bothsided => $data->{bothsided}, out_path => $data->{pdf_file_name});
+    unlink @pdf_file_names;
+
+    1;
+
+  } or do {
+    push @{ $data->{print_errors} }, { message => $@ };
+  };
+
+  $job_obj->update_attributes(data_as_hash => $data);
+}
+
+sub print_pdfs {
+  my ($self)     = @_;
+
+  my $job_obj         = $self->{job_obj};
+  my $data            = $job_obj->data_as_hash;
+  my $printer_id      = $data->{printer_id};
+  my $copy_printer_id = $data->{copy_printer_id};
+
+  return if !$printer_id;
+
+  my $out;
+
+  foreach  my $local_printer_id ($printer_id, $copy_printer_id) {
+    next unless $local_printer_id;
+    SL::DB::Printer
+      ->new(id => $local_printer_id)
+      ->load
+      ->print_document(file_name => $data->{pdf_file_name});
+  }
+
+}
+
+1;
+
+__END__
+
+=encoding utf-8
+
+=head1 NAME
+
+SL::Helper::MassPrint_CreatePDF
+
+
+=head1 DESCRIPTION
+
+This Helper used bei Background Processing for Mass Printing.
+The redundant way to fill data for createPDF is concentrated into this helper.
+There are some additional settings for printing which are missed in CreatePDF Helper
+and also the appending of generic PDF-Documents.
+
+(This extension may be included in the CreatePDF Helper).
+
+
+=head1 REQUIRES
+
+L<SL::Helper::CreatePDF>
+
+=head1 METHODS
+
+=head2 C<create_massprint_pdf PARAMS>
+
+a tempory $form is used to set
+
+=over 2
+
+=item 1. content types
+
+=item 2. flatten_to_form
+
+=item 3. prepare_for_printing
+
+=item 4. set history
+
+=back
+
+before printing is done
+
+
+=head1 AUTHOR
+
+Martin Helmling E<lt>martin.helmling@opendynamic.deE<gt>
+
+
+=cut
+
 
 
   $form->{follow_up_trans_info} = $form->{donumber} .'('. $form->{VC_OBJ}->name .')';
 
-  $::request->{layout}->use_javascript(map { "${_}.js" } qw(kivi.File kivi.SalesPurchase ckeditor/ckeditor ckeditor/adapters/jquery kivi.io autocomplete_customer autocomplete_part));
+  $::request->{layout}->use_javascript(map { "${_}.js" } qw(kivi.File kivi.MassDeliveryOrderPrint kivi.SalesPurchase ckeditor/ckeditor ckeditor/adapters/jquery kivi.io autocomplete_customer autocomplete_part));
 
   my @custom_hidden;
   push @custom_hidden, map { "shiptocvar_" . $_->name } @{ SL::DB::Manager::CustomVariableConfig->get_all(where => [ module => 'ShipTo' ]) };
   my $locale   = $main::locale;
   my $cgi      = $::request->{cgi};
 
+  $::request->{layout}->use_javascript(map { "${_}.js" } qw(kivi.MassDeliveryOrderPrint));
   ($form->{ $form->{vc} }, $form->{"$form->{vc}_id"}) = split(/--/, $form->{ $form->{vc} });
 
   report_generator_set_default_sort('transdate', 1);
   my $href = build_std_url('action=orders', grep { $form->{$_} } @hidden_variables);
 
   my %column_defs = (
-    'ids'                     => { 'text' => '', },
+    'ids'                     => { 'text' => '<input type="checkbox" id="multi_all" value="1">', 'align' => 'center' },
     'transdate'               => { 'text' => $locale->text('Delivery Order Date'), },
     'reqdate'                 => { 'text' => $locale->text('Reqdate'), },
     'id'                      => { 'text' => $locale->text('ID'), },
     push @options, $locale->text('Not delivered');
   }
 
+  # all_vc ruft get_employee auf, dort wird emloyee überschrieben, deshalb retten:
+  my $save_employee_id = $form->{'employee_id'};
+  my $save_employee    = $form->{'employee'};
+  $form->all_vc(\%myconfig, $form->{vc}, ($form->{vc} eq 'customer') ? "AR" : "AP");
+  $form->{'employee_id'} = $save_employee_id;
+  $form->{'employee'}    = $save_employee;
+
+  my $pr = SL::DB::Manager::Printer->find_by(
+      printer_description => $::locale->text("sales_delivery_order_printer"));
+  if ($pr ) {
+      $form->{printer_id} = $pr->id;
+  }
+
   $report->set_options('top_info_text'        => join("\n", @options),
                        'raw_top_info_text'    => $form->parse_html_template('do/orders_top'),
-                       'raw_bottom_info_text' => $form->parse_html_template('do/orders_bottom'),
+                       'raw_bottom_info_text' => $form->parse_html_template('do/orders_bottom',
+                        {
+                           print_options   => print_options(inline => 1,hide_language_id => 1),
+                        }),
                        'output_format'        => 'HTML',
                        'title'                => $form->{title},
                        'attachment_basename'  => $attachment_basename . strftime('_%Y%m%d', localtime time),
 
     my $row = { map { $_ => { 'data' => $dord->{$_} } } @columns };
 
+    my $ord_id = $dord->{id};
     $row->{ids}  = {
-      'raw_data' =>   $cgi->hidden('-name' => "trans_id_${idx}", '-value' => $dord->{id})
-                    . $cgi->checkbox('-name' => "multi_id_${idx}", '-value' => 1, '-label' => ''),
+      'raw_data' =>   $cgi->hidden('-name' => "trans_id_${idx}", '-value' => $ord_id)
+                    . $cgi->checkbox('-name' => "multi_id_${idx}",' id' => "multi_id_id_".$ord_id, '-value' => 1, '-label' => ''),
       'valign'   => 'center',
       'align'    => 'center',
     };
 
 
   $form->{TEMPLATE_DRIVER_OPTIONS} = { };
   if (any { $form->{type} eq $_ } qw(sales_quotation sales_order sales_delivery_order invoice request_quotation purchase_order purchase_delivery_order credit_note)) {
-    $form->{TEMPLATE_DRIVER_OPTIONS}->{variable_content_types} = {
-      longdescription => 'html',
-      partnotes       => 'html',
-      notes           => 'html',
-    };
+    $form->{TEMPLATE_DRIVER_OPTIONS}->{variable_content_types} = $form->get_variable_content_types();
   }
 
   $form->isblank("email", $locale->text('E-mail address missing!'))
 
 # Set language for login and admin forms. Currently "de" (German)
 # and "en" (English, not perfect) are available.
 language = de
+# MassPrint Timeout
+# must be less than cgi timeout
+#
+massprint_timeout = 30
 
 # Set default_manager for admin forms. Currently "german"
 # and "swiss" are available.
 
--- /dev/null
+namespace('kivi.MassDeliveryOrderPrint', function(ns) {
+    
+  ns.massConversionFinishProcess = function() {
+    $('#mass_print_dialog').dialog('close');
+  };
+
+  ns.massConversionStarted = function() {
+   $('#mdo_start_process_button,.ui-dialog-titlebar button.ui-dialog-titlebar-close').prop('disabled', 'disabled');
+   $('#mdo_start_process_abort_link').remove();
+   $('#mass_print_dialog').data('timerId', setInterval(function() {
+      $.get("controller.pl", {
+        action: 'MassDeliveryOrderPrint/mass_mdo_status',
+        job_id: $('#mdo_job_id').val()
+      }, kivi.eval_json_result);
+    }, 5000));
+  };
+
+  ns.massConversionPopup = function() {
+    kivi.popup_dialog({
+      id: 'mass_print_dialog',
+      dialog: {
+        title: kivi.t8('Generate and print sales delivery orders')
+      }
+    });
+  };
+
+  ns.massConversionFinished = function() {
+    clearInterval($('#mass_print_dialog').data('timerId'));
+    $('.ui-dialog-titlebar button.ui-dialog-titlebar-close').prop('disabled', '')
+  };
+
+  ns.submitMultiOrders = function () {
+      $("#old_table_id").remove();
+      var checkboxes = $('input[type=checkbox]').filter(function () { return  $(this).prop('checked'); });
+      if (checkboxes.size() == 0) {
+          alert(kivi.t8("No delievery orders selected, please set one checkbox!"));
+          return false;
+      }
+      
+      var tmpform = $("#report_table_id").clone();
+      tmpform.hide();
+      tmpform.attr('id',"old_table_id");
+      tmpform.appendTo("#print_multi_id");
+      return kivi.submit_ajax_form('controller.pl?action=MassDeliveryOrderPrint/mass_mdo_print',$('#print_multi_id'));
+  };
+
+  ns.setup = function() {
+    $('#multi_all').checkall("input[name^='multi_id']");
+    $('#print_multi_button').click(kivi.MassDeliveryOrderPrint.submitMultiOrders);
+  };
+});
+
+$(kivi.MassDeliveryOrderPrint.setup);
 
     var data = {
       action:             'MassInvoiceCreatePrint/create_print_all_start',
       number_of_invoices: $('#cpa_number_of_invoices').val(),
+      bothsided:          $('#cpa_bothsided').val(),
       printer_id:         $('#cpa_printer_id').val(),
       copy_printer_id:    $('#cpa_copy_printer_id').val(),
       transdate:          $('#transdate').val()
 
 "Enter longdescription":"Langtext eingeben",
 "Error: Name missing":"Fehler: Name fehlt",
 "Function block actions":"Funktionsblockaktionen",
+"Generate and print sales delivery orders":"Erzeuge und drucke Lieferscheine",
 "Hide all details":"Alle Details verbergen",
 "Hide details":"Details verbergen",
 "History":"Historie",
 "If you switch to a different tab without saving you will lose the data you've entered in the current tab.":"Wenn Sie auf einen anderen Tab wechseln, ohne vorher zu speichern, so gehen die im aktuellen Tab eingegebenen Daten verloren.",
 "Map":"Karte",
 "No":"Nein",
+"No delievery orders selected, please set one checkbox!":"Kein Lieferschein selektiert, bitte eine Box anklicken!",
 "No delivery orders have been selected.":"Es wurden keine Lieferscheine ausgewählt.",
 "No entries have been selected.":"Es wurden keine Einträge ausgewählt.",
 "No invoices have been selected.":"Es wurden keine Rechnungen ausgewählt.",
 
   'Created by'                  => 'Erstellt von',
   'Created for'                 => 'Erstellt für',
   'Created on'                  => 'Erstellt am',
+  'Creating Documents'          => 'Erzeuge Dokumente',
   'Creating invoices'           => 'Erzeuge Rechnungen',
   'Creating the PDF failed:'    => 'PDF-Erzeugung fehlgeschlagen:',
   'Creation Date'               => 'Erstelldatum',
   'Document Project (description)' => 'Projektnummer des Belegs (Beschreibung)',
   'Document Project (number)'   => 'Projektnummer des Belegs',
   'Document Project Number'     => 'Projektnummer des Belegs',
+  'Document generating failed. Please check Templates an LateX !' => 'Das Dokument konnte nicht erzeugt werden. Bitte Vorlagen und LateX prüfen!',
   'Documentation'               => 'Dokumentation',
   'Documentation (in German)'   => 'Dokumentation',
   'Documents in the WebDAV repository' => 'Dokumente im WebDAV-Repository',
   'Done.'                       => 'Fertig.',
   'Double partnumbers'          => 'Doppelte Artikelnummern',
   'Download PDF'                => 'PDF herunterladen',
-  'Download PDF, do not print'  => 'PDF herunterladen, nicht drucken',
+  'Download PDF, do not print'  => 'Nicht drucken, sondern PDF herunterladen',
   'Download SEPA XML export file' => 'SEPA-XML-Exportdatei herunterladen',
   'Download picture'            => 'Bild herunterladen',
   'Download sample file'        => 'Beispieldatei herunterladen',
   'General ledger corrections'  => 'Korrekturen im Hauptbuch',
   'General ledger transaction \'#1\' posted' => 'Dialogbuchung \'#1\' verbucht.',
   'General settings'            => 'Allgemeine Einstellungen',
+  'Generate and print sales delivery orders' => 'Erzeuge und drucke Lieferscheine',
   'Generic Tax Report'          => 'USTVA Bericht',
   'Germany'                     => 'Deutschland',
   'Git revision: #1, #2 #3'     => 'Git-Revision: #1, #2 #3',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
   'No data was found.'          => 'Es wurden keine Daten gefunden.',
   'No default currency'         => 'Keine Standardwährung',
+  'No delievery orders selected, please set one checkbox!' => 'Kein Lieferschein selektiert, bitte eine Box anklicken!',
   'No delivery orders have been selected.' => 'Es wurden keine Lieferscheine ausgewählt.',
   'No delivery term has been created yet.' => 'Es wurden noch keine Lieferbedingungen angelegt',
   'No department has been created yet.' => 'Es wurde noch keine Abteilung erfasst.',
   'No entries have been selected.' => 'Es wurden keine Einträge ausgewählt.',
   'No errors have occurred.'    => 'Es sind keine Fehler aufgetreten.',
   'No file has been uploaded yet.' => 'Es wurde noch keine Datei hochgeladen.',
+  'No file selected, please set one checkbox!' => 'Kein Element selektiert,bitte eine Box anklicken',
+  'No file uploaded yet'        => 'Keine Datei hochgeladen',
+  'No filename exists!'         => 'Kein Dateiname angegeben',
   'No function blocks have been created yet.' => 'Es wurden noch keine Funktionsblöcke angelegt.',
   'No groups have been created yet.' => 'Es wurden noch keine Gruppen angelegt.',
   'No internal phone extensions have been configured yet.' => 'Es wurden noch keine internen Durchwahlen konfiguriert.',
   'No sections have been created yet.' => 'Es wurden noch keine Abschnitte angelegt.',
   'No shipto selected to delete' => 'Keine Lieferadresse zum Löschen ausgewählt',
   'No start date given, setting to #1' => 'Kein Startdatum gegeben, setze Startdatum auf #1',
+  'No such job #1 in the database.' => 'Hintergrund-Job #1 existiert nicht mehr.',
   'No summary account'          => 'Kein Sammelkonto',
   'No text blocks have been created for this position.' => 'Für diese Position wurden noch keine Textblöcke angelegt.',
   'No text has been entered yet.' => 'Es wurde noch kein Text eingegeben.',
   'Number of bins'              => 'Anzahl Lagerplätze',
   'Number of columns of custom variables in form details (second row)' => 'Anzahl der Spalten für benutzerdef. Variablen in den Formulardetails (zweite Positionszeile)',
   'Number of copies'            => 'Anzahl Kopien',
+  'Number of deliveryorders created:' => 'Anzahl erzeugter Lieferscheine:',
+  'Number of deliveryorders printed:' => 'Anzahl gedruckter Lieferscheine:',
   'Number of entries changed: #1' => 'Anzahl geänderter Einträge: #1',
   'Number of invoices'          => 'Anzahl Rechnungen',
   'Number of invoices created:' => 'Anzahl erstellter Rechnungen:',
   'Print'                       => 'Drucken',
   'Print and Post'              => 'Drucken und Buchen',
   'Print automatically'         => 'Automatisch ausdrucken',
-  'Print destination'           => 'Druckausgabe',
+  'Print both sided'            => 'Beidseitig ausdrucken',
+  'Print delivery orders'       => 'Drucke Lieferscheine',
+  'Print destination'           => 'Druckort',
   'Print destination (copy)'    => 'Druckausgabe (Kopie)',
   'Print dunnings'              => 'Mahnungen drucken',
   'Print list'                  => 'Liste ausdrucken',
   'Print options'               => 'Druckoptionen',
+  'Print selected'              => 'Drucken',
+  'Print selected delivery orders both sided' => 'Ausgewählte Lieferscheine (ggf beidseitig)',
   'Print template base file name' => 'Druckvorlagen-Basisdateiname',
   'Print templates'             => 'Druckvorlagen',
   'Print templates to use'      => 'Zu verwendende Druckvorlagen',
   'Printer Management'          => 'Druckeradministration',
   'Printer management'          => 'Druckerverwaltung',
   'Printing ... '               => 'Es wird gedruckt.',
+  'Printing Documents'          => 'Drucke Dokumente',
   'Printing invoices (this can take a while)' => 'Drucke Rechnungen (kann eine Weile dauern)',
   'Prior year'                  => 'Vorheriges Jahr',
   'Priority'                    => 'Priorität',
   'Ship via'                    => 'Transportmittel',
   'Shipping Address'            => 'Lieferadresse',
   'Shipping Point'              => 'Versandort',
+  'Shipping address (name)'     => '',
   'Shipping date'               => 'Lieferdatum',
   'Shipto'                      => 'Lieferanschriften',
   'Shipto deleted.'             => 'Lieferadresse gelöscht',
   'There are Bins defined in your Inventory.' => 'Unter Stammdaten/Waren sind Lagerplätze definiert.',
   'There are Bins defined in your master data.' => 'Unter Stammdaten/Waren sind Lagerplätze defininert',
   'There are bookings to the account 3803 after 01.01.2007. If you didn\'t change this account manually to 19% the bookings are probably incorrect.' => 'Das Konto 3803 wurde nach dem 01.01.2007 bebucht. Falls Sie dieses Konto nicht manuell auf 19% gestellt haben sind die Buchungen wahrscheinlich mit falscher Umsatzsteuer gebucht worden.',
+  'There are currently no delivery orders, or none matches your filter conditions.' => 'kein Lieferschein vorhanden',
   'There are currently no open invoices, or none matches your filter conditions.' => 'Es gibt momentan keine offenen Rechnungen, oder keine erfüllt die Filterkriterien.',
   'There are currently no open sales delivery orders.' => 'Es gibt zur Zeit keine offenen Verkaufslieferscheine.',
   'There are double partnumbers in your database.' => 'In ihrer Datenbank befinden sich mehrfach vergebene Artikelnummern.',
   'Warning'                     => 'Warnung',
   'Warning! Loading a draft will discard unsaved data!' => 'Achtung! Beim Laden eines Entwurfs werden ungespeicherte Daten verworfen!',
   'Warnings and errors'         => 'Warnungen und Fehler',
+  'Watch status'                => 'Hintergrund-Job Status',
   'WebDAV'                      => 'WebDAV',
   'WebDAV link'                 => 'WebDAV-Link',
   'WebDAV save documents'       => 'Belege in WebDAV-Ablage speichern',
   'running'                     => 'läuft',
   'sales tax identification number' => 'USt-IdNr.',
   'sales_delivery_order_list'   => 'lieferscheinliste_verkauf',
+  'sales_delivery_order_printer' => '',
   'sales_invoice_printer'       => 'Rechnungsdrucker',
   'sales_order'                 => 'Kundenauftrag',
   'sales_order_list'            => 'auftragsliste',
 
 EOL
   }
 }
+sub check_pdfinfo {
+  my $line = "Looking for pdfinfo executable";
+  my $shell_out = `pdfinfo -v 2>&1 | grep version 2> /dev/null`;
+  my ($label,$vers,$ver_string)  = split / /,$shell_out;
+  if ( $label && $label eq 'pdfinfo' ) {
+    print_line($line, $ver_string, 'green');
+  } else {
+    print_line($line, 'not installed','red');
+    my %modinfo = ( name => 'pdfinfo' );
+    push @missing_modules, \%modinfo;
+
+  }
+}
 
 sub check_pdfinfo {
   my $line = "Looking for pdfinfo executable";
 
 [%- USE T8 %]
 [% USE HTML %]
- [% 'New invoice' | $T8 %]<br>
+<table  width="100%">
+   <tr><td width = "200px" >
+ [% 'New invoice' | $T8 %]</td><td width = "150px">
  <input class="submit" type="submit" name="action" value="[% 'Continue' | $T8 %]">
  <input type="hidden" name="nextsub" value="invoice_multi">
  <input type="hidden" name="type" value="[% HTML.escape(type) %]">
  <input type="hidden" name="vc" value="[% HTML.escape(vc) %]">
  <input type="hidden" name="callback" value="[% HTML.escape(callback) %]">
  <input type="hidden" name="rowcount" value="[% HTML.escape(rowcount) %]">
-</form>
+</td><td></td></tr></table></form>
+<form method="post" id="print_multi_id">
+[% print_options %]
+<div id="mass_print_dialog" style="display: none"></div>
+<table  width="100%">
+  <tr><td width="300px" align="right">[% 'Print selected delivery orders both sided' | $T8 %]</td>
+      <td><input type="checkbox" name="bothsided" value="1">
+<input type="hidden" name="type" value="[% HTML.escape(type) %]">
+<input type="hidden" name="rowcount" value="[% HTML.escape(rowcount) %]">
+<input class="submit" type="button" name="action" id="print_multi_button" value="[% 'Print selected' | $T8 %]">
+</td><td></td></tr></table></form>
 
-<form method="post" action="do.pl">
+[%- INCLUDE 'common/flash.html' %]
+<form method="post" id="do_id" action="do.pl">
 
--- /dev/null
+[%- USE L %][%- USE LxERP %][%- USE HTML %]
+<div>
+ <form action="controller.pl" method="post">
+  <div class="filter_toggle" [% IF nowshow==0 %]style="display:none"[% END %]>
+   <a href="#" onClick="javascript:$('.filter_toggle').toggle()">[% LxERP.t8('Show Filter') %]</a>
+   [% IF SELF.filter_summary %]([% LxERP.t8("Current filter") %]: [% SELF.filter_summary %])[% END %]
+  </div>
+
+  <div class="filter_toggle" [% IF nowshow==1 %]style="display:none"[% END %]>
+   <a href="#" onClick="javascript:$('.filter_toggle').toggle()">[% LxERP.t8('Hide Filter') %]</a>
+   <table id="filter_table">
+    <tr>
+     <th align="right">[% LxERP.t8('Customer') %]</th>
+     <td>[% L.input_tag('filter.customer.name:substr::ilike', filter.customer.name_substr__ilike, size = 20) %]</td>
+    </tr>
+    <tr>
+     <th align="right">[% LxERP.t8('Shipping address (name)') %]</th>
+     <td>[% L.input_tag('filter.shipto.shiptoname:substr::ilike', filter.shipto.shiptoname_substr__ilike, size = 20) %]</td>
+    </tr>
+    <tr>
+     <th align="right">[% LxERP.t8('Delivery Date') %] [% LxERP.t8('From Date') %]</th>
+     <td>[% L.date_tag('filter.reqdate:date::ge', filter.reqdate_date__ge) %]</td>
+    </tr>
+    <tr>
+     <th align="right">[% LxERP.t8('Delivery Date') %] [% LxERP.t8('To Date') %]</th>
+     <td>[% L.date_tag('filter.reqdate:date::le', filter.reqdate_date__le) %]</td>
+    </tr>
+   </table>
+
+   [% L.hidden_tag('action', 'ODMassPrint/dispatch') %]
+   [% L.hidden_tag('sort_by', FORM.sort_by) %]
+   [% L.hidden_tag('sort_dir', FORM.sort_dir) %]
+   [% L.hidden_tag('page', FORM.page) %]
+   [% L.submit_tag(LIST_ACTION, LxERP.t8('Continue'))%]
+
+   <a href="#" onClick="javascript:$('#filter_table input,#filter_table select').val('');">[% LxERP.t8('Reset') %]</a>
+
+  </div>
+
+ </form>
+</div>
 
--- /dev/null
+[%- USE LxERP -%][%- USE L -%][%- USE HTML -%]
+[% SET data = job.data_as_hash %]
+<h2>[% LxERP.t8("Watch status") %]</h2>
+
+[% L.hidden_tag('', job.id, id="mdo_job_id") %]
+
+<p>
+ [% LxERP.t8("This status output will be refreshed every five seconds.") %]
+</p>
+
+<p>
+ [% IF data.status < 2 %]
+  [% L.link("login.pl?action=company_logo", LxERP.t8("Open new tab"), target="_blank") %]
+
+ [% ELSE %]
+ [% IF data.pdf_file_name %]
+   [% L.link(SELF.url_for(action="mass_mdo_download", job_id=job.id), LxERP.t8("Download PDF")) %]
+ [% END %]
+ [% L.link("#", LxERP.t8("Close window"), onclick="kivi.MassDeliveryOrderPrint.massConversionFinishProcess();") %]
+[% END %]
+</p>
+
+<p>
+ <table>
+  <tr>
+   <th valign="top" align="left">[% LxERP.t8("Current status:") %]</th>
+   <td valign="top">
+    [% IF !data.status %]
+     [% LxERP.t8("waiting for job to be started") %]
+    [% ELSIF data.status == 1 %]
+     [% LxERP.t8("Creating Documents") %]
+    [% ELSIF data.status == 2 %]
+     [% LxERP.t8("Printing Documents") %]
+    [% ELSE %]
+     [% LxERP.t8("Done.") %]
+     [% IF data.pdf_file_name %]
+      [% LxERP.t8("The file is available for download.") %]
+     [% ELSIF data.printer_id %]
+      [% LxERP.t8("The file has been sent to the printer.") %]
+     [% END %]
+    [% END %]
+   </td>
+  </tr>
+
+  <tr>
+   <th valign="top" align="left">[% LxERP.t8("Number of deliveryorders created:") %]</th>
+   <td valign="top">[% IF data.status > 0 %][% HTML.escape(data.num_created) %] / [% HTML.escape(data.record_ids.size) %][% ELSE %]–[% END %]</td>
+  </tr>
+
+  <tr>
+   <th valign="top" align="left">[% LxERP.t8("Number of deliveryorders printed:") %]</th>
+   <td valign="top">[% IF data.status > 1 %][% HTML.escape(data.num_printed) %] / [% HTML.escape(data.record_ids.size) %][% ELSE %]–[% END %]</td>
+  </tr>
+
+  <tr>
+   <th valign="top" align="left">[% LxERP.t8("Errors during conversion:") %]</th>
+   <td valign="top">
+[% IF !data.status %]
+  –
+[% ELSIF !data.conversion_errors.size %]
+ [% LxERP.t8("No errors have occurred.") %]
+[% ELSE %]
+    <table>
+     <tr class="listheader">
+      <th>[% LxERP.t8("Delivery Order") %]</th>
+      <th>[% LxERP.t8("Error") %]</th>
+     </tr>
+
+ [% FOREACH error = data.conversion_errors %]
+     <tr>
+      <td valign="top">[% IF error.id %][% L.link(SELF.url_for(controller='do.pl', action='edit', type='sales_delivery_order', id=error.id), HTML.escape(error.number), target="_blank") %][% ELSE %]–[% END %]</td>
+      <td valign="top">[% HTML.escape(error.message) %]</td>
+     </tr>
+ [% END %]
+    </table>
+[% END %]
+   </td>
+  </tr>
+
+  <tr>
+   <th valign="top" align="left">[% LxERP.t8("Errors during printing:") %]</th>
+   <td valign="top">
+[% IF data.status < 2 %]
+ –
+[% ELSIF !data.print_errors.size %]
+ [% LxERP.t8("No errors have occurred.") %]
+[% ELSE %]
+    <table>
+     <tr class="listheader">
+      <th>[% LxERP.t8("Invoice") %]</th>
+      <th>[% LxERP.t8("Error") %]</th>
+     </tr>
+
+ [% FOREACH error = data.print_errors %]
+     <tr>
+      <td valign="top">[% IF error.id %][% L.link(SELF.url_for(controller='is.pl', action='edit', type='sales_invoice',id=error.id), HTML.escape(error.number), target="_blank") %][% ELSE %]–[% END %]</td>
+      <td valign="top">[% HTML.escape(error.message) %]</td>
+     </tr>
+ [% END %]
+    </table>
+[% END %]
+   </td>
+  </tr>
+
+ </table>
+</p>
 
--- /dev/null
+[% USE HTML %][% USE L %][% USE LxERP %]
+
+<h1>[% FORM.title %]</h1>
+
+[%- INCLUDE "common/flash.html" %]
+
+[% LIST_ACTION     = 'action_list_delivery_orders' %]
+[%- PROCESS 'mass_delivery_order_print/_filter.html' filter=SELF.filter %]
+
+[% IF nowshow==1 %]
+[% delivery_orders = SELF.delivery_order_models.get;
+   MODELS          = SELF.delivery_order_models %]
+[%- IF !delivery_orders.size %]
+ <p>
+  [%- LxERP.t8("There are currently no delivery orders, or none matches your filter conditions.") %]
+ </p>
+[%- ELSE %]
+
+ <form method="post" action="controller.pl">
+  <table width="100%">
+   <thead>
+    <tr class="listheading">
+     <th>[% L.checkbox_tag("", id="check_all", checkall="[data-checkall=1]") %]</th>
+     <th>[% L.sortable_table_header("transdate") %]</th>
+     <th>[% L.sortable_table_header("reqdate") %]</th>
+     <th>[% L.sortable_table_header("donumber") %]</th>
+     <th>[% L.sortable_table_header("ordnumber") %]</th>
+     <th>[% L.sortable_table_header("customer") %]</th>
+     <th>[% LxERP.t8("Shipto") %]</th>
+    </tr>
+   </thead>
+
+   <tbody>
+    [%- FOREACH delivery_order = delivery_orders %]
+     [% delivery_order_id = delivery_order.id
+        sales_order       = delivery_order.sales_order %]
+     <tr class="listrow">
+      <td>[% L.checkbox_tag('id[]', value=delivery_order.id, "data-checkall"=1, checked=selected_ids.$delivery_order_id) %]</td>
+      <td>[% HTML.escape(delivery_order.transdate_as_date) %]</td>
+      <td>[% HTML.escape(delivery_order.reqdate_as_date) %]</td>
+      <td>[% L.link(SELF.url_for(controller="do.pl", action="edit", type="sales_delivery_order", id=delivery_order.id), delivery_order.donumber) %]</td>
+      <td>[% HTML.escape(delivery_order.ordnumber) %]</td>
+      <td>[% HTML.escape(delivery_order.customer.name) %]</td>
+      <td>[% HTML.escape(SELF.make_shipto_title(delivery_order.shipto || delivery_order.custom_shipto)) %]</td>
+     </tr>
+    [%- END %]
+   </tbody>
+  </table>
+
+  [% IF !SELF.delivery_order_ids.size %]
+   [% L.paginate_controls %]
+  [% END %]
+
+  <hr size="3" noshade>
+
+  <p>[% print_opt %]</p>
+  [% IF SELF.printers.size %]
+   <p>
+    [% LxERP.t8("Print destination") %]:
+    [% SET  printers = [ { description=LxERP.t8("Download PDF, do not print") } ] ;
+       CALL printers.import(SELF.printers);
+       L.select_tag("printer_id", printers, title_key="description", default=FORM.printer_id) %]
+   </p>
+  [% END %]
+
+  <p>
+   [% L.hidden_tag("action", "MassDeliveryOrderPrint/dispatch") %]
+   [% L.submit_tag("action_print", LxERP.t8("Print")) %]
+  </p>
+ </form>
+[%- END %]
+[%- END %]
 
   <td>[% LxERP.t8("Number of invoices to create") %]:</td>
   <td>[% L.input_tag('', num_delivery_orders, size="5", id="cpa_number_of_invoices") %]</td>
  </tr>
-
+ <tr>
+  <td>[% LxERP.t8("Print both sided") %]:</td>
+  <td>[% L.checkbox_tag('', id="cpa_bothsided") %]</td>
+ </tr>
  <tr>
   <td>[% LxERP.t8("Print destination") %]:</td>
   <td>
 
 
  [% IF DATA_PRESENT %]
  <p>
-  <table [% IF TABLE_CLASS %]class="[% TABLE_CLASS %]"[% END %] width="100%">
+  <table [% IF TABLE_CLASS %]class="[% TABLE_CLASS %]"[% END %] id="report_table_id" width="100%">
    [%- FOREACH row = HEADER_ROWS %]
    <tr>
     [% FOREACH col = row %]