Auftrags-Controller: Druck-Möglichkeit mit Options
authorBernd Bleßmann <bernd@kivitendo-premium.de>
Sat, 16 Jan 2016 22:04:27 +0000 (23:04 +0100)
committerBernd Bleßmann <bernd@kivitendo-premium.de>
Fri, 11 Mar 2016 11:53:26 +0000 (12:53 +0100)
Todos/Anmerkungen
- im Moment werden nur PDF/Bildschirm und PDF/Drucker unterstützt
- Sprache kann die Vorlage steuern, aber nicht das Hinzufügen von übersetzten
  Artikeln
- es kann sicher noch mehr ausgelagert werden, entweder in den
  PrintOptions-Helper oder in einen PrintOptions-Controller, der
  dann auch noch mehr machen könnte
- E-Mail ist nicht berücksichtigt bzw. wird im Controller getrennt behandelt

SL/Controller/Order.pm
js/locale/de.js
locale/de/all
templates/webpages/order/form.html

index 68b5ca9..c980db7 100644 (file)
@@ -10,6 +10,7 @@ use SL::SessionFile::Random;
 use SL::PriceSource;
 use SL::Form;
 use SL::Webdav;
+use SL::Template;
 
 use SL::DB::Order;
 use SL::DB::Customer;
@@ -21,9 +22,12 @@ use SL::DB::Default;
 use SL::DB::Unit;
 use SL::DB::Price;
 use SL::DB::Part;
+use SL::DB::Printer;
+use SL::DB::Language;
 
 use SL::Helper::DateTime;
 use SL::Helper::CreatePDF qw(:all);
+use SL::Helper::PrintOptions;
 
 use SL::Controller::Helper::GetModels;
 
@@ -43,10 +47,10 @@ use Rose::Object::MakeMethods::Generic
 __PACKAGE__->run_before('_check_auth');
 
 __PACKAGE__->run_before('_recalc',
-                        only => [ qw(update save save_and_delivery_order create_pdf send_email) ]);
+                        only => [ qw(update save save_and_delivery_order print create_pdf send_email) ]);
 
 __PACKAGE__->run_before('_get_unalterable_data',
-                        only => [ qw(save save_and_delivery_order create_pdf send_email) ]);
+                        only => [ qw(save save_and_delivery_order print create_pdf send_email) ]);
 
 #
 # actions
@@ -135,30 +139,78 @@ sub action_save {
   $self->redirect_to(@redirect_params);
 }
 
