email opt-out flag, #19312
authorMark Wells <mark@freeside.biz>
Mon, 25 Mar 2013 22:47:34 +0000 (15:47 -0700)
committerMark Wells <mark@freeside.biz>
Mon, 25 Mar 2013 22:47:34 +0000 (15:47 -0700)
FS/FS/Schema.pm
FS/FS/cust_main.pm
FS/FS/part_event/Condition/message_email.pm [new file with mode: 0644]
httemplate/edit/cust_main/billing.html
httemplate/elements/menu.html
httemplate/misc/manage_cust_email.html [new file with mode: 0644]
httemplate/misc/process/manage_cust_email.html [new file with mode: 0644]
httemplate/misc/xmlhttp-cust_main-email_search.html [new file with mode: 0644]
httemplate/view/cust_main/billing.html

index 29f8ea4..cd42e4e 100644 (file)
@@ -1080,6 +1080,7 @@ sub tables_hashref {
         'locale', 'varchar', 'NULL', 16, '', '', 
         'calling_list_exempt', 'char', 'NULL', 1, '', '',
         'invoice_noemail', 'char', 'NULL', 1, '', '',
+        'message_noemail', 'char', 'NULL', 1, '', '',
         'bill_locationnum', 'int', 'NULL', '', '', '',
         'ship_locationnum', 'int', 'NULL', '', '', '',
       ],
index 3e5d4c1..2a4602e 100644 (file)
@@ -1778,9 +1778,10 @@ sub check {
     || $self->ut_floatn('credit_limit')
     || $self->ut_numbern('billday')
     || $self->ut_numbern('prorate_day')
-    || $self->ut_enum('edit_subject', [ '', 'Y' ] )
-    || $self->ut_enum('calling_list_exempt', [ '', 'Y' ] )
-    || $self->ut_enum('invoice_noemail', [ '', 'Y' ] )
+    || $self->ut_flag('edit_subject')
+    || $self->ut_flag('calling_list_exempt')
+    || $self->ut_flag('invoice_noemail')
+    || $self->ut_flag('message_noemail')
     || $self->ut_enum('locale', [ '', FS::Locales->locales ])
   ;
 
diff --git a/FS/FS/part_event/Condition/message_email.pm b/FS/FS/part_event/Condition/message_email.pm
new file mode 100644 (file)
index 0000000..7cceba6
--- /dev/null
@@ -0,0 +1,22 @@
+package FS::part_event::Condition::message_email;
+use base qw( FS::part_event::Condition );
+use strict;
+
+sub description {
+  'Customer allows email notices'
+}
+
+sub condition {
+  my( $self, $object ) = @_;
+  my $cust_main = $self->cust_main($object);
+
+  $cust_main->message_noemail ? 0 : 1;
+}
+
+sub condition_sql {
+  my( $self, $table ) = @_;
+
+  "cust_main.message_noemail IS NULL"
+}
+
+1;
index 6ba73ad..5a66f0a 100644 (file)
         <% $conf->exists('cust_main-require_invoicing_list_email', $agentnum) 
             ? $r : '' %>Email address(es)
       </TD>
-      <TD WIDTH="408"><INPUT TYPE="text" NAME="invoicing_list" VALUE="<% join(', ', grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list ) %>"></TD>
+      <TD WIDTH="408"><INPUT TYPE="text" NAME="invoicing_list" VALUE="<% join(', ', grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list ) %>">
+      <INPUT TYPE="checkbox" NAME="message_noemail" VALUE="Y" <%
+        ( $cust_main->message_noemail eq 'Y' )
+          ? 'CHECKED'
+          : ''
+        %>> <% emt('Do not send notices') %>
+      </TD>
     </TR>
 % }
 
