summaryrefslogtreecommitdiff
path: root/httemplate/search
diff options
context:
space:
mode:
Diffstat (limited to 'httemplate/search')
-rwxr-xr-xhttemplate/search/cust_bill.cgi180
-rwxr-xr-xhttemplate/search/cust_bill.html21
-rwxr-xr-xhttemplate/search/cust_main-payinfo.html20
-rwxr-xr-xhttemplate/search/cust_main.cgi315
-rwxr-xr-xhttemplate/search/cust_main.html36
-rwxr-xr-xhttemplate/search/cust_pkg.cgi155
-rwxr-xr-xhttemplate/search/svc_acct.cgi211
-rwxr-xr-xhttemplate/search/svc_acct.html21
-rwxr-xr-xhttemplate/search/svc_acct_sm.cgi144
-rwxr-xr-xhttemplate/search/svc_acct_sm.html23
-rwxr-xr-xhttemplate/search/svc_domain.cgi214
-rwxr-xr-xhttemplate/search/svc_domain.html22
12 files changed, 1362 insertions, 0 deletions
diff --git a/httemplate/search/cust_bill.cgi b/httemplate/search/cust_bill.cgi
new file mode 100755
index 000000000..5550b5513
--- /dev/null
+++ b/httemplate/search/cust_bill.cgi
@@ -0,0 +1,180 @@
+<%
+#
+# $Id: cust_bill.cgi,v 1.1 2001-07-30 07:36:04 ivan Exp $
+#
+# Usage: post form to:
+# http://server.name/path/cust_bill.cgi
+#
+# ivan@voicenet.com 97-apr-4
+#
+# Changes to allow page to work at a relative position in server
+# bmccane@maxbaud.net 98-apr-3
+#
+# $Log: cust_bill.cgi,v $
+# Revision 1.1 2001-07-30 07:36:04 ivan
+# templates!!!
+#
+# Revision 1.6 2001/04/22 01:38:39 ivan
+# svc_domain needs to import dbh sub from Record
+# view/cust_main.cgi needs to use ->owed method, not check (depriciated) owed field
+# search/cust_bill.cgi redirect error when there's only one invoice
+#
+# Revision 1.5 2000/07/17 16:45:41 ivan
+# first shot at invoice browsing and some other cleanups
+#
+# Revision 1.4 1999/02/28 00:03:54 ivan
+# removed misleading comments
+#
+# Revision 1.3 1999/01/19 05:14:11 ivan
+# for mod_perl: no more top-level my() variables; use vars instead
+# also the last s/create/new/;
+#
+# Revision 1.2 1998/12/17 09:41:07 ivan
+# s/CGI::(Base|Request)/CGI.pm/;
+#
+
+use strict;
+use vars qw ( $cgi $invnum $query $sortby @cust_bill );
+use CGI;
+use CGI::Carp qw(fatalsToBrowser);
+use Date::Format;
+use FS::UID qw(cgisuidsetup);
+use FS::CGI qw(popurl header menubar eidiot table );
+use FS::Record qw(qsearch qsearchs);
+use FS::cust_bill;
+use FS::cust_main;
+
+$cgi = new CGI;
+cgisuidsetup($cgi);
+
+if ( $cgi->keywords ) {
+ my($query) = $cgi->keywords;
+ if ( $query eq 'invnum' ) {
+ $sortby = \*invnum_sort;
+ @cust_bill = qsearch('cust_bill', {} );
+ } elsif ( $query eq 'date' ) {
+ $sortby = \*date_sort;
+ @cust_bill = qsearch('cust_bill', {} );
+ } elsif ( $query eq 'custnum' ) {
+ $sortby = \*custnum_sort;
+ @cust_bill = qsearch('cust_bill', {} );
+ } elsif ( $query eq 'OPEN_invnum' ) {
+ $sortby = \*invnum_sort;
+ @cust_bill = grep $_->owed != 0, qsearch('cust_bill', {} );
+ } elsif ( $query eq 'OPEN_date' ) {
+ $sortby = \*date_sort;
+ @cust_bill = grep $_->owed != 0, qsearch('cust_bill', {} );
+ } elsif ( $query eq 'OPEN_custnum' ) {
+ $sortby = \*custnum_sort;
+ @cust_bill = grep $_->owed != 0, qsearch('cust_bill', {} );
+ } elsif ( $query =~ /^OPEN(\d+)_invnum$/ ) {
+ my $open = $1 * 86400;
+ $sortby = \*invnum_sort;
+ @cust_bill =
+ grep $_->owed != 0 && $_->_date < time - $open, qsearch('cust_bill', {} );
+ } elsif ( $query =~ /^OPEN(\d+)_date$/ ) {
+ my $open = $1 * 86400;
+ $sortby = \*date_sort;
+ @cust_bill =
+ grep $_->owed != 0 && $_->_date < time - $open, qsearch('cust_bill', {} );
+ } elsif ( $query =~ /^OPEN(\d+)_custnum$/ ) {
+ my $open = $1 * 86400;
+ $sortby = \*custnum_sort;
+ @cust_bill =
+ grep $_->owed != 0 && $_->_date < time - $open, qsearch('cust_bill', {} );
+ } else {
+ die "unknown query string $query";
+ }
+} else {
+ $cgi->param('invnum') =~ /^\s*(FS-)?(\d+)\s*$/;
+ $invnum = $2;
+ @cust_bill = qsearchs('cust_bill', { 'invnum' => $invnum } );
+ $sortby = \*invnum_sort;
+}
+
+if ( scalar(@cust_bill) == 1 ) {
+ my $invnum = $cust_bill[0]->invnum;
+ print $cgi->redirect(popurl(2). "view/cust_bill.cgi?$invnum"); #redirect
+} elsif ( scalar(@cust_bill) == 0 ) {
+ eidiot("Invoice not found.");
+} else {
+ my $total = scalar(@cust_bill);
+ print $cgi->header( '-expires' => 'now' ),
+ &header("Invoice Search Results", menubar(
+ 'Main Menu', popurl(2)
+ )), "$total matching invoices found<BR>", &table(), <<END;
+ <TR>
+ <TH></TH>
+ <TH>Balance</TH>
+ <TH>Amount</TH>
+ <TH>Date</TH>
+ <TH>Contact name</TH>
+ <TH>Company</TH>
+ </TR>
+END
+
+ my(%saw, $cust_bill);
+ foreach $cust_bill (
+ sort $sortby grep(!$saw{$_->invnum}++, @cust_bill)
+ ) {
+ my($invnum, $owed, $charged, $date ) = (
+ $cust_bill->invnum,
+ $cust_bill->owed,
+ $cust_bill->charged,
+ $cust_bill->_date,
+ );
+ my $pdate = time2str("%b %d %Y", $date);
+
+ my $rowspan = 1;
+
+ my $view = popurl(2). "view/cust_bill.cgi?$invnum";
+ print <<END;
+ <TR>
+ <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>$invnum</FONT></A></TD>
+ <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>\$$owed</FONT></A></TD>
+ <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>\$$charged</FONT></A></TD>
+ <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>$pdate</FONT></A></TD>
+END
+ my $custnum = $cust_bill->custnum;
+ my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } );
+ if ( $cust_main ) {
+ my $cview = popurl(2). "view/cust_main.cgi?". $cust_main->custnum;
+ my ( $name, $company ) = (
+ $cust_main->last. ', '. $cust_main->first,
+ $cust_main->company,
+ );
+ print <<END;
+ <TD ROWSPAN=$rowspan><A HREF="$cview"><FONT SIZE=-1>$name</FONT></A></TD>
+ <TD ROWSPAN=$rowspan><A HREF="$cview"><FONT SIZE=-1>$company</FONT></A></TD>
+END
+ } else {
+ print <<END
+ <TD ROWSPAN=$rowspan COLSPAN=2>WARNING: couldn't find cust_main.custnum $custnum (cust_bill.invnum $invnum)</TD>
+END
+ }
+
+ print "</TR>";
+ }
+
+ print <<END;
+ </TABLE>
+ </BODY>
+</HTML>
+END
+
+}
+
+#
+
+sub invnum_sort {
+ $a->invnum <=> $b->invnum;
+}
+
+sub custnum_sort {
+ $a->custnum <=> $b->custnum || $a->invnum <=> $b->invnum;
+}
+
+sub date_sort {
+ $a->_date <=> $b->_date || $a->invnum <=> $b->invnum;
+}
+%>
diff --git a/httemplate/search/cust_bill.html b/httemplate/search/cust_bill.html
new file mode 100755
index 000000000..4adb40e4a
--- /dev/null
+++ b/httemplate/search/cust_bill.html
@@ -0,0 +1,21 @@
+<HTML>
+ <HEAD>
+ <TITLE>Invoice Search</TITLE>
+ </HEAD>
+ <BODY>
+ <CENTER>
+ <H1>Invoice Search</H1>
+ </CENTER>
+ <HR>
+ <FORM ACTION="cust_bill.cgi" METHOD="post">
+ Search for <B>invoice #</B>:
+ <INPUT TYPE="text" NAME="invnum">
+
+ <P><INPUT TYPE="submit" VALUE="Search">
+
+ </FORM>
+
+ <HR>
+ </BODY>
+</HTML>
+
diff --git a/httemplate/search/cust_main-payinfo.html b/httemplate/search/cust_main-payinfo.html
new file mode 100755
index 000000000..47bb83cbd
--- /dev/null
+++ b/httemplate/search/cust_main-payinfo.html
@@ -0,0 +1,20 @@
+<HTML>
+ <HEAD>
+ <TITLE>Customer Search</TITLE>
+ </HEAD>
+ <BODY BGCOLOR="#ffffff">
+ <FONT COLOR="#ff0000" SIZE=7>
+ Customer Search
+ </FONT>
+ <BR>
+ <FORM ACTION="cust_main.cgi" METHOD="post">
+ Search for <B>Credit card #</B>:
+ <INPUT TYPE="hidden" NAME="card_on" VALUE="TRUE">
+ <INPUT TYPE="text" NAME="card">
+
+ <P><INPUT TYPE="submit" VALUE="Search">
+
+ </FORM>
+ </BODY>
+</HTML>
+
diff --git a/httemplate/search/cust_main.cgi b/httemplate/search/cust_main.cgi
new file mode 100755
index 000000000..844bb98b8
--- /dev/null
+++ b/httemplate/search/cust_main.cgi
@@ -0,0 +1,315 @@
+<%
+#
+# $Id: cust_main.cgi,v 1.1 2001-07-30 07:36:04 ivan Exp $
+#
+# Usage: post form to:
+# http://server.name/path/cust_main.cgi
+#
+# ivan@voicenet.com 96-dec-12
+#
+# rewrite ivan@sisd.com 98-mar-4
+#
+# now does browsing too ivan@sisd.com 98-mar-6
+#
+# Changes to allow page to work at a relative position in server
+# bmccane@maxbaud.net 98-apr-3
+#
+# display total, use FS::CGI ivan@sisd.com 98-jul-17
+#
+# $Log: cust_main.cgi,v $
+# Revision 1.1 2001-07-30 07:36:04 ivan
+# templates!!!
+#
+# Revision 1.17 2001/04/23 16:07:54 ivan
+# fix
+# Insecure dependency in eval while running with -T switch at /usr/local/lib/site_perl/FS/Record.pm line 202.
+#
+# Revision 1.16 2001/02/07 19:45:45 ivan
+# tyop
+#
+# Revision 1.15 2000/07/17 16:45:41 ivan
+# first shot at invoice browsing and some other cleanups
+#
+# Revision 1.14 1999/08/12 04:45:21 ivan
+# typo - missed a paren
+#
+# Revision 1.13 1999/08/12 04:32:21 ivan
+# hidecancelledcustomers
+#
+# Revision 1.12 1999/07/17 10:38:52 ivan
+# scott nelson <scott@ultimanet.com> noticed this mod_perl-triggered bug and
+# gave me a great bugreport at the last rhythmethod
+#
+# Revision 1.11 1999/04/09 04:22:34 ivan
+# also table()
+#
+# Revision 1.10 1999/04/09 03:52:55 ivan
+# explicit & for table/itable/ntable
+#
+# Revision 1.9 1999/02/28 00:03:55 ivan
+# removed misleading comments
+#
+# 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 vars qw( $conf %ncancelled_pkgs %all_pkgs $cgi @cust_main $sortby );
+use vars qw( $conf %all_pkgs $cgi @cust_main $sortby );
+use CGI;
+use CGI::Carp qw(fatalsToBrowser);
+use IO::Handle;
+use String::Approx qw(amatch);
+use FS::UID qw(cgisuidsetup);
+use FS::Record qw(qsearch qsearchs);
+use FS::CGI qw(header menubar eidiot popurl table);
+use FS::cust_main;
+use FS::cust_svc;
+
+$cgi = new CGI;
+cgisuidsetup($cgi);
+
+$conf = new FS::Conf;
+
+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 {
+ die "unknown query string $query";
+ }
+} else {
+ @cust_main=();
+ &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') );
+}
+
+@cust_main = grep { $_->ncancelled_pkgs || ! $_->all_pkgs } @cust_main
+ if $conf->exists('hidecancelledcustomers');
+if ( $conf->exists('hidecancelledpackages' ) ) {
+ %all_pkgs = map { $_->custnum => [ $_->ncancelled_pkgs ] } @cust_main;
+} else {
+ %all_pkgs = map { $_->custnum => [ $_->all_pkgs ] } @cust_main;
+}
+
+if ( scalar(@cust_main) == 1 ) {
+ print $cgi->redirect(popurl(2). "view/cust_main.cgi?". $cust_main[0]->custnum);
+ exit;
+} elsif ( scalar(@cust_main) == 0 ) {
+ eidiot "No matching customers found!\n";
+} else {
+
+ my($total)=scalar(@cust_main);
+ print $cgi->header( '-expires' => 'now' ), header("Customer Search Results",menubar(
+ 'Main Menu', popurl(2)
+ )), "$total matching customers found<BR>", &table(), <<END;
+ <TR>
+ <TH></TH>
+ <TH>Contact name</TH>
+ <TH>Company</TH>
+ <TH>Packages</TH>
+ <TH COLSPAN=2>Services</TH>
+ </TR>
+END
+
+ my(%saw,$cust_main);
+ foreach $cust_main (
+ sort $sortby grep(!$saw{$_->custnum}++, @cust_main)
+ ) {
+ my($custnum,$last,$first,$company)=(
+ $cust_main->custnum,
+ $cust_main->getfield('last'),
+ $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 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>
+ </BODY>
+</HTML>
+END
+
+}
+
+#
+
+sub last_sort {
+ $a->getfield('last') cmp $b->getfield('last');
+}
+
+sub company_sort {
+ return -1 if $a->company && ! $b->company;
+ return 1 if ! $a->company && $b->company;
+ $a->getfield('company') cmp $b->getfield('company');
+}
+
+sub custnum_sort {
+ $a->getfield('custnum') <=> $b->getfield('custnum');
+}
+
+sub cardsearch {
+
+ my($card)=$cgi->param('card');
+ $card =~ s/\D//g;
+ $card =~ /^(\d{13,16})$/ or eidiot "Illegal card number\n";
+ my($payinfo)=$1;
+
+ push @cust_main, qsearch('cust_main',{'payinfo'=>$payinfo, 'payby'=>'CARD'});
+
+}
+
+sub lastsearch {
+ my(%last_type);
+ foreach ( $cgi->param('last_type') ) {
+ $last_type{$_}++;
+ }
+
+ $cgi->param('last_text') =~ /^([\w \,\.\-\']*)$/
+ or eidiot "Illegal last name";
+ my($last)=$1;
+
+ if ( $last_type{'Exact'}
+ && ! $last_type{'Fuzzy'}
+ # && ! $last_type{'Sound-alike'}
+ ) {
+
+ push @cust_main, qsearch('cust_main',{'last'=>$last});
+
+ } else {
+
+ my(%last);
+
+ my(@all_last)=map $_->getfield('last'), qsearch('cust_main',{});
+ if ($last_type{'Fuzzy'}) {
+ foreach ( amatch($last, [ qw(i) ], @all_last) ) {
+ $last{$_}++;
+ }
+ }
+
+ #if ($last_type{'Sound-alike'}) {
+ #}
+
+ foreach ( keys %last ) {
+ push @cust_main, qsearch('cust_main',{'last'=>$_});
+ }
+
+ }
+ $sortby=\*last_sort;
+}
+
+sub companysearch {
+
+ my(%company_type);
+ foreach ( $cgi->param('company_type') ) {
+ $company_type{$_}++
+ };
+
+ $cgi->param('company_text') =~ /^([\w \,\.\-\']*)$/
+ or eidiot "Illegal company";
+ my($company)=$1;
+
+ if ( $company_type{'Exact'}
+ && ! $company_type{'Fuzzy'}
+ # && ! $company_type{'Sound-alike'}
+ ) {
+
+ push @cust_main, qsearch('cust_main',{'company'=>$company});
+
+ } else {
+
+ my(%company);
+ my(@all_company)=map $_->company, qsearch('cust_main',{});
+
+ if ($company_type{'Fuzzy'}) {
+ foreach ( amatch($company, [ qw(i) ], @all_company ) ) {
+ $company{$_}++;
+ }
+ }
+
+ #if ($company_type{'Sound-alike'}) {
+ #}
+
+ foreach ( keys %company ) {
+ push @cust_main, qsearch('cust_main',{'company'=>$_});
+ }
+
+ }
+ $sortby=\*company_sort;
+
+}
+%>
diff --git a/httemplate/search/cust_main.html b/httemplate/search/cust_main.html
new file mode 100755
index 000000000..3184698b4
--- /dev/null
+++ b/httemplate/search/cust_main.html
@@ -0,0 +1,36 @@
+<HTML>
+ <HEAD>
+ <TITLE>Customer Search</TITLE>
+ </HEAD>
+ <BODY BGCOLOR="#ffffff">
+ <FONT COLOR="#ff0000" SIZE=7>
+ Customer Search
+ </FONT>
+ <BR>
+ <FORM ACTION="cust_main.cgi" METHOD="post">
+ <INPUT TYPE="checkbox" NAME="last_on" CHECKED> Search for <B>last name</B>:
+ <INPUT TYPE="text" NAME="last_text">
+ using search method: <SELECT NAME="last_type">
+ <OPTION SELECTED>Fuzzy
+ <OPTION>Exact
+ </SELECT>
+
+ <P><INPUT TYPE="checkbox" NAME="company_on" CHECKED> Search for <B>company</B>:
+ <INPUT TYPE="text" NAME="company_text">
+ using search methods: <SELECT NAME="company_type">
+ <OPTION SELECTED>Fuzzy
+ <OPTION>Exact
+ </SELECT>
+
+ <P><INPUT TYPE="submit" VALUE="Search"> Note: Fuzzy searching can take a while. Please be patient.
+
+ </FORM>
+
+ <HR>Explanation of search methods:
+ <UL>
+ <LI><B>Fuzzy</B> - Searches for matches that are close to your text.
+ <LI><B>Exact</B> - Finds exact matches only, but much faster than the other search methods.
+ </UL>
+ </BODY>
+</HTML>
+
diff --git a/httemplate/search/cust_pkg.cgi b/httemplate/search/cust_pkg.cgi
new file mode 100755
index 000000000..d63d2d188
--- /dev/null
+++ b/httemplate/search/cust_pkg.cgi
@@ -0,0 +1,155 @@
+<%
+#
+# $Id: cust_pkg.cgi,v 1.1 2001-07-30 07:36:04 ivan Exp $
+#
+# based on search/svc_acct.cgi ivan@sisd.com 98-jul-17
+#
+# $Log: cust_pkg.cgi,v $
+# Revision 1.1 2001-07-30 07:36:04 ivan
+# templates!!!
+#
+# Revision 1.11 2000/07/17 16:45:41 ivan
+# first shot at invoice browsing and some other cleanups
+#
+# Revision 1.10 2000/07/17 12:49:29 ivan
+# better error message if a package isn't linked to a customer (that shouldn't happen)
+#
+# Revision 1.9 1999/07/17 10:38:52 ivan
+# scott nelson <scott@ultimanet.com> noticed this mod_perl-triggered bug and
+# gave me a great bugreport at the last rhythmethod
+#
+# Revision 1.8 1999/02/09 09:22:57 ivan
+# visual and bugfixes
+#
+# Revision 1.7 1999/02/07 09:59:37 ivan
+# more mod_perl fixes, and bugfixes Peter Wemm sent via email
+#
+# Revision 1.6 1999/01/19 05:14:13 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:38 ivan
+# all $cgi->header calls now include ( '-expires' => 'now' ) for mod_perl
+# (good idea anyway)
+#
+# Revision 1.4 1999/01/18 09:22:33 ivan
+# changes to track email addresses for email invoicing
+#
+# Revision 1.3 1998/12/23 03:05:59 ivan
+# $cgi->keywords instead of $cgi->query_string
+#
+# Revision 1.2 1998/12/17 09:41:09 ivan
+# s/CGI::(Base|Request)/CGI.pm/;
+#
+
+use strict;
+use vars qw ( $cgi @cust_pkg $sortby $query );
+use CGI;
+use CGI::Carp qw(fatalsToBrowser);
+use FS::UID qw(cgisuidsetup);
+use FS::Record qw(qsearch qsearchs);
+use FS::CGI qw(header eidiot popurl);
+use FS::cust_pkg;
+use FS::pkg_svc;
+use FS::cust_svc;
+use FS::cust_main;
+
+$cgi = new CGI;
+&cgisuidsetup($cgi);
+
+($query) = $cgi->keywords;
+#this tree is a little bit redundant
+if ( $query eq 'pkgnum' ) {
+ $sortby=\*pkgnum_sort;
+ @cust_pkg=qsearch('cust_pkg',{});
+} elsif ( $query eq 'APKG_pkgnum' ) {
+ $sortby=\*pkgnum_sort;
+ @cust_pkg=();
+ #perhaps this should go in cust_pkg as a qsearch-like constructor?
+ my($cust_pkg);
+ foreach $cust_pkg (qsearch('cust_pkg',{})) {
+ my($flag)=0;
+ my($pkg_svc);
+ PKG_SVC:
+ foreach $pkg_svc (qsearch('pkg_svc',{ 'pkgpart' => $cust_pkg->pkgpart })) {
+ if ( $pkg_svc->quantity
+ > scalar(qsearch('cust_svc',{
+ 'pkgnum' => $cust_pkg->pkgnum,
+ 'svcpart' => $pkg_svc->svcpart,
+ }))
+ )
+ {
+ $flag=1;
+ last PKG_SVC;
+ }
+ }
+ push @cust_pkg, $cust_pkg if $flag;
+ }
+} else {
+ die "Empty QUERY_STRING!";
+}
+
+if ( scalar(@cust_pkg) == 1 ) {
+ my($pkgnum)=$cust_pkg[0]->pkgnum;
+ print $cgi->redirect(popurl(2). "view/cust_pkg.cgi?$pkgnum");
+ exit;
+} elsif ( scalar(@cust_pkg) == 0 ) { #error
+ eidiot("No packages found");
+} else {
+ my($total)=scalar(@cust_pkg);
+ print $cgi->header( '-expires' => 'now' ), header('Package Search Results',''), <<END;
+ $total matching packages found
+ <TABLE BORDER=4 CELLSPACING=0 CELLPADDING=0>
+ <TR>
+ <TH>Package #</TH>
+ <TH>Customer #</TH>
+ <TH>Contact name</TH>
+ <TH>Company</TH>
+ </TR>
+END
+
+ my(%saw,$cust_pkg);
+ foreach $cust_pkg (
+ sort $sortby grep(!$saw{$_->pkgnum}++, @cust_pkg)
+ ) {
+ my($cust_main)=qsearchs('cust_main',{'custnum'=>$cust_pkg->custnum});
+ my($pkgnum,$custnum,$name,$company)=(
+ $cust_pkg->pkgnum,
+ $cust_pkg->custnum,
+ $cust_main ? $cust_main->last. ', '. $cust_main->first : '',
+ $cust_main ? $cust_main->company : '',
+ );
+ my $p = popurl(2);
+ print <<END;
+ <TR>
+ <TD><A HREF="${p}view/cust_pkg.cgi?$pkgnum"><FONT SIZE=-1>$pkgnum</FONT></A></TD>
+END
+ if ( $cust_main ) {
+ print <<END;
+ <TD><FONT SIZE=-1><A HREF="${p}view/cust_main.cgi?$custnum">$custnum</A></FONT></TD>
+ <TD><FONT SIZE=-1><A HREF="${p}view/cust_main.cgi?$custnum">$name</A></FONT></TD>
+ <TD><FONT SIZE=-1><A HREF="${p}view/cust_main.cgi?$custnum">$company</A></FONT></TD>
+ </TR>
+END
+ } else {
+ print <<END;
+ <TD COLSPAN=3>WARNING: couldn't find cust_main.custnum $custnum (cust_pkg.pkgnum $pkgnum)</TD>
+ </TR>
+END
+ }
+ }
+
+ print <<END;
+ </TABLE>
+ </BODY>
+</HTML>
+END
+ exit;
+
+}
+
+sub pkgnum_sort {
+ $a->getfield('pkgnum') <=> $b->getfield('pkgnum');
+}
+
+%>
diff --git a/httemplate/search/svc_acct.cgi b/httemplate/search/svc_acct.cgi
new file mode 100755
index 000000000..15f74ac20
--- /dev/null
+++ b/httemplate/search/svc_acct.cgi
@@ -0,0 +1,211 @@
+<%
+#
+# $Id: svc_acct.cgi,v 1.1 2001-07-30 07:36:04 ivan Exp $
+#
+# Usage: post form to:
+# http://server.name/path/svc_acct.cgi
+#
+# Note: Should be run setuid freeside as user nobody.
+#
+# loosely (sp?) based on search/cust_main.cgi
+#
+# ivan@voicenet.com 96-jan-3 -> 96-jan-4
+#
+# rewrite (now does browsing too) ivan@sisd.com 98-mar-9
+#
+# Changes to allow page to work at a relative position in server
+# bmccane@maxbaud.net 98-apr-3
+#
+# show unlinked accounts ivan@sisd.com 98-jun-22
+#
+# use FS::CGI, show total ivan@sisd.com 98-jul-17
+#
+# give service and customer info too ivan@sisd.com 98-aug-16
+#
+# $Log: svc_acct.cgi,v $
+# Revision 1.1 2001-07-30 07:36:04 ivan
+# templates!!!
+#
+# Revision 1.11 1999/04/14 11:25:33 ivan
+# *** empty log message ***
+#
+# Revision 1.10 1999/04/14 11:20:21 ivan
+# visual fix
+#
+# Revision 1.9 1999/04/10 01:53:18 ivan
+# oops, search usernames limited to 8 chars
+#
+# Revision 1.8 1999/04/09 23:43:29 ivan
+# just in case
+#
+# Revision 1.7 1999/02/07 09:59:38 ivan
+# more mod_perl fixes, and bugfixes Peter Wemm sent via email
+#
+# Revision 1.6 1999/01/19 05:14:14 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:39 ivan
+# all $cgi->header calls now include ( '-expires' => 'now' ) for mod_perl
+# (good idea anyway)
+#
+# Revision 1.4 1999/01/18 09:22:34 ivan
+# changes to track email addresses for email invoicing
+#
+# Revision 1.3 1998/12/23 03:06:28 ivan
+# $cgi->keywords instead of $cgi->query_string
+#
+# Revision 1.2 1998/12/17 09:41:10 ivan
+# s/CGI::(Base|Request)/CGI.pm/;
+#
+
+use strict;
+use vars qw( $cgi @svc_acct $sortby $query );
+use CGI;
+use CGI::Carp qw(fatalsToBrowser);
+use FS::UID qw(cgisuidsetup);
+use FS::Record qw(qsearch qsearchs);
+use FS::CGI qw(header eidiot popurl table);
+use FS::svc_acct;
+use FS::cust_main;
+
+$cgi = new CGI;
+&cgisuidsetup($cgi);
+
+($query)=$cgi->keywords;
+$query ||= ''; #to avoid use of unitialized value errors
+#this tree is a little bit redundant
+if ( $query eq 'svcnum' ) {
+ $sortby=\*svcnum_sort;
+ @svc_acct=qsearch('svc_acct',{});
+} elsif ( $query eq 'username' ) {
+ $sortby=\*username_sort;
+ @svc_acct=qsearch('svc_acct',{});
+} elsif ( $query eq 'uid' ) {
+ $sortby=\*uid_sort;
+ @svc_acct=grep $_->uid ne '', qsearch('svc_acct',{});
+} elsif ( $query eq 'UN_svcnum' ) {
+ $sortby=\*svcnum_sort;
+ @svc_acct = grep qsearchs('cust_svc',{
+ 'svcnum' => $_->svcnum,
+ 'pkgnum' => '',
+ }), qsearch('svc_acct',{});
+} elsif ( $query eq 'UN_username' ) {
+ $sortby=\*username_sort;
+ @svc_acct = grep qsearchs('cust_svc',{
+ 'svcnum' => $_->svcnum,
+ 'pkgnum' => '',
+ }), qsearch('svc_acct',{});
+} elsif ( $query eq 'UN_uid' ) {
+ $sortby=\*uid_sort;
+ @svc_acct = grep qsearchs('cust_svc',{
+ 'svcnum' => $_->svcnum,
+ 'pkgnum' => '',
+ }), qsearch('svc_acct',{});
+} else {
+ $sortby=\*uid_sort;
+ &usernamesearch;
+}
+
+if ( scalar(@svc_acct) == 1 ) {
+ my($svcnum)=$svc_acct[0]->svcnum;
+ print $cgi->redirect(popurl(2). "view/svc_acct.cgi?$svcnum"); #redirect
+ exit;
+} elsif ( scalar(@svc_acct) == 0 ) { #error
+ eidiot("Account not found");
+} else {
+ my($total)=scalar(@svc_acct);
+ print $cgi->header( '-expires' => 'now' ),
+ header("Account Search Results",''),
+ "$total matching accounts found",
+ &table(), <<END;
+ <TR>
+ <TH><FONT SIZE=-1>Service #</FONT></TH>
+ <TH><FONT SIZE=-1>Username</FONT></TH>
+ <TH><FONT SIZE=-1>UID</FONT></TH>
+ <TH><FONT SIZE=-1>Service</FONT></TH>
+ <TH><FONT SIZE=-1>Customer #</FONT></TH>
+ <TH><FONT SIZE=-1>Contact name</FONT></TH>
+ <TH><FONT SIZE=-1>Company</FONT></TH>
+ </TR>
+END
+
+ my(%saw,$svc_acct);
+ my $p = popurl(2);
+ foreach $svc_acct (
+ sort $sortby grep(!$saw{$_->svcnum}++, @svc_acct)
+ ) {
+ my $cust_svc = qsearchs('cust_svc', { 'svcnum' => $svc_acct->svcnum })
+ or die "No cust_svc record for svcnum ". $svc_acct->svcnum;
+ my $part_svc = qsearchs('part_svc', { 'svcpart' => $cust_svc->svcpart })
+ or die "No part_svc record for svcpart ". $cust_svc->svcpart;
+ my($cust_pkg,$cust_main);
+ if ( $cust_svc->pkgnum ) {
+ $cust_pkg = qsearchs('cust_pkg', { 'pkgnum' => $cust_svc->pkgnum })
+ or die "No cust_pkg record for pkgnum ". $cust_svc->pkgnum;
+ $cust_main = qsearchs('cust_main', { 'custnum' => $cust_pkg->custnum })
+ or die "No cust_main record for custnum ". $cust_pkg->custnum;
+ }
+ my($svcnum,$username,$uid,$svc,$custnum,$last,$first,$company)=(
+ $svc_acct->svcnum,
+ $svc_acct->getfield('username'),
+ $svc_acct->getfield('uid'),
+ $part_svc->svc,
+ $cust_svc->pkgnum ? $cust_main->custnum : '',
+ $cust_svc->pkgnum ? $cust_main->getfield('last') : '',
+ $cust_svc->pkgnum ? $cust_main->getfield('first') : '',
+ $cust_svc->pkgnum ? $cust_main->company : '',
+ );
+ my($pcustnum) = $custnum
+ ? "<A HREF=\"${p}view/cust_main.cgi?$custnum\"><FONT SIZE=-1>$custnum</FONT></A>"
+ : "<I>(unlinked)</I>"
+ ;
+ my($pname) = $custnum ? "<A HREF=\"${p}view/cust_main.cgi?$custnum\">$last, $first</A>" : '';
+ my $pcompany = $custnum ? "<A HREF=\"${p}view/cust_main.cgi?$custnum\">$company</A>" : '';
+ print <<END;
+ <TR>
+ <TD><A HREF="${p}view/svc_acct.cgi?$svcnum"><FONT SIZE=-1>$svcnum</FONT></A></TD>
+ <TD><A HREF="${p}view/svc_acct.cgi?$svcnum"><FONT SIZE=-1>$username</FONT></A></TD>
+ <TD><A HREF="${p}view/svc_acct.cgi?$svcnum"><FONT SIZE=-1>$uid</FONT></A></TD>
+ <TD><FONT SIZE=-1>$svc</FONT></TH>
+ <TD><FONT SIZE=-1>$pcustnum</FONT></TH>
+ <TD><FONT SIZE=-1>$pname<FONT></TH>
+ <TD><FONT SIZE=-1>$pcompany</FONT></TH>
+ </TR>
+END
+
+ }
+
+ print <<END;
+ </TABLE>
+ </CENTER>
+ </BODY>
+</HTML>
+END
+ exit;
+
+}
+
+sub svcnum_sort {
+ $a->getfield('svcnum') <=> $b->getfield('svcnum');
+}
+
+sub username_sort {
+ $a->getfield('username') cmp $b->getfield('username');
+}
+
+sub uid_sort {
+ $a->getfield('uid') <=> $b->getfield('uid');
+}
+
+sub usernamesearch {
+
+ $cgi->param('username') =~ /^([\w\d\-]+)$/; #untaint username_text
+ my($username)=$1;
+
+ @svc_acct=qsearch('svc_acct',{'username'=>$username});
+
+}
+
+
+%>
diff --git a/httemplate/search/svc_acct.html b/httemplate/search/svc_acct.html
new file mode 100755
index 000000000..91291be99
--- /dev/null
+++ b/httemplate/search/svc_acct.html
@@ -0,0 +1,21 @@
+<HTML>
+ <HEAD>
+ <TITLE>Account Search</TITLE>
+ </HEAD>
+ <BODY>
+ <CENTER>
+ <H1>Account Search</H1>
+ </CENTER>
+ <HR>
+ <FORM ACTION="svc_acct.cgi" METHOD="post">
+ Search for <B>username</B>:
+ <INPUT TYPE="text" NAME="username">
+
+ <P><INPUT TYPE="submit" VALUE="Search">
+
+ </FORM>
+
+ <HR>
+ </BODY>
+</HTML>
+
diff --git a/httemplate/search/svc_acct_sm.cgi b/httemplate/search/svc_acct_sm.cgi
new file mode 100755
index 000000000..451e1fd3d
--- /dev/null
+++ b/httemplate/search/svc_acct_sm.cgi
@@ -0,0 +1,144 @@
+<%
+#
+# $Id: svc_acct_sm.cgi,v 1.1 2001-07-30 07:36:04 ivan Exp $
+#
+# Usage: post form to:
+# http://server.name/path/svc_domain.cgi
+#
+# ivan@voicenet.com 96-mar-5
+#
+# need to look at table in results to make it more readable
+#
+# ivan@voicenet.com
+#
+# rewrite ivan@sisd.com 98-mar-15
+#
+# Changes to allow page to work at a relative position in server
+# bmccane@maxbaud.net 98-apr-3
+#
+# $Log: svc_acct_sm.cgi,v $
+# Revision 1.1 2001-07-30 07:36:04 ivan
+# templates!!!
+#
+# Revision 1.10 1999/07/20 06:03:36 ivan
+# s/CGI::Request/CGI/; (how'd i miss that before?)
+#
+# Revision 1.9 1999/04/09 04:22:34 ivan
+# also table()
+#
+# Revision 1.8 1999/04/09 03:52:55 ivan
+# explicit & for table/itable/ntable
+#
+# Revision 1.7 1999/02/28 00:03:56 ivan
+# removed misleading comments
+#
+# Revision 1.6 1999/02/09 09:22:58 ivan
+# visual and bugfixes
+#
+# Revision 1.5 1999/01/19 05:14:16 ivan
+# for mod_perl: no more top-level my() variables; use vars instead
+# also the last s/create/new/;
+#
+# Revision 1.4 1999/01/18 09:41:40 ivan
+# all $cgi->header calls now include ( '-expires' => 'now' ) for mod_perl
+# (good idea anyway)
+#
+# Revision 1.3 1998/12/17 09:41:11 ivan
+# s/CGI::(Base|Request)/CGI.pm/;
+#
+
+use strict;
+use vars qw( $conf $cgi $mydomain $domuser $svc_domain $domsvc @svc_acct_sm );
+use CGI;
+use CGI::Carp qw(fatalsToBrowser);
+use FS::UID qw(cgisuidsetup);
+use FS::CGI qw(popurl idiot header table);
+use FS::Record qw(qsearch qsearchs);
+use FS::Conf;
+use FS::svc_domain;
+use FS::svc_acct_sm;
+use FS::svc_acct;
+
+$cgi = new CGI;
+&cgisuidsetup($cgi);
+
+$conf = new FS::Conf;
+$mydomain = $conf->config('domain');
+
+$cgi->param('domuser') =~ /^([a-z0-9_\-]{0,32})$/;
+$domuser = $1;
+
+$cgi->param('domain') =~ /^([\w\-\.]+)$/ or die "Illegal domain";
+$svc_domain = qsearchs('svc_domain',{'domain'=>$1})
+ or die "Unknown domain";
+$domsvc = $svc_domain->svcnum;
+
+if ($domuser) {
+ @svc_acct_sm=qsearch('svc_acct_sm',{
+ 'domuser' => $domuser,
+ 'domsvc' => $domsvc,
+ });
+} else {
+ @svc_acct_sm=qsearch('svc_acct_sm',{'domsvc' => $domsvc});
+}
+
+if ( scalar(@svc_acct_sm) == 1 ) {
+ my($svcnum)=$svc_acct_sm[0]->svcnum;
+ print $cgi->redirect(popurl(2). "view/svc_acct_sm.cgi?$svcnum");
+} elsif ( scalar(@svc_acct_sm) > 1 ) {
+ print $cgi->header( '-expires' => 'now' ),
+ header('Mail Alias Search Results'),
+ &table(), <<END;
+ <TR>
+ <TH>Mail to<BR><FONT SIZE=-1>(click to view mail alias)</FONT></TH>
+ <TH>Forwards to<BR><FONT SIZE=-1>(click to view account)</FONT></TH>
+ </TR>
+END
+
+ my($svc_acct_sm);
+ foreach $svc_acct_sm (@svc_acct_sm) {
+ my($svcnum,$domuser,$domuid,$domsvc)=(
+ $svc_acct_sm->svcnum,
+ $svc_acct_sm->domuser,
+ $svc_acct_sm->domuid,
+ $svc_acct_sm->domsvc,
+ );
+
+ my $svc_domain = qsearchs( 'svc_domain', { 'svcnum' => $domsvc } );
+ if ( $svc_domain ) {
+ my $domain = $svc_domain->domain;
+
+ print qq!<TR><TD><A HREF="!. popurl(2). qq!view/svc_acct_sm.cgi?$svcnum">!,
+ #print '', ( ($domuser eq '*') ? "<I>(anything)</I>" : $domuser );
+ ( ($domuser eq '*') ? "<I>(anything)</I>" : $domuser ),
+ qq!\@$domain</A> </TD>!,
+ ;
+ } else {
+ my $warning = "couldn't find svc_domain.svcnum $svcnum ( svc_acct_sm.svcnum $svcnum";
+ warn $warning;
+ print "<TR><TD>WARNING: $warning</TD>";
+ }
+
+ my $svc_acct = qsearchs( 'svc_acct', { 'uid' => $domuid } );
+ if ( $svc_acct ) {
+ my $username = $svc_acct->username;
+ my $svc_acct_svcnum =$svc_acct->svcnum;
+ print qq!<TD><A HREF="!, popurl(2),
+ qq!view/svc_acct.cgi?$svc_acct_svcnum">$username\@$mydomain</A>!,
+ qq!</TD></TR>!
+ ;
+ } else {
+ my $warning = "couldn't find svc_acct.uid $domuid (svc_acct_sm.svcnum $svcnum)!";
+ warn $warning;
+ print "<TD>WARNING: $warning</TD></TR>";
+ }
+
+ }
+
+ print '</TABLE></BODY></HTML>';
+
+} else { #error
+ idiot("Mail Alias not found");
+}
+
+%>
diff --git a/httemplate/search/svc_acct_sm.html b/httemplate/search/svc_acct_sm.html
new file mode 100755
index 000000000..0719856db
--- /dev/null
+++ b/httemplate/search/svc_acct_sm.html
@@ -0,0 +1,23 @@
+<HTML>
+ <HEAD>
+ <TITLE>Mail Alias Search</TITLE>
+ </HEAD>
+ <BODY>
+ <CENTER>
+ <H1>Mail Alias Search</H1>
+ </CENTER>
+ <HR>
+ <FORM ACTION="svc_acct_sm.cgi" METHOD="post">
+ Search for <B>mail alias</B>:
+ <INPUT TYPE="text" NAME="domuser"><FONT SIZE=-1>(opt.)</FONT> @
+ <INPUT TYPE="text" NAME="domain"><FONT SIZE=-1>(req.)</FONT>
+
+ <P><INPUT TYPE="submit" VALUE="Search">
+
+ </FORM>
+
+ <HR>
+
+ </BODY>
+</HTML>
+
diff --git a/httemplate/search/svc_domain.cgi b/httemplate/search/svc_domain.cgi
new file mode 100755
index 000000000..8bcf4a694
--- /dev/null
+++ b/httemplate/search/svc_domain.cgi
@@ -0,0 +1,214 @@
+<%
+#
+# $Id: svc_domain.cgi,v 1.1 2001-07-30 07:36:04 ivan Exp $
+#
+# Usage: post form to:
+# http://server.name/path/svc_domain.cgi
+#
+# ivan@voicenet.com 97-mar-5
+#
+# rewrite ivan@sisd.com 98-mar-14
+#
+# Changes to allow page to work at a relative position in server
+# bmccane@maxbaud.net 98-apr-3
+#
+# display total, use FS::CGI now does browsing too ivan@sisd.com 98-jul-17
+#
+# $Log: svc_domain.cgi,v $
+# Revision 1.1 2001-07-30 07:36:04 ivan
+# templates!!!
+#
+# Revision 1.11 2000/03/03 18:22:44 ivan
+# changes from 1.2.3 release, fixes from webdemo
+#
+# Revision 1.10 1999/07/17 10:38:52 ivan
+# scott nelson <scott@ultimanet.com> noticed this mod_perl-triggered bug and
+# gave me a great bugreport at the last rhythmethod
+#
+# Revision 1.9 1999/04/15 13:39:16 ivan
+# $cgi->header( '-expires' => 'now' )
+#
+# Revision 1.8 1999/02/28 00:03:57 ivan
+# removed misleading comments
+#
+# Revision 1.7 1999/02/23 08:09:24 ivan
+# beginnings of one-screen new customer entry and some other miscellania
+#
+# Revision 1.6 1999/02/09 09:22:59 ivan
+# visual and bugfixes
+#
+# Revision 1.5 1999/02/07 09:59:39 ivan
+# more mod_perl fixes, and bugfixes Peter Wemm sent via email
+#
+# Revision 1.4 1999/01/19 05:14:17 ivan
+# for mod_perl: no more top-level my() variables; use vars instead
+# also the last s/create/new/;
+#
+# Revision 1.3 1998/12/23 03:06:50 ivan
+# $cgi->keywords instead of $cgi->query_string
+#
+# Revision 1.2 1998/12/17 09:41:12 ivan
+# s/CGI::(Base|Request)/CGI.pm/;
+#
+
+use strict;
+use vars qw ( $cgi @svc_domain $sortby $query $conf $mydomain );
+use CGI;
+use CGI::Carp qw(fatalsToBrowser);
+use FS::UID qw(cgisuidsetup);
+use FS::Record qw(qsearch qsearchs);
+use FS::CGI qw(header eidiot popurl);
+use FS::svc_domain;
+use FS::cust_svc;
+use FS::svc_acct_sm;
+use FS::svc_acct;
+
+$cgi = new CGI;
+&cgisuidsetup($cgi);
+
+$conf = new FS::Conf;
+$mydomain = $conf->config('domain');
+
+($query)=$cgi->keywords;
+$query ||= ''; #to avoid use of unitialized value errors
+if ( $query eq 'svcnum' ) {
+ $sortby=\*svcnum_sort;
+ @svc_domain=qsearch('svc_domain',{});
+} elsif ( $query eq 'domain' ) {
+ $sortby=\*domain_sort;
+ @svc_domain=qsearch('svc_domain',{});
+} elsif ( $query eq 'UN_svcnum' ) {
+ $sortby=\*svcnum_sort;
+ @svc_domain = grep qsearchs('cust_svc',{
+ 'svcnum' => $_->svcnum,
+ 'pkgnum' => '',
+ }), qsearch('svc_domain',{});
+} elsif ( $query eq 'UN_domain' ) {
+ $sortby=\*domain_sort;
+ @svc_domain = grep qsearchs('cust_svc',{
+ 'svcnum' => $_->svcnum,
+ 'pkgnum' => '',
+ }), qsearch('svc_domain',{});
+} else {
+ $cgi->param('domain') =~ /^([\w\-\.]+)$/;
+ my($domain)=$1;
+ #push @svc_domain, qsearchs('svc_domain',{'domain'=>$domain});
+ @svc_domain = qsearchs('svc_domain',{'domain'=>$domain});
+}
+
+if ( scalar(@svc_domain) == 1 ) {
+ print $cgi->redirect(popurl(2). "view/svc_domain.cgi?". $svc_domain[0]->svcnum);
+ exit;
+} elsif ( scalar(@svc_domain) == 0 ) {
+ eidiot "No matching domains found!\n";
+} else {
+
+ my($total)=scalar(@svc_domain);
+ print $cgi->header( '-expires' => 'now' ),
+ header("Domain Search Results",''), <<END;
+
+ $total matching domains found
+ <TABLE BORDER=4 CELLSPACING=0 CELLPADDING=0>
+ <TR>
+ <TH>Service #</TH>
+ <TH>Domain</TH>
+ <TH>Mail to<BR><FONT SIZE=-1>(click to view mail alias)</FONT></TH>
+ <TH>Forwards to<BR><FONT SIZE=-1>(click to view account)</FONT></TH>
+ </TR>
+END
+
+ my(%saw,$svc_domain);
+ my $p = popurl(2);
+ foreach $svc_domain (
+ sort $sortby grep(!$saw{$_->svcnum}++, @svc_domain)
+ ) {
+ my($svcnum,$domain)=(
+ $svc_domain->svcnum,
+ $svc_domain->domain,
+ );
+ #my($malias);
+ #if ( qsearch('svc_acct_sm',{'domsvc'=>$svcnum}) ) {
+ # $malias=(
+ # qq|<FORM ACTION="svc_acct_sm.cgi" METHOD="post">|.
+ # qq|<INPUT TYPE="hidden" NAME="domuser" VALUE="">|.
+ # qq|<INPUT TYPE="hidden" NAME="domain" VALUE="$domain">|.
+ # qq|<INPUT TYPE="submit" VALUE="(mail aliases)">|.
+ # qq|</FORM>|
+ # );
+ #} else {
+ # $malias='';
+ #}
+
+ my @svc_acct_sm=qsearch('svc_acct_sm',{'domsvc' => $svcnum});
+ my $rowspan = scalar(@svc_acct_sm) || 1;
+
+ print <<END;
+ <TR>
+ <TD ROWSPAN=$rowspan><A HREF="${p}view/svc_domain.cgi?$svcnum"><FONT SIZE=-1>$svcnum</FONT></A></TD>
+ <TD ROWSPAN=$rowspan>$domain</TD>
+END
+
+ my $n1 = '';
+ # false laziness: this was stolen from search/svc_acct_sm.cgi. but the
+ # web interface in general needs to be rewritten in a mucho cleaner way
+ my($svc_acct_sm);
+ foreach $svc_acct_sm (@svc_acct_sm) {
+ my($svcnum,$domuser,$domuid,$domsvc)=(
+ $svc_acct_sm->svcnum,
+ $svc_acct_sm->domuser,
+ $svc_acct_sm->domuid,
+ $svc_acct_sm->domsvc,
+ );
+ #my $svc_domain = qsearchs( 'svc_domain', { 'svcnum' => $domsvc } );
+ #if ( $svc_domain ) {
+ # my $domain = $svc_domain->domain;
+
+ print qq!$n1<TD><A HREF="!. popurl(2). qq!view/svc_acct_sm.cgi?$svcnum">!,
+ #print '', ( ($domuser eq '*') ? "<I>(anything)</I>" : $domuser );
+ ( ($domuser eq '*') ? "<I>(anything)</I>" : $domuser ),
+ qq!\@$domain</A> </TD>!,
+ ;
+ #} else {
+ # my $warning = "couldn't find svc_domain.svcnum $svcnum ( svc_acct_sm.svcnum $svcnum";
+ # warn $warning;
+ # print "$n1<TD>WARNING: $warning</TD>";
+ #}
+
+ my $svc_acct = qsearchs( 'svc_acct', { 'uid' => $domuid } );
+ if ( $svc_acct ) {
+ my $username = $svc_acct->username;
+ my $svc_acct_svcnum =$svc_acct->svcnum;
+ print qq!<TD><A HREF="!, popurl(2),
+ qq!view/svc_acct.cgi?$svc_acct_svcnum">$username\@$mydomain</A>!,
+ qq!</TD></TR>!
+ ;
+ } else {
+ my $warning = "couldn't find svc_acct.uid $domuid (svc_acct_sm.svcnum $svcnum)!";
+ warn $warning;
+ print "<TD>WARNING: $warning</TD>";
+ }
+ $n1 = "</TR><TR>";
+ }
+ #end of false laziness
+ print "</TR>";
+
+ }
+
+ print <<END;
+ </TABLE>
+ </BODY>
+</HTML>
+END
+
+}
+
+sub svcnum_sort {
+ $a->getfield('svcnum') <=> $b->getfield('svcnum');
+}
+
+sub domain_sort {
+ $a->getfield('domain') cmp $b->getfield('doimain');
+}
+
+
+%>
diff --git a/httemplate/search/svc_domain.html b/httemplate/search/svc_domain.html
new file mode 100755
index 000000000..533743ba2
--- /dev/null
+++ b/httemplate/search/svc_domain.html
@@ -0,0 +1,22 @@
+<HTML>
+ <HEAD>
+ <TITLE>Domain Search</TITLE>
+ </HEAD>
+ <BODY>
+ <CENTER>
+ <H1>Domain Search</H1>
+ </CENTER>
+ <HR>
+ <FORM ACTION="svc_domain.cgi" METHOD="post">
+ Search for <B>domain</B>:
+ <INPUT TYPE="text" NAME="domain">
+
+ <P><INPUT TYPE="submit" VALUE="Search">
+
+ </FORM>
+
+ <HR>
+
+ </BODY>
+</HTML>
+