From 54ce51443886623bb785e7c54492ecbc8dc9b3aa Mon Sep 17 00:00:00 2001 From: Martin Helmling Date: Tue, 19 Apr 2016 12:39:43 +0200 Subject: [PATCH] Dateimanagement: Massendruck MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- SL/BackgroundJob/CreatePeriodicInvoices.pm | 9 +- SL/BackgroundJob/MassDeliveryOrderPrinting.pm | 105 +++++++ .../MassRecordCreationAndPrinting.pm | 96 ++---- SL/Controller/MassDeliveryOrderPrint.pm | 283 ++++++++++++++++++ SL/Controller/MassInvoiceCreatePrint.pm | 36 +-- SL/DB/Helper/FlattenToForm.pm | 4 +- SL/Form.pm | 16 + SL/Helper/File.pm | 5 +- SL/Helper/MassPrintCreatePDF.pm | 169 +++++++++++ bin/mozilla/do.pl | 28 +- bin/mozilla/io.pl | 6 +- config/kivitendo.conf.default | 4 + js/kivi.MassDeliveryOrderPrint.js | 53 ++++ js/kivi.MassInvoiceCreatePrint.js | 1 + js/locale/de.js | 2 + locale/de/all | 23 +- scripts/installation_check.pl | 13 + templates/webpages/do/orders_bottom.html | 16 +- templates/webpages/do/orders_top.html | 3 +- .../mass_delivery_order_print/_filter.html | 41 +++ .../_print_status.html | 106 +++++++ .../list_delivery_orders.html | 72 +++++ .../_create_print_all_step_1.html | 5 +- .../report_generator/html_report.html | 2 +- 24 files changed, 973 insertions(+), 125 deletions(-) create mode 100644 SL/BackgroundJob/MassDeliveryOrderPrinting.pm create mode 100644 SL/Controller/MassDeliveryOrderPrint.pm create mode 100644 SL/Helper/MassPrintCreatePDF.pm create mode 100644 js/kivi.MassDeliveryOrderPrint.js create mode 100644 templates/webpages/mass_delivery_order_print/_filter.html create mode 100644 templates/webpages/mass_delivery_order_print/_print_status.html create mode 100644 templates/webpages/mass_delivery_order_print/list_delivery_orders.html diff --git a/SL/BackgroundJob/CreatePeriodicInvoices.pm b/SL/BackgroundJob/CreatePeriodicInvoices.pm index 1b57cbeaf..c8b16ab4b 100644 --- a/SL/BackgroundJob/CreatePeriodicInvoices.pm +++ b/SL/BackgroundJob/CreatePeriodicInvoices.pm @@ -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 index 000000000..c46a8d7c3 --- /dev/null +++ b/SL/BackgroundJob/MassDeliveryOrderPrinting.pm @@ -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; + diff --git a/SL/BackgroundJob/MassRecordCreationAndPrinting.pm b/SL/BackgroundJob/MassRecordCreationAndPrinting.pm index 16823dcbd..e134807e3 100644 --- a/SL/BackgroundJob/MassRecordCreationAndPrinting.pm +++ b/SL/BackgroundJob/MassRecordCreationAndPrinting.pm @@ -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 index 000000000..ca3026b26 --- /dev/null +++ b/SL/Controller/MassDeliveryOrderPrint.pm @@ -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/
/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; diff --git a/SL/Controller/MassInvoiceCreatePrint.pm b/SL/Controller/MassInvoiceCreatePrint.pm index b7212c780..ef5bfaf74 100644 --- a/SL/Controller/MassInvoiceCreatePrint.pm +++ b/SL/Controller/MassInvoiceCreatePrint.pm @@ -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( diff --git a/SL/DB/Helper/FlattenToForm.pm b/SL/DB/Helper/FlattenToForm.pm index dff9e1df9..5166ff9b2 100644 --- a/SL/DB/Helper/FlattenToForm.pm +++ b/SL/DB/Helper/FlattenToForm.pm @@ -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)); diff --git a/SL/Form.pm b/SL/Form.pm index f50a121d6..84349d25d 100644 --- a/SL/Form.pm +++ b/SL/Form.pm @@ -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(); diff --git a/SL/Helper/File.pm b/SL/Helper/File.pm index 7b31ebdd6..fcf48d67d 100644 --- a/SL/Helper/File.pm +++ b/SL/Helper/File.pm @@ -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 index 000000000..454088e6d --- /dev/null +++ b/SL/Helper/MassPrintCreatePDF.pm @@ -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 + +=head1 METHODS + +=head2 C + +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 Emartin.helmling@opendynamic.deE + + +=cut + diff --git a/bin/mozilla/do.pl b/bin/mozilla/do.pl index 0e8918bdc..1e5c5a203 100644 --- a/bin/mozilla/do.pl +++ b/bin/mozilla/do.pl @@ -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' => '', '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', }; diff --git a/bin/mozilla/io.pl b/bin/mozilla/io.pl index abbdda173..f07187162 100644 --- a/bin/mozilla/io.pl +++ b/bin/mozilla/io.pl @@ -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!')) diff --git a/config/kivitendo.conf.default b/config/kivitendo.conf.default index 7f5b626b0..f4b8fe437 100644 --- a/config/kivitendo.conf.default +++ b/config/kivitendo.conf.default @@ -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 index 000000000..426b4c116 --- /dev/null +++ b/js/kivi.MassDeliveryOrderPrint.js @@ -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); diff --git a/js/kivi.MassInvoiceCreatePrint.js b/js/kivi.MassInvoiceCreatePrint.js index 61355191b..bfb215e80 100644 --- a/js/kivi.MassInvoiceCreatePrint.js +++ b/js/kivi.MassInvoiceCreatePrint.js @@ -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() diff --git a/js/locale/de.js b/js/locale/de.js index 2f197b86d..71749f7d4 100644 --- a/js/locale/de.js +++ b/js/locale/de.js @@ -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.", diff --git a/locale/de/all b/locale/de/all index 813284ad2..9cf72dd7a 100644 --- a/locale/de/all +++ b/locale/de/all @@ -723,6 +723,7 @@ $self->{texts} = { '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', @@ -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ä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', diff --git a/scripts/installation_check.pl b/scripts/installation_check.pl index 2535a2c37..94751b961 100755 --- a/scripts/installation_check.pl +++ b/scripts/installation_check.pl @@ -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"; diff --git a/templates/webpages/do/orders_bottom.html b/templates/webpages/do/orders_bottom.html index 4138ca40e..be56ee235 100644 --- a/templates/webpages/do/orders_bottom.html +++ b/templates/webpages/do/orders_bottom.html @@ -1,10 +1,22 @@ [%- USE T8 %] [% USE HTML %] - [% 'New invoice' | $T8 %]
+ +
+ [% 'New invoice' | $T8 %] - +
+ diff --git a/templates/webpages/do/orders_top.html b/templates/webpages/do/orders_top.html index bd402c4e1..964e12260 100644 --- a/templates/webpages/do/orders_top.html +++ b/templates/webpages/do/orders_top.html @@ -1 +1,2 @@ -
+[%- INCLUDE 'common/flash.html' %] + diff --git a/templates/webpages/mass_delivery_order_print/_filter.html b/templates/webpages/mass_delivery_order_print/_filter.html new file mode 100644 index 000000000..7bb547e22 --- /dev/null +++ b/templates/webpages/mass_delivery_order_print/_filter.html @@ -0,0 +1,41 @@ +[%- USE L %][%- USE LxERP %][%- USE HTML %] +
+ +
+ [% LxERP.t8('Show Filter') %] + [% IF SELF.filter_summary %]([% LxERP.t8("Current filter") %]: [% SELF.filter_summary %])[% END %] +
+ +
+ [% LxERP.t8('Hide Filter') %] + + + + + + + + + + + + + + + + + +
[% LxERP.t8('Customer') %][% L.input_tag('filter.customer.name:substr::ilike', filter.customer.name_substr__ilike, size = 20) %]
[% LxERP.t8('Shipping address (name)') %][% L.input_tag('filter.shipto.shiptoname:substr::ilike', filter.shipto.shiptoname_substr__ilike, size = 20) %]
[% LxERP.t8('Delivery Date') %] [% LxERP.t8('From Date') %][% L.date_tag('filter.reqdate:date::ge', filter.reqdate_date__ge) %]
[% LxERP.t8('Delivery Date') %] [% LxERP.t8('To Date') %][% L.date_tag('filter.reqdate:date::le', filter.reqdate_date__le) %]
+ + [% 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'))%] + + [% LxERP.t8('Reset') %] + +
+ + +
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 index 000000000..3d38a0d2a --- /dev/null +++ b/templates/webpages/mass_delivery_order_print/_print_status.html @@ -0,0 +1,106 @@ +[%- USE LxERP -%][%- USE L -%][%- USE HTML -%] +[% SET data = job.data_as_hash %] +

[% LxERP.t8("Watch status") %]

+ +[% L.hidden_tag('', job.id, id="mdo_job_id") %] + +

+ [% LxERP.t8("This status output will be refreshed every five seconds.") %] +

+ +

+ [% 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 %] +

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
[% LxERP.t8("Current status:") %] + [% 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 %] +
[% LxERP.t8("Number of deliveryorders created:") %][% IF data.status > 0 %][% HTML.escape(data.num_created) %] / [% HTML.escape(data.record_ids.size) %][% ELSE %]–[% END %]
[% LxERP.t8("Number of deliveryorders printed:") %][% IF data.status > 1 %][% HTML.escape(data.num_printed) %] / [% HTML.escape(data.record_ids.size) %][% ELSE %]–[% END %]
[% LxERP.t8("Errors during conversion:") %] +[% IF !data.status %] + – +[% ELSIF !data.conversion_errors.size %] + [% LxERP.t8("No errors have occurred.") %] +[% ELSE %] + + + + + + + [% FOREACH error = data.conversion_errors %] + + + + + [% END %] +
[% LxERP.t8("Delivery Order") %][% LxERP.t8("Error") %]
[% 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 %][% HTML.escape(error.message) %]
+[% END %] +
[% LxERP.t8("Errors during printing:") %] +[% IF data.status < 2 %] + – +[% ELSIF !data.print_errors.size %] + [% LxERP.t8("No errors have occurred.") %] +[% ELSE %] + + + + + + + [% FOREACH error = data.print_errors %] + + + + + [% END %] +
[% LxERP.t8("Invoice") %][% LxERP.t8("Error") %]
[% 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 %][% HTML.escape(error.message) %]
+[% END %] +
+

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 index 000000000..a7fa7a2f8 --- /dev/null +++ b/templates/webpages/mass_delivery_order_print/list_delivery_orders.html @@ -0,0 +1,72 @@ +[% USE HTML %][% USE L %][% USE LxERP %] + +

[% FORM.title %]

+ +[%- 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 %] +

+ [%- LxERP.t8("There are currently no delivery orders, or none matches your filter conditions.") %] +

+[%- ELSE %] + +
+ + + + + + + + + + + + + + + [%- FOREACH delivery_order = delivery_orders %] + [% delivery_order_id = delivery_order.id + sales_order = delivery_order.sales_order %] + + + + + + + + + + [%- END %] + +
[% L.checkbox_tag("", id="check_all", checkall="[data-checkall=1]") %][% L.sortable_table_header("transdate") %][% L.sortable_table_header("reqdate") %][% L.sortable_table_header("donumber") %][% L.sortable_table_header("ordnumber") %][% L.sortable_table_header("customer") %][% LxERP.t8("Shipto") %]
[% L.checkbox_tag('id[]', value=delivery_order.id, "data-checkall"=1, checked=selected_ids.$delivery_order_id) %][% HTML.escape(delivery_order.transdate_as_date) %][% HTML.escape(delivery_order.reqdate_as_date) %][% L.link(SELF.url_for(controller="do.pl", action="edit", type="sales_delivery_order", id=delivery_order.id), delivery_order.donumber) %][% HTML.escape(delivery_order.ordnumber) %][% HTML.escape(delivery_order.customer.name) %][% HTML.escape(SELF.make_shipto_title(delivery_order.shipto || delivery_order.custom_shipto)) %]
+ + [% IF !SELF.delivery_order_ids.size %] + [% L.paginate_controls %] + [% END %] + +
+ +

[% print_opt %]

+ [% IF SELF.printers.size %] +

+ [% 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) %] +

