more mod_perl fixes, and bugfixes Peter Wemm sent via email
[freeside.git] / htdocs / search / cust_main.cgi
index 70ce991..ed7b714 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl -Tw
 #
-# process/cust_main.cgi: Search for customers (process form)
+# $Id: cust_main.cgi,v 1.8 1999-02-07 09:59:36 ivan Exp $
 #
 # Usage: post form to:
 #        http://server.name/path/cust_main.cgi
 #       bmccane@maxbaud.net     98-apr-3
 #
 # display total, use FS::CGI ivan@sisd.com 98-jul-17
+#
+# $Log: cust_main.cgi,v $
+# Revision 1.8  1999-02-07 09:59:36  ivan
+# more mod_perl fixes, and bugfixes Peter Wemm sent via email
+#
+# Revision 1.7  1999/01/25 12:19:11  ivan
+# yet more mod_perl stuff
+#
+# Revision 1.6  1999/01/19 05:14:12  ivan
+# for mod_perl: no more top-level my() variables; use vars instead
+# also the last s/create/new/;
+#
+# Revision 1.5  1999/01/18 09:41:37  ivan
+# all $cgi->header calls now include ( '-expires' => 'now' ) for mod_perl
+# (good idea anyway)
+#
+# Revision 1.4  1998/12/30 00:57:50  ivan
+# bug
+#
+# Revision 1.3  1998/12/17 09:41:08  ivan
+# s/CGI::(Base|Request)/CGI.pm/;
+#
+# Revision 1.2  1998/11/12 08:10:22  ivan
+# CGI.pm instead of CGI-modules
+# relative URLs using popurl
+# got rid of lots of little tables
+# s/agrep/String::Approx/;
+# bubble up packages and services and link (slow)
+#
 
 use strict;
-use CGI::Request;
+use vars qw(%ncancelled_pkgs %all_pkgs $cgi @cust_main $sortby );
+use CGI;
 use CGI::Carp qw(fatalsToBrowser);
 use IO::Handle;
-use IPC::Open2;
+use String::Approx qw(amatch);
 use FS::UID qw(cgisuidsetup);
 use FS::Record qw(qsearch qsearchs);
