From 2e868fc7bc85401ec4dbca6b4889d5222061da55 Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 27 Oct 2009 18:11:55 +0000 Subject: [PATCH] address1 search, RT#5060 --- FS/FS/Conf.pm | 7 +++ FS/FS/cust_main.pm | 103 +++++++++++++++++++++++++++------------- httemplate/elements/header.html | 36 +++++++++----- 3 files changed, 101 insertions(+), 45 deletions(-) diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 6ad3fcb82..bd7250f2f 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -1860,6 +1860,13 @@ worry that config_items is freeside-specific and icky. }, { + 'key' => 'address1-search', + 'section' => 'UI', + 'description' => 'Enable the ability to search the address1 field from customer search.', + 'type' => 'checkbox', + }, + + { 'key' => 'address2-search', 'section' => 'UI', 'description' => 'Enable a "Unit" search box which searches the second address field. Useful for multi-tenant applications. See also: cust_main-require_address2', diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index 2559cd3e8..ee9064d70 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -1,8 +1,12 @@ package FS::cust_main; use strict; -use vars qw( @ISA @EXPORT_OK $DEBUG $me $conf @encrypted_fields - $import $skip_fuzzyfiles $ignore_expired_card @paytypes); +use vars qw( @ISA @EXPORT_OK $DEBUG $me $conf + @encrypted_fields + $import $ignore_expired_card + $skip_fuzzyfiles @fuzzyfields + @paytypes + ); use vars qw( $realtime_bop_decline_quiet ); #ugh use Safe; use Carp; @@ -70,9 +74,11 @@ $DEBUG = 0; $me = '[FS::cust_main]'; $import = 0; -$skip_fuzzyfiles = 0; $ignore_expired_card = 0; +$skip_fuzzyfiles = 0; +@fuzzyfields = ( 'first', 'last', 'company', 'address1' ); + @encrypted_fields = ('payinfo', 'paycvv'); sub nohistory_fields { ('paycvv'); } @@ -1203,9 +1209,7 @@ sub queue_fuzzyfiles_update { my $dbh = dbh; my $queue = new FS::queue { 'job' => 'FS::cust_main::append_fuzzyfiles' }; - my $error = $queue->insert( map $self->getfield($_), - qw(first last company) - ); + my $error = $queue->insert( map $self->getfield($_), @fuzzyfields ); if ( $error ) { $dbh->rollback if $oldAutoCommit; return "queueing job (transaction rolled back): $error"; @@ -1213,9 +1217,7 @@ sub queue_fuzzyfiles_update { if ( $self->ship_last ) { $queue = new FS::queue { 'job' => 'FS::cust_main::append_fuzzyfiles' }; - $error = $queue->insert( map $self->getfield("ship_$_"), - qw(first last company) - ); + $error = $queue->insert( map $self->getfield("ship_$_"), @fuzzyfields ); if ( $error ) { $dbh->rollback if $oldAutoCommit; return "queueing job (transaction rolled back): $error"; @@ -3292,9 +3294,9 @@ sub remove_cvv { sub _bop_recurring_billing { my( $self, %opt ) = @_; - my $method = $conf->config('credit_card-recurring_billing_flag'); + my $method = scalar($conf->config('credit_card-recurring_billing_flag')); - if ( $method eq 'transaction_is_recur' ) { + if ( defined($method) && $method eq 'transaction_is_recur' ) { return 1 if $opt{'trans_is_recur'}; @@ -5352,8 +5354,8 @@ sub process_email_search_sql { =item fuzzy_search FUZZY_HASHREF [ HASHREF, SELECT, EXTRA_SQL, CACHE_OBJ ] Performs a fuzzy (approximate) search and returns the matching FS::cust_main -records. Currently, I, I and/or I may be specified (the -appropriate ship_ field is also searched). +records. Currently, I, I, I and/or I may be +specified (the appropriate ship_ field is also searched). Additional options are the same as FS::Record::qsearch @@ -5480,31 +5482,53 @@ sub smart_search { # custnum search (also try agent_custid), with some tweaking options if your # legacy cust "numbers" have letters } elsif ( $search =~ /^\s*(\d+)\s*$/ - || ( $conf->config('cust_main-agent_custid-format') eq 'ww?d+' - && $search =~ /^\s*(\w\w?\d+)\s*$/ - ) + || ( $conf->config('cust_main-agent_custid-format') eq 'ww?d+' + && $search =~ /^\s*(\w\w?\d+)\s*$/ + ) + || ( $conf->exists('address1-search' ) + && $search =~ /^\s*(\d+\-?\w*)\s*$/ #i.e. 1234A or 9432-D + ) ) { - push @cust_main, qsearch( { - 'table' => 'cust_main', - 'hashref' => { 'custnum' => $1, %options }, - 'extra_sql' => " AND $agentnums_sql", #agent virtualization - } ); + my $num = $1; + + if ( $num =~ /^(\d+)$/ && $num <= 2147483647 ) { #need a bigint custnum? wow + push @cust_main, qsearch( { + 'table' => 'cust_main', + 'hashref' => { 'custnum' => $num, %options }, + 'extra_sql' => " AND $agentnums_sql", #agent virtualization + } ); + } push @cust_main, qsearch( { 'table' => 'cust_main', - 'hashref' => { 'agent_custid' => $1, %options }, + 'hashref' => { 'agent_custid' => $num, %options }, 'extra_sql' => " AND $agentnums_sql", #agent virtualization } ); + if ( $conf->exists('address1-search') ) { + my $len = length($num); + $num = lc($num); + foreach my $prefix ( '', 'ship_' ) { + push @cust_main, qsearch( { + 'table' => 'cust_main', + 'hashref' => { %options, }, + 'extra_sql' => + ( keys(%options) ? ' AND ' : ' WHERE ' ). + " LOWER(SUBSTRING(${prefix}address1 FROM 1 FOR $len)) = '$num' ". + " AND $agentnums_sql", + } ); + } + } + } elsif ( $search =~ /^\s*(\S.*\S)\s+\((.+), ([^,]+)\)\s*$/ ) { my($company, $last, $first) = ( $1, $2, $3 ); # "Company (Last, First)" #this is probably something a browser remembered, - #so just do an exact search + #so just do an exact (but case-insensitive) search foreach my $prefix ( '', 'ship_' ) { push @cust_main, qsearch( { @@ -5573,11 +5597,16 @@ sub smart_search { #exact my $sql = scalar(keys %options) ? ' AND ' : ' WHERE '; - $sql .= " ( LOWER(last) = $q_value - OR LOWER(company) = $q_value - OR LOWER(ship_last) = $q_value - OR LOWER(ship_company) = $q_value - )"; + $sql .= " ( LOWER(last) = $q_value + OR LOWER(company) = $q_value + OR LOWER(ship_last) = $q_value + OR LOWER(ship_company) = $q_value + "; + $sql .= " OR LOWER(address1) = $q_value + OR LOWER(ship_address1) = $q_value + " + if $conf->exists('address1-search'); + $sql .= " )"; push @cust_main, qsearch( { 'table' => 'cust_main', @@ -5617,6 +5646,13 @@ sub smart_search { ; } + if ( $conf->exists('address1-search') ) { + push @hashrefs, + { 'address1' => { op=>'ILIKE', value=>"%$value%" }, }, + { 'ship_address1' => { op=>'ILIKE', value=>"%$value%" }, }, + ; + } + foreach my $hashref ( @hashrefs ) { push @cust_main, qsearch( { @@ -5647,6 +5683,10 @@ sub smart_search { push @cust_main, FS::cust_main->fuzzy_search( { $field => $value }, @fuzopts ); } + if ( $conf->exists('address1-search') ) { + push @cust_main, + FS::cust_main->fuzzy_search( { 'address1' => $value }, @fuzopts ); + } } @@ -5730,9 +5770,6 @@ sub email_search { =cut -use vars qw(@fuzzyfields); -@fuzzyfields = ( 'last', 'first', 'company' ); - sub check_and_rebuild_fuzzyfiles { my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc; rebuild_fuzzyfiles() if grep { ! -e "$dir/cust_main.$_" } @fuzzyfields @@ -5792,7 +5829,7 @@ sub all_X { \@array; } -=item append_fuzzyfiles LASTNAME COMPANY +=item append_fuzzyfiles FIRSTNAME LASTNAME COMPANY ADDRESS1 =cut @@ -5805,7 +5842,7 @@ sub append_fuzzyfiles { my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc; - foreach my $field (qw( first last company )) { + foreach my $field (@fuzzyfields) { my $value = shift; if ( $value ) { diff --git a/httemplate/elements/header.html b/httemplate/elements/header.html index 3843a0fd2..c26f48b0b 100644 --- a/httemplate/elements/header.html +++ b/httemplate/elements/header.html @@ -17,27 +17,27 @@ @@ -167,7 +167,7 @@ input.fsblackbuttonselected { % if ( $curuser->access_right('List customers') ) {
-
+
Advanced
@@ -178,7 +178,7 @@ input.fsblackbuttonselected { % if ( $conf->exists('address2-search') ) {
- +
@@ -187,12 +187,11 @@ input.fsblackbuttonselected { % if ( $curuser->access_right('View invoices') ) { -
- + % if ( $curuser->access_right('List invoices') ) { - Advanced + Adv % }
@@ -204,7 +203,7 @@ input.fsblackbuttonselected { % if ( $curuser->access_right('View customer services') ) { -
+
Advanced
@@ -214,7 +213,7 @@ input.fsblackbuttonselected { % if ( $conf->config("ticket_system") ) {
-
+
Advanced
@@ -276,4 +275,17 @@ my $curuser = $FS::CurrentUser::CurrentUser; my $menu_position = $FS::CurrentUser::CurrentUser->option('menu_position') || 'left'; +my $cust_width = 288; #251 #ok for IE, slightly bigger for windows firefox +my $cust_label = '(cust #, name, company'; +if ( $conf->exists('address1-search') ) { + $cust_label .= ', address'; + $cust_width += 64; +} +$cust_label .= ' or contact phone)'; + +my $address2_label = '(Unit #)'; +my $inv_label = '(inv #)'; +my $svc_label = '(user, email, ip, mac, or domain)'; +my $ticketing_label = '(ticket # or subject string)'; + -- 2.11.0