[freeside-commits] freeside/FS/FS cust_main.pm, 1.545, 1.546 Mason.pm, 1.52, 1.53

Ivan,,, ivan at wavetail.420.am
Fri Sep 17 16:32:35 PDT 2010


Update of /home/cvs/cvsroot/freeside/FS/FS
In directory wavetail.420.am:/tmp/cvs-serv30868/FS/FS

Modified Files:
	cust_main.pm Mason.pm 
Log Message:
refactor giant cust_main.pm a little in preparation of adding API methods for maestro, RT#9967

Index: Mason.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/Mason.pm,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -w -d -r1.52 -r1.53
--- Mason.pm	17 Sep 2010 18:07:07 -0000	1.52
+++ Mason.pm	17 Sep 2010 23:32:33 -0000	1.53
@@ -142,7 +142,8 @@
   use FS::cust_bill_pay;
   use FS::cust_credit;
   use FS::cust_credit_bill;
-  use FS::cust_main qw(smart_search);
+  use FS::cust_main;
+  use FS::cust_main::Search qw(smart_search);
   use FS::cust_main::Import;
   use FS::cust_main_county;
   use FS::cust_location;

Index: cust_main.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_main.pm,v
retrieving revision 1.545
retrieving revision 1.546
diff -u -w -d -r1.545 -r1.546
--- cust_main.pm	17 Sep 2010 20:19:41 -0000	1.545
+++ cust_main.pm	17 Sep 2010 23:32:33 -0000	1.546
@@ -6,7 +6,7 @@
              FS::otaker_Mixin FS::payinfo_Mixin FS::cust_main_Mixin
              FS::Record
            );
-use vars qw( @EXPORT_OK $DEBUG $me $conf
+use vars qw( $DEBUG $me $conf
              @encrypted_fields
              $import $ignore_expired_card
              $skip_fuzzyfiles @fuzzyfields
@@ -14,7 +14,6 @@
            );
 use vars qw( $realtime_bop_decline_quiet ); #ugh
 use Carp;
-use Exporter;
 use Scalar::Util qw( blessed );
 use List::Util qw( min );
 use Time::Local qw(timelocal);
@@ -26,7 +25,6 @@
 use Date::Format;
 #use Date::Manip;
 use File::Temp qw( tempfile );
-use String::Approx qw(amatch);
 use Business::CreditCard 0.28;
 use Locale::Country;
 use FS::UID qw( getotaker dbh driver_name );
@@ -67,8 +65,6 @@
 use FS::banned_pay;
 use FS::TicketSystem;
 
- at EXPORT_OK = qw( smart_search );
-
 $realtime_bop_decline_quiet = 0; #move to Billing_Realtime
 
 # 1 is mostly method/subroutine entry and options
@@ -4714,6 +4710,22 @@
   scalar(@svc_X) ? ( $svc_X[0]->latitude, $svc_X[0]->longitude ) : ()
 }
 
+=item masked FIELD
+
+Returns a masked version of the named field
+
+=cut
+
+sub masked {
+my ($self,$field) = @_;
+
+# Show last four
+
+'x'x(length($self->getfield($field))-4).
+  substr($self->getfield($field), (length($self->getfield($field))-4));
+
+}
+
 =back
 
 =head1 CLASS METHODS
@@ -5002,356 +5014,11 @@
 
 }
 
-=item search HASHREF
-
-(Class method)
-
-Returns a qsearch hash expression to search for parameters specified in
-HASHREF.  Valid parameters are
-
-=over 4
-
-=item agentnum
-
-=item status
-
-=item cancelled_pkgs
-
-bool
-
-=item signupdate
-
-listref of start date, end date
-
-=item payby
-
-listref
-
-=item paydate_year
-
-=item paydate_month
-
-=item current_balance
-
-listref (list returned by FS::UI::Web::parse_lt_gt($cgi, 'current_balance'))
-
-=item cust_fields
-
-=item flattened_pkgs
-
-bool
-
-=back
-
-=cut
-
+#for dyanmic FS::$table->search in httemplate/misc/email_customers.html
+use FS::cust_main::Search;
 sub search {
-  my ($class, $params) = @_;
-
-  my $dbh = dbh;
-
-  my @where = ();
-  my $orderby;
-
-  ##
-  # parse agent
-  ##
-
-  if ( $params->{'agentnum'} =~ /^(\d+)$/ and $1 ) {
-    push @where,
-      "cust_main.agentnum = $1";
-  }
-
-  ##
-  # do the same for user
-  ##
-
-  if ( $params->{'usernum'} =~ /^(\d+)$/ and $1 ) {
-    push @where,
-      "cust_main.usernum = $1";
-  }
-
-  ##
-  # parse status
-  ##
-
-  #prospect ordered active inactive suspended cancelled
-  if ( grep { $params->{'status'} eq $_ } FS::cust_main->statuses() ) {
-    my $method = $params->{'status'}. '_sql';
-    #push @where, $class->$method();
-    push @where, FS::cust_main->$method();
-  }
-  
-  ##
-  # parse cancelled package checkbox
-  ##
-
-  my $pkgwhere = "";
-
-  $pkgwhere .= "AND (cancel = 0 or cancel is null)"
-    unless $params->{'cancelled_pkgs'};
-
-  ##
-  # parse without census tract checkbox
-  ##
-
-  push @where, "(censustract = '' or censustract is null)"
-    if $params->{'no_censustract'};
-
-  ##
-  # dates
-  ##
-
-  foreach my $field (qw( signupdate )) {
-
-    next unless exists($params->{$field});
-
-    my($beginning, $ending, $hour) = @{$params->{$field}};
-
-    push @where,
-      "cust_main.$field IS NOT NULL",
-      "cust_main.$field >= $beginning",
-      "cust_main.$field <= $ending";
-
-    # XXX: do this for mysql and/or pull it out of here
-    if(defined $hour) {
-      if ($dbh->{Driver}->{Name} eq 'Pg') {
-        push @where, "extract(hour from to_timestamp(cust_main.$field)) = $hour";
-      }
-      else {
-        warn "search by time of day not supported on ".$dbh->{Driver}->{Name}." databases";
-      }
-    }
-
-    $orderby ||= "ORDER BY cust_main.$field";
-
-  }
-
-  ###
-  # classnum
-  ###
-
-  if ( $params->{'classnum'} ) {
-
-    my @classnum = ref( $params->{'classnum'} )
-                     ? @{ $params->{'classnum'} }
-                     :  ( $params->{'classnum'} );
-
-    @classnum = grep /^(\d*)$/, @classnum;
-
-    if ( @classnum ) {
-      push @where, '( '. join(' OR ', map {
-                                            $_ ? "cust_main.classnum = $_"
-                                               : "cust_main.classnum IS NULL"
-                                          }
-                                          @classnum
-                             ).
-                   ' )';
-    }
-
-  }
-
-  ###
-  # payby
-  ###
-
-  if ( $params->{'payby'} ) {
-
-    my @payby = ref( $params->{'payby'} )
-                  ? @{ $params->{'payby'} }
-                  :  ( $params->{'payby'} );
-
-    @payby = grep /^([A-Z]{4})$/, @payby;
-
-    push @where, '( '. join(' OR ', map "cust_main.payby = '$_'", @payby). ' )'
-      if @payby;
-
-  }
-
-  ###
-  # paydate_year / paydate_month
-  ###
-
-  if ( $params->{'paydate_year'} =~ /^(\d{4})$/ ) {
-    my $year = $1;
-    $params->{'paydate_month'} =~ /^(\d\d?)$/
-      or die "paydate_year without paydate_month?";
-    my $month = $1;
-
-    push @where,
-      'paydate IS NOT NULL',
-      "paydate != ''",
-      "CAST(paydate AS timestamp) < CAST('$year-$month-01' AS timestamp )"
-;
-  }
-
-  ###
-  # invoice terms
-  ###
-
-  if ( $params->{'invoice_terms'} =~ /^([\w ]+)$/ ) {
-    my $terms = $1;
-    if ( $1 eq 'NULL' ) {
-      push @where,
-        "( cust_main.invoice_terms IS NULL OR cust_main.invoice_terms = '' )";
-    } else {
-      push @where,
-        "cust_main.invoice_terms IS NOT NULL",
-        "cust_main.invoice_terms = '$1'";
-    }
-  }
-
-  ##
-  # amounts
-  ##
-
-  if ( $params->{'current_balance'} ) {
-
-    #my $balance_sql = $class->balance_sql();
-    my $balance_sql = FS::cust_main->balance_sql();
-
-    my @current_balance =
-      ref( $params->{'current_balance'} )
-      ? @{ $params->{'current_balance'} }
-      :  ( $params->{'current_balance'} );
-
-    push @where, map { s/current_balance/$balance_sql/; $_ }
-                     @current_balance;
-
-  }
-
-  ##
-  # custbatch
-  ##
-
-  if ( $params->{'custbatch'} =~ /^([\w\/\-\:\.]+)$/ and $1 ) {
-    push @where,
-      "cust_main.custbatch = '$1'";
-  }
-
-  ##
-  # setup queries, subs, etc. for the search
-  ##
-
-  $orderby ||= 'ORDER BY custnum';
-
-  # here is the agent virtualization
-  push @where, $FS::CurrentUser::CurrentUser->agentnums_sql;
-
-  my $extra_sql = scalar(@where) ? ' WHERE '. join(' AND ', @where) : '';
-
-  my $addl_from = 'LEFT JOIN cust_pkg USING ( custnum  ) ';
-
-  my $count_query = "SELECT COUNT(*) FROM cust_main $extra_sql";
-
-  my $select = join(', ', 
-                 'cust_main.custnum',
-                 FS::UI::Web::cust_sql_fields($params->{'cust_fields'}),
-               );
-
-  my(@extra_headers) = ();
-  my(@extra_fields)  = ();
-
-  if ($params->{'flattened_pkgs'}) {
-
-    if ($dbh->{Driver}->{Name} eq 'Pg') {
-
-      $select .= ", array_to_string(array(select pkg from cust_pkg left join part_pkg using ( pkgpart ) where cust_main.custnum = cust_pkg.custnum $pkgwhere),'|') as magic";
-
-    }elsif ($dbh->{Driver}->{Name} =~ /^mysql/i) {
-      $select .= ", GROUP_CONCAT(pkg SEPARATOR '|') as magic";
-      $addl_from .= " LEFT JOIN part_pkg using ( pkgpart )";
-    }else{
-      warn "warning: unknown database type ". $dbh->{Driver}->{Name}. 
-           "omitting packing information from report.";
-    }
-
-    my $header_query = "SELECT COUNT(cust_pkg.custnum = cust_main.custnum) AS count FROM cust_main $addl_from $extra_sql $pkgwhere group by cust_main.custnum order by count desc limit 1";
-
-    my $sth = dbh->prepare($header_query) or die dbh->errstr;
-    $sth->execute() or die $sth->errstr;
-    my $headerrow = $sth->fetchrow_arrayref;
-    my $headercount = $headerrow ? $headerrow->[0] : 0;
-    while($headercount) {
-      unshift @extra_headers, "Package ". $headercount;
-      unshift @extra_fields, eval q!sub {my $c = shift;
-                                         my @a = split '\|', $c->magic;
-                                         my $p = $a[!.--$headercount. q!];
-                                         $p;
-                                        };!;
-    }
-
-  }
-
-  my $sql_query = {
-    'table'         => 'cust_main',
-    'select'        => $select,
-    'hashref'       => {},
-    'extra_sql'     => $extra_sql,
-    'order_by'      => $orderby,
-    'count_query'   => $count_query,
-    'extra_headers' => \@extra_headers,
-    'extra_fields'  => \@extra_fields,
-  };
-
-}
-
-=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<first>, I<last>, I<company> and/or I<address1> may be
-specified (the appropriate ship_ field is also searched).
-
-Additional options are the same as FS::Record::qsearch
-
-=cut
-
-sub fuzzy_search {
-  my( $self, $fuzzy, $hash, @opt) = @_;
-  #$self
-  $hash ||= {};
-  my @cust_main = ();
-
-  check_and_rebuild_fuzzyfiles();
-  foreach my $field ( keys %$fuzzy ) {
-
-    my $all = $self->all_X($field);
-    next unless scalar(@$all);
-
-    my %match = ();
-    $match{$_}=1 foreach ( amatch( $fuzzy->{$field}, ['i'], @$all ) );
-
-    my @fcust = ();
-    foreach ( keys %match ) {
-      push @fcust, qsearch('cust_main', { %$hash, $field=>$_}, @opt);
-      push @fcust, qsearch('cust_main', { %$hash, "ship_$field"=>$_}, @opt);
-    }
-    my %fsaw = ();
-    push @cust_main, grep { ! $fsaw{$_->custnum}++ } @fcust;
-  }
-
-  # we want the components of $fuzzy ANDed, not ORed, but still don't want dupes
-  my %saw = ();
-  @cust_main = grep { ++$saw{$_->custnum} == scalar(keys %$fuzzy) } @cust_main;
-
-  @cust_main;
-
-}
-
-=item masked FIELD
-
-Returns a masked version of the named field
-
-=cut
-
-sub masked {
-my ($self,$field) = @_;
-
-# Show last four
-
-'x'x(length($self->getfield($field))-4).
-  substr($self->getfield($field), (length($self->getfield($field))-4));
-
+  my $class = shift;
+  FS::cust_main::Search->search(@_);
 }
 
 =back
@@ -5360,427 +5027,6 @@
 
 =over 4
 
-=item smart_search OPTION => VALUE ...
-
-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
-skip fuzzy matching when an exact match is found.
-
-Any additional options are treated as an additional qualifier on the search
-(i.e. I<agentnum>).
-
-Returns a (possibly empty) array of FS::cust_main objects.
-
-=cut
-
-sub smart_search {
-  my %options = @_;
-
-  #here is the agent virtualization
-  my $agentnums_sql = $FS::CurrentUser::CurrentUser->agentnums_sql;
-
-  my @cust_main = ();
-
-  my $skip_fuzzy = delete $options{'no_fuzzy_on_exact'};
-  my $search = delete $options{'search'};
-  ( my $alphanum_search = $search ) =~ s/\W//g;
-  
-  if ( $alphanum_search =~ /^1?(\d{3})(\d{3})(\d{4})(\d*)$/ ) { #phone# search
-
-    #false laziness w/Record::ut_phone
-    my $phonen = "$1-$2-$3";
-    $phonen .= " x$4" if $4;
-
-    push @cust_main, qsearch( {
-      'table'   => 'cust_main',
-      'hashref' => { %options },
-      'extra_sql' => ( scalar(keys %options) ? ' AND ' : ' WHERE ' ).
-                     ' ( '.
-                         join(' OR ', map "$_ = '$phonen'",
-                                          qw( daytime night fax
-                                              ship_daytime ship_night ship_fax )
-                             ).
-                     ' ) '.
-                     " AND $agentnums_sql", #agent virtualization
-    } );
-
-    unless ( @cust_main || $phonen =~ /x\d+$/ ) { #no exact match
-      #try looking for matches with extensions unless one was specified
-
-      push @cust_main, qsearch( {
-        'table'   => 'cust_main',
-        'hashref' => { %options },
-        'extra_sql' => ( scalar(keys %options) ? ' AND ' : ' WHERE ' ).
-                       ' ( '.
-                           join(' OR ', map "$_ LIKE '$phonen\%'",
-                                            qw( daytime night
-                                                ship_daytime ship_night )
-                               ).
-                       ' ) '.
-                       " AND $agentnums_sql", #agent virtualization
-      } );
-
-    }
-
-  # custnum search (also try agent_custid), with some tweaking options if your
-  # legacy cust "numbers" have letters
-  } 
-
-  if ( $search =~ /^\s*(\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 =~ /^(\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' => $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 (but case-insensitive, so USPS standardization
-    #doesn't throw a wrench in the works)
-
-    foreach my $prefix ( '', 'ship_' ) {
-      push @cust_main, qsearch( {
-        'table'     => 'cust_main',
-        'hashref'   => { %options },
-        'extra_sql' => 
-          ( keys(%options) ? ' AND ' : ' WHERE ' ).
-          join(' AND ',
-            " LOWER(${prefix}first)   = ". dbh->quote(lc($first)),
-            " LOWER(${prefix}last)    = ". dbh->quote(lc($last)),
-            " LOWER(${prefix}company) = ". dbh->quote(lc($company)),
-            $agentnums_sql,
-          ),
-      } );
-    }
-
-  } elsif ( $search =~ /^\s*(\S.*\S)\s*$/ ) { # value search
-                                              # try (ship_){last,company}
-
-    my $value = lc($1);
-
-    # # remove "(Last, First)" in "Company (Last, First)", otherwise the
-    # # full strings the browser remembers won't work
-    # $value =~ s/\([\w \,\.\-\']*\)$//; #false laziness w/Record::ut_name
-
-    use Lingua::EN::NameParse;
-    my $NameParse = new Lingua::EN::NameParse(
-             auto_clean     => 1,
-             allow_reversed => 1,
-    );
-
-    my($last, $first) = ( '', '' );
-    #maybe disable this too and just rely on NameParse?
-    if ( $value =~ /^(.+),\s*([^,]+)$/ ) { # Last, First
-    
-      ($last, $first) = ( $1, $2 );
-    
-    #} elsif  ( $value =~ /^(.+)\s+(.+)$/ ) {
-    } elsif ( ! $NameParse->parse($value) ) {
-
-      my %name = $NameParse->components;
-      $first = $name{'given_name_1'};
-      $last  = $name{'surname_1'};
-
-    }
-
-    if ( $first && $last ) {
-
-      my($q_last, $q_first) = ( dbh->quote($last), dbh->quote($first) );
-
-      #exact
-      my $sql = scalar(keys %options) ? ' AND ' : ' WHERE ';
-      $sql .= "
-        (     ( LOWER(last) = $q_last AND LOWER(first) = $q_first )
-           OR ( LOWER(ship_last) = $q_last AND LOWER(ship_first) = $q_first )
-        )";
-
-      push @cust_main, qsearch( {
-        'table'     => 'cust_main',
-        'hashref'   => \%options,
-        'extra_sql' => "$sql AND $agentnums_sql", #agent virtualization
-      } );
-
-      # or it just be something that was typed in... (try that in a sec)
-
-    }
-
-    my $q_value = dbh->quote($value);
-
-    #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 .= "   OR LOWER(address1)      = $q_value
-                OR LOWER(ship_address1) = $q_value
-            "
-      if $conf->exists('address1-search');
-    $sql .= " )";
-
-    push @cust_main, qsearch( {
-      'table'     => 'cust_main',
-      'hashref'   => \%options,
-      'extra_sql' => "$sql AND $agentnums_sql", #agent virtualization
-    } );
-
-    #no exact match, trying substring/fuzzy
-    #always do substring & fuzzy (unless they're explicity config'ed off)
-    #getting complaints searches are not returning enough
-    unless ( @cust_main  && $skip_fuzzy || $conf->exists('disable-fuzzy') ) {
-
-      #still some false laziness w/search (was search/cust_main.cgi)
-
-      #substring
-
-      my @hashrefs = (
-        { 'company'      => { op=>'ILIKE', value=>"%$value%" }, },
-        { 'ship_company' => { op=>'ILIKE', value=>"%$value%" }, },
-      );
-
-      if ( $first && $last ) {
-
-        push @hashrefs,
-          { 'first'        => { op=>'ILIKE', value=>"%$first%" },
-            'last'         => { op=>'ILIKE', value=>"%$last%" },
-          },
-          { 'ship_first'   => { op=>'ILIKE', value=>"%$first%" },
-            'ship_last'    => { op=>'ILIKE', value=>"%$last%" },
-          },
-        ;
-
-      } else {
-
-        push @hashrefs,
-          { 'last'         => { op=>'ILIKE', value=>"%$value%" }, },
-          { 'ship_last'    => { op=>'ILIKE', value=>"%$value%" }, },
-        ;
-      }
-
-      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( {
-          'table'     => 'cust_main',
-          'hashref'   => { %$hashref,
-                           %options,
-                         },
-          'extra_sql' => " AND $agentnums_sql", #agent virtualizaiton
-        } );
-
-      }
-
-      #fuzzy
-      my @fuzopts = (
-        \%options,                #hashref
-        '',                       #select
-        " AND $agentnums_sql",    #extra_sql  #agent virtualization
-      );
-
-      if ( $first && $last ) {
-        push @cust_main, FS::cust_main->fuzzy_search(
-          { 'last'   => $last,    #fuzzy hashref
-            'first'  => $first }, #
-          @fuzopts
-        );
-      }
-      foreach my $field ( 'last', 'company' ) {
-        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 );
-      }
-
-    }
-
-  }
-
-  #eliminate duplicates
-  my %saw = ();
-  @cust_main = grep { !$saw{$_->custnum}++ } @cust_main;
-
-  @cust_main;
-
-}
-
-=item email_search
-
-Accepts the following options: I<email>, the email address to search for.  The
-email address will be searched for as an email invoice destination and as an
-svc_acct account.
-
-#Any additional options are treated as an additional qualifier on the search
-#(i.e. I<agentnum>).
-
-Returns a (possibly empty) array of FS::cust_main objects (but usually just
-none or one).
-
-=cut
-
-sub email_search {
-  my %options = @_;
-
-  local($DEBUG) = 1;
-
-  my $email = delete $options{'email'};
-
-  #we're only being used by RT at the moment... no agent virtualization yet
-  #my $agentnums_sql = $FS::CurrentUser::CurrentUser->agentnums_sql;
-
-  my @cust_main = ();
-
-  if ( $email =~ /([^@]+)\@([^@]+)/ ) {
-
-    my ( $user, $domain ) = ( $1, $2 );
-
-    warn "$me smart_search: searching for $user in domain $domain"
-      if $DEBUG;
-
-    push @cust_main,
-      map $_->cust_main,
-          qsearch( {
-                     'table'     => 'cust_main_invoice',
-                     'hashref'   => { 'dest' => $email },
-                   }
-                 );
-
-    push @cust_main,
-      map  $_->cust_main,
-      grep $_,
-      map  $_->cust_svc->cust_pkg,
-          qsearch( {
-                     'table'     => 'svc_acct',
-                     'hashref'   => { 'username' => $user, },
-                     'extra_sql' =>
-                       'AND ( SELECT domain FROM svc_domain
-                                WHERE svc_acct.domsvc = svc_domain.svcnum
-                            ) = '. dbh->quote($domain),
-                   }
-                 );
-  }
-
-  my %saw = ();
-  @cust_main = grep { !$saw{$_->custnum}++ } @cust_main;
-
-  warn "$me smart_search: found ". scalar(@cust_main). " unique customers"
-    if $DEBUG;
-
-  @cust_main;
-
-}
-
-=item check_and_rebuild_fuzzyfiles
-
-=cut
-
-sub check_and_rebuild_fuzzyfiles {
-  my $dir = $FS::UID::conf_dir. "/cache.". $FS::UID::datasrc;
-  rebuild_fuzzyfiles() if grep { ! -e "$dir/cust_main.$_" } @fuzzyfields
-}
-
-=item rebuild_fuzzyfiles
-
-=cut
-
-sub rebuild_fuzzyfiles {
-
-  use Fcntl qw(:flock);
-
-  my $dir = $FS::UID::conf_dir. "/cache.". $FS::UID::datasrc;
-  mkdir $dir, 0700 unless -d $dir;
-
-  foreach my $fuzzy ( @fuzzyfields ) {
-
-    open(LOCK,">>$dir/cust_main.$fuzzy")
-      or die "can't open $dir/cust_main.$fuzzy: $!";
-    flock(LOCK,LOCK_EX)
-      or die "can't lock $dir/cust_main.$fuzzy: $!";
-
-    open (CACHE,">$dir/cust_main.$fuzzy.tmp")
-      or die "can't open $dir/cust_main.$fuzzy.tmp: $!";
-
-    foreach my $field ( $fuzzy, "ship_$fuzzy" ) {
-      my $sth = dbh->prepare("SELECT $field FROM cust_main".
-                             " WHERE $field != '' AND $field IS NOT NULL");
-      $sth->execute or die $sth->errstr;
-
-      while ( my $row = $sth->fetchrow_arrayref ) {
-        print CACHE $row->[0]. "\n";
-      }
-
-    } 
-
-    close CACHE or die "can't close $dir/cust_main.$fuzzy.tmp: $!";
-  
-    rename "$dir/cust_main.$fuzzy.tmp", "$dir/cust_main.$fuzzy";
-    close LOCK;
-  }
-
-}
-
-=item all_X
-
-=cut
-
-sub all_X {
-  my( $self, $field ) = @_;
-  my $dir = $FS::UID::conf_dir. "/cache.". $FS::UID::datasrc;
-  open(CACHE,"<$dir/cust_main.$field")
-    or die "can't open $dir/cust_main.$field: $!";
-  my @array = map { chomp; $_; } <CACHE>;
-  close CACHE;
-  \@array;
-}
-
 =item append_fuzzyfiles FIRSTNAME LASTNAME COMPANY ADDRESS1
 
 =cut



More information about the freeside-commits mailing list