+ [% END %] + +

+ [% L.hidden_tag("action", "MassDeliveryOrderPrint/dispatch") %] + [% L.submit_tag("action_print", LxERP.t8("Print")) %] +

+
+[%- END %] +[%- END %] diff --git a/templates/webpages/mass_invoice_create_print_from_do/_create_print_all_step_1.html b/templates/webpages/mass_invoice_create_print_from_do/_create_print_all_step_1.html index 794f51865..e66b41fea 100644 --- a/templates/webpages/mass_invoice_create_print_from_do/_create_print_all_step_1.html +++ b/templates/webpages/mass_invoice_create_print_from_do/_create_print_all_step_1.html @@ -12,7 +12,10 @@ [% LxERP.t8("Number of invoices to create") %]: [% L.input_tag('', num_delivery_orders, size="5", id="cpa_number_of_invoices") %] - + + [% LxERP.t8("Print both sided") %]: + [% L.checkbox_tag('', id="cpa_bothsided") %] + [% LxERP.t8("Print destination") %]: diff --git a/templates/webpages/report_generator/html_report.html b/templates/webpages/report_generator/html_report.html index 19a5ca603..2dfc871a9 100644 --- a/templates/webpages/report_generator/html_report.html +++ b/templates/webpages/report_generator/html_report.html @@ -29,7 +29,7 @@ [% IF DATA_PRESENT %]

- +
[%- FOREACH row = HEADER_ROWS %] [% FOREACH col = row %] -- 2.20.1