use a message template for invoice_email_pdf message body, #31786
authorMark Wells <mark@freeside.biz>
Mon, 23 Feb 2015 19:09:12 +0000 (11:09 -0800)
committerMark Wells <mark@freeside.biz>
Mon, 23 Feb 2015 19:09:12 +0000 (11:09 -0800)
FS/FS/Conf.pm
FS/FS/Template_Mixin.pm
FS/FS/msg_template.pm

index 169f9fe..9213681 100644 (file)
@@ -1562,6 +1562,13 @@ and customer address. Include units.',
   },
 
   {
+    'key'         => 'invoice_email_pdf_msgnum',
+    'section'     => 'invoicing',
+    'description' => 'Message template to send as the text and HTML part of PDF invoices. If not selected, a text and HTML version of the invoice will be sent.',
+    %msg_template_options,
+  },
+
+  {
     'key'         => 'invoice_email_pdf_note',
     'section'     => 'invoicing',
     'description' => 'If defined, this text will replace the default HTML invoice as the body of emailed PDF invoices.',
index 606c6c8..9045291 100644 (file)
@@ -2037,10 +2037,6 @@ sender address, required
 
 alternate template name, optional
 
-=item print_text
-
-text attachment arrayref, optional
-
 =item subject
 
 email subject, optional
@@ -2084,61 +2080,61 @@ sub generate_email {
 
   my $tc = $self->template_conf;
 
-  if ( $conf->exists($tc.'html') ) {
+  my @text; # array of lines
+  my $html; # a big string
+  my @related_parts; # will contain the text/HTML alternative, and images
+  my $related; # will contain the multipart/related object
 
-    warn "$me creating HTML/text multipart message"
-      if $DEBUG;
+  if ( $conf->exists($tc. 'email_pdf') ) {
+    if ( my $msgnum = $conf->config($tc.'email_pdf_msgnum') ) {
 
-    $return{'nobody'} = 1;
+      warn "$me using '${tc}email_pdf_msgnum' in multipart message"
+        if $DEBUG;
 
-    my $alternative = build MIME::Entity
-      'Type'        => 'multipart/alternative',
-      #'Encoding'    => '7bit',
-      'Disposition' => 'inline'
-    ;
+      my $msg_template = FS::msg_template->by_key($msgnum)
+        or die "${tc}email_pdf_msgnum $msgnum not found\n";
+      my %prepared = $msg_template->prepare(
+        cust_main => $self->cust_main,
+        object    => $self
+      );
+
+      @text = split(/(?=\n)/, $prepared{'text_body'});
+      $html = $prepared{'html_body'};
 
-    my $data = '';
-    if ( $conf->exists($tc. 'email_pdf')
-         and scalar($conf->config($tc. 'email_pdf_note')) ) {
+    } elsif ( my @note = $conf->config($tc.'email_pdf_note') ) {
 
       warn "$me using '${tc}email_pdf_note' in multipart message"
         if $DEBUG;
-      $data = [ map { $_ . "\n" }
-                    $conf->config($tc.'email_pdf_note')
-              ];
+      @text = $conf->config($tc.'email_pdf_note');
+      $html = join('<BR>', @text);
+  
+    } # else use the plain text invoice
+  }
 
-    } else {
+  if (!@text) {
 
-      warn "$me not using '${tc}email_pdf_note' in multipart message"
-        if $DEBUG;
-      if ( ref($args{'print_text'}) eq 'ARRAY' ) {
-        $data = $args{'print_text'};
-      } elsif ( $conf->exists($tc.'template') ) { #plaintext invoice_template
-        $data = [ $self->print_text(\%args) ];
-      }
+    warn "$me generating plain text invoice"
+      if $DEBUG;
 
-    }
+    # 'print_text' argument is no longer used
+    @text = $self->print_text(\%args);
 
-    if ( $data ) {
-      $alternative->attach(
-        'Type'        => 'text/plain',
-        'Encoding'    => 'quoted-printable',
-        'Charset'     => 'UTF-8',
-        #'Encoding'    => '7bit',
-        'Data'        => $data,
-        'Disposition' => 'inline',
-      );
-    }
+  }
 
-    my $htmldata;
-    my $image = '';
-    my $barcode = '';
-    if ( $conf->exists($tc.'email_pdf')
-         and scalar($conf->config($tc.'email_pdf_note')) ) {
+  my $text_part = build MIME::Entity (
+    'Type'        => 'text/plain',
+    'Encoding'    => 'quoted-printable',
+    'Charset'     => 'UTF-8',
+    #'Encoding'    => '7bit',
+    'Data'        => \@text,
+    'Disposition' => 'inline',
+  );
 
-      $htmldata = join('<BR>', $conf->config($tc.'email_pdf_note') );
+  if (!$html) {
 
-    } else {
+    if ( $conf->exists($tc.'html') ) {
+      warn "$me generating HTML invoice"
+        if $DEBUG;
 
       $args{'from'} =~ /\@([\w\.\-]+)/;
       my $from = $1 || 'example.com';
@@ -2157,7 +2153,7 @@ sub generate_email {
       }
       my $image_data = $conf->config_binary( $logo, $agentnum);
 
-      $image = build MIME::Entity
+      push @related_parts, build MIME::Entity
         'Type'       => 'image/png',
         'Encoding'   => 'base64',
         'Data'       => $image_data,
@@ -2167,7 +2163,7 @@ sub generate_email {
    
       if ( ref($self) eq 'FS::cust_bill' && $conf->exists('invoice-barcode') ) {
         my $barcode_content_id = join('.', rand()*(2**32), $$, time). "\@$from";
-        $barcode = build MIME::Entity
+        push @related_parts, build MIME::Entity
           'Type'       => 'image/png',
           'Encoding'   => 'base64',
           'Data'       => $self->invoice_barcode(0),
@@ -2177,7 +2173,26 @@ sub generate_email {
         $args{'barcode_cid'} = $barcode_content_id;
       }
 
-      $htmldata = $self->print_html({ 'cid'=>$content_id, %args });
+      $html = $self->print_html({ 'cid'=>$content_id, %args });
+    }
+
+  }
+
+  if ( $html ) {
+
+    warn "$me creating HTML/text multipart message"
+      if $DEBUG;
+
+    $return{'nobody'} = 1;
+
+    my $alternative = build MIME::Entity
+      'Type'        => 'multipart/alternative',
+      #'Encoding'    => '7bit',
+      'Disposition' => 'inline'
+    ;
+
+    if ( @text ) {
+      $alternative->add_part($text_part);
     }
 
     $alternative->attach(
@@ -2190,7 +2205,7 @@ sub generate_email {
                          '    </title>',
                          '  </head>',
                          '  <body bgcolor="#e8e8e8">',
-                         $htmldata,
+                         $html,
                          '  </body>',
                          '</html>',
                        ],
@@ -2198,104 +2213,68 @@ sub generate_email {
       #'Filename'    => 'invoice.pdf',
     );
 
+    unshift @related_parts, $alternative;
 
-    my @otherparts = ();
-    if ( ref($self) eq 'FS::cust_bill' && $cust_main->email_csv_cdr ) {
-
-      push @otherparts, build MIME::Entity
-        'Type'        => 'text/csv',
-        'Encoding'    => '7bit',
-        'Data'        => [ map { "$_\n" }
-                             $self->call_details('prepend_billed_number' => 1)
-                         ],
-        'Disposition' => 'attachment',
-        'Filename'    => 'usage-'. $self->invnum. '.csv',
-      ;
-
-    }
-
-    if ( $conf->exists($tc.'email_pdf') ) {
-
-      #attaching pdf too:
-      # multipart/mixed
-      #   multipart/related
-      #     multipart/alternative
-      #       text/plain
-      #       text/html
-      #     image/png
-      #   application/pdf
-
-      my $related = build MIME::Entity 'Type'     => 'multipart/related',
-                                       'Encoding' => '7bit';
-
-      #false laziness w/Misc::send_email
-      $related->head->replace('Content-type',
-        $related->mime_type.
-        '; boundary="'. $related->head->multipart_boundary. '"'.
-        '; type=multipart/alternative'
-      );
-
-      $related->add_part($alternative);
-
-      $related->add_part($image) if $image;
+    $related = build MIME::Entity 'Type'     => 'multipart/related',
+                                  'Encoding' => '7bit';
 
-      my $pdf = build MIME::Entity $self->mimebuild_pdf(\%args);
+    #false laziness w/Misc::send_email
+    $related->head->replace('Content-type',
+      $related->mime_type.
+      '; boundary="'. $related->head->multipart_boundary. '"'.
+      '; type=multipart/alternative'
+    );
 
-      $return{'mimeparts'} = [ $related, $pdf, @otherparts ];
+    $related->add_part($_) foreach @related_parts;
 
-    } else {
+  }
 
-      #no other attachment:
-      # multipart/related
-      #   multipart/alternative
-      #     text/plain
-      #     text/html
-      #   image/png
+  my @otherparts = ();
+  if ( ref($self) eq 'FS::cust_bill' && $cust_main->email_csv_cdr ) {
 
-      $return{'content-type'} = 'multipart/related';
-      if ($conf->exists('invoice-barcode') && $barcode) {
-        $return{'mimeparts'} = [ $alternative, $image, $barcode, @otherparts ];
-      } else {
-        $return{'mimeparts'} = [ $alternative, $image, @otherparts ];
-      }
-      $return{'type'} = 'multipart/alternative'; #Content-Type of first part...
-      #$return{'disposition'} = 'inline';
+    push @otherparts, build MIME::Entity
+      'Type'        => 'text/csv',
+      'Encoding'    => '7bit',
+      'Data'        => [ map { "$_\n" }
+                           $self->call_details('prepend_billed_number' => 1)
+                       ],
+      'Disposition' => 'attachment',
+      'Filename'    => 'usage-'. $self->invnum. '.csv',
+    ;
 
-    }
-  
-  } else {
+  }
 
-    if ( $conf->exists($tc.'email_pdf') ) {
-      warn "$me creating PDF attachment"
-        if $DEBUG;
+  if ( $conf->exists($tc.'email_pdf') ) {
 
-      #mime parts arguments a la MIME::Entity->build().
-      $return{'mimeparts'} = [
-        { $self->mimebuild_pdf(\%args) }
-      ];
-    }
-  
-    if ( $conf->exists($tc.'email_pdf')
-         and scalar($conf->config($tc.'email_pdf_note')) ) {
+    #attaching pdf too:
+    # multipart/mixed
+    #   multipart/related
+    #     multipart/alternative
+    #       text/plain
+    #       text/html
+    #     image/png
+    #   application/pdf
 
-      warn "$me using '${tc}email_pdf_note'"
-        if $DEBUG;
-      $return{'body'} = [ map { $_ . "\n" }
-                              $conf->config($tc.'email_pdf_note')
-                        ];
+    my $pdf = build MIME::Entity $self->mimebuild_pdf(\%args);
+    push @otherparts, $pdf;
+  }
 
+  if (@otherparts) {
+    $return{'content-type'} = 'multipart/mixed'; # of the outer container
+    if ( $html ) {
+      $return{'mimeparts'} = [ $related, @otherparts ];
+      $return{'type'} = 'multipart/related'; # of the first part
     } else {
-
-      warn "$me not using '${tc}email_pdf_note'"
-        if $DEBUG;
-      if ( ref($args{'print_text'}) eq 'ARRAY' ) {
-        $return{'body'} = $args{'print_text'};
-      } else {
-        $return{'body'} = [ $self->print_text(\%args) ];
-      }
-
+      $return{'mimeparts'} = [ $text_part, @otherparts ];
+      $return{'type'} = 'text/plain';
     }
-
+  } elsif ( $html ) { # no PDF or CSV, strip the outer container
+    $return{'mimeparts'} = \@related_parts;
+    $return{'content-type'} = 'multipart/related';
+    $return{'type'} = 'multipart/alternative';
+  } else { # no HTML either
+    $return{'body'} = \@text;
+    $return{'content-type'} = 'text/plain';
   }
 
   %return;
index 94d478f..9599e4f 100644 (file)
@@ -601,8 +601,9 @@ sub substitutions {
       _date
       _date_pretty
       due_date
-      due_date2str
-    )],
+    ),
+      [ due_date2str      => sub { shift->due_date2str('short') } ],
+    ],
     #XXX not really thinking about cust_bill substitutions quite yet
     
     # for welcome and limit warning messages