]> wagnertech.de Git - mfinanz.git/commitdiff
Verknüpfte Belege um die Verknüpfung 'E-Mail Journal' erweitert.
authorJan Büren <jan@kivitendo-premium.de>
Mon, 26 Mar 2018 11:02:56 +0000 (13:02 +0200)
committerJan Büren <jan@kivitendo-premium.de>
Mon, 26 Mar 2018 11:02:56 +0000 (13:02 +0200)
Falls das E-Mail-Journal aktiviert ist wird zusätzlich zu der
archivierten E-Mail auch die Verknüpfung vom Beleg zu der E-Mail mitgespeichert
und ist im Beleg zusätzlich direkt anwählbar.
Etwas mehr Details im POD vom Mailer.pm, die Implementierung orientiert
sich überwiegend an der Erweiterung der Verknüpfung von Letter.pm, bzw. dem ShopConnector.

SL/BackgroundJob/CreatePeriodicInvoices.pm
SL/Controller/Letter.pm
SL/Controller/RecordLinks.pm
SL/DB/EmailJournal.pm
SL/DB/Helper/LinkedRecords.pm
SL/Mailer.pm
SL/Presenter/Record.pm

index 45a41d012c7216742b7cb05db39861cdebf34f44..b7b3e3305d87971c36386f2d353000542c435b5e 100644 (file)
@@ -404,6 +404,8 @@ sub _email_invoice {
 
     for my $recipient (@recipients) {
       my $mail             = Mailer->new;
+      $mail->{record_id}   = $data->{invoice}->id,
+      $mail->{record_type} = 'invoice',
       $mail->{from}        = $data->{config}->email_sender || $::lx_office_conf{periodic_invoices}->{email_from};
       $mail->{to}          = $recipient;
       $mail->{bcc}         = $global_bcc;
index 4cc5b55737dd115c9caac8e1b60c0e8936fa7cf4..b16a913656c87b0c5e1c7f709c5141224d56c3b5 100644 (file)
@@ -246,7 +246,7 @@ sub action_print_letter {
                                 name => $params{email}->{attachment_filename} }];
       $mail->{message}    .=  "\n-- \n$signature";
       $mail->{message}     =~ s/\r//g;
-
+      $mail->{record_id}   =  $letter->id;
       $mail->send;
       unlink $result{file_name};
 
index 67b97d92e8b0c6f07a66eeb0576e13b4790d2efe..cd57e98fdbb4e252d77c5a0b7e1e12988073d5d3 100644 (file)
@@ -49,6 +49,7 @@ my @link_type_specifics = (
   { title => t8('Purchase delivery order'), type => 'purchase_delivery_order', model => 'DeliveryOrder',   number => 'donumber',  },
   { title => t8('Purchase Invoice'),        type => 'purchase_invoice',        model => 'PurchaseInvoice', number => 'invnumber', },
   { title => t8('Letter'),                  type => 'letter',                  model => 'Letter',          number => 'letternumber', description => 'subject', description_title => t8('Subject'), date => 'date', project => undef },
+  { title => t8('Email'),                   type => 'email_journal',           model => 'EmailJournal',    number => 'id', description => 'subject', description_title => t8('Subject'), },
 );
 
 my @link_types = map { +{ %link_type_defaults, %{ $_ } } } @link_type_specifics;
index 9920d59d777b35392f59a6175b76c50fd8f009bf..5f3a51da83efc0ffa4589a1a7d69f31323ef3317 100644 (file)
@@ -18,4 +18,42 @@ __PACKAGE__->meta->initialize;
 
 __PACKAGE__->attr_sorted('attachments');
 
+sub compare_to {
+  my ($self, $other) = @_;
+
+  return -1 if  $self->sent_on && !$other->sent_on;
+  return  1 if !$self->sent_on &&  $other->sent_on;
+
+  my $result = 0;
+  $result    = $other->sent_on <=> $self->sent_on;
+  return $result || ($self->id <=> $other->id);
+}
+
 1;
+
+__END__
+
+=pod
+
+=encoding utf8
+
+=head1 NAME
+
+SL::DB::EmailJournal - RDBO model for email journal
+
+=head1 SYNOPSIS
+
+This is a standard Rose::DB::Object based model and can be used as one.
+
+=head1 METHODS
+
+=over 4
+
+=item C<compare_to $self, $other>
+
+Compares C<$self> with C<$other> and returns the newer entry.
+
+=back
+
+=cut
+
index bf91e6a7b0ce6eaf3e923e390e3d7df55523ad98..8b719aa9f466ffee6f5ab3db18f134f494443c89 100644 (file)
@@ -210,7 +210,7 @@ sub _linked_records_implementation {
     }
 
     # don't use rose retrieval here. too slow.
-    # instead use recursive sql to get all the linked record_links entrys, and retrieve the objects from there
+    # instead use recursive sql to get all the linked record_links entries and retrieve the objects from there
     my $query = <<"";
       WITH RECURSIVE record_links_rec_${wanted}(id, from_table, from_id, to_table, to_id, depth, path, cycle) AS (
         SELECT id, from_table, from_id, to_table, to_id,
@@ -313,6 +313,7 @@ sub sort_linked_records {
                   'SL::DB::RequirementSpec' => sub { $_[0]->id },
                   'SL::DB::Letter'          => sub { $_[0]->letternumber },
                   'SL::DB::ShopOrder'       => sub { $_[0]->shop_ordernumber },
+                  'SL::DB::EmailJournal'    => sub { $_[0]->id },
                   UNKNOWN                   => '9999999999999999',
                 );
   my $number_xtor = sub {
@@ -343,6 +344,7 @@ sub sort_linked_records {
               'SL::DB::PurchaseInvoice' => 150,
               'SL::DB::Letter'          => 200,
               'SL::DB::ShopOrder'       => 250,
+              'SL::DB::EmailJournal'    => 300,
               UNKNOWN                   => 999,
             );
   my $score_xtor = sub {
index b7932457b938cf5be583f4959b65236ea9427a89..67f46fe21a483fd584b10072361b81d876553c61 100644 (file)
@@ -45,6 +45,19 @@ my %mail_delivery_modules = (
   smtp     => 'SL::Mailer::SMTP',
 );
 
+my %type_to_table = (
+  sales_quotation         => 'oe',
+  request_quotation       => 'oe',
+  sales_order             => 'oe',
+  purchase_order          => 'oe',
+  invoice                 => 'ar',
+  credit_note             => 'ar',
+  purchase_invoice        => 'ap',
+  letter                  => 'letter',
+  purchase_delivery_order => 'delivery_orders',
+  sales_delivery_order    => 'delivery_orders',
+);
+
 sub new {
   my ($type, %params) = @_;
   my $self = { %params };
@@ -263,7 +276,9 @@ sub send {
 
   $error = $@ if !$ok;
 
+  # create journal and link to record
   $self->{journalentry} = $self->_store_in_journal;
+  $self->_create_record_link if $self->{journalentry};
 
   return $ok ? '' : ($error || "undefined error");
 }
@@ -303,4 +318,123 @@ sub _store_in_journal {
   return $jentry->id;
 }
 
+
+sub _create_record_link {
+  my ($self) = @_;
+
+  # check for custom/overloaded types and ids (form != controller)
+  my $record_type = $self->{record_type} || $::form->{type};
+  my $record_id   = $self->{record_id}   || $::form->{id};
+
+  # you may send mails for unsaved objects (no record_id => unlinkable case)
+  if ($self->{journalentry} && $record_id && exists($type_to_table{$record_type})) {
+    RecordLinks->create_links(
+      mode       => 'ids',
+      from_table => $type_to_table{$record_type},
+      from_ids   => $record_id,
+      to_table   => 'email_journal',
+      to_id      => $self->{journalentry},
+    );
+  }
+}
+
 1;
+
+
+__END__
+
+=pod
+
+=encoding utf8
+
+=head1 NAME
+
+SL::Mailer - Base class for sending mails from kivitendo
+
+=head1 SYNOPSIS
+
+  package SL::BackgroundJob::CreatePeriodicInvoices;
+
+  use SL::Mailer;
+
+  my $mail              = Mailer->new;
+  $mail->{from}         = $config{periodic_invoices}->{email_from};
+  $mail->{to}           = $email;
+  $mail->{subject}      = $config{periodic_invoices}->{email_subject};
+  $mail->{content_type} = $filename =~ m/.html$/ ? 'text/html' : 'text/plain';
+  $mail->{message}      = $output;
+
+  $mail->send;
+
+=head1 OVERVIEW
+
+Mail can be send from kivitendo via the sendmail command or the smtp protocol.
+
+
+=head1 INTERNAL DATA TYPES
+
+
+=over 2
+
+=item C<%mail_delivery_modules>
+
+  Currently two modules are supported either smtp or sendmail.
+
+=item C<%type_to_table>
+
+  Due to the lack of a single global mapping for $form->{type},
+  type is mapped to the corresponding database table. All types which
+  implement a mail action are currently mapped and should be mapped.
+  Type is either the value of the old form or the newer controller
+  based object type.
+
+=back
+
+=head1 FUNCTIONS
+
+=over 4
+
+=item C<new>
+
+=item C<_create_driver>
+
+=item C<_cleanup_addresses>
+
+=item C<_create_address_headers>
+
+=item C<_create_message_id>
+
+=item C<_create_attachment_part>
+
+=item C<_create_message>
+
+=item C<send>
+
+  If a mail was send successfully the internal functions _store_in_journal
+  is called if email journaling is enabled. If _store_in_journal was executed
+  successfully and the calling form is already persistent (database id) a
+  record_link will be created.
+
+=item C<_all_recipients>
+
+=item C<_store_in_journal>
+
+=item C<_create_record_link $self->{journalentry}, $::form->{id}, $self->{record_id}>
+
+
+  If $self->{journalentry} and either $self->{record_id} or $::form->{id} (checked in
+  this order) exists a record link from record to email journal is created.
+  Will fail silently if record_link creation wasn't successful (same behaviour as
+  _store_in_journal).
+
+=item C<validate>
+
+=back
+
+=head1 BUGS
+
+Nothing here yet.
+
+=head1 AUTHOR
+
+=cut
index d1d7c3b44d1293c07c6add2dc95c16eded7ae709..5890f429242952f99d3cda8f1c795e25ae12bc42 100644 (file)
@@ -65,6 +65,7 @@ sub grouped_record_list {
   $output .= _sepa_transfer_list(          $groups{sepa_transfers},           %params) if $groups{sepa_transfers};
 
   $output .= _letter_list(                 $groups{letters},                  %params) if $groups{letters};
+  $output .= _email_journal_list(          $groups{email_journals},           %params) if $groups{email_journals};
 
   $output  = SL::Presenter->get->render('presenter/record/grouped_record_list', %params, output => $output);
 
@@ -193,6 +194,7 @@ sub _group_records {
     gl_transactions          => sub { (ref($_[0]) eq 'SL::DB::GLTransaction')                                           },
     bank_transactions        => sub { (ref($_[0]) eq 'SL::DB::BankTransaction') &&  $_[0]->id                           },
     letters                  => sub { (ref($_[0]) eq 'SL::DB::Letter')          &&  $_[0]->id                           },
+    email_journals           => sub { (ref($_[0]) eq 'SL::DB::EmailJournal')    &&  $_[0]->id                           },
   );
 
   my %groups;
@@ -554,6 +556,25 @@ sub _letter_list {
   );
 }
 
+sub _email_journal_list {
+  my ($list, %params) = @_;
+
+  return record_list(
+    $list,
+    title   => $::locale->text('Email'),
+    type    => 'email_journal',
+    columns => [
+      [ $::locale->text('Sent on'), sub { $_[0]->sent_on->to_kivitendo(precision => 'seconds') } ],
+      [ $::locale->text('Subject'), sub { $_[0]->presenter->email_journal(display => 'table-cell') } ],
+      [ $::locale->text('Status'),  'status'                                                     ],
+      [ $::locale->text('From'),    'from'                                                       ],
+      [ $::locale->text('To'),      'recipients'                                                 ],
+    ],
+    %params,
+  );
+}
+
+
 1;
 
 __END__