From: ivan Date: Mon, 21 Aug 2006 23:01:43 +0000 (+0000) Subject: add cust_bill_pay_pkg and cust_credit_bill_pkg - applying credits and payments agains... X-Git-Tag: BEFORE_FINAL_MASONIZE~7 X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=commitdiff_plain;h=4845aaefedfcbaa25716694b6d80f3dd6d56530a add cust_bill_pay_pkg and cust_credit_bill_pkg - applying credits and payments against specific line items --- diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index ce2d79067..b3d8a56f1 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -390,6 +390,19 @@ sub tables_hashref { '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 @@ sub tables_hashref { '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', '', '', '', '', diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index d45b66faf..a93d175e8 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -225,6 +225,33 @@ sub cust_bill_pkg { 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) for this diff --git a/FS/FS/cust_bill_ApplicationCommon.pm b/FS/FS/cust_bill_ApplicationCommon.pm new file mode 100644 index 000000000..fb06a4b1f --- /dev/null +++ b/FS/FS/cust_bill_ApplicationCommon.pm @@ -0,0 +1,243 @@ +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) or credits (see L). + +=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) + +=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 and L, +L and L + +=cut + +1; + diff --git a/FS/FS/cust_bill_pay.pm b/FS/FS/cust_bill_pay.pm index 7abbe9a3b..67f8eaf83 100644 --- a/FS/FS/cust_bill_pay.pm +++ b/FS/FS/cust_bill_pay.pm @@ -2,11 +2,12 @@ package FS::cust_bill_pay; 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; -@ISA = qw( FS::Record ); +@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 @@ FS::cust_bill_pay - Object methods for cust_bill_pay records =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 @@ Creates a new record. To add the record to the database, see L<"insert">. 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 @@ sub delete { 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 @@ Currently unimplemented (accounting reasons). =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 @@ sub check { 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 @@ sub cust_pay { qsearchs( 'cust_pay', { 'paynum' => $self->paynum } ); } -=item cust_bill - -Returns the invoice (see L) - -=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, L, L, schema.html from the diff --git a/FS/FS/cust_bill_pay_pkg.pm b/FS/FS/cust_bill_pay_pkg.pm new file mode 100644 index 000000000..af331cd6f --- /dev/null +++ b/FS/FS/cust_bill_pay_pkg.pm @@ -0,0 +1,132 @@ +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) to a specific line item within an invoice (see +L). 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) + +=item billpkgnum - Line item to which payment is applied (see L) + +=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 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 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, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/FS/cust_bill_pkg.pm b/FS/FS/cust_bill_pkg.pm index d718b05fd..e41a3c58c 100644 --- a/FS/FS/cust_bill_pkg.pm +++ b/FS/FS/cust_bill_pkg.pm @@ -7,6 +7,8 @@ use FS::cust_main_Mixin; 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 @@ sub desc { } } -=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 and credit applications (see +L). -=over 4 +=cut + +sub owed_setup { + my $self = shift; + $self->owed('setup', @_); +} -=item +=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 and credit applications (see +L). + +=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, L, L, L, schema.html diff --git a/FS/FS/cust_credit_bill.pm b/FS/FS/cust_credit_bill.pm index 695df6e8d..c015ec15b 100644 --- a/FS/FS/cust_credit_bill.pm +++ b/FS/FS/cust_credit_bill.pm @@ -4,12 +4,11 @@ use strict; 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; -@ISA = qw( FS::Record ); +@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 @@ FS::cust_credit_bill - Object methods for cust_credit_bill records An FS::cust_credit_bill object represents application of a credit (see L) to an invoice (see L). 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 @@ see L<"insert">. 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 @@ sub delete { 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 @@ sub check { 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 @@ sub check { 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 @@ sub cust_credit { qsearchs( 'cust_credit', { 'crednum' => $self->crednum } ); } -=item cust_bill - -Returns the invoice (see L) - -=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, L, L, L, +L, L, L, schema.html from the base documentation. =cut diff --git a/FS/FS/cust_credit_bill_pkg.pm b/FS/FS/cust_credit_bill_pkg.pm new file mode 100644 index 000000000..98521d611 --- /dev/null +++ b/FS/FS/cust_credit_bill_pkg.pm @@ -0,0 +1,132 @@ +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) to a specific line item within an invoice +(see L). 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) + +=item billpkgnum - Line item to which credit is applied (see L) + +=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 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 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, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/MANIFEST b/FS/MANIFEST index 42b616575..10f9ffa22 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -350,3 +350,7 @@ FS/CurrentUser.pm FS/svc_phone.pm t/svc_phone.t FS/h_svc_phone.pm +FS/cust_bill_pay_pkg.pm +t/cust_bill_pay_pkg.t +FS/cust_credit_bill_pkg.pm +t/cust_credit_bill_pkg.t diff --git a/FS/t/cust_bill_ApplicationCommon.t b/FS/t/cust_bill_ApplicationCommon.t new file mode 100644 index 000000000..fa03d3420 --- /dev/null +++ b/FS/t/cust_bill_ApplicationCommon.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::cust_bill_ApplicationCommon; +$loaded=1; +print "ok 1\n"; diff --git a/FS/t/cust_bill_pay_pkg.t b/FS/t/cust_bill_pay_pkg.t new file mode 100644 index 000000000..b8fcddb41 --- /dev/null +++ b/FS/t/cust_bill_pay_pkg.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::cust_bill_pay_pkg; +$loaded=1; +print "ok 1\n"; diff --git a/FS/t/cust_credit_bill_pkg.t b/FS/t/cust_credit_bill_pkg.t new file mode 100644 index 000000000..4eb84c327 --- /dev/null +++ b/FS/t/cust_credit_bill_pkg.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::cust_credit_bill_pkg; +$loaded=1; +print "ok 1\n";