-sub action_create_pdf {
+sub action_print {
   my ($self) = @_;
 
-  my $pdf;
-  my @errors = _create_pdf($self->order, \$pdf);
-  if (scalar @errors) {
-    return $self->js->flash('error', t8('Conversion to PDF failed: #1', $errors[0]))->render($self);
+  my $format      = $::form->{print_options}->{format};
+  my $media       = $::form->{print_options}->{media};
+  my $formname    = $::form->{print_options}->{formname};
+  my $copies      = $::form->{print_options}->{copies};
+  my $groupitems  = $::form->{print_options}->{groupitems};
+
+  # only pdf by now
+  if (none { $format eq $_ } qw(pdf)) {
+    return $self->js->flash('error', t8('Format \'#1\' is not supported yet/anymore.', $format))->render;
   }
 
-  my $sfile = SL::SessionFile::Random->new(mode => "w");
-  $sfile->fh->print($pdf);
-  $sfile->fh->close;
+  # only screen or printer by now
+  if (none { $media eq $_ } qw(screen printer)) {
+    return $self->js->flash('error', t8('Media \'#1\' is not supported yet/anymore.', $media))->render;
+  }
 
-  my $key = join('_', Time::HiRes::gettimeofday(), int rand 1000000000000);
-  $::auth->set_session_value("Order::create_pdf-${key}" => $sfile->file_name);
+  my $language;
+  $language = SL::DB::Language->new(id => $::form->{print_options}->{language_id})->load if $::form->{print_options}->{language_id};
 
   my $form = Form->new;
   $form->{ordnumber} = $self->order->ordnumber;
-  $form->{formname}  = $self->type;
   $form->{type}      = $self->type;
-  $form->{language}  = 'de';
-  $form->{format}    = 'pdf';
+  $form->{format}    = $format;
+  $form->{formname}  = $formname;
+  $form->{language}  = '_' . $language->template_code if $language;
+  my $pdf_filename   = $form->generate_attachment_filename();
+
+  my $pdf;
+  my @errors = _create_pdf($self->order, \$pdf, { format     => $format,
+                                                  formname   => $formname,
+                                                  language   => $language,
+                                                  groupitems => $groupitems });
+  if (scalar @errors) {
+    return $self->js->flash('error', t8('Conversion to PDF failed: #1', $errors[0]))->render;
+  }
+
+  if ($media eq 'screen') {
+    # screen/download
+    my $sfile = SL::SessionFile::Random->new(mode => "w");
+    $sfile->fh->print($pdf);
+    $sfile->fh->close;
+
+    my $key = join('_', Time::HiRes::gettimeofday(), int rand 1000000000000);
+    $::auth->set_session_value("Order::create_pdf-${key}" => $sfile->file_name);
+
+    $self->js
+    ->run('download_pdf', $pdf_filename, $key)
+    ->flash('info', t8('The PDF has been created'));
+
+  } elsif ($media eq 'printer') {
+    # printer
+    my $printer_id = $::form->{print_options}->{printer_id};
+    my $printer;
+    $printer = SL::DB::Printer->new(id => $printer_id)->load if $printer_id;
+    if (!$printer) {
+      return $self->js->flash('error', t8('Printer not found.'))->render;
+    }
+
+    my $command = SL::Template::create(type => 'ShellCommand', form => Form->new(''))->parse($printer->printer_command);
 
-  my $pdf_filename = $form->generate_attachment_filename();
+    for my $i (1 .. $copies) {
+      open my $out, '|-', $command or die $!;
+      binmode $out;
+      print $out $pdf;
+      close $out;
+    }
+
+    $self->js->flash('info', t8('The PDF has been printed'));
+  }
 
   # copy file to webdav folder
   if ($self->order->ordnumber && $::instance_conf->get_webdav_documents) {
@@ -178,9 +230,7 @@ sub action_create_pdf {
     }
   }
 
-  $self->js
-    ->run('download_pdf', $pdf_filename, $key)
-    ->flash('info', t8('The PDF has been created'))->render($self);
+  $self->js->render;
 }
 
 sub action_download_pdf {
@@ -853,6 +903,20 @@ sub _pre_render {
 
   $self->{current_employee_id} = SL::DB::Manager::Employee->current->id;
 
+  my $print_form = Form->new('');
+  $print_form->{type}      = $self->type;
+  $print_form->{printers}  = SL::DB::Manager::Printer->get_all_sorted;
+  $print_form->{languages} = SL::DB::Manager::Language->get_all_sorted;
+  $self->{print_options}   = SL::Helper::PrintOptions->get_print_options(
+    form => $print_form,
+    options => {dialog_name_prefix => 'print_options.',
+                show_headers       => 1,
+                no_queue           => 1,
+                no_postscript      => 1,
+                no_opendocument    => 1,
+                no_html            => 1},
+  );
+
   foreach my $item (@{$self->order->orderitems}) {
     my $price_source = SL::PriceSource->new(record_item => $item, record => $self->order);
     $item->active_price_source(   $price_source->price_from_source(   $item->active_price_source   ));
@@ -878,23 +942,42 @@ sub _pre_render {
 sub _create_pdf {
   my ($order, $pdf_ref, $params) = @_;
 
+  my @errors = ();
+
   my $print_form = Form->new('');
-  $print_form->{type}     = $order->type;
-  $print_form->{formname} = $order->type;
-  $print_form->{format}   = $params->{format} || 'pdf',
-  $print_form->{media}    = $params->{media}  || 'file';
+  $print_form->{type}        = $order->type;
+  $print_form->{formname}    = $params->{formname} || $order->type;
+  $print_form->{format}      = $params->{format}   || 'pdf';
+  $print_form->{media}       = $params->{media}    || 'file';
+  $print_form->{groupitems}  = $params->{groupitems};
+  $print_form->{media}       = 'file'                             if $print_form->{media} eq 'screen';
+  $print_form->{language}    = $params->{language}->template_code if $print_form->{language};
+  $print_form->{language_id} = $params->{language}->id            if $print_form->{language};
 
   $order->flatten_to_form($print_form, format_amounts => 1);
   # flatten_to_form sets payment_terms from customer/vendor - we do not want that here
   delete $print_form->{payment_terms} if !$print_form->{payment_id};
 
-  my @errors = ();
+  # search for the template
+  my ($template_file, @template_files) = SL::Helper::CreatePDF->find_template(
+    name        => $print_form->{formname},
+    email       => $print_form->{media} eq 'email',
+    language    => $params->{language},
+    printer_id  => $print_form->{printer_id},  # todo
+  );
+
+  if (!defined $template_file) {
+    push @errors, $::locale->text('Cannot find matching template for this print request. Please contact your template maintainer. I tried these: #1.', join ', ', map { "'$_'"} @template_files);
+  }
+
+  return @errors if scalar @errors;
+
   $print_form->throw_on_error(sub {
     eval {
       $print_form->prepare_for_printing;
 
       $$pdf_ref = SL::Helper::CreatePDF->create_pdf(
-        template  => SL::Helper::CreatePDF->find_template(name => $print_form->{formname}),
+        template  => $template_file,
         variables => $print_form,
         variable_content_types => {
           longdescription => 'html',
index cbc57d9..6a29ba5 100644 (file)
@@ -56,6 +56,7 @@ namespace("kivi").setupLocale({
 "Please select a customer.":"Bitte wählen Sie einen Kunden aus.",
 "Please select a vendor.":"Bitte wählen Sie einen Lieferanten aus.",
 "Price Types":"Preistypen",
+"Print options":"Druckoptionen",
 "Project link actions":"Projektverknüpfungs-Aktionen",
 "Quotations/Orders actions":"Aktionen für Angebote/Aufträge",
 "Re-numbering all sections and function blocks in the order they are currently shown cannot be undone.":"Das Neu-Nummerieren aller Abschnitte und Funktionsblöcke kann nicht rückgängig gemacht werden.",
index 3fa000b..27ca622 100755 (executable)
@@ -1287,6 +1287,7 @@ $self->{texts} = {
   'Foreign Exchange Gain'       => 'Wechselkurserträge',
   'Foreign Exchange Loss'       => 'Wechselkursaufwendungen',
   'Form details (second row)'   => 'Formulardetails (zweite Positionszeile)',
+  'Format \'#1\' is not supported yet/anymore.' => 'Das Format \'#1\' wird noch nicht oder nicht mehr unterstützt.',
   'Formula'                     => 'Formel',
   'Found #1 errors.'            => '#1 Fehler gefunden.',
   'Found #1 objects of which #2 can be imported.' => 'Es wurden #1 Objekte gefunden, von denen #2 importiert werden können.',
@@ -1660,6 +1661,7 @@ $self->{texts} = {
   'May '                        => 'Mai',
   'May set the BCC field when sending emails' => 'Beim Verschicken von E-Mails das Feld \'BCC\' setzen',
   'Meaning'                     => 'Bedeutung',
+  'Media \'#1\' is not supported yet/anymore.' => 'Das Medium \'#1\' wird noch nicht oder nicht mehr unterstützt.',
   'Medium Number'               => 'Datentr&auml;gernummer',
   'Memo'                        => 'Memo',
   'Message'                     => 'Nachricht',
@@ -2102,6 +2104,7 @@ $self->{texts} = {
   'Printer Description'         => 'Druckerbeschreibung',
   'Printer Management'          => 'Druckeradministration',
   'Printer management'          => 'Druckerverwaltung',
+  'Printer not found.'          => 'Drucker nicht gefunden.',
   'Printing ... '               => 'Es wird gedruckt.',
   'Printing invoices (this can take a while)' => 'Drucke Rechnungen (kann eine Weile dauern)',
   'Prior year'                  => 'Vorheriges Jahr',
@@ -2696,6 +2699,7 @@ $self->{texts} = {
   'The LDAP server "#1:#2" is unreachable. Please check config/kivitendo.conf.' => 'Der LDAP-Server "#1:#2" ist nicht erreichbar. Bitte &uuml;berpr&uuml;fen Sie die Angaben in config/kivitendo.conf.',
   'The MT940 import needs an import profile called MT940' => 'Der MT940 Import benötigt ein Importprofil mit dem Namen "MT940"',
   'The PDF has been created'    => 'Die PDF-Datei wurde erstellt.',
+  'The PDF has been printed'    => 'Das PDF-Dokument wurde gedruckt.',
   'The SEPA export has been created.' => 'Der SEPA-Export wurde erstellt',
   'The SEPA strings have been saved.' => 'Die bei SEPA-Überweisungen verwendeten Begriffe wurden gespeichert.',
   'The WebDAV feature has been used.' => 'Das WebDAV-Feature wurde benutzt.',
index df51631..55e27db 100644 (file)
@@ -2,6 +2,15 @@
 [%- USE LxERP %]
 [%- USE L %]
 
+<div id="print_options" style="display:none">
+  <form method="post" action="controller.pl" id="print_options_form">
+    [% SELF.print_options %]
+    <br>
+    [% L.button_tag('print()', LxERP.t8('Print')) %]
+    <a href="#" onclick="$('#print_options').dialog('close');">[% LxERP.t8("Cancel") %]</a>
+  </form>
+</div>
+
 <form method="post" action="controller.pl" id="order_form">
   <div class="listtop">[% FORM.title %]</div>
 
@@ -31,7 +40,7 @@
   [% L.hidden_tag('action', 'Order/dispatch') %]
 
   [% L.button_tag('save()', LxERP.t8('Save')) %]
-  [% L.button_tag('create_pdf()', LxERP.t8('Create PDF')) %]
+  [% L.button_tag('show_print_options()', LxERP.t8('Print')) %]
   [% L.button_tag('email()', LxERP.t8('E-mail')) %]
   [% L.button_tag('save_and_delivery_order()', LxERP.t8('Save and Delivery Order')) %]
 [%- IF SELF.order.id && ( (SELF.cv == 'customer' && INSTANCE_CONF.get_sales_order_show_delete) || (SELF.cv == 'vendor' && INSTANCE_CONF.get_purchase_order_show_delete) ) %]
@@ -58,10 +67,25 @@ function save() {
   $.post("controller.pl", data, kivi.eval_json_result);
 }
 
-function create_pdf() {
+function show_print_options() {
   if (!check_cv()) return;
+
+  kivi.popup_dialog({
+    id: 'print_options',
+    dialog: {
+      title: kivi.t8('Print options'),
+      width:  800,
+      height: 300
+    }
+  });
+}
+
+function print() {
+  $('#print_options').dialog('close');
+
   var data = $('#order_form').serializeArray();
-  data.push({ name: 'action', value: 'Order/create_pdf' });
+  data = data.concat($('#print_options_form').serializeArray());
+  data.push({ name: 'action', value: 'Order/print' });
 
   $.post("controller.pl", data, kivi.eval_json_result);
 }