X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=FS%2FFS%2Fcontact.pm;h=26f39eda509b99b005a6912f3b0160fc0d19dadf;hp=81dfdbc015ef889213a6b262e1a067b57648f61f;hb=HEAD;hpb=d5988a9f7a3617de33da3058f2e9f1151b24420e diff --git a/FS/FS/contact.pm b/FS/FS/contact.pm index 81dfdbc01..26f39eda5 100644 --- a/FS/FS/contact.pm +++ b/FS/FS/contact.pm @@ -160,70 +160,71 @@ sub insert { $self->$_(''); } - #look for an existing contact with this email address + + ## check for an existing contact with this email address other than current customer + ## if found, just add that contact to cust_contact with link_hash credentials + ## as email can not be tied to two contacts. + my $no_new_contact; my $existing_contact = ''; + my @contact_emails = (); + my %contact_nums = (); + if ( $self->get('emailaddress') =~ /\S/ ) { - - my %existing_contact = (); foreach my $email ( split(/\s*,\s*/, $self->get('emailaddress') ) ) { - my $contact_email = qsearchs('contact_email', { emailaddress=>$email } ) - or next; + my $contact_email = qsearchs('contact_email', { emailaddress=>$email } ); + unless ($contact_email) { push @contact_emails, $email; next; } my $contact = $contact_email->contact; - $existing_contact{ $contact->contactnum } = $contact; + if ($contact->contactnum eq $self->contactnum) { + push @contact_emails, $email; + } + else { + $contact_nums{$contact->contactnum} = '1'; + } } - if ( scalar( keys %existing_contact ) > 1 ) { - $dbh->rollback if $oldAutoCommit; - return 'Multiple email addresses specified '. - ' that already belong to separate contacts'; - } elsif ( scalar( keys %existing_contact ) ) { - ($existing_contact) = values %existing_contact; - } + my $emails = join(' , ', @contact_emails); + $self->emailaddress($emails); + + $no_new_contact = '1' unless $self->emailaddress; } my $error; - if ( $existing_contact ) { - - $self->$_($existing_contact->$_()) - for qw( contactnum _password _password_encoding ); - $error = $self->SUPER::replace($existing_contact); - - } else { - - $error = $self->SUPER::insert; - - } + $error = $self->SUPER::insert unless $no_new_contact; if ( $error ) { $dbh->rollback if $oldAutoCommit; return $error; } + $contact_nums{$self->contactnum} = '1' if $self->contactnum; + my $cust_contact = ''; # if $self->custnum was set, then the customer-specific properties # (custnum, classnum, invoice_dest, selfservice_access, comment) are in # pseudo-fields, and are now in %link_hash. otherwise, ignore all those # fields. if ( $custnum ) { - my %hash = ( 'contactnum' => $self->contactnum, - 'custnum' => $custnum, - ); - $cust_contact = qsearchs('cust_contact', \%hash ) - || new FS::cust_contact { %hash, %link_hash }; - my $error = $cust_contact->custcontactnum ? $cust_contact->replace + foreach my $contactnum (keys %contact_nums) { + my %hash = ( 'contactnum' => $contactnum, + 'custnum' => $custnum, + ); + $cust_contact = qsearchs('cust_contact', \%hash ) + || new FS::cust_contact { %hash, %link_hash }; + my $error = $cust_contact->custcontactnum ? $cust_contact->replace : $cust_contact->insert; - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return $error; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } } } - if ( $prospectnum ) { + if ( $prospectnum && !$no_new_contact) { my %hash = ( 'contactnum' => $self->contactnum, 'prospectnum' => $prospectnum, ); @@ -238,6 +239,7 @@ sub insert { } } + unless ($no_new_contact) { foreach my $pf ( grep { /^phonetypenum(\d+)$/ && $self->get($_) =~ /\S/ } keys %{ $self->hashref } ) { $pf =~ /^phonetypenum(\d+)$/ or die "wtf (daily, the)"; @@ -256,6 +258,7 @@ sub insert { return $error; } } + } if ( $self->get('emailaddress') =~ /\S/ ) { @@ -434,14 +437,50 @@ sub replace { my $prospectnum = $self->prospectnum; $self->prospectnum(''); my $custnum = $self->custnum; - $self->custnum(''); + $self->custnum(''); $old->custnum(''); # remove because now stored cust_contact my %link_hash = (); for (qw( classnum comment selfservice_access invoice_dest message_dest )) { $link_hash{$_} = $self->get($_); + $old->$_(''); ##remove values from old record, causes problem with history $self->$_(''); } + ## check for an existing contact with this email address other than current customer + ## if found, just add that contact to cust_contact with link_hash credentials + ## as email can not be tied to two contacts. + my @contact_emails = (); + my %contact_nums = (); + $contact_nums{$self->contactnum} = '1' if $self->contactnum; + if ( $self->get('emailaddress') =~ /\S/ ) { + + foreach my $email ( split(/\s*,\s*/, $self->get('emailaddress') ) ) { + + my $contact_email = qsearchs('contact_email', { emailaddress=>$email } ); + unless ($contact_email) { push @contact_emails, $email; next; } + + my $contact = $contact_email->contact; + if ($contact->contactnum eq $self->contactnum) { + push @contact_emails, $email; + } + else { + $contact_nums{$contact->contactnum} = '1'; + } + + } + + ## were all emails duplicates? if so reset original emails + if (scalar @contact_emails < 1 && scalar (keys %contact_nums) > 1) { + foreach (qsearch('contact_email', {'contactnum' => $self->contactnum})) { + push @contact_emails, $_->emailaddress; + } + } + + my $emails = join(' , ', @contact_emails); + $self->emailaddress($emails); + + } + my $error = $self->SUPER::replace($old); if ( $old->_password ne $self->_password ) { $error ||= $self->insert_password_history; @@ -457,20 +496,24 @@ sub replace { # pseudo-fields, and are now in %link_hash. otherwise, ignore all those # fields. if ( $custnum ) { - my %hash = ( 'contactnum' => $self->contactnum, - 'custnum' => $custnum, - ); - my $error; - if ( $cust_contact = qsearchs('cust_contact', \%hash ) ) { - $cust_contact->$_($link_hash{$_}) for keys %link_hash; - $error = $cust_contact->replace; - } else { - $cust_contact = new FS::cust_contact { %hash, %link_hash }; - $error = $cust_contact->insert; - } - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return $error; + + foreach my $contactnum (keys %contact_nums) { + + my %hash = ( 'contactnum' => $contactnum, + 'custnum' => $custnum, + ); + my $error; + if ( $cust_contact = qsearchs('cust_contact', \%hash ) ) { + $cust_contact->$_($link_hash{$_}) for keys %link_hash; + $error = $cust_contact->replace; + } else { + $cust_contact = new FS::cust_contact { %hash, %link_hash }; + $error = $cust_contact->insert; + } + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } } } @@ -533,30 +576,38 @@ sub replace { if ( defined($self->hashref->{'emailaddress'}) ) { - #ineffecient but whatever, how many email addresses can there be? - + my %contact_emails = (); foreach my $contact_email ( $self->contact_email ) { - my $error = $contact_email->delete; - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return $error; - } + $contact_emails{$contact_email->emailaddress} = '1'; } foreach my $email ( split(/\s*,\s*/, $self->get('emailaddress') ) ) { - my $contact_email = new FS::contact_email { - 'contactnum' => $self->contactnum, - 'emailaddress' => $email, - }; - $error = $contact_email->insert; - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return $error; + unless ($contact_emails{$email}) { + my $contact_email = new FS::contact_email { + 'contactnum' => $self->contactnum, + 'emailaddress' => $email, + }; + $error = $contact_email->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } } + else { delete($contact_emails{$email}); } } + foreach my $contact_email ( $self->contact_email ) { + if ($contact_emails{$contact_email->emailaddress}) { + my $error = $contact_email->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + } + } unless ( $skip_fuzzyfiles ) { #unless ( $import || $skip_fuzzyfiles ) { @@ -777,7 +828,38 @@ or there isn't one, returns the empty string. =cut sub by_selfservice_email { - my($class, $email) = @_; + my($class, $email, $case_insensitive) = @_; + + my $email_search = "emailaddress = '".$email."'"; + $email_search = "LOWER(emailaddress) = LOWER('".$email."')" if $case_insensitive; + + my $contact_email = qsearchs({ + 'table' => 'contact_email', + 'addl_from' => ' LEFT JOIN contact USING ( contactnum ) ', + 'extra_sql' => " + WHERE $email_search + AND ( contact.disabled IS NULL ) + AND EXISTS ( SELECT 1 FROM cust_contact + WHERE contact.contactnum = cust_contact.contactnum + AND cust_contact.selfservice_access = 'Y' + ) + ", + }) or return ''; + + $contact_email->contact; + +} + +=item by_selfservice_email_custnum EMAILADDRESS, CUSTNUM + +Alternate search constructor (class method). Given an email address and custnum, returns +the contact for that address and custnum. If that contact doesn't have selfservice access, +or there isn't one, returns the empty string. + +=cut + +sub by_selfservice_email_custnum { + my($class, $email, $custnum) = @_; my $contact_email = qsearchs({ 'table' => 'contact_email', @@ -788,6 +870,7 @@ sub by_selfservice_email { AND EXISTS ( SELECT 1 FROM cust_contact WHERE contact.contactnum = cust_contact.contactnum AND cust_contact.selfservice_access = 'Y' + AND cust_contact.custnum = $custnum ) ", }) or return '';