[freeside-commits] freeside/FS/FS Schema.pm, 1.23,
1.24 cust_bill_pay_pkg.pm, NONE, 1.1 cust_credit_bill_pkg.pm,
NONE, 1.1 cust_bill_ApplicationCommon.pm, NONE,
1.1 cust_bill_pkg.pm, 1.10, 1.11 cust_bill.pm, 1.150,
1.151 cust_bill_pay.pm, 1.16, 1.17 cust_credit_bill.pm, 1.13, 1.14
Ivan,,,
ivan at wavetail.420.am
Mon Aug 21 16:01:45 PDT 2006
Update of /home/cvs/cvsroot/freeside/FS/FS
In directory wavetail:/tmp/cvs-serv15920/FS/FS
Modified Files:
Schema.pm cust_bill_pkg.pm cust_bill.pm cust_bill_pay.pm
cust_credit_bill.pm
Added Files:
cust_bill_pay_pkg.pm cust_credit_bill_pkg.pm
cust_bill_ApplicationCommon.pm
Log Message:
add cust_bill_pay_pkg and cust_credit_bill_pkg - applying credits and payments against specific line items
--- NEW FILE: cust_credit_bill_pkg.pm ---
package FS::cust_credit_bill_pkg;
use strict;
use vars qw( @ISA );
use FS::Record qw( qsearch qsearchs );
@ISA = qw(FS::Record);
=head1 NAME
FS::cust_credit_bill_pkg - Object methods for cust_credit_bill_pkg records
=head1 SYNOPSIS
use FS::cust_credit_bill_pkg;
$record = new FS::cust_credit_bill_pkg \%hash;
$record = new FS::cust_credit_bill_pkg { 'column' => 'value' };
$error = $record->insert;
$error = $new_record->replace($old_record);
$error = $record->delete;
$error = $record->check;
=head1 DESCRIPTION
An FS::cust_credit_bill_pkg object represents application of a credit (see
L<FS::cust_credit_bill>) to a specific line item within an invoice
(see L<FS::cust_bill_pkg>). FS::cust_credit_bill_pkg inherits from FS::Record.
The following fields are currently supported:
=over 4
=item creditbillpkg - primary key
=item creditbillnum - Credit application to the overall invoice (see L<FS::cust_credit::bill>)
=item billpkgnum - Line item to which credit is applied (see L<FS::cust_bill_pkg>)
=item amount - Amount of the credit applied to this line item.
=item setuprecur - 'setup' or 'recur', designates whether the payment was applied to the setup or recurring portion of the line item.
=back
=head1 METHODS
=over 4
=item new HASHREF
Creates a new example. To add the example 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.
=cut
# the new method can be inherited from FS::Record, if a table method is defined
sub table { 'cust_credit_bill_pkg'; }
=item insert
Adds this record to the database. If there is an error, returns the error,
otherwise returns false.
=cut
# the insert method can be inherited from FS::Record
=item delete
Delete this record from the database.
=cut
# the delete method can be inherited from FS::Record
=item replace OLD_RECORD
Replaces the OLD_RECORD with this one in the database. If there is an error,
returns the error, otherwise returns false.
=cut
# the replace method can be inherited from FS::Record
=item check
Checks all fields to make sure this is a valid credit applicaiton. If there is
an error, returns the error, otherwise returns false. Called by the insert
and replace methods.
=cut
# the check method should currently be supplied - FS::Record contains some
# data checking routines
sub check {
my $self = shift;
my $error =
$self->ut_numbern('creditbillpkgnum')
|| $self->ut_foreign_key('creditbillnum', 'cust_credit_bill', 'creditbillnum')
|| $self->ut_foreign_key('billpkgnum', 'cust_bill_pkg', 'billpkgnum' )
|| $self->ut_money('amount')
|| $self->ut_enum('setuprecur', [ 'setup', 'recur' ] )
;
return $error if $error;
$self->SUPER::check;
}
=back
=head1 BUGS
B<setuprecur> field is a kludge to compensate for cust_bill_pkg having separate
setup and recur fields. It should be removed once that's fixed.
=head1 SEE ALSO
L<FS::Record>, schema.html from the base documentation.
=cut
1;
--- NEW FILE: cust_bill_pay_pkg.pm ---
package FS::cust_bill_pay_pkg;
use strict;
use vars qw( @ISA );
use FS::Record qw( qsearch qsearchs );
@ISA = qw(FS::Record);
=head1 NAME
FS::cust_bill_pay_pkg - Object methods for cust_bill_pay_pkg records
=head1 SYNOPSIS
use FS::cust_bill_pay_pkg;
$record = new FS::cust_bill_pay_pkg \%hash;
$record = new FS::cust_bill_pay_pkg { 'column' => 'value' };
$error = $record->insert;
$error = $new_record->replace($old_record);
$error = $record->delete;
$error = $record->check;
=head1 DESCRIPTION
An FS::cust_bill_pay_pkg object represents application of a payment (see
L<FS::cust_bill_pay>) to a specific line item within an invoice (see
L<FS::cust_bill_pkg>). FS::cust_bill_pay_pkg inherits from FS::Record. The
following fields are currently supported:
=over 4
=item billpaypkgnum - primary key
=item billpaynum - Payment application to the overall invoice (see L<FS::cust_bill_pay>)
=item billpkgnum - Line item to which payment is applied (see L<FS::cust_bill_pkg>)
=item amount - Amount of the payment applied to this line item.
=item setuprecur - 'setup' or 'recur', designates whether the payment was applied to the setup or recurring portion of the line item.
=back
=head1 METHODS
=over 4
=item new HASHREF
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.
=cut
# the new method can be inherited from FS::Record, if a table method is defined
sub table { 'cust_bill_pay_pkg'; }
=item insert
Adds this record to the database. If there is an error, returns the error,
otherwise returns false.
=cut
# the insert method can be inherited from FS::Record
=item delete
Delete this record from the database.
=cut
# the delete method can be inherited from FS::Record
=item replace OLD_RECORD
Replaces the OLD_RECORD with this one in the database. If there is an error,
returns the error, otherwise returns false.
=cut
# the replace method can be inherited from FS::Record
=item check
Checks all fields to make sure this is a valid payment application. If there
is an error, returns the error, otherwise returns false. Called by the insert
and replace methods.
=cut
# the check method should currently be supplied - FS::Record contains some
# data checking routines
sub check {
my $self = shift;
my $error =
$self->ut_numbern('billpaypkgnum')
|| $self->ut_foreign_key('billpaynum', 'cust_bill_pay', 'billpaynum' )
|| $self->ut_foreign_key('billpkgnum', 'cust_bill_pkg', 'billpkgnum' )
|| $self->ut_money('amount')
|| $self->ut_enum('setuprecur', [ 'setup', 'recur' ] )
;
return $error if $error;
$self->SUPER::check;
}
=back
=head1 BUGS
B<setuprecur> field is a kludge to compensate for cust_bill_pkg having separate
setup and recur fields. It should be removed once that's fixed.
=head1 SEE ALSO
L<FS::Record>, schema.html from the base documentation.
=cut
1;
Index: cust_credit_bill.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_credit_bill.pm,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- cust_credit_bill.pm 30 Jun 2004 17:57:03 -0000 1.13
+++ cust_credit_bill.pm 21 Aug 2006 23:01:43 -0000 1.14
@@ -4,12 +4,11 @@
use vars qw( @ISA $conf );
use FS::UID qw( getotaker );
use FS::Record qw( qsearch qsearchs );
-use FS::cust_main;
-#use FS::cust_refund;
-use FS::cust_credit;
+use FS::cust_bill_ApplicationCommon;
use FS::cust_bill;
+use FS::cust_credit;
- at ISA = qw( FS::Record );
+ at ISA = qw( FS::cust_bill_ApplicationCommon );
#ask FS::UID to run this stuff for us later
FS::UID->install_callback( sub {
@@ -39,7 +38,8 @@
An FS::cust_credit_bill object represents application of a credit (see
L<FS::cust_credit>) to an invoice (see L<FS::cust_bill>). FS::cust_credit_bill
-inherits from FS::Record. The following fields are currently supported:
+inherits from FS::cust_bill_ApplicationCommon and FS::Record. The following
+fields are currently supported:
=over 4
@@ -69,6 +69,10 @@
sub table { 'cust_credit_bill'; }
+sub _app_source_name { 'credit'; }
+sub _app_source_table { 'cust_credit'; }
+sub _app_lineitem_breakdown_table { 'cust_credit_bill_pkg'; }
+
=item insert
Adds this cust_credit_bill to the database ("Posts" all or part of a credit).
@@ -84,6 +88,8 @@
my $self = shift;
return "Can't delete application for closed credit"
if $self->cust_credit->closed =~ /^Y/i;
+ return "Can't delete application for closed invoice"
+ if $self->cust_bill->closed =~ /^Y/i;
$self->SUPER::delete(@_);
}
@@ -110,8 +116,8 @@
my $error =
$self->ut_numbern('creditbillnum')
- || $self->ut_number('crednum')
- || $self->ut_number('invnum')
+ || $self->ut_foreign_key('crednum', 'cust_credit', 'crednum')
+ || $self->ut_foreign_key('invnum', 'cust_bill', 'invnum' )
|| $self->ut_numbern('_date')
|| $self->ut_money('amount')
;
@@ -119,21 +125,13 @@
return "amount must be > 0" if $self->amount <= 0;
- return "Unknown credit"
- unless my $cust_credit =
- qsearchs( 'cust_credit', { 'crednum' => $self->crednum } );
-
- return "Unknown invoice"
- unless my $cust_bill =
- qsearchs( 'cust_bill', { 'invnum' => $self->invnum } );
-
$self->_date(time) unless $self->_date;
return "Cannot apply more than remaining value of credit"
- unless $self->amount <= $cust_credit->credited;
+ unless $self->amount <= $self->cust_credit->credited;
return "Cannot apply more than remaining value of invoice"
- unless $self->amount <= $cust_bill->owed;
+ unless $self->amount <= $self->cust_bill->owed;
$self->SUPER::check;
}
@@ -149,26 +147,17 @@
qsearchs( 'cust_credit', { 'crednum' => $self->crednum } );
}
-=item cust_bill
-
-Returns the invoice (see L<FS::cust_bill>)
-
-=cut
-
-sub cust_bill {
- my $self = shift;
- qsearchs( 'cust_bill', { 'invnum' => $self->invnum } );
-}
-
=back
=head1 BUGS
The delete method.
+This probably should have been called cust_bill_credit.
+
=head1 SEE ALSO
-L<FS::Record>, L<FS::cust_refund>, L<FS::cust_bill>, L<FS::cust_credit>,
+L<FS::Record>, L<FS::cust_bill>, L<FS::cust_credit>,
schema.html from the base documentation.
=cut
--- NEW FILE: cust_bill_ApplicationCommon.pm ---
package FS::cust_bill_ApplicationCommon;
use strict;
use vars qw( @ISA $DEBUG );
use FS::Schema qw( dbdef );
use FS::Record qw( qsearch qsearchs dbh );
@ISA = qw( FS::Record );
$DEBUG = 1;
=head1 NAME
FS::cust_bill_ApplicationCommon - Base class for bill application classes
=head1 SYNOPSIS
use FS::cust_bill_ApplicationCommon;
@ISA = qw( FS::cust_bill_ApplicationCommon );
sub _app_source_name { 'payment'; }
sub _app_source_table { 'cust_pay'; }
sub _app_lineitem_breakdown_table { 'cust_bill_pay_pkg'; }
=head1 DESCRIPTION
FS::cust_bill_ApplicationCommon is intended as a base class for classes which
represent application of things to invoices, currently payments
(see L<FS::cust_bill_pay>) or credits (see L<FS::cust_credit_bill>).
=head1 METHODS
=item insert
=cut
sub insert {
my $self = shift;
local $SIG{HUP} = 'IGNORE';
local $SIG{INT} = 'IGNORE';
local $SIG{QUIT} = 'IGNORE';
local $SIG{TERM} = 'IGNORE';
local $SIG{TSTP} = 'IGNORE';
local $SIG{PIPE} = 'IGNORE';
my $oldAutoCommit = $FS::UID::AutoCommit;
local $FS::UID::AutoCommit = 0;
my $dbh = dbh;
my $error = $self->SUPER::insert(@_)
|| $self->apply_to_lineitems;
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
return $error;
}
$dbh->commit or die $dbh->errstr if $oldAutoCommit;
'';
}
=item delete
=cut
sub delete {
my $self = shift;
local $SIG{HUP} = 'IGNORE';
local $SIG{INT} = 'IGNORE';
local $SIG{QUIT} = 'IGNORE';
local $SIG{TERM} = 'IGNORE';
local $SIG{TSTP} = 'IGNORE';
local $SIG{PIPE} = 'IGNORE';
my $oldAutoCommit = $FS::UID::AutoCommit;
local $FS::UID::AutoCommit = 0;
my $dbh = dbh;
foreach my $app ( $self->lineitem_applications ) {
my $error = $app->delete;
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
return $error;
}
}
my $error = $self->SUPER::delete(@_);
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
return $error;
}
$dbh->commit or die $dbh->errstr if $oldAutoCommit;
'';
}
=item apply_to_lineitems
Auto-applies this invoice application to specific line items, if possible.
=cut
sub apply_to_lineitems {
my $self = shift;
my @apply = ();
local $SIG{HUP} = 'IGNORE';
local $SIG{INT} = 'IGNORE';
local $SIG{QUIT} = 'IGNORE';
local $SIG{TERM} = 'IGNORE';
local $SIG{TSTP} = 'IGNORE';
local $SIG{PIPE} = 'IGNORE';
my $oldAutoCommit = $FS::UID::AutoCommit;
local $FS::UID::AutoCommit = 0;
my $dbh = dbh;
my @open = $self->cust_bill->open_cust_bill_pkg; #FOR UPDATE...?
warn scalar(@open). " open line items for invoice ".
$self->cust_bill->invnum. "\n"
if $DEBUG;
my $total = 0;
$total += $_->setup + $_->recur foreach @open;
$total = sprintf('%.2f', $total);
if ( $self->amount > $total ) {
dbh->rollback if $oldAutoCommit;
return "Can't apply a ". $self->_app_source_name. ' of $'. $self->amount.
" greater than the remaining owed on line items (\$$total)";
}
#easy cases:
# - one lineitem (a simple special case of:)
# - amount is for whole invoice (well, all of remaining lineitem links)
if ( $self->amount == $total ) {
#@apply = map { [ $_, $_->amount ]; } @open;
@apply = map { [ $_, $_->setup || $_->recur ]; } @open;
} else {
#slightly magic case:
# - amount exactly and uniquely matches a single open lineitem
# (you must be trying to pay or credit that item, then)
my @same = grep { $_->setup == $self->amount
|| $_->recur == $self->amount
}
@open;
@apply = map { [ $_, $self->amount ]; } @same
if scalar(@same) == 1;
}
#and the rest:
# - leave unapplied, for now
# - eventually, auto-apply? sequentially? pro-rated against total remaining?
# do the applicaiton(s)
my $table = $self->lineitem_breakdown_table;
my $source_key = dbdef->table($self->table)->primary_key;
foreach my $apply ( @apply ) {
my ( $cust_bill_pkg, $amount ) = @$apply;
my $application = "FS::$table"->new( {
$source_key => $self->$source_key(),
'billpkgnum' => $cust_bill_pkg->billpkgnum,
'amount' => $amount,
'setuprecur' => ( $cust_bill_pkg->setup > 0 ? 'setup' : 'recur' ),
});
my $error = $application->insert;
if ( $error ) {
dbh->rollbck if $oldAutoCommit;
return $error;
}
}
'';
}
=item lineitem_applications
Returns all the specific line item applications for this invoice application.
=cut
sub lineitem_applications {
my $self = shift;
my $primary_key = dbdef->table($self->table)->primary_key;
qsearchs({
'table' => $self->lineitem_breakdown_table,
'hashref' => { $primary_key => $self->$primary_key() },
});
}
=item cust_bill
Returns the invoice (see L<FS::cust_bill>)
=cut
sub cust_bill {
my $self = shift;
qsearchs( 'cust_bill', { 'invnum' => $self->invnum } );
}
=item lineitem_breakdown_table
=cut
sub lineitem_breakdown_table {
my $self = shift;
$self->_load_table($self->_app_lineitem_breakdown_table);
}
sub _load_table {
my( $self, $table ) = @_;
eval "use FS::$table";
die $@ if $@;
$table;
}
=back
=head1 BUGS
=head1 SEE ALSO
L<FS::cust_bill_pay> and L<FS::cust_bill_pay_pkg>,
L<FS::cust_credit_bill> and L<FS::cust_credit_bill_pkg>
=cut
1;
Index: cust_bill.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_bill.pm,v
retrieving revision 1.150
retrieving revision 1.151
diff -u -d -r1.150 -r1.151
--- cust_bill.pm 9 Aug 2006 06:43:01 -0000 1.150
+++ cust_bill.pm 21 Aug 2006 23:01:43 -0000 1.151
@@ -225,6 +225,33 @@
qsearch( 'cust_bill_pkg', { 'invnum' => $self->invnum } );
}
+=item open_cust_bill_pkg
+
+Returns the open line items for this invoice.
+
+Note that cust_bill_pkg with both setup and recur fees are returned as two
+separate line items, each with only one fee.
+
+=cut
+
+# modeled after cust_main::open_cust_bill
+sub open_cust_bill_pkg {
+ my $self = shift;
+
+ # grep { $_->owed > 0 } $self->cust_bill_pkg
+
+ my %other = ( 'recur' => 'setup',
+ 'setup' => 'recur', );
+ my @open = ();
+ foreach my $field ( qw( recur setup )) {
+ push @open, map { $_->set( $other{$field}, 0 ); $_; }
+ grep { $_->owed($field) > 0 }
+ $self->cust_bill_pkg;
+ }
+
+ @open;
+}
+
=item cust_bill_event
Returns the completed invoice events (see L<FS::cust_bill_event>) for this
Index: Schema.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/Schema.pm,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- Schema.pm 10 Aug 2006 13:50:44 -0000 1.23
+++ Schema.pm 21 Aug 2006 23:01:43 -0000 1.24
@@ -390,6 +390,19 @@
'index' => [ ['crednum'], ['invnum'] ],
},
+ 'cust_credit_bill_pkg' => {
+ 'columns' => [
+ 'creditbillpkgnum', 'serial', '', '', '', '',
+ 'creditbillnum', 'int', '', '', '', '',
+ 'billpkgnum', 'int', '', '', '', '',
+ 'amount', @money_type, '', '',
+ 'setuprecur', 'varchar', '', $char_d, '', '',
+ ],
+ 'primary_key' => 'creditbillpkgnum',
+ 'unique' => [],
+ 'index' => [ [ 'creditbillnum' ], [ 'billpkgnum' ], ],
+ },
+
'cust_main' => {
'columns' => [
'custnum', 'serial', '', '', '', '',
@@ -540,6 +553,19 @@
'index' => [ [ 'paynum' ], [ 'invnum' ] ],
},
+ 'cust_bill_pay_pkg' => {
+ 'columns' => [
+ 'billpaypkgnum', 'serial', '', '', '', '',
+ 'billpaynum', 'int', '', '', '', '',
+ 'billpkgnum', 'int', '', '', '', '',
+ 'amount', @money_type, '', '',
+ 'setuprecur', 'varchar', '', $char_d, '', '',
+ ],
+ 'primary_key' => 'billpaypkgnum',
+ 'unique' => [],
+ 'index' => [ [ 'billpaynum' ], [ 'billpkgnum' ], ],
+ },
+
'pay_batch' => { #batches of payments to an external processor
'columns' => [
'batchnum', 'serial', '', '', '', '',
Index: cust_bill_pkg.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_bill_pkg.pm,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- cust_bill_pkg.pm 22 Dec 2005 04:01:17 -0000 1.10
+++ cust_bill_pkg.pm 21 Aug 2006 23:01:43 -0000 1.11
@@ -7,6 +7,8 @@
use FS::cust_pkg;
use FS::cust_bill;
use FS::cust_bill_pkg_detail;
+use FS::cust_bill_pay_pkg;
+use FS::cust_credit_bill_pkg;
@ISA = qw( FS::cust_main_Mixin FS::Record );
@@ -224,18 +226,78 @@
}
}
-=back
+=item owed_setup
-=head1 CLASS METHODS
+Returns the amount owed (still outstanding) on this line item's setup fee,
+which is the amount of the line item minus all payment applications (see
+L<FS::cust_bill_pay_pkg> and credit applications (see
+L<FS::cust_credit_bill_pkg>).
-=over 4
+=cut
-=item
+sub owed_setup {
+ my $self = shift;
+ $self->owed('setup', @_);
+}
+
+=item owed_recur
+
+Returns the amount owed (still outstanding) on this line item's recurring fee,
+which is the amount of the line item minus all payment applications (see
+L<FS::cust_bill_pay_pkg> and credit applications (see
+L<FS::cust_credit_bill_pkg>).
+
+=cut
+
+sub owed_recur {
+ my $self = shift;
+ $self->owed('recur', @_);
+}
+
+# modeled after cust_bill::owed...
+sub owed {
+ my( $self, $field ) = @_;
+ my $balance = $self->$field();
+ $balance -= $_->amount foreach ( $self->cust_bill_pay_pkg($field) );
+ $balance -= $_->amount foreach ( $self->cust_credit_bill_pkg($field) );
+ $balance = sprintf( '%.2f', $balance );
+ $balance =~ s/^\-0\.00$/0.00/; #yay ieee fp
+ $balance;
+}
+
+sub cust_bill_pay_pkg {
+ my( $self, $field ) = @_;
+ qsearch( 'cust_bill_pay_pkg', { 'billpkgnum' => $self->billpkgnum,
+ 'setuprecur' => $field,
+ }
+ );
+}
+
+sub cust_credit_bill_pkg {
+ my( $self, $field ) = @_;
+ qsearch( 'cust_credit_bill_pkg', { 'billpkgnum' => $self->billpkgnum,
+ 'setuprecur' => $field,
+ }
+ );
+}
=back
=head1 BUGS
+setup and recur shouldn't be separate fields. There should be one "amount"
+field and a flag to tell you if it is a setup/one-time fee or a recurring fee.
+
+A line item with both should really be two separate records (preserving
+sdate and edate for setup fees for recurring packages - that information may
+be valuable later). Invoice generation (cust_main::bill), invoice printing
+(cust_bill), tax reports (report_tax.cgi) and line item reports
+(cust_bill_pkg.cgi) would need to be updated.
+
+owed_setup and owed_recur could then be repaced by just owed, and
+cust_bill::open_cust_bill_pkg and
+cust_bill_ApplicationCommon::apply_to_lineitems could be simplified.
+
=head1 SEE ALSO
L<FS::Record>, L<FS::cust_bill>, L<FS::cust_pkg>, L<FS::cust_main>, schema.html
Index: cust_bill_pay.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_bill_pay.pm,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- cust_bill_pay.pm 30 Jun 2004 17:57:03 -0000 1.16
+++ cust_bill_pay.pm 21 Aug 2006 23:01:43 -0000 1.17
@@ -2,11 +2,12 @@
use strict;
use vars qw( @ISA $conf );
-use FS::Record qw( qsearch qsearchs dbh );
+use FS::Record qw( qsearchs );
+use FS::cust_bill_ApplicationCommon;
use FS::cust_bill;
use FS::cust_pay;
- at ISA = qw( FS::Record );
+ at ISA = qw( FS::cust_bill_ApplicationCommon );
#ask FS::UID to run this stuff for us later
FS::UID->install_callback( sub {
@@ -35,8 +36,9 @@
=head1 DESCRIPTION
An FS::cust_bill_pay object represents the application of a payment to a
-specific invoice. FS::cust_bill_pay inherits from FS::Record. The following
-fields are currently supported:
+specific invoice. FS::cust_bill_pay inherits from
+FS::cust_bill_ApplicationCommon and FS::Record. The following fields are
+currently supported:
=over 4
@@ -65,6 +67,10 @@
sub table { 'cust_bill_pay'; }
+sub _app_source_name { 'payment'; }
+sub _app_source_table { 'cust_pay'; }
+sub _app_lineitem_breakdown_table { 'cust_bill_pay_pkg'; }
+
=item insert
Adds this record to the database. If there is an error, returns the error,
@@ -81,6 +87,8 @@
my $self = shift;
return "Can't delete application for closed payment"
if $self->cust_pay->closed =~ /^Y/i;
+ return "Can't delete application for closed invoice"
+ if $self->cust_bill->closed =~ /^Y/i;
$self->SUPER::delete(@_);
}
@@ -91,13 +99,14 @@
=cut
sub replace {
- return "Can't (yet?) modify cust_bill_pay records!";
+ return "Can't modify application of payment!";
}
=item check
-Checks all fields to make sure this is a valid payment. If there is an error,
-returns the error, otherwise returns false. Called by the insert method.
+Checks all fields to make sure this is a valid payment application. If there
+is an error, returns the error, otherwise returns false. Called by the insert
+method.
=cut
@@ -106,30 +115,22 @@
my $error =
$self->ut_numbern('billpaynum')
- || $self->ut_number('invnum')
- || $self->ut_number('paynum')
- || $self->ut_money('amount')
+ || $self->ut_foreign_key('paynum', 'cust_pay', 'paynum' )
+ || $self->ut_foreign_key('invnum', 'cust_bill', 'invnum' )
|| $self->ut_numbern('_date')
+ || $self->ut_money('amount')
;
return $error if $error;
return "amount must be > 0" if $self->amount <= 0;
- return "Unknown invoice"
- unless my $cust_bill =
- qsearchs( 'cust_bill', { 'invnum' => $self->invnum } );
-
- return "Unknown payment"
- unless my $cust_pay =
- qsearchs( 'cust_pay', { 'paynum' => $self->paynum } );
-
$self->_date(time) unless $self->_date;
return "Cannot apply more than remaining value of invoice"
- unless $self->amount <= $cust_bill->owed;
+ unless $self->amount <= $self->cust_bill->owed;
return "Cannot apply more than remaining value of payment"
- unless $self->amount <= $cust_pay->unapplied;
+ unless $self->amount <= $self->cust_pay->unapplied;
$self->SUPER::check;
}
@@ -145,26 +146,12 @@
qsearchs( 'cust_pay', { 'paynum' => $self->paynum } );
}
-=item cust_bill
-
-Returns the invoice (see L<FS::cust_bill>)
-
-=cut
-
-sub cust_bill {
- my $self = shift;
- qsearchs( 'cust_bill', { 'invnum' => $self->invnum } );
-}
-
=back
=head1 BUGS
Delete and replace methods.
-the checks for over-applied payments could be better done like the ones in
-cust_bill_credit
-
=head1 SEE ALSO
L<FS::cust_pay>, L<FS::cust_bill>, L<FS::Record>, schema.html from the
More information about the freeside-commits
mailing list