customer-to-customer referrals in singup server
[freeside.git] / httemplate / search / cust_main.cgi
1 <%
2 #<!-- $Id: cust_main.cgi,v 1.4 2001-08-28 16:58:08 ivan Exp $ -->
3
4 use strict;
5 #use vars qw( $conf %ncancelled_pkgs %all_pkgs $cgi @cust_main $sortby );
6 use vars qw( $conf %all_pkgs $cgi @cust_main $sortby );
7 use CGI;
8 use CGI::Carp qw(fatalsToBrowser);
9 use IO::Handle;
10 use String::Approx qw(amatch);
11 use FS::UID qw(cgisuidsetup);
12 use FS::Record qw(qsearch qsearchs dbdef);
13 use FS::CGI qw(header menubar eidiot popurl table);
14 use FS::cust_main;
15 use FS::cust_svc;
16
17 $cgi = new CGI;
18 cgisuidsetup($cgi);
19
20 $conf = new FS::Conf;
21
22 if ( $cgi->keywords ) {
23   my($query)=$cgi->keywords;
24   if ( $query eq 'custnum' ) {
25     $sortby=\*custnum_sort;
26     @cust_main=qsearch('cust_main',{});  
27   } elsif ( $query eq 'last' ) {
28     $sortby=\*last_sort;
29     @cust_main=qsearch('cust_main',{});  
30   } elsif ( $query eq 'company' ) {
31     $sortby=\*company_sort;
32     @cust_main=qsearch('cust_main',{});
33   } else {
34     die "unknown query string $query";
35   }
36 } else {
37   @cust_main=();
38   &cardsearch if $cgi->param('card_on') && $cgi->param('card');
39   &lastsearch if $cgi->param('last_on') && $cgi->param('last_text');
40   &companysearch if $cgi->param('company_on') && $cgi->param('company_text');
41   &referralsearch if $cgi->param('referral_custnum');
42 }
43
44 @cust_main = grep { $_->ncancelled_pkgs || ! $_->all_pkgs } @cust_main
45   if $conf->exists('hidecancelledcustomers');
46 if ( $conf->exists('hidecancelledpackages' ) ) {
47   %all_pkgs = map { $_->custnum => [ $_->ncancelled_pkgs ] } @cust_main;
48 } else {
49   %all_pkgs = map { $_->custnum => [ $_->all_pkgs ] } @cust_main;
50 }
51
52 if ( scalar(@cust_main) == 1 && ! $cgi->param('referral_custnum') ) {
53   print $cgi->redirect(popurl(2). "view/cust_main.cgi?". $cust_main[0]->custnum);
54   exit;
55 } elsif ( scalar(@cust_main) == 0 ) {
56   eidiot "No matching customers found!\n";
57 } else { 
58
59   my($total)=scalar(@cust_main);
60   print $cgi->header( '-expires' => 'now' ), header("Customer Search Results",menubar(
61     'Main Menu', popurl(2)
62   )), "$total matching customers found";
63   if ( $cgi->param('referral_custnum') ) {
64     $cgi->param('referral_custnum') =~ /^(\d+)$/
65       or eidiot "Illegal referral_custnum\n";
66     my $referral_custnum = $1;
67     my $cust_main = qsearchs('cust_main', { custnum => $referral_custnum } );
68     print '<FORM METHOD=POST>'.
69           qq!<INPUT TYPE="hidden" NAME="referral_custnum" VALUE="$referral_custnum">!.
70           'referrals of <A HREF="'. popurl(2).
71           "view/cust_main.cgi?$referral_custnum\">$referral_custnum: ".
72           ( $cust_main->company
73             || $cust_main->last. ', '. $cust_main->first ).
74           '</A>';
75     print "\n",<<END;
76       <SCRIPT>
77       function changed(what) {
78         what.form.submit();
79       }
80       </SCRIPT>
81 END
82     print ' <SELECT NAME="referral_depth" SIZE="1" onChange="changed(this)">';
83     my $max = 8; #config file
84     $cgi->param('referral_depth') =~ /^(\d*)$/ 
85       or eidiot "Illegal referral_depth";
86     my $referral_depth = $1;
87
88     foreach my $depth ( 1 .. $max ) {
89       print '<OPTION',
90             ' SELECTED'x($depth == $referral_depth),
91             ">$depth";
92     }
93     print "</SELECT> levels deep".
94           '<NOSCRIPT> <INPUT TYPE="submit" VALUE="change"></NOSCRIPT>'.
95           '</FORM>';
96   }
97   print "<BR>", &table(), <<END;
98       <TR>
99         <TH></TH>
100         <TH>(bill) name</TH>
101         <TH>company</TH>
102 END
103
104 if ( defined dbdef->table('cust_main')->column('ship_last') ) {
105   print <<END;
106       <TH>(service) name</TH>
107       <TH>company</TH>
108 END
109 }
110
111 print <<END;
112         <TH>Packages</TH>
113         <TH COLSPAN=2>Services</TH>
114       </TR>
115 END
116
117   my(%saw,$cust_main);
118   foreach $cust_main (
119     sort $sortby grep(!$saw{$_->custnum}++, @cust_main)
120   ) {
121     my($custnum,$last,$first,$company)=(
122       $cust_main->custnum,
123       $cust_main->getfield('last'),
124       $cust_main->getfield('first'),
125       $cust_main->company,
126     );
127
128     my(@lol_cust_svc);
129     my($rowspan)=0;#scalar( @{$all_pkgs{$custnum}} );
130     foreach ( @{$all_pkgs{$custnum}} ) {
131       my(@cust_svc) = qsearch( 'cust_svc', { 'pkgnum' => $_->pkgnum } );
132       push @lol_cust_svc, \@cust_svc;
133       $rowspan += scalar(@cust_svc) || 1;
134     }
135
136     #my($rowspan) = scalar(@{$all_pkgs{$custnum}});
137     my($view) = popurl(2). "view/cust_main.cgi?$custnum";
138     print <<END;
139     <TR>
140       <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>$custnum</FONT></A></TD>
141       <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>$last, $first</FONT></A></TD>
142       <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>$company</FONT></A></TD>
143 END
144     if ( defined dbdef->table('cust_main')->column('ship_last') ) {
145       my($ship_last,$ship_first,$ship_company)=(
146         $cust_main->ship_last || $cust_main->getfield('last'),
147         $cust_main->ship_last ? $cust_main->ship_first : $cust_main->first,
148         $cust_main->ship_last ? $cust_main->ship_company : $cust_main->company,
149       );
150 print <<END;
151       <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>$ship_last, $ship_first</FONT></A></TD>
152       <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>$ship_company</FONT></A></TD>
153 END
154     }
155
156     my($n1)='';
157     foreach ( @{$all_pkgs{$custnum}} ) {
158       my($pkgnum) = ($_->pkgnum);
159       my($pkg) = $_->part_pkg->pkg;
160       my $comment = $_->part_pkg->comment;
161       my($pkgview) = popurl(2). "/view/cust_pkg.cgi?$pkgnum";
162       #my(@cust_svc) = shift @lol_cust_svc;
163       my(@cust_svc) = qsearch( 'cust_svc', { 'pkgnum' => $_->pkgnum } );
164       my($rowspan) = scalar(@cust_svc) || 1;
165
166       print $n1, qq!<TD ROWSPAN=$rowspan><A HREF="$pkgview"><FONT SIZE=-1>$pkg - $comment</FONT></A></TD>!;
167       my($n2)='';
168       foreach my $cust_svc ( @cust_svc ) {
169          my($label, $value, $svcdb) = $cust_svc->label;
170          my($svcnum) = $cust_svc->svcnum;
171          my($sview) = popurl(2). "/view";
172          print $n2,qq!<TD><A HREF="$sview/$svcdb.cgi?$svcnum"><FONT SIZE=-1>$label</FONT></A></TD>!,
173                qq!<TD><A HREF="$sview/$svcdb.cgi?$svcnum"><FONT SIZE=-1>$value</FONT></A></TD>!;
174          $n2="</TR><TR>";
175       }
176       #print qq!</TR><TR>\n!;
177       $n1="</TR><TR>";
178     }
179     print "</TR>";
180   }
181  
182   print <<END;
183     </TABLE>
184   </BODY>
185 </HTML>
186 END
187
188 }
189
190 #
191
192 sub last_sort {
193   $a->getfield('last') cmp $b->getfield('last');
194 }
195
196 sub company_sort {
197   return -1 if $a->company && ! $b->company;
198   return 1 if ! $a->company && $b->company;
199   $a->getfield('company') cmp $b->getfield('company');
200 }
201
202 sub custnum_sort {
203   $a->getfield('custnum') <=> $b->getfield('custnum');
204 }
205
206 sub cardsearch {
207
208   my($card)=$cgi->param('card');
209   $card =~ s/\D//g;
210   $card =~ /^(\d{13,16})$/ or eidiot "Illegal card number\n";
211   my($payinfo)=$1;
212
213   push @cust_main, qsearch('cust_main',{'payinfo'=>$payinfo, 'payby'=>'CARD'});
214   $sortby=\*last_sort;
215 }
216
217 sub referralsearch {
218   $cgi->param('referral_custnum') =~ /^(\d+)$/
219     or eidiot "Illegal referral_custnum";
220   my $cust_main = qsearchs('cust_main', { 'custnum' => $1 } )
221     or eidiot "Customer $1 not found";
222   my $depth;
223   if ( $cgi->param('referral_depth') ) {
224     $cgi->param('referral_depth') =~ /^(\d+)$/
225       or eidiot "Illegal referral_depth";
226     $depth = $1;
227   } else {
228     $depth = 1;
229   }
230   push @cust_main, $cust_main->referral_cust_main($depth);
231   $sortby=\*last_sort;
232 }
233
234 sub lastsearch {
235   my(%last_type);
236   foreach ( $cgi->param('last_type') ) {
237     $last_type{$_}++;
238   }
239
240   $cgi->param('last_text') =~ /^([\w \,\.\-\']*)$/
241     or eidiot "Illegal last name";
242   my($last)=$1;
243
244   if ( $last_type{'Exact'}
245        && ! $last_type{'Fuzzy'} 
246      #  && ! $last_type{'Sound-alike'}
247   ) {
248
249     push @cust_main, qsearch('cust_main',{'last'=>$last});
250
251     push @cust_main, qsearch('cust_main',{'ship_last'=>$last})
252       if defined dbdef->table('cust_main')->column('ship_last');
253
254   } else {
255
256     my(%last);
257
258     my(@all_last)=map $_->getfield('last'), qsearch('cust_main',{});
259     push @all_last, grep $_, map $_->getfield('ship_last'), qsearch('cust_main',{})
260       if defined dbdef->table('cust_main')->column('ship_last');
261     if ($last_type{'Fuzzy'}) { 
262       foreach ( amatch($last, [ qw(i) ], @all_last) ) {
263         $last{$_}++; 
264       }
265     }
266
267     #if ($last_type{'Sound-alike'}) {
268     #}
269
270     foreach ( keys %last ) {
271       push @cust_main, qsearch('cust_main',{'last'=>$_});
272       push @cust_main, qsearch('cust_main',{'ship_last'=>$_})
273         if defined dbdef->table('cust_main')->column('ship_last');
274     }
275
276   }
277   $sortby=\*last_sort;
278 }
279
280 sub companysearch {
281
282   my(%company_type);
283   foreach ( $cgi->param('company_type') ) {
284     $company_type{$_}++ 
285   };
286
287   $cgi->param('company_text') =~ /^([\w \,\.\-\']*)$/
288     or eidiot "Illegal company";
289   my($company)=$1;
290
291   if ( $company_type{'Exact'}
292        && ! $company_type{'Fuzzy'} 
293      #  && ! $company_type{'Sound-alike'}
294   ) {
295
296     push @cust_main, qsearch('cust_main',{'company'=>$company});
297
298     push @cust_main, qsearch('cust_main',{'ship_company'=>$company})
299       if defined dbdef->table('cust_main')->column('ship_last');
300
301   } else {
302
303     my(%company);
304     my(@all_company)=map $_->company, qsearch('cust_main',{});
305     push @all_company, grep $_, map $_->getfield('ship_company'), qsearch('cust_main',{})
306       if defined dbdef->table('cust_main')->column('ship_last');
307
308     if ($company_type{'Fuzzy'}) { 
309       foreach ( amatch($company, [ qw(i) ], @all_company ) ) {
310         $company{$_}++;
311       }
312     }
313
314     #if ($company_type{'Sound-alike'}) {
315     #}
316
317     foreach ( keys %company ) {
318       push @cust_main, qsearch('cust_main',{'company'=>$_});
319       push @cust_main, qsearch('cust_main',{'ship_company'=>$_})
320         if defined dbdef->table('cust_main')->column('ship_last');
321     }
322
323   }
324   $sortby=\*company_sort;
325
326 }
327 %>