[freeside-commits] branch master updated. fc672686f119da0b3b34fd3c73acc3fea81262e6

Mark Wells mark at 420.am
Wed Oct 7 14:18:56 PDT 2015


The branch, master has been updated
       via  fc672686f119da0b3b34fd3c73acc3fea81262e6 (commit)
      from  956df0bc6383ed0513d4dd00668f3b24c42ba1e4 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit fc672686f119da0b3b34fd3c73acc3fea81262e6
Author: Mark Wells <mark at freeside.biz>
Date:   Wed Oct 7 14:18:15 2015 -0700

    #37098: convert one-shot email notices to use message templates

diff --git a/FS/FS/cust_main_Mixin.pm b/FS/FS/cust_main_Mixin.pm
index 3d05f84..867d43e 100644
--- a/FS/FS/cust_main_Mixin.pm
+++ b/FS/FS/cust_main_Mixin.pm
@@ -426,6 +426,18 @@ sub email_search_result {
   if ( $msgnum ) {
     $msg_template = qsearchs('msg_template', { msgnum => $msgnum } )
       or die "msgnum $msgnum not found\n";
+  } else {
+    $msg_template = FS::msg_template->new({
+        from_addr => $from,
+        msgname   => $subject, # maybe a timestamp also?
+        disabled  => 'D', # 'D'raft
+        # msgclass, maybe
+    });
+    $error = $msg_template->insert(
+      subject => $subject,
+      body    => $html_body,
+    );
+    return "$error (when creating draft template)" if $error;
   }
 
   my $sql_query = $class->search($param->{'search'});
@@ -446,7 +458,7 @@ sub email_search_result {
   my %sent_to = ();
 
   if ( !$msg_template ) {
-    # XXX create on the fly
+    die "email_search_result now requires a msg_template";
   }
 
   #eventually order+limit magic to reduce memory use?
@@ -516,6 +528,14 @@ sub email_search_result {
     }
   } # foreach $obj
 
+  # if the message template was created as "draft", change its status to
+  # "completed"
+  if ($msg_template->disabled eq 'D') {
+    $msg_template->set('disabled' => 'C');
+    my $error = $msg_template->replace;
+    warn "$error (setting draft message template status)" if $error;
+  }
+
   if(@retry_jobs) {
     # fail the job, but with a status message that makes it clear
     # something was sent.
diff --git a/FS/FS/msg_template.pm b/FS/FS/msg_template.pm
index 4940388..d17fd41 100644
--- a/FS/FS/msg_template.pm
+++ b/FS/FS/msg_template.pm
@@ -66,7 +66,9 @@ global template.
 
 =item bcc_addr - Bcc all mail to this address.
 
-=item disabled - disabled ('Y' or NULL).
+=item disabled - disabled (NULL for not-disabled and selectable, 'D' for a
+draft of a one-time message, 'C' for a completed one-time message, 'Y' for a
+normal template disabled by user action).
 
 =back
 
@@ -247,7 +249,7 @@ sub check {
     || $self->ut_text('msgname')
     || $self->ut_foreign_keyn('agentnum', 'agent', 'agentnum')
     || $self->ut_textn('mime_type')
-    || $self->ut_enum('disabled', [ '', 'Y' ] )
+    || $self->ut_enum('disabled', [ '', 'Y', 'D', 'S' ] )
     || $self->ut_textn('from_addr')
     || $self->ut_textn('bcc_addr')
     # fine for now, but change this to some kind of dynamic check if we
diff --git a/httemplate/misc/email-customers.html b/httemplate/misc/email-customers.html
index bffd0cf..8e28634 100644
--- a/httemplate/misc/email-customers.html
+++ b/httemplate/misc/email-customers.html
@@ -22,13 +22,13 @@ title - the title of the page
 no_search_fields - arrayref of additional fields that are not search parameters
 
 alternate_form - subroutine that returns alternate html for the initial form,
-replaces msgnum/from/subject/html_body/action inputs and submit button, not
+replaces msgnum/from/subject/body/action inputs and submit button, not
 used if an action is specified
 
 post_search_hook - sub hook for additional processing after search has been
 processed from cgi, gets passed options 'conf' and 'search' (a reference to
 the unfrozen %search hash), should be used to set msgnum or
-from/subject/html_body cgi params
+from/subject/body cgi params
 
 </%doc>
 % if ($popup) {
@@ -37,6 +37,7 @@ from/subject/html_body cgi params
 <& /elements/header.html, $title &>
 % }
 
+<& /elements/error.html &>
 
 <FORM NAME="OneTrueForm" ACTION="<% $form_action %>" METHOD="POST">
 <INPUT TYPE="hidden" NAME="table" VALUE="<% $table %>">
@@ -48,48 +49,40 @@ from/subject/html_body cgi params
 <INPUT TYPE="hidden" NAME="popup" VALUE="<% $popup %>">
 <INPUT TYPE="hidden" NAME="url" VALUE="<% $url | h %>">
 
-% if ( $cgi->param('action') eq 'send' ) { 
-
-    <FONT SIZE="+2">Sending notice</FONT>
+% if ( $cgi->param('preview') ) {
+%   # preview mode: at this point we have a msg_template (either "real" or
+%   # draft) and $html_body and $text_body contain the preview message.
+%   # give the user a chance to back out (by going back to edit mode).
 
+    <FONT SIZE="+2">Preview notice</FONT>
     <& /elements/progress-init.html,
                  'OneTrueForm',
-                 [ qw( search table from subject html_body text_body msgnum ) ],
+                 [ qw( search table msgnum ) ],
                  $process_url,
                  $pdest,
     &>
 
-% } elsif ( $cgi->param('action') eq 'preview' ) {
-
-    <FONT SIZE="+2">Preview notice</FONT>
-
-% }
-
-% if ( $cgi->param('action') ) {
-
     <TABLE CLASS="fsinnerbox">
-    <INPUT TYPE="hidden" NAME="msgnum" VALUE="<% scalar($cgi->param('msgnum')) %>">
-
-%   if ( $msg_template ) {
-      <& /elements/tr-fixed.html,
-                   'label'      => 'Template:',
-                   'value'      => $msg_template->msgname,
-      &>
-% }
+    <INPUT TYPE="hidden" NAME="msgnum" VALUE="<% $msg_template->msgnum %>">
+%   # kludge these through hidden inputs because they're not really part
+%   # of the template, but should be sticky during draft editing
+    <INPUT TYPE="hidden" NAME="from_name" VALUE="<% $cgi->param('from_name') %>">
+    <INPUT TYPE="hidden" NAME="from_addr" VALUE="<% $cgi->param('from_addr') %>">
+
+%   if ( !$msg_template->disabled ) {
+      <& /elements/tr-td-label.html, 'label' => 'Template:' &>
+        <td><% $msg_template->msgname |h %></td>
+      </tr>
+%   }
 
-      <& /elements/tr-fixed.html,
-                   'field'      => 'from',
-                   'label'      => 'From:',
-                   'value'      => $from,
-      &>
+      <& /elements/tr-td-label.html, 'label' => 'From:' &>
+        <td><% $from |h %></td>
+      </tr>
 
-      <& /elements/tr-fixed.html,
-                   'field'      => 'subject',
-                   'label'      => 'Subject:',
-                   'value'      => $subject,
-      &>
+      <& /elements/tr-td-label.html, 'label' => 'Subject:' &>
+        <td><% $subject |h %></td>
+      </tr>
 
-      <INPUT TYPE="hidden" NAME="html_body" VALUE="<% $html_body |h %>">
       <TR><TD COLSPAN=2> </TD></TR>
       <TR>
         <TH ALIGN="right" VALIGN="top">Message (HTML display): </TD>
@@ -101,7 +94,6 @@ from/subject/html_body cgi params
 %                         $html_body
 %                       )
 %                     );
-      <INPUT TYPE="hidden" NAME="text_body" VALUE="<% $text_body |h %>">
       <TR><TD COLSPAN=2> </TD></TR>
       <TR>
         <TH ALIGN="right" VALIGN="top">Message (Text display): </TD>
@@ -114,38 +106,37 @@ from/subject/html_body cgi params
 
     </TABLE>
 
-%   if ( $cgi->param('action') eq 'preview' ) {
+    <SCRIPT>
 
-      <SCRIPT>
+      function showtext() {
+        $('#email-message-text-view').css('display','none');
+        $('#email-message-text-hide').css('display','');
+        $('#email-message-text').slideDown();
+      }
 
-        function showtext() {
-          $('#email-message-text-view').css('display','none');
-          $('#email-message-text-hide').css('display','');
-          $('#email-message-text').slideDown();
-        }
-
-        function hidetext() {
-          $('#email-message-text-view').css('display','');
-          $('#email-message-text-hide').css('display','none');
-          $('#email-message-text').slideUp();
-        }
+      function hidetext() {
+        $('#email-message-text-view').css('display','');
+        $('#email-message-text-hide').css('display','none');
+        $('#email-message-text').slideUp();
+      }
 
-        function areyousure(href) {
-          return confirm("Send this notice to <% ($num_cust > 1) ? "$num_cust customers" : '1 customer' %> ?");
+      function areyousure(href) {
+        if (confirm("Send this notice to <% ($num_cust > 1) ? "$num_cust customers" : '1 customer' %> ?")) {
+          process();
         }
-      </SCRIPT>
+      }
+    </SCRIPT>
 
-      <BR>
-      <INPUT TYPE="hidden" NAME="action" VALUE="send">
-      <INPUT TYPE="submit" VALUE="Send notice" onClick="return areyousure()">
-    
-%   }
+    <BR>
+    <INPUT TYPE="submit" NAME="edit" VALUE="Edit">
+    <INPUT TYPE="button" VALUE="Send notice" onClick="areyousure()">
 
 % } elsif ($opt{'alternate_form'}) {
 
 <% &{$opt{'alternate_form'}}() %>
 
 % } else {
+%   # Edit mode.
 
 <SCRIPT TYPE="text/javascript">
 function toggle(obj) {
@@ -153,11 +144,20 @@ function toggle(obj) {
 }
 
 </SCRIPT>
+% if ( $msg_template and $msg_template->disabled ) {
+%   # if we've already established a draft template, don't let msgnum be changed
+    <& /elements/hidden.html,
+      field => 'msgnum',
+      curr_value => ($cgi->param('msgnum') || ''),
+    &>
+% } else {
 Template: 
     <& /elements/select-msg_template.html,
-         onchange => 'toggle(this)',
+        onchange   => 'toggle(this)',
+        curr_value => ($cgi->param('msgnum') || ''),
     &>
     <BR>
+% }
   <TABLE BGCOLOR="#cccccc" CELLSPACING=0 WIDTH="100%" id="table_no_template">
     <& /elements/tr-td-label.html, 'label' => 'From:' &>
       <TD><& /elements/input-text.html,
@@ -165,46 +165,41 @@ Template:
               'value' => $conf->config('invoice_from_name', $agent_virt_agentnum) ||
                          $conf->config('company_name', $agent_virt_agentnum), #?
               'size'  => 20,
+              'curr_value' => $cgi->param('from_name'),
           &> <\
           <& /elements/input-text.html,
               'field' => 'from_addr',
               'type'  => 'email', # HTML5, woot
               'value' => $conf->config('invoice_from', $agent_virt_agentnum),
               'size'  => 20,
+              'curr_value' => $cgi->param('from_addr'),
           &>></TD>
  
     <& /elements/tr-input-text.html,
                  'field' => 'subject',
                  'label' => 'Subject:',
                  'size'  => 50,
+                 'curr_value' => $subject,
     &>
 
     <TR>
       <TD ALIGN="right" VALIGN="top" STYLE="padding-top:3px">Message: </TD>
       <TD><& /elements/htmlarea.html, 
-               'field' => 'html_body',
+               'field' => 'body',
                'width' => 763,
+               'curr_value' => $body,
           &>
       </TD>
     </TR>
 
   </TABLE>
 
-%#Substitution vars:
-
-    <INPUT TYPE="hidden" NAME="action" VALUE="preview">
-    <INPUT TYPE="submit" VALUE="Preview notice">
+  <INPUT TYPE="submit" NAME="preview" VALUE="Preview notice">
 
 % } #end not action or alternate form
 
 </FORM>
 
-% if ( $cgi->param('action') eq 'send' ) {
-    <SCRIPT TYPE="text/javascript">
-      process();
-    </SCRIPT>
-% }
-
 <& /elements/footer.html &>
 
 <%init>
@@ -217,7 +212,7 @@ die "access denied"
   unless $FS::CurrentUser::CurrentUser->access_right($opt{'acl'});
 
 my $conf = FS::Conf->new;
-my @no_search_fields = qw( action table from subject html_body text_body popup url );
+my @no_search_fields = qw( table from subject html_body text_body popup url );
 
 my $form_action = $opt{'form_action'} || 'email-customers.html';
 my $process_url = $opt{'process_url'} || 'process/email-customers.html';
@@ -261,12 +256,26 @@ if ( $cgi->param('from') ) {
   $from = $cgi->param('from_addr');
 }
 
-my $subject = $cgi->param('subject') || '';
-my $html_body = $cgi->param('html_body') || '';
-
 my $msg_template = '';
+if ( $cgi->param('msgnum') =~ /^(\d+)$/ ) {
+  $msg_template = FS::msg_template->by_key($1)
+    or die "template not found: ".$cgi->param('msgnum');
+}
+
+my $subject = $cgi->param('subject');
+my $body = $cgi->param('body');
+my ($html_body, $text_body);
 
-if ( $cgi->param('action') eq 'preview' ) {
+if ( !$cgi->param('preview') ) {
+
+  # edit mode: initialize the fields from the saved draft, if there is one
+  if ( $msg_template and $msg_template->disabled eq 'D' ) {
+    my $content = $msg_template->content(''); # no localization on these yet
+    $subject ||= $content->subject;
+    $body ||= $content->body;
+  }
+
+} else {
 
   my $sql_query = "FS::$table"->search(\%search);
   my $count_query = delete($sql_query->{'count_query'});
@@ -277,10 +286,40 @@ if ( $cgi->param('action') eq 'preview' ) {
   my $count_arrayref = $count_sth->fetchrow_arrayref;
   $num_cust = $count_arrayref->[0];
 
-  if ( $cgi->param('msgnum') ) {
-    $msg_template = qsearchs('msg_template', 
-                             { msgnum => scalar($cgi->param('msgnum')) } )
-        or die "template not found: ".$cgi->param('msgnum');
+  if ( !$msg_template or $msg_template->disabled eq 'D' ) {
+    # then this is a one-off template; edit it in place
+    my $subject = $cgi->param('subject') || '';
+    my $body = $cgi->param('body') || '';
+
+    # create a draft template
+    $msg_template ||= FS::msg_template->new({
+      msgclass  => 'email',
+      disabled  => 'D',
+    });
+    # anyone have a better idea for msgname?
+    $msg_template->set('msgname' => "Notice " . DateTime->now->iso8601);
+    $msg_template->set('from_addr' => $from);
+    my %content = (
+      subject => $subject,
+      body    => $body,
+    );
+    my $error;
+    if ( $msg_template->msgnum ) {
+      $error = $msg_template->replace(%content);
+    } else {
+      $error = $msg_template->insert(%content);
+    }
+
+    if ( $error ) {
+      $cgi->param('error', $error);
+      $cgi->delete('preview'); # don't go on to preview stage yet
+      undef $msg_template;
+    }
+  }
+  # unless creating the msg_template failed, we now have one, so construct a
+  # preview message from the first customer/whatever in the search results
+
+  if ( $msg_template ) { 
     $sql_query->{'extra_sql'} .= ' LIMIT 1';
     $sql_query->{'select'} = "$table.*";
     $sql_query->{'order_by'} = '';

-----------------------------------------------------------------------

Summary of changes:
 FS/FS/cust_main_Mixin.pm             |   22 +++-
 FS/FS/msg_template.pm                |    6 +-
 httemplate/misc/email-customers.html |  191 ++++++++++++++++++++--------------
 3 files changed, 140 insertions(+), 79 deletions(-)




More information about the freeside-commits mailing list