summaryrefslogtreecommitdiff
path: root/FS/FS/cust_main.pm
diff options
context:
space:
mode:
Diffstat (limited to 'FS/FS/cust_main.pm')
-rw-r--r--FS/FS/cust_main.pm147
1 files changed, 121 insertions, 26 deletions
diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm
index 4fb4f52..f6b6862 100644
--- a/FS/FS/cust_main.pm
+++ b/FS/FS/cust_main.pm
@@ -558,13 +558,42 @@ sub insert {
$invoicing_list ||= $options{'invoicing_list'};
if ( $invoicing_list ) {
- $invoicing_list = join(',', @$invoicing_list) if ref $invoicing_list;
+ $invoicing_list = [ $invoicing_list ] if !ref($invoicing_list);
+
+ my $email = '';
+ foreach my $dest (@$invoicing_list ) {
+ if ($dest eq 'POST') {
+ $self->set('postal_invoice', 'Y');
+ } else {
+
+ my $contact_email = qsearchs('contact_email', { emailaddress => $dest });
+ if ( $contact_email ) {
+ my $cust_contact = FS::cust_contact->new({
+ contactnum => $contact_email->contactnum,
+ custnum => $self->custnum,
+ });
+ $cust_contact->set('invoice_dest', 'Y');
+ my $error = $cust_contact->contactnum ?
+ $cust_contact->replace : $cust_contact->insert;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "$error (linking to email address $dest)";
+ }
+
+ } else {
+ # this email address is not yet linked to any contact
+ $email .= ',' if length($email);
+ $email .= $dest;
+ }
+ }
+ }
+
my $contact = FS::contact->new({
'custnum' => $self->get('custnum'),
'last' => $self->get('last'),
'first' => $self->get('first'),
- 'emailaddress' => $invoicing_list,
- 'invoice_dest' => 'Y',
+ 'emailaddress' => $email,
+ 'invoice_dest' => 'Y', # yes, you can set this via the contact
});
my $error = $contact->insert;
if ( $error ) {
@@ -1365,40 +1394,106 @@ sub replace {
$invoicing_list ||= $options{invoicing_list};
+ my @contacts = map { $_->contact } $self->cust_contact;
+ # find a contact that matches the customer's name
+ my ($implicit_contact) = grep { $_->first eq $old->get('first')
+ and $_->last eq $old->get('last') }
+ @contacts;
+ $implicit_contact ||= FS::contact->new({
+ 'custnum' => $self->custnum,
+ 'locationnum' => $self->get('bill_locationnum'),
+ });
+
+ # for any of these that are already contact emails, link to the existing
+ # contact
if ( $invoicing_list ) {
my $email = '';
- foreach (@$invoicing_list) {
- if ($_ eq 'POST') {
+
+ # kind of like process_m2m on these, except:
+ # - the other side is two tables in a join
+ # - and we might have to create new contact_emails
+ # - and possibly a new contact
+ #
+ # Find existing invoice emails that aren't on the implicit contact.
+ # Any of these that are not on the new invoicing list will be removed.
+ my %old_email_cust_contact;
+ foreach my $cust_contact ($self->cust_contact) {
+ next if !$cust_contact->invoice_dest;
+ next if $cust_contact->contactnum == ($implicit_contact->contactnum || 0);
+
+ foreach my $contact_email ($cust_contact->contact->contact_email) {
+ $old_email_cust_contact{ $contact_email->emailaddress } = $cust_contact;
+ }
+ }
+
+ foreach my $dest (@$invoicing_list) {
+
+ if ($dest eq 'POST') {
+
$self->set('postal_invoice', 'Y');
+
+ } elsif ( exists($old_email_cust_contact{$dest}) ) {
+
+ delete $old_email_cust_contact{$dest}; # don't need to remove it, then
+
} else {
- $email .= ',' if length($email);
- $email .= $_;
+
+ # See if it belongs to some other contact; if so, link it.
+ my $contact_email = qsearchs('contact_email', { emailaddress => $dest });
+ if ( $contact_email
+ and $contact_email->contactnum != ($implicit_contact->contactnum || 0) ) {
+ my $cust_contact = qsearchs('cust_contact', {
+ contactnum => $contact_email->contactnum,
+ custnum => $self->custnum,
+ }) || FS::cust_contact->new({
+ contactnum => $contact_email->contactnum,
+ custnum => $self->custnum,
+ });
+ $cust_contact->set('invoice_dest', 'Y');
+ my $error = $cust_contact->custcontactnum ?
+ $cust_contact->replace : $cust_contact->insert;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "$error (linking to email address $dest)";
+ }
+
+ } else {
+ # This email address is not yet linked to any contact, so it will
+ # be added to the implicit contact.
+ $email .= ',' if length($email);
+ $email .= $dest;
+ }
+ }
+ }
+
+ foreach my $remove_dest (keys %old_email_cust_contact) {
+ my $cust_contact = $old_email_cust_contact{$remove_dest};
+ # These were not in the list of requested destinations, so take them off.
+ $cust_contact->set('invoice_dest', '');
+ my $error = $cust_contact->replace;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "$error (unlinking email address $remove_dest)";
}
}
- my @contacts = map { $_->contact } $self->cust_contact;
- # if possible, use a contact that matches the customer's name
- my ($contact) = grep { $_->first eq $old->get('first') and
- $_->last eq $old->get('last') }
- @contacts;
- $contact ||= FS::contact->new({
- 'custnum' => $self->custnum,
- 'locationnum' => $self->get('bill_locationnum'),
- });
- $contact->set('last', $self->get('last'));
- $contact->set('first', $self->get('first'));
- $contact->set('emailaddress', $email);
- $contact->set('invoice_dest', 'Y');
+
+ # make sure it keeps up with the changed customer name, if any
+ $implicit_contact->set('last', $self->get('last'));
+ $implicit_contact->set('first', $self->get('first'));
+ $implicit_contact->set('emailaddress', $email);
+ $implicit_contact->set('invoice_dest', 'Y');
+ $implicit_contact->set('custnum', $self->custnum);
my $error;
- if ( $contact->contactnum ) {
- $error = $contact->replace;
- } elsif ( length($email) ) { # don't create a new contact if email is empty
- $error = $contact->insert;
+ if ( $implicit_contact->contactnum ) {
+ $error = $implicit_contact->replace;
+ } elsif ( length($email) ) { # don't create a new contact if not needed
+ $error = $implicit_contact->insert;
}
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
- return $error;
+ return "$error (adding email address $email)";
}
}
@@ -2987,7 +3082,7 @@ sub invoicing_list_emailonly {
addl_from => ' JOIN contact USING (contactnum) '.
' JOIN contact_email USING (contactnum)',
hashref => { 'custnum' => $self->custnum, },
- extra_sql => q( AND invoice_dest = 'Y'),
+ extra_sql => q( AND cust_contact.invoice_dest = 'Y'),
});
}