[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