s/CGI::(Base|Request)/CGI.pm/;
[freeside.git] / htdocs / search / cust_main.cgi
1 #!/usr/bin/perl -Tw
2 #
3 # $Id: cust_main.cgi,v 1.3 1998-12-17 09:41:08 ivan Exp $
4 #
5 # Usage: post form to:
6 #        http://server.name/path/cust_main.cgi
7 #
8 # Note: Should be run setuid freeside as user nobody.
9 #
10 # ivan@voicenet.com 96-dec-12
11 #
12 # rewrite ivan@sisd.com 98-mar-4
13 #
14 # now does browsing too ivan@sisd.com 98-mar-6
15 #
16 # Changes to allow page to work at a relative position in server
17 #       bmccane@maxbaud.net     98-apr-3
18 #
19 # display total, use FS::CGI ivan@sisd.com 98-jul-17
20 #
21 # $Log: cust_main.cgi,v $
22 # Revision 1.3  1998-12-17 09:41:08  ivan
23 # s/CGI::(Base|Request)/CGI.pm/;
24 #
25 # Revision 1.2  1998/11/12 08:10:22  ivan
26 # CGI.pm instead of CGI-modules
27 # relative URLs using popurl
28 # got rid of lots of little tables
29 # s/agrep/String::Approx/;
30 # bubble up packages and services and link (slow)
31 #
32
33 use strict;
34 use vars qw(%ncancelled_pkgs %all_pkgs);
35 use CGI;
36 use CGI::Carp qw(fatalsToBrowser);
37 use IO::Handle;
38 use String::Approx qw(amatch);
39 use FS::UID qw(cgisuidsetup);
40 use FS::Record qw(qsearch qsearchs);
41 use FS::CGI qw(header menubar idiot popurl table);
42 use FS::cust_main;
43
44 my($cgi)=new CGI;
45 cgisuidsetup($cgi);
46
47 my(@cust_main);
48 my($sortby);
49
50 if ( $cgi->keywords ) {
51   my($query)=$cgi->keywords;
52   if ( $query eq 'custnum' ) {
53     $sortby=\*custnum_sort;
54     @cust_main=qsearch('cust_main',{});  
55   } elsif ( $query eq 'last' ) {
56     $sortby=\*last_sort;
57     @cust_main=qsearch('cust_main',{});  
58   } elsif ( $query eq 'company' ) {
59     $sortby=\*company_sort;
60     @cust_main=qsearch('cust_main',{});
61   }
62 } else {
63   &cardsearch if ( $cgi->param('card_on') && $cgi->param('card') );
64   &lastsearch if ( $cgi->param('last_on') && $cgi->param('last_text') );
65   &companysearch if ( $cgi->param('company_on') && $cgi->param('company_text') );
66 }
67
68 my(%ncancelled_pkgs) =
69   map { $_->custnum => [ $_->ncancelled_pkgs ] } @cust_main;
70 my(%all_pkgs) = 
71   map { $_->custnum => [ $_->all_pkgs ] } @cust_main;
72
73 if ( scalar(@cust_main) == 1 ) {
74   print $cgi->redirect(popurl(2). "view/cust_main.cgi?". $cust_main[0]->custnum);
75   exit;
76 } elsif ( scalar(@cust_main) == 0 ) {
77   idiot "No matching customers found!\n";
78   exit;
79 } else { 
80
81   my($total)=scalar(@cust_main);
82   print $cgi->header, header("Customer Search Results",menubar(
83     'Main Menu', popurl(2)
84   )), "$total matching customers found<BR>", table, <<END;
85       <TR>
86         <TH></TH>
87         <TH>Contact name</TH>
88         <TH>Company</TH>
89         <TH>Packages</TH>
90         <TH COLSPAN=2>Services</TH>
91       </TR>
92 END
93
94   my(%saw,$cust_main);
95   foreach $cust_main (
96     sort $sortby grep(!$saw{$_->custnum}++, @cust_main)
97   ) {
98     my($custnum,$last,$first,$company)=(
99       $cust_main->custnum,
100       $cust_main->getfield('last'),
101       $cust_main->getfield('first'),
102       $cust_main->company,
103     );
104
105     my(@lol_cust_svc);
106     my($rowspan)=0;#scalar( @{$all_pkgs{$custnum}} );
107     foreach ( @{$all_pkgs{$custnum}} ) {
108       my(@cust_svc) = qsearch( 'cust_svc', { 'pkgnum' => $_->pkgnum } );
109       push @lol_cust_svc, \@cust_svc;
110       $rowspan += scalar(@cust_svc) || 1;
111     }
112
113     #my($rowspan) = scalar(@{$all_pkgs{$custnum}});
114     my($view) = popurl(2). "/view/cust_main.cgi?$custnum";
115     print <<END;
116     <TR>
117       <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>$custnum</FONT></A></TD>
118       <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>$last, $first</FONT></A></TD>
119       <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>$company</FONT></A></TD>
120 END
121
122     my($n1)='';
123     foreach ( @{$all_pkgs{$custnum}} ) {
124       my($pkgnum) = ($_->pkgnum);
125       my($pkg) = $_->part_pkg->pkg;
126       my($pkgview) = popurl(2). "/view/cust_pkg.cgi?$pkgnum";
127       #my(@cust_svc) = shift @lol_cust_svc;
128       my(@cust_svc) = qsearch( 'cust_svc', { 'pkgnum' => $_->pkgnum } );
129       my($rowspan) = scalar(@cust_svc) || 1;
130
131       print $n1, qq!<TD ROWSPAN=$rowspan><A HREF="$pkgview"><FONT SIZE=-1>$pkg</FONT></A></TD>!;
132       my($n2)='';
133       foreach my $cust_svc ( @cust_svc ) {
134          my($label, $value, $svcdb) = $cust_svc->label;
135          my($svcnum) = $cust_svc->svcnum;
136          my($sview) = popurl(2). "/view";
137          print $n2,qq!<TD><A HREF="$sview/$svcdb.cgi?$svcnum"><FONT SIZE=-1>$label</FONT></A></TD>!,
138                qq!<TD><A HREF="$sview/$svcdb.cgi?$svcnum"><FONT SIZE=-1>$value</FONT></A></TD>!;
139          $n2="</TR><TR>";
140       }
141       #print qq!</TR><TR>\n!;
142       $n1="</TR><TR>";
143     }
144     print "<\TR>";
145   }
146  
147   print <<END;
148     </TABLE>
149     </CENTER>
150   </BODY>
151 </HTML>
152 END
153
154 }
155
156 #
157
158 sub last_sort {
159   $a->getfield('last') cmp $b->getfield('last');
160 }
161
162 sub company_sort {
163   return -1 if $a->company && ! $b->company;
164   return 1 if ! $a->company && $b->company;
165   $a->getfield('company') cmp $b->getfield('company');
166 }
167
168 sub custnum_sort {
169   $a->getfield('custnum') <=> $b->getfield('custnum');
170 }
171
172 sub cardsearch {
173
174   my($card)=$cgi->param('card');
175   $card =~ s/\D//g;
176   $card =~ /^(\d{13,16})$/ or do { idiot "Illegal card number\n"; exit; };
177   my($payinfo)=$1;
178
179   push @cust_main, qsearch('cust_main',{'payinfo'=>$payinfo, 'payby'=>'CARD'});
180
181 }
182
183 sub lastsearch {
184   my(%last_type);
185   foreach ( $cgi->param('last_type') ) {
186     $last_type{$_}++;
187   }
188
189   $cgi->param('last_text') =~ /^([\w \,\.\-\']*)$/
190     or do { idiot "Illegal last name"; exit; };
191   my($last)=$1;
192
193   if ( $last_type{'Exact'}
194        && ! $last_type{'Fuzzy'} 
195      #  && ! $last_type{'Sound-alike'}
196   ) {
197
198     push @cust_main, qsearch('cust_main',{'last'=>$last});
199
200   } else {
201
202     my(%last);
203
204     my(@all_last)=map $_->getfield('last'), qsearch('cust_main',{});
205     if ($last_type{'Fuzzy'}) { 
206       foreach ( amatch($last, [ qw(i) ], @all_last) ) {
207         $last{$_}++; 
208       }
209     }
210
211     #if ($last_type{'Sound-alike'}) {
212     #}
213
214     foreach ( keys %last ) {
215       push @cust_main, qsearch('cust_main',{'last'=>$_});
216     }
217
218   }
219   $sortby=\*last_sort;
220 }
221
222 sub companysearch {
223
224   my(%company_type);
225   foreach ( $cgi->param('company_type') ) {
226     $company_type{$_}++ 
227   };
228
229   $cgi->param('company_text') =~ /^([\w \,\.\-\']*)$/
230     or do { idiot "Illegal company"; exit; };
231   my($company)=$1;
232
233   if ( $company_type{'Exact'}
234        && ! $company_type{'Fuzzy'} 
235      #  && ! $company_type{'Sound-alike'}
236   ) {
237
238     push @cust_main, qsearch('cust_main',{'company'=>$company});
239
240   } else {
241
242     my(%company);
243     my(@all_company)=map $_->company, qsearch('cust_main',{});
244
245     if ($company_type{'Fuzzy'}) { 
246       foreach ( amatch($company, [ qw(i) ], @all_company ) ) {
247         $company{$_}++;
248       }
249     }
250
251     #if ($company_type{'Sound-alike'}) {
252     #}
253
254     foreach ( keys %company ) {
255       push @cust_main, qsearch('cust_main',{'company'=>$_});
256     }
257
258   }
259   $sortby=\*company_sort;
260
261 }