7d5941a16d42abd2b714fffe6d67c3ea66944d38
[freeside.git] / httemplate / search / cust_main.cgi
1 <%
2
3 my $conf = new FS::Conf;
4 my $maxrecords = $conf->config('maxsearchrecordsperpage');
5
6 #my $cache;
7
8 #my $monsterjoin = <<END;
9 #cust_main left outer join (
10 #  ( cust_pkg left outer join part_pkg using(pkgpart)
11 #  ) left outer join (
12 #    (
13 #      (
14 #        ( cust_svc left outer join part_svc using (svcpart)
15 #        ) left outer join svc_acct using (svcnum)
16 #      ) left outer join svc_domain using(svcnum)
17 #    ) left outer join svc_forward using(svcnum)
18 #  ) using (pkgnum)
19 #) using (custnum)
20 #END
21
22 #my $monsterjoin = <<END;
23 #cust_main left outer join (
24 #  ( cust_pkg left outer join part_pkg using(pkgpart)
25 #  ) left outer join (
26 #    (
27 #      (
28 #        ( cust_svc left outer join part_svc using (svcpart)
29 #        ) left outer join (
30 #          svc_acct left outer join (
31 #            select svcnum, domain, catchall from svc_domain
32 #            ) as svc_acct_domsvc (
33 #              svc_acct_svcnum, svc_acct_domain, svc_acct_catchall
34 #          ) on svc_acct.domsvc = svc_acct_domsvc.svc_acct_svcnum
35 #        ) using (svcnum)
36 #      ) left outer join svc_domain using(svcnum)
37 #    ) left outer join svc_forward using(svcnum)
38 #  ) using (pkgnum)
39 #) using (custnum)
40 #END
41
42 my $limit = '';
43 $limit .= "LIMIT $maxrecords" if $maxrecords;
44
45 my $offset = $cgi->param('offset') || 0;
46 $limit .= " OFFSET $offset" if $offset;
47
48 my $total = 0;
49
50 my(@cust_main, $sortby, $orderby);
51 my @select = ();
52 my @addl_headers = ();
53 my @addl_cols = ();
54 if ( $cgi->param('browse')
55      || $cgi->param('otaker_on')
56      || $cgi->param('agentnum_on')
57 ) {
58
59   my %search = ();
60
61   if ( $cgi->param('browse') ) {
62     my $query = $cgi->param('browse');
63     if ( $query eq 'custnum' ) {
64       $sortby=\*custnum_sort;
65       $orderby = "ORDER BY custnum";
66     } elsif ( $query eq 'last' ) {
67       $sortby=\*last_sort;
68       $orderby = "ORDER BY LOWER(last || ' ' || first)";
69     } elsif ( $query eq 'company' ) {
70       $sortby=\*company_sort;
71       $orderby = "ORDER BY LOWER(company || ' ' || last || ' ' || first )";
72     } elsif ( $query eq 'tickets' ) {
73       $sortby = \*tickets_sort;
74       $orderby = "ORDER BY tickets DESC";
75       push @select, FS::TicketSystem->sql_num_customer_tickets. " as tickets";
76       push @addl_headers, 'Tickets';
77       push @addl_cols, 'tickets';
78     } else {
79       die "unknown browse field $query";
80     }
81   } else {
82     $sortby = \*last_sort; #??
83     $orderby = "ORDER BY LOWER(last || ' ' || first)"; #??
84   }
85
86   if ( $cgi->param('otaker_on') ) {
87     $cgi->param('otaker') =~ /^(\w{1,32})$/ or eidiot "Illegal otaker\n";
88     $search{otaker} = $1;
89   } elsif ( $cgi->param('agentnum_on') ) {
90     $cgi->param('agentnum') =~ /^(\d+)$/ or eidiot "Illegal agentnum\n";
91     $search{agentnum} = $1;
92 #  } else {
93 #    die "unknown query...";
94   }
95
96   my @qual = ();
97
98   my $ncancelled = '';
99
100   if (  $cgi->param('showcancelledcustomers') eq '0' #see if it was set by me
101        || ( $conf->exists('hidecancelledcustomers')
102              && ! $cgi->param('showcancelledcustomers') )
103      ) {
104     #grep { $_->ncancelled_pkgs || ! $_->all_pkgs }
105     push @qual, FS::cust_main->uncancel_sql;
106
107    }
108
109   push @qual, FS::cust_main->cancel_sql   if $cgi->param('cancelled');
110   push @qual, FS::cust_main->prospect_sql if $cgi->param('prospect');
111   push @qual, FS::cust_main->active_sql   if $cgi->param('active');
112   push @qual, FS::cust_main->susp_sql     if $cgi->param('suspended');
113
114   #EWWWWWW
115   my $qual = join(' AND ',
116             map { "$_ = ". dbh->quote($search{$_}) } keys %search );
117
118   my $addl_qual = join(' AND ', @qual);
119
120   #here is the agent virtualization
121   $addl_qual .= ( $addl_qual ? ' AND ' : '' ).
122                 $FS::CurrentUser::CurrentUser->agentnums_sql;
123
124   if ( $addl_qual ) {
125     $qual .= ' AND ' if $qual;
126     $qual .= $addl_qual;
127   }
128     
129   $qual = " WHERE $qual" if $qual;
130   my $statement = "SELECT COUNT(*) FROM cust_main $qual";
131   my $sth = dbh->prepare($statement) or die dbh->errstr." preparing $statement";
132   $sth->execute or die "Error executing \"$statement\": ". $sth->errstr;
133
134   $total = $sth->fetchrow_arrayref->[0];
135
136   if ( $addl_qual ) {
137     if ( %search ) {
138       $addl_qual = " AND $addl_qual";
139     } else {
140       $addl_qual = " WHERE $addl_qual";
141     }
142   }
143
144   my $select;
145   if ( @select ) {
146     $select = 'cust_main.*, '. join (', ', @select);
147   } else {
148     $select = '*';
149   }
150
151   @cust_main = qsearch('cust_main', \%search, $select,   
152                          "$addl_qual $orderby $limit" );
153
154 #  foreach my $cust_main ( @just_cust_main ) {
155 #
156 #    my @one_cust_main;
157 #    $FS::Record::DEBUG=1;
158 #    ( $cache, @one_cust_main ) = jsearch(
159 #      "$monsterjoin",
160 #      { 'custnum' => $cust_main->custnum },
161 #      '',
162 #      '',
163 #      'cust_main',
164 #      'custnum',
165 #    );
166 #    push @cust_main, @one_cust_main;
167 #  }
168
169 } else {
170   @cust_main=();
171   $sortby = \*last_sort;
172
173   push @cust_main, @{&custnumsearch}
174     if $cgi->param('custnum_on') && $cgi->param('custnum_text');
175   push @cust_main, @{&cardsearch}
176     if $cgi->param('card_on') && $cgi->param('card');
177   push @cust_main, @{&lastsearch}
178     if $cgi->param('last_on') && $cgi->param('last_text');
179   push @cust_main, @{&companysearch}
180     if $cgi->param('company_on') && $cgi->param('company_text');
181   push @cust_main, @{&address2search}
182     if $cgi->param('address2_on') && $cgi->param('address2_text');
183   push @cust_main, @{&phonesearch}
184     if $cgi->param('phone_on') && $cgi->param('phone_text');
185   push @cust_main, @{&referralsearch}
186     if $cgi->param('referral_custnum');
187
188   if ( $cgi->param('company_on') && $cgi->param('company_text') ) {
189     $sortby = \*company_sort;
190     push @cust_main, @{&companysearch};
191   }
192
193   if ( $cgi->param('search_cust') ) {
194     $sortby = \*company_sort;
195     $orderby = "ORDER BY LOWER(company || ' ' || last || ' ' || first )";
196     warn "smart searching for: ". $cgi->param('search_cust');
197     push @cust_main, smart_search( 'search' => $cgi->param('search_cust') );
198   }
199
200   @cust_main = grep { $_->ncancelled_pkgs || ! $_->all_pkgs } @cust_main
201     if ! $cgi->param('cancelled')
202        && (
203          $cgi->param('showcancelledcustomers') eq '0' #see if it was set by me
204          || ( $conf->exists('hidecancelledcustomers')
205                && ! $cgi->param('showcancelledcustomers') )
206        );
207
208   my %saw = ();
209   @cust_main = grep { !$saw{$_->custnum}++ } @cust_main;
210 }
211
212 my %all_pkgs;
213 if ( $conf->exists('hidecancelledpackages' ) ) {
214   %all_pkgs = map { $_->custnum => [ $_->ncancelled_pkgs ] } @cust_main;
215 } else {
216   %all_pkgs = map { $_->custnum => [ $_->all_pkgs ] } @cust_main;
217 }
218 #%all_pkgs = ();
219
220 if ( scalar(@cust_main) == 1 && ! $cgi->param('referral_custnum') ) {
221   if ( $cgi->param('quickpay') eq 'yes' ) {
222     print $cgi->redirect(popurl(2). "edit/cust_pay.cgi?quickpay=yes;custnum=". $cust_main[0]->custnum);
223   } else {
224     print $cgi->redirect(popurl(2). "view/cust_main.cgi?". $cust_main[0]->custnum);
225   }
226   #exit;
227 } elsif ( scalar(@cust_main) == 0 ) {
228 %>
229 <!-- mason kludge -->
230 <%
231   eidiot "No matching customers found!\n";
232 } else { 
233 %>
234 <%= include('/elements/header.html', "Customer Search Results", '' ) %>
235
236   <% $total ||= scalar(@cust_main); %>
237
238   <%= $total %> matching customers found
239
240   <%
241   #begin pager
242   my $pager = '';
243   if ( $total != scalar(@cust_main) && $maxrecords ) {
244     unless ( $offset == 0 ) {
245       $cgi->param('offset', $offset - $maxrecords);
246       $pager .= '<A HREF="'. $cgi->self_url.
247                 '"><B><FONT SIZE="+1">Previous</FONT></B></A> ';
248     }
249     my $poff;
250     my $page;
251     for ( $poff = 0; $poff < $total; $poff += $maxrecords ) {
252       $page++;
253       if ( $offset == $poff ) {
254         $pager .= qq!<FONT SIZE="+2">$page</FONT> !;
255       } else {
256         $cgi->param('offset', $poff);
257         $pager .= qq!<A HREF="!. $cgi->self_url. qq!">$page</A> !;
258       }
259     }
260     unless ( $offset + $maxrecords > $total ) {
261       $cgi->param('offset', $offset + $maxrecords);
262       $pager .= '<A HREF="'. $cgi->self_url.
263                 '"><B><FONT SIZE="+1">Next</FONT></B></A> ';
264     }
265   }
266   #end pager
267
268   unless ( $cgi->param('cancelled') ) {
269     if ( $cgi->param('showcancelledcustomers') eq '0' #see if it was set by me
270          || ( $conf->exists('hidecancelledcustomers')
271               && ! $cgi->param('showcancelledcustomers')
272             )
273        ) {
274       $cgi->param('showcancelledcustomers', 1);
275       $cgi->param('offset', 0);
276       print qq!( <a href="!. $cgi->self_url. qq!">show!;
277     } else {
278       $cgi->param('showcancelledcustomers', 0);
279       $cgi->param('offset', 0);
280       print qq!( <a href="!. $cgi->self_url. qq!">hide!;
281     }
282     print ' cancelled customers</a> )';
283   }
284
285   if ( $cgi->param('referral_custnum') ) {
286     $cgi->param('referral_custnum') =~ /^(\d+)$/
287       or eidiot "Illegal referral_custnum\n";
288     my $referral_custnum = $1;
289     my $cust_main = qsearchs('cust_main', { custnum => $referral_custnum } );
290     print '<FORM METHOD="GET">'.
291           qq!<INPUT TYPE="hidden" NAME="referral_custnum" VALUE="$referral_custnum">!.
292           'referrals of <A HREF="'. popurl(2).
293           "view/cust_main.cgi?$referral_custnum\">$referral_custnum: ".
294           ( $cust_main->company
295             || $cust_main->last. ', '. $cust_main->first ).
296           '</A>';
297     print "\n",<<END;
298       <SCRIPT>
299       function changed(what) {
300         what.form.submit();
301       }
302       </SCRIPT>
303 END
304     print ' <SELECT NAME="referral_depth" SIZE="1" onChange="changed(this)">';
305     my $max = 8; #config file
306     $cgi->param('referral_depth') =~ /^(\d*)$/ 
307       or eidiot "Illegal referral_depth";
308     my $referral_depth = $1;
309
310     foreach my $depth ( 1 .. $max ) {
311       print '<OPTION',
312             ' SELECTED'x($depth == $referral_depth),
313             ">$depth";
314     }
315     print "</SELECT> levels deep".
316           '<NOSCRIPT> <INPUT TYPE="submit" VALUE="change"></NOSCRIPT>'.
317           '</FORM>';
318   }
319
320   my @custom_priorities = ();
321   if ( $conf->config('ticket_system-custom_priority_field')
322        && @{[ $conf->config('ticket_system-custom_priority_field-values') ]} ) {
323     @custom_priorities =
324       $conf->config('ticket_system-custom_priority_field-values');
325   }
326
327   print "<BR><BR>". $pager. include('/elements/table-grid.html'). <<END;
328       <TR>
329         <TH CLASS="grid" BGCOLOR="#cccccc"></TH>
330         <TH CLASS="grid" BGCOLOR="#cccccc">(bill) name</TH>
331         <TH CLASS="grid" BGCOLOR="#cccccc">company</TH>
332 END
333
334 if ( defined dbdef->table('cust_main')->column('ship_last') ) {
335   print <<END;
336       <TH CLASS="grid" BGCOLOR="#cccccc">(service) name</TH>
337       <TH CLASS="grid" BGCOLOR="#cccccc">company</TH>
338 END
339 }
340
341 foreach my $addl_header ( @addl_headers ) {
342   print '<TH CLASS="grid" BGCOLOR="#cccccc">'. "$addl_header</TH>";
343 }
344
345 print <<END;
346         <TH CLASS="grid" BGCOLOR="#cccccc">Packages</TH>
347         <TH CLASS="grid" BGCOLOR="#cccccc" COLSPAN=2>Services</TH>
348       </TR>
349 END
350
351   my $bgcolor1 = '#eeeeee';
352   my $bgcolor2 = '#ffffff';
353   my $bgcolor;
354
355   my(%saw,$cust_main);
356   foreach $cust_main (
357     sort $sortby grep(!$saw{$_->custnum}++, @cust_main)
358   ) {
359
360     if ( $bgcolor eq $bgcolor1 ) {
361       $bgcolor = $bgcolor2;
362     } else {
363       $bgcolor = $bgcolor1;
364     }
365
366     my($custnum,$last,$first,$company)=(
367       $cust_main->custnum,
368       $cust_main->getfield('last'),
369       $cust_main->getfield('first'),
370       $cust_main->company,
371     );
372
373     my(@lol_cust_svc);
374     my($rowspan)=0;#scalar( @{$all_pkgs{$custnum}} );
375     foreach ( @{$all_pkgs{$custnum}} ) {
376       #my(@cust_svc) = qsearch( 'cust_svc', { 'pkgnum' => $_->pkgnum } );
377       my @cust_svc = $_->cust_svc;
378       push @lol_cust_svc, \@cust_svc;
379       $rowspan += scalar(@cust_svc) || 1;
380     }
381
382     #my($rowspan) = scalar(@{$all_pkgs{$custnum}});
383     my $view;
384     if ( defined $cgi->param('quickpay') && $cgi->param('quickpay') eq 'yes' ) {
385       $view = $p. 'edit/cust_pay.cgi?quickpay=yes;custnum='. $custnum;
386     } else {
387       $view = $p. 'view/cust_main.cgi?'. $custnum;
388     }
389     my $pcompany = $company
390       ? qq!<A HREF="$view"><FONT SIZE=-1>$company</FONT></A>!
391       : '<FONT SIZE=-1>&nbsp;</FONT>';
392     %>
393
394     <TR>
395       <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>" ROWSPAN=<%= $rowspan || 1 %>><A HREF="<%= $view %>"><FONT SIZE=-1><%= $custnum %></FONT></A></TD>
396       <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>" ROWSPAN=<%= $rowspan || 1 %>><A HREF="<%= $view %>"><FONT SIZE=-1><%= "$last, $first" %></FONT></A></TD>
397       <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>" ROWSPAN=<%= $rowspan || 1 %>><%= $pcompany %></TD>
398
399     <%
400     if ( defined dbdef->table('cust_main')->column('ship_last') ) {
401       my($ship_last,$ship_first,$ship_company)=(
402         $cust_main->ship_last || $cust_main->getfield('last'),
403         $cust_main->ship_last ? $cust_main->ship_first : $cust_main->first,
404         $cust_main->ship_last ? $cust_main->ship_company : $cust_main->company,
405       );
406       my $pship_company = $ship_company
407         ? qq!<A HREF="$view"><FONT SIZE=-1>$ship_company</FONT></A>!
408         : '<FONT SIZE=-1>&nbsp;</FONT>';
409       %>
410
411       <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>" ROWSPAN=<%= $rowspan || 1 %>><A HREF="<%= $view %>"><FONT SIZE=-1><%= "$ship_last, $ship_first" %></FONT></A></TD>
412       <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>" ROWSPAN=<%= $rowspan || 1 %>><%= $pship_company %></A></TD>
413
414     <% }
415
416     foreach my $addl_col ( @addl_cols ) { %>
417
418       <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>" ROWSPAN=<%= $rowspan || 1 %> ALIGN=right><FONT SIZE=-1>
419
420       <% if ( $addl_col eq 'tickets' ) {
421         if ( @custom_priorities ) {
422           print &itable('', 0);
423           foreach my $priority ( @custom_priorities, '' ) {
424           
425             my $num =
426               FS::TicketSystem->num_customer_tickets($custnum,$priority);
427             my $ahref = '';
428             $ahref= '<A HREF="'.
429                     FS::TicketSystem->href_customer_tickets($custnum,$priority).
430                     '">'
431               if $num;
432
433             print '<TR>'.
434                   "  <TD ALIGN=right><FONT SIZE=-1>$ahref$num</A></FONT></TD>".
435                   "<TD ALIGN=left><FONT SIZE=-1>$ahref".
436                   ( $priority || '<i>(none)</i>' ).
437                   "</A></FONT></TD></TR>";
438
439           }
440           print '<TR><TD BGCOLOR="#000000" COLSPAN=2></TD></TR>'.
441                 '<TR><TD ALIGN=right><FONT SIZE=-1>';
442         }
443
444         my $ahref = '';
445         $ahref = '<A HREF="'.
446                     FS::TicketSystem->href_customer_tickets($custnum).
447                     '">'
448           if $cust_main->get($addl_col);
449
450         print $ahref. $cust_main->get($addl_col). '</A>';
451         print "</FONT></TD><TD ALIGN=left>".
452               "<FONT SIZE=-1>${ahref}Total</A><FONT>".
453               "</TD></TR></TABLE>"
454           if @custom_priorities;
455
456       } else {
457         print $cust_main->get($addl_col);
458       }
459       print "</FONT></TD>";
460     }
461
462     my($n1)='';
463     foreach ( @{$all_pkgs{$custnum}} ) {
464       my $pkgnum = $_->pkgnum;
465 #      my $part_pkg = qsearchs( 'part_pkg', { pkgpart => $_->pkgpart } );
466       my $part_pkg = $_->part_pkg;
467
468       my $pkg = $part_pkg->pkg;
469       my $comment = $part_pkg->comment;
470       my $pkgview = "${p}view/cust_main.cgi?$custnum#cust_pkg$pkgnum";
471       my @cust_svc = @{shift @lol_cust_svc};
472       #my(@cust_svc) = qsearch( 'cust_svc', { 'pkgnum' => $_->pkgnum } );
473       my $rowspan = scalar(@cust_svc) || 1;
474
475       print $n1, qq!<TD CLASS="grid" BGCOLOR="$bgcolor"  ROWSPAN=$rowspan><A HREF="$pkgview"><FONT SIZE=-1>$pkg - $comment</FONT></A></TD>!;
476
477       my($n2)='';
478       foreach my $cust_svc ( @cust_svc ) {
479          my($label, $value, $svcdb) = $cust_svc->label;
480          my($svcnum) = $cust_svc->svcnum;
481          my($sview) = $p.'view';
482          print $n2,qq!<TD CLASS="grid" BGCOLOR="$bgcolor" ><A HREF="$sview/$svcdb.cgi?$svcnum"><FONT SIZE=-1>$label</FONT></A></TD>!,
483                qq!<TD CLASS="grid" BGCOLOR="$bgcolor" ><A HREF="$sview/$svcdb.cgi?$svcnum"><FONT SIZE=-1>$value</FONT></A></TD>!;
484          $n2="</TR><TR>";
485       }
486
487       unless ( @cust_svc ) {
488         print qq!<TD CLASS="grid" BGCOLOR="$bgcolor" COLSPAN=2>&nbsp;</TD>!;
489       }
490
491       #print qq!</TR><TR>\n!;
492       $n1="</TR><TR>";
493     }
494
495     unless ( @{$all_pkgs{$custnum}} ) {
496       print qq!<TD CLASS="grid" BGCOLOR="$bgcolor" COLSPAN=3>&nbsp;</TD>!;
497     }
498     
499     print "</TR>";
500   }
501
502   %>
503  
504   </TABLE><%= $pager %>
505
506   <%= include('/elements/footer.html') %>
507
508 <% }
509
510 #undef $cache; #does this help?
511
512 #
513
514 sub last_sort {
515   lc($a->getfield('last')) cmp lc($b->getfield('last'))
516   || lc($a->first) cmp lc($b->first);
517 }
518
519 sub company_sort {
520   return -1 if $a->company && ! $b->company;
521   return 1 if ! $a->company && $b->company;
522   lc($a->company) cmp lc($b->company)
523   || lc($a->getfield('last')) cmp lc($b->getfield('last'))
524   || lc($a->first) cmp lc($b->first);;
525 }
526
527 sub custnum_sort {
528   $a->getfield('custnum') <=> $b->getfield('custnum');
529 }
530
531 sub tickets_sort {
532   $b->getfield('tickets') <=> $a->getfield('tickets');
533 }
534
535 sub custnumsearch {
536
537   my $custnum = $cgi->param('custnum_text');
538   $custnum =~ s/\D//g;
539   $custnum =~ /^(\d{1,23})$/ or eidiot "Illegal customer number\n";
540   $custnum = $1;
541   
542   [ qsearchs('cust_main', { 'custnum' => $custnum } ) ];
543 }
544
545 sub cardsearch {
546
547   my($card)=$cgi->param('card');
548   $card =~ s/\D//g;
549   $card =~ /^(\d{13,16})$/ or eidiot "Illegal card number\n";
550   my($payinfo)=$1;
551
552   [ qsearch('cust_main',{'payinfo'=>$payinfo, 'payby'=>'CARD'}),
553     qsearch('cust_main',{'payinfo'=>$payinfo, 'payby'=>'DCRD'})
554   ];
555 }
556
557 sub referralsearch {
558   $cgi->param('referral_custnum') =~ /^(\d+)$/
559     or eidiot "Illegal referral_custnum";
560   my $cust_main = qsearchs('cust_main', { 'custnum' => $1 } )
561     or eidiot "Customer $1 not found";
562   my $depth;
563   if ( $cgi->param('referral_depth') ) {
564     $cgi->param('referral_depth') =~ /^(\d+)$/
565       or eidiot "Illegal referral_depth";
566     $depth = $1;
567   } else {
568     $depth = 1;
569   }
570   [ $cust_main->referral_cust_main($depth) ];
571 }
572
573 sub lastsearch {
574   my(%last_type);
575   my @cust_main;
576   foreach ( $cgi->param('last_type') ) {
577     $last_type{$_}++;
578   }
579
580   $cgi->param('last_text') =~ /^([\w \,\.\-\']*)$/
581     or eidiot "Illegal last name";
582   my($last)=$1;
583
584   if ( $last_type{'Exact'} || $last_type{'Fuzzy'} ) {
585     push @cust_main, qsearch( 'cust_main',
586                               { 'last' => { 'op'    => 'ILIKE',
587                                             'value' => $last    } } );
588
589     push @cust_main, qsearch( 'cust_main',
590                               { 'ship_last' => { 'op'    => 'ILIKE',
591                                                  'value' => $last    } } )
592       if defined dbdef->table('cust_main')->column('ship_last');
593   }
594
595   if ( $last_type{'Substring'} || $last_type{'All'} ) {
596
597     push @cust_main, qsearch( 'cust_main',
598                               { 'last' => { 'op'    => 'ILIKE',
599                                             'value' => "%$last%" } } );
600
601     push @cust_main, qsearch( 'cust_main',
602                               { 'ship_last' => { 'op'    => 'ILIKE',
603                                                  'value' => "%$last%" } } )
604       if defined dbdef->table('cust_main')->column('ship_last');
605
606   }
607
608   if ( $last_type{'Fuzzy'} || $last_type{'All'} ) {
609     push @cust_main, FS::cust_main->fuzzy_search( { 'last' => $last } );
610   }
611
612   #if ($last_type{'Sound-alike'}) {
613   #}
614
615   \@cust_main;
616 }
617
618 sub companysearch {
619
620   my(%company_type);
621   my @cust_main;
622   foreach ( $cgi->param('company_type') ) {
623     $company_type{$_}++ 
624   };
625
626   $cgi->param('company_text') =~
627     /^([\w \!\@\#\$\%\&\(\)\-\+\;\:\'\"\,\.\?\/\=]*)$/
628       or eidiot "Illegal company";
629   my $company = $1;
630
631   if ( $company_type{'Exact'} || $company_type{'Fuzzy'} ) {
632     push @cust_main, qsearch( 'cust_main',
633                               { 'company' => { 'op'    => 'ILIKE',
634                                                'value' => $company } } );
635
636     push @cust_main, qsearch( 'cust_main',
637                               { 'ship_company' => { 'op'    => 'ILIKE',
638                                                     'value' => $company } } )
639       if defined dbdef->table('cust_main')->column('ship_last');
640   }
641
642   if ( $company_type{'Substring'} || $company_type{'All'} ) {
643
644     push @cust_main, qsearch( 'cust_main',
645                               { 'company' => { 'op'    => 'ILIKE',
646                                                'value' => "%$company%" } } );
647
648     push @cust_main, qsearch( 'cust_main',
649                               { 'ship_company' => { 'op'    => 'ILIKE',
650                                                     'value' => "%$company%" } })
651       if defined dbdef->table('cust_main')->column('ship_last');
652
653   }
654
655   if ( $company_type{'Fuzzy'} || $company_type{'All'} ) {
656     push @cust_main, FS::cust_main->fuzzy_search( { 'company' => $company } );
657   }
658
659   if ($company_type{'Sound-alike'}) {
660   }
661
662   \@cust_main;
663 }
664
665 sub address2search {
666   my @cust_main;
667
668   $cgi->param('address2_text') =~
669     /^([\w \!\@\#\$\%\&\(\)\-\+\;\:\'\"\,\.\?\/\=]*)$/
670       or eidiot "Illegal address2";
671   my $address2 = $1;
672
673   push @cust_main, qsearch( 'cust_main',
674                             { 'address2' => { 'op'    => 'ILIKE',
675                                               'value' => $address2 } } );
676   push @cust_main, qsearch( 'cust_main',
677                             { 'address2' => { 'op'    => 'ILIKE',
678                                               'value' => $address2 } } )
679     if defined dbdef->table('cust_main')->column('ship_last');
680
681   \@cust_main;
682 }
683
684 sub phonesearch {
685   my @cust_main;
686
687   my $phone = $cgi->param('phone_text');
688
689   #(no longer really) false laziness with Record::ut_phonen
690   #only works with US/CA numbers...
691   $phone =~ s/\D//g;
692   if ( $phone =~ /^(\d{3})(\d{3})(\d{4})(\d*)$/ ) {
693     $phone = "$1-$2-$3";
694     $phone .= " x$4" if $4;
695   } elsif ( $phone =~ /^(\d{3})(\d{4})$/ ) {
696     $phone = "$1-$2";
697   } elsif ( $phone =~ /^(\d{3,4})$/ ) {
698     $phone = $1;
699   } else {
700     eidiot gettext('illegal_phone'). ": $phone";
701   }
702
703   my @fields = qw(daytime night fax);
704   push @fields, qw(ship_daytime ship_night ship_fax)
705     if defined dbdef->table('cust_main')->column('ship_last');
706
707   for my $field ( @fields ) {
708     push @cust_main, qsearch ( 'cust_main', 
709                                { $field => { 'op'    => 'LIKE',
710                                              'value' => "%$phone%" } } );
711   }
712
713   \@cust_main;
714 }
715
716 %>