summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS/cust_bill.pm24
-rw-r--r--FS/FS/cust_bill_void.pm65
-rw-r--r--httemplate/elements/menu.html3
-rwxr-xr-xhttemplate/search/cust_bill.html28
-rwxr-xr-xhttemplate/view/cust_bill-logo.cgi8
5 files changed, 117 insertions, 11 deletions
diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm
index cd85f67..1b765fa 100644
--- a/FS/FS/cust_bill.pm
+++ b/FS/FS/cust_bill.pm
@@ -3317,6 +3317,22 @@ flag, return net invoices only
=item newest_percust
+=item custnum
+
+Return only invoices belonging to that customer.
+
+=item cust_classnum
+
+Limit to that customer class (single value or arrayref).
+
+=item payby
+
+Limit to customers with that payment method (single value or arrayref).
+
+=item refnum
+
+Limit to customers with that advertising source.
+
=back
Note: validates all passed-in data; i.e. safe to use with unchecked CGI params.
@@ -3368,6 +3384,14 @@ sub search_sql_where {
}
+ #payby
+ if ( $param->{payby} ) {
+ my $payby = $param->{payby};
+ $payby = [ $payby ] unless ref $payby;
+ my $payby_in = join(',', map {dbh->quote($_)} @$payby);
+ push @search, "cust_main.payby IN($payby_in)" if length($payby_in);
+ }
+
#_date
if ( $param->{_date} ) {
my($beginning, $ending) = @{$param->{_date}};
diff --git a/FS/FS/cust_bill_void.pm b/FS/FS/cust_bill_void.pm
index b829b8d..bf147c0 100644
--- a/FS/FS/cust_bill_void.pm
+++ b/FS/FS/cust_bill_void.pm
@@ -258,6 +258,71 @@ sub cust_bill_pkg { #actually cust_bill_pkg_void objects
=back
+=item cust_pkg
+
+Returns the packages (see L<FS::cust_pkg>) corresponding to the line items for
+this invoice.
+
+=cut
+
+sub cust_pkg {
+ my $self = shift;
+ my @cust_pkg = map { $_->pkgnum > 0 ? $_->cust_pkg : () }
+ $self->cust_bill_pkg;
+ my %saw = ();
+ grep { ! $saw{$_->pkgnum}++ } @cust_pkg;
+}
+
+=item search_sql_where HASHREF
+
+Class method which returns an SQL WHERE fragment to search for parameters
+specified in HASHREF. Accepts the following parameters for
+L<FS::cust_bill::search_sql_where>: C<_date>, C<invnum_min>, C<invnum_max>,
+C<agentnum>, C<custnum>, C<cust_classnum>, C<refnum>, C<payby>. Also
+accepts the following:
+
+=over 4
+
+=item void_date
+
+Arrayref of start and end date to find invoices voided in a date range.
+
+=item void_usernum
+
+User identifier (L<FS::access_user> key) that voided the invoice.
+
+=back
+
+=cut
+
+sub search_sql_where {
+ my($class, $param) = @_;
+
+ my $cust_bill_param = {
+ map { $_ => $param->{$_} }
+ grep { exists($param->{$_}) }
+ qw( _date invnum_min invnum_max agentnum custnum cust_classnum
+ refnum payby )
+ };
+ my $search_sql = FS::cust_bill->search_sql_where($cust_bill_param);
+ $search_sql =~ s/cust_bill/cust_bill_void/g;
+ my @search = ($search_sql);
+
+ if ( $param->{void_date} ) {
+ my($beginning, $ending) = @{$param->{void_date}};
+ push @search, "cust_bill_void.void_date >= $beginning",
+ "cust_bill_void.void_date < $ending";
+ }
+
+ if ( $param->{void_usernum} =~ /^(\d+)$/ ) {
+ my $usernum = $1;
+ push @search, "cust_bill_void.void_usernum = $1";
+ }
+
+ join(" AND ", @search);
+}
+
+
=item enable_previous
=cut
diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html
index 10c554a..7df2448 100644
--- a/httemplate/elements/menu.html
+++ b/httemplate/elements/menu.html
@@ -132,6 +132,9 @@ tie my %report_invoices, 'Tie::IxHash',
'Advanced invoice reports' => [ $fsurl.'search/report_cust_bill.html', 'by agent, date range, etc.' ],
'separator' => '',
'Line items' => [ $fsurl. 'search/report_cust_bill_pkg.html', 'Individual line item detail' ],
+ 'separator' => '',
+ 'Voided invoices' => [ $fsurl.'search/report_cust_bill_void.html', 'Search for voided invoices' ],
+
;
tie my %report_discounts, 'Tie::IxHash',
diff --git a/httemplate/search/cust_bill.html b/httemplate/search/cust_bill.html
index 473aed3..8d512f5 100755
--- a/httemplate/search/cust_bill.html
+++ b/httemplate/search/cust_bill.html
@@ -84,6 +84,20 @@ if ( $cgi->param('invnum') =~ /^\s*(FS-)?(\d+)\s*$/ ) {
'extra_sql' => $where,
};
+ if ( FS::Record->scalar_sql($count_query) == 0 ) {
+
+ # check for a voided invoice
+ $count_query =~ s/cust_bill/cust_bill_void/g;
+ if ( FS::Record->scalar_sql($count_query) > 0 ) {
+ # Redirect to the void search.
+ my $url = $cgi->self_url;
+ $url =~ s(search/cust_bill)(search/cust_bill_void);
+ $m->clear_buffer;
+ $m->print($cgi->redirect($url));
+ $m->abort;
+ }
+ }
+
} else {
#some false laziness w/cust_bill::re_X
@@ -156,15 +170,13 @@ if ( grep { $_ eq 'cust_classnum' } $cgi->param ) {
}
}
- my $payby_sql = '';
- $payby_sql = ' AND (' .
- join(' OR ', map { "cust_main.payby = '$_'" } $cgi->param('payby') ) .
- ')'
- if $cgi->param('payby');
+ #payby
+ if ($cgi->param('payby')) {
+ $search{payby} = [ $cgi->param('payby') ];
+ }
- my $extra_sql = ' WHERE '.
- FS::cust_bill->search_sql_where( \%search ).
- $payby_sql;
+ my $extra_sql = FS::cust_bill->search_sql_where( \%search );
+ $extra_sql = "WHERE $extra_sql" if $extra_sql;
unless ( $count_query ) {
$count_query = 'SELECT COUNT(*), '. join(', ',
diff --git a/httemplate/view/cust_bill-logo.cgi b/httemplate/view/cust_bill-logo.cgi
index d55ec04..dc8b674 100755
--- a/httemplate/view/cust_bill-logo.cgi
+++ b/httemplate/view/cust_bill-logo.cgi
@@ -9,10 +9,12 @@ my $conf;
my $templatename;
my $agentnum = '';
-if ( $cgi->param('invnum') ) {
+if ( $cgi->param('invnum') =~ /^(\d+)$/ ) {
+ my $invnum = $1;
$templatename = $cgi->param('template') || $cgi->param('templatename');
- my $cust_bill = qsearchs('cust_bill', { 'invnum' => $cgi->param('invnum') } )
- or die 'unknown invnum';
+ my $cust_bill = FS::cust_bill->by_key($invnum)
+ || FS::cust_bill_void->by_key($invnum);
+ die 'unknown invnum' unless $cust_bill;
$conf = $cust_bill->conf;
$agentnum = $cust_bill->cust_main->agentnum;
} else {