diff options
author | Mark Wells <mark@freeside.biz> | 2016-04-30 18:07:50 -0700 |
---|---|---|
committer | Mark Wells <mark@freeside.biz> | 2016-05-02 13:24:53 -0700 |
commit | 755159a8654a2eda89badd1498f8def3a472cb15 (patch) | |
tree | 05908f7215c7a7f3f9a0b4b416e668b9a80f5338 /FS | |
parent | bd714630f4747b3f411ae53515a734e9e771c6b3 (diff) |
allow sending email to specific contact classes, #33316
Conflicts:
FS/FS/cust_main_Mixin.pm
FS/FS/msg_template/email.pm
httemplate/misc/email-customers.html
Diffstat (limited to 'FS')
-rw-r--r-- | FS/FS/cust_main.pm | 67 | ||||
-rw-r--r-- | FS/FS/cust_main_Mixin.pm | 24 | ||||
-rw-r--r-- | FS/FS/msg_template.pm | 22 |
3 files changed, 106 insertions, 7 deletions
diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index cfcd5f43f..ef3ab61a7 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -3363,6 +3363,73 @@ sub invoicing_list_emailonly_scalar { join(', ', $self->invoicing_list_emailonly); } +=item contact_list [ CLASSNUM, ... ] + +Returns a list of contacts (L<FS::contact> objects) for the customer. If +a list of contact classnums is given, returns only contacts in those +classes. If the pseudo-classnum 'invoice' is given, returns contacts that +are marked as invoice destinations. If '0' is given, also returns contacts +with no class. + +If no arguments are given, returns all contacts for the customer. + +=cut + +sub contact_list { + my $self = shift; + my $search = { + table => 'contact', + select => 'contact.*, cust_contact.invoice_dest', + addl_from => ' JOIN cust_contact USING (contactnum)', + extra_sql => ' WHERE cust_contact.custnum = '.$self->custnum, + }; + + my @orwhere; + my @classnums; + foreach (@_) { + if ( $_ eq 'invoice' ) { + push @orwhere, 'cust_contact.invoice_dest = \'Y\''; + } elsif ( $_ eq '0' ) { + push @orwhere, 'cust_contact.classnum is null'; + } elsif ( /^\d+$/ ) { + push @classnums, $_; + } else { + die "bad classnum argument '$_'"; + } + } + + if (@classnums) { + push @orwhere, 'cust_contact.classnum IN ('.join(',', @classnums).')'; + } + if (@orwhere) { + $search->{extra_sql} .= ' AND (' . + join(' OR ', map "( $_ )", @orwhere) . + ')'; + } + + qsearch($search); +} + +=item contact_list_email [ CLASSNUM, ... ] + +Same as L</contact_list>, but returns email destinations instead of contact +objects. + +=cut + +sub contact_list_email { + my $self = shift; + my @contacts = $self->contact_list(@_); + my @emails; + foreach my $contact (@contacts) { + foreach my $contact_email ($contact->contact_email) { + push @emails, + $contact->firstlast . ' <' . $contact_email->emailaddress . '>'; + } + } + @emails; +} + =item referral_custnum_cust_main Returns the customer who referred this customer (or the empty string, if diff --git a/FS/FS/cust_main_Mixin.pm b/FS/FS/cust_main_Mixin.pm index 96e520d52..94e6eaa29 100644 --- a/FS/FS/cust_main_Mixin.pm +++ b/FS/FS/cust_main_Mixin.pm @@ -380,6 +380,12 @@ HTML body Text body +=item to_contact_classnum + +The customer contact class (or classes, as a comma-separated list) to send +the message to. If unspecified, will be sent to any contacts that are marked +as invoice destinations (the equivalent of specifying 'invoice'). + =back Returns an error message, or false for success. @@ -403,6 +409,7 @@ sub email_search_result { my $subject = delete $param->{subject}; my $html_body = delete $param->{html_body}; my $text_body = delete $param->{text_body}; + my $to_contact_classnum = delete $param->{to_contact_classnum}; my $error = ''; my $job = delete $param->{'job'} @@ -455,10 +462,21 @@ sub email_search_result { %message = $msg_template->prepare( 'cust_main' => $cust_main, 'object' => $obj, + 'to_contact_classnum' => $to_contact_classnum, ); - } - else { - my @to = $cust_main->invoicing_list_emailonly; + + } else { + # 3.x: false laziness with msg_template.pm; on 4.x, all email notices + # are generated from templates and this case goes away + my @classes; + if ( $opt{'to_contact_classnum'} ) { + my $classnum = $opt{'to_contact_classnum'}; + @classes = ref($classnum) ? @$classnum : split(',', $classnum); + } + if (!@classes) { + @classes = ( 'invoice' ); + } + my @to = $cust_main->contact_list_email(@classes); next if !@to; %message = ( diff --git a/FS/FS/msg_template.pm b/FS/FS/msg_template.pm index 70e556924..50a9b3f27 100644 --- a/FS/FS/msg_template.pm +++ b/FS/FS/msg_template.pm @@ -383,12 +383,26 @@ sub prepare { my @to; if ( exists($opt{'to'}) ) { + @to = split(/\s*,\s*/, $opt{'to'}); + + } elsif ( $cust_main ) { + + my @classes; + if ( $opt{'to_contact_classnum'} ) { + my $classnum = $opt{'to_contact_classnum'}; + @classes = ref($classnum) ? @$classnum : split(',', $classnum); + } + if (!@classes) { + @classes = ( 'invoice' ); + } + @to = $cust_main->contact_list_email(@classes); + + } else { + + die 'no To: address or cust_main object specified'; + } - else { - @to = $cust_main->invoicing_list_emailonly; - } - # no warning when preparing with no destination my $from_addr = $self->from_addr; |