Optionally show previous invoices on statements, #15864
authorMark Wells <mark@freeside.biz>
Tue, 17 Jul 2012 21:34:54 +0000 (14:34 -0700)
committerMark Wells <mark@freeside.biz>
Tue, 17 Jul 2012 21:34:54 +0000 (14:34 -0700)
FS/FS/Conf.pm
FS/FS/Template_Mixin.pm
FS/FS/cust_bill.pm
FS/FS/cust_statement.pm
FS/FS/quotation.pm
httemplate/view/cust_main_statement-pdf.cgi

index f081c17..13a84bc 100644 (file)
@@ -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.',
index c42e239..a608691 100644 (file)
@@ -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;
index 83748be..c3d48a6 100644 (file)
@@ -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<FS::cust_bill_pkg>) for this invoice.
index 45fae1c..9954b7b 100644 (file)
@@ -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<hash> 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
index 0cfb11e..ccaa1c3 100644 (file)
@@ -150,6 +150,12 @@ sub cust_bill_pkg {
 
 =back
 
+=item enable_previous
+
+=cut
+
+sub enable_previous { 0 }
+
 =head1 BUGS
 
 =head1 SEE ALSO
index 7a0e198..7c2c207 100755 (executable)
@@ -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' );