diff options
Diffstat (limited to 'httemplate/search')
-rw-r--r-- | httemplate/search/cust_bill_event.cgi | 2 | ||||
-rwxr-xr-x | httemplate/search/cust_main-quickpay.html | 11 | ||||
-rwxr-xr-x | httemplate/search/cust_main.cgi | 77 | ||||
-rwxr-xr-x | httemplate/search/cust_pay.cgi | 40 | ||||
-rwxr-xr-x | httemplate/search/cust_pkg.cgi | 33 | ||||
-rwxr-xr-x | httemplate/search/cust_pkg.html | 24 | ||||
-rwxr-xr-x | httemplate/search/cust_pkg_report.cgi | 63 | ||||
-rw-r--r-- | httemplate/search/elements/search.html | 59 | ||||
-rwxr-xr-x | httemplate/search/report_cc.html | 44 | ||||
-rwxr-xr-x | httemplate/search/report_credit.html | 44 | ||||
-rw-r--r-- | httemplate/search/report_cust_pay.html | 60 | ||||
-rw-r--r-- | httemplate/search/report_prepaid_income.cgi | 75 | ||||
-rw-r--r-- | httemplate/search/report_prepaid_income.html | 17 | ||||
-rwxr-xr-x | httemplate/search/report_receivables.cgi | 159 | ||||
-rwxr-xr-x | httemplate/search/report_tax.html | 46 | ||||
-rwxr-xr-x | httemplate/search/sql.cgi | 76 | ||||
-rw-r--r-- | httemplate/search/sql.html | 12 | ||||
-rwxr-xr-x | httemplate/search/svc_acct.cgi | 21 | ||||
-rwxr-xr-x | httemplate/search/svc_domain.cgi | 7 | ||||
-rwxr-xr-x | httemplate/search/svc_forward.cgi | 79 |
20 files changed, 738 insertions, 211 deletions
diff --git a/httemplate/search/cust_bill_event.cgi b/httemplate/search/cust_bill_event.cgi index b76f66b76..ec952ea5b 100644 --- a/httemplate/search/cust_bill_event.cgi +++ b/httemplate/search/cust_bill_event.cgi @@ -7,7 +7,7 @@ $cgi->param('beginning') =~ /^([ 0-9\-\/]{0,10})$/; my $beginning = str2time($1) || 0; $cgi->param('ending') =~ /^([ 0-9\-\/]{0,10})$/; -my $ending = str2time($1) + 86400; +my $ending = str2time($1) + 86399; my @cust_bill_event = sort { $a->_date <=> $b->_date } diff --git a/httemplate/search/cust_main-quickpay.html b/httemplate/search/cust_main-quickpay.html index 9f39db914..d48f1d08f 100755 --- a/httemplate/search/cust_main-quickpay.html +++ b/httemplate/search/cust_main-quickpay.html @@ -7,27 +7,28 @@ Quick payment entry </FONT> <BR><BR> + <A HREF="../">Main Menu</A><BR><BR> <FORM ACTION="cust_main.cgi" METHOD="post"> <INPUT TYPE="hidden" NAME="quickpay" VALUE="yes"> <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>All + <OPTION>All <OPTION>Fuzzy <OPTION>Substring - <OPTION>Exact + <OPTION SELECTED>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>All + <OPTION>All <OPTION>Fuzzy <OPTION>Substring - <OPTION>Exact + <OPTION SELECTED>Exact </SELECT> - <P><INPUT TYPE="submit" VALUE="Search"> Note: Fuzzy searching can take a while. Please be patient. + <P><INPUT TYPE="submit" VALUE="Search"> </FORM> diff --git a/httemplate/search/cust_main.cgi b/httemplate/search/cust_main.cgi index 5b39a09f2..50d367e1e 100755 --- a/httemplate/search/cust_main.cgi +++ b/httemplate/search/cust_main.cgi @@ -50,6 +50,7 @@ my $total = 0; my(@cust_main, $sortby, $orderby); if ( $cgi->param('browse') || $cgi->param('otaker_on') + || $cgi->param('agentnum_on') ) { my %search = (); @@ -73,6 +74,9 @@ if ( $cgi->param('browse') if ( $cgi->param('otaker_on') ) { $cgi->param('otaker') =~ /^(\w{1,32})$/ or eidiot "Illegal otaker\n"; $search{otaker} = $1; + } elsif ( $cgi->param('agentnum_on') ) { + $cgi->param('agentnum') =~ /^(\d+)$/ or eidiot "Illegal agentnum\n"; + $search{agentnum} = $1; } else { die "unknown query..."; } @@ -112,6 +116,7 @@ if ( $cgi->param('browse') AND (temp1_$$.count > 0 OR temp2_$$.count = 0 ) "; + } else { $ncancelled = " 0 < ( SELECT COUNT(*) FROM cust_pkg @@ -124,15 +129,32 @@ if ( $cgi->param('browse') WHERE cust_pkg.custnum = cust_main.custnum ) "; - } - + } + } + + my $cancelled = ''; + if ( $cgi->param('cancelled') ) { + $cancelled = " + 0 = ( SELECT COUNT(*) FROM cust_pkg + WHERE cust_pkg.custnum = cust_main.custnum + AND ( cust_pkg.cancel IS NULL + OR cust_pkg.cancel = 0 + ) + ) + AND 0 < ( SELECT COUNT(*) FROM cust_pkg + WHERE cust_pkg.custnum = cust_main.custnum + ) + "; } #EWWWWWW my $qual = join(' AND ', map { "$_ = ". dbh->quote($search{$_}) } keys %search ); - if ( $ncancelled ) { + if ( $cancelled ) { + $qual .= ' AND ' if $qual; + $qual .= $cancelled; + } elsif ( $ncancelled ) { $qual .= ' AND ' if $qual; $qual .= $ncancelled; } @@ -150,21 +172,22 @@ if ( $cgi->param('browse') $total = $sth->fetchrow_arrayref->[0]; - if ( $ncancelled ) { + my $rqual = $cancelled || $ncancelled; + if ( $rqual ) { if ( %search ) { - $ncancelled = " AND $ncancelled"; + $rqual = " AND $rqual"; } else { - $ncancelled = " WHERE $ncancelled"; + $rqual = " WHERE $rqual"; } } my @just_cust_main; if ( driver_name eq 'mysql' ) { @just_cust_main = qsearch('cust_main', \%search, 'cust_main.*', - ",temp1_$$,temp2_$$ $ncancelled $orderby $limit"); + ",temp1_$$,temp2_$$ $rqual $orderby $limit"); } else { @just_cust_main = qsearch('cust_main', \%search, '', - "$ncancelled $orderby $limit" ); + "$rqual $orderby $limit" ); } if ( driver_name eq 'mysql' ) { my $sql = "DROP TABLE temp1_$$,temp2_$$;"; @@ -213,9 +236,12 @@ if ( $cgi->param('browse') } @cust_main = grep { $_->ncancelled_pkgs || ! $_->all_pkgs } @cust_main - if $cgi->param('showcancelledcustomers') eq '0' #see if it was set by me - || ( $conf->exists('hidecancelledcustomers') - && ! $cgi->param('showcancelledcustomers') ); + if ! $cgi->param('cancelled') + && ( + $cgi->param('showcancelledcustomers') eq '0' #see if it was set by me + || ( $conf->exists('hidecancelledcustomers') + && ! $cgi->param('showcancelledcustomers') ) + ); my %saw = (); @cust_main = grep { !$saw{$_->custnum}++ } @cust_main; @@ -277,19 +303,22 @@ if ( scalar(@cust_main) == 1 && ! $cgi->param('referral_custnum') ) { } } #end pager - - if ( $cgi->param('showcancelledcustomers') eq '0' #see if it was set by me - || ( $conf->exists('hidecancelledcustomers') - && ! $cgi->param('showcancelledcustomers') - ) - ) { - $cgi->param('showcancelledcustomers', 1); - $cgi->param('offset', 0); - print qq!( <a href="!. $cgi->self_url. qq!">show cancelled customers</a> )!; - } else { - $cgi->param('showcancelledcustomers', 0); - $cgi->param('offset', 0); - print qq!( <a href="!. $cgi->self_url. qq!">hide cancelled customers</a> )!; + + unless ( $cgi->param('cancelled') ) { + if ( $cgi->param('showcancelledcustomers') eq '0' #see if it was set by me + || ( $conf->exists('hidecancelledcustomers') + && ! $cgi->param('showcancelledcustomers') + ) + ) { + $cgi->param('showcancelledcustomers', 1); + $cgi->param('offset', 0); + print qq!( <a href="!. $cgi->self_url. qq!">show!; + } else { + $cgi->param('showcancelledcustomers', 0); + $cgi->param('offset', 0); + print qq!( <a href="!. $cgi->self_url. qq!">hide!; + } + print ' cancelled customers</a> )'; } if ( $cgi->param('referral_custnum') ) { $cgi->param('referral_custnum') =~ /^(\d+)$/ diff --git a/httemplate/search/cust_pay.cgi b/httemplate/search/cust_pay.cgi index e4dba01e9..51dd3b340 100755 --- a/httemplate/search/cust_pay.cgi +++ b/httemplate/search/cust_pay.cgi @@ -5,27 +5,53 @@ my @cust_pay; if ( $cgi->param('magic') && $cgi->param('magic') eq '_date' ) { my %search; + my @search; + if ( $cgi->param('payby') ) { - $cgi->param('payby') =~ /^(CARD|CHEK|BILL)$/ + $cgi->param('payby') =~ /^(CARD|CHEK|BILL)(-(VisaMC|Amex|Discover))?$/ or die "illegal payby ". $cgi->param('payby'); $search{'payby'} = $1; + if ( $3 ) { + if ( $3 eq 'VisaMC' ) { + #avoid posix regexes for portability + push @search, " ( substring(payinfo from 1 for 1) = '4' ". + " OR substring(payinfo from 1 for 2) = '51' ". + " OR substring(payinfo from 1 for 2) = '52' ". + " OR substring(payinfo from 1 for 2) = '53' ". + " OR substring(payinfo from 1 for 2) = '54' ". + " OR substring(payinfo from 1 for 2) = '54' ". + " OR substring(payinfo from 1 for 2) = '55' ". + " ) "; + } elsif ( $3 eq 'Amex' ) { + push @search, " ( substring(payinfo from 1 for 2 ) = '34' ". + " OR substring(payinfo from 1 for 2 ) = '37' ". + " ) "; + } elsif ( $3 eq 'Discover' ) { + push @search, " substring(payinfo from 1 for 4 ) = '6011' "; + } else { + die "unknown card type $3"; + } + } } #false laziness with cust_pkg.cgi - my $range = ''; if ( $cgi->param('beginning') && $cgi->param('beginning') =~ /^([ 0-9\-\/]{0,10})$/ ) { my $beginning = str2time($1); - $range = " WHERE _date >= $beginning "; + push @search, "_date >= $beginning "; } if ( $cgi->param('ending') && $cgi->param('ending') =~ /^([ 0-9\-\/]{0,10})$/ ) { - my $ending = str2time($1) + 86400; - $range .= ( $range ? ' AND ' : ' WHERE ' ). " _date <= $ending "; + my $ending = str2time($1) + 86399; + push @search, " _date <= $ending "; + } + my $search; + if ( @search ) { + $search = ( scalar(keys %search) ? ' AND ' : ' WHERE ' ). + join(' AND ', @search); } - $range =~ s/^\s*WHERE/ AND/ if scalar(keys %search) ; - @cust_pay = qsearch('cust_pay', \%search, '', $range ); + @cust_pay = qsearch('cust_pay', \%search, '', $search ); $sortby = \*date_sort; diff --git a/httemplate/search/cust_pkg.cgi b/httemplate/search/cust_pkg.cgi index 8b2fd0ca0..45420f4c4 100755 --- a/httemplate/search/cust_pkg.cgi +++ b/httemplate/search/cust_pkg.cgi @@ -29,10 +29,18 @@ if ( $cgi->param('magic') && $cgi->param('magic') eq 'bill' ) { } if ( $cgi->param('ending') && $cgi->param('ending') =~ /^([ 0-9\-\/]{0,10})$/ ) { - my $ending = str2time($1) + 86400; + my $ending = str2time($1) + 86399; $range .= ( $range ? ' AND ' : ' WHERE ' ). " bill <= $ending "; } + $range .= ( $range ? 'AND ' : ' WHERE ' ). '( cancel IS NULL OR cancel = 0 )'; + + if ( $cgi->param('agentnum') =~ /^(\d+)$/ and $1 ) { + $range .= ( $range ? 'AND ' : ' WHERE ' ). + "$1 = ( SELECT agentnum FROM cust_main". + " WHERE cust_main.custnum = cust_pkg.custnum )"; + } + #false laziness with below my $statement = "SELECT COUNT(*) FROM cust_pkg $range"; warn $statement; @@ -46,10 +54,21 @@ if ( $cgi->param('magic') && $cgi->param('magic') eq 'bill' ) { } else { my $qual = ''; - if ( $cgi->param('magic') && $cgi->param('magic') eq 'active' ) { + if ( $cgi->param('magic') && + $cgi->param('magic') =~ /^(active|suspended|canceled)$/ + ) { - $qual = 'WHERE ( susp IS NULL OR susp = 0 )'. - ' AND ( cancel IS NULL OR cancel = 0)'; + if ( $cgi->param('magic') eq 'active' ) { + $qual = 'WHERE ( susp IS NULL OR susp = 0 )'. + ' AND ( cancel IS NULL OR cancel = 0)'; + } elsif ( $cgi->param('magic') eq 'suspended' ) { + $qual = 'WHERE susp IS NOT NULL AND susp != 0'. + ' AND ( cancel IS NULL OR cancel = 0)'; + } elsif ( $cgi->param('magic') eq 'canceled' ) { + $qual = 'WHERE cancel IS NOT NULL AND cancel != 0'; + } else { + die "guru meditation #420"; + } $sortby = \*pkgnum_sort; @@ -61,12 +80,6 @@ if ( $cgi->param('magic') && $cgi->param('magic') eq 'bill' ) { $sortby=\*pkgnum_sort; - } elsif ( $query eq 'SUSP_pkgnum' ) { - - $sortby=\*pkgnum_sort; - - $qual = 'WHERE susp IS NOT NULL AND susp != 0'; - } elsif ( $query eq 'APKG_pkgnum' ) { $sortby=\*pkgnum_sort; diff --git a/httemplate/search/cust_pkg.html b/httemplate/search/cust_pkg.html deleted file mode 100755 index bb0a5407c..000000000 --- a/httemplate/search/cust_pkg.html +++ /dev/null @@ -1,24 +0,0 @@ -<HTML> - <HEAD> - <TITLE>Packages</TITLE> - </HEAD> - <BODY> - <CENTER> - <H1>Packages</H1> - </CENTER> - <HR> - <FORM ACTION="cust_pkg.cgi" METHOD="post"> - <INPUT TYPE="hidden" NAME="magic" VALUE="bill"> - Return <B>packages</B> with next bill date: - from <INPUT TYPE="text" NAME="beginning"> <i>m/d/y</i> - to <INPUT TYPE="text" NAME="ending"> <i>m/d/y</i> - - <P><INPUT TYPE="submit" VALUE="Get Report"> - - </FORM> - - <HR> - - </BODY> -</HTML> - diff --git a/httemplate/search/cust_pkg_report.cgi b/httemplate/search/cust_pkg_report.cgi new file mode 100755 index 000000000..b31674540 --- /dev/null +++ b/httemplate/search/cust_pkg_report.cgi @@ -0,0 +1,63 @@ +<HTML> + <HEAD> + <TITLE>Packages</TITLE> + <LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2"> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT> + </HEAD> + <BODY BGCOLOR="#e8e8e8"> + <H1>Packages</H1> + <FORM ACTION="cust_pkg.cgi" METHOD="post"> + <INPUT TYPE="hidden" NAME="magic" VALUE="bill"> + Return packages with next bill date:<BR><BR> + <TABLE> + <TR> + <TD ALIGN="right">From: </TD> + <TD><INPUT TYPE="text" NAME="beginning" ID="beginning_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="beginning_button" STYLE="cursor: pointer" TITLE="Select date"><BR><I>m/d/y</I></TD> +<SCRIPT TYPE="text/javascript"> + Calendar.setup({ + inputField: "beginning_text", + ifFormat: "%m/%d/%Y", + button: "beginning_button", + align: "BR" + }); +</SCRIPT> + </TR> + <TR> + <TD ALIGN="right">To: </TD> + <TD><INPUT TYPE="text" NAME="ending" ID="ending_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="ending_button" STYLE="cursor: pointer" TITLE="Select date"><BR><I>m/d/y</I></TD> +<SCRIPT TYPE="text/javascript"> + Calendar.setup({ + inputField: "ending_text", + ifFormat: "%m/%d/%Y", + button: "ending_button", + align: "BR" + }); +</SCRIPT> + </TR> +<% my %agent_search = dbdef->table('agent')->column('disabled') + ? ( 'disabled' => '' ) : (); + my @agents = qsearch( 'agent', \%agent_search ); + if ( scalar(@agents) == 1 ) { +%> + <INPUT TYPE="hidden" NAME="agentnum" VALUE="<%= $agents[0]->agentnum %>"> +<% } else { %> + + <TR> + <TD ALIGN="right">Agent: </TD> + <TD><SELECT NAME="agentnum"><OPTION VALUE="">(all) + <% foreach my $agent ( sort { $a->agent cmp $b->agent; } @agents) { %> + <OPTION VALUE="<%= $agent->agentnum %>"><%= $agent->agent %> + <% } %> + </TD> + </TR> +<% } %> + </TABLE> + <BR><INPUT TYPE="submit" VALUE="Get Report"> + + </FORM> + + </BODY> +</HTML> + diff --git a/httemplate/search/elements/search.html b/httemplate/search/elements/search.html new file mode 100644 index 000000000..fbedcaa26 --- /dev/null +++ b/httemplate/search/elements/search.html @@ -0,0 +1,59 @@ +<% + + my %opt = @_; + unless (exists($opt{'count_query'}) && length($opt{'count_query'})) { + ( $opt{'count_query'} = $opt{'query'} ) =~ + s/^\s*SELECT\s*(.*)\s+FROM\s/SELECT COUNT(*) FROM /i; + } + + my $conf = new FS::Conf; + my $maxrecords = $conf->config('maxsearchrecordsperpage'); + + my $limit = $maxrecords ? "LIMIT $maxrecords" : ''; + + my $offset = $cgi->param('offset') || 0; + $limit .= " OFFSET $offset" if $offset; + + my $count_sth = dbh->prepare($opt{'count_query'}) + or die "Error preparing $opt{'count_query'}: ". dbh->errstr; + $count_sth->execute + or die "Error executing $opt{'count_query'}: ". $count_sth->errstr; + my $total = $count_sth->fetchrow_arrayref->[0]; + + my $sth = dbh->prepare("$opt{'query'} $limit") + or die "Error preparing $opt{'query'}: ". dbh->errstr; + $sth->execute + or die "Error executing $opt{'query'}: ". $sth->errstr; + + #can get # of rows without fetching them all? + my $rows = $sth->fetchall_arrayref; + +%> +<!-- mason kludge --> +<% my $pager = include ( '/elements/pager.html', + 'offset' => $offset, + 'num_rows' => scalar(@$rows), + 'total' => $total, + 'maxrecords' => $maxrecords, + ); +%> + +<%= $total %> total <%= $opt{'name'} %><BR><BR><%= $pager %> +<%= include( '/elements/table.html' ) %> + <TR> + <% foreach ( @{$sth->{NAME}} ) { %> + <TH><%= $_ %></TH> + <% } %> + </TR> + <% foreach my $row ( @$rows ) { %> + <TR> + <% foreach ( @$row ) { %> + <TD><%= $_ %></TD> + <% } %> + </TR> + <% } %> + +</TABLE> +<%= $pager %> +</BODY> +</HTML> diff --git a/httemplate/search/report_cc.html b/httemplate/search/report_cc.html index 8653dcc69..595a7b150 100755 --- a/httemplate/search/report_cc.html +++ b/httemplate/search/report_cc.html @@ -1,23 +1,43 @@ <HTML> <HEAD> <TITLE>Credit Card Receipt Report Criteria</TITLE> - </HEAD> - <BODY> - <CENTER> - <H1>Credit Card Receipt Report Criteria</H1> - </CENTER> - <HR> + <LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2"> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT> </HEAD> + <BODY BGCOLOR="#e8e8e8"> + <H1>Credit Card Receipt Report Criteria</H1> <FORM ACTION="report_cc.cgi" METHOD="post"> Return <B>credit card receipt report</B> for period: - from <INPUT TYPE="text" NAME="beginning"> <i>m/d/y</i> - to <INPUT TYPE="text" NAME="ending"> <i>m/d/y</i> + <TABLE> + <TR> + <TD ALIGN="right">From: </TD> + <TD><INPUT TYPE="text" NAME="beginning" ID="beginning_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="beginning_button" STYLE="cursor: pointer" TITLE="Select date"><BR><i>m/d/y</i></TD> +<SCRIPT TYPE="text/javascript"> + Calendar.setup({ + inputField: "beginning_text", + ifFormat: "%m/%d/%Y", + button: "beginning_button", + align: "BR" + }); +</SCRIPT> + </TR> + <TD ALIGN="right">To: </TD> + <TD><INPUT TYPE="text" NAME="ending" ID="ending_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="ending_button" STYLE="cursor: pointer" TITLE="Select date"><BR><i>m/d/y</i></TD> +<SCRIPT TYPE="text/javascript"> + Calendar.setup({ + inputField: "ending_text", + ifFormat: "%m/%d/%Y", + button: "ending_button", + align: "BR" + }); +</SCRIPT> + </TR> + </TABLE> - <P><INPUT TYPE="submit" VALUE="Get Report"> + <BR><INPUT TYPE="submit" VALUE="Get Report"> </FORM> - - <HR> - </BODY> </HTML> diff --git a/httemplate/search/report_credit.html b/httemplate/search/report_credit.html index df9b9581f..11cb32ed8 100755 --- a/httemplate/search/report_credit.html +++ b/httemplate/search/report_credit.html @@ -1,23 +1,43 @@ <HTML> <HEAD> <TITLE>In House Credit Report Criteria</TITLE> - </HEAD> - <BODY> - <CENTER> - <H1>In House Credit Report Criteria</H1> - </CENTER> - <HR> + <LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2"> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT> </HEAD> + <BODY BGCOLOR="#e8e8e8"> + <H1>In House Credit Report Criteria</H1> <FORM ACTION="report_credit.cgi" METHOD="post"> Return <B>in house credit report</B> for period: - from <INPUT TYPE="text" NAME="beginning"> <i>m/d/y</i> - to <INPUT TYPE="text" NAME="ending"> <i>m/d/y</i> + <TABLE> + <TR> + <TD ALIGN="right">From: </TD> + <TD><INPUT TYPE="text" NAME="beginning" ID="beginning_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="beginning_button" STYLE="cursor: pointer" TITLE="Select date"><BR><i>m/d/y</i></TD> +<SCRIPT TYPE="text/javascript"> + Calendar.setup({ + inputField: "beginning_text", + ifFormat: "%m/%d/%Y", + button: "beginning_button", + align: "BR" + }); +</SCRIPT> + </TR> + <TD ALIGN="right">To: </TD> + <TD><INPUT TYPE="text" NAME="ending" ID="ending_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="ending_button" STYLE="cursor: pointer" TITLE="Select date"><BR><i>m/d/y</i></TD> +<SCRIPT TYPE="text/javascript"> + Calendar.setup({ + inputField: "ending_text", + ifFormat: "%m/%d/%Y", + button: "ending_button", + align: "BR" + }); +</SCRIPT> + </TR> + </TABLE> - <P><INPUT TYPE="submit" VALUE="Get Report"> + <BR><INPUT TYPE="submit" VALUE="Get Report"> </FORM> - - <HR> - </BODY> </HTML> diff --git a/httemplate/search/report_cust_pay.html b/httemplate/search/report_cust_pay.html index 93053e1ee..1b30685dc 100644 --- a/httemplate/search/report_cust_pay.html +++ b/httemplate/search/report_cust_pay.html @@ -1,24 +1,54 @@ <HTML> <HEAD> <TITLE>Payment report criteria</TITLE> + <LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2"> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT> </HEAD> - <BODY> - <CENTER> - <H1>Payment report criteria</H1> - </CENTER> - <HR> + <BODY BGCOLOR="#e8e8e8"> + <H1>Payment report criteria</H1> <FORM ACTION="cust_pay.cgi" METHOD="post"> <INPUT TYPE="hidden" NAME="magic" VALUE="_date"> - Return <SELECT NAME="payby"> - <OPTION VALUE="">all</OPTION> - <OPTION VALUE="CARD">credit card</OPTION> - <OPTION VALUE="CHEK">electronic check (ACH)</OPTION> - <OPTION VALUE="BILL">check/cash</OPTION> - </SELECT> payments for period<BR> - from <INPUT TYPE="text" NAME="beginning"> <i>m/d/y</i> - to <INPUT TYPE="text" NAME="ending"> <i>m/d/y</i> - <P><INPUT TYPE="submit" VALUE="Get Report"> + <TABLE> + <TR> + <TD ALIGN="right">Payments of type: </TD> + <TD><SELECT NAME="payby"> + <OPTION VALUE="">all</OPTION> + <OPTION VALUE="CARD">credit card (all)</OPTION> + <OPTION VALUE="CARD-VisaMC">credit card (Visa/MasterCard)</OPTION> + <OPTION VALUE="CARD-Amex">credit card (American Express)</OPTION> + <OPTION VALUE="CARD-Discover">credit card (Discover)</OPTION> + <OPTION VALUE="CHEK">electronic check / ACH</OPTION> + <OPTION VALUE="BILL">check / cash</OPTION> + </SELECT> + </TD> + </TR> + <TR> + <TD ALIGN="right">From: </TD> + <TD><INPUT TYPE="text" NAME="beginning" ID="beginning_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="beginning_button" STYLE="cursor: pointer" TITLE="Select date"><BR><i>m/d/y</i></TD> +<SCRIPT TYPE="text/javascript"> + Calendar.setup({ + inputField: "beginning_text", + ifFormat: "%m/%d/%Y", + button: "beginning_button", + align: "BR" + }); +</SCRIPT> + </TR> + <TD ALIGN="right">To: </TD> + <TD><INPUT TYPE="text" NAME="ending" ID="ending_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="ending_button" STYLE="cursor: pointer" TITLE="Select date"><BR><i>m/d/y</i></TD> +<SCRIPT TYPE="text/javascript"> + Calendar.setup({ + inputField: "ending_text", + ifFormat: "%m/%d/%Y", + button: "ending_button", + align: "BR" + }); +</SCRIPT> + </TR> + </TABLE> + <BR><INPUT TYPE="submit" VALUE="Get Report"> </FORM> - <HR> </BODY> </HTML> diff --git a/httemplate/search/report_prepaid_income.cgi b/httemplate/search/report_prepaid_income.cgi new file mode 100644 index 000000000..eb8bbb55e --- /dev/null +++ b/httemplate/search/report_prepaid_income.cgi @@ -0,0 +1,75 @@ +<!-- mason kludge --> +<% + + #doesn't yet deal with daily/weekly packages + + #needs to be re-written in sql for efficiency + + my $now = $cgi->param('date') && str2time($cgi->param('date')) || time; + $now =~ /^(\d+)$/ or die "unparsable date?"; + $now = $1; + + my %prepaid; + + my @cust_bill_pkg = + grep { $_->cust_pkg && $_->cust_pkg->part_pkg->freq !~ /^([01]|\d+[dw])$/ } + qsearch( 'cust_bill_pkg', { + 'recur' => { op=>'!=', value=>0 }, + 'edate' => { op=>'>', value=>$now }, + }, ); + + foreach my $cust_bill_pkg ( @cust_bill_pkg ) { + + #conceptual false laziness w/texas tax exempt_amount stuff in + #FS::cust_main::bill + + my $freq = $cust_bill_pkg->cust_pkg->part_pkg->freq; + my $per_month = sprintf("%.2f", $cust_bill_pkg->recur / $freq); + + my($mon, $year) = (localtime($cust_bill_pkg->sdate) )[4,5]; + $mon+=2; $year+=1900; + + foreach my $which_month ( 2 .. $freq ) { + until ( $mon < 13 ) { $mon -= 12; $year++; } + $prepaid{"$year-$mon"} += $per_month; + $mon++; + } + + } + + my @mon = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); + +%> + +<%= header( 'Prepaid Income (Unearned Revenue) Report', + menubar( 'Main Menu'=>$p, ) ) %> +<%= table() %> +<% + + my $total = 0; + + my ($now_mon, $now_year) = (localtime($now))[4,5]; + $now_mon+=2; $now_year+=1900; + until ( $now_mon < 13 ) { $now_mon -= 12; $now_year++; } + + my $subseq = 0; + for my $year ( $now_year .. 2037 ) { + for my $mon ( ( $subseq++ ? 1 : $now_mon ) .. 12 ) { + if ( $prepaid{"$year-$mon"} ) { + $total += $prepaid{"$year-$mon"}; + %> <TR><TD ALIGN="right"><%= $mon[$mon-1]. ' '. $year %></TD> + <TD ALIGN="right"> + <%= sprintf("%.2f", $prepaid{"$year-$mon"} ) %> + </TD> + </TR> + <% + } + } + + } + +%> +<TR><TH>Total</TH><TD ALIGN="right"><%= sprintf("%.2f", $total) %></TD></TR> +</TABLE> +</BODY> +</HTML> diff --git a/httemplate/search/report_prepaid_income.html b/httemplate/search/report_prepaid_income.html new file mode 100644 index 000000000..b85a481be --- /dev/null +++ b/httemplate/search/report_prepaid_income.html @@ -0,0 +1,17 @@ +<HTML> + <HEAD> + <TITLE>Prepaid Income (Unearned Revenue) Report</TITLE> + <LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2"> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT> + </HEAD> + <BODY BGCOLOR="#e8e8e8"> + <H1>Prepaid Income (Unearned Revenue) Report</H1> + <FORM ACTION="report_prepaid_income.cgi" METHOD="post"> + Prepaid income (unearned revenue) as of <INPUT TYPE="text" NAME="date" VALUE="now"> + <INPUT TYPE="submit" VALUE="Generate report"> + </BODY> +</HTML> + <TABLE> + diff --git a/httemplate/search/report_receivables.cgi b/httemplate/search/report_receivables.cgi index fdd3779a9..ad353a1b3 100755 --- a/httemplate/search/report_receivables.cgi +++ b/httemplate/search/report_receivables.cgi @@ -1,19 +1,158 @@ <!-- mason kludge --> <% -my $user = getotaker; + my $charged = <<END; + sum( charged + - coalesce( + ( select sum(amount) from cust_bill_pay + where cust_bill.invnum = cust_bill_pay.invnum ) + ,0 + ) + - coalesce( + ( select sum(amount) from cust_credit_bill + where cust_bill.invnum = cust_credit_bill.invnum ) + ,0 + ) -print header('Current Receivables Report Results'); + ) +END -open (REPORT, "freeside-receivables-report -v $user |"); + my $owed_cols = <<END; + coalesce( + ( select $charged from cust_bill + where cust_bill._date > extract(epoch from now())-2592000 + and cust_main.custnum = cust_bill.custnum + ) + ,0 + ) as owed_0_30, -print '<PRE>'; -while(<REPORT>) { - print $_; -} -print '</PRE>'; + coalesce( + ( select $charged from cust_bill + where cust_bill._date > extract(epoch from now())-5184000 + and cust_bill._date <= extract(epoch from now())-2592000 + and cust_main.custnum = cust_bill.custnum + ) + ,0 + ) as owed_30_60, -print '</BODY></HTML>'; + coalesce( + ( select $charged from cust_bill + where cust_bill._date > extract(epoch from now())-7776000 + and cust_bill._date <= extract(epoch from now())-5184000 + and cust_main.custnum = cust_bill.custnum + ) + ,0 + ) as owed_60_90, -%> + coalesce( + ( select $charged from cust_bill + where cust_bill._date <= extract(epoch from now())-7776000 + and cust_main.custnum = cust_bill.custnum + ) + ,0 + ) as owed_90_plus, + + coalesce( + ( select $charged from cust_bill + where cust_main.custnum = cust_bill.custnum + ) + ,0 + ) as owed_total +END + + my $recurring = <<END; + 0 < ( select freq from part_pkg + where cust_pkg.pkgpart = part_pkg.pkgpart ) +END + + my $packages_cols = <<END; + + ( select count(*) from cust_pkg + where cust_main.custnum = cust_pkg.custnum + and $recurring + and ( cancel = 0 or cancel is null ) + ) as uncancelled_pkgs, + + ( select count(*) from cust_pkg + where cust_main.custnum = cust_pkg.custnum + and $recurring + and ( cancel = 0 or cancel is null ) + and ( susp = 0 or susp is null ) + ) as active_pkgs + +END + + my $sql = <<END; +select *, $owed_cols, $packages_cols from cust_main +where 0 < + coalesce( + ( select $charged from cust_bill + where cust_main.custnum = cust_bill.custnum + ) + ,0 + ) + +order by lower(company), lower(last) + +END + + my $total_sql = "select $owed_cols"; + + my $sth = dbh->prepare($sql) or die dbh->errstr; + $sth->execute or die $sth->errstr; + + my $total_sth = dbh->prepare($total_sql) or die dbh->errstr; + $total_sth->execute or die $total_sth->errstr; + +%> +<%= header('Accounts Receivable Aging Summary', menubar( 'Main Menu'=>$p, ) ) %> +<%= table() %> + <TR> + <TH>Customer</TH> + <TH>Status</TH> + <TH>0-30</TH> + <TH>30-60</TH> + <TH>60-90</TH> + <TH>90+</TH> + <TH>Total</TH> + </TR> +<% while ( my $row = $sth->fetchrow_hashref() ) { + my $status = 'Cancelled'; + my $statuscol = 'FF0000'; + if ( $row->{uncancelled_pkgs} ) { + $status = 'Suspended'; + $statuscol = 'FF9900'; + if ( $row->{active_pkgs} ) { + $status = 'Active'; + $statuscol = '00CC00'; + } + } +%> + <TR> + <TD><A HREF="<%= $p %>view/cust_main.cgi?<%= $row->{'custnum'} %>"><%= $row->{'custnum'} %>: + <%= $row->{'company'} ? $row->{'company'}. ' (' : '' %><%= $row->{'last'}. ', '. $row->{'first'} %><%= $row->{'company'} ? ')' : '' %></A> + </TD> + <TD><B><FONT SIZE=-1 COLOR="#<%= $statuscol %>"><%= $status %></FONT></B></TD> + <TD ALIGN="right">$<%= sprintf("%.2f", $row->{'owed_0_30'} ) %></TD> + <TD ALIGN="right">$<%= sprintf("%.2f", $row->{'owed_30_60'} ) %></TD> + <TD ALIGN="right">$<%= sprintf("%.2f", $row->{'owed_60_90'} ) %></TD> + <TD ALIGN="right">$<%= sprintf("%.2f", $row->{'owed_90_plus'} ) %></TD> + <TD ALIGN="right"><B>$<%= sprintf("%.2f", $row->{'owed_total'} ) %></B></TD> + </TR> +<% } %> +<% my $row = $total_sth->fetchrow_hashref(); %> + <TR> + <TD COLSPAN=6> </TD> + </TR> + <TR> + <TD COLSPAN=2><I>Total</I></TD> + <TD ALIGN="right"><I>$<%= sprintf("%.2f", $row->{'owed_0_30'} ) %></TD> + <TD ALIGN="right"><I>$<%= sprintf("%.2f", $row->{'owed_30_60'} ) %></TD> + <TD ALIGN="right"><I>$<%= sprintf("%.2f", $row->{'owed_60_90'} ) %></TD> + <TD ALIGN="right"><I>$<%= sprintf("%.2f", $row->{'owed_90_plus'} ) %></TD> + <TD ALIGN="right"><I><B>$<%= sprintf("%.2f", $row->{'owed_total'} ) %></B></I></TD> + </TR> +</TABLE> +</BODY> +</HTML> diff --git a/httemplate/search/report_tax.html b/httemplate/search/report_tax.html index 7bf681b42..7bc35e3ed 100755 --- a/httemplate/search/report_tax.html +++ b/httemplate/search/report_tax.html @@ -1,23 +1,43 @@ <HTML> <HEAD> <TITLE>Tax Report Criteria</TITLE> - </HEAD> - <BODY> - <CENTER> - <H1>Tax Report Criteria</H1> - </CENTER> - <HR> + <LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2"> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT> + <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT> </HEAD> + <BODY BGCOLOR="#e8e8e8"> + <H1>Tax Report Criteria</H1> <FORM ACTION="report_tax.cgi" METHOD="post"> - Return <B>tax report</B> for period: - from <INPUT TYPE="text" NAME="beginning"> <i>m/d/y</i> - to <INPUT TYPE="text" NAME="ending"> <i>m/d/y</i> + Return <B>tax report</B> for period: + <TABLE> + <TR> + <TD ALIGN="right">From: </TD> + <TD><INPUT TYPE="text" NAME="beginning" ID="beginning_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="beginning_button" STYLE="cursor: pointer" TITLE="Select date"><BR><i>m/d/y</i></TD> +<SCRIPT TYPE="text/javascript"> + Calendar.setup({ + inputField: "beginning_text", + ifFormat: "%m/%d/%Y", + button: "beginning_button", + align: "BR" + }); +</SCRIPT> + </TR> + <TD ALIGN="right">To: </TD> + <TD><INPUT TYPE="text" NAME="ending" ID="ending_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="ending_button" STYLE="cursor: pointer" TITLE="Select date"><BR><i>m/d/y</i></TD> +<SCRIPT TYPE="text/javascript"> + Calendar.setup({ + inputField: "ending_text", + ifFormat: "%m/%d/%Y", + button: "ending_button", + align: "BR" + }); +</SCRIPT> + </TR> + </TABLE> - <P><INPUT TYPE="submit" VALUE="Get Report"> + <BR><INPUT TYPE="submit" VALUE="Get Report"> </FORM> - - <HR> - </BODY> </HTML> diff --git a/httemplate/search/sql.cgi b/httemplate/search/sql.cgi deleted file mode 100755 index b83ef039f..000000000 --- a/httemplate/search/sql.cgi +++ /dev/null @@ -1,76 +0,0 @@ -<% - -my $conf = new FS::Conf; -my $maxrecords = $conf->config('maxsearchrecordsperpage'); - -my $limit = ''; -$limit .= "LIMIT $maxrecords" if $maxrecords; - -my $offset = $cgi->param('offset') || 0; -$limit .= " OFFSET $offset" if $offset; - -my $total; - -my $sql = $cgi->param('sql'); -$sql =~ s/^\s*SELECT//i; - -my $count_sql = $sql; -$count_sql =~ s/^(.*)\s+FROM\s/COUNT(*) FROM /i; - -my $sth = dbh->prepare("SELECT $count_sql") - or eidiot dbh->errstr. " doing $count_sql\n"; -$sth->execute or eidiot "Error executing \"$count_sql\": ". $sth->errstr; - -$total = $sth->fetchrow_arrayref->[0]; - -my $sth = dbh->prepare("SELECT $sql $limit") - or eidiot dbh->errstr. " doing $sql\n"; -$sth->execute or eidiot "Error executing \"$sql\": ". $sth->errstr; -my $rows = $sth->fetchall_arrayref; - -%> -<!-- mason kludge --> -<% - - #begin pager - my $pager = ''; - if ( $total != scalar(@$rows) && $maxrecords ) { - unless ( $offset == 0 ) { - $cgi->param('offset', $offset - $maxrecords); - $pager .= '<A HREF="'. $cgi->self_url. - '"><B><FONT SIZE="+1">Previous</FONT></B></A> '; - } - my $poff; - my $page; - for ( $poff = 0; $poff < $total; $poff += $maxrecords ) { - $page++; - if ( $offset == $poff ) { - $pager .= qq!<FONT SIZE="+2">$page</FONT> !; - } else { - $cgi->param('offset', $poff); - $pager .= qq!<A HREF="!. $cgi->self_url. qq!">$page</A> !; - } - } - unless ( $offset + $maxrecords > $total ) { - $cgi->param('offset', $offset + $maxrecords); - $pager .= '<A HREF="'. $cgi->self_url. - '"><B><FONT SIZE="+1">Next</FONT></B></A> '; - } - } - #end pager - - print header('Query Results', menubar('Main Menu'=>$p) ). - "$total total rows<BR><BR>$pager". table(). - "<TR>"; - print "<TH>$_</TH>" foreach @{$sth->{NAME}}; - print "</TR>"; - - foreach $row ( @$rows ) { - print "<TR>"; - print "<TD>$_</TD>" foreach @$row; - print "</TR>"; - } - - print "</TABLE>$pager</BODY></HTML>"; - -%> diff --git a/httemplate/search/sql.html b/httemplate/search/sql.html new file mode 100644 index 000000000..7d7fc0890 --- /dev/null +++ b/httemplate/search/sql.html @@ -0,0 +1,12 @@ +<%= include( '/elements/header.html', 'Query Results', + include( '/elements/menubar.html', 'Main Menu' => $p ) + ) +%> + +<%= include( 'elements/search.html', + 'name' => 'rows', + 'query' => 'SELECT '. ( $cgi->param('sql') + || eidiot('Empty query') ), + ) +%> + diff --git a/httemplate/search/svc_acct.cgi b/httemplate/search/svc_acct.cgi index e43f4f79b..1e4a03d84 100755 --- a/httemplate/search/svc_acct.cgi +++ b/httemplate/search/svc_acct.cgi @@ -46,14 +46,31 @@ if ( $query eq 'svcnum' ) { $orderby = "ORDER BY ${tblname}username"; } elsif ( $query eq 'uid' ) { $sortby=\*uid_sort; - $orderby = ( $unlinked ? 'AND' : 'WHERE' ). + $orderby = ( $unlinked ? ' AND' : ' WHERE' ). " ${tblname}uid IS NOT NULL ORDER BY ${tblname}uid"; +} elsif ( $cgi->param('popnum') =~ /^(\d+)$/ ) { + $unlinked .= ( $unlinked ? 'AND' : 'WHERE' ). + " popnum = $1"; + $sortby=\*username_sort; + $orderby = "ORDER BY ${tblname}username"; +} elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) { + $unlinked .= ( $unlinked ? ' AND' : ' WHERE' ). + " $1 = ( SELECT svcpart FROM cust_svc ". + " WHERE cust_svc.svcnum = svc_acct.svcnum ) "; + $sortby=\*uid_sort; + #$sortby=\*svcnum_sort; } else { $sortby=\*uid_sort; @svc_acct = @{&usernamesearch}; } -if ( $query eq 'svcnum' || $query eq 'username' || $query eq 'uid' ) { + +if ( $query eq 'svcnum' + || $query eq 'username' + || $query eq 'uid' + || $cgi->param('popnum') =~ /^(\d+)$/ + || $cgi->param('svcpart') =~ /^(\d+)$/ + ) { my $statement = "SELECT COUNT(*) FROM svc_acct $unlinked"; my $sth = dbh->prepare($statement) diff --git a/httemplate/search/svc_domain.cgi b/httemplate/search/svc_domain.cgi index c0acf1143..948b1d9ae 100755 --- a/httemplate/search/svc_domain.cgi +++ b/httemplate/search/svc_domain.cgi @@ -23,6 +23,13 @@ if ( $query eq 'svcnum' ) { 'svcnum' => $_->svcnum, 'pkgnum' => '', }), qsearch('svc_domain',{}); +} elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) { + @svc_domain = + qsearch( 'svc_domain', {}, '', + " WHERE $1 = ( SELECT svcpart FROM cust_svc ". + " WHERE cust_svc.svcnum = svc_domain.svcnum ) " + ); + $sortby=\*svcnum_sort; } else { $cgi->param('domain') =~ /^([\w\-\.]+)$/; my($domain)=$1; diff --git a/httemplate/search/svc_forward.cgi b/httemplate/search/svc_forward.cgi new file mode 100755 index 000000000..10094bc99 --- /dev/null +++ b/httemplate/search/svc_forward.cgi @@ -0,0 +1,79 @@ +<% + +my $conf = new FS::Conf; + +my($query)=$cgi->keywords; +$query ||= ''; #to avoid use of unitialized value errors +my(@svc_forward,$sortby); +if ( $query eq 'svcnum' ) { + $sortby=\*svcnum_sort; + @svc_forward=qsearch('svc_forward',{}); +} else { + eidiot('unimplemented'); +} + +if ( scalar(@svc_forward) == 1 ) { + print $cgi->redirect(popurl(2). "view/svc_forward.cgi?". $svc_forward[0]->svcnum); + #exit; +} elsif ( scalar(@svc_forward) == 0 ) { +%> +<!-- mason kludge --> +<% + eidiot "No matching forwards found!\n"; +} else { +%> +<!-- mason kludge --> +<% + my $total = scalar(@svc_forward); + print header("Mail forward Search Results",''), <<END; + + $total matching mail forwards found + <TABLE BORDER=4 CELLSPACING=0 CELLPADDING=0> + <TR> + <TH>Service #<BR><FONT SIZE=-1>(click to view forward)</FONT></TH> + <TH>Mail to<BR><FONT SIZE=-1>(click to view account)</FONT></TH> + <TH>Forwards to<BR><FONT SIZE=-1>(click to view account)</FONT></TH> + </TR> +END + + foreach my $svc_forward ( + sort $sortby (@svc_forward) + ) { + my $svcnum = $svc_forward->svcnum; + + my $src = $svc_forward->src; + $src = "<I>(anything)</I>$src" if $src =~ /^@/; + if ( $svc_forward->srcsvc_acct ) { + $src = qq!<A HREF="${p}view/svc_acct.cgi?!. $svc_forward->srcsvc. '">'. + $svc_forward->srcsvc_acct->email. '</A>'; + } + + my $dst = $svc_forward->dst; + if ( $svc_forward->dstsvc_acct ) { + $dst = qq!<A HREF="${p}view/svc_acct.cgi?!. $svc_forward->dstsvc. '">'. + $svc_forward->dstsvc_acct->email. '</A>'; + } + + print <<END; + <TR> + <TD><A HREF="${p}view/svc_forward.cgi?$svcnum">$svcnum</A></TD> + <TD>$src</TD> + <TD>$dst</TD> + </TR> +END + + } + + print <<END; + </TABLE> + </BODY> +</HTML> +END + +} + +sub svcnum_sort { + $a->getfield('svcnum') <=> $b->getfield('svcnum'); +} + +%> |