1 package FS::cust_statement;
4 use base qw( FS::cust_bill );
5 use FS::Record qw( dbh qsearch ); #qsearchs );
9 use List::Util qw( sum );
13 FS::cust_statement - Object methods for cust_statement records
17 use FS::cust_statement;
19 $record = new FS::cust_statement \%hash;
20 $record = new FS::cust_statement { 'column' => 'value' };
22 $error = $record->insert;
24 $error = $new_record->replace($old_record);
26 $error = $record->delete;
28 $error = $record->check;
32 An FS::cust_statement object represents an informational statement which
33 aggregates one or more invoices. FS::cust_statement inherits from
36 The following fields are currently supported:
60 Creates a new record. To add the record to the database, see L<"insert">.
62 Note that this stores the hash reference, not a distinct copy of the hash it
63 points to. You can ask the object for a copy with the I<hash> method.
65 Pass "statementnum => 'ALL'" to create a temporary statement that includes
66 all of the customer's open invoices. This statement can't be inserted and
67 won't set the statementnum field on any invoices.
69 Pass "invnum => number" to create a temporary statement including only
70 the specified invoice. This is functionally the same as the invoice itself,
71 but will be rendered using the statement template and other
72 statement-specific options.
76 sub new { FS::Record::new(@_); }
78 sub table { 'cust_statement'; }
82 Adds this record to the database. If there is an error, returns the error,
83 otherwise returns false.
90 local $SIG{HUP} = 'IGNORE';
91 local $SIG{INT} = 'IGNORE';
92 local $SIG{QUIT} = 'IGNORE';
93 local $SIG{TERM} = 'IGNORE';
94 local $SIG{TSTP} = 'IGNORE';
95 local $SIG{PIPE} = 'IGNORE';
97 my $oldAutoCommit = $FS::UID::AutoCommit;
98 local $FS::UID::AutoCommit = 0;
101 FS::Record::insert($self);
103 foreach my $cust_bill (
105 'table' => 'cust_bill',
106 'hashref' => { 'custnum' => $self->custnum,
107 'statementnum' => '',
109 'extra_sql' => 'FOR UPDATE' ,
113 $cust_bill->statementnum( $self->statementnum );
114 my $error = $cust_bill->replace;
116 $dbh->rollback if $oldAutoCommit;
117 return "Error associating invoice: $error";
121 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
128 Delete this record from the database.
132 sub delete { FS::Record::delete(@_); }
134 =item replace OLD_RECORD
136 Replaces the OLD_RECORD with this one in the database. If there is an error,
137 returns the error, otherwise returns false.
141 sub replace { FS::Record::replace(@_); }
143 sub replace_check { ''; }
147 Checks all fields to make sure this is a valid record. If there is
148 an error, returns the error, otherwise returns false. Called by the insert
157 $self->ut_numbern('statementnum')
158 || $self->ut_foreign_key('custnum', 'cust_main', 'custnum' )
159 || $self->ut_numbern('_date')
161 return $error if $error;
163 $self->_date(time) unless $self->_date;
165 #don't want to call cust_bill, and Record just checks virtual fields
166 #$self->SUPER::check;
173 Returns the associated invoices (cust_bill records) for this statement.
179 # we use it about a thousand times, let's cache it
180 if ( !exists($self->{Hash}->{cust_bill}) ) {
182 if ( $self->invnum && $self->invnum =~ /^\d+$/ ) {
183 # one specific invoice
184 @cust_bill = FS::cust_bill->by_key($self->invnum)
185 or die "unknown invnum '".$self->invnum."'";
186 $self->set('custnum' => $cust_bill[0]->custnum);
187 } elsif ( $self->statementnum eq 'ALL' ) {
189 @cust_bill = $self->cust_main->open_cust_bill;
191 @cust_bill = qsearch('cust_bill',
192 { statementnum => $self->statementnum }
195 $self->{Hash}->{cust_bill} = \@cust_bill;
198 @{ $self->{Hash}->{cust_bill} }
202 my( $self, $method ) = ( shift, shift );
206 foreach my $cust_bill ( $self->cust_bill ) {
207 push @agg, $cust_bill->$method( @_ );
214 my( $self, $method ) = ( shift, shift );
218 foreach my $cust_bill ( $self->cust_bill ) {
219 $total += $cust_bill->$method( @_ );
227 Returns the line items (see L<FS::cust_bill_pkg>) for all associated invoices.
229 =item cust_bill_pkg_pkgnum PKGNUM
231 Returns the line items (see L<FS::cust_bill_pkg>) for all associated invoices
232 and specified pkgnum.
236 Returns all payment applications (see L<FS::cust_bill_pay>) for all associated
241 Returns all applied credits (see L<FS::cust_credit_bill>) for all associated
244 =item cust_bill_pay_pkgnum PKGNUM
246 Returns all payment applications (see L<FS::cust_bill_pay>) for all associated
247 invoices with matching pkgnum.
249 =item cust_credited_pkgnum PKGNUM
251 Returns all applied credits (see L<FS::cust_credit_bill>) for all associated
252 invoices with matching pkgnum.
256 sub cust_bill_pay { shift->_aggregate('cust_bill_pay', @_); }
257 sub cust_credited { shift->_aggregate('cust_credited', @_); }
258 sub cust_bill_pay_pkgnum { shift->_aggregate('cust_bill_pay_pkgnum', @_); }
259 sub cust_credited_pkgnum { shift->_aggregate('cust_credited_pkgnum', @_); }
261 sub cust_bill_pkg { shift->_aggregate('cust_bill_pkg', @_); }
262 sub cust_bill_pkg_pkgnum { shift->_aggregate('cust_bill_pkg_pkgnum', @_); }
266 Returns the total tax amount for all assoicated invoices.0
272 Returns the total amount charged for all associated invoices.
278 Returns the total amount owed for all associated invoices.
282 sub tax { shift->_total('tax', @_); }
283 sub charged { shift->_total('charged', @_); }
284 sub owed { shift->_total('owed', @_); }
286 sub enable_previous {
288 $self->conf->exists('previous_balance-show_on_statements');
293 if ( $self->enable_previous ) {
294 my @previous = grep { $_->_date < ($self->cust_bill)[0]->_date }
295 $self->cust_main->open_cust_bill;
296 return(sum(map {$_->owed} @previous), @previous);
308 L<FS::cust_bill>, L<FS::Record>, schema.html from the base documentation.