-use FS::CGI qw(header idiot);
-
-my($fuzziness)=2; #fuzziness for fuzzy searches, see man agrep
-                  #0-4: 0=no fuzz, 4=very fuzzy (too much fuzz!)
-
-my($req)=new CGI::Request;
-&cgisuidsetup($req->cgi);
-
-my(@cust_main);
-my($sortby);
-
-my($query)=$req->cgi->var('QUERY_STRING');
-if ( $query eq 'custnum' ) {
-  $sortby=\*custnum_sort;
-  @cust_main=qsearch('cust_main',{});  
-} elsif ( $query eq 'last' ) {
-  $sortby=\*last_sort;
-  @cust_main=qsearch('cust_main',{});  
-} elsif ( $query eq 'company' ) {
-  $sortby=\*company_sort;
-  @cust_main=qsearch('cust_main',{});  
+use FS::CGI qw(header menubar eidiot popurl table);
+use FS::cust_main;
+
+$cgi = new CGI;
+cgisuidsetup($cgi);
+
+if ( $cgi->keywords ) {
+  my($query)=$cgi->keywords;
+  if ( $query eq 'custnum' ) {
+    $sortby=\*custnum_sort;
+    @cust_main=qsearch('cust_main',{});  
+  } elsif ( $query eq 'last' ) {
+    $sortby=\*last_sort;
+    @cust_main=qsearch('cust_main',{});  
+  } elsif ( $query eq 'company' ) {
+    $sortby=\*company_sort;
+    @cust_main=qsearch('cust_main',{});
+  }
 } else {
-  &cardsearch if ($req->param('card_on') );
-  &lastsearch if ($req->param('last_on') );
-  &companysearch if ($req->param('company_on') );
+  &cardsearch if ( $cgi->param('card_on') && $cgi->param('card') );
+  &lastsearch if ( $cgi->param('last_on') && $cgi->param('last_text') );
+  &companysearch if ( $cgi->param('company_on') && $cgi->param('company_text') );
 }
 
+#%ncancelled_pkgs = map { $_->custnum => [ $_->ncancelled_pkgs ] } @cust_main;
+%all_pkgs = map { $_->custnum => [ $_->all_pkgs ] } @cust_main;
+
 if ( scalar(@cust_main) == 1 ) {
-  $req->cgi->redirect("../view/cust_main.cgi?". $cust_main[0]->custnum);
+  print $cgi->redirect(popurl(2). "view/cust_main.cgi?". $cust_main[0]->custnum);
   exit;
 } elsif ( scalar(@cust_main) == 0 ) {
-  idiot "No matching customers found!\n";
-  exit;
+  eidiot "No matching customers found!\n";
 } else { 
 
   my($total)=scalar(@cust_main);
-  CGI::Base::SendHeaders(); # one guess
-  print header("Customer Search Results",''), <<END;
-
-    $total matching customers found
-    <TABLE BORDER=4 CELLSPACING=0 CELLPADDING=0>
+  print $cgi->header( '-expires' => 'now' ), header("Customer Search Results",menubar(
+    'Main Menu', popurl(2)
+  )), "$total matching customers found<BR>", table, <<END;
       <TR>
-        <TH>Cust. #</TH>
+        <TH></TH>
         <TH>Contact name</TH>
         <TH>Company</TH>
+        <TH>Packages</TH>
+        <TH COLSPAN=2>Services</TH>
       </TR>
 END
 
-  my($lines)=16;
-  my($lcount)=$lines;
   my(%saw,$cust_main);
   foreach $cust_main (
     sort $sortby grep(!$saw{$_->custnum}++, @cust_main)
@@ -85,30 +112,52 @@ END
       $cust_main->getfield('first'),
       $cust_main->company,
     );
+
+    my(@lol_cust_svc);
+    my($rowspan)=0;#scalar( @{$all_pkgs{$custnum}} );
+    foreach ( @{$all_pkgs{$custnum}} ) {
+      my(@cust_svc) = qsearch( 'cust_svc', { 'pkgnum' => $_->pkgnum } );
+      push @lol_cust_svc, \@cust_svc;
+      $rowspan += scalar(@cust_svc) || 1;
+    }
+
+    #my($rowspan) = scalar(@{$all_pkgs{$custnum}});
+    my($view) = popurl(2). "view/cust_main.cgi?$custnum";
     print <<END;
     <TR>
-      <TD><A HREF="../view/cust_main.cgi?$custnum"><FONT SIZE=-1>$custnum</FONT></A></TD>
-      <TD><FONT SIZE=-1>$last, $first</FONT></TD>
-      <TD><FONT SIZE=-1>$company</FONT></TD>
-    </TR>
-END
-    if ($lcount-- == 0) { # lots of little tables instead of one big one
-      $lcount=$lines;
-      print <<END;   
-  </TABLE>
-  <TABLE BORDER=4 CELLSPACING=0 CELLPADDING=0>
-    <TR>
-      <TH>Cust. #</TH>
-      <TH>Contact name</TH>
-      <TH>Company<TH>
-    </TR>
+      <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>$custnum</FONT></A></TD>
+      <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>$last, $first</FONT></A></TD>
+      <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>$company</FONT></A></TD>
 END
+
+    my($n1)='';
+    foreach ( @{$all_pkgs{$custnum}} ) {
+      my($pkgnum) = ($_->pkgnum);
+      my($pkg) = $_->part_pkg->pkg;
+      my $comment = $_->part_pkg->comment;
+      my($pkgview) = popurl(2). "/view/cust_pkg.cgi?$pkgnum";
+      #my(@cust_svc) = shift @lol_cust_svc;
+      my(@cust_svc) = qsearch( 'cust_svc', { 'pkgnum' => $_->pkgnum } );
+      my($rowspan) = scalar(@cust_svc) || 1;
+
+      print $n1, qq!<TD ROWSPAN=$rowspan><A HREF="$pkgview"><FONT SIZE=-1>$pkg - $comment</FONT></A></TD>!;
+      my($n2)='';
+      foreach my $cust_svc ( @cust_svc ) {
+         my($label, $value, $svcdb) = $cust_svc->label;
+         my($svcnum) = $cust_svc->svcnum;
+         my($sview) = popurl(2). "/view";
+         print $n2,qq!<TD><A HREF="$sview/$svcdb.cgi?$svcnum"><FONT SIZE=-1>$label</FONT></A></TD>!,
+               qq!<TD><A HREF="$sview/$svcdb.cgi?$svcnum"><FONT SIZE=-1>$value</FONT></A></TD>!;
+         $n2="</TR><TR>";
+      }
+      #print qq!</TR><TR>\n!;
+      $n1="</TR><TR>";
     }
+    print "<\TR>";
   }
  
   print <<END;
     </TABLE>
-    </CENTER>
   </BODY>
 </HTML>
 END
@@ -122,6 +171,8 @@ sub last_sort {
 }
 
 sub company_sort {
+  return -1 if $a->company && ! $b->company;
+  return 1 if ! $a->company && $b->company;
   $a->getfield('company') cmp $b->getfield('company');
 }
 
@@ -131,9 +182,9 @@ sub custnum_sort {
 
 sub cardsearch {
 
-  my($card)=$req->param('card');
+  my($card)=$cgi->param('card');
   $card =~ s/\D//g;
-  $card =~ /^(\d{13,16})$/ or do { idiot "Illegal card number\n"; exit; };
+  $card =~ /^(\d{13,16})$/ or eidiot "Illegal card number\n";
   my($payinfo)=$1;
 
   push @cust_main, qsearch('cust_main',{'payinfo'=>$payinfo, 'payby'=>'CARD'});
@@ -142,12 +193,12 @@ sub cardsearch {
 
 sub lastsearch {
   my(%last_type);
-  foreach ( $req->param('last_type') ) {
+  foreach ( $cgi->param('last_type') ) {
     $last_type{$_}++;
   }
 
-  $req->param('last_text') =~ /^([\w \,\.\-\']*)$/
-    or do { idiot "Illegal last name"; exit; };
+  $cgi->param('last_text') =~ /^([\w \,\.\-\']*)$/
+    or eidiot "Illegal last name";
   my($last)=$1;
 
   if ( $last_type{'Exact'}
@@ -163,16 +214,9 @@ sub lastsearch {
 
     my(@all_last)=map $_->getfield('last'), qsearch('cust_main',{});
     if ($last_type{'Fuzzy'}) { 
-      my($reader,$writer) = ( new IO::Handle, new IO::Handle );
-      open2($reader,$writer,'agrep',"-$fuzziness",'-i','-k',
-            substr($last,0,30));
-      print $writer join("\n",@all_last),"\n";
-      close $writer;
-      while (<$reader>) {
-        chop;
-        $last{$_}++;
-      } 
-      close $reader;
+      foreach ( amatch($last, [ qw(i) ], @all_last) ) {
+        $last{$_}++; 
+      }
     }
 
     #if ($last_type{'Sound-alike'}) {
@@ -189,12 +233,12 @@ sub lastsearch {
 sub companysearch {
 
   my(%company_type);
-  foreach ( $req->param('company_type') ) {
+  foreach ( $cgi->param('company_type') ) {
     $company_type{$_}++ 
   };
 
-  $req->param('company_text') =~ /^([\w \,\.\-\']*)$/
-    or do { idiot "Illegal company"; exit; };
+  $cgi->param('company_text') =~ /^([\w \,\.\-\']*)$/
+    or eidiot "Illegal company";
   my($company)=$1;
 
   if ( $company_type{'Exact'}
@@ -210,16 +254,9 @@ sub companysearch {
     my(@all_company)=map $_->company, qsearch('cust_main',{});
 
     if ($company_type{'Fuzzy'}) { 
-      my($reader,$writer) = ( new IO::Handle, new IO::Handle );
-      open2($reader,$writer,'agrep',"-$fuzziness",'-i','-k',
-            substr($company,0,30));
-      print $writer join("\n",@all_company),"\n";
-      close $writer;
-      while (<$reader>) {
-        chop;
+      foreach ( amatch($company, [ qw(i) ], @all_company ) ) {
         $company{$_}++;
       }
-      close $reader;
     }
 
     #if ($company_type{'Sound-alike'}) {