[freeside-commits] branch master updated. 4b695753d2456060e6a16808120cbb488a19c584

Jonathan Prykop jonathan at 420.am
Mon Jul 13 16:35:23 PDT 2015


The branch, master has been updated
       via  4b695753d2456060e6a16808120cbb488a19c584 (commit)
      from  2ead33f915536127cd148d4e2ca474b9c45c634b (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 4b695753d2456060e6a16808120cbb488a19c584
Author: Jonathan Prykop <jonathan at freeside.biz>
Date:   Mon Jul 13 18:33:52 2015 -0500

    RT#31594: Unapplied payment issues

diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index 24ca858..eb5f1d3 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -2431,6 +2431,7 @@ sub tables_hashref {
         'payunique',   'varchar', 'NULL', $char_d, '', '',#separate paybatch "unique" functions from current usage
         'closed',         'char', 'NULL',       1, '', '', 
         'pkgnum', 'int', 'NULL', '', '', '', #desired pkgnum for pkg-balances
+        'no_auto_apply',  'char', 'NULL',       1, '', '', 
 
         # cash/check deposit info fields
         'bank',        'varchar', 'NULL', $char_d, '', '',
diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm
index db90930..5052ed1 100644
--- a/FS/FS/cust_bill.pm
+++ b/FS/FS/cust_bill.pm
@@ -888,6 +888,7 @@ sub hide {
 =item apply_payments_and_credits [ OPTION => VALUE ... ]
 
 Applies unapplied payments and credits to this invoice.
+Payments with the no_auto_apply flag set will not be applied.
 
 A hash of optional arguments may be passed.  Currently "manual" is supported.
 If true, a payment receipt is sent instead of a statement when
@@ -914,7 +915,9 @@ sub apply_payments_and_credits {
 
   $self->select_for_update; #mutex
 
-  my @payments = grep { $_->unapplied > 0 } $self->cust_main->cust_pay;
+  my @payments = grep { $_->unapplied > 0 } 
+                   grep { !$_->no_auto_apply }
+                     $self->cust_main->cust_pay;
   my @credits  = grep { $_->credited > 0 } $self->cust_main->cust_credit;
 
   if ( $conf->exists('pkg-balances') ) {
diff --git a/FS/FS/cust_main/Billing.pm b/FS/FS/cust_main/Billing.pm
index 87be4e6..df7e17f 100644
--- a/FS/FS/cust_main/Billing.pm
+++ b/FS/FS/cust_main/Billing.pm
@@ -2177,6 +2177,7 @@ sub due_cust_event {
 =item apply_payments_and_credits [ OPTION => VALUE ... ]
 
 Applies unapplied payments and credits.
+Payments with the no_auto_apply flag set will not be applied.
 
 In most cases, this new method should be used in place of sequential
 apply_payments and apply_credits methods.
@@ -2319,6 +2320,7 @@ sub apply_credits {
 
 Applies (see L<FS::cust_bill_pay>) unapplied payments (see L<FS::cust_pay>)
 to outstanding invoice balances in chronological order.
+Payments with the no_auto_apply flag set will not be applied.
 
  #and returns the value of any remaining unapplied payments.
 
@@ -2348,7 +2350,7 @@ sub apply_payments {
 
   #return 0 unless
 
-  my @payments = $self->unapplied_cust_pay;
+  my @payments = grep { !$_->no_auto_apply } $self->unapplied_cust_pay;
 
   my @invoices = $self->open_cust_bill;
 
diff --git a/FS/FS/cust_pay.pm b/FS/FS/cust_pay.pm
index 8b4c98a..d135599 100644
--- a/FS/FS/cust_pay.pm
+++ b/FS/FS/cust_pay.pm
@@ -116,6 +116,10 @@ books closed flag, empty or `Y'
 
 Desired pkgnum when using experimental package balances.
 
+=item no_auto_apply
+
+Flag to only allow manual application of payment, empty or 'Y'
+
 =item bank
 
 The bank where the payment was deposited.
@@ -539,6 +543,7 @@ sub check {
     || $self->ut_textn('paybatch')
     || $self->ut_textn('payunique')
     || $self->ut_enum('closed', [ '', 'Y' ])
+    || $self->ut_flag('no_auto_apply')
     || $self->ut_foreign_keyn('pkgnum', 'cust_pkg', 'pkgnum')
     || $self->ut_textn('bank')
     || $self->ut_alphan('depositor')
diff --git a/httemplate/edit/cust_pay.cgi b/httemplate/edit/cust_pay.cgi
index 888335f..5d74365 100755
--- a/httemplate/edit/cust_pay.cgi
+++ b/httemplate/edit/cust_pay.cgi
@@ -87,15 +87,17 @@
   <TD ALIGN="right"><% mt('Auto-apply to invoices') |h %></TD>
   <TD COLSPAN=2>
     <SELECT NAME="apply">
-      <OPTION VALUE="yes" SELECTED><% mt('yes') |h %> 
-      <OPTION><% mt('no') |h %></SELECT>
-    </TD>
+      <OPTION VALUE="yes" SELECTED><% mt('yes') |h %></OPTION> 
+      <OPTION VALUE=""><% mt('not now') |h %></OPTION>
+      <OPTION VALUE="never"><% mt('never') |h %></OPTION>
+    </SELECT>
+  </TD>
 
 % } elsif ( $link eq 'invnum' ) { 
 
   <TD ALIGN="right"><% mt('Apply to') |h %></TD>
   <TD COLSPAN=2 BGCOLOR="#ffffff">Invoice #<B><% $linknum %></B> only</TD>
-  <INPUT TYPE="hidden" NAME="apply" VALUE="no">
+  <INPUT TYPE="hidden" NAME="apply" VALUE="">
 
 % } 
 </TR>
diff --git a/httemplate/edit/process/cust_pay-no_auto_apply.cgi b/httemplate/edit/process/cust_pay-no_auto_apply.cgi
new file mode 100644
index 0000000..ccbd2d7
--- /dev/null
+++ b/httemplate/edit/process/cust_pay-no_auto_apply.cgi
@@ -0,0 +1,48 @@
+<%doc>
+Quick process for toggling no_auto_apply field in cust_pay.
+
+Requires paynum and no_auto_apply ('Y' or '') in cgi.
+
+Requires 'Apply payment' acl.
+</%doc>
+
+% if ($error) {
+
+<P STYLE="color: #FF0000"><% emt($error) %></P>
+
+% } else {
+
+<P STYLE="font-weight: bold;"><% emt($message) %></P>
+<P><% emt('Please wait while the page reloads.') %></P>
+<SCRIPT TYPE="text/javascript">
+window.top.location.reload();
+</SCRIPT>
+
+% }
+
+<%init>
+die "access denied"
+  unless $FS::CurrentUser::CurrentUser->access_right('Apply payment');
+
+my $paynum = $cgi->param('paynum');
+my $noauto = $cgi->param('no_auto_apply');
+
+my $error = '';
+my $message = '';
+my $cust_pay = qsearchs('cust_pay',{ paynum => $paynum });
+if ($cust_pay) {
+  if (($noauto eq 'Y') || (defined($noauto) && (length($noauto) == 0))) {
+    $cust_pay->no_auto_apply($noauto);
+    $error = $cust_pay->replace;
+    $message = $noauto ?
+               q(Payment will not be automatically applied to open invoices, must be applied manually) :
+               q(Payment will be automatically applied to open invoices the next time this customer's payments are processed);
+  } else {
+    $error = 'no_auto_apply not specified';
+  }
+} else {
+  $error .= 'Payment could not be found in database';
+}
+
+
+</%init>
diff --git a/httemplate/edit/process/cust_pay.cgi b/httemplate/edit/process/cust_pay.cgi
index a002fa1..56d3f2f 100755
--- a/httemplate/edit/process/cust_pay.cgi
+++ b/httemplate/edit/process/cust_pay.cgi
@@ -50,6 +50,7 @@ else {
 my $new = new FS::cust_pay ( {
   $field => $linknum,
   _date  => $_date,
+  no_auto_apply => ($cgi->param('apply') eq 'never') ? 'Y' : '',
   map {
     $_, scalar($cgi->param($_));
   } qw( paid payby payinfo paybatch
diff --git a/httemplate/misc/batch-cust_pay.html b/httemplate/misc/batch-cust_pay.html
index 3b0ebc1..9f2540c 100644
--- a/httemplate/misc/batch-cust_pay.html
+++ b/httemplate/misc/batch-cust_pay.html
@@ -461,6 +461,16 @@ push @footer, '';
 push @footer_align, '';
 push @onchange, 'toggle_application_row';
 
+push @header, 'No Auto Allocate';
+push @fields, 'no_auto_apply';
+push @types, 'checkbox';
+push @align, 'c';
+push @sizes, '0';
+push @colors, '';
+push @footer, '';
+push @footer_align, '';
+push @onchange, '';
+
 #push @header, 'Error';
 push @header, '';
 push @fields, 'error';
diff --git a/httemplate/misc/process/batch-cust_pay.cgi b/httemplate/misc/process/batch-cust_pay.cgi
index bb4b973..ff78862 100644
--- a/httemplate/misc/process/batch-cust_pay.cgi
+++ b/httemplate/misc/process/batch-cust_pay.cgi
@@ -40,6 +40,7 @@ foreach my $row ( map /^custnum(\d+)$/, keys %$param ) {
                     'payinfo'        => $param->{"payinfo$row"},
                     'discount_term'  => $param->{"discount_term$row"},
                     'paybatch'       => $paybatch,
+                    'no_auto_apply'  => exists($param->{"no_auto_apply$row"}) ? 'Y' : '',
                   }
     if    $param->{"custnum$row"}
        || $param->{"paid$row"}
diff --git a/httemplate/view/cust_main/payment_history/payment.html b/httemplate/view/cust_main/payment_history/payment.html
index 4ec9271..bf88a66 100644
--- a/httemplate/view/cust_main/payment_history/payment.html
+++ b/httemplate/view/cust_main/payment_history/payment.html
@@ -9,6 +9,7 @@ my $date_format = $opt{'date_format'} || '%m/%d/%Y';
 
 my @cust_bill_pay = $cust_pay->cust_bill_pay;
 my @cust_pay_refund = $cust_pay->cust_pay_refund;
+my $unapplied = $cust_pay->unapplied;
 
 my ($payby,$payinfo) = translate_payinfo($cust_pay);
 my $target = "$payby$payinfo";
@@ -50,39 +51,14 @@ if (    scalar(@cust_bill_pay)   == 0
   $payment = emt("Unapplied Payment by [_1]",$otaker);
   $payment =~ s/$otaker/<i>$otaker<\/i>/ if $italicize_otaker;
   $payment = '<B><FONT COLOR="#FF0000">'.$payment.'</FONT></B>';
-  if ( $opt{'Apply payment'} ) {
-    if ( $opt{total_owed} > 0 ) {
-      $apply = ' ('.
-               include( '/elements/popup_link.html',
-                          'label'       => emt('apply'),
-                          'action'      => "${p}edit/cust_bill_pay.cgi?".
-                                           $cust_pay->paynum,
-                          'actionlabel' => emt('Apply payment'),
-                          %cust_bill_pay_width,
-                          %cust_bill_pay_height,
-                      ).
-                ')';
-    }
-    if ( $opt{total_unapplied_refunds} > 0 ) {
-      $apply.= ' ('.
-               include( '/elements/popup_link.html',
-                          'label'       => emt('apply to refund'),
-                          'action'      => "${p}edit/cust_pay_refund.cgi?".
-                                           $cust_pay->paynum,
-                          'actionlabel' => emt('Apply payment to refund'),
-                          'width'       => 392,
-                      ).
-               ')';
-    }
-  }
 } elsif (    scalar(@cust_bill_pay)   == 1
           && scalar(@cust_pay_refund) == 0
-          && $cust_pay->unapplied == 0     ) {
+          && $unapplied == 0     ) {
   #applied to one invoice, the usual situation
   $desc .= ' '. $cust_bill_pay[0]->applied_to_invoice;
 } elsif (    scalar(@cust_bill_pay)   == 0
           && scalar(@cust_pay_refund) == 1
-          && $cust_pay->unapplied == 0     ) {
+          && $unapplied == 0     ) {
   #applied to one refund
   $desc .= emt(" refunded on [_1]", time2str($date_format, $cust_pay_refund[0]->_date) );
 } else {
@@ -101,40 +77,59 @@ if (    scalar(@cust_bill_pay)   == 0
       die "$app is not a FS::cust_bill_pay or FS::cust_pay_refund";
     }
   }
-  if ( $cust_pay->unapplied > 0 ) {
+  if ( $unapplied > 0 ) {
     $desc .= '  '.
              '<B><FONT COLOR="#FF0000">'.
-             emt("[_1][_2] unapplied", $opt{money_char}, $cust_pay->unapplied).
+             emt("[_1][_2] unapplied", $opt{money_char}, $unapplied).
              '</FONT></B>';
-    if ( $opt{'Apply payment'} ) {
-      if ( $opt{total_owed} > 0 ) {
-        $apply = ' ('.
-                 include( '/elements/popup_link.html',
-                            'label'      => emt('apply'),
-                            'action'     => "${p}edit/cust_bill_pay.cgi?".
-                                            $cust_pay->paynum,
-                            'actionlabel' => emt('Apply payment'),
-                            %cust_bill_pay_width,
-                            %cust_bill_pay_height,
-                        ).
-                 ')';
-      }
-      if ( $opt{total_unapplied_refunds} > 0 ) {
-        $apply.= ' ('.
-                 include( '/elements/popup_link.html',
-                            'label'      => emt('apply to refund'),
-                            'action'     => "${p}edit/cust_pay_refund.cgi?".
-                                            $cust_pay->paynum,
-                            'actionlabel' => emt('Apply payment to refund'),
-                            'width'      => 392,
-                        ).
-                 ')';
-      }
-    }
     $desc .= '<BR>';
   }
 }
 
+if ($unapplied > 0) {
+  if ( $opt{'Apply payment'} ) {
+    if ( $opt{total_owed} > 0 ) {
+      $apply = ' ('.
+               include( '/elements/popup_link.html',
+                          'label'       => emt('apply'),
+                          'action'      => "${p}edit/cust_bill_pay.cgi?".
+                                           $cust_pay->paynum,
+                          'actionlabel' => emt('Apply payment'),
+                          %cust_bill_pay_width,
+                          %cust_bill_pay_height,
+                      ).
+                ')';
+    }
+    if ( $opt{total_unapplied_refunds} > 0 ) {
+      $apply.= ' ('.
+               include( '/elements/popup_link.html',
+                          'label'       => emt('apply to refund'),
+                          'action'      => "${p}edit/cust_pay_refund.cgi?".
+                                           $cust_pay->paynum,
+                          'actionlabel' => emt('Apply payment to refund'),
+                          'width'       => 392,
+                      ).
+               ')';
+    }
+    $apply .= ' (auto‑apply: '
+           .  ($cust_pay->no_auto_apply ? 'no' : 'yes')
+           .  ' | '
+           .  include( '/elements/popup_link.html',
+                          'label'       => emt($cust_pay->no_auto_apply ? 'yes' : 'no'),
+                          'action'      => "${p}edit/process/cust_pay-no_auto_apply.cgi?paynum="
+                                           . $cust_pay->paynum
+                                           . '&no_auto_apply='
+                                           . ($cust_pay->no_auto_apply ? '' : 'Y'),
+                          'actionlabel' => emt('Toggle Auto-Apply'),
+                          'width'       => 392,
+                          'height'      => 200,
+                      )
+           . ')';
+  } else { # end if $opt('Apply payment')
+    $apply .= ' (no auto-apply)' if $cust_pay->no_auto_apply;
+  }
+} # end if $unapplied > 0
+
 my $view =
   ' ('. include('/elements/popup_link.html',
                   'label'     => emt('view receipt'),

-----------------------------------------------------------------------

Summary of changes:
 FS/FS/Schema.pm                                    |    1 +
 FS/FS/cust_bill.pm                                 |    5 +-
 FS/FS/cust_main/Billing.pm                         |    4 +-
 FS/FS/cust_pay.pm                                  |    5 +
 httemplate/edit/cust_pay.cgi                       |   10 +-
 httemplate/edit/process/cust_pay-no_auto_apply.cgi |   48 +++++++++
 httemplate/edit/process/cust_pay.cgi               |    1 +
 httemplate/misc/batch-cust_pay.html                |   10 ++
 httemplate/misc/process/batch-cust_pay.cgi         |    1 +
 .../view/cust_main/payment_history/payment.html    |  103 ++++++++++----------
 10 files changed, 128 insertions(+), 60 deletions(-)
 create mode 100644 httemplate/edit/process/cust_pay-no_auto_apply.cgi




More information about the freeside-commits mailing list