Auftrags-Controller: E-Mail-Dialog aus common verwenden.
authorBernd Bleßmann <bernd@kivitendo-premium.de>
Wed, 24 Jan 2018 10:59:38 +0000 (11:59 +0100)
committerBernd Bleßmann <bernd@kivitendo-premium.de>
Mon, 29 Jan 2018 15:41:57 +0000 (16:41 +0100)
SL/Controller/Order.pm
js/kivi.Order.js
locale/de/all
locale/en/all
templates/webpages/order/tabs/_email_dialog.html [deleted file]

index b581774..b1a90f3 100644 (file)
@@ -24,9 +24,11 @@ use SL::Helper::PrintOptions;
 use SL::Controller::Helper::GetModels;
 
 use List::Util qw(first);
+use List::UtilsBy qw(sort_by uniq_by);
 use List::MoreUtils qw(none pairwise first_index);
 use English qw(-no_match_vars);
 use File::Spec;
+use Cwd;
 
 use Rose::Object::MakeMethods::Generic
 (
@@ -254,10 +256,11 @@ sub action_show_email_dialog {
                     ->render($self);
   }
 
-  $self->{email}->{to}   = $self->order->contact->cp_email if $self->order->contact;
-  $self->{email}->{to} ||= $self->order->$cv_method->email;
-  $self->{email}->{cc}   = $self->order->$cv_method->cc;
-  $self->{email}->{bcc}  = join ', ', grep $_, $self->order->$cv_method->bcc, SL::DB::Default->get->global_bcc;
+  my $email_form;
+  $email_form->{to}   = $self->order->contact->cp_email if $self->order->contact;
+  $email_form->{to} ||= $self->order->$cv_method->email;
+  $email_form->{cc}   = $self->order->$cv_method->cc;
+  $email_form->{bcc}  = join ', ', grep $_, $self->order->$cv_method->bcc, SL::DB::Default->get->global_bcc;
   # Todo: get addresses from shipto, if any
 
   my $form = Form->new;
@@ -267,11 +270,19 @@ sub action_show_email_dialog {
   $form->{language} = 'de';
   $form->{format}   = 'pdf';
 
-  $self->{email}->{subject}             = $form->generate_email_subject();
-  $self->{email}->{attachment_filename} = $form->generate_attachment_filename();
-  $self->{email}->{message}             = $form->create_email_signature();
+  $email_form->{subject}             = $form->generate_email_subject();
+  $email_form->{attachment_filename} = $form->generate_attachment_filename();
+  $email_form->{message}             = $form->generate_email_body();
+  $email_form->{js_send_function}    = 'kivi.Order.send_email()';
+
+  my %files = $self->_get_files_for_email_dialog();
+  my $dialog_html = $self->render('common/_send_email_dialog', { output => 0 },
+                                  email_form  => $email_form,
+                                  show_bcc    => $::auth->assert('email_bcc', 'may fail'),
+                                  FILES       => \%files,
+                                  is_customer => $self->cv eq 'customer',
+  );
 
-  my $dialog_html = $self->render('order/tabs/_email_dialog', { output => 0 });
   $self->js
       ->run('kivi.Order.show_email_dialog', $dialog_html)
       ->reinit_widgets
@@ -284,38 +295,56 @@ sub action_show_email_dialog {
 sub action_send_email {
   my ($self) = @_;
 
-  my $mail      = Mailer->new;
-  $mail->{from} = qq|"$::myconfig{name}" <$::myconfig{email}>|;
-  $mail->{$_}   = $::form->{email}->{$_} for qw(to cc bcc subject message);
+  my $email_form  = delete $::form->{email_form};
+  my %field_names = (to => 'email');
 
-  my $pdf;
-  my @errors = _create_pdf($self->order, \$pdf, {media => 'email'});
-  if (scalar @errors) {
-    return $self->js->flash('error', t8('Conversion to PDF failed: #1', $errors[0]))->render($self);
-  }
+  $::form->{ $field_names{$_} // $_ } = $email_form->{$_} for keys %{ $email_form };
 
-  $mail->{attachments} = [{ "content" => $pdf,
-                            "name"    => $::form->{email}->{attachment_filename} }];
+  # for Form::cleanup which may be called in Form::send_email
+  $::form->{cwd}    = getcwd();
+  $::form->{tmpdir} = $::lx_office_conf{paths}->{userspath};
 
-  if (my $err = $mail->send) {
-    return $self->js->flash('error', t8('Sending E-mail: ') . $err)
-                    ->render($self);
+  $::form->{media}  = 'email';
+
+  if (($::form->{attachment_policy} // '') eq 'normal') {
+    my $language;
+    $language = SL::DB::Language->new(id => $::form->{print_options}->{language_id})->load if $::form->{print_options}->{language_id};
+
+    my $pdf;
+    my @errors = _create_pdf($self->order, \$pdf, {media      => $::form->{media},
+                                                   format     => $::form->{print_options}->{format},
+                                                   formname   => $::form->{print_options}->{formname},
+                                                   language   => $language,
+                                                   groupitems => $::form->{print_options}->{groupitems}});
+    if (scalar @errors) {
+      return $self->js->flash('error', t8('Conversion to PDF failed: #1', $errors[0]))->render($self);
+    }
+
+    my $sfile = SL::SessionFile::Random->new(mode => "w");
+    $sfile->fh->print($pdf);
+    $sfile->fh->close;
+
+    $::form->{tmpfile} = $sfile->file_name;
+    $::form->{tmpdir}  = $sfile->get_path; # for Form::cleanup which may be called in Form::send_email
   }
 
+  $::form->send_email(\%::myconfig, 'pdf');
+
   # internal notes
   my $intnotes = $self->order->intnotes;
   $intnotes   .= "\n\n" if $self->order->intnotes;
   $intnotes   .= t8('[email]')                                                                                        . "\n";
   $intnotes   .= t8('Date')       . ": " . $::locale->format_date_object(DateTime->now_local, precision => 'seconds') . "\n";
-  $intnotes   .= t8('To (email)') . ": " . $mail->{to}                                                                . "\n";
-  $intnotes   .= t8('Cc')         . ": " . $mail->{cc}                                                                . "\n"    if $mail->{cc};
-  $intnotes   .= t8('Bcc')        . ": " . $mail->{bcc}                                                               . "\n"    if $mail->{bcc};
-  $intnotes   .= t8('Subject')    . ": " . $mail->{subject}                                                           . "\n\n";
-  $intnotes   .= t8('Message')    . ": " . $mail->{message};
+  $intnotes   .= t8('To (email)') . ": " . $::form->{email}                                                           . "\n";
+  $intnotes   .= t8('Cc')         . ": " . $::form->{cc}                                                              . "\n"    if $::form->{cc};
+  $intnotes   .= t8('Bcc')        . ": " . $::form->{bcc}                                                             . "\n"    if $::form->{bcc};
+  $intnotes   .= t8('Subject')    . ": " . $::form->{subject}                                                         . "\n\n";
+  $intnotes   .= t8('Message')    . ": " . $::form->{message};
 
   $self->js
       ->val('#order_intnotes', $intnotes)
       ->run('kivi.Order.close_email_dialog')
+      ->flash('info', t8('The email has been sent.'))
       ->render($self);
 }
 
@@ -1237,6 +1266,38 @@ sub _create_pdf {
   return @errors;
 }
 
+sub _get_files_for_email_dialog {
+  my ($self) = @_;
+
+  my %files = map { ($_ => []) } qw(versions files vc_files part_files);
+
+  return %files if !$::instance_conf->get_doc_storage;
+
+  if ($self->order->id) {
+    $files{versions} = [ SL::File->get_all_versions(object_id => $self->order->id,              object_type => $self->order->type, file_type => 'document') ];
+    $files{files}    = [ SL::File->get_all(         object_id => $self->order->id,              object_type => $self->order->type, file_type => 'attachment') ];
+    $files{vc_files} = [ SL::File->get_all(         object_id => $self->order->{$self->cv}->id, object_type => $self->cv,          file_type => 'attachment') ];
+  }
+
+  my @parts =
+    uniq_by { $_->{id} }
+    map {
+      +{ id         => $_->part->id,
+         partnumber => $_->part->partnumber }
+    } @{$self->order->items_sorted};
+
+  foreach my $part (@parts) {
+    my @pfiles = SL::File->get_all(object_id => $part->{id}, object_type => 'part');
+    push @{ $files{part_files} }, map { +{ %{ $_ }, partnumber => $part->{partnumber} } } @pfiles;
+  }
+
+  foreach my $key (keys %files) {
+    $files{$key} = [ sort_by { lc $_->{db_file}->{file_name} } @{ $files{$key} } ];
+  }
+
+  return %files;
+}
+
 sub _sales_order_type {
   'sales_order';
 }
@@ -1354,10 +1415,6 @@ Results for the filter in the multi items dialog
 
 Dialog for selecting price and discount sources
 
-=item * C<template/webpages/order/tabs/_email_dialog.html>
-
-Email dialog
-
 =back
 
 =item * C<js/kivi.Order.js>
@@ -1440,6 +1497,10 @@ should be implemented.
 C<show_multi_items_dialog> does not use the currently inserted string for
 filtering.
 
+=item *
+
+The language selected in print or email dialog is not saved when the order is saved.
+
 =back
 
 =head1 To discuss / Nice to have
index cce54f4..6e26d7b 100644 (file)
@@ -114,16 +114,35 @@ namespace('kivi.Order', function(ns) {
 
   var email_dialog;
 
+  ns.setup_send_email_dialog = function() {
+    kivi.SalesPurchase.show_all_print_options_elements();
+    kivi.SalesPurchase.show_print_options_elements([ 'sendmode', 'media', 'copies', 'remove_draft' ], false);
+
+    $('#print_options_form table').first().remove().appendTo('#email_form_print_options');
+
+    var to_focus = $('#email_form_to').val() === '' ? 'to' : 'subject';
+    $('#email_form_' + to_focus).focus();
+  };
+
+  ns.finish_send_email_dialog = function() {
+    kivi.SalesPurchase.show_all_print_options_elements();
+
+    $('#email_form_print_options table').first().remove().prependTo('#print_options_form');
+    return true;
+  };
+
   ns.show_email_dialog = function(html) {
-    var id            = 'jqueryui_popup_dialog';
+    var id            = 'send_email_dialog';
     var dialog_params = {
       id:     id,
       width:  800,
-      height: 500,
+      height: 600,
+      title:  kivi.t8('Send email'),
       modal:  true,
+      beforeClose: kivi.Order.finish_send_email_dialog,
       close: function(event, ui) {
         email_dialog.remove();
-      },
+      }
     };
 
     $('#' + id).remove();
@@ -132,6 +151,8 @@ namespace('kivi.Order', function(ns) {
     email_dialog.html(html);
     email_dialog.dialog(dialog_params);
 
+    kivi.Order.setup_send_email_dialog();
+
     $('.cancel').click(ns.close_email_dialog);
 
     return true;
@@ -139,7 +160,8 @@ namespace('kivi.Order', function(ns) {
 
   ns.send_email = function() {
     var data = $('#order_form').serializeArray();
-    data = data.concat($('#email_form').serializeArray());
+    data = data.concat($('[name^="email_form."]').serializeArray());
+    data = data.concat($('[name^="print_options."]').serializeArray());
     data.push({ name: 'action', value: 'Order/send_email' });
     $.post("controller.pl", data, kivi.eval_json_result);
   };
index 3b5ba1e..80eae73 100755 (executable)
@@ -2758,7 +2758,6 @@ $self->{texts} = {
   'Send printout of record'     => 'Belegausdruck mitschicken',
   'Send the last printout created for this record' => 'Den zuletzt erstellen Belegausdruck mitschicken',
   'Sender'                      => 'AbsenderIn',
-  'Sending E-mail: '            => 'E-Mail versenden: ',
   'Sent emails can be optionally stored in the database with or without their attachments.' => 'Gesendete E-Mails können optional mit oder ohne ihre Anhänge in der Datenbank gespeichert werden.',
   'Sent on'                     => 'Verschickt am',
   'Sent payments can only be posted for purchase invoices and sales credit notes.' => 'Gesendete Zahlungen können nur mit Einkaufsrechnungen und Verkaufsgutschriften verbucht werden.',
index b35495c..eba3dd8 100644 (file)
@@ -2715,7 +2715,6 @@ $self->{texts} = {
   'Send printout of record'     => '',
   'Send the last printout created for this record' => '',
   'Sender'                      => '',
-  'Sending E-mail: '            => '',
   'Sent emails can be optionally stored in the database with or without their attachments.' => '',
   'Sent on'                     => '',
   'Sent payments can only be posted for purchase invoices and sales credit notes.' => '',
diff --git a/templates/webpages/order/tabs/_email_dialog.html b/templates/webpages/order/tabs/_email_dialog.html
deleted file mode 100644 (file)
index 27b1ccd..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-[%- USE T8 %][%- USE HTML %][%- USE L %][%- USE LxERP %]
-<h2>[%- 'E-mail' | $T8 %]&nbsp;[%- SELF.type | $T8 %]</h2>
-
-<form method="post" id="email_form" method="POST">
-<table width="100%">
-  <tr>
-    <td>
-      <table>
-        <tr  align="left">
-          <th align="right" nowrap>[% 'To' | $T8 %]</th>
-          <td>[% L.input_tag("email.to", SELF.email.to, size=30, class=(SELF.email.to ? '' : 'initial_focus')) %]</td>
-        </tr>
-        <tr>
-          <th align="right" nowrap>[% 'Cc' | $T8 %]</th>
-          <td>[% L.input_tag("email.cc", SELF.email.cc, size=30) %]</td>
-        </tr>
-        [%- IF AUTH.assert('email_bcc', 1) %]
-        <tr>
-          <th align="right" nowrap>[% 'Bcc' | $T8 %]</th>
-          <td>[% L.input_tag("email.bcc", SELF.email.bcc, size=30) %]</td>
-        </tr>
-        [%- END %]
-        <tr>
-          <th align="right" nowrap>[% 'Subject' | $T8 %]</th>
-          <td>[% L.input_tag('email.subject', SELF.email.subject, size=30, class=(SELF.email.subject ? 'initial_focus' : '')) %]</td>
-        </tr>
-        <tr>
-          <th align="right" nowrap>[% 'Attachment name' | $T8 %]</th>
-          <td>[% L.input_tag("email.attachment_filename", SELF.email.attachment_filename, size=30) %]</td>
-        </tr>
-      </table>
-    </td>
-  </tr>
-
-  <tr>
-    <table>
-      <tr>
-        <th align="left" nowrap>[% 'Message' | $T8 %]</th>
-      </tr>
-      <tr>
-        <td>
-          [% L.textarea_tag("email.message", SELF.email.message, wrap="soft", style="width: 350px; height: 150px") %]
-        </td>
-      </tr>
-  </tr>
-
-</table>
-
-<br>
-[% L.hidden_tag('action', 'Order/dispatch') %]
-[% L.button_tag('kivi.Order.send_email()', LxERP.t8('Continue')) %]
-<a href="#" onclick="kivi.Order.close_email_dialog();">[%- LxERP.t8("Cancel") %]</a>
-
-</form>