index 00c43bb..14d36c3 100644 (file)
@@ -464,6 +464,8 @@ $tools_menu{'Job Queue'} =  [ $fsurl.'search/queue.html', 'View pending job queu
   if $curuser->access_right('Job queue');
 $tools_menu{'Ticketing'} = [ \%tools_ticketing, 'Ticketing tools' ]
   if $conf->config('ticket_system');
+$tools_menu{'Customer email settings'} = [ $fsurl.'misc/manage_cust_email.html' ]
+  if $curuser->access_right('Edit customer');
 $tools_menu{'Business card scan'} = [ $fsurl.'edit/prospect_main-upload.html' ]
   if $curuser->access_right('New prospect');
 $tools_menu{'Time Queue'} =  [ $fsurl.'search/report_timeworked.html', 'View pending support time' ]
diff --git a/httemplate/misc/manage_cust_email.html b/httemplate/misc/manage_cust_email.html
new file mode 100644 (file)
index 0000000..3ece459
--- /dev/null
@@ -0,0 +1,106 @@
+<& /elements/header.html, 'Manage customer email settings' &>
+<STYLE TYPE="text/css">
+.hidden { display: none }
+</STYLE>
+<& /elements/xmlhttp.html,
+    url => $p.'misc/xmlhttp-cust_main-email_search.html',
+    subs => ['email_search']
+&>
+<SCRIPT TYPE="text/javascript">
+
+function receive_search(result) {
+  var recs = JSON.parse(result);
+  var tbody = document.getElementById('tbody_results');
+  var j = tbody.rows.length;
+  for(var i = 0; i < j; i++) {
+    tbody.deleteRow(tbody.rows[i]);
+  }
+  if (recs.length > 0) {
+    for(var i = 0; i < recs.length; i++) {
+      var rec = recs[i];
+      var row = tbody.insertRow(i);
+      row.style.backgroundColor = (i % 2 ? '#eeeeee' : '#ffffff');
+
+      var cell = row.insertCell(0); // custnum
+      cell.appendChild( document.createTextNode(rec[0]) );
+      cell = row.insertCell(1);     // customer name
+      cell.appendChild( document.createTextNode(rec[1]) );
+      cell = row.insertCell(2);     // email
+      cell.appendChild( document.createTextNode(rec[2]) );
+
+      cell = row.insertCell(3);     // invoice_email
+      var input = document.createElement('INPUT');
+      input.type = 'hidden';
+      input.name = 'custnum';
+      input.value = rec[0];
+      cell.appendChild(input);
+
+      input = document.createElement('INPUT');
+      input.type = 'checkbox';
+      input.name = 'custnum' + rec[0] + '_invoice_email';
+      input.value = 'Y';
+      input.checked = (rec[3] != 'Y');
+      cell.appendChild(input);
+      cell.style.textAlign = 'center';
+      
+      cell = row.insertCell(4);     // message_email
+      input = document.createElement('INPUT');
+      input.type = 'checkbox';
+      input.name = 'custnum' + rec[0] + '_message_email';
+      input.value = 'Y';
+      input.checked = (rec[4] != 'Y');
+      cell.appendChild(input);
+      cell.style.textAlign = 'center';
+    }
+    document.getElementById('div_found').style.display = '';
+  } else {
+    document.getElementById('div_notfound').style.display = '';
+  }
+}
+
+function start_search() {
+  document.getElementById('div_found').style.display = 'none';
+  document.getElementById('div_notfound').style.display = 'none';
+  var email = document.getElementById('input_email').value;
+  email_search(email, receive_search);
+}
+% if ( $cgi->param('search') ) {
+window.onload = start_search;
+% }
+</SCRIPT>
+<FORM ACTION="<%$p%>misc/process/manage_cust_email.html" METHOD="POST">
+<DIV>
+% if ( $cgi->param('done') ) {
+<P STYLE="font-weight: bold; color: #00ff00">Changes saved.</P>
+% } elsif ( $cgi->param('error') ) {
+<P STYLE="font-weight: bold; color: #ff0000"><% $cgi->param('error') |h %></P>
+% }
+  Email address: 
+  <INPUT TYPE="text" ID="input_email" NAME="search"\
+         VALUE="<% $cgi->param('search') |h %>">
+  <INPUT TYPE="button" onclick="start_search()" VALUE="find">
+</DIV>
+<DIV ID="div_notfound" STYLE="display: none; padding: 1em">
+No matching email addresses found.
+</DIV>
+<DIV ID="div_found" STYLE="display: none">
+<TABLE CLASS="grid" STYLE="border-spacing: 0px">
+  <THEAD>
+    <TR STYLE="background-color: #dddddd">
+      <TH>#</TH>
+      <TH>Customer</TH>
+      <TH>Email</TH>
+      <TH>Send invoices</TH>
+      <TH>Send other notices</TH>
+    </TR>
+  </THEAD>
+  <TBODY ID="tbody_results"></TBODY>
+</TABLE>
+<INPUT TYPE="submit" VALUE="Save changes">
+</FORM>
+<& /elements/footer.html &>
+<%init>
+die "access denied"
+  unless $FS::CurrentUser::CurrentUser->access_right('Edit customer');
+
+</%init>
diff --git a/httemplate/misc/process/manage_cust_email.html b/httemplate/misc/process/manage_cust_email.html
new file mode 100644 (file)
index 0000000..5bf1470
--- /dev/null
@@ -0,0 +1,32 @@
+<% $cgi->redirect($fsurl.'misc/manage_cust_email.html?' .
+                  $cgi->query_string) %>
+<%init>
+die "access denied"
+  unless $FS::CurrentUser::CurrentUser->access_right('Edit customer');
+
+my $error;
+foreach my $custnum ($cgi->param('custnum')) {
+  my $cust = FS::cust_main->by_key($custnum)
+    or die "customer not found: $custnum\n";
+  my $new_invoice_noemail = 
+    $cgi->param('custnum'.$custnum.'_invoice_email') ? '' : 'Y';
+  my $new_message_noemail =
+    $cgi->param('custnum'.$custnum.'_message_email') ? '' : 'Y';
+  if ( $new_invoice_noemail ne $cust->invoice_noemail
+    or $new_message_noemail ne $cust->message_noemail ) {
+
+    $cust->set('invoice_noemail', $new_invoice_noemail);
+    $cust->set('message_noemail', $new_message_noemail);
+    $error ||= $cust->replace;
+
+  }
+  $cgi->delete('custnum'.$custnum.'_invoice_email');
+  $cgi->delete('custnum'.$custnum.'_message_email');
+}
+$cgi->delete('custnum');
+if ( $error ) {
+  $cgi->param('error' => $error); # probably unnecessary...
+} else {
+  $cgi->param('done' => 1) unless $error;
+}
+</%init>
diff --git a/httemplate/misc/xmlhttp-cust_main-email_search.html b/httemplate/misc/xmlhttp-cust_main-email_search.html
new file mode 100644 (file)
index 0000000..d8c8ef4
--- /dev/null
@@ -0,0 +1,29 @@
+<% JSON::to_json(\@result) %>\
+<%init>
+die 'access denied'
+  unless $FS::CurrentUser::CurrentUser->access_right('Edit customer');
+
+my $sub = $cgi->param('sub');
+my $email = $cgi->param('arg');
+my @where = (
+  "cust_main_invoice.dest != 'POST'",
+  "cust_main_invoice.dest LIKE ".dbh->quote('%'.$email.'%'),
+  $FS::CurrentUser::CurrentUser->agentnums_sql(table => 'cust_main'),
+);
+my @cust_main = qsearch({
+  'table'     => 'cust_main',
+  'select'    => 'cust_main.*, cust_main_invoice.dest',
+  'addl_from' => 'JOIN cust_main_invoice USING (custnum)',
+  'extra_sql' => 'WHERE '.join(' AND ', @where),
+});
+
+my @result = map {
+  [ $_->custnum,
+    $_->name,
+    $_->dest,
+    $_->invoice_noemail,
+    $_->message_noemail,
+  ]
+} @cust_main;
+
+</%init>
index 5c46803..b863a73 100644 (file)
   <TD ALIGN="right"><% mt('Email address(es)') |h %></TD>
   <TD BGCOLOR="#ffffff">
     <% join(', ', grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list ) || $no %>
+%   if ( $cust_main->message_noemail ) {
+    <BR>
+    <SPAN STYLE="font-size: small"><% emt('(do not send notices)') %></SPAN>
+%   }
   </TD>
 </TR>
 % }