delete fees, RT#81713
[freeside.git] / FS / FS / cust_statement.pm
index cd3e7ce..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
@@ -60,6 +62,15 @@ Creates a new record.  To add the record to the database, see L<"insert">.
 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 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
 
 sub new { FS::Record::new(@_); }
@@ -165,7 +176,26 @@ Returns the associated invoices (cust_bill records) for this statement.
 
 sub cust_bill {
   my $self = shift;
-  qsearch('cust_bill', { 'statementnum' => $self->statementnum } );
+  # we use it about a thousand times, let's cache it
+  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} }
 }
 
 sub _aggregate {
@@ -180,6 +210,18 @@ sub _aggregate {
   @agg;
 }
 
+sub _total {
+  my( $self, $method ) = ( shift, shift );
+
+  my $total = 0;
+
+  foreach my $cust_bill ( $self->cust_bill ) {
+    $total += $cust_bill->$method( @_ );
+  }
+
+  $total;
+}
+
 =item cust_bill_pkg
 
 Returns the line items (see L<FS::cust_bill_pkg>) for all associated invoices.
@@ -221,20 +263,40 @@ sub cust_bill_pkg_pkgnum { shift->_aggregate('cust_bill_pkg_pkgnum', @_); }
 
 =item tax
 
-Returns the tax amount (see L<FS::cust_bill_pkg>) for this invoice.
+Returns the total tax amount for all assoicated invoices.0
 
 =cut
 
-sub tax {
-  my $self = shift;
+=item charged
 
-  my $total = 0;
+Returns the total amount charged for all associated invoices.
 
-  foreach my $cust_bill ( $self->cust_bill ) {
-    $total += $cust_bill->tax;
-  }
+=cut
 
-  $total;
+=item owed
+
+Returns the total amount owed for all associated invoices.
+
+=cut
+
+sub tax     { shift->_total('tax',     @_); }
+sub charged { shift->_total('charged', @_); }
+sub owed    { shift->_total('owed',    @_); }
+
+sub enable_previous {
+  my $self = shift;
+  $self->conf->exists('previous_balance-show_on_statements');
+}
+
+sub previous {
+  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