summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS/cust_main/Search.pm133
-rw-r--r--httemplate/elements/searchbar-cust_main.html2
-rw-r--r--httemplate/search/contact.html30
-rwxr-xr-xhttemplate/search/cust_main.html13
-rw-r--r--httemplate/search/elements/options_cust_contacts.html36
-rwxr-xr-xhttemplate/search/report_cust_main.html8
6 files changed, 153 insertions, 69 deletions
diff --git a/FS/FS/cust_main/Search.pm b/FS/FS/cust_main/Search.pm
index 68471ec30..2ec87cd14 100644
--- a/FS/FS/cust_main/Search.pm
+++ b/FS/FS/cust_main/Search.pm
@@ -93,7 +93,7 @@ sub smart_search {
my $phonenum = "$1$2$3";
#my $extension = $4;
- #cust_main phone numbers
+ #cust_main phone numbers and contact phone number
push @cust_main, qsearch( {
'table' => 'cust_main',
'hashref' => { %options },
@@ -102,20 +102,12 @@ sub smart_search {
join(' OR ', map "$_ = '$phonen'",
qw( daytime night mobile fax )
).
+ " OR phonenum = '$phonenum' ".
' ) '.
" AND $agentnums_sql", #agent virtualization
+ 'addl_from' => ' left join cust_contact using (custnum) left join contact_phone using (contactnum) ',
} );
- #contact phone numbers
- push @cust_main,
- grep $agentnums_href->{$_->agentnum}, #agent virt
- grep $_, #skip contacts that don't have cust_main records
- map $_->contact->cust_main,
- qsearch({
- 'table' => 'contact_phone',
- 'hashref' => { 'phonenum' => $phonenum },
- });
-
unless ( @cust_main || $phonen =~ /x\d+$/ ) { #no exact match
#try looking for matches with extensions unless one was specified
@@ -136,28 +128,20 @@ sub smart_search {
}
- if ( $search =~ /@/ ) { #email address
-
- # invoicing email address
- push @cust_main,
- grep $agentnums_href->{$_->agentnum}, #agent virt
- map $_->cust_main,
- qsearch( {
- 'table' => 'cust_main_invoice',
- 'hashref' => { 'dest' => $search },
- }
- );
-
- # contact email address
- push @cust_main,
- grep $agentnums_href->{$_->agentnum}, #agent virt
- grep $_, #skip contacts that don't have cust_main records
- map $_->contact->cust_main,
- qsearch( {
- 'table' => 'contact_email',
- 'hashref' => { 'emailaddress' => $search },
- }
- );
+ if ( $search =~ /@/ ) { #email address from cust_main_invoice and contact_email
+
+ push @cust_main, qsearch( {
+ 'table' => 'cust_main',
+ 'hashref' => { %options },
+ 'extra_sql' => ( scalar(keys %options) ? ' AND ' : ' WHERE ' ).
+ ' ( '.
+ join(' OR ', map "$_ = '$search'",
+ qw( dest emailaddress )
+ ).
+ ' ) '.
+ " AND $agentnums_sql", #agent virtualization
+ 'addl_from' => ' left join cust_main_invoice using (custnum) left join cust_contact using (custnum) left join contact_email using (contactnum) ',
+ } );
# custnum search (also try agent_custid), with some tweaking options if your
# legacy cust "numbers" have letters
@@ -281,8 +265,8 @@ sub smart_search {
} elsif ( ! $NameParse->parse($value) ) {
my %name = $NameParse->components;
- $first = $name{'given_name_1'} || $name{'initials_1'}; #wtf NameParse, Ed?
- $last = $name{'surname_1'};
+ $first = lc($name{'given_name_1'}) || $name{'initials_1'}; #wtf NameParse, Ed?
+ $last = lc($name{'surname_1'});
}
@@ -292,28 +276,18 @@ sub smart_search {
#exact
my $sql = scalar(keys %options) ? ' AND ' : ' WHERE ';
- $sql .= "( LOWER(cust_main.last) = $q_last AND LOWER(cust_main.first) = $q_first )";
+ $sql .= "( (LOWER(cust_main.last) = $q_last AND LOWER(cust_main.first) = $q_first)
+ OR (LOWER(contact.last) = $q_last AND LOWER(contact.first) = $q_first) )";
- #cust_main
+ #cust_main and contacts
push @cust_main, qsearch( {
'table' => 'cust_main',
- 'hashref' => \%options,
+ 'select' => 'cust_main.*, cust_contact.*, contact.contactnum, contact.last as contact_last, contact.first as contact_first, contact.title',
+ 'hashref' => { %options },
'extra_sql' => "$sql AND $agentnums_sql", #agent virtualization
+ 'addl_from' => ' left join cust_contact on cust_main.custnum = cust_contact.custnum left join contact using (contactnum) ',
} );
- #contacts
- push @cust_main,
- grep $agentnums_href->{$_->agentnum}, #agent virt
- grep $_, #skip contacts that don't have cust_main records
- map $_->cust_main,
- qsearch( {
- 'table' => 'contact',
- 'hashref' => { 'first' => $first,
- 'last' => $last,
- },
- }
- );
-
# or it just be something that was typed in... (try that in a sec)
}
@@ -326,7 +300,9 @@ sub smart_search {
OR LOWER(cust_main.last) = $q_value
OR LOWER(cust_main.company) = $q_value
OR LOWER(cust_main.ship_company) = $q_value
- ";
+ OR LOWER(contact.first) = $q_value
+ OR LOWER(contact.last) = $q_value
+ )";
#address1 (yes, it's a kludge)
$sql .= " OR EXISTS (
@@ -336,20 +312,12 @@ sub smart_search {
)"
if $conf->exists('address1-search');
- #contacts (look, another kludge)
- $sql .= " OR EXISTS ( SELECT 1 FROM contact
- WHERE ( LOWER(contact.first) = $q_value
- OR LOWER(contact.last) = $q_value
- )
- AND contact.custnum IS NOT NULL
- AND contact.custnum = cust_main.custnum
- )
- ) ";
-
push @cust_main, qsearch( {
'table' => 'cust_main',
- 'hashref' => \%options,
+ 'select' => 'cust_main.*, cust_contact.*, contact.contactnum, contact.last as contact_last, contact.first as contact_first, contact.title',
+ 'hashref' => { %options },
'extra_sql' => "$sql AND $agentnums_sql", #agent virtualization
+ 'addl_from' => 'left join cust_contact on cust_main.custnum = cust_contact.custnum left join contact using (contactnum) ',
} );
#no exact match, trying substring/fuzzy
@@ -1085,6 +1053,45 @@ sub search {
my @extra_fields = ();
my @extra_sort_fields = ();
+ ## search contacts
+ if ($params->{'contacts'}) {
+ my $contact_params = $params->{'contacts'};
+
+ $addl_from .=
+ ' LEFT JOIN cust_contact ON ( cust_main.custnum = cust_contact.custnum ) ';
+
+ if ($contact_params->{'contacts_firstname'} || $contact_params->{'contacts_lastname'}) {
+ $addl_from .= ' LEFT JOIN contact ON ( cust_contact.contactnum = contact.contactnum ) ';
+ my $first_query = " AND contact.first = '" . $contact_params->{'contacts_firstname'} . "'"
+ unless !$contact_params->{'contacts_firstname'};
+ my $last_query = " AND contact.last = '" . $contact_params->{'contacts_lastname'} . "'"
+ unless !$contact_params->{'contacts_lastname'};
+ $extra_sql .= " AND ( '1' $first_query $last_query )";
+ }
+
+ if ($contact_params->{'contacts_email'}) {
+ $addl_from .= ' LEFT JOIN contact_email ON ( cust_contact.contactnum = contact_email.contactnum ) ';
+ $extra_sql .= " AND ( contact_email.emailaddress = '" . $contact_params->{'contacts_email'} . "' )";
+ }
+
+ if ($contact_params->{'contacts_homephone'} || $contact_params->{'contacts_workphone'} || $contact_params->{'contacts_mobilephone'}) {
+ $addl_from .= ' LEFT JOIN contact_phone ON ( cust_contact.contactnum = contact_phone.contactnum ) ';
+ my $contacts_mobilephone;
+ foreach my $phone (qw( contacts_homephone contacts_workphone contacts_mobilephone )) {
+ (my $num = $contact_params->{$phone}) =~ s/\W//g;
+ if ( $num =~ /^1?(\d{3})(\d{3})(\d{4})(\d*)$/ ) { $contact_params->{$phone} = "$1$2$3"; }
+ }
+ my $home_query = " AND ( contact_phone.phonetypenum = '2' AND contact_phone.phonenum = '" . $contact_params->{'contacts_homephone'} . "' )"
+ unless !$contact_params->{'contacts_homephone'};
+ my $work_query = " AND ( contact_phone.phonetypenum = '1' AND contact_phone.phonenum = '" . $contact_params->{'contacts_workphone'} . "' )"
+ unless !$contact_params->{'contacts_workphone'};
+ my $mobile_query = " AND ( contact_phone.phonetypenum = '3' AND contact_phone.phonenum = '" . $contact_params->{'contacts_mobilephone'} . "' )"
+ unless !$contact_params->{'contacts_mobilephone'};
+ $extra_sql .= " AND ( '1' $home_query $work_query $mobile_query )";
+ }
+
+ }
+
if ($params->{'flattened_pkgs'}) {
#my $pkg_join = '';
diff --git a/httemplate/elements/searchbar-cust_main.html b/httemplate/elements/searchbar-cust_main.html
index 5bfef484a..7f8f9d850 100644
--- a/httemplate/elements/searchbar-cust_main.html
+++ b/httemplate/elements/searchbar-cust_main.html
@@ -26,7 +26,7 @@ my $curuser = $FS::CurrentUser::CurrentUser;
my $menu_position = $curuser->option('menu_position') || 'top';
my $cust_width = 246;
-my $cust_label = '(cust #, name, company';
+my $cust_label = '(cust #, name, company, email';
if ( $conf->exists('address1-search') ) {
$cust_label .= ', address';
$cust_width += 56;
diff --git a/httemplate/search/contact.html b/httemplate/search/contact.html
index 759f09521..5f02fef2f 100644
--- a/httemplate/search/contact.html
+++ b/httemplate/search/contact.html
@@ -29,6 +29,30 @@ my $email_sub = sub {
join(', ', map $_->emailaddress, @contact_email);
};
+my $work_phone_sub = sub {
+ my $contact = shift;
+ my $phone_type = qsearchs('phone_type', { 'typename' => 'Work' });
+ #can't because contactnum is in the wrong field
+ my @contact_workphone = qsearch('contact_phone', { 'contactnum' => $contact->contact_contactnum, 'phonetypenum' => $phone_type->phonetypenum } );
+ join(', ', map $_->phonenum, @contact_workphone);
+};
+
+my $mobile_phone_sub = sub {
+ my $contact = shift;
+ my $phone_type = qsearchs('phone_type', { 'typename' => 'Mobile' });
+ #can't because contactnum is in the wrong field
+ my @contact_mobilephone = qsearch('contact_phone', { 'contactnum' => $contact->contact_contactnum, 'phonetypenum' => $phone_type->phonetypenum } );
+ join(', ', map $_->phonenum, @contact_mobilephone);
+};
+
+my $home_phone_sub = sub {
+ my $contact = shift;
+ my $phone_type = qsearchs('phone_type', { 'typename' => 'Home' });
+ #can't because contactnum is in the wrong field
+ my @contact_homephone = qsearch('contact_phone', { 'contactnum' => $contact->contact_contactnum, 'phonetypenum' => $phone_type->phonetypenum } );
+ join(', ', map $_->phonenum, @contact_homephone);
+};
+
my $link; #for closure in this sub, we'll define it later
my $contact_classname_sub = sub {
my $contact = shift;
@@ -44,9 +68,9 @@ my $contact_classname_sub = sub {
$X_contact->contact_classname;
};
-my @header = ( 'First', 'Last', 'Title', 'Email', 'Type' );
-my @fields = ( 'first', 'last', 'title', $email_sub, $contact_classname_sub );
-my @links = ( '', '', '', '', '', );
+my @header = ( 'First', 'Last', 'Title', 'Email', 'Work Phone', 'Mobile Phone', 'Home Phone', 'Type' );
+my @fields = ( 'first', 'last', 'title', $email_sub, $work_phone_sub, $mobile_phone_sub, $home_phone_sub, $contact_classname_sub );
+my @links = ( '', '', '', '', '', '', '', '', );
my $company_link = '';
diff --git a/httemplate/search/cust_main.html b/httemplate/search/cust_main.html
index 22996a20c..30162506f 100755
--- a/httemplate/search/cust_main.html
+++ b/httemplate/search/cust_main.html
@@ -72,11 +72,20 @@ for my $param (qw( classnum refnum pkg_classnum )) {
$search_hash{$param} = [ $cgi->param($param) ];
}
-#tags
my $params = $cgi->Vars;
+
+#contacts
+$search_hash{'contacts'} = {
+ map { $_ => $cgi->param($_), }
+ grep { /^(contacts_*)/ && $cgi->param($_) }
+ keys %$params
+};
+
+#tags
$search_hash{'tagnum'} = [
map { /^tagnum(\d+)/ && $1 }
- grep { /^tagnum(\d+)/ && $cgi->param($_) } keys %$params
+ grep { /^tagnum(\d+)/ && $cgi->param($_) }
+ keys %$params
];
###
diff --git a/httemplate/search/elements/options_cust_contacts.html b/httemplate/search/elements/options_cust_contacts.html
new file mode 100644
index 000000000..cfbf834b0
--- /dev/null
+++ b/httemplate/search/elements/options_cust_contacts.html
@@ -0,0 +1,36 @@
+ <TR>
+ <TH ALIGN="right" VALIGN="center"><% mt('First name') |h %></TH>
+ <TD><INPUT TYPE="text" NAME="<%$field_prefix%>firstname" SIZE=54></TD>
+ </TR>
+
+ <TR>
+ <TH ALIGN="right" VALIGN="center"><% mt('Last name') |h %></TH>
+ <TD><INPUT TYPE="text" NAME="<%$field_prefix%>lastname" SIZE=54></TD>
+ </TR>
+
+ <TR>
+ <TH ALIGN="right" VALIGN="center"><% mt('Email') |h %></TH>
+ <TD><INPUT TYPE="text" NAME="<%$field_prefix%>email" SIZE=54></TD>
+ </TR>
+
+ <TR>
+ <TH ALIGN="right" VALIGN="center"><% mt('Home Phone') |h %></TH>
+ <TD><INPUT TYPE="text" NAME="<%$field_prefix%>homephone" SIZE=54></TD>
+ </TR>
+
+ <TR>
+ <TH ALIGN="right" VALIGN="center"><% mt('Work Phone') |h %></TH>
+ <TD><INPUT TYPE="text" NAME="<%$field_prefix%>workphone" SIZE=54></TD>
+ </TR>
+
+ <TR>
+ <TH ALIGN="right" VALIGN="center"><% mt('Mobile Phone') |h %></TH>
+ <TD><INPUT TYPE="text" NAME="<%$field_prefix%>mobilephone" SIZE=54></TD>
+ </TR>
+
+<%init>
+
+my %opt = @_;
+my $field_prefix = $opt{'pre_fix'} ? $opt{'pre_fix'} : '';
+
+</%init> \ No newline at end of file
diff --git a/httemplate/search/report_cust_main.html b/httemplate/search/report_cust_main.html
index 14e784454..0a6726215 100755
--- a/httemplate/search/report_cust_main.html
+++ b/httemplate/search/report_cust_main.html
@@ -166,6 +166,14 @@
</TABLE>
<BR>
+ <FONT CLASS="fsinnerbox-title"><% emt('Contacts search options') %></FONT>
+ <TABLE CLASS="fsinnerbox">
+ <& elements/options_cust_contacts.html,
+ 'pre_fix' => 'contacts_',
+ &>
+ </TABLE>
+ <BR>
+
<FONT CLASS="fsinnerbox-title"><% emt('Billing search options') %></FONT>
<TABLE CLASS="fsinnerbox">