From 3b6c827909d8cf04949b58a683d0e9e5a7e8e723 Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 27 Oct 2009 18:11:29 +0000 Subject: [PATCH] address1 search, RT#5060 --- FS/FS/Conf.pm | 7 ++++ FS/FS/cust_main.pm | 91 ++++++++++++++++++++++++++++------------- httemplate/elements/header.html | 40 +++++++++++------- 3 files changed, 95 insertions(+), 43 deletions(-) diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index a57c4732b..a6a738a75 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -2113,6 +2113,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 ffc9f0fce..1c6284976 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -2,8 +2,12 @@ package FS::cust_main; require 5.006; 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; @@ -77,9 +81,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'); } @@ -1492,9 +1498,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"; @@ -1502,9 +1506,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"; @@ -4457,9 +4459,9 @@ sub realtime_bop { 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'}; @@ -8443,8 +8445,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 @@ -8573,15 +8575,18 @@ sub smart_search { } if ( $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 + ) + ) { my $num = $1; - if ( $num <= 2147483647 ) { #need a bigint custnum? wow. + if ( $num =~ /^(\d+)$/ && $num <= 2147483647 ) { #need a bigint custnum? wow push @cust_main, qsearch( { 'table' => 'cust_main', 'hashref' => { 'custnum' => $num, %options }, @@ -8595,13 +8600,28 @@ sub smart_search { '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( { @@ -8670,11 +8690,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', @@ -8715,6 +8740,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( { @@ -8745,6 +8777,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 ); + } } @@ -8828,9 +8864,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 @@ -8890,7 +8923,7 @@ sub all_X { \@array; } -=item append_fuzzyfiles LASTNAME COMPANY +=item append_fuzzyfiles FIRSTNAME LASTNAME COMPANY ADDRESS1 =cut @@ -8903,7 +8936,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 b9ddc7369..0e6bbdeb2 100644 --- a/httemplate/elements/header.html +++ b/httemplate/elements/header.html @@ -40,27 +40,27 @@ Example: @@ -196,7 +196,7 @@ input.fstext { % if ( $curuser->access_right('List customers') ) {
-
+
Advanced
@@ -207,7 +207,7 @@ input.fstext { % if ( $conf->exists('address2-search') ) {
- +
@@ -216,14 +216,13 @@ input.fstext { % if ( $curuser->access_right('View invoices') ) { -
- + % if ( $curuser->access_right('List invoices') ) { - Adv + Adv\ % } -
- +
+
% } @@ -231,7 +230,7 @@ input.fstext { % if ( $curuser->access_right('View customer services') ) {
-
+
Advanced
@@ -241,7 +240,7 @@ input.fstext { % if ( $conf->config("ticket_system") ) {
-
+
Advanced
@@ -335,4 +334,17 @@ if ( scalar(@agentnums) == 1 ) { $company_name = $conf->config('company_name'); } +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, domain or service phone)'; +my $ticketing_label = '(ticket #, subject, email or fulltext:text)'; + -- 2.11.0