]> wagnertech.de Git - mfinanz.git/commitdiff
Dateimanagement: Massendruck
authorMartin Helmling <martin.helmling@octosoft.eu>
Tue, 19 Apr 2016 10:39:43 +0000 (12:39 +0200)
committerMartin Helmling martin.helmling@octosoft.eu <martin.helmling@octosoft.eu>
Wed, 1 Feb 2017 07:52:09 +0000 (08:52 +0100)
Der Massendruck per BackgroundJob nutzt nun das FileManagement

Die erzeugten Dateien werden ggf. mit PDF Anhängen erweitert
und entsprechend abgespeichert.

Per Flag kann dem massendruck mitgeteilt werden,
dass eine leere Seite ggf hinzugefügt wird
(Template in templates/print/Standard/emptyPage.pdf o.ä.),
damit nächster Lieferschein auf neuem Blatt beginnt.

pdfinfo wird beim installationscheck gesucht,
leere Seite in Druckvorlagen

Vereinheitlichen der HTML -> PDF Konvertierung

Der HASH "variable_content_types" wird an unterschiedlichsten Stellen mit
unterschiedlichen oder unvollständiger Information befüllt.

Nun wird es an zentraler Stelle gemacht

24 files changed:
SL/BackgroundJob/CreatePeriodicInvoices.pm
SL/BackgroundJob/MassDeliveryOrderPrinting.pm [new file with mode: 0644]
SL/BackgroundJob/MassRecordCreationAndPrinting.pm
SL/Controller/MassDeliveryOrderPrint.pm [new file with mode: 0644]
SL/Controller/MassInvoiceCreatePrint.pm
SL/DB/Helper/FlattenToForm.pm
SL/Form.pm
SL/Helper/File.pm
SL/Helper/MassPrintCreatePDF.pm [new file with mode: 0644]
bin/mozilla/do.pl
bin/mozilla/io.pl
config/kivitendo.conf.default
js/kivi.MassDeliveryOrderPrint.js [new file with mode: 0644]
js/kivi.MassInvoiceCreatePrint.js
js/locale/de.js
locale/de/all
scripts/installation_check.pl
templates/webpages/do/orders_bottom.html
templates/webpages/do/orders_top.html
templates/webpages/mass_delivery_order_print/_filter.html [new file with mode: 0644]
templates/webpages/mass_delivery_order_print/_print_status.html [new file with mode: 0644]
templates/webpages/mass_delivery_order_print/list_delivery_orders.html [new file with mode: 0644]
templates/webpages/mass_invoice_create_print_from_do/_create_print_all_step_1.html
templates/webpages/report_generator/html_report.html

index 1b57cbeaf0499f5ea3001bc7c1cf6046de7fb647..c8b16ab4bdb25111a1f493a447997b3709315532 100644 (file)
@@ -337,13 +337,8 @@ sub _print_invoice {
   $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;
 
diff --git a/SL/BackgroundJob/MassDeliveryOrderPrinting.pm b/SL/BackgroundJob/MassDeliveryOrderPrinting.pm
new file mode 100644 (file)
index 0000000..c46a8d7
--- /dev/null
@@ -0,0 +1,105 @@
+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;
+
index 16823dcbd02c94bafabb0eedb9527d3cd6867e30..e134807e3316b69bb27d9d54d2acfbd3822b6c53 100644 (file)
@@ -12,12 +12,16 @@ use SL::DB::Printer;
 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, ],
