From 493be9f0635db1e24783e5c3945b8bef39624674 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 17 Jul 2012 14:34:54 -0700 Subject: [PATCH] Optionally show previous invoices on statements, #15864 --- FS/FS/Conf.pm | 9 +++++- FS/FS/Template_Mixin.pm | 48 ++++++++++++++------------- FS/FS/cust_bill.pm | 13 ++++++++ FS/FS/cust_statement.pm | 50 ++++++++++++++++++++++------- FS/FS/quotation.pm | 6 ++++ httemplate/view/cust_main_statement-pdf.cgi | 6 +++- 6 files changed, 97 insertions(+), 35 deletions(-) diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index f081c1796..13a84bcca 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -3985,7 +3985,7 @@ and customer address. Include units.', { 'key' => 'disable_previous_balance', 'section' => 'invoicing', - 'description' => 'Disable inclusion of previous balance, payment, and credit lines on invoices', + 'description' => 'Disable inclusion of previous balance, payment, and credit lines on invoices.', 'type' => 'checkbox', 'per_agent' => 1, }, @@ -4012,6 +4012,13 @@ and customer address. Include units.', }, { + 'key' => 'previous_balance-show_on_statements', + 'section' => 'invoicing', + 'description' => 'Show previous invoices on statements, without itemized charges.', + 'type' => 'checkbox', + }, + + { 'key' => 'balance_due_below_line', 'section' => 'invoicing', 'description' => 'Place the balance due message below a line. Only meaningful when when invoice_sections is false.', diff --git a/FS/FS/Template_Mixin.pm b/FS/FS/Template_Mixin.pm index c42e239dc..a608691b2 100644 --- a/FS/FS/Template_Mixin.pm +++ b/FS/FS/Template_Mixin.pm @@ -806,11 +806,11 @@ sub print_generic { } } - unless ( $conf->exists('disable_previous_balance', $agentnum) - || $conf->exists('previous_balance-summary_only') - || ! $self->can('_items_previous') - ) - { + # previous invoice balances in the Previous Charges section if there + # is one, otherwise in the main detail section + if ( $self->can('_items_previous') && + $self->enable_previous && + ! $conf->exists('previous_balance-summary_only') ) { warn "$me adding previous balances\n" if $DEBUG > 1; @@ -841,9 +841,8 @@ sub print_generic { } } - - if ( @pr_cust_bill && !$conf->exists('disable_previous_balance', $agentnum) ) - { + + if ( @pr_cust_bill && $self->enable_previous ) { push @buf, ['','-----------']; push @buf, [ $self->mt('Total Previous Balance'), $money_char. sprintf("%10.2f", $pr_total) ]; @@ -961,7 +960,9 @@ sub print_generic { $invoice_data{current_less_finance} = sprintf('%.2f', $self->charged - $invoice_data{finance_amount} ); - if ( $multisection && !$conf->exists('disable_previous_balance', $agentnum) + # create a major section for previous balance if we have major sections, + # or if previous_section is in summary form + if ( ( $multisection && $self->enable_previous ) || $conf->exists('previous_balance-summary_only') ) { unshift @sections, $previous_section if $pr_total; @@ -1025,25 +1026,26 @@ sub print_generic { push @buf,['','-----------']; push @buf,[$self->mt( - $conf->exists('disable_previous_balance', $agentnum) + (!$self->enable_previous) ? 'Total Charges' : 'Total New Charges' ), $money_char. sprintf("%10.2f",$self->charged) ]; push @buf,['','']; + # calculate total, possibly including total owed on previous + # invoices { my $total = {}; my $item = 'Total'; $item = $conf->config('previous_balance-exclude_from_total') || 'Total New Charges' if $conf->exists('previous_balance-exclude_from_total'); - my $amount = $self->charged + - ( $conf->exists('disable_previous_balance', $agentnum) || - $conf->exists('previous_balance-exclude_from_total') - ? 0 - : $pr_total - ); + my $amount = $self->charged; + if ( $self->enable_previous and !$conf->exists('previous_balance-exclude_from_total') ) { + $amount += $pr_total; + } + $total->{'total_item'} = &$embolden_function($self->mt($item)); $total->{'total_amount'} = &$embolden_function( $other_money_char. sprintf( '%.2f', $amount ) ); @@ -1065,12 +1067,13 @@ sub print_generic { ]; push @buf,['','']; } - - unless ( $conf->exists('disable_previous_balance', $agentnum) - || ! $self->can('_items_credits') - || ! $self->can('_items_payments') - ) - { + + # if we're showing previous invoices, also show previous + # credits and payments + if ( $self->enable_previous + and $self->can('_items_credits') + and $self->can('_items_payments') ) + { #foreach my $thing ( sort { $a->_date <=> $b->_date } $self->_items_credits, $self->_items_payments # credits @@ -2133,6 +2136,7 @@ sub _items_cust_bill_pkg { my $summary_page = $opt{summary_page} || ''; #unused my $multilocation = $opt{multilocation} || ''; my $multisection = $opt{multisection} || ''; + my $enable_previous = $self->enable_previous; my $discount_show_always = 0; my $maxlength = $conf->config('cust_bill-latex_lineitem_maxlength') || 50; diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index 83748be1b..c3d48a61c 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -387,6 +387,19 @@ sub previous { $total, @cust_bill; } +=item enable_previous + +Whether to show the 'Previous Charges' section when printing this invoice. +The negation of the 'disable_previous_balance' config setting. + +=cut + +sub enable_previous { + my $self = shift; + my $agentnum = $self->cust_main->agentnum; + !$self->conf->exists('disable_previous_balance', $agentnum); +} + =item cust_bill_pkg Returns the line items (see L) for this invoice. diff --git a/FS/FS/cust_statement.pm b/FS/FS/cust_statement.pm index 45fae1ccf..9954b7b90 100644 --- a/FS/FS/cust_statement.pm +++ b/FS/FS/cust_statement.pm @@ -6,6 +6,8 @@ use FS::Record qw( dbh qsearch ); #qsearchs ); use FS::cust_main; use FS::cust_bill; +use List::Util qw( sum ); + =head1 NAME FS::cust_statement - Object methods for cust_statement records @@ -61,8 +63,13 @@ Note that this stores the hash reference, not a distinct copy of the hash it points to. You can ask the object for a copy with the I method. Pass "statementnum => 'ALL'" to create a temporary statement that includes -all of the customer's invoices. This statement can't be inserted and won't -set the statementnum field on any invoices. +all of the customer's open invoices. This statement can't be inserted and +won't set the statementnum field on any invoices. + +Pass "invnum => number" to create a temporary statement including only +the specified invoice. This is functionally the same as the invoice itself, +but will be rendered using the statement template and other +statement-specific options. =cut @@ -170,13 +177,23 @@ Returns the associated invoices (cust_bill records) for this statement. sub cust_bill { my $self = shift; # we use it about a thousand times, let's cache it - $self->{Hash}->{cust_bill} ||= [ - qsearch('cust_bill', { - $self->statementnum eq 'ALL' ? - ('custnum' => $self->custnum) : - ('statementnum' => $self->statementnum) - } ) - ]; + if ( !exists($self->{Hash}->{cust_bill}) ) { + my @cust_bill; + if ( $self->invnum && $self->invnum =~ /^\d+$/ ) { + # one specific invoice + @cust_bill = FS::cust_bill->by_key($self->invnum) + or die "unknown invnum '".$self->invnum."'"; + $self->set('custnum' => $cust_bill[0]->custnum); + } elsif ( $self->statementnum eq 'ALL' ) { + # all open invoices + @cust_bill = $self->cust_main->open_cust_bill; + } else { + @cust_bill = qsearch('cust_bill', + { statementnum => $self->statementnum } + ); + } + $self->{Hash}->{cust_bill} = \@cust_bill; + } @{ $self->{Hash}->{cust_bill} } } @@ -266,9 +283,20 @@ sub tax { shift->_total('tax', @_); } sub charged { shift->_total('charged', @_); } sub owed { shift->_total('owed', @_); } -#don't show previous info +sub enable_previous { + my $self = shift; + $self->conf->exists('previous_balance-show_on_statements'); +} + sub previous { - ( 0 ); # 0, empty list + my $self = shift; + if ( $self->enable_previous ) { + my @previous = grep { $_->_date < ($self->cust_bill)[0]->_date } + $self->cust_main->open_cust_bill; + return(sum(map {$_->owed} @previous), @previous); + } else { + return 0; + } } =back diff --git a/FS/FS/quotation.pm b/FS/FS/quotation.pm index 0cfb11e2f..ccaa1c34b 100644 --- a/FS/FS/quotation.pm +++ b/FS/FS/quotation.pm @@ -150,6 +150,12 @@ sub cust_bill_pkg { =back +=item enable_previous + +=cut + +sub enable_previous { 0 } + =head1 BUGS =head1 SEE ALSO diff --git a/httemplate/view/cust_main_statement-pdf.cgi b/httemplate/view/cust_main_statement-pdf.cgi index 7a0e19838..7c2c20799 100755 --- a/httemplate/view/cust_main_statement-pdf.cgi +++ b/httemplate/view/cust_main_statement-pdf.cgi @@ -23,13 +23,17 @@ my $cust_main = qsearchs({ 'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql, }); die "Customer #$custnum not found!" unless $cust_main; +my $cust_bill = ($cust_main->cust_bill)[-1] + or die "Customer #$custnum has no invoices!"; my $cust_statement = FS::cust_statement->new({ 'custnum' => $custnum, - 'statementnum' => 'ALL', #magic +# 'statementnum' => 'ALL', #magic + 'invnum' => $cust_bill->invnum, '_date' => time, }); + my $pdf = $cust_statement->print_pdf( '', $templatename ); http_header('Content-Type' => 'application/pdf' ); -- 2.11.0