diff options
Diffstat (limited to 'httemplate/search')
31 files changed, 1453 insertions, 2053 deletions
diff --git a/httemplate/search/cust_bill.html b/httemplate/search/cust_bill.html index 2108653..3ae624a 100755 --- a/httemplate/search/cust_bill.html +++ b/httemplate/search/cust_bill.html @@ -1,52 +1,6 @@ <% my( $count_query, $sql_query ); - my( $count_addl ) = ( '' ); - my( $distinct ) = ( '' ); - my($begin, $end) = ( '', '' ); - my($agentnum) = ( '' ); - my($open, $days) = ( '', '' ); - if ( $cgi->param('invnum') =~ /^\s*(FS-)?(\d+)\s*$/ ) { - $count_query = "SELECT COUNT(*) FROM cust_bill WHERE invnum = $2"; - $sql_query = { - 'table' => 'cust_bill', - 'hashref' => { 'invnum' => $2 }, - #'select' => '*', - }; - } else { - #if ( $cgi->param('begin') || $cgi->param('end') - # || $cgi->param('beginning') || $cgi->param('ending') - # || $cgi->keywords - # ) - #{ - - #some false laziness w/cust_bill::re_X - my @where; - my $orderby = 'ORDER BY cust_bill._date'; - - if ( $cgi->param('beginning') - && $cgi->param('beginning') =~ /^([ 0-9\-\/]{0,10})$/ ) { - $begin = str2time($1); - push @where, "cust_bill._date >= $begin"; - } - if ( $cgi->param('ending') - && $cgi->param('ending') =~ /^([ 0-9\-\/]{0,10})$/ ) { - $end = str2time($1) + 86399; - push @where, "cust_bill._date < $end"; - } - - if ( $cgi->param('begin') =~ /^(\d+)$/ ) { - $begin = $1; - push @where, "cust_bill._date >= $begin"; - } - if ( $cgi->param('end') =~ /^(\d+)$/ ) { - $end = $1; - push @where, "cust_bill._date < $end"; - } - - if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) { - $agentnum = $1; - push @where, "cust_main.agentnum = $agentnum"; - } + if ( $cgi->param('begin') || $cgi->param('end') || $cgi->keywords ) { my $owed = "charged - ( SELECT COALESCE(SUM(amount),0) FROM cust_bill_pay @@ -54,126 +8,94 @@ - ( SELECT COALESCE(SUM(amount),0) FROM cust_credit_bill WHERE cust_credit_bill.invnum = cust_bill.invnum )"; - if ( $cgi->param('open') ) { - push @where, "0 != $owed"; - $open = 1; + my @where; + my $orderby = 'ORDER BY cust_bill._date'; + + if ( $cgi->param('begin') =~ /^(\d+)$/ ) { + push @where, "cust_bill._date >= $1", + } + if ( $cgi->param('end') =~ /^(\d+)$/ ) { + push @where, "cust_bill._date < $1", } my($query) = $cgi->keywords; if ( $query =~ /^(OPEN(\d*)_)?(invnum|date|custnum)$/ ) { - ($open, $days, my $field) = ($1, $2, $3); + my($open, $days, $field) = ($1, $2, $3); $field = "_date" if $field eq 'date'; $orderby = "ORDER BY cust_bill.$field"; push @where, "0 != $owed" if $open; push @where, "cust_bill._date < ". (time-86400*$days) if $days; } - + my $extra_sql = scalar(@where) ? 'WHERE '. join(' AND ', @where) : ''; - - my $addl_from = 'left join cust_main using ( custnum )'; - - if ( $cgi->param('newest_percust') ) { - $distinct = 'DISTINCT ON ( cust_bill.custnum )'; - $orderby = 'ORDER BY cust_bill.custnum ASC, cust_bill._date DESC'; - #$count_query = "SELECT 'N/A', 'N/A', 'N/A'"; #XXXXXXX fix - $count_query = "SELECT COUNT(DISTINCT cust_bill.custnum), 'N/A', 'N/A'"; - } - unless ( $count_query ) { - $count_query = "SELECT COUNT(*), sum(charged), sum($owed)"; - $count_addl = [ '$%.2f total invoiced', - '$%.2f total outstanding balance', - ]; - } - $count_query .= " FROM cust_bill $addl_from $extra_sql"; + $count_query = "SELECT COUNT(*), sum(charged), sum($owed) + FROM cust_bill $extra_sql"; $sql_query = { 'table' => 'cust_bill', - 'addl_from' => $addl_from, 'hashref' => {}, - 'select' => "$distinct ". join(', ', - 'cust_bill.*', - #( map "cust_main.$_", qw(custnum last first company) ), - 'cust_main.custnum as cust_main_custnum', - FS::UI::Web::cust_sql_fields(), - "$owed as owed", - ), + 'select' => "cust_bill.*, $owed as owed", 'extra_sql' => "$extra_sql $orderby" }; + } else { + $cgi->param('invnum') =~ /^\s*(FS-)?(\d+)\s*$/; + $count_query = "SELECT COUNT(*) FROM cust_bill WHERE invnum = $2"; + $sql_query = { + 'table' => 'cust_bill', + 'hashref' => { 'invnum' => $2 }, + #'select' => '*', + }; } my $link = [ "${p}view/cust_bill.cgi?", 'invnum', ]; my $clink = sub { my $cust_bill = shift; - $cust_bill->cust_main_custnum + my $cust_main = $cust_bill->cust_main; + $cust_main ? [ "${p}view/cust_main.cgi?", 'custnum' ] : ''; }; - my $conf = new FS::Conf; - my $money_char = $conf->config('money_char') || '$'; - - my $html_init = join("\n", map { - ( my $action = $_ ) =~ s/_$//; - include('/elements/progress-init.html', - $_.'form', - [ 'begin', 'end', 'agentnum', 'open', 'days', 'newest_percust' ], - "../misc/${_}invoices.cgi", - { 'message' => "Invoices re-${action}ed" }, #would be nice to show the number of them, but... - $_, #key - ), - qq!<FORM NAME="${_}form">!, - qq!<INPUT TYPE="hidden" NAME="begin" VALUE="$begin">!, - qq!<INPUT TYPE="hidden" NAME="end" VALUE="$end">!, - qq!<INPUT TYPE="hidden" NAME="agentnum" VALUE="$agentnum">!, - qq!<INPUT TYPE="hidden" NAME="open" VALUE="$open">!, - qq!<INPUT TYPE="hidden" NAME="days" VALUE="$days">!, - qq!</FORM>! - } qw( print_ email_ fax_ ) ); - - my $menubar = [ - 'Main menu' => $p, - 'Print these invoices' => - "javascript:print_process()", - 'Email these invoices' => - "javascript:email_process()", - ]; - - push @$menubar, 'Fax these invoices' => - "javascript:fax_process()" - if $conf->exists('hylafax'); - -%><%= include( 'elements/search.html', - 'title' => 'Invoice Search Results', - 'html_init' => $html_init, - 'menubar' => $menubar, - 'name' => 'invoices', - 'query' => $sql_query, - 'count_query' => $count_query, - 'count_addl' => $count_addl, - 'redirect' => $link, - 'header' => [ 'Invoice #', - 'Balance', - 'Amount', - 'Date', - FS::UI::Web::cust_header(), - ], - 'fields' => [ - 'invnum', - sub { sprintf($money_char.'%.2f', shift->get('owed') ) }, - sub { sprintf($money_char.'%.2f', shift->charged ) }, - sub { time2str('%b %d %Y', shift->_date ) }, - \&FS::UI::Web::cust_fields, - ], - 'align' => 'rrrrll', - 'links' => [ - $link, - $link, - $link, - $link, - ( map { $clink } FS::UI::Web::cust_header() ), - ], - - ) +%> +<%= include( 'elements/search.html', + 'title' => 'Invoice Search Results', + 'name' => 'invoices', + 'query' => $sql_query, + 'count_query' => $count_query, + 'count_addl' => [ '$%.2f total invoiced', + '$%.2f total outstanding balance', + ], + 'redirect' => $link, + 'header' => + [ 'Invoice #', qw(Balance Amount Date), 'Contact name', + 'Company' ], + 'fields' => [ + 'invnum', + sub { sprintf('$%.2f', shift->get('owed') ) }, + sub { sprintf('$%.2f', shift->charged ) }, + sub { time2str('%b %d %Y', shift->_date ) }, + sub { my $cust_bill = shift; + my $cust_main = $cust_bill->cust_main; + $cust_main + ? $cust_main->get('last'). ', '. $cust_main->first + : "WARNING: can't find cust_main.custnum ". + $cust_bill->custnum. ' (cust_bill.invnum '. + $cust_bill->invnum. ')'; + }, + sub { my $cust_main = shift->cust_main; + $cust_main ? $cust_main->company : ''; + }, + ], + 'links' => [ + $link, + $link, + $link, + $link, + $clink, + $clink, + ], + + ) %> diff --git a/httemplate/search/cust_bill_event.cgi b/httemplate/search/cust_bill_event.cgi index d82a833..7c2b3a2 100644 --- a/httemplate/search/cust_bill_event.cgi +++ b/httemplate/search/cust_bill_event.cgi @@ -1,137 +1,62 @@ +<!-- mason kludge --> <% -my $title = $cgi->param('failed') ? 'Failed invoice events' : 'Invoice events'; +#false laziness with view/cust_bill.cgi -my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi); +$cgi->param('beginning') =~ /^([ 0-9\-\/]{0,10})$/; +my $beginning = str2time($1) || 0; -##tie my %hash, 'Tie::DxHash', -#my %hash = ( -# _date => { op=> '>=', value=>$beginning }, -## i wish... -## _date => { op=> '<=', value=>$ending }, -#); -#$hash{'statustext'} = { op=> '!=', value=>'' } -# if $cgi->param('failed'); +$cgi->param('ending') =~ /^([ 0-9\-\/]{0,10})$/; +my $ending = ( $1 ? str2time($1) : 4294880896 ) + 86399; -my $where = " WHERE cust_bill_event._date >= $beginning". - " AND cust_bill_event._date <= $ending"; +my @cust_bill_event = + sort { $a->_date <=> $b->_date } + qsearch('cust_bill_event', { + _date => { op=> '>=', value=>$beginning }, + statustext => { op=> '!=', value=>'' }, +# i wish... +# _date => { op=> '<=', value=>$ending }, + }, '', "AND _date <= $ending"); -if ( $cgi->param('failed') ) { - $where .= " AND statustext != '' ". - " AND statustext IS NOT NULL ". - " AND statustext != 'N/A' " -} - -if ( $cgi->param('part_bill_event.payby') =~ /^(\w+)$/ ) { - $where .= " AND part_bill_event.payby = '$1' "; -} - -my $sql_query = { - 'table' => 'cust_bill_event', - #'hashref' => \%hash, - 'hashref' => {}, - 'select' => join(', ', - 'cust_bill_event.*', - 'part_bill_event.event', - 'cust_bill.custnum', - 'cust_bill._date AS cust_bill_date', - 'cust_main.custnum AS cust_main_custnum', - FS::UI::Web::cust_sql_fields(), - ), - 'extra_sql' => "$where ORDER BY _date ASC", - 'addl_from' => 'LEFT JOIN part_bill_event USING ( eventpart ) '. - 'LEFT JOIN cust_bill USING ( invnum ) '. - 'LEFT JOIN cust_main USING ( custnum ) ', -}; - -my $count_sql = "SELECT COUNT(*) FROM cust_bill_event ". - "LEFT JOIN part_bill_event USING ( eventpart ) ". - $where; - -my $conf = new FS::Conf; - -my $failed = $cgi->param('failed'); - -my $html_init = join("\n", map { - ( my $action = $_ ) =~ s/_$//; - include('/elements/progress-init.html', - $_.'form', - [ 'action', 'beginning', 'ending', 'failed' ], - "../misc/${_}invoice_events.cgi", - { 'message' => "Invoices re-${action}ed" }, #would be nice to show the number of them, but... - $_, #key - ), - qq!<FORM NAME="${_}form">!, - qq!<INPUT TYPE="hidden" NAME="action" VALUE="$_">!, #not used though - qq!<INPUT TYPE="hidden" NAME="beginning" VALUE="$beginning">!, - qq!<INPUT TYPE="hidden" NAME="ending" VALUE="$ending">!, - qq!<INPUT TYPE="hidden" NAME="failed" VALUE="$failed">!, - qq!</FORM>! -} qw( print_ email_ fax_ ) ); - -my $menubar = [ - 'Main menu' => $p, - 'Re-print these events' => - "javascript:print_process()", - 'Re-email these events' => - "javascript:email_process()", - ]; - -push @$menubar, 'Re-fax these events' => - "javascript:fax_process()" - if $conf->exists('hylafax'); - -my $link_cust = sub { - my $cust_bill_event = shift; - $cust_bill_event->cust_main_custnum - ? [ "${p}view/cust_main.cgi?", 'custnum' ] - : ''; -}; +%> -%><%= include( 'elements/search.html', - 'title' => $title, - 'html_init' => $html_init, - 'menubar' => $menubar, - 'name' => 'billing events', - 'query' => $sql_query, - 'count_query' => $count_sql, - 'header' => [ 'Event', - 'Date', - 'Status', - #'Inv #', 'Inv Date', 'Cust #', - 'Invoice', - FS::UI::Web::cust_header(), - ], - 'fields' => [ - 'event', - sub { time2str("%b %d %Y %T", $_[0]->_date) }, - sub { - #my $cust_bill_event = shift; - my $status = $_[0]->status; - $status .= ': '.$_[0]->statustext - if $_[0]->statustext; - $status; - }, - sub { - #my $cust_bill_event = shift; - 'Invoice #'. $_[0]->invnum. - ' ('. - time2str("%D", $_[0]->cust_bill_date). - ')'; - }, - \&FS::UI::Web::cust_fields, - ], - 'links' => [ - '', - '', - '', - sub { - my $part_bill_event = shift; - my $template = $part_bill_event->templatename; - $template .= '-' if $template; - [ "${p}view/cust_bill.cgi?$template", 'invnum']; - }, - ( map { $link_cust } FS::UI::Web::cust_header() ), - ], - ) +<%= header('Failed billing events') %> + +<%= table() %> +<TR> + <TH>Event</TH> + <TH>Date</TH> + <TH>Status</TH> + <TH>Invoice</TH> + <TH>(bill) name</TH> + <TH>company</TH> +<% if ( defined dbdef->table('cust_main')->column('ship_last') ) { %> + <TH>(service) name</TH> + <TH>company</TH> +<% } %> +</TR> + +<% foreach my $cust_bill_event ( @cust_bill_event ) { + my $status = $cust_bill_event->status; + $status .= ': '.$cust_bill_event->statustext if $cust_bill_event->statustext; + my $cust_bill = $cust_bill_event->cust_bill; + my $cust_main = $cust_bill->cust_main; + my $invlink = "${p}view/cust_bill.cgi?". $cust_bill->invnum; + my $custlink = "${p}view/cust_main.cgi?". $cust_main->custnum; %> +<TR> + <TD><%= $cust_bill_event->part_bill_event->event %></TD> + <TD><%= time2str("%a %b %e %T %Y", $cust_bill_event->_date) %></TD> + <TD><%= $status %></TD> + <TD><A HREF="<%=$invlink%>">Invoice #<%= $cust_bill->invnum %> (<%= time2str("%D", $cust_bill->_date ) %>)</A></TD> + <TD><A HREF="<%=$custlink%>"><%= $cust_main->last. ', '. $cust_main->first %></A></TD> + <TD><A HREF="<%=$custlink%>"><%= $cust_main->company %></A></TD> + <% if ( defined dbdef->table('cust_main')->column('ship_last') ) { %> + <TD><A HREF="<%=$custlink%>"><%= $cust_main->ship_last. ', '. $cust_main->ship_first %></A></TD> + <TD><A HREF="<%=$custlink%>"><%= $cust_main->ship_company %></A></TD> + <% } %> +</TR> +<% } %> +</TABLE> + +</BODY></HTML> diff --git a/httemplate/search/cust_bill_event.html b/httemplate/search/cust_bill_event.html index 197f280..cd96ddf 100755 --- a/httemplate/search/cust_bill_event.html +++ b/httemplate/search/cust_bill_event.html @@ -1,15 +1,14 @@ -<%= include( - '/elements/header.html', - ( $cgi->param('failed') ? 'Failed invoice events' : 'Invoice events' ), - include('/elements/menubar.html', - 'Main menu' => $p, # popurl(2), - ), - - ) -%> - - <FORM ACTION="cust_bill_event.cgi" METHOD="GET"> - <INPUT TYPE="hidden" NAME="failed" VALUE="<%= $cgi->param('failed') %>"> +<HTML> + <HEAD> + <TITLE>Invoice event errors</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>Invoice event errors</H1> + <FORM ACTION="cust_bill_event.cgi" METHOD="post"> <TABLE> <!--<TR> <TD ALIGN="right">Customer type</TD> @@ -23,36 +22,33 @@ </TD> </TR> --> - <%= include( '/elements/tr-input-beginning_ending.html' ) %> - <!-- <TR> - <TD ALIGN="right">Events: </TD> - <TD> - <SELECT NAME="eventpart"> - <OPTION SELECTED VALUE=""><%= $cgi->param('failed') ? '(all failed events)' : '(all events)' %> - <% foreach my $part_bill_event ( qsearch( 'part_bill_event', {} ) ) { %> - <% } %> - </SELECT> - </TD> + <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">Events for payment type: </TD> - <TD> - <SELECT NAME="part_bill_event.payby"> - <OPTION SELECTED VALUE="">(all) - <OPTION VALUE="CARD">Credit card (automatic) - <OPTION VALUE="BILL">Billing - <OPTION VALUE="CHEK">Electronic check (automatic) - <OPTION VALUE="DCRD">Credit card (on-demand) - <OPTION VALUE="DCHK">Electronic check (on-demand) - <OPTION VALUE="LECB">Phone bill billing - <OPTION VALUE="COMP">Complimentary - </SELECT> - </TD> + <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> </BODY> </HTML> + diff --git a/httemplate/search/cust_bill_pkg.cgi b/httemplate/search/cust_bill_pkg.cgi deleted file mode 100644 index 082ccc8..0000000 --- a/httemplate/search/cust_bill_pkg.cgi +++ /dev/null @@ -1,148 +0,0 @@ -<% - -my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi); - -my $join_cust = " - JOIN cust_bill USING ( invnum ) - JOIN cust_main USING ( custnum ) -"; - -my $join_pkg = " - LEFT JOIN cust_pkg USING ( pkgnum ) - LEFT JOIN part_pkg USING ( pkgpart ) -"; - -my $where = " - WHERE _date >= $beginning AND _date <= $ending - AND payby != 'COMP' -"; - -if ( $cgi->param('out') ) { - - $where .= " - AND 0 = ( - SELECT COUNT(*) FROM cust_main_county - WHERE ( cust_main_county.county = cust_main.county - OR ( cust_main_county.county IS NULL AND cust_main.county = '' ) - OR ( cust_main_county.county = '' AND cust_main.county IS NULL) - OR ( cust_main_county.county IS NULL AND cust_main.county IS NULL) - ) - AND ( cust_main_county.state = cust_main.state - OR ( cust_main_county.state IS NULL AND cust_main.state = '' ) - OR ( cust_main_county.state = '' AND cust_main.state IS NULL ) - OR ( cust_main_county.state IS NULL AND cust_main.state IS NULL ) - ) - AND cust_main_county.country = cust_main.country - AND cust_main_county.tax > 0 - ) - "; - -} elsif ( $cgi->param('country' ) ) { - - my $county = dbh->quote( $cgi->param('county') ); - my $state = dbh->quote( $cgi->param('state') ); - my $country = dbh->quote( $cgi->param('country') ); - $where .= " - AND ( county = $county OR $county = '' ) - AND ( state = $state OR $state = '' ) - AND country = $country - "; - $where .= ' AND taxclass = '. dbh->quote( $cgi->param('taxclass') ) - if $cgi->param('taxclass'); - -} - -$where .= ' AND pkgnum != 0' if $cgi->param('nottax'); - -$where .= ' AND pkgnum = 0' if $cgi->param('istax'); - -$where .= " AND tax = 'Y'" if $cgi->param('cust_tax'); - -my $count_query; -if ( $cgi->param('pkg_tax') ) { - - $count_query = - "SELECT COUNT(*), SUM( ( CASE WHEN part_pkg.setuptax = 'Y' - THEN cust_bill_pkg.setup - ELSE 0 ) - + - ( CASE WHEN part_pkg.recurtax = 'Y' - THEN cust_bill_pkg.recur - ELSE 0 ) - )"; - - $where .= " AND ( - ( part_pkg.setuptax = 'Y' AND cust_bill_pkg.setup > 0 ) - OR ( part_pkg.recurtax = 'Y' AND cust_bill_pkg.recur > 0 ) - )"; - -} else { - - $count_query = - "SELECT COUNT(*), SUM(cust_bill_pkg.setup + cust_bill_pkg.recur)"; - -} -$count_query .= " FROM cust_bill_pkg $join_cust $join_pkg $where"; - -my $query = { - 'table' => 'cust_bill_pkg', - 'addl_from' => "$join_cust $join_pkg", - 'hashref' => {}, - 'select' => join(', ', - 'cust_bill_pkg.*', - 'cust_bill._date', - 'part_pkg.pkg', - 'cust_main.custnum', - FS::UI::Web::cust_sql_fields(), - ), - 'extra_sql' => $where, -}; - -my $ilink = [ "${p}view/cust_bill.cgi?", 'invnum' ]; -my $clink = [ "${p}view/cust_main.cgi?", 'custnum' ]; - -my $conf = new FS::Conf; -my $money_char = $conf->config('money_char') || '$'; - -%><%= include( 'elements/search.html', - 'title' => 'Line items', - 'name' => 'line items', - 'query' => $query, - 'count_query' => $count_query, - 'count_addl' => [ $money_char. '%.2f total', ], - 'header' => [ - '#', - 'Description', - 'Setup charge', - 'Recurring charge', - 'Invoice', - 'Date', - FS::UI::Web::cust_header(), - ], - 'fields' => [ - 'billpkgnum', - sub { $_[0]->pkgnum > 0 - ? $_[0]->get('pkg') - : $_[0]->get('itemdesc') - }, - #strikethrough or "N/A ($amount)" or something these when - # they're not applicable to pkg_tax search - sub { sprintf($money_char.'%.2f', shift->setup ) }, - sub { sprintf($money_char.'%.2f', shift->recur ) }, - 'invnum', - sub { time2str('%b %d %Y', shift->_date ) }, - \&FS::UI::Web::cust_fields, - ], - 'links' => [ - '', - '', - '', - '', - $ilink, - $ilink, - ( map { $clink } FS::UI::Web::cust_header() ), - ], - 'align' => 'rlrrrc', - ) -%> - diff --git a/httemplate/search/cust_credit.html b/httemplate/search/cust_credit.html index 279d682..faaa7a8 100755 --- a/httemplate/search/cust_credit.html +++ b/httemplate/search/cust_credit.html @@ -1,18 +1,10 @@ <% - my $title = 'Credit Search Results'; #my( $count_query, $sql_query ); my @search = (); if ( $cgi->param('otaker') && $cgi->param('otaker') =~ /^([\w\.\-]+)$/ ) { - push @search, "cust_credit.otaker = '$1'"; - } - - if ( $cgi->param('agentnum') && $cgi->param('agentnum') =~ /^(\d+)$/ ) { - push @search, "agentnum = $1"; - my $agent = qsearchs('agent', { 'agentnum' => $1 } ); - die "unknown agentnum $1" unless $agent; - $title = $agent->agent. " $title"; + push @search, "otaker = '$1'"; } #false laziness with cust_pkg.cgi and cust_pay.cgi @@ -40,58 +32,49 @@ ? 'WHERE '. join(' AND ', @search) : ''; - my $count_query = 'SELECT COUNT(*), SUM(amount) '. - 'FROM cust_credit LEFT JOIN cust_main USING ( custnum ) '. - $where; - + my $count_query = "SELECT COUNT(*), SUM(amount) FROM cust_credit $where"; my $sql_query = { 'table' => 'cust_credit', - 'select' => join(', ', - 'cust_credit.*', - 'cust_main.custnum as cust_main_custnum', - FS::UI::Web::cust_sql_fields(), - ), 'hashref' => {}, 'extra_sql' => $where, - 'addl_from' => 'LEFT JOIN cust_main USING ( custnum )', }; - my $clink = sub { - my $cust_bill = shift; - $cust_bill->cust_main_custnum - ? [ "${p}view/cust_main.cgi?", 'custnum' ] - : ''; - }; + my $clink = [ "${p}view/cust_main.cgi?", 'custnum' ]; -%><%= include( 'elements/search.html', - 'title' => $title, - 'name' => 'credits', - 'query' => $sql_query, - 'count_query' => $count_query, - 'count_addl' => [ '$%.2f total credited', ], - #'redirect' => $link, - 'header' => [ 'Amount', - 'Date', - FS::UI::Web::cust_header(), - 'By', - 'Reason' - ], - 'fields' => [ - #'crednum', - sub { sprintf('$%.2f', shift->amount ) }, - sub { time2str('%b %d %Y', shift->_date ) }, - \&FS::UI::Web::cust_fields, - 'otaker', - 'reason', - ], - #'align' => 'rrrllll', - 'align' => 'rr', - 'links' => [ - '', - '', - ( map { $clink } FS::UI::Web::cust_header() ), - '', - '', - ], - ) +%> +<%= include( 'elements/search.html', + 'title' => 'Credit Search Results', + 'name' => 'credits', + 'query' => $sql_query, + 'count_query' => $count_query, + 'count_addl' => [ '$%.2f total credited', ], + #'redirect' => $link, + 'header' => + [ qw(Amount Date), 'Cust #', 'Contact name', + qw(Company By Reason) ], + 'fields' => [ + #'crednum', + sub { sprintf('$%.2f', shift->amount ) }, + sub { time2str('%b %d %Y', shift->_date ) }, + 'custnum', + sub { my $cust_main = shift->cust_main; + $cust_main->get('last'). ', '. $cust_main->first; + }, + sub { my $cust_main = shift->cust_main; + $cust_main->company; + }, + 'otaker', + 'reason', + ], + 'align' => 'rrrllll', + 'links' => [ + '', + '', + $clink, + $clink, + $clink, + '', + '', + ], + ) %> diff --git a/httemplate/search/cust_main-otaker.cgi b/httemplate/search/cust_main-otaker.cgi index 03c2619..4421436 100755 --- a/httemplate/search/cust_main-otaker.cgi +++ b/httemplate/search/cust_main-otaker.cgi @@ -7,7 +7,7 @@ Customer Search </FONT> <BR> - <FORM ACTION="cust_main.cgi" METHOD="GET"> + <FORM ACTION="cust_main.cgi" METHOD="post"> Search for <B>Order taker</B>: <INPUT TYPE="hidden" NAME="otaker_on" VALUE="TRUE"> <% my $sth = dbh->prepare("SELECT DISTINCT otaker FROM cust_main") diff --git a/httemplate/search/cust_main-payinfo.html b/httemplate/search/cust_main-payinfo.html index b82b610..671b5ef 100755 --- a/httemplate/search/cust_main-payinfo.html +++ b/httemplate/search/cust_main-payinfo.html @@ -7,7 +7,7 @@ Customer Search </FONT> <BR> - <FORM ACTION="cust_main.cgi" METHOD="GET"> + <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"> diff --git a/httemplate/search/cust_main-quickpay.html b/httemplate/search/cust_main-quickpay.html index 154a641..077d290 100755 --- a/httemplate/search/cust_main-quickpay.html +++ b/httemplate/search/cust_main-quickpay.html @@ -8,7 +8,7 @@ </FONT> <BR><BR> <A HREF="../">Main Menu</A><BR><BR> - <FORM ACTION="cust_main.cgi" METHOD="GET"> + <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"> diff --git a/httemplate/search/cust_main.cgi b/httemplate/search/cust_main.cgi index 665f563..ecff4bf 100755 --- a/httemplate/search/cust_main.cgi +++ b/httemplate/search/cust_main.cgi @@ -57,7 +57,6 @@ if ( $cgi->param('browse') ) { my %search = (); - if ( $cgi->param('browse') ) { my $query = $cgi->param('browse'); if ( $query eq 'custnum' ) { @@ -81,16 +80,15 @@ if ( $cgi->param('browse') } else { $sortby = \*last_sort; #?? $orderby = "ORDER BY LOWER(last || ' ' || first)"; #?? - } - - 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..."; + 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..."; + } } my @qual = (); @@ -287,7 +285,7 @@ if ( scalar(@cust_main) == 1 && ! $cgi->param('referral_custnum') ) { or eidiot "Illegal referral_custnum\n"; my $referral_custnum = $1; my $cust_main = qsearchs('cust_main', { custnum => $referral_custnum } ); - print '<FORM METHOD="GET">'. + print '<FORM METHOD=POST>'. qq!<INPUT TYPE="hidden" NAME="referral_custnum" VALUE="$referral_custnum">!. 'referrals of <A HREF="'. popurl(2). "view/cust_main.cgi?$referral_custnum\">$referral_custnum: ". diff --git a/httemplate/search/cust_main.html b/httemplate/search/cust_main.html index 4f75084..5a066e4 100755 --- a/httemplate/search/cust_main.html +++ b/httemplate/search/cust_main.html @@ -7,7 +7,7 @@ Customer Search </FONT> <BR><BR> - <FORM ACTION="cust_main.cgi" METHOD="GET"> + <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"> diff --git a/httemplate/search/cust_pay.cgi b/httemplate/search/cust_pay.cgi index 99ffc3d..3f5b72a 100755 --- a/httemplate/search/cust_pay.cgi +++ b/httemplate/search/cust_pay.cgi @@ -1,122 +1,74 @@ <% - my $title = 'Payment Search Results'; my( $count_query, $sql_query ); - if ( $cgi->param('magic') ) { - - my @search = (); - my $orderby; - if ( $cgi->param('magic') eq '_date' ) { + if ( $cgi->param('magic') && $cgi->param('magic') eq '_date' ) { - - if ( $cgi->param('agentnum') && $cgi->param('agentnum') =~ /^(\d+)$/ ) { - push @search, "agentnum = $1"; # $search{'agentnum'} = $1; - my $agent = qsearchs('agent', { 'agentnum' => $1 } ); - die "unknown agentnum $1" unless $agent; - $title = $agent->agent. " $title"; - } - - if ( $cgi->param('payby') ) { - $cgi->param('payby') =~ - /^(CARD|CHEK|BILL|PREP|CASH|WEST|MCRD)(-(VisaMC|Amex|Discover|Maestro))?$/ - or die "illegal payby ". $cgi->param('payby'); - push @search, "cust_pay.payby = '$1'"; - if ( $3 ) { - if ( $3 eq 'VisaMC' ) { - #avoid posix regexes for portability - push @search, - " ( ( substring(cust_pay.payinfo from 1 for 1) = '4' ". - " AND substring(cust_pay.payinfo from 1 for 4) != '4936' ". - " AND substring(cust_pay.payinfo from 1 for 6) ". - " NOT SIMILAR TO '49030[2-9]' ". - " AND substring(cust_pay.payinfo from 1 for 6) ". - " NOT SIMILAR TO '49033[5-9]' ". - " AND substring(cust_pay.payinfo from 1 for 6) ". - " NOT SIMILAR TO '49110[1-2]' ". - " AND substring(cust_pay.payinfo from 1 for 6) ". - " NOT SIMILAR TO '49117[4-9]' ". - " AND substring(cust_pay.payinfo from 1 for 6) ". - " NOT SIMILAR TO '49118[1-2]' ". - " )". - " OR substring(cust_pay.payinfo from 1 for 2) = '51' ". - " OR substring(cust_pay.payinfo from 1 for 2) = '52' ". - " OR substring(cust_pay.payinfo from 1 for 2) = '53' ". - " OR substring(cust_pay.payinfo from 1 for 2) = '54' ". - " OR substring(cust_pay.payinfo from 1 for 2) = '54' ". - " OR substring(cust_pay.payinfo from 1 for 2) = '55' ". - " ) "; - } elsif ( $3 eq 'Amex' ) { - push @search, - " ( substring(cust_pay.payinfo from 1 for 2 ) = '34' ". - " OR substring(cust_pay.payinfo from 1 for 2 ) = '37' ". - " ) "; - } elsif ( $3 eq 'Discover' ) { - push @search, - " ( substring(cust_pay.payinfo from 1 for 4 ) = '6011' ". - " OR substring(cust_pay.payinfo from 1 for 3 ) = '650' ". - " ) "; - } elsif ( $3 eq 'Maestro' ) { - push @search, - " ( substring(cust_pay.payinfo from 1 for 2 ) = '63' ". - " OR substring(cust_pay.payinfo from 1 for 2 ) = '67' ". - " OR substring(cust_pay.payinfo from 1 for 6 ) = '564182' ". - " OR substring(cust_pay.payinfo from 1 for 4 ) = '4936' ". - " OR substring(cust_pay.payinfo from 1 for 6 ) ". - " SIMILAR TO '49030[2-9]' ". - " OR substring(cust_pay.payinfo from 1 for 6 ) ". - " SIMILAR TO '49033[5-9]' ". - " OR substring(cust_pay.payinfo from 1 for 6 ) ". - " SIMILAR TO '49110[1-2]' ". - " OR substring(cust_pay.payinfo from 1 for 6 ) ". - " SIMILAR TO '49117[4-9]' ". - " OR substring(cust_pay.payinfo from 1 for 6 ) ". - " SIMILAR TO '49118[1-2]' ". - " ) "; - } else { - die "unknown card type $3"; - } + my %search; + my @search; + + if ( $cgi->param('payby') ) { + $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"; } } - - my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi); - push @search, "_date >= $beginning ", - "_date <= $ending"; - - $orderby = '_date'; + } - } elsif ( $cgi->param('magic') eq 'paybatch' ) { - - $cgi->param('paybatch') =~ /^([\w\/\:\-\.]+)$/ - or die "illegal paybatch: ". $cgi->param('paybatch'); - - push @search, "paybatch = '$1'"; - - $orderby = "LOWER(company || ' ' || last || ' ' || first )"; - - } else { - die "unknown search magic: ". $cgi->param('magic'); + #false laziness with cust_pkg.cgi + if ( $cgi->param('beginning') + && $cgi->param('beginning') =~ /^([ 0-9\-\/]{0,10})$/ ) { + my $beginning = str2time($1); + push @search, "_date >= $beginning "; } - - my $search = ''; + if ( $cgi->param('ending') + && $cgi->param('ending') =~ /^([ 0-9\-\/]{0,10})$/ ) { + my $ending = str2time($1) + 86399; + push @search, " _date <= $ending "; + } + if ( $cgi->param('begin') + && $cgi->param('begin') =~ /^(\d+)$/ ) { + push @search, "_date >= $1 "; + } + if ( $cgi->param('end') + && $cgi->param('end') =~ /^(\d+)$/ ) { + push @search, " _date < $1 "; + } + + my $search; if ( @search ) { - $search = ' WHERE '. join(' AND ', @search); + $search = ( scalar(keys %search) ? ' AND ' : ' WHERE ' ). + join(' AND ', @search); } - - $count_query = "SELECT COUNT(*), SUM(paid) ". - "FROM cust_pay LEFT JOIN cust_main USING ( custnum )". - $search; + my $hsearch = join(' AND ', map { "$_ = '$search{$_}'" } keys %search ); + $count_query = "SELECT COUNT(*), SUM(paid) FROM cust_pay ". + ( $hsearch ? " WHERE $hsearch " : '' ). + $search; + $sql_query = { 'table' => 'cust_pay', - 'select' => join(', ', - 'cust_pay.*', - 'cust_main.custnum as cust_main_custnum', - FS::UI::Web::cust_sql_fields(), - ), - 'hashref' => {}, - 'extra_sql' => "$search ORDER BY $orderby", - 'addl_from' => 'LEFT JOIN cust_main USING ( custnum )', + 'hashref' => \%search, + 'extra_sql' => "$search ORDER BY _date", }; - + } else { $cgi->param('payinfo') =~ /^\s*(\d+)\s*$/ or die "illegal payinfo"; @@ -137,56 +89,49 @@ } - my $link = sub { - my $cust_pay = shift; - $cust_pay->cust_main_custnum - ? [ "${p}view/cust_main.cgi?", 'custnum' ] - : ''; - }; + my $link = [ "${p}view/cust_main.cgi?", 'custnum' ]; -%><%= include( 'elements/search.html', - 'title' => $title, - 'name' => 'payments', - 'query' => $sql_query, - 'count_query' => $count_query, - 'count_addl' => [ '$%.2f total paid', ], - 'header' => [ 'Payment', - 'Amount', - 'Date', - FS::UI::Web::cust_header(), - ], - 'fields' => [ - sub { - my $cust_pay = shift; - if ( $cust_pay->payby eq 'CARD' ) { - 'Card #'. $cust_pay->payinfo_masked; - } elsif ( $cust_pay->payby eq 'CHEK' ) { - 'E-check acct#'. $cust_pay->payinfo; - } elsif ( $cust_pay->payby eq 'BILL' ) { - 'Check #'. $cust_pay->payinfo; - } elsif ( $cust_pay->payby eq 'PREP' ) { - 'Prepaid card #'. $cust_pay->payinfo; - } elsif ( $cust_pay->payby eq 'CASH' ) { - 'Cash '. $cust_pay->payinfo; - } elsif ( $cust_pay->payby eq 'WEST' ) { - 'Western Union'; #. $cust_pay->payinfo; - } elsif ( $cust_pay->payby eq 'MCRD' ) { - 'Manual credit card'; #. $cust_pay->payinfo; - } else { - $cust_pay->payby. ' '. $cust_pay->payinfo; - } - }, - sub { sprintf('$%.2f', shift->paid ) }, - sub { time2str('%b %d %Y', shift->_date ) }, - \&FS::UI::Web::cust_fields, - ], - #'align' => 'lrrrll', - 'align' => 'rrr', - 'links' => [ - '', - '', - '', - ( map { $link } FS::UI::Web::cust_header() ), - ], - ) +%> +<%= include( 'elements/search.html', + 'title' => 'Payment Search Results', + 'name' => 'payments', + 'query' => $sql_query, + 'count_query' => $count_query, + 'count_addl' => [ '$%.2f total paid', ], + 'header' => + [ qw(Payment Amount Date), 'Cust #', 'Contact name', + 'Company', ], + 'fields' => [ + sub { + my $cust_pay = shift; + if ( $cust_pay->payby eq 'CARD' ) { + 'Card #'. $cust_pay->payinfo_masked; + } elsif ( $cust_pay->payby eq 'CHEK' ) { + 'E-check acct#'. $cust_pay->payinfo; + } elsif ( $cust_pay->payby eq 'BILL' ) { + 'Check #'. $cust_pay->payinfo; + } else { + $cust_pay->payby. ' '. $cust_pay->payinfo; + } + }, + sub { sprintf('$%.2f', shift->paid ) }, + sub { time2str('%b %d %Y', shift->_date ) }, + 'custnum', + sub { my $cust_main = shift->cust_main; + $cust_main->get('last'). ', '. $cust_main->first; + }, + sub { my $cust_main = shift->cust_main; + $cust_main->company; + }, + ], + 'align' => 'lrrrll', + 'links' => [ + '', + '', + '', + $link, + $link, + $link, + ], + ) %> diff --git a/httemplate/search/cust_pay.html b/httemplate/search/cust_pay.html index 6414cf7..3848d66 100755 --- a/httemplate/search/cust_pay.html +++ b/httemplate/search/cust_pay.html @@ -7,7 +7,7 @@ Check # Search </FONT> <BR><BR> - <FORM ACTION="cust_pay.cgi" METHOD="GET"> + <FORM ACTION="cust_pay.cgi" METHOD="post"> Search for <B>check #</B>: <INPUT TYPE="text" NAME="payinfo"> <INPUT TYPE="hidden" NAME="payby" VALUE="BILL"> diff --git a/httemplate/search/cust_pkg.cgi b/httemplate/search/cust_pkg.cgi index 5da4d82..6d26317 100755 --- a/httemplate/search/cust_pkg.cgi +++ b/httemplate/search/cust_pkg.cgi @@ -1,234 +1,363 @@ <% +my $conf = new FS::Conf; +my $maxrecords = $conf->config('maxsearchrecordsperpage'); + my %part_pkg = map { $_->pkgpart => $_ } qsearch('part_pkg', {}); -my($query) = $cgi->keywords; +my $limit = ''; +$limit .= "LIMIT $maxrecords" if $maxrecords; -my $orderby; -my @where; -my $cjoin = ''; +my $offset = $cgi->param('offset') || 0; +$limit .= " OFFSET $offset" if $offset; -if ( $cgi->param('agentnum') =~ /^(\d+)$/ and $1 ) { - $cjoin = "LEFT JOIN cust_main USING ( custnum )"; - push @where, - "agentnum = $1"; -} +my $total; + +my($query) = $cgi->keywords; +my $sortby; +my @cust_pkg; if ( $cgi->param('magic') && $cgi->param('magic') eq 'bill' ) { - $orderby = 'ORDER BY bill'; + $sortby=\*bill_sort; + + #false laziness with cust_pay.cgi + my $range = ''; + if ( $cgi->param('beginning') + && $cgi->param('beginning') =~ /^([ 0-9\-\/]{0,10})$/ ) { + my $beginning = str2time($1); + $range = " WHERE bill >= $beginning "; + } + if ( $cgi->param('ending') + && $cgi->param('ending') =~ /^([ 0-9\-\/]{0,10})$/ ) { + my $ending = str2time($1) + 86399; + $range .= ( $range ? ' AND ' : ' WHERE ' ). " bill <= $ending "; + } - my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi); - push @where, - "bill >= $beginning ", - "bill <= $ending", - '( cancel IS NULL OR cancel = 0 )'; + $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; + my $sth = dbh->prepare($statement) or die dbh->errstr." preparing $statement"; + $sth->execute or die "Error executing \"$statement\": ". $sth->errstr; + + $total = $sth->fetchrow_arrayref->[0]; + + @cust_pkg = qsearch('cust_pkg',{}, '', " $range ORDER BY bill $limit" ); } else { + my $qual = ''; if ( $cgi->param('magic') && - $cgi->param('magic') =~ /^(active|suspended|cancell?ed)$/ + $cgi->param('magic') =~ /^(active|suspended|canceled)$/ ) { - $orderby = 'ORDER BY pkgnum'; - if ( $cgi->param('magic') eq 'active' ) { - - #push @where, - # '( susp IS NULL OR susp = 0 )', - # '( cancel IS NULL OR cancel = 0)'; - push @where, FS::cust_pkg->active_sql(); - + $qual = 'WHERE ( susp IS NULL OR susp = 0 )'. + ' AND ( cancel IS NULL OR cancel = 0)'; } elsif ( $cgi->param('magic') eq 'suspended' ) { - - push @where, - 'susp IS NOT NULL', - 'susp != 0', - '( cancel IS NULL OR cancel = 0)'; - - } elsif ( $cgi->param('magic') =~ /^cancell?ed$/ ) { - - push @where, - 'cancel IS NOT NULL', - 'cancel != 0'; - + $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; + if ( $cgi->param('pkgpart') =~ /^(\d+)$/ ) { - push @where, "pkgpart = $1"; + $qual .= " AND pkgpart = $1"; } } elsif ( $query eq 'pkgnum' ) { - $orderby = 'ORDER BY pkgnum'; + $sortby=\*pkgnum_sort; } elsif ( $query eq 'APKG_pkgnum' ) { - $orderby = 'ORDER BY 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',{}, '', "ORDER BY pkgnum $limit" ) + #) { + # 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; + #} + + if ( driver_name eq 'mysql' ) { + #$query = "DROP TABLE temp1_$$,temp2_$$;"; + #my $sth = dbh->prepare($query); + #$sth->execute; + + $query = "CREATE TEMPORARY TABLE temp1_$$ TYPE=MYISAM + SELECT cust_svc.pkgnum,cust_svc.svcpart,COUNT(*) as count + FROM cust_pkg,cust_svc,pkg_svc + WHERE cust_pkg.pkgnum = cust_svc.pkgnum + AND cust_svc.svcpart = pkg_svc.svcpart + AND cust_pkg.pkgpart = pkg_svc.pkgpart + GROUP BY cust_svc.pkgnum,cust_svc.svcpart"; + my $sth = dbh->prepare($query) or die dbh->errstr. " preparing $query"; + + $sth->execute or die "Error executing \"$query\": ". $sth->errstr; - push @where, '0 < ( - SELECT count(*) FROM pkg_svc - WHERE pkg_svc.pkgpart = cust_pkg.pkgpart - AND pkg_svc.quantity > ( SELECT count(*) FROM cust_svc - WHERE cust_svc.pkgnum = cust_pkg.pkgnum - AND cust_svc.svcpart = pkg_svc.svcpart - ) - )'; + $query = "CREATE TEMPORARY TABLE temp2_$$ TYPE=MYISAM + SELECT cust_pkg.pkgnum FROM cust_pkg + LEFT JOIN pkg_svc ON (cust_pkg.pkgpart=pkg_svc.pkgpart) + LEFT JOIN temp1_$$ ON (cust_pkg.pkgnum = temp1_$$.pkgnum + AND pkg_svc.svcpart=temp1_$$.svcpart) + WHERE ( pkg_svc.quantity > temp1_$$.count + OR temp1_$$.pkgnum IS NULL ) + AND pkg_svc.quantity != 0;"; + $sth = dbh->prepare($query) or die dbh->errstr. " preparing $query"; + $sth->execute or die "Error executing \"$query\": ". $sth->errstr; + $qual = " LEFT JOIN temp2_$$ ON cust_pkg.pkgnum = temp2_$$.pkgnum + WHERE temp2_$$.pkgnum IS NOT NULL"; + + } else { + + $qual = " + WHERE 0 < + ( SELECT count(*) FROM pkg_svc + WHERE pkg_svc.pkgpart = cust_pkg.pkgpart + AND pkg_svc.quantity > ( SELECT count(*) FROM cust_svc + WHERE cust_svc.pkgnum = cust_pkg.pkgnum + AND cust_svc.svcpart = pkg_svc.svcpart + ) + ) + "; + + } } else { die "Empty or unknown QUERY_STRING!"; } + + my $statement = "SELECT COUNT(*) FROM cust_pkg $qual"; + my $sth = dbh->prepare($statement) or die dbh->errstr." preparing $statement"; + $sth->execute or die "Error executing \"$statement\": ". $sth->errstr; + + $total = $sth->fetchrow_arrayref->[0]; + + my $tblname = driver_name eq 'mysql' ? 'cust_pkg.' : ''; + @cust_pkg = + qsearch('cust_pkg',{}, '', "$qual ORDER BY ${tblname}pkgnum $limit" ); + + if ( driver_name eq 'mysql' ) { + $query = "DROP TABLE temp1_$$,temp2_$$;"; + my $sth = dbh->prepare($query) or die dbh->errstr. " doing $query"; + $sth->execute; # or die "Error executing \"$query\": ". $sth->errstr; + } + +} + +if ( scalar(@cust_pkg) == 1 ) { + print $cgi->redirect("${p}view/cust_main.cgi?". $cust_pkg[0]->custnum. + "#cust_pkg". $cust_pkg[0]->pkgnum ); + #exit; +} elsif ( scalar(@cust_pkg) == 0 ) { #error +%> +<!-- mason kludge --> +<% + eidiot("No packages found"); +} else { +%> +<!-- mason kludge --> +<% + $total ||= scalar(@cust_pkg); + + #begin pager + my $pager = ''; + if ( $total != scalar(@cust_pkg) && $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('Package Search Results',''), + "$total matching packages found<BR><BR>$pager", &table(), <<END; + <TR> + <TH>Package</TH> + <TH><FONT SIZE=-1>Setup</FONT></TH> +END + + print '<TH><FONT SIZE=-1>Last<BR>bill</FONT></TH>' + if defined dbdef->table('cust_pkg')->column('last_bill'); + + print <<END; + <TH><FONT SIZE=-1>Next<BR>bill</FONT></TH> + <TH><FONT SIZE=-1>Susp.</FONT></TH> + <TH><FONT SIZE=-1>Expire</FONT></TH> + <TH><FONT SIZE=-1>Cancel</FONT></TH> + <TH><FONT SIZE=-1>Cust#</FONT></TH> + <TH>(bill) name</TH> + <TH>company</TH> +END + + print '<TH>(service) name</TH><TH>company</TH>' + if defined dbdef->table('cust_main')->column('ship_last'); + + print '<TH COLSPAN=2>Services</TH></TR>'; + + my $n1 = '<TR>'; + 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, $setup, $bill, $susp, $expire, $cancel, + $custnum, $last, $first, $company ) = ( + $cust_pkg->pkgnum, + $cust_pkg->getfield('setup') + ? time2str("%D", $cust_pkg->getfield('setup') ) + : '', + $cust_pkg->getfield('bill') + ? time2str("%D", $cust_pkg->getfield('bill') ) + : '', + $cust_pkg->getfield('susp') + ? time2str("%D", $cust_pkg->getfield('susp') ) + : '', + $cust_pkg->getfield('expire') + ? time2str("%D", $cust_pkg->getfield('expire') ) + : '', + $cust_pkg->getfield('cancel') + ? time2str("%D", $cust_pkg->getfield('cancel') ) + : '', + $cust_pkg->custnum, + $cust_main ? $cust_main->last : '', + $cust_main ? $cust_main->first : '', + $cust_main ? $cust_main->company : '', + ); + + my $last_bill = $cust_pkg->getfield('last_bill') + ? time2str("%D", $cust_pkg->getfield('last_bill') ) + : '' + if defined dbdef->table('cust_pkg')->column('last_bill'); + + my($ship_last, $ship_first, $ship_company); + if ( defined dbdef->table('cust_main')->column('ship_last') ) { + ($ship_last, $ship_first, $ship_company) = ( + $cust_main + ? ( $cust_main->ship_last || $cust_main->getfield('last') ) + : '', + $cust_main + ? ( $cust_main->ship_last + ? $cust_main->ship_first + : $cust_main->first ) + : '', + $cust_main + ? ( $cust_main->ship_last + ? $cust_main->ship_company + : $cust_main->company ) + : '', + ); + } + my $pkg = $part_pkg{$cust_pkg->pkgpart}->pkg; + #$pkg .= ' - '. $part_pkg{$cust_pkg->pkgpart}->comment; + my @cust_svc = qsearch( 'cust_svc', { 'pkgnum' => $pkgnum } ); + my $rowspan = scalar(@cust_svc) || 1; + my $p = popurl(2); + print $n1, <<END; + <TD ROWSPAN=$rowspan><A HREF="${p}view/cust_main.cgi?$custnum#cust_pkg$pkgnum"><FONT SIZE=-1>$pkgnum - $pkg</FONT></A></TD> + <TD ROWSPAN=$rowspan>$setup</TD> +END + + print "<TD ROWSPAN=$rowspan>$last_bill</TD>" + if defined dbdef->table('cust_pkg')->column('last_bill'); + + print <<END; + <TD ROWSPAN=$rowspan>$bill</TD> + <TD ROWSPAN=$rowspan>$susp</TD> + <TD ROWSPAN=$rowspan>$expire</TD> + <TD ROWSPAN=$rowspan>$cancel</TD> +END + if ( $cust_main ) { + print <<END; + <TD ROWSPAN=$rowspan><FONT SIZE=-1><A HREF="${p}view/cust_main.cgi?$custnum">$custnum</A></FONT></TD> + <TD ROWSPAN=$rowspan><FONT SIZE=-1><A HREF="${p}view/cust_main.cgi?$custnum">$last, $first</A></FONT></TD> + <TD ROWSPAN=$rowspan><FONT SIZE=-1><A HREF="${p}view/cust_main.cgi?$custnum">$company</A></FONT></TD> +END + if ( defined dbdef->table('cust_main')->column('ship_last') ) { + print <<END; + <TD ROWSPAN=$rowspan><FONT SIZE=-1><A HREF="${p}view/cust_main.cgi?$custnum">$ship_last, $ship_first</A></FONT></TD> + <TD ROWSPAN=$rowspan><FONT SIZE=-1><A HREF="${p}view/cust_main.cgi?$custnum">$ship_company</A></FONT></TD> +END + } + } else { + my $colspan = defined dbdef->table('cust_main')->column('ship_last') + ? 5 : 3; + print <<END; + <TD ROWSPAN=$rowspan COLSPAN=$colspan>WARNING: couldn't find cust_main.custnum $custnum (cust_pkg.pkgnum $pkgnum)</TD> +END + } + + my $n2 = ''; + foreach my $cust_svc ( @cust_svc ) { + my($label, $value, $svcdb) = $cust_svc->label; + my $svcnum = $cust_svc->svcnum; + my $sview = $p. "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>"; + } + + $n1 = "</TR><TR>"; + + } + print '</TR>'; + + print "</TABLE>$pager</BODY></HTML>"; + +} +sub pkgnum_sort { + $a->getfield('pkgnum') <=> $b->getfield('pkgnum'); } -my $extra_sql = scalar(@where) ? ' WHERE '. join(' AND ', @where) : ''; - -my $count_query = "SELECT COUNT(*) FROM cust_pkg $cjoin $extra_sql"; - -my $sql_query = { - 'table' => 'cust_pkg', - 'hashref' => {}, - 'select' => join(', ', - 'cust_pkg.*', - 'cust_main.custnum as cust_main_custnum', - FS::UI::Web::cust_sql_fields(), - ), - 'extra_sql' => "$extra_sql $orderby", - 'addl_from' => ' LEFT JOIN cust_main USING ( custnum ) ', - #' LEFT JOIN part_pkg USING ( pkgpart ) ' -}; - -my $link = sub { - [ "${p}view/cust_main.cgi?".shift->custnum.'#cust_pkg', 'pkgnum' ]; -}; - -my $clink = sub { - my $cust_pkg = shift; - $cust_pkg->cust_main_custnum - ? [ "${p}view/cust_main.cgi?", 'custnum' ] - : ''; -}; - -#if ( scalar(@cust_pkg) == 1 ) { -# print $cgi->redirect("${p}view/cust_main.cgi?". $cust_pkg[0]->custnum. -# "#cust_pkg". $cust_pkg[0]->pkgnum ); - -# my @cust_svc = qsearch( 'cust_svc', { 'pkgnum' => $pkgnum } ); -# my $rowspan = scalar(@cust_svc) || 1; - -# my $n2 = ''; -# foreach my $cust_svc ( @cust_svc ) { -# my($label, $value, $svcdb) = $cust_svc->label; -# my $svcnum = $cust_svc->svcnum; -# my $sview = $p. "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>"; -# } - -sub time_or_blank { - my $column = shift; - return sub { - my $record = shift; - my $value = $record->get($column); #mmm closures - $value ? time2str('%b %d %Y', $value ) : ''; - }; +sub bill_sort { + $a->getfield('bill') <=> $b->getfield('bill'); } -%><%= include( 'elements/search.html', - 'title' => 'Package Search Results', - 'name' => 'packages', - 'query' => $sql_query, - 'count_query' => $count_query, - 'redirect' => $link, - 'header' => [ '#', - 'Package', - 'Status', - 'Freq.', - 'Setup', - 'Last bill', - 'Next bill', - 'Susp.', - 'Expire', - 'Cancel', - FS::UI::Web::cust_header(), - 'Services', - ], - 'fields' => [ - 'pkgnum', - sub { my $part_pkg = $part_pkg{shift->pkgpart}; - $part_pkg->pkg; # ' - '. $part_pkg->comment; - }, - sub { ucfirst(shift->status); }, - sub { #shift->part_pkg->freq_pretty; - my $part_pkg = $part_pkg{shift->pkgpart}; - $part_pkg->freq_pretty; - }, - - #sub { time2str('%b %d %Y', shift->setup); }, - #sub { time2str('%b %d %Y', shift->last_bill); }, - #sub { time2str('%b %d %Y', shift->bill); }, - #sub { time2str('%b %d %Y', shift->susp); }, - #sub { time2str('%b %d %Y', shift->expire); }, - #sub { time2str('%b %d %Y', shift->get('cancel')); }, - ( map { time_or_blank($_) } - qw( setup last_bill bill susp expire cancel ) ), - - \&FS::UI::Web::cust_fields, - #sub { '<table border=0 cellspacing=0 cellpadding=0 STYLE="border:none">'. - # join('', map { '<tr><td align="right" style="border:none">'. $_->[0]. - # ':</td><td style="border:none">'. $_->[1]. '</td></tr>' } - # shift->labels - # ). - # '</table>'; - # }, - sub { - [ map { - [ - { 'data' => $_->[0]. ':', - 'align'=> 'right', - }, - { 'data' => $_->[1], - 'align'=> 'left', - 'link' => $p. 'view/' . - $_->[2]. '.cgi?'. $_->[3], - }, - ]; - } shift->labels - ]; - }, - ], - 'color' => [ - '', - '', - sub { shift->statuscolor; }, - '', - '', - '', - '', - '', - '', - '', - ( map { '' } FS::UI::Web::cust_header() ), - '', - ], - 'style' => [ '', '', 'b' ], - 'size' => [ '', '', '-1', ], - 'align' => 'rlclrrrrrr', - 'links' => [ - $link, - $link, - '', - '', - '', - '', - '', - '', - '', - '', - ( map { $clink } FS::UI::Web::cust_header() ), - '', - ], - ) %> diff --git a/httemplate/search/cust_pkg_report.cgi b/httemplate/search/cust_pkg_report.cgi index 412c3f7..b316745 100755 --- a/httemplate/search/cust_pkg_report.cgi +++ b/httemplate/search/cust_pkg_report.cgi @@ -1,18 +1,58 @@ <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="GET"> + <FORM ACTION="cust_pkg.cgi" METHOD="post"> <INPUT TYPE="hidden" NAME="magic" VALUE="bill"> Return packages with next bill date:<BR><BR> <TABLE> - <%= include( '/elements/tr-input-beginning_ending.html' ) %> - <%= include( '/elements/tr-select-agent.html', - $cgi->param('agentnum'), - ) - %> + <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"> diff --git a/httemplate/search/elements/search.html b/httemplate/search/elements/search.html index d19fb4a..566ea83 100644 --- a/httemplate/search/elements/search.html +++ b/httemplate/search/elements/search.html @@ -1,7 +1,6 @@ <% my(%opt) = @_; - #warn join(' / ', map { "$_ => $opt{$_}" } keys %opt ). "\n"; my %align = ( 'l' => 'left', @@ -13,39 +12,31 @@ $opt{align} = [ map $align{$_}, split(//, $opt{align}) ], unless !$opt{align} || ref($opt{align}); - my $type = ''; - my $limit = ''; - my($maxrecords, $total, $offset, $count_arrayref); - - if ( $cgi->param('_type') =~ /^(csv|\w*\.xls)$/ ) { - - $type = $1; - - } else { #setup some pagination things if we're in html mode + if ( ref($opt{'query'}) ) { - 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; - $maxrecords = $conf->config('maxsearchrecordsperpage'); + 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; + } - $limit = $maxrecords ? "LIMIT $maxrecords" : ''; + my $conf = new FS::Conf; + my $maxrecords = $conf->config('maxsearchrecordsperpage'); - $offset = $cgi->param('offset') || 0; - $limit .= " OFFSET $offset" if $offset; + my $limit = $maxrecords ? "LIMIT $maxrecords" : ''; - 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; - $count_arrayref = $count_sth->fetchrow_arrayref; - $total = $count_arrayref->[0]; + 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 $count_arrayref = $count_sth->fetchrow_arrayref; + my $total = $count_arrayref->[0]; - # run the query + #warn join(' / ', map { "$_ => $opt{$_}" } keys %opt ). "\n"; my $header = $opt{'header'}; my $rows; @@ -56,8 +47,6 @@ $opt{'query'}->{'hashref'} || {}, $opt{'query'}->{'select'}, $opt{'query'}->{'extra_sql'}. " $limit", - '', - (exists($opt{'query'}->{'addl_from'}) ? $opt{'query'}->{'addl_from'} : '') ) ]; } else { my $sth = dbh->prepare("$opt{'query'} $limit") @@ -71,322 +60,80 @@ $header ||= $sth->{NAME}; } - if ( $type eq 'csv' ) { - - #http_header('Content-Type' => 'text/comma-separated-values' ); #IE chokes - http_header('Content-Type' => 'text/plain' ); - - my $csv = new Text::CSV_XS { 'always_quote' => 1, - 'eol' => "\n", #"\015\012", #"\012" - }; - - $csv->combine(@$header); #or die $csv->status; - %><%= $csv->string %><% - - foreach my $row ( @$rows ) { - - if ( $opt{'fields'} ) { - - my @line = (); - - foreach my $field ( @{$opt{'fields'}} ) { - if ( ref($field) eq 'CODE' ) { - push @line, map { - ref($_) eq 'ARRAY' - ? '(N/A)' #unimplemented - : $_; - } - &{$field}($row); - } else { - push @line, $row->$field(); - } - } - - $csv->combine(@line); #or die $csv->status; - - } else { - $csv->combine(@$row); #or die $csv->status; - } - - %><%= $csv->string %><% - - } - - #} elsif ( $type eq 'excel' ) { - } elsif ( $type =~ /\.xls$/ ) { - - #http_header('Content-Type' => 'application/excel' ); #eww - http_header('Content-Type' => 'application/vnd.ms-excel' ); - #http_header('Content-Type' => 'application/msexcel' ); #alas - - my $data = ''; - my $XLS = new IO::Scalar \$data; - my $workbook = Spreadsheet::WriteExcel->new($XLS) - or die "Error opening .xls file: $!"; - - my $worksheet = $workbook->add_worksheet(substr($opt{'title'},0,31)); - - my($r,$c) = (0,0); - - $worksheet->write($r, $c++, $_) foreach @$header; - - foreach my $row ( @$rows ) { - $r++; - $c = 0; - - if ( $opt{'fields'} ) { - - #my $links = $opt{'links'} ? [ @{$opt{'links'}} ] : ''; - #my $aligns = $opt{'align'} ? [ @{$opt{'align'}} ] : ''; - - foreach my $field ( @{$opt{'fields'}} ) { - #my $align = $aligns ? shift @$aligns : ''; - #$align = " ALIGN=$align" if $align; - #my $a = ''; - #if ( $links ) { - # my $link = shift @$links; - # $link = &{$link}($row) if ref($link) eq 'CODE'; - # if ( $link ) { - # my( $url, $method ) = @{$link}; - # if ( ref($method) eq 'CODE' ) { - # $a = $url. &{$method}($row); - # } else { - # $a = $url. $row->$method(); - # } - # $a = qq(<A HREF="$a">); - # } - #} - if ( ref($field) eq 'CODE' ) { - foreach my $value ( &{$field}($row) ) { - if ( ref($value) eq 'ARRAY' ) { - $worksheet->write($r, $c++, '(N/A)' ); #unimplemented - } else { - $worksheet->write($r, $c++, $value ); - } - } - } else { - $worksheet->write($r, $c++, $row->$field() ); - } - } - - } else { - $worksheet->write($r, $c++, $_) foreach @$row; - } - - } - - $workbook->close();# or die "Error creating .xls file: $!"; - - http_header('Content-Length' => length($data) ); - %><%= $data %><% - - } else { # regular HTML - - if ( exists($opt{'redirect'}) && scalar(@$rows) == 1 && $total == 1 ) { - my $redirect = $opt{'redirect'}; - $redirect = &{$redirect}($rows->[0]) if ref($redirect) eq 'CODE'; - my( $url, $method ) = @$redirect; - redirect( $url. $rows->[0]->$method() ); - } else { - ( my $xlsname = $opt{'name'} ) =~ s/\W//g; - $opt{'name'} =~ s/s$// if $total == 1; - - my @menubar = (); - if ( $opt{'menubar'} ) { - @menubar = @{ $opt{'menubar'} }; - } else { - @menubar = ( 'Main menu' => $p ); - } - %> - <%= include( '/elements/header.html', $opt{'title'}, - include( '/elements/menubar.html', @menubar ) - ) - %> - <%= defined($opt{'html_init'}) ? $opt{'html_init'} : '' %> - <% my $pager = include ( '/elements/pager.html', - 'offset' => $offset, - 'num_rows' => scalar(@$rows), - 'total' => $total, - 'maxrecords' => $maxrecords, - ); - %> - <% unless ( $total ) { %> - No matching <%= $opt{'name'} %> found.<BR> - <% } else { %> - - <TABLE> - <TR> - <TD VALIGN="bottom"> - <%= $total %> total <%= $opt{'name'} %><BR> - <% if ( $opt{'count_addl'} ) { %> - <% my $n=0; foreach my $count ( @{$opt{'count_addl'}} ) { %> - <%= sprintf( $count, $count_arrayref->[++$n] ) %><BR> - <% } %> - <% } %> - </TD> - <TD ALIGN="right"> - <% $cgi->param('_type', "$xlsname.xls" ); %> - Download full results<BR> - as <A HREF="<%= $cgi->self_url %>">Excel spreadsheet</A><BR> - <% $cgi->param('_type', 'csv'); %> - as <A HREF="<%= $cgi->self_url %>">CSV file</A> - </TD> - </TR> - <TR> - <TD COLSPAN=2> - <%= $pager %> - - <%= include('/elements/table-grid.html') %> - - <TR> - <% foreach my $header ( @$header ) { %> - <TH CLASS="grid" BGCOLOR="#cccccc"><%= $header %></TH> - <% } %> - </TR> - <% my $bgcolor1 = '#eeeeee'; - my $bgcolor2 = '#ffffff'; - my $bgcolor; - foreach my $row ( @$rows ) { - if ( $bgcolor eq $bgcolor1 ) { - $bgcolor = $bgcolor2; - } else { - $bgcolor = $bgcolor1; - } - %> - <TR> - <% if ( $opt{'fields'} ) { - - my $links = $opt{'links'} ? [ @{$opt{'links'}} ] : ''; - my $aligns = $opt{'align'} ? [ @{$opt{'align'}} ] : ''; - my $colors = $opt{'color'} ? [ @{$opt{'color'}} ] : []; - my $sizes = $opt{'size'} ? [ @{$opt{'size'}} ] : []; - my $styles = $opt{'style'} ? [ @{$opt{'style'}} ] : []; - - foreach my $field ( - - map { - if ( ref($_) eq 'ARRAY' ) { - - my $tableref = $_; - - '<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0'. - ' STYLE="border:none">'. - - join('', map { - - my $rowref = $_; - - '<tr>'. - - join('', map { - - my $element = $_; - - '<TD STYLE="border:none"'. - ( $element->{'align'} - ? ' ALIGN="'. $element->{'align'}. '"' - : '' - ). '>'. - ( $element->{'link'} - ? '<A HREF="'. $element->{'link'}.'">' - : '' - ). - $element->{'data'}. - ( $element->{'link'} - ? '</A>' - : '' - ). - '</td>'; - - } @$rowref ). - - '</tr>'; - } @$tableref ). - - '</table>'; - - } else { - $_; - } - } - - map { - if ( ref($_) eq 'CODE' ) { - &{$_}($row); - } else { - $row->$_(); - } - } - @{$opt{'fields'}} - - ) { - - my $align = $aligns ? shift @$aligns : ''; - $align = " ALIGN=$align" if $align; - - my $a = ''; - if ( $links ) { - my $link = shift @$links; - $link = &{$link}($row) if ref($link) eq 'CODE'; - if ( $link ) { - my( $url, $method ) = @{$link}; - if ( ref($method) eq 'CODE' ) { - $a = $url. &{$method}($row); - } else { - $a = $url. $row->$method(); - } - $a = qq(<A HREF="$a">); - } - } - - my $font = ''; - my $color = shift @$colors; - $color = &{$color}($row) if ref($color) eq 'CODE'; - my $size = shift @$sizes; - $size = &{$size}($row) if ref($size) eq 'CODE'; - if ( $color || $size ) { - $font = '<FONT '. - ( $color ? "COLOR=#$color " : '' ). - ( $size ? qq(SIZE="$size" ) : '' ). - '>'; - } - - my($s, $es) = ( '', '' ); - my $style = shift @$styles; - $style = &{$style}($row) if ref($style) eq 'CODE'; - if ( $style ) { - $s = join( '', map "<$_>", split('', $style) ); - $es = join( '', map "</$_>", split('', $style) ); - } - - %> - <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"<%= $align %>><%= $font %><%= $a %><%= $s %><%= $field %><%= $es %><%= $a ? '</A>' : '' %><%= $font ? '</FONT>' : '' %></TD> - <% } %> - <% } else { %> - <% foreach ( @$row ) { %> - <TD CLASS="grid" BGCOLOR="$bgcolor"><%= $_ %></TD> - <% } %> - <% } %> - </TR> - <% } %> - - <% if ( $opt{'footer'} ) { %> - <TR> - <% foreach my $footer ( @{ $opt{'footer'} } ) { %> - <TD CLASS="grid" BGCOLOR="#dddddd" STYLE="border-top: dashed 1px black;"><i><%= $footer %></i></TH> - <% } %> - </TR> - <% } %> - - </TABLE> - <%= $pager %> - - </TD> - </TR> - </TABLE> - - <% } %> - </BODY> - </HTML> + if ( exists($opt{'redirect'}) && scalar(@$rows) == 1 && $total == 1 ) { + my( $url, $method ) = @{$opt{'redirect'}}; + redirect( $url. $rows->[0]->$method() ); + } else { + $opt{'name'} =~ s/s$// if $total == 1; +%> +<%= include( '/elements/header.html', $opt{'title'}, + include( '/elements/menubar.html', 'Main menu' => $p ) + ) +%> +<% my $pager = include ( '/elements/pager.html', + 'offset' => $offset, + 'num_rows' => scalar(@$rows), + 'total' => $total, + 'maxrecords' => $maxrecords, + ); +%> +<% unless ( $total ) { %> + No matching <%= $opt{'name'} %> found.<BR> +<% } else { %> + <%= $total %> total <%= $opt{'name'} %><BR> + <% if ( $opt{'count_addl'} ) { %> + <% my $n=0; foreach my $count ( @{$opt{'count_addl'}} ) { %> + <%= sprintf( $count, $count_arrayref->[++$n] ) %><BR> + <% } %> <% } %> + <BR><%= $pager %> + <%= include( '/elements/table.html' ) %> + <TR> + <% foreach my $header ( @$header ) { %> + <TH><%= $header %></TH> + <% } %> + </TR> + <% foreach my $row ( @$rows ) { %> + <TR> + <% if ( $opt{'fields'} ) { + my $links = $opt{'links'} ? [ @{$opt{'links'}} ] : ''; + my $aligns = $opt{'align'} ? [ @{$opt{'align'}} ] : ''; + foreach my $field ( @{$opt{'fields'}} ) { + my $align = $aligns ? shift @$aligns : ''; + $align = " ALIGN=$align" if $align; + my $a = ''; + if ( $links ) { + my $link = shift @$links; + $link = &{$link}($row) if ref($link) eq 'CODE'; + if ( $link ) { + my( $url, $method ) = @{$link}; + if ( ref($method) eq 'CODE' ) { + $a = $url. &{$method}($row); + } else { + $a = $url. $row->$method(); + } + $a = qq(<A HREF="$a">); + } + } + %> + <% if ( ref($field) eq 'CODE' ) { %> + <TD<%= $align %>><%= $a %><%= &{$field}($row) %><%= $a ? '</A>' : '' %></TD> + <% } else { %> + <TD<%= $align %>><%= $a %><%= $row->$field() %><%= $a ? '</A>' : '' %></TD> + <% } %> + <% } %> + <% } else { %> + <% foreach ( @$row ) { %> + <TD><%= $_ %></TD> + <% } %> + <% } %> + </TR> + <% } %> + + </TABLE> + <%= $pager %> <% } %> +</BODY> +</HTML> +<% } %> + diff --git a/httemplate/search/prepay_credit.html b/httemplate/search/prepay_credit.html deleted file mode 100644 index 8c8f57b..0000000 --- a/httemplate/search/prepay_credit.html +++ /dev/null @@ -1,43 +0,0 @@ -<% -my $agent = ''; -my $hashref = {}; -if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) { - $hashref->{agentnum} = $1; - $agent = qsearchs('agent', { 'agentnum' => $1 } ); -} - -my $count_query = 'SELECT COUNT(*) FROM prepay_credit'; -$count_query .= ' WHERE agentnum = '. $agent->agentnum if $agent; - -%><%= include( 'elements/search.html', - 'title' => 'Unused Prepaid Cards'. - ($agent ? ' for '. $agent->agent : ''), - 'menubar' => [ - 'Main menu' => $p, - 'Generate cards' => $p.'edit/prepay_credit.cgi', - ], - 'name' => 'prepaid cards', - 'query' => { 'table' => 'prepay_credit', - 'hashref' => $hashref, - }, - 'count_query' => $count_query, - #'redirect' => $link, - 'header' => [ '#', qw(Amount Time Agent) ], - 'fields' => [ - 'identifier', - sub { sprintf('$%.2f', shift->amount ) }, - sub { my $c = shift; $c ? duration_exact($c->seconds) : '' }, - sub { my $agent = shift->agent; - $agent ? $agent->agent : ''; - }, - ], - 'links' => [ - '', - '', - '', - sub { my $agent = shift->agent; - $agent ? [ "${p}view/agent.cgi?", 'agentnum' ] : ''; - }, - ], - ) -%> diff --git a/httemplate/search/reg_code.html b/httemplate/search/reg_code.html deleted file mode 100644 index 52a99ff..0000000 --- a/httemplate/search/reg_code.html +++ /dev/null @@ -1,36 +0,0 @@ -<% - -my $agentnum = $cgi->param('agentnum'); -$agentnum =~ /^(\d+)$/ or eidiot "illegal agentnum $agentnum"; -$agentnum = $1; -my $agent = qsearchs('agent', { 'agentnum' => $agentnum } ); - -my $count_query = "SELECT COUNT(*) FROM reg_code WHERE agentnum = $agentnum"; - -%><%= include( 'elements/search.html', - 'title' => 'Unused Registration Codes for '. - $agent->agent, - 'name' => 'registration codes', - 'query' => { 'table' => 'reg_code', - 'hashref' => { 'agentnum' => $agentnum, }, - }, - 'count_query' => $count_query, - #'redirect' => $link, - 'header' => [ qw(Code Packages) ], - 'fields' => [ - 'code', - sub { - map { - qq!<A HREF="${p}edit/part_pkg.cgi?!. $_->pkgpart. '">'. - $_->pkg. ' - '. $_->comment. - '</A><BR>' - } $_[0]->part_pkg - }, - ], - 'links' => [ - '', - #$plink, - '', - ], - ) -%> diff --git a/httemplate/search/report_cust_bill.html b/httemplate/search/report_cust_bill.html deleted file mode 100644 index a7be766..0000000 --- a/httemplate/search/report_cust_bill.html +++ /dev/null @@ -1,28 +0,0 @@ - <HEAD> - <TITLE>Invoice report criteria</TITLE> - </HEAD> - <BODY BGCOLOR="#e8e8e8"> - <H1>Invoice report criteria</H1> - <FORM ACTION="cust_bill.html" METHOD="GET"> - <INPUT TYPE="hidden" NAME="magic" VALUE="_date"> - <TABLE> - <%= include( '/elements/tr-select-agent.html', - $cgi->param('agentnum'), - 'label' => 'Invoices for agent: ', - ) - %> - <%= include( '/elements/tr-input-beginning_ending.html' ) %> - <TR> - <TD ALIGN="right"><INPUT TYPE="checkbox" NAME="open" VALUE="1" CHECKED></TD> - <TD>Show only open invoices</TD> - </TR> - <TR> - <TD ALIGN="right"><INPUT TYPE="checkbox" NAME="newest_percust" VALUE="1"></TD> - <TD>Show only the single most recent invoice per-customer</TD> - </TR> - </TABLE> - <BR><INPUT TYPE="submit" VALUE="Get Report"> - </FORM> - </BODY> -</HTML> - diff --git a/httemplate/search/report_cust_credit.html b/httemplate/search/report_cust_credit.html index 56bbd0a..ceffca7 100644 --- a/httemplate/search/report_cust_credit.html +++ b/httemplate/search/report_cust_credit.html @@ -1,10 +1,14 @@ <HTML> <HEAD> <TITLE>Credit 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 BGCOLOR="#e8e8e8"> <H1>Credit report criteria</H1> - <FORM ACTION="cust_credit.html" METHOD="GET"> + <FORM ACTION="cust_credit.html" METHOD="post"> <INPUT TYPE="hidden" NAME="magic" VALUE="_date"> <TABLE> <TR> @@ -23,12 +27,30 @@ </SELECT> </TD> </TR> - <%= include( '/elements/tr-select-agent.html', - $cgi->param('agentnum'), - 'label' => 'for agent: ', - ) - %> - <%= include( '/elements/tr-input-beginning_ending.html' ) %> + <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> </TABLE> <BR><INPUT TYPE="submit" VALUE="Get Report"> </FORM> diff --git a/httemplate/search/report_cust_pay.html b/httemplate/search/report_cust_pay.html index 5d8b74e..95198c7 100644 --- a/httemplate/search/report_cust_pay.html +++ b/httemplate/search/report_cust_pay.html @@ -1,10 +1,14 @@ <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 BGCOLOR="#e8e8e8"> <H1>Payment report criteria</H1> - <FORM ACTION="cust_pay.cgi" METHOD="GET"> + <FORM ACTION="cust_pay.cgi" METHOD="post"> <INPUT TYPE="hidden" NAME="magic" VALUE="_date"> <TABLE> <TR> @@ -15,22 +19,35 @@ <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="CARD-Maestro">credit card (Maestro/Switch/Solo)</OPTION> <OPTION VALUE="CHEK">electronic check / ACH</OPTION> - <OPTION VALUE="BILL">check</OPTION> - <OPTION VALUE="PREP">prepaid card</OPTION> - <OPTION VALUE="CASH">cash</OPTION> - <OPTION VALUE="WEST">Western Union</OPTION> - <OPTION VALUE="MCRD">manual credit card</OPTION> + <OPTION VALUE="BILL">check / cash</OPTION> </SELECT> </TD> </TR> - <%= include( '/elements/tr-select-agent.html', - $cgi->param('agentnum'), - 'label' => 'for agent: ', - ) - %> - <%= include( '/elements/tr-input-beginning_ending.html' ) %> + <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> </TABLE> <BR><INPUT TYPE="submit" VALUE="Get Report"> </FORM> diff --git a/httemplate/search/report_prepaid_income.html b/httemplate/search/report_prepaid_income.html index 57c318e..e8b6ac4 100644 --- a/httemplate/search/report_prepaid_income.html +++ b/httemplate/search/report_prepaid_income.html @@ -8,7 +8,7 @@ </HEAD> <BODY BGCOLOR="#e8e8e8"> <H1>Prepaid Income (Unearned Revenue) Report</H1> - <FORM ACTION="report_prepaid_income.cgi" METHOD="GET"> + <FORM ACTION="report_prepaid_income.cgi" METHOD="post"> <TABLE> <TR> <TD>Prepaid income (unearned revenue) as of </TD> diff --git a/httemplate/search/report_receivables.cgi b/httemplate/search/report_receivables.cgi index d675346..0e95ad7 100755 --- a/httemplate/search/report_receivables.cgi +++ b/httemplate/search/report_receivables.cgi @@ -1,3 +1,4 @@ +<!-- mason kludge --> <% my $charged = <<END; @@ -49,7 +50,7 @@ END and cust_main.custnum = cust_bill.custnum ) ,0 - ) as owed_90_pl, + ) as owed_90_plus, coalesce( ( select $charged from cust_bill @@ -60,8 +61,8 @@ END END my $recurring = <<END; - '0' != ( select freq from part_pkg - where cust_pkg.pkgpart = part_pkg.pkgpart ) + 0 < ( select freq from part_pkg + where cust_pkg.pkgpart = part_pkg.pkgpart ) END my $packages_cols = <<END; @@ -81,7 +82,9 @@ END END - my $where = <<END; + my $sql = <<END; + +select *, $owed_cols, $packages_cols from cust_main where 0 < coalesce( ( select $charged from cust_bill @@ -89,144 +92,67 @@ where 0 < ) ,0 ) + +order by coalesce(lower(company), ''), lower(last) + END - my $agentnum = ''; - if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) { - $agentnum = $1; - $where .= " AND agentnum = '$agentnum' "; - } - - my $count_sql = "select count(*) from cust_main $where"; - - my $sql_query = { - 'table' => 'cust_main', - 'hashref' => {}, - 'select' => "*, $owed_cols, $packages_cols", - 'extra_sql' => "$where order by coalesce(lower(company), ''), lower(last)", - }; - - if ( $agentnum ) { - $owed_cols =~ - s/cust_bill\.custnum/cust_bill.custnum AND cust_main.agentnum = '$agentnum'/g; - } 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; - my $row = $total_sth->fetchrow_hashref(); - - my $conf = new FS::Conf; - my $money_char = $conf->config('money_char') || '$'; - - my $align = join('', map { /#/ ? 'r' : 'l' } FS::UI::Web::cust_header() ). - 'crrrrr'; - - my $clink = [ "${p}view/cust_main.cgi?", 'custnum' ]; - -%><%= include( 'elements/search.html', - 'title' => 'Accounts Receivable Aging Summary', - 'name' => 'customers', - 'query' => $sql_query, - 'count_query' => $count_sql, - 'header' => [ - FS::UI::Web::cust_header(), - 'Status', # (me)', - #'Status', # (cust_main)', - '0-30', - '30-60', - '60-90', - '90+', - 'Total', - ], - 'footer' => [ - 'Total', - ( map '', - ( 1 .. - scalar(FS::UI::Web::cust_header()-1) - ) - ), - '', - #'', - sprintf( $money_char.'%.2f', - $row->{'owed_0_30'} ), - sprintf( $money_char.'%.2f', - $row->{'owed_30_60'} ), - sprintf( $money_char.'%.2f', - $row->{'owed_60_90'} ), - sprintf( $money_char.'%.2f', - $row->{'owed_90_pl'} ), - sprintf( '<b>'. $money_char.'%.2f'. '</b>', - $row->{'owed_total'} ), - ], - 'fields' => [ - \&FS::UI::Web::cust_fields, - sub { - my $row = shift; - my $status = 'Cancelled'; - my $statuscol = 'FF0000'; - if ( $row->uncancelled_pkgs ) { - $status = 'Suspended'; - $statuscol = 'FF9900'; - if ( $row->active_pkgs ) { - $status = 'Active'; - $statuscol = '00CC00'; - } - } - $status; - }, - #sub { ucfirst(shift->status) }, - sub { sprintf( $money_char.'%.2f', - shift->get('owed_0_30') ) }, - sub { sprintf( $money_char.'%.2f', - shift->get('owed_30_60') ) }, - sub { sprintf( $money_char.'%.2f', - shift->get('owed_60_90') ) }, - sub { sprintf( $money_char.'%.2f', - shift->get('owed_90_pl') ) }, - sub { sprintf( $money_char.'%.2f', - shift->get('owed_total') ) }, - ], - 'links' => [ - ( map $clink, FS::UI::Web::cust_header() ), - '', - #'', - '', - '', - '', - '', - '', - ], - #'align' => 'rlccrrrrr', - 'align' => $align, - #'size' => [ '', '', '-1', '-1', '', '', '', '', '', ], - #'style' => [ '', '', 'b', 'b', '', '', '', '', 'b', ], - 'size' => [ ( map '', FS::UI::Web::cust_header() ), - '-1', '', '', '', '', '', ], - 'style' => [ ( map '', FS::UI::Web::cust_header() ), - 'b', '', '', '', '', 'b', ], - 'color' => [ - ( map '', FS::UI::Web::cust_header() ), - sub { - my $row = shift; - my $status = 'Cancelled'; - my $statuscol = 'FF0000'; - if ( $row->uncancelled_pkgs ) { - $status = 'Suspended'; - $statuscol = 'FF9900'; - if ( $row->active_pkgs ) { - $status = 'Active'; - $statuscol = '00CC00'; - } - } - $statuscol; - }, - #sub { shift->statuscolor; }, - '', - '', - '', - '', - '', - ], - - ) + +%> +<%= 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.cgi b/httemplate/search/report_tax.cgi index 9062f06..5876657 100755 --- a/httemplate/search/report_tax.cgi +++ b/httemplate/search/report_tax.cgi @@ -1,11 +1,15 @@ +<!-- mason kludge --> <% -my $conf = new FS::Conf; -my $money_char = $conf->config('money_char') || '$'; - my $user = getotaker; -my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi); +$cgi->param('beginning') =~ /^([ 0-9\-\/]{0,10})$/; +my $pbeginning = $1; +my $beginning = $1 ? str2time($1) : 0; + +$cgi->param('ending') =~ /^([ 0-9\-\/]{0,10})$/; +my $pending = $1; +my $ending = ( $1 ? str2time($1) : 4294880896 ) + 86399; my $from_join_cust = " FROM cust_bill_pkg @@ -20,19 +24,11 @@ my $where = " WHERE _date >= $beginning AND _date <= $ending AND ( county = ? OR ? = '' ) AND ( state = ? OR ? = '' ) - AND country = ? + AND ( country = ? ) AND payby != 'COMP' "; my @base_param = qw( county county state state country ); -my $agentname = ''; -if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) { - my $agent = qsearchs('agent', { 'agentnum' => $1 } ); - die "agent not found" unless $agent; - $agentname = $agent->agent; - $where .= ' AND agentnum = '. $agent->agentnum; -} - my $gotcust = " WHERE 0 < ( SELECT COUNT(*) FROM cust_main WHERE ( cust_main.county = cust_main_county.county @@ -47,72 +43,52 @@ my $gotcust = " "; my $monthly_exempt_warning = 0; -my $taxclass_flag = 0; -my($total, $tot_taxable, $owed, $tax) = ( 0, 0, 0, 0, 0 ); -my( $exempt_cust, $exempt_pkg, $exempt_monthly ) = ( 0, 0 ); +my($total, $exempt, $taxable, $owed, $tax) = ( 0, 0, 0, 0, 0 ); my $out = 'Out of taxable region(s)'; -my %regions = (); +my %regions; foreach my $r (qsearch('cust_main_county', {}, '', $gotcust) ) { #warn $r->county. ' '. $r->state. ' '. $r->country. "\n"; my $label = getlabel($r); $regions{$label}->{'label'} = $label; - $regions{$label}->{'url_param'} = join(';', map "$_=".$r->$_(), qw( county state country ) ); my $fromwhere = $from_join_cust. $join_pkg. $where; - my @param = @base_param; + my @param = @base_param; if ( $r->taxclass ) { - $fromwhere .= " AND taxclass = ? "; + $fromwhere .= " AND ( taxclass = ? ) "; push @param, 'taxclass'; - $regions{$label}->{'url_param'} .= ';taxclass='. $r->taxclass - if $cgi->param('show_taxclasses'); - $taxclass_flag = 1; } -# my $label = getlabel($r); -# $regions{$label}->{'label'} = $label; - my $nottax = 'pkgnum != 0'; - ## calculate total for this region - - my $t = scalar_sql($r, \@param, + my $a = scalar_sql($r, \@param, "SELECT SUM(cust_bill_pkg.setup+cust_bill_pkg.recur) $fromwhere AND $nottax" ); - $total += $t; - $regions{$label}->{'total'} += $t; - - ## calculate package-exemption for this region + $total += $a; + $regions{$label}->{'total'} += $a; foreach my $e ( grep { $r->get($_.'tax') =~ /^Y/i } qw( cust_bill_pkg.setup cust_bill_pkg.recur ) ) { my $x = scalar_sql($r, \@param, "SELECT SUM($e) $fromwhere AND $nottax" ); - $exempt_pkg += $x; - $regions{$label}->{'exempt_pkg'} += $x; + $exempt += $x; + $regions{$label}->{'exempt'} += $x; } - ## calculate customer-exemption for this region - - my($taxable, $x_cust) = (0, 0); + my($t, $x) = (0, 0); foreach my $e ( grep { $r->get($_.'tax') !~ /^Y/i } qw( cust_bill_pkg.setup cust_bill_pkg.recur ) ) { - $taxable += scalar_sql($r, \@param, + $t += scalar_sql($r, \@param, "SELECT SUM($e) $fromwhere AND $nottax AND ( tax != 'Y' OR tax IS NULL )" ); - $x_cust += scalar_sql($r, \@param, + $x += scalar_sql($r, \@param, "SELECT SUM($e) $fromwhere AND $nottax AND tax = 'Y'" ); } - $exempt_cust += $x_cust; - $regions{$label}->{'exempt_cust'} += $x_cust; - - ## calculate monthly exemption (texas tax) for this region - my($sday,$smon,$syear) = (localtime($beginning) )[ 3, 4, 5 ]; $monthly_exempt_warning=1 if $sday != 1 && $beginning; $smon++; $syear+=1900; @@ -121,24 +97,25 @@ foreach my $r (qsearch('cust_main_county', {}, '', $gotcust) ) { my($eday,$emon,$eyear) = (localtime($eending) )[ 3, 4, 5 ]; $emon++; $eyear+=1900; - my $x_monthly = scalar_sql($r, [ 'taxnum' ], + my $monthly_exemption = scalar_sql($r, [ 'taxnum' ], "SELECT SUM(amount) FROM cust_tax_exempt where taxnum = ? ". " AND ( year > $syear OR ( year = $syear and month >= $smon ) )". " AND ( year < $eyear OR ( year = $eyear and month <= $emon ) )" ); - if ( $x_monthly ) { - warn $r->taxnum(). ": $x_monthly\n"; - $taxable -= $x_monthly; + #warn $r->taxnum(). ": $monthly_exemption\n"; + if ( $monthly_exemption ) { + $t -= $monthly_exemption; + $x += $monthly_exemption; } - $exempt_monthly += $x_monthly; - $regions{$label}->{'exempt_monthly'} += $x_monthly; + $taxable += $t; + $regions{$label}->{'taxable'} += $t; - $tot_taxable += $taxable; - $regions{$label}->{'taxable'} += $taxable; + $exempt += $x; + $regions{$label}->{'exempt'} += $x; - $owed += $taxable * ($r->tax/100); - $regions{$label}->{'owed'} += $taxable * ($r->tax/100); + $owed += $t * ($r->tax/100); + $regions{$label}->{'owed'} += $t * ($r->tax/100); if ( defined($regions{$label}->{'rate'}) && $regions{$label}->{'rate'} != $r->tax.'%' ) { @@ -151,7 +128,7 @@ foreach my $r (qsearch('cust_main_county', {}, '', $gotcust) ) { my $taxwhere = "$from_join_cust $where"; my @taxparam = @base_param; -my %base_regions = (); + #foreach my $label ( keys %regions ) { foreach my $r ( qsearch( 'cust_main_county', @@ -180,58 +157,30 @@ foreach my $r ( $tax += $x; $regions{$label}->{'tax'} += $x; - if ( $cgi->param('show_taxclasses') ) { - my $base_label = getlabel($r, 'no_taxclass'=>1 ); - $base_regions{$base_label}->{'label'} = $base_label; - $base_regions{$base_label}->{'url_param'} = - join(';', map "$_=".$r->$_(), qw( county state country ) ); - $base_regions{$base_label}->{'tax'} += $x; - } - } #ordering -my @regions = - map $regions{$_}, - sort { ( ($a eq $out) cmp ($b eq $out) ) || ($b cmp $a) } - keys %regions; - -my @base_regions = - map $base_regions{$_}, - sort { ( ($a eq $out) cmp ($b eq $out) ) || ($b cmp $a) } - keys %base_regions; +my @regions = map $regions{$_}, + sort { ( ($a eq $out) cmp ($b eq $out) ) || ($b cmp $a) } + keys %regions; push @regions, { - 'label' => 'Total', - 'url_param' => '', - 'total' => $total, - 'exempt_cust' => $exempt_cust, - 'exempt_pkg' => $exempt_pkg, - 'exempt_monthly' => $exempt_monthly, - 'taxable' => $tot_taxable, - 'rate' => '', - 'owed' => $owed, - 'tax' => $tax, + 'label' => 'Total', + 'total' => $total, + 'exempt' => $exempt, + 'taxable' => $taxable, + 'rate' => '', + 'owed' => $owed, + 'tax' => $tax, }; #-- sub getlabel { my $r = shift; - my %opt = @_; my $label; - if ( - $r->tax == 0 - && ! scalar( qsearch('cust_main_county', { 'state' => $r->state, - 'county' => $r->county, - 'country' => $r->country, - 'tax' => { op=>'>', value=>0 }, - } - ) - ) - - ) { + if ( $r->tax == 0 ) { #kludge to avoid "will not stay shared" warning my $out = 'Out of taxable region(s)'; $label = $out; @@ -243,10 +192,6 @@ sub getlabel { $label = $r->country; $label = $r->state.", $label" if $r->state; $label = $r->county." county, $label" if $r->county; - $label = "$label (". $r->taxclass. ")" - if $r->taxclass - && $cgi->param('show_taxclasses') - && ! $opt{'no_taxclasses'}; #$label = $r->taxname. " ($label)" if $r->taxname; } return $label; @@ -265,159 +210,35 @@ sub scalar_sql { %> -<% - -my $baselink = $p. "search/cust_bill_pkg.cgi?begin=$beginning;end=$ending"; - -%> - - -<%= header( "$agentname Sales Tax Report - ". - time2str('%h %o %Y through ', $beginning ). - ( $ending == 4294967295 - ? 'now' - : time2str('%h %o %Y', $ending ) - ), - menubar( 'Main Menu'=>$p, ) - ) -%> - -<%= include('/elements/table-grid.html') %> - +<%= header( "Sales Tax Report - $pbeginning through ".($pending||'now'), + menubar( 'Main Menu'=>$p, ) ) %> +<%= table() %> <TR> - <TH CLASS="grid" BGCOLOR="#cccccc" ROWSPAN=2></TH> - <TH CLASS="grid" BGCOLOR="#cccccc" COLSPAN=9>Sales</TH> - <TH CLASS="grid" BGCOLOR="#cccccc" ROWSPAN=2></TH> - <TH CLASS="grid" BGCOLOR="#cccccc" ROWSPAN=2>Rate</TH> - <TH CLASS="grid" BGCOLOR="#cccccc" ROWSPAN=2></TH> - <TH CLASS="grid" BGCOLOR="#cccccc" ROWSPAN=2>Tax owed</TH> - <% unless ( $cgi->param('show_taxclasses') ) { %> - <TH CLASS="grid" BGCOLOR="#cccccc" ROWSPAN=2>Tax invoiced</TH> - <% } %> + <TH ROWSPAN=2></TH> + <TH COLSPAN=3>Sales</TH> + <TH ROWSPAN=2>Rate</TH> + <TH ROWSPAN=2>Tax owed</TH> + <TH ROWSPAN=2>Tax invoiced</TH> </TR> <TR> - <TH CLASS="grid" BGCOLOR="#cccccc">Total</TH> - <TH CLASS="grid" BGCOLOR="#cccccc"></TH> - <TH CLASS="grid" BGCOLOR="#cccccc">Non-taxable<BR><FONT SIZE=-1>(tax-exempt customer)</FONT></TH> - <TH CLASS="grid" BGCOLOR="#cccccc"></TH> - <TH CLASS="grid" BGCOLOR="#cccccc">Non-taxable<BR><FONT SIZE=-1>(tax-exempt package)</FONT></TH> - <TH CLASS="grid" BGCOLOR="#cccccc"></TH> - <TH CLASS="grid" BGCOLOR="#cccccc">Non-taxable<BR><FONT SIZE=-1>(monthly exemption)</FONT></TH> - <TH CLASS="grid" BGCOLOR="#cccccc"></TH> - <TH CLASS="grid" BGCOLOR="#cccccc">Taxable</TH> + <TH>Total</TH> + <TH>Non-taxable</TH> + <TH>Taxable</TH> </TR> - -<% my $bgcolor1 = '#eeeeee'; - my $bgcolor2 = '#ffffff'; - my $bgcolor; -%> - - <% foreach my $region ( @regions ) { - - if ( $bgcolor eq $bgcolor1 ) { - $bgcolor = $bgcolor2; - } else { - $bgcolor = $bgcolor1; - } - - my $link = $baselink; - if ( $region->{'label'} ne 'Total' ) { - if ( $region->{'label'} eq $out ) { - $link .= ';out=1'; - } else { - $link .= ';'. $region->{'url_param'}; - } - } - %> - + <% foreach my $region ( @regions ) { %> <TR> - <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><%= $region->{'label'} %></TD> - <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>" ALIGN="right"> - <A HREF="<%= $link %>;nottax=1"><%= $money_char %><%= sprintf('%.2f', $region->{'total'} ) %></A> - </TD> - <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><FONT SIZE="+1"><B> - </B></FONT></TD> - <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>" ALIGN="right"> - <A HREF="<%= $link %>;nottax=1;cust_tax=Y"><%= $money_char %><%= sprintf('%.2f', $region->{'exempt_cust'} ) %></A> - </TD> - <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><FONT SIZE="+1"><B> - </B></FONT></TD> - <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>" ALIGN="right"> - <A HREF="<%= $link %>;nottax=1;pkg_tax=Y"><%= $money_char %><%= sprintf('%.2f', $region->{'exempt_pkg'} ) %></A> - </TD> - <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><FONT SIZE="+1"><B> - </B></FONT></TD> - <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>" ALIGN="right"> - <%= $money_char %><%= sprintf('%.2f', $region->{'exempt_monthly'} ) %></A> - </TD> - <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><FONT SIZE="+1"><B> = </B></FONT></TD> - <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>" ALIGN="right"> - <%= $money_char %><%= sprintf('%.2f', $region->{'taxable'} ) %></A> - </TD> - <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><%= $region->{'label'} eq 'Total' ? '' : '<FONT FACE="sans-serif" SIZE="+1"><B> X </B></FONT>' %></TD> - <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>" ALIGN="right"><%= $region->{'rate'} %></TD> - <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><%= $region->{'label'} eq 'Total' ? '' : '<FONT FACE="sans-serif" SIZE="+1"><B> = </B></FONT>' %></TD> - <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>" ALIGN="right"> - <%= $money_char %><%= sprintf('%.2f', $region->{'owed'} ) %> - </TD> - <% unless ( $cgi->param('show_taxclasses') ) { %> - <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>" ALIGN="right"> - <A HREF="<%= $link %>;istax=1"><%= $money_char %><%= sprintf('%.2f', $region->{'tax'} ) %></A> - </TD> - <% } %> + <TD><%= $region->{'label'} %></TD> + <TD ALIGN="right">$<%= sprintf('%.2f', $region->{'total'} ) %></TD> + <TD ALIGN="right">$<%= sprintf('%.2f', $region->{'exempt'} ) %></TD> + <TD ALIGN="right">$<%= sprintf('%.2f', $region->{'taxable'} ) %></TD> + <TD ALIGN="right"><%= $region->{'rate'} %></TD> + <TD ALIGN="right">$<%= sprintf('%.2f', $region->{'owed'} ) %></TD> + <TD ALIGN="right">$<%= sprintf('%.2f', $region->{'tax'} ) %></TD> </TR> - <% } %> </TABLE> - -<% if ( $cgi->param('show_taxclasses') ) { %> - - <BR> - <%= include('/elements/table-grid.html') %> - <TR> - <TH CLASS="grid" BGCOLOR="#cccccc"></TH> - <TH CLASS="grid" BGCOLOR="#cccccc">Tax invoiced</TH> - </TR> - - <% #some false laziness w/above - foreach my $region ( @base_regions ) { - - if ( $bgcolor eq $bgcolor1 ) { - $bgcolor = $bgcolor2; - } else { - $bgcolor = $bgcolor1; - } - - my $link = $baselink; - #if ( $region->{'label'} ne 'Total' ) { - if ( $region->{'label'} eq $out ) { - $link .= ';out=1'; - } else { - $link .= ';'. $region->{'url_param'}; - } - #} - %> - - <TR> - <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><%= $region->{'label'} %></TD> - <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>" ALIGN="right"> - <A HREF="<%= $link %>;istax=1"><%= $money_char %><%= sprintf('%.2f', $region->{'tax'} ) %></A> - </TD> - </TR> - - <% } %> - - <TR> - <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>">Total</TD> - <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>" ALIGN="right"> - <A HREF="<%= $baselink %>;istax=1"><%= $money_char %><%= sprintf('%.2f', $tax ) %></A> - </TD> - </TR> - - </TABLE> - -<% } %> - - <% if ( $monthly_exempt_warning ) { %> <BR> Partial-month tax reports (except for current month) may not be correct due diff --git a/httemplate/search/report_tax.html b/httemplate/search/report_tax.html index eeaccc1..d217e56 100755 --- a/httemplate/search/report_tax.html +++ b/httemplate/search/report_tax.html @@ -1,17 +1,39 @@ <HTML> <HEAD> <TITLE>Tax Report Criteria</TITLE> - </HEAD> + <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="GET"> + <FORM ACTION="report_tax.cgi" METHOD="post"> + Return <B>tax report</B> for period: <TABLE> - <%= include( '/elements/tr-select-agent.html' ) %> - <%= include( '/elements/tr-input-beginning_ending.html' ) %> - <TR> - <TD ALIGN="right"><INPUT TYPE="checkbox" NAME="show_taxclasses" VALUE="1"></TD> - <TD>Show tax classes</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> + <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"> diff --git a/httemplate/search/sqlradius.html b/httemplate/search/sqlradius.html index 8f4878d..20e8fb8 100644 --- a/httemplate/search/sqlradius.html +++ b/httemplate/search/sqlradius.html @@ -4,7 +4,7 @@ <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT> <SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT> ') %> -<FORM NAME="OneTrueForm" ACTION="sqlradius.cgi" METHOD="GET"> +<FORM NAME="OneTrueForm" ACTION="sqlradius.cgi" METHOD="POST"> <% #include( '/elements/table.html' ) %> <%= ntable('#cccccc') %> <TR> diff --git a/httemplate/search/svc_acct.cgi b/httemplate/search/svc_acct.cgi index b145919..1e4a03d 100755 --- a/httemplate/search/svc_acct.cgi +++ b/httemplate/search/svc_acct.cgi @@ -1,37 +1,250 @@ <% -my $orderby = 'ORDER BY svcnum'; +my $conf = new FS::Conf; +my $maxrecords = $conf->config('maxsearchrecordsperpage'); + +my $orderby = ''; #removeme + +my $limit = ''; +$limit .= "LIMIT $maxrecords" if $maxrecords; + +my $offset = $cgi->param('offset') || 0; +$limit .= " OFFSET $offset" if $offset; + +my $total; my($query)=$cgi->keywords; $query ||= ''; #to avoid use of unitialized value errors -my $cjoin = ''; -my @extra_sql = (); +my $unlinked = ''; if ( $query =~ /^UN_(.*)$/ ) { $query = $1; - $cjoin = 'LEFT JOIN cust_svc USING ( svcnum )'; - push @extra_sql, 'pkgnum IS NULL'; + my $empty = driver_name eq 'Pg' ? qq('') : qq(""); + if ( driver_name eq 'mysql' ) { + $unlinked = "LEFT JOIN cust_svc ON cust_svc.svcnum = svc_acct.svcnum + WHERE cust_svc.pkgnum IS NULL + OR cust_svc.pkgnum = 0 + OR cust_svc.pkgnum = $empty"; + } else { + $unlinked = " + WHERE 0 < + ( SELECT count(*) FROM cust_svc + WHERE cust_svc.svcnum = svc_acct.svcnum + AND ( pkgnum IS NULL OR pkgnum = 0 ) + ) + "; + } } +my $tblname = driver_name eq 'mysql' ? 'svc_acct.' : ''; +my(@svc_acct, $sortby); if ( $query eq 'svcnum' ) { - #$orderby = "ORDER BY svcnum"; + $sortby=\*svcnum_sort; + $orderby = "ORDER BY ${tblname}svcnum"; } elsif ( $query eq 'username' ) { - $orderby = "ORDER BY LOWER(username)"; + $sortby=\*username_sort; + $orderby = "ORDER BY ${tblname}username"; } elsif ( $query eq 'uid' ) { - $orderby = "ORDER BY uid"; - push @extra_sql, "uid IS NOT NULL"; + $sortby=\*uid_sort; + $orderby = ( $unlinked ? ' AND' : ' WHERE' ). + " ${tblname}uid IS NOT NULL ORDER BY ${tblname}uid"; } elsif ( $cgi->param('popnum') =~ /^(\d+)$/ ) { - push @extra_sql, "popnum = $1"; - $orderby = "ORDER BY LOWER(username)"; + $unlinked .= ( $unlinked ? 'AND' : 'WHERE' ). + " popnum = $1"; + $sortby=\*username_sort; + $orderby = "ORDER BY ${tblname}username"; } elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) { - $cjoin ||= 'LEFT JOIN cust_svc USING ( svcnum )'; - push @extra_sql, "svcpart = $1"; - $orderby = "ORDER BY uid"; - #$orderby = "ORDER BY svcnum"; + $unlinked .= ( $unlinked ? ' AND' : ' WHERE' ). + " $1 = ( SELECT svcpart FROM cust_svc ". + " WHERE cust_svc.svcnum = svc_acct.svcnum ) "; + $sortby=\*uid_sort; + #$sortby=\*svcnum_sort; } else { - $orderby = "ORDER BY uid"; + $sortby=\*uid_sort; + @svc_acct = @{&usernamesearch}; +} + + +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) + or die dbh->errstr. " doing $statement"; + $sth->execute or die "Error executing \"$statement\": ". $sth->errstr; + + $total = $sth->fetchrow_arrayref->[0]; + + @svc_acct = qsearch('svc_acct', {}, '', "$unlinked $orderby $limit"); + +} + +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 +%> +<!-- mason kludge --> +<% + idiot("Account not found"); +} else { +%> +<!-- mason kludge --> +<% + $total ||= scalar(@svc_acct); + + #begin pager + my $pager = ''; + if ( $total != scalar(@svc_acct) && $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("Account Search Results",menubar('Main Menu'=>popurl(2))), + "$total matching accounts found<BR><BR>$pager", + &table(), <<END; + <TR> + <TH><FONT SIZE=-1>#</FONT></TH> + <TH><FONT SIZE=-1>Username</FONT></TH> + <TH><FONT SIZE=-1>Domain</FONT></TH> + <TH><FONT SIZE=-1>UID</FONT></TH> + <TH><FONT SIZE=-1>Service</FONT></TH> + <TH><FONT SIZE=-1>Cust#</FONT></TH> + <TH><FONT SIZE=-1>(bill) name</FONT></TH> + <TH><FONT SIZE=-1>company</FONT></TH> +END + if ( defined dbdef->table('cust_main')->column('ship_last') ) { + print <<END; + <TH><FONT SIZE=-1>(service) name</FONT></TH> + <TH><FONT SIZE=-1>company</FONT></TH> +END + } + print "</TR>"; - my @username_sql; + 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 $domain; + my $svc_domain = qsearchs('svc_domain', { 'svcnum' => $svc_acct->domsvc }); + if ( $svc_domain ) { + $domain = "<A HREF=\"${p}view/svc_domain.cgi?". $svc_domain->svcnum. + "\">". $svc_domain->domain. "</A>"; + } else { + die "No svc_domain.svcnum record for svc_acct.domsvc: ". + $svc_acct->domsvc; + } + 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>" : ''; + my($pship_name, $pship_company); + if ( defined dbdef->table('cust_main')->column('ship_last') ) { + my($ship_last, $ship_first, $ship_company) = ( + $cust_svc->pkgnum ? ( $cust_main->ship_last || $last ) : '', + $cust_svc->pkgnum ? ( $cust_main->ship_last + ? $cust_main->ship_first + : $first + ) : '', + $cust_svc->pkgnum ? ( $cust_main->ship_last + ? $cust_main->ship_company + : $company + ) : '', + ); + $pship_name = $custnum ? "<A HREF=\"${p}view/cust_main.cgi?$custnum\">$ship_last, $ship_first</A>" : ''; + $pship_company = $custnum ? "<A HREF=\"${p}view/cust_main.cgi?$custnum\">$ship_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><FONT SIZE=-1>$domain</FONT></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> +END + if ( defined dbdef->table('cust_main')->column('ship_last') ) { + print <<END; + <TD><FONT SIZE=-1>$pship_name<FONT></TH> + <TD><FONT SIZE=-1>$pship_company</FONT></TH> +END + } + print "</TR>"; + + } + + print "</TABLE>$pager<BR>". + '</BODY></HTML>'; + +} + +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 { + + my @svc_acct; my %username_type; foreach ( $cgi->param('username_type') ) { @@ -41,13 +254,17 @@ if ( $query eq 'svcnum' ) { $cgi->param('username') =~ /^([\w\-\.\&]+)$/; #untaint username_text my $username = $1; - push @username_sql, "username ILIKE '$username'" - if $username_type{'Exact'} - || $username_type{'Fuzzy'}; + if ( $username_type{'Exact'} || $username_type{'Fuzzy'} ) { + push @svc_acct, qsearch( 'svc_acct', + { 'username' => { 'op' => 'ILIKE', + 'value' => $username } } ); + } - push @username_sql, "username ILIKE '\%$username\%'" - if $username_type{'Substring'} - || $username_type{'All'}; + if ( $username_type{'Substring'} || $username_type{'All'} ) { + push @svc_acct, qsearch( 'svc_acct', + { 'username' => { 'op' => 'ILIKE', + 'value' => "%$username%" } } ); + } if ( $username_type{'Fuzzy'} || $username_type{'All'} ) { &FS::svc_acct::check_and_rebuild_fuzzyfiles; @@ -63,78 +280,15 @@ if ( $query eq 'svcnum' ) { #if ($username_type{'Sound-alike'}) { #} - push @username_sql, "username = '$_'" - foreach (keys %username); + foreach ( keys %username ) { + push @svc_acct, qsearch('svc_acct',{'username'=>$_}); + } } - push @extra_sql, '( '. join( ' OR ', @username_sql). ' )'; + #[ qsearch('svc_acct',{'username'=>$username}) ]; + \@svc_acct; } -my $extra_sql = - scalar(@extra_sql) - ? ' WHERE '. join(' AND ', @extra_sql ) - : ''; - -my $count_query = "SELECT COUNT(*) FROM svc_acct $cjoin $extra_sql"; -#if ( keys %svc_acct ) { -# $count_query .= ' WHERE '. -# join(' AND ', map "$_ = ". dbh->quote($svc_acct{$_}), -# keys %svc_acct -# ); -#} - -my $sql_query = { - 'table' => 'svc_acct', - 'hashref' => {}, # \%svc_acct, - 'select' => join(', ', - 'svc_acct.*', - 'cust_main.custnum', - FS::UI::Web::cust_sql_fields(), - ), - 'extra_sql' => "$extra_sql $orderby", - 'addl_from' => ' LEFT JOIN cust_svc USING ( svcnum ) '. - ' LEFT JOIN part_svc USING ( svcpart ) '. - ' LEFT JOIN cust_pkg USING ( pkgnum ) '. - ' LEFT JOIN cust_main USING ( custnum ) ', -}; - -my $link = [ "${p}view/svc_acct.cgi?", 'svcnum' ]; -my $link_cust = sub { - my $svc_acct = shift; - if ( $svc_acct->custnum ) { - [ "${p}view/cust_main.cgi?", 'custnum' ]; - } else { - ''; - } -}; - -%><%= include( 'elements/search.html', - 'title' => 'Account Search Results', - 'name' => 'accounts', - 'query' => $sql_query, - 'count_query' => $count_query, - 'redirect' => $link, - 'header' => [ '#', - 'Account', - 'UID', - 'Service', - FS::UI::Web::cust_header(), - ], - 'fields' => [ 'svcnum', - 'email', - 'uid', - 'svc', - \&FS::UI::Web::cust_fields, - ], - 'links' => [ $link, - $link, - $link, - '', - ( map { $link_cust } - FS::UI::Web::cust_header() - ), - ], - ) %> diff --git a/httemplate/search/svc_acct.html b/httemplate/search/svc_acct.html index c504c2f..7423605 100755 --- a/httemplate/search/svc_acct.html +++ b/httemplate/search/svc_acct.html @@ -7,7 +7,7 @@ Account Search </FONT> <BR><BR> - <FORM ACTION="svc_acct.cgi" METHOD="GET"> + <FORM ACTION="svc_acct.cgi" METHOD="post"> Search for <B>username</B>: <INPUT TYPE="text" NAME="username"> diff --git a/httemplate/search/svc_domain.cgi b/httemplate/search/svc_domain.cgi index f261ea9..948b1d9 100755 --- a/httemplate/search/svc_domain.cgi +++ b/httemplate/search/svc_domain.cgi @@ -4,82 +4,158 @@ my $conf = new FS::Conf; my($query)=$cgi->keywords; $query ||= ''; #to avoid use of unitialized value errors - -my $orderby = 'ORDER BY svcnum'; -my $join = ''; -my %svc_domain = (); -my $extra_sql = ''; +my(@svc_domain,$sortby); if ( $query eq 'svcnum' ) { - #$orderby = 'ORDER BY svcnum'; + $sortby=\*svcnum_sort; + @svc_domain=qsearch('svc_domain',{}); } elsif ( $query eq 'domain' ) { - $orderby = 'ORDER BY domain'; + $sortby=\*domain_sort; + @svc_domain=qsearch('svc_domain',{}); } elsif ( $query eq 'UN_svcnum' ) { - #$orderby = 'ORDER BY svcnum'; - $join = 'LEFT JOIN cust_svc USING ( svcnum )'; - $extra_sql = ' WHERE pkgnum IS NULL'; + $sortby=\*svcnum_sort; + @svc_domain = grep qsearchs('cust_svc',{ + 'svcnum' => $_->svcnum, + 'pkgnum' => '', + }), qsearch('svc_domain',{}); } elsif ( $query eq 'UN_domain' ) { - $orderby = 'ORDER BY domain'; - $join = 'LEFT JOIN cust_svc USING ( svcnum )'; - $extra_sql = ' WHERE pkgnum IS NULL'; + $sortby=\*domain_sort; + @svc_domain = grep qsearchs('cust_svc',{ + 'svcnum' => $_->svcnum, + 'pkgnum' => '', + }), qsearch('svc_domain',{}); } elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) { - #$orderby = 'ORDER BY svcnum'; - $join = 'LEFT JOIN cust_svc USING ( svcnum )'; - $extra_sql = " WHERE svcpart = $1"; + @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\-\.]+)$/; - $join = ''; - $svc_domain{'domain'} = $1; + 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 ) { +%> +<!-- mason kludge --> +<% + eidiot "No matching domains found!\n"; +} else { +%> +<!-- mason kludge --> +<% + my($total)=scalar(@svc_domain); + print 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 account)</FONT></TH> + <TH>Forwards to<BR><FONT SIZE=-1>(click to view account)</FONT></TH> +--> + </TR> +END + +# my(%saw); # if we've multiple domains with the same + # svcnum, then we've a corrupt database + + foreach my $svc_domain ( +# sort $sortby grep(!$saw{$_->svcnum}++, @svc_domain) + sort $sortby (@svc_domain) + ) { + my($svcnum,$domain)=( + $svc_domain->svcnum, + $svc_domain->domain, + ); + + #don't display all accounts here + my $rowspan = 1; + + #my @svc_acct=qsearch('svc_acct',{'domsvc' => $svcnum}); + #my $rowspan = 0; + # + #my $n1 = ''; + #my($svc_acct, @rows); + #foreach $svc_acct ( + # sort {$b->getfield('username') cmp $a->getfield('username')} (@svc_acct) + #) { + # + # my (@forwards) = (); + # + # my($svcnum,$username)=( + # $svc_acct->svcnum, + # $svc_acct->username, + # ); + # + # my @svc_forward = qsearch( 'svc_forward', { 'srcsvc' => $svcnum } ); + # my $svc_forward; + # foreach $svc_forward (@svc_forward) { + # my($dstsvc,$dst) = ( + # $svc_forward->dstsvc, + # $svc_forward->dst, + # ); + # if ($dstsvc) { + # my $dst_svc_acct=qsearchs( 'svc_acct', { 'svcnum' => $dstsvc } ); + # my $destination=$dst_svc_acct->email; + # push @forwards, qq!<TD><A HREF="!, popurl(2), + # qq!view/svc_acct.cgi?$dstsvc">$destination</A>!, + # qq!</TD></TR>! + # ; + # }else{ + # push @forwards, qq!<TD>$dst</TD></TR>! + # ; + # } + # } + # + # push @rows, qq!$n1<TD ROWSPAN=!, (scalar(@svc_forward) || 1), + # qq!><A HREF="!. popurl(2). qq!view/svc_acct.cgi?$svcnum">!, + # #print '', ( ($domuser eq '*') ? "<I>(anything)</I>" : $domuser ); + # ( ($username eq '*') ? "<I>(anything)</I>" : $username ), + # qq!\@$domain</A> </TD>!, + # ; + # + # push @rows, @forwards; + # + # $rowspan += (scalar(@svc_forward) || 1); + # $n1 = "</TR><TR>"; + #} + ##end of false laziness + # + # + + print <<END; + <TR> + <TD ROWSPAN=$rowspan><A HREF="${p}view/svc_domain.cgi?$svcnum">$svcnum</A></TD> + <TD ROWSPAN=$rowspan><A HREF="${p}view/svc_domain.cgi?$svcnum">$domain</A></TD> +END + + #print @rows; + print "</TR>"; + + } + + print <<END; + </TABLE> + </BODY> +</HTML> +END + } -my $count_query = "SELECT COUNT(*) FROM svc_domain $join $extra_sql"; -if ( keys %svc_domain ) { - $count_query .= ' WHERE '. - join(' AND ', map "$_ = ". dbh->quote($svc_domain{$_}), - keys %svc_domain - ); +sub svcnum_sort { + $a->getfield('svcnum') <=> $b->getfield('svcnum'); } -my $sql_query = { - 'table' => 'svc_domain', - 'hashref' => \%svc_domain, - 'select' => join(', ', - 'svc_domain.*', - 'cust_main.custnum', - FS::UI::Web::cust_sql_fields(), - ), - 'extra_sql' => "$extra_sql $orderby", - 'addl_from' => 'LEFT JOIN cust_svc USING ( svcnum ) '. - 'LEFT JOIN cust_pkg USING ( pkgnum ) '. - 'LEFT JOIN cust_main USING ( custnum ) ', -}; - -my $link = [ "${p}view/svc_domain.cgi?", 'svcnum' ]; - -#smaller false laziness w/svc_*.cgi here -my $link_cust = sub { - my $svc_x = shift; - $svc_x->custnum ? [ "${p}view/cust_main.cgi?", 'custnum' ] : ''; -}; - -%><%= include ('elements/search.html', - 'title' => "Domain Search Results", - 'name' => 'domains', - 'query' => $sql_query, - 'count_query' => $count_query, - 'redirect' => $link, - 'header' => [ '#', - 'Domain', - FS::UI::Web::cust_header(), - ], - 'fields' => [ 'svcnum', - 'domain', - \&FS::UI::Web::cust_fields, - ], - 'links' => [ $link, - $link, - ( map { $link_cust } - FS::UI::Web::cust_header() - ), - ], - ) +sub domain_sort { + $a->getfield('domain') cmp $b->getfield('domain'); +} + + %> diff --git a/httemplate/search/svc_domain.html b/httemplate/search/svc_domain.html index b759102..94bb9a6 100755 --- a/httemplate/search/svc_domain.html +++ b/httemplate/search/svc_domain.html @@ -7,7 +7,7 @@ Domain Search </FONT> <BR><BR> - <FORM ACTION="svc_domain.cgi" METHOD="GET"> + <FORM ACTION="svc_domain.cgi" METHOD="post"> Search for <B>domain</B>: <INPUT TYPE="text" NAME="domain"> diff --git a/httemplate/search/svc_forward.cgi b/httemplate/search/svc_forward.cgi index a204e34..10094bc 100755 --- a/httemplate/search/svc_forward.cgi +++ b/httemplate/search/svc_forward.cgi @@ -4,117 +4,76 @@ my $conf = new FS::Conf; my($query)=$cgi->keywords; $query ||= ''; #to avoid use of unitialized value errors - - -my $orderby; - -my $cjoin = ''; -my @extra_sql = (); -if ( $query =~ /^UN_(.*)$/ ) { - $query = $1; - $cjoin = 'LEFT JOIN cust_svc USING ( svcnum )'; - push @extra_sql, 'pkgnum IS NULL'; -} - +my(@svc_forward,$sortby); if ( $query eq 'svcnum' ) { - $orderby = 'ORDER BY svcnum'; + $sortby=\*svcnum_sort; + @svc_forward=qsearch('svc_forward',{}); } else { eidiot('unimplemented'); } -my $extra_sql = - scalar(@extra_sql) - ? ' WHERE '. join(' AND ', @extra_sql ) - : ''; - -my $count_query = "SELECT COUNT(*) FROM svc_forward $cjoin $extra_sql"; -my $sql_query = { - 'table' => 'svc_forward', - 'hashref' => {}, - 'select' => join(', ', - 'svc_forward.*', - 'cust_main.custnum', - FS::UI::Web::cust_sql_fields(), - ), - 'extra_sql' => "$extra_sql $orderby", - 'addl_from' => ' LEFT JOIN cust_svc USING ( svcnum ) '. - ' LEFT JOIN part_svc USING ( svcpart ) '. - ' LEFT JOIN cust_pkg USING ( pkgnum ) '. - ' LEFT JOIN cust_main USING ( custnum ) ', -}; - -# <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> - -my $link = [ "${p}view/svc_forward.cgi?", 'svcnum' ]; +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 $format_src = sub { - my $svc_forward = shift; - if ( $svc_forward->srcsvc_acct ) { - $svc_forward->srcsvc_acct->email; - } else { my $src = $svc_forward->src; $src = "<I>(anything)</I>$src" if $src =~ /^@/; - $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 -my $link_src = sub { - my $svc_forward = shift; - if ( $svc_forward->srcsvc_acct ) { - [ "${p}view/svc_acct.cgi?", 'srcsvc' ]; - } else { - ''; } -}; + + print <<END; + </TABLE> + </BODY> +</HTML> +END -my $format_dst = sub { - my $svc_forward = shift; - if ( $svc_forward->dstsvc_acct ) { - $svc_forward->dstsvc_acct->email; - } else { - $svc_forward->dst; - } -}; - -my $link_dst = sub { - my $svc_forward = shift; - if ( $svc_forward->dstsvc_acct ) { - [ "${p}view/svc_acct.cgi?", 'dstsvc' ]; - } else { - ''; - } -}; +} -#smaller false laziness w/svc_*.cgi here -my $link_cust = sub { - my $svc_x = shift; - $svc_x->custnum ? [ "${p}view/cust_main.cgi?", 'custnum' ] : ''; -}; +sub svcnum_sort { + $a->getfield('svcnum') <=> $b->getfield('svcnum'); +} -%><%= include( 'elements/search.html', - 'title' => "Mail forward Search Results", - 'name' => 'mail forwards', - 'query' => $sql_query, - 'count_query' => $count_query, - 'redirect' => $link, - 'header' => [ '#', - 'Mail to', - 'Forwards to', - FS::UI::Web::cust_header(), - ], - 'fields' => [ 'svcnum', - $format_src, - $format_dst, - \&FS::UI::Web::cust_fields, - ], - 'links' => [ $link, - $link_src, - $link_dst, - ( map { $link_cust } - FS::UI::Web::cust_header() - ), - ], - ) %> diff --git a/httemplate/search/svc_www.cgi b/httemplate/search/svc_www.cgi index ae51c61..1f05c23 100755 --- a/httemplate/search/svc_www.cgi +++ b/httemplate/search/svc_www.cgi @@ -4,7 +4,7 @@ my($query)=$cgi->keywords; $query ||= ''; #to avoid use of unitialized value errors -my $orderby; +my(@svc_www, $orderby); if ( $query eq 'svcnum' ) { $orderby = 'ORDER BY svcnum'; } else { @@ -15,55 +15,28 @@ my $count_query = 'SELECT COUNT(*) FROM svc_www'; my $sql_query = { 'table' => 'svc_www', 'hashref' => {}, - 'select' => join(', ', - 'svc_www.*', - 'cust_main.custnum', - FS::UI::Web::cust_sql_fields(), - ), 'extra_sql' => $orderby, - 'addl_from' => 'LEFT JOIN cust_svc USING ( svcnum )'. - 'LEFT JOIN cust_pkg USING ( pkgnum )'. - 'LEFT JOIN cust_main USING ( custnum )', }; my $link = [ "${p}view/svc_www.cgi?", 'svcnum', ]; #my $dlink = [ "${p}view/svc_www.cgi?", 'svcnum', ]; my $ulink = [ "${p}view/svc_acct.cgi?", 'usersvc', ]; -#smaller false laziness w/svc_*.cgi here -my $link_cust = sub { - my $svc_x = shift; - $svc_x->custnum ? [ "${p}view/cust_main.cgi?", 'custnum' ] : ''; -}; -%><%= include( 'elements/search.html', - 'title' => 'Virtual Host Search Results', - 'name' => 'virtual hosts', - 'query' => $sql_query, - 'count_query' => $count_query, - 'redirect' => $link, - 'header' => [ '#', - 'Zone', - 'User', - FS::UI::Web::cust_header(), - ], - 'fields' => [ 'svcnum', - sub { $_[0]->domain_record->zone }, - sub { - my $svc_www = shift; - my $svc_acct = $svc_www->svc_acct; - $svc_acct - ? $svc_acct->email - : ''; - }, - \&FS::UI::Web::cust_fields, - ], - 'links' => [ $link, - '', - $ulink, - ( map { $link_cust } - FS::UI::Web::cust_header() - ), - ], - ) +%> +<%= include( 'elements/search.html', + 'title' => 'Virtual Host Search Results', + 'name' => 'virtual hosts', + 'query' => $sql_query, + 'count_query' => $count_query, + 'header' => [ '#', 'Zone', 'User', ], + 'fields' => [ 'svcnum', + sub { $_[0]->domain_record->zone }, + sub { $_[0]->svc_acct->email }, + ], + 'links' => [ $link, + '', + $ulink, + ], + ) %> |