[freeside-commits] branch FREESIDE_4_BRANCH updated. d5205ac7d2d2f2f8207d77715e20f7f750e6176c

Christopher Burger burgerc at freeside.biz
Tue Nov 6 11:37:28 PST 2018


The branch, FREESIDE_4_BRANCH has been updated
       via  d5205ac7d2d2f2f8207d77715e20f7f750e6176c (commit)
       via  1fcb4ef3e4e3ad7eae7067d37e7675efa37680fb (commit)
      from  8b610864ee3d14b7874fc21685651004bf94cb1d (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 d5205ac7d2d2f2f8207d77715e20f7f750e6176c
Author: Christopher Burger <burgerc at freeside.biz>
Date:   Tue Nov 6 13:57:35 2018 -0500

    RT# 76093 - added ability for processing fee to be used with batch processing.

diff --git a/FS/FS/cust_main/Billing_Batch.pm b/FS/FS/cust_main/Billing_Batch.pm
index f7713295d..2975dff79 100644
--- a/FS/FS/cust_main/Billing_Batch.pm
+++ b/FS/FS/cust_main/Billing_Batch.pm
@@ -165,6 +165,27 @@ sub batch_card {
   if ($options{'processing-fee'} > 0) {
     my $pf_cust_pkg;
     my $processing_fee_text = 'Payment Processing Fee';
+
+    unless ( $invnum ) { # probably from a payment screen
+      # do we have any open invoices? pick earliest
+      # uses the fact that cust_main->cust_bill sorts by date ascending
+      my @open = $self->open_cust_bill;
+      $invnum = $open[0]->invnum if scalar(@open);
+    }
+
+    unless ( $invnum ) {  # still nothing? pick last closed invoice
+      # again uses fact that cust_main->cust_bill sorts by date ascending
+      my @closed = $self->cust_bill;
+      $invnum = $closed[$#closed]->invnum if scalar(@closed);
+    }
+
+    unless ( $invnum ) {
+      # XXX: unlikely case - pre-paying before any invoices generated
+      # what it should do is create a new invoice and pick it
+      warn '\PROCESS FEE AND NO INVOICES PICKED TO APPLY IT!';
+      return '';
+    }
+
     my $pf_change_error = $self->charge({
             'amount'  => $options{'processing-fee'},
             'pkg'   => $processing_fee_text,

commit 1fcb4ef3e4e3ad7eae7067d37e7675efa37680fb
Author: Christopher Burger <burgerc at freeside.biz>
Date:   Mon Nov 5 17:44:50 2018 -0500

    RT# 76093 - Added ability to charge a processing fee when taking a payment on the back end

diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm
index 733ed00fe..a2436aacd 100644
--- a/FS/FS/Conf.pm
+++ b/FS/FS/Conf.pm
@@ -2671,6 +2671,14 @@ and customer address. Include units.',
   },
 
   {
+    'key'         => 'processing-fee',
+    'section'     => 'payments',
+    'description' => 'Fee for back end payment processing.',
+    'type'        => 'text',
+    'per_agent'   => 1,
+  },
+
+  {
     'key'         => 'banned_pay-pad',
     'section'     => 'credit_cards',
     'description' => 'Padding for encrypted storage of banned credit card hashes.  If you already have new-style SHA512 entries in the banned_pay table, do not change as this will invalidate the old entries.',
diff --git a/FS/FS/cust_main/Billing_Batch.pm b/FS/FS/cust_main/Billing_Batch.pm
index 077478189..f7713295d 100644
--- a/FS/FS/cust_main/Billing_Batch.pm
+++ b/FS/FS/cust_main/Billing_Batch.pm
@@ -162,6 +162,41 @@ sub batch_card {
     return $error; # e.g. "Illegal zip" ala RT#75998
   }
 
+  if ($options{'processing-fee'} > 0) {
+    my $pf_cust_pkg;
+    my $processing_fee_text = 'Payment Processing Fee';
+    my $pf_change_error = $self->charge({
+            'amount'  => $options{'processing-fee'},
+            'pkg'   => $processing_fee_text,
+            'setuptax'  => 'Y',
+            'cust_pkg_ref' => \$pf_cust_pkg,
+    });
+
+    if($pf_change_error) {
+      warn 'Unable to add payment processing fee';
+      return '';
+    }
+
+    $pf_cust_pkg->setup(time);
+    my $pf_error = $pf_cust_pkg->replace;
+    if($pf_error) {
+      warn 'Unable to set setup time on cust_pkg for processing fee';
+      # but keep going...
+    }
+
+    my $cust_bill = qsearchs('cust_bill', { 'invnum' => $invnum });
+    unless ( $cust_bill ) {
+      warn "race condition + invoice deletion just happened";
+      return '';
+    }
+
+    my $grand_pf_error =
+      $cust_bill->add_cc_surcharge($pf_cust_pkg->pkgnum,$options{'processing-fee'});
+
+    warn "cannot add Processing fee to invoice #$invnum: $grand_pf_error"
+      if $grand_pf_error;
+  }
+
   my $unapplied =   $self->total_unapplied_credits
                   + $self->total_unapplied_payments
                   + $self->in_transit_payments;
diff --git a/FS/FS/cust_main/Billing_Realtime.pm b/FS/FS/cust_main/Billing_Realtime.pm
index 64b551cab..09f4d25be 100644
--- a/FS/FS/cust_main/Billing_Realtime.pm
+++ b/FS/FS/cust_main/Billing_Realtime.pm
@@ -474,8 +474,8 @@ sub realtime_bop {
   elsif($cc_surcharge_pct > 0 || $cc_surcharge_flat > 0) {
     # we're called not from event (i.e. from a
     # payment screen), so consider the given
-		# amount as post-surcharge
-    $cc_surcharge = $options{'amount'} - (($options{'amount'} - $cc_surcharge_flat) / ( 1 + $cc_surcharge_pct/100 )) if $options{'amount'} > 0;
+		# amount as post-surcharge-processing_fee
+    $cc_surcharge = $options{'amount'} - $options{'processing-fee'} - (($options{'amount'} - ($cc_surcharge_flat + $options{'processing-fee'})) / ( 1 + $cc_surcharge_pct/100 )) if $options{'amount'} > 0;
   }
   
   $cc_surcharge = sprintf("%.2f",$cc_surcharge) if $cc_surcharge > 0;
@@ -1061,7 +1061,7 @@ sub _realtime_bop_result {
       }
 
       # have a CC surcharge portion --> one-time charge
-      if ( $options{'cc_surcharge'} > 0 ) { 
+      if ( $options{'cc_surcharge'} > 0 || $options{'processing-fee'} > 0) {
 	    # XXX: this whole block needs to be in a transaction?
 
 	  my $invnum;
@@ -1082,44 +1082,83 @@ sub _realtime_bop_result {
 	  unless ( $invnum ) {
 	    # XXX: unlikely case - pre-paying before any invoices generated
 	    # what it should do is create a new invoice and pick it
-		warn 'CC SURCHARGE AND NO INVOICES PICKED TO APPLY IT!';
+		warn 'CC SURCHARGE OR PROCESS FEE AND NO INVOICES PICKED TO APPLY IT!';
 		return '';
 	  }
 
-	  my $cust_pkg;
-    my $cc_surcharge_text = 'Credit Card Surcharge';
-    $cc_surcharge_text = $conf->config('credit-card-surcharge-text', $self->agentnum) if $conf->exists('credit-card-surcharge-text', $self->agentnum);
-	  my $charge_error = $self->charge({
+    if ($options{'cc_surcharge'} > 0) {
+	    my $cust_pkg;
+      my $cc_surcharge_text = 'Credit Card Surcharge';
+      $cc_surcharge_text = $conf->config('credit-card-surcharge-text', $self->agentnum) if $conf->exists('credit-card-surcharge-text', $self->agentnum);
+	    my $charge_error = $self->charge({
 				    'amount' 	=> $options{'cc_surcharge'},
 				    'pkg' 	=> $cc_surcharge_text,
 				    'setuptax'  => 'Y',
 				    'cust_pkg_ref' => \$cust_pkg,
-				});
-	  if($charge_error) {
-		warn 'Unable to add CC surcharge cust_pkg';
-		return '';
-	  }
+			});
+
+	    if($charge_error) {
+		    warn 'Unable to add CC surcharge cust_pkg';
+		    return '';
+	    }
+
+      $cust_pkg->setup(time);
+      my $cp_error = $cust_pkg->replace;
+      if($cp_error) {
+        warn 'Unable to set setup time on cust_pkg for cc surcharge';
+        # but keep going...
+      }
 
-	  $cust_pkg->setup(time);
-	  my $cp_error = $cust_pkg->replace;
-	  if($cp_error) {
-	      warn 'Unable to set setup time on cust_pkg for cc surcharge';
-	    # but keep going...
-	  }
-				    
-	  my $cust_bill = qsearchs('cust_bill', { 'invnum' => $invnum });
-	  unless ( $cust_bill ) {
-	      warn "race condition + invoice deletion just happened";
-	      return '';
-	  }
+      my $cust_bill = qsearchs('cust_bill', { 'invnum' => $invnum });
+      unless ( $cust_bill ) {
+        warn "race condition + invoice deletion just happened";
+        return '';
+      }
+
+      my $grand_error =
+        $cust_bill->add_cc_surcharge($cust_pkg->pkgnum,$options{'cc_surcharge'});
+
+      warn "cannot add CC surcharge to invoice #$invnum: $grand_error"
+        if $grand_error;
+    } # end if $options{'cc_surcharge'}
+
+    if ($options{'processing-fee'} > 0) {
+      my $pf_cust_pkg;
+      my $processing_fee_text = 'Payment Processing Fee';
+      my $pf_change_error = $self->charge({
+            'amount'  => $options{'processing-fee'},
+            'pkg'   => $processing_fee_text,
+            'setuptax'  => 'Y',
+            'cust_pkg_ref' => \$pf_cust_pkg,
+      });
+
+      if($pf_change_error) {
+        warn 'Unable to add payment processing fee';
+        return '';
+      }
 
-	  my $grand_error = 
-	    $cust_bill->add_cc_surcharge($cust_pkg->pkgnum,$options{'cc_surcharge'});
+      $pf_cust_pkg->setup(time);
+      my $pf_error = $pf_cust_pkg->replace;
+      if($pf_error) {
+        warn 'Unable to set setup time on cust_pkg for processing fee';
+        # but keep going...
+      }
 
-	  warn "cannot add CC surcharge to invoice #$invnum: $grand_error"
-	    if $grand_error;
+      my $cust_bill = qsearchs('cust_bill', { 'invnum' => $invnum });
+      unless ( $cust_bill ) {
+        warn "race condition + invoice deletion just happened";
+        return '';
       }
 
+      my $grand_pf_error =
+        $cust_bill->add_cc_surcharge($pf_cust_pkg->pkgnum,$options{'processing-fee'});
+
+      warn "cannot add Processing fee to invoice #$invnum: $grand_pf_error"
+        if $grand_pf_error;
+    } #end if $options{'processing-fee'}
+
+      } #end if ( $options{'cc_surcharge'} > 0 || $options{'processing-fee'} > 0)
+
       return ''; #no error
 
     }
diff --git a/httemplate/elements/tr-amount_fee.html b/httemplate/elements/tr-amount_fee.html
index a84fef6ec..94795de37 100644
--- a/httemplate/elements/tr-amount_fee.html
+++ b/httemplate/elements/tr-amount_fee.html
@@ -8,7 +8,7 @@
                                 VALUE    = "<% $amount %>"
                                 SIZE     = 8
                                 STYLE    = "text-align:right;"
-%                               if ( $fee || $surcharge_percentage || $surcharge_flatfee ) {
+%                               if ( $fee || $surcharge_percentage || $surcharge_flatfee || $processing_fee) {
                                   onChange   = "amount_changed(this)"
                                   onKeyDown  = "amount_changed(this)"
                                   onKeyUp    = "amount_changed(this)"
@@ -38,7 +38,23 @@
     </TD>
   </TR>
 
-% if ($fee || $surcharge_percentage || $surcharge_flatfee ) {
+%        if ( $processing_fee ) {
+      <TR>
+        <TH ALIGN="right"><% mt('Apply processing fee') |h %></TH>
+        <TD>
+          <TABLE><TR>
+            <TD BGCOLOR="#ffffff">
+             <INPUT TYPE="checkbox" NAME="processing_fee" ID="processing_fee" VALUE="<% $processing_fee %>" onclick="<% $opt{prefix} %>process_fee_changed()">
+            </TD>
+            <TD ID="ajax_processingfee_cell" BGCOLOR="#dddddd" STYLE="border:1px solid blue">
+             <FONT SIZE="+1">A processing fee of <% $processing_fee %> is being applied to this transaction.</FONT>
+            </TD>
+          </TR></TABLE>
+        </TD>
+      </TR>
+%        }
+
+% if ($fee || $surcharge_percentage || $surcharge_flatfee || $processing_fee) {
 
     <SCRIPT TYPE="text/javascript">
 
@@ -58,6 +74,10 @@
 
 % if ( $surcharge_percentage || $surcharge_flatfee ) {
         var surcharge_cell = document.getElementById('ajax_surcharge_cell');
+        var amount = what.value;
+        if (document.getElementById('processing_fee').checked == true) {
+          amount = (what.value - <% $processing_fee %>);
+        }
         var surcharge = ((what.value - <% $surcharge_flatfee %>) * <% $surcharge_percentage %>) + <% $surcharge_flatfee %>;
         surcharge_cell.innerHTML = '<FONT SIZE="+1">A credit card surcharge of ' + surcharge.toFixed(2) + ' is included in this payment</FONT>';
 % }
@@ -82,6 +102,7 @@ my $fee_op = '';
 my $surcharge = '';
 my $surcharge_percentage = 0;
 my $surcharge_flatfee = 0;
+my $processing_fee = 0;
 
 if ( $opt{'process-pkgpart'}
      and ! $opt{'process-skip_first'} || $opt{'num_payments'}
@@ -115,6 +136,7 @@ if ( $amount ) {
   $surcharge_flatfee = $opt{'surcharge_flatfee'} if $opt{'surcharge_flatfee'} > 0;
   $surcharge = $amount * $surcharge_percentage if $surcharge_percentage > 0;
   $surcharge += $surcharge_flatfee if ( $surcharge_flatfee > 0 && $amount > 0 );
+  $processing_fee = $opt{'processing_fee'} if $opt{'processing_fee'} > 0;
 
   $amount += $surcharge;
 
diff --git a/httemplate/elements/tr-select-payment_options.html b/httemplate/elements/tr-select-payment_options.html
index f86f3edfd..c5b84e756 100644
--- a/httemplate/elements/tr-select-payment_options.html
+++ b/httemplate/elements/tr-select-payment_options.html
@@ -22,6 +22,7 @@ Example:
           ? scalar($conf->config('credit-card-surcharge-flatfee', $cust_main->agentnum))
           : 0
       ),
+    'processing_fee' => scalar($conf->config('processing-fee', $cust_main->agentnum)),
   )
 
 </%doc>
@@ -59,6 +60,7 @@ Example:
 
       $('#payment_option_row').<% $payment_option_row %>();
       $('#payment_amount_row').<% $payment_amount_row %>();
+      $('#ajax_processingfee_cell').hide();
 
       if($('#payment_amount_row').is(':visible')) {
         var surcharge;
@@ -76,11 +78,21 @@ Example:
       function <% $opt{prefix} %>payment_option_changed(what) {
 
         var surcharge;
+        var processingFee = 0;
+        var pfElement = document.getElementById('processing_fee');
+
         if (document.getElementById('surcharge_percentage') || document.getElementById('surcharge_flatfee')) {
           surcharge = (+what.value * +document.getElementById('surcharge_percentage').value) + +document.getElementById('surcharge_flatfee').value;
         }
         else { surcharge = 0; }
-        var amount = +what.value + +surcharge;
+
+        if (pfElement != null) {
+          if (pfElement.checked == true) {
+           processingFee = +pfElement.value;
+          }
+        }
+
+        var amount = +what.value + +surcharge + +processingFee;
         document.getElementById('amount').disabled = true;
 
         if ( what.value == 'select' ) {
@@ -131,12 +143,21 @@ Example:
       function <% $opt{prefix} %>invoice_select_changed(what) {
 
         var surcharge;
+        var processingFee = 0;
+        var pfElement = document.getElementById('processing_fee');
         var invdue = document.getElementById("<% $opt{prefix} %>inv" + what.value);
         if (document.getElementById('surcharge_percentage') || document.getElementById('surcharge_flatfee')) {
           surcharge = (+invdue.value * +document.getElementById('surcharge_percentage').value) + +document.getElementById('surcharge_flatfee').value;
         }
         else { surcharge = 0; }
-        var amount = +invdue.value + +surcharge;
+
+        if (pfElement != null) {
+          if (pfElement.checked == true) {
+           processingFee = +pfElement.value;
+          }
+        }
+
+        var amount = +invdue.value + +surcharge + +processingFee;
 
         if ( what.value == 'select' ) {
           $('#payment_amount_row').hide();
@@ -154,6 +175,21 @@ Example:
 
       }
 
+      function <% $opt{prefix} %>process_fee_changed(what) {
+
+        if (document.getElementById('processing_fee').checked == true) {
+          var amount = +document.getElementById('amount').value + +document.getElementById('processing_fee').value;
+          $('#amount').val(amount.toFixed(2));
+          $('#ajax_processingfee_cell').show();
+        }
+        else {
+          var amount = +document.getElementById('amount').value - +document.getElementById('processing_fee').value;
+          $('#amount').val(amount.toFixed(2));
+          $('#ajax_processingfee_cell').hide();
+        }
+
+      }
+
 </SCRIPT>
 
 <%init>
diff --git a/httemplate/misc/payment.cgi b/httemplate/misc/payment.cgi
index 77f5acd6a..7911a5dd9 100644
--- a/httemplate/misc/payment.cgi
+++ b/httemplate/misc/payment.cgi
@@ -29,6 +29,7 @@
              ? scalar($conf->config('credit-card-surcharge-flatfee', $cust_main->agentnum))
              : 0
          ),
+         'processing_fee' => scalar($conf->config('processing-fee', $cust_main->agentnum)),
   &>
 
 % if ( $conf->exists('part_pkg-term_discounts') ) {
diff --git a/httemplate/misc/process/payment.cgi b/httemplate/misc/process/payment.cgi
index 7747bcbea..56bcfd872 100644
--- a/httemplate/misc/process/payment.cgi
+++ b/httemplate/misc/process/payment.cgi
@@ -41,6 +41,8 @@ my $cust_main = qsearchs({
 
 my $invoice = ($cgi->param('invoice') =~ /^(\d+)$/) ? $cgi->param('invoice') : '';
 
+my $processing_fee = $cgi->param('processing_fee') ? $cgi->param('processing_fee') : '';
+
 $cgi->param('amount') =~ /^\s*(\d*(\.\d\d)?)\s*$/
   or errorpage("illegal amount ". $cgi->param('amount'));
 my $amount = $1;
@@ -233,6 +235,7 @@ if ( $cgi->param('batch') ) {
                                      'paydate'  => $paydate,
                                      'payname'  => $payname,
                                      'invnum'   => $invoice,
+                                     'processing-fee' => $processing_fee,
                                      map { $_ => scalar($cgi->param($_)) } 
                                        @{$payby2fields{$payby}}
                                    );
@@ -256,6 +259,7 @@ if ( $cgi->param('batch') ) {
     'no_auto_apply' => ($cgi->param('apply') eq 'never') ? 'Y' : '',
     'no_invnum'     => 1,
     'invnum'        => $invoice,
+    'processing-fee' => $processing_fee,
     map { $_ => scalar($cgi->param($_)) } @{$payby2fields{$payby}}
   );
   errorpage($error) if $error;

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

Summary of changes:
 FS/FS/Conf.pm                                      |  8 ++
 FS/FS/cust_main/Billing_Batch.pm                   | 56 +++++++++++++
 FS/FS/cust_main/Billing_Realtime.pm                | 97 +++++++++++++++-------
 httemplate/elements/tr-amount_fee.html             | 26 +++++-
 httemplate/elements/tr-select-payment_options.html | 40 ++++++++-
 httemplate/misc/payment.cgi                        |  1 +
 httemplate/misc/process/payment.cgi                |  4 +
 7 files changed, 199 insertions(+), 33 deletions(-)




More information about the freeside-commits mailing list