@@ -46,12 +50,17 @@ sub create_invoices {
     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;
@@ -75,42 +84,36 @@ sub convert_invoices_to_pdf {
   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(
@@ -129,8 +132,6 @@ sub convert_invoices_to_pdf {
         }
       }
 
-      $data->{num_printed}++;
-
       1;
 
     } or do {
@@ -140,52 +141,7 @@ sub convert_invoices_to_pdf {
     $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 {
diff --git a/SL/Controller/MassDeliveryOrderPrint.pm b/SL/Controller/MassDeliveryOrderPrint.pm
new file mode 100644 (file)
index 0000000..ca3026b
--- /dev/null
@@ -0,0 +1,283 @@
+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;
index b7212c780b88f55deb02fb85b654441e35ac6893..ef5bfaf7404431bc75e25eea4a01074379ff93f8 100644 (file)
@@ -13,12 +13,12 @@ use SL::Controller::Helper::GetModels;
 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) ],
@@ -130,6 +130,7 @@ sub action_create_print_all_start {
     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,
@@ -172,7 +173,7 @@ sub action_create_print_all_download {
   $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(
@@ -187,6 +188,7 @@ sub action_create_print_all_download {
 #
 
 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 }
 
@@ -268,30 +270,6 @@ sub setup {
 # 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) = @_;
@@ -300,13 +278,13 @@ sub download_or_print_documents {
 
   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);
@@ -314,7 +292,7 @@ sub download_or_print_documents {
     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(
index dff9e1df9740f7658dfffc2c00096a6b0b54f8ac..5166ff9b20341278002077f9bb281a5d4b45b140 100644 (file)
@@ -82,7 +82,9 @@ sub flatten_to_form {
 
     $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));
index f50a121d64116a99b7619bdb9fca8e9c767ca189..84349d25dcd3a0a918c0e7ba53e40df9cf97adb7 100644 (file)
@@ -2846,6 +2846,22 @@ sub lastname_used {
   $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();
 
index 7b31ebdd6f64aadfe38ded01736acb7e65edb195..fcf48d67d5c0cd7ecbe9575db92f71f54c201352 100644 (file)
@@ -80,7 +80,10 @@ SL::Helper::File - Helper for $::Form to store generated PDF-Documents
 
  $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
 
diff --git a/SL/Helper/MassPrintCreatePDF.pm b/SL/Helper/MassPrintCreatePDF.pm
new file mode 100644 (file)
index 0000000..454088e
--- /dev/null
@@ -0,0 +1,169 @@
+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
+
index 0e8918bdc5c60843c2cd2af03258fea959f7ae51..1e5c5a20339b5ae43a6e4a362a8728812a16d4ee 100644 (file)
@@ -302,7 +302,7 @@ sub form_header {
 
   $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' ]) };
@@ -507,6 +507,7 @@ sub orders {
   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);
@@ -544,7 +545,7 @@ sub orders {
   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'), },
@@ -642,9 +643,25 @@ sub orders {
     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),
@@ -669,9 +686,10 @@ sub orders {
 
     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',
     };
index abbdda173ae42ce81be6d07cbcdf7bba5c0565e6..f0718716201270d511898b5277687cd52a05d503 100644 (file)
@@ -1294,11 +1294,7 @@ sub print_form {
 
   $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!'))
index 7f5b626b0f72cb7b1d8af5c927e173ad0e754c33..f4b8fe437c91c10e496757d7f2b861009485289d 100644 (file)
@@ -64,6 +64,10 @@ bind_password =
 # 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.
diff --git a/js/kivi.MassDeliveryOrderPrint.js b/js/kivi.MassDeliveryOrderPrint.js
new file mode 100644 (file)
index 0000000..426b4c1
--- /dev/null
@@ -0,0 +1,53 @@
+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);
index 61355191b15a2e23b66e9693d3fdbe4dfafa09bc..bfb215e80239446ece238aa26e61623b5bd035d6 100644 (file)
@@ -45,6 +45,7 @@ namespace('kivi.MassInvoiceCreatePrint', function(ns) {
     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()
index 2f197b86d2ae164e0ab8ca00ed8efdc3756eeb21..71749f7d4b1e0fbecb0fb4b5681628bdd64b5da6 100644 (file)
@@ -50,12 +50,14 @@ namespace("kivi").setupLocale({
 "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.",
index 813284ad2e10ca1bda7e3d91fa69ba5186599dc3..9cf72dd7a6bd9e281395a8f3e22a4c3c3b5d76c3 100644 (file)
@@ -723,6 +723,7 @@ $self->{texts} = {
   'Created by'                  => 'Erstellt von',
   'Created for'                 => 'Erstellt f&uuml;r',
   'Created on'                  => 'Erstellt am',
+  'Creating Documents'          => 'Erzeuge Dokumente',
   'Creating invoices'           => 'Erzeuge Rechnungen',
   'Creating the PDF failed:'    => 'PDF-Erzeugung fehlgeschlagen:',
   'Creation Date'               => 'Erstelldatum',
@@ -995,6 +996,7 @@ $self->{texts} = {
   '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',
@@ -1002,7 +1004,7 @@ $self->{texts} = {
   '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',
@@ -1383,6 +1385,7 @@ $self->{texts} = {
   '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',
@@ -1830,6 +1833,7 @@ $self->{texts} = {
   '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.',
@@ -1840,6 +1844,9 @@ $self->{texts} = {
   '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.',
@@ -1871,6 +1878,7 @@ $self->{texts} = {
   '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.',
@@ -1919,6 +1927,8 @@ $self->{texts} = {
   'Number of bins'              => 'Anzahl Lagerpl&auml;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:',
@@ -2184,11 +2194,15 @@ $self->{texts} = {
   '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',
@@ -2199,6 +2213,7 @@ $self->{texts} = {
   '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',
@@ -2576,6 +2591,7 @@ $self->{texts} = {
   'Ship via'                    => 'Transportmittel',
   'Shipping Address'            => 'Lieferadresse',
   'Shipping Point'              => 'Versandort',
+  'Shipping address (name)'     => '',
   'Shipping date'               => 'Lieferdatum',
   'Shipto'                      => 'Lieferanschriften',
   'Shipto deleted.'             => 'Lieferadresse gelöscht',
@@ -3156,6 +3172,7 @@ $self->{texts} = {
   '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.',
@@ -3491,6 +3508,7 @@ $self->{texts} = {
   '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',
@@ -3767,6 +3785,7 @@ $self->{texts} = {
   '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',
index 2535a2c37001b3d7b8fd2acebc90097ab5a80835..94751b96125ace80d0a1bf83c14fa2eca22764b4 100755 (executable)
@@ -202,6 +202,19 @@ sub kpsewhich {
 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";
index 4138ca40e638b1621716da1760be58516d30604f..be56ee2350ec337e6ed4bb2b8ae6c42afb3172cd 100644 (file)
@@ -1,10 +1,22 @@
 [%- 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>
index bd402c4e10e55fb0ead683d22b7d4a7ecc8fdf75..964e122600d86d0ca5a673e152efed3a60a49e18 100644 (file)
@@ -1 +1,2 @@
-<form method="post" action="do.pl">
+[%- INCLUDE 'common/flash.html' %]
+<form method="post" id="do_id" action="do.pl">
diff --git a/templates/webpages/mass_delivery_order_print/_filter.html b/templates/webpages/mass_delivery_order_print/_filter.html
new file mode 100644 (file)
index 0000000..7bb547e
--- /dev/null
@@ -0,0 +1,41 @@
+[%- 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>
diff --git a/templates/webpages/mass_delivery_order_print/_print_status.html b/templates/webpages/mass_delivery_order_print/_print_status.html
new file mode 100644 (file)
index 0000000..3d38a0d
--- /dev/null
@@ -0,0 +1,106 @@
+[%- 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>
diff --git a/templates/webpages/mass_delivery_order_print/list_delivery_orders.html b/templates/webpages/mass_delivery_order_print/list_delivery_orders.html
new file mode 100644 (file)
index 0000000..a7fa7a2
--- /dev/null
@@ -0,0 +1,72 @@
+[% 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 %]
index 794f51865bca9cb5475dc4d2760870f1db293514..e66b41feaadc0d5dc67b8e99a9f1a29e29d4d44b 100644 (file)
   <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>
index 19a5ca603640b14446e581977a9416408d2679a5..2dfc871a9579057c47cebc2db7105d76ddff787a 100644 (file)
@@ -29,7 +29,7 @@
 
  [% 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 %]