use FS::cust_main;
use FS::cust_main_invoice;
use FS::svc_acct;
+use FS::payinfo_Mixin;
@EXPORT_OK = qw( smart_search );
Accepts the following options: I<search>, the string to search for. The string
will be searched for as a customer number, phone number, name or company name,
-as an exact, or, in some cases, a substring or fuzzy match (see the source code
-for the exact heuristics used); I<no_fuzzy_on_exact>, causes smart_search to
+address (if address1-search is on), invoicing email address, or credit card
+number.
+
+Searches match as an exact, or, in some cases, a substring or fuzzy match (see
+the source code for the exact heuristics used); I<no_fuzzy_on_exact>, causes
+smart_search to
skip fuzzy matching when an exact match is found.
Any additional options are treated as an additional qualifier on the search
}
- # custnum search (also try agent_custid), with some tweaking options if your
- # legacy cust "numbers" have letters
}
- if ( $search =~ /@/ ) {
+ if ( $search =~ /@/ ) { #invoicing email address
push @cust_main,
map $_->cust_main,
qsearch( {
'hashref' => { 'dest' => $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*$/
}
+ ( my $nospace_search = $search ) =~ s/\s//g;
+ ( my $card_search = $nospace_search ) =~ s/\-//g;
+ $card_search =~ s/[x\*\.\_]/x/gi;
+
+ if ( $nospace_search =~ /^[\dx]{15,16}$/i ) { #credit card search
+
+ ( my $like_search = $card_search ) =~ s/x/_/g;
+ my $mask_search = FS::payinfo_Mixin->mask_payinfo('CARD', $card_search);
+
+ push @cust_main, qsearch({
+ 'table' => 'cust_main',
+ 'hashref' => {},
+ 'extra_sql' => " WHERE ( payinfo LIKE '$like_search'
+ OR paymask = '$mask_search'
+ ) ".
+ " AND payby IN ('CARD','DCRD') ".
+ " AND $agentnums_sql", #agent virtulization
+ });
+
+ }
+
+
#eliminate duplicates
my %saw = ();
@cust_main = grep { !$saw{$_->custnum}++ } @cust_main;
# parse without census tract checkbox
##
- push @where, "(censustract = '' or censustract is null)"
+ push @where, "(ship_location.censustract = '' or ship_location.censustract is null)"
if $params->{'no_censustract'};
##
# parse with hardcoded tax location checkbox
##
- push @where, "geocode is not null"
+ push @where, "ship_location.geocode is not null"
if $params->{'with_geocode'};
##
'ON (cust_main.'.$pre.'locationnum = '.$pre.'location.locationnum) ';
}
- my $count_query = "SELECT COUNT(*) FROM cust_main $extra_sql";
+ my $count_query = "SELECT COUNT(*) FROM cust_main $addl_from $extra_sql";
my @select = (
'cust_main.custnum',
if ($params->{'flattened_pkgs'}) {
#my $pkg_join = '';
- $addl_from .= ' LEFT JOIN cust_pkg USING ( custnum ) ';
+ $addl_from .=
+ ' LEFT JOIN cust_pkg ON ( cust_main.custnum = cust_pkg.custnum ) ';
if ($dbh->{Driver}->{Name} eq 'Pg') {
'extra_headers' => \@extra_headers,
'extra_fields' => \@extra_fields,
};
+ warn Data::Dumper::Dumper($sql_query);
+ $sql_query;
}
my @cust_main = ();
+ my @fuzzy_mod = 'i';
+ my $conf = new FS::Conf;
+ my $fuzziness = $conf->config('fuzzy-fuzziness');
+ push @fuzzy_mod, $fuzziness if $fuzziness;
+
check_and_rebuild_fuzzyfiles();
foreach my $field ( keys %$fuzzy ) {
next unless scalar(@$all);
my %match = ();
- $match{$_}=1 foreach ( amatch( $fuzzy->{$field}, ['i'], @$all ) );
+ $match{$_}=1 foreach ( amatch( $fuzzy->{$field}, \@fuzzy_mod, @$all ) );
next if !keys(%match);
my $in_matches = 'IN (' .