[freeside-commits] freeside/FS/FS Conf.pm, 1.311, 1.312 cust_pay.pm, 1.73, 1.74 cust_main.pm, 1.454, 1.455 cust_bill.pm, 1.253, 1.254 cust_bill_ApplicationCommon.pm, 1.12, 1.13 cust_bill_pay.pm, 1.20, 1.21 cust_bill_pay_pkg.pm, 1.2, 1.3

Ivan,,, ivan at wavetail.420.am
Sun Sep 20 19:41:45 PDT 2009


Update of /home/cvs/cvsroot/freeside/FS/FS
In directory wavetail.420.am:/tmp/cvs-serv21901/FS/FS

Modified Files:
	Conf.pm cust_pay.pm cust_main.pm cust_bill.pm 
	cust_bill_ApplicationCommon.pm cust_bill_pay.pm 
	cust_bill_pay_pkg.pm 
Log Message:
add ability to trigger receipts when payment is used against a specific package instead of when it was made, RT#5199

Index: cust_pay.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_pay.pm,v
retrieving revision 1.73
retrieving revision 1.74
diff -u -d -r1.73 -r1.74
--- cust_pay.pm	30 Jul 2009 06:42:31 -0000	1.73
+++ cust_pay.pm	21 Sep 2009 02:41:43 -0000	1.74
@@ -132,21 +132,22 @@
   ' (cust_pay.paynum '. $self->paynum. ')';
 }
 
-=item insert
+=item insert [ OPTION => VALUE ... ]
 
 Adds this payment to the database.
 
 For backwards-compatibility and convenience, if the additional field invnum
 is defined, an FS::cust_bill_pay record for the full amount of the payment
-will be created.  In this case, custnum is optional.  An hash of optional
-arguments may be passed.  Currently "manual" is supported.  If true, a
-payment receipt is sent instead of a statement when 'payment_receipt_email'
-configuration option is set.
+will be created.  In this case, custnum is optional.
+
+A hash of optional arguments may be passed.  Currently "manual" is supported.
+If true, a payment receipt is sent instead of a statement when
+'payment_receipt_email' configuration option is set.
 
 =cut
 
 sub insert {
-  my ($self, %options) = @_;
+  my($self, %options) = @_;
 
   local $SIG{HUP} = 'IGNORE';
   local $SIG{INT} = 'IGNORE';
@@ -169,7 +170,6 @@
     $self->custnum($cust_bill->custnum );
   }
 
-
   my $error = $self->check;
   return $error if $error;
 
@@ -189,7 +189,7 @@
       'amount' => $self->paid,
       '_date'  => $self->_date,
     };
-    $error = $cust_bill_pay->insert;
+    $error = $cust_bill_pay->insert(%options);
     if ( $error ) {
       if ( $ignore_noapply ) {
         warn "warning: error inserting $cust_bill_pay: $error ".
@@ -216,74 +216,15 @@
 
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
 
-  #my $cust_main = $self->cust_main;
-  if ( $conf->exists('payment_receipt_email')
-       && grep { $_ !~ /^(POST|FAX)$/ } $cust_main->invoicing_list
-  ) {
-
-    $cust_bill ||= ($cust_main->cust_bill)[-1]; #rather inefficient though?
-
-    my $error;
-    if (    ( exists($options{'manual'}) && $options{'manual'} )
-         || ! $conf->exists('invoice_html_statement')
-         || ! $cust_bill
-       ) {
-
-      my $receipt_template = new Text::Template (
-        TYPE   => 'ARRAY',
-        SOURCE => [ map "$_\n", $conf->config('payment_receipt_email') ],
-      ) or do {
-        warn "can't create payment receipt template: $Text::Template::ERROR";
-        return '';
-      };
-
-      my @invoicing_list = grep { $_ !~ /^(POST|FAX)$/ }
-                             $cust_main->invoicing_list;
-
-      my $payby = $self->payby;
-      my $payinfo = $self->payinfo;
-      $payby =~ s/^BILL$/Check/ if $payinfo;
-      if ( $payby eq 'CARD' || $payby eq 'CHEK' ) {
-        $payinfo = $self->paymask
-      } else {
-        $payinfo = $self->decrypt($payinfo);
-      }
-      $payby =~ s/^CHEK$/Electronic check/;
-
-      $error = send_email(
-        'from'    => $conf->config('invoice_from', $cust_main->agentnum),
-                                   #invoice_from??? well as good as any
-        'to'      => \@invoicing_list,
-        'subject' => 'Payment receipt',
-        'body'    => [ $receipt_template->fill_in( HASH => {
-                       'date'         => time2str("%a %B %o, %Y", $self->_date),
-                       'name'         => $cust_main->name,
-                       'paynum'       => $self->paynum,
-                       'paid'         => sprintf("%.2f", $self->paid),
-                       'payby'        => ucfirst(lc($payby)),
-                       'payinfo'      => $payinfo,
-                       'balance'      => $cust_main->balance,
-                       'company_name' => $conf->config('company_name'),
-                     } ) ],
-      );
-
-    } else {
-
-      my $queue = new FS::queue {
-         'paynum' => $self->paynum,
-         'job'    => 'FS::cust_bill::queueable_email',
-      };
-      $error = $queue->insert(
-        'invnum' => $cust_bill->invnum,
-        'template' => 'statement',
-      );
-
-    }
-
-    if ( $error ) {
-      warn "can't send payment receipt/statement: $error";
-    }
-
+  #payment receipt
+  my $trigger = $conf->config('payment_receipt-trigger') || 'cust_pay';
+  if ( $trigger eq 'cust_pay' ) {
+    my $error = $self->send_receipt(
+      'manual'    => $options{'manual'},
+      'cust_bill' => $cust_bill,
+      'cust_main' => $cust_main,
+    );
+    warn "can't send payment receipt/statement: $error" if $error;
   }
 
   '';
@@ -471,58 +412,109 @@
   $self->SUPER::check;
 }
 
-=item batch_insert CUST_PAY_OBJECT, ...
+=item send_receipt HASHREF | OPTION => VALUE ...
 
-Class method which inserts multiple payments.  Takes a list of FS::cust_pay
-objects.  Returns a list, each element representing the status of inserting the
-corresponding payment - empty.  If there is an error inserting any payment, the
-entire transaction is rolled back, i.e. all payments are inserted or none are.
+Sends a payment receipt for this payment..
 
-For example:
+Available options:
 
-  my @errors = FS::cust_pay->batch_insert(@cust_pay);
-  my $num_errors = scalar(grep $_, @errors);
-  if ( $num_errors == 0 ) {
-    #success; all payments were inserted
-  } else {
-    #failure; no payments were inserted.
-  }
+=over 4
+
+=item manual
+
+Flag indicating the payment is being made manually.
+
+=item cust_bill
+
+Invoice (FS::cust_bill) object.  If not specified, the most recent invoice
+will be assumed.
+
+=item cust_main
+
+Customer (FS::cust_main) object (for efficiency).
+
+=back
 
 =cut
 
-sub batch_insert {
-  my $self = shift; #class method
+sub send_receipt {
+  my $self = shift;
+  my $opt = ref($_[0]) ? 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 $cust_bill = $opt->{'cust_bill'};
+  my $cust_main = $opt->{'cust_main'} || $self->cust_main;
 
-  my $oldAutoCommit = $FS::UID::AutoCommit;
-  local $FS::UID::AutoCommit = 0;
-  my $dbh = dbh;
+  my $conf = new FS::Conf;
 
-  my $errors = 0;
-  
-  my @errors = map {
-    my $error = $_->insert( 'manual' => 1 );
-    if ( $error ) { 
-      $errors++;
+  return ''
+    unless $conf->exists('payment_receipt_email')
+        && grep { $_ !~ /^(POST|FAX)$/ } $cust_main->invoicing_list;
+
+  $cust_bill ||= ($cust_main->cust_bill)[-1]; #rather inefficient though?
+
+  if (    ( exists($opt->{'manual'}) && $opt->{'manual'} )
+       || ! $conf->exists('invoice_html_statement')
+       || ! $cust_bill
+     ) {
+
+    my $receipt_template = new Text::Template (
+      TYPE   => 'ARRAY',
+      SOURCE => [ map "$_\n", $conf->config('payment_receipt_email') ],
+    ) or do {
+      warn "can't create payment receipt template: $Text::Template::ERROR";
+      return '';
+    };
+
+    my @invoicing_list = grep { $_ !~ /^(POST|FAX)$/ }
+                           $cust_main->invoicing_list;
+
+    my $payby = $self->payby;
+    my $payinfo = $self->payinfo;
+    $payby =~ s/^BILL$/Check/ if $payinfo;
+    if ( $payby eq 'CARD' || $payby eq 'CHEK' ) {
+      $payinfo = $self->paymask
     } else {
-      $_->cust_main->apply_payments;
+      $payinfo = $self->decrypt($payinfo);
     }
-    $error;
-  } @_;
+    $payby =~ s/^CHEK$/Electronic check/;
+
+    my %fill_in = (
+      'date'         => time2str("%a %B %o, %Y", $self->_date),
+      'name'         => $cust_main->name,
+      'paynum'       => $self->paynum,
+      'paid'         => sprintf("%.2f", $self->paid),
+      'payby'        => ucfirst(lc($payby)),
+      'payinfo'      => $payinfo,
+      'balance'      => $cust_main->balance,
+      'company_name' => $conf->config('company_name', $cust_main->agentnum),
+    );
+
+    if ( $opt->{'cust_pkg'} ) {
+      $fill_in{'pkg'} = $opt->{'cust_pkg'}->part_pkg->pkg;
+      #setup date, other things?
+    }
+
+    send_email(
+      'from'    => $conf->config('invoice_from', $cust_main->agentnum),
+                                 #invoice_from??? well as good as any
+      'to'      => \@invoicing_list,
+      'subject' => 'Payment receipt',
+      'body'    => [ $receipt_template->fill_in( HASH => \%fill_in ) ],
+    );
 
-  if ( $errors ) {
-    $dbh->rollback if $oldAutoCommit;
   } else {
-    $dbh->commit or die $dbh->errstr if $oldAutoCommit;
-  }
 
-  @errors;
+    my $queue = new FS::queue {
+       'paynum' => $self->paynum,
+       'job'    => 'FS::cust_bill::queueable_email',
+    };
+
+    $queue->insert(
+      'invnum'   => $cust_bill->invnum,
+      'template' => 'statement',
+    );
+
+  }
 
 }
 
@@ -603,6 +595,61 @@
 
 =over 4
 
+=item batch_insert CUST_PAY_OBJECT, ...
+
+Class method which inserts multiple payments.  Takes a list of FS::cust_pay
+objects.  Returns a list, each element representing the status of inserting the
+corresponding payment - empty.  If there is an error inserting any payment, the
+entire transaction is rolled back, i.e. all payments are inserted or none are.
+
+For example:
+
+  my @errors = FS::cust_pay->batch_insert(@cust_pay);
+  my $num_errors = scalar(grep $_, @errors);
+  if ( $num_errors == 0 ) {
+    #success; all payments were inserted
+  } else {
+    #failure; no payments were inserted.
+  }
+
+=cut
+
+sub batch_insert {
+  my $self = shift; #class method
+
+  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 $errors = 0;
+  
+  my @errors = map {
+    my $error = $_->insert( 'manual' => 1 );
+    if ( $error ) { 
+      $errors++;
+    } else {
+      $_->cust_main->apply_payments;
+    }
+    $error;
+  } @_;
+
+  if ( $errors ) {
+    $dbh->rollback if $oldAutoCommit;
+  } else {
+    $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+  }
+
+  @errors;
+
+}
+
 =item unapplied_sql
 
 Returns an SQL fragment to retreive the unapplied amount.

Index: cust_bill.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_bill.pm,v
retrieving revision 1.253
retrieving revision 1.254
diff -u -d -r1.253 -r1.254
--- cust_bill.pm	17 Sep 2009 23:45:21 -0000	1.253
+++ cust_bill.pm	21 Sep 2009 02:41:43 -0000	1.254
@@ -16,6 +16,7 @@
 use FS::Record qw( qsearch qsearchs dbh );
 use FS::cust_main_Mixin;
 use FS::cust_main;
+use FS::cust_statement;
 use FS::cust_bill_pkg;
 use FS::cust_bill_pkg_display;
 use FS::cust_credit;
@@ -82,6 +83,8 @@
 (see L<FS::cust_bill_pkg>).  FS::cust_bill inherits from FS::Record.  The
 following fields are currently supported:
 
+Regular fields
+
 =over 4
 
 =item invnum - primary key (assigned automatically for new invoices)
@@ -93,10 +96,26 @@
 
 =item charged - amount of this invoice
 
+=back
+
+Deprecated
+
+=over 4
+
 =item printed - deprecated
 
+=back
+
+Specific use cases
+
+=over 4
+
 =item closed - books closed flag, empty or `Y'
 
+=item statementnum - invoice aggregation (see L<FS::cust_statement>)
+
+=item agent_invid - legacy invoice number
+
 =back
 
 =head1 METHODS
@@ -183,17 +202,16 @@
 
   my $error =
     $self->ut_numbern('invnum')
-    || $self->ut_number('custnum')
+    || $self->ut_foreign_key('custnum', 'cust_main', 'custnum' )
     || $self->ut_numbern('_date')
     || $self->ut_money('charged')
     || $self->ut_numbern('printed')
     || $self->ut_enum('closed', [ '', 'Y' ])
+    || $self->ut_foreign_keyn('statementnum', 'cust_statement', 'statementnum' )
+    || $self->ut_numbern('agent_invid') #varchar?
   ;
   return $error if $error;
 
-  return "Unknown customer"
-    unless qsearchs( 'cust_main', { 'custnum' => $self->custnum } );
-
   $self->_date(time) unless $self->_date;
 
   $self->printed(0) if $self->printed eq '';
@@ -201,6 +219,22 @@
   $self->SUPER::check;
 }
 
+=item display_invnum
+
+Returns the displayed invoice number for this invoice: agent_invid if
+cust_bill-default_agent_invid is set and it has a value, invnum otherwise.
+
+=cut
+
+sub display_invnum {
+  my $self = shift;
+  if ( $conf->exists('cust_bill-default_agent_invid') && $self->agent_invid ){
+    return $self->agent_invid;
+  } else {
+    return $self->invnum;
+  }
+}
+
 =item previous
 
 Returns a list consisting of the total previous balance for this customer, 
@@ -531,12 +565,20 @@
   $balance;
 }
 
-=item apply_payments_and_credits
+=item apply_payments_and_credits [ OPTION => VALUE ... ]
+
+Applies unapplied payments and credits to this invoice.
+
+A hash of optional arguments may be passed.  Currently "manual" is supported.
+If true, a payment receipt is sent instead of a statement when
+'payment_receipt_email' configuration option is set.
+
+If there is an error, returns the error, otherwise returns false.
 
 =cut
 
 sub apply_payments_and_credits {
-  my $self = shift;
+  my( $self, %options ) = @_;
 
   local $SIG{HUP} = 'IGNORE';
   local $SIG{INT} = 'IGNORE';
@@ -633,7 +675,7 @@
 
     $app->invnum( $self->invnum );
 
-    my $error = $app->insert;
+    my $error = $app->insert(%options);
     if ( $error ) {
       $dbh->rollback if $oldAutoCommit;
       return "Error inserting ". $app->table. " record: $error";

Index: cust_bill_pay_pkg.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_bill_pay_pkg.pm,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- cust_bill_pay_pkg.pm	15 Sep 2006 05:10:36 -0000	1.2
+++ cust_bill_pay_pkg.pm	21 Sep 2009 02:41:43 -0000	1.3
@@ -2,7 +2,10 @@
 
 use strict;
 use vars qw( @ISA );
+use FS::Conf;
 use FS::Record qw( qsearch qsearchs );
+use FS::cust_bill_pay;
+use FS::cust_bill_pkg;
 
 @ISA = qw(FS::Record);
 
@@ -77,7 +80,39 @@
 
 =cut
 
-# the insert method can be inherited from FS::Record
+sub insert {
+  my($self, %options) = @_;
+
+  #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;
+  if ( $error ) {
+    #$dbh->rollback if $oldAutoCommit;
+    return "error inserting $self: $error";
+  }
+
+  #payment receipt
+  my $conf = new FS::Conf;
+  my $trigger = $conf->config('payment_receipt-trigger') || 'cust_pay';
+  if ( $trigger eq 'cust_bill_pay_pkg' ) {
+    my $error = $self->send_receipt(
+      'manual'    => $options{'manual'},
+    );
+    warn "can't send payment receipt/statement: $error" if $error;
+  }
+
+  '';
+
+}
 
 =item delete
 
@@ -124,6 +159,47 @@
   $self->SUPER::check;
 }
 
+=item cust_bill_pay
+
+Returns the FS::cust_bill_pay object (payment application to the overall
+invoice).
+
+=cut
+
+sub cust_bill_pay {
+  my $self = shift;
+  qsearchs('cust_bill_pay', { 'billpaynum' => $self->billpaynum } );
+}
+
+=item cust_bill_pkg
+
+Returns the FS::cust_bill_pkg object (line item to which payment is applied).
+
+=cut
+
+sub cust_bill_pkg {
+  my $self = shift;
+  qsearchs('cust_bill_pkg', { 'billpkgnum' => $self->billpkgnum } );
+}
+
+=item send_receipt
+
+Sends a payment receipt for the associated payment, against this specific
+invoice and packages.  If there is an error, returns the error, otherwise
+returns false.
+
+=cut
+
+sub send_receipt {
+  my $self = shift;
+  my $opt = ref($_[0]) ? shift : { @_ };
+  $self->cust_bill_pay->send_receipt(
+    'cust_pkg' => $self->cust_bill_pkg->cust_pkg,
+    %$opt,
+  );
+}
+
+
 =back
 
 =head1 BUGS

Index: Conf.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/Conf.pm,v
retrieving revision 1.311
retrieving revision 1.312
diff -u -d -r1.311 -r1.312
--- Conf.pm	22 Aug 2009 00:22:08 -0000	1.311
+++ Conf.pm	21 Sep 2009 02:41:42 -0000	1.312
@@ -1015,11 +1015,22 @@
   {
     'key'         => 'payment_receipt_email',
     'section'     => 'billing',
-    'description' => 'Template file for payment receipts.  Payment receipts are sent to the customer email invoice destination(s) when a payment is received.  See the <a href="http://search.cpan.org/dist/Text-Template/lib/Text/Template.pm">Text::Template</a> documentation for details on the template substitution language.  The following variables are available: <ul><li><code>$date</code> <li><code>$name</code> <li><code>$paynum</code> - Freeside payment number <li><code>$paid</code> - Amount of payment <li><code>$payby</code> - Payment type (Card, Check, Electronic check, etc.) <li><code>$payinfo</code> - Masked credit card number or check number <li><code>$balance</code> - New balance</ul>',
+    'description' => 'Template file for payment receipts.  Payment receipts are sent to the customer email invoice destination(s) when a payment is received.  See the <a href="http://search.cpan.org/dist/Text-Template/lib/Text/Template.pm">Text::Template</a> documentation for details on the template substitution language.  The following variables are available: <ul><li><code>$date</code> <li><code>$name</code> <li><code>$paynum</code> - Freeside payment number <li><code>$paid</code> - Amount of payment <li><code>$payby</code> - Payment type (Card, Check, Electronic check, etc.) <li><code>$payinfo</code> - Masked credit card number or check number <li><code>$balance</code> - New balance<li><code>$pkg</code> - Package (requires payment_receipt-trigger set to cust_bill_pay_pkg)</ul>',
     'type'        => [qw( checkbox textarea )],
   },
 
   {
+    'key'         => 'payment_receipt-trigger',
+    'section'     => 'billing',
+    'description' => 'When payment receipts are triggered.  Defaults to when payment is made.',
+    'type'        => 'select',
+    'select_hash' => [
+                       'cust_pay'          => 'When payment is made.',
+                       'cust_bill_pay_pkg' => 'When payment is applied.',
+                     ],
+  },
+
+  {
     'key'         => 'lpr',
     'section'     => 'required',
     'description' => 'Print command for paper invoices, for example `lpr -h\'',
@@ -2487,6 +2498,14 @@
   },
 
   {
+    'key'         => 'dashboard-install_welcome',
+    'section'     => 'UI',
+    'description' => 'New install welcome screen.',
+    'type'        => 'select',
+    'select_enum' => [ '', 'ITSP_fsinc_hosted', ],
+  },
+
+  {
     'key'         => 'dashboard-toplist',
     'section'     => 'UI',
     'description' => 'List of items to display on the top of the front page',
@@ -2769,7 +2788,14 @@
   {
     'key'         => 'cust_main-default_agent_custid',
     'section'     => 'UI',
-    'description' => 'Display the agent_custid field instead of the custnum field.',
+    'description' => 'Display the agent_custid field when available instead of the custnum field.',
+    'type'        => 'checkbox',
+  },
+
+  {
+    'key'         => 'cust_bill-default_agent_invid',
+    'section'     => 'UI',
+    'description' => 'Display the agent_invid field when available instead of the invnum field.',
     'type'        => 'checkbox',
   },
 

Index: cust_bill_ApplicationCommon.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_bill_ApplicationCommon.pm,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- cust_bill_ApplicationCommon.pm	24 Aug 2009 06:39:58 -0000	1.12
+++ cust_bill_ApplicationCommon.pm	21 Sep 2009 02:41:43 -0000	1.13
@@ -56,7 +56,7 @@
   my $dbh = dbh;
 
   my $error =    $self->SUPER::insert(@_)
-              || $self->apply_to_lineitems;
+              || $self->apply_to_lineitems(@_);
   if ( $error ) {
     $dbh->rollback if $oldAutoCommit;
     return $error;
@@ -113,7 +113,8 @@
 =cut
 
 sub apply_to_lineitems {
-  my $self = shift;
+  #my $self = shift;
+  my( $self, %options ) = @_;
 
   return '' if $skip_apply_to_lineitems_hack;
 
@@ -322,7 +323,7 @@
       'sdate'      => $cust_bill_pkg->sdate,
       'edate'      => $cust_bill_pkg->edate,
     });
-    my $error = $application->insert;
+    my $error = $application->insert(%options);
     if ( $error ) {
       $dbh->rollback if $oldAutoCommit;
       return $error;

Index: cust_main.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_main.pm,v
retrieving revision 1.454
retrieving revision 1.455
diff -u -d -r1.454 -r1.455
--- cust_main.pm	18 Sep 2009 22:41:25 -0000	1.454
+++ cust_main.pm	21 Sep 2009 02:41:43 -0000	1.455
@@ -6168,19 +6168,23 @@
   '';
 }
 
-=item apply_payments_and_credits
+=item apply_payments_and_credits [ OPTION => VALUE ... ]
 
 Applies unapplied payments and credits.
 
 In most cases, this new method should be used in place of sequential
 apply_payments and apply_credits methods.
 
+A hash of optional arguments may be passed.  Currently "manual" is supported.
+If true, a payment receipt is sent instead of a statement when
+'payment_receipt_email' configuration option is set.
+
 If there is an error, returns the error, otherwise returns false.
 
 =cut
 
 sub apply_payments_and_credits {
-  my $self = shift;
+  my( $self, %options ) = @_;
 
   local $SIG{HUP} = 'IGNORE';
   local $SIG{INT} = 'IGNORE';
@@ -6196,7 +6200,7 @@
   $self->select_for_update; #mutex
 
   foreach my $cust_bill ( $self->open_cust_bill ) {
-    my $error = $cust_bill->apply_payments_and_credits;
+    my $error = $cust_bill->apply_payments_and_credits(%options);
     if ( $error ) {
       $dbh->rollback if $oldAutoCommit;
       return "Error applying: $error";
@@ -6305,19 +6309,24 @@
   return $total_unapplied_credits;
 }
 
-=item apply_payments
+=item apply_payments  [ OPTION => VALUE ... ]
 
 Applies (see L<FS::cust_bill_pay>) unapplied payments (see L<FS::cust_pay>)
 to outstanding invoice balances in chronological order.
 
  #and returns the value of any remaining unapplied payments.
 
+A hash of optional arguments may be passed.  Currently "manual" is supported.
+If true, a payment receipt is sent instead of a statement when
+'payment_receipt_email' configuration option is set.
+
+
 Dies if there is an error.
 
 =cut
 
 sub apply_payments {
-  my $self = shift;
+  my( $self, %options ) = @_;
 
   local $SIG{HUP} = 'IGNORE';
   local $SIG{INT} = 'IGNORE';
@@ -6381,7 +6390,7 @@
     } );
     $cust_bill_pay->pkgnum( $payment->pkgnum )
       if $conf->exists('pkg-balances') && $payment->pkgnum;
-    my $error = $cust_bill_pay->insert;
+    my $error = $cust_bill_pay->insert(%options);
     if ( $error ) {
       $dbh->rollback or die $dbh->errstr if $oldAutoCommit;
       die $error;

Index: cust_bill_pay.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_bill_pay.pm,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- cust_bill_pay.pm	30 Jul 2009 06:42:31 -0000	1.20
+++ cust_bill_pay.pm	21 Sep 2009 02:41:43 -0000	1.21
@@ -150,6 +150,25 @@
   qsearchs( 'cust_pay', { 'paynum' => $self->paynum } );
 }
 
+=item send_receipt HASHREF | OPTION => VALUE ...
+
+
+Sends a payment receipt for the associated payment, against this specific
+invoice.  If there is an error, returns the error, otherwise returns false.
+
+See L<FS::cust_pay/send_receipt>.
+
+=cut
+
+sub send_receipt {
+  my $self = shift;
+  my $opt = ref($_[0]) ? shift : { @_ };
+  $self->cust_pay->send_receipt(
+    'cust_bill' => $self->cust_bill,
+    %$opt,
+  );
+}
+
 =back
 
 =head1 BUGS



More information about the freeside-commits mailing list