fix advanced customer report w/"add package columns" under mysql, RT#16214
[freeside.git] / FS / FS / cust_main / Search.pm
index 06a4522..4da516b 100644 (file)
@@ -18,7 +18,7 @@ use FS::svc_acct;
 $DEBUG = 0;
 $me = '[FS::cust_main::Search]';
 
-@fuzzyfields = @FS::cust_main::fuzzyfields;
+@fuzzyfields = ( 'first', 'last', 'company', 'address1' );
 
 install_callback FS::UID sub { 
   $conf = new FS::Conf;
@@ -64,7 +64,8 @@ sub smart_search {
   my %options = @_;
 
   #here is the agent virtualization
-  my $agentnums_sql = $FS::CurrentUser::CurrentUser->agentnums_sql;
+  my $agentnums_sql = 
+    $FS::CurrentUser::CurrentUser->agentnums_sql(table => 'cust_main');
 
   my @cust_main = ();
 
@@ -142,6 +143,19 @@ sub smart_search {
       } );
     }
 
+    #if this becomes agent-virt need to get a list of all prefixes the current
+    #user can see (via their agents)
+    my $prefix = $conf->config('cust_main-custnum-display_prefix');
+    if ( $prefix && $prefix eq substr($num, 0, length($prefix)) ) {
+      push @cust_main, qsearch( {
+        'table'     => 'cust_main',
+        'hashref'   => { 'custnum' => 0 + substr($num, length($prefix)),
+                         %options,
+                       },
+        'extra_sql' => " AND $agentnums_sql", #agent virtualization
+      } );
+    }
+
     push @cust_main, qsearch( {
       'table'     => 'cust_main',
       'hashref'   => { 'agent_custid' => $num, %options },
@@ -471,6 +485,33 @@ sub search {
   my @where = ();
   my $orderby;
 
+  # initialize these to prevent warnings
+  $params = {
+    'custnum'       => '',
+    'agentnum'      => '',
+    'usernum'       => '',
+    'status'        => '',
+    'address'       => '',
+    'paydate_year'  => '',
+    'invoice_terms' => '',
+    'custbatch'     => '',
+    %$params
+  };
+
+  ##
+  # explicit custnum(s)
+  ##
+
+  if ( $params->{'custnum'} ) {
+    my @custnums = ref($params->{'custnum'}) ? 
+                      @{ $params->{'custnum'} } : 
+                      $params->{'custnum'};
+    push @where, 
+      'cust_main.custnum IN (' . 
+      join(',', map { $_ =~ /^(\d+)$/ ? $1 : () } @custnums ) .
+      ')' if scalar(@custnums) > 0;
+  }
+
   ##
   # parse agent
   ##
@@ -690,11 +731,12 @@ sub search {
   $orderby ||= 'ORDER BY custnum';
 
   # here is the agent virtualization
-  push @where, $FS::CurrentUser::CurrentUser->agentnums_sql;
+  push @where,
+    $FS::CurrentUser::CurrentUser->agentnums_sql(table => 'cust_main');
 
   my $extra_sql = scalar(@where) ? ' WHERE '. join(' AND ', @where) : '';
 
-  my $addl_from = 'LEFT JOIN cust_pkg USING ( custnum  ) ';
+  my $addl_from = '';
 
   my $count_query = "SELECT COUNT(*) FROM cust_main $extra_sql";
 
@@ -708,19 +750,22 @@ sub search {
 
   if ($params->{'flattened_pkgs'}) {
 
+    my $pkg_join = '';
+
     if ($dbh->{Driver}->{Name} eq 'Pg') {
 
       push @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) {
-      push @select, "GROUP_CONCAT(pkg SEPARATOR '|') as magic";
-      $addl_from .= " LEFT JOIN part_pkg using ( pkgpart )";
-    }else{
+    } elsif ($dbh->{Driver}->{Name} =~ /^mysql/i) {
+      push @select, "GROUP_CONCAT(part_pkg.pkg SEPARATOR '|') as magic";
+      $addl_from .= ' LEFT JOIN cust_pkg USING ( custnum ) '; #Pg too w/flatpkg?
+      $pkg_join  .= ' 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 $header_query = "SELECT COUNT(cust_pkg.custnum = cust_main.custnum) AS count FROM cust_main $addl_from $pkg_join $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;
@@ -755,6 +800,7 @@ sub search {
   my $sql_query = {
     'table'         => 'cust_main',
     'select'        => $select,
+    'addl_from'     => $addl_from,
     'hashref'       => {},
     'extra_sql'     => $extra_sql,
     'order_by'      => $orderby,
@@ -819,7 +865,7 @@ sub fuzzy_search {
 
 sub check_and_rebuild_fuzzyfiles {
   my $dir = $FS::UID::conf_dir. "/cache.". $FS::UID::datasrc;
-  rebuild_fuzzyfiles() if grep { ! -e "$dir/cust_main.$_" } @fuzzyfields
+  rebuild_fuzzyfiles() if grep { ! -e "$dir/cust_main.$_" } @fuzzyfields;
 }
 
 =item rebuild_fuzzyfiles
@@ -840,7 +886,7 @@ sub rebuild_fuzzyfiles {
     flock(LOCK,LOCK_EX)
       or die "can't lock $dir/cust_main.$fuzzy: $!";
 
-    open (CACHE,">$dir/cust_main.$fuzzy.tmp")
+    open (CACHE, '>:encoding(UTF-8)', "$dir/cust_main.$fuzzy.tmp")
       or die "can't open $dir/cust_main.$fuzzy.tmp: $!";
 
     foreach my $field ( $fuzzy, "ship_$fuzzy" ) {
@@ -862,6 +908,41 @@ sub rebuild_fuzzyfiles {
 
 }
 
+=item append_fuzzyfiles FIRSTNAME LASTNAME COMPANY ADDRESS1
+
+=cut
+
+sub append_fuzzyfiles {
+  #my( $first, $last, $company ) = @_;
+
+  check_and_rebuild_fuzzyfiles();
+
+  use Fcntl qw(:flock);
+
+  my $dir = $FS::UID::conf_dir. "/cache.". $FS::UID::datasrc;
+
+  foreach my $field (@fuzzyfields) {
+    my $value = shift;
+
+    if ( $value ) {
+
+      open(CACHE, '>>:encoding(UTF-8)', "$dir/cust_main.$field" )
+        or die "can't open $dir/cust_main.$field: $!";
+      flock(CACHE,LOCK_EX)
+        or die "can't lock $dir/cust_main.$field: $!";
+
+      print CACHE "$value\n";
+
+      flock(CACHE,LOCK_UN)
+        or die "can't unlock $dir/cust_main.$field: $!";
+      close CACHE;
+    }
+
+  }
+
+  1;
+}
+
 =item all_X
 
 =cut
@@ -869,7 +950,7 @@ sub rebuild_fuzzyfiles {
 sub all_X {
   my( $self, $field ) = @_;
   my $dir = $FS::UID::conf_dir. "/cache.". $FS::UID::datasrc;
-  open(CACHE,"<$dir/cust_main.$field")
+  open(CACHE, '<:encoding(UTF-8)', "$dir/cust_main.$field")
     or die "can't open $dir/cust_main.$field: $!";
   my @array = map { chomp; $_; } <CACHE>;
   close CACHE;