[freeside-commits] branch FREESIDE_4_BRANCH updated. 9c523f51fb75084936141a686994d141ccca15e9

Christopher Burger burgerc at freeside.biz
Mon Mar 11 09:06:03 PDT 2019


The branch, FREESIDE_4_BRANCH has been updated
       via  9c523f51fb75084936141a686994d141ccca15e9 (commit)
       via  6f08493827f30fe18fd99c32bbb1625b064017ec (commit)
      from  59b1fe7b375932fc13c920eb6f02b8da61d4c8fe (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 9c523f51fb75084936141a686994d141ccca15e9
Author: Christopher Burger <burgerc at freeside.biz>
Date:   Mon Mar 11 11:13:28 2019 -0400

    RT# 82988 - fixed resolve credit batches from RBC

diff --git a/FS/FS/pay_batch/RBC.pm b/FS/FS/pay_batch/RBC.pm
index 7c165a315..691e2a2af 100644
--- a/FS/FS/pay_batch/RBC.pm
+++ b/FS/FS/pay_batch/RBC.pm
@@ -94,22 +94,17 @@ $name = 'RBC';
   },
   'begin_condition' => sub {
       my $hash = shift;
-      # Debit Detail Record
-      if ($hash->{recordtype} eq '1') {
+      # Detail Record
+      if ($hash->{recordtype} eq '1' || $hash->{recordtype} eq '2') {
         $declined = {};
         $totaloffset = 0;
         return 1;
-      # Credit Detail Record, will immediately trigger end condition & error
-      } elsif ($hash->{recordtype} eq '2') { 
-        return 1;
       } else {
         return 0;
       }
   },
   'end_hook'    => sub {
       my( $hash, $total, $line ) = @_;
-      return "Can't process Credit Detail Record, aborting import"
-        if ($hash->{'recordtype'} eq '2');
       $total += $totaloffset;
       $total = sprintf("%.2f", $total);
       # We assume here that this is an 'All Records' or 'Input Records' report.
@@ -120,8 +115,7 @@ $name = 'RBC';
   },
   'end_condition' => sub {
       my $hash = shift;
-      return ($hash->{recordtype} eq '4')  # Client Trailer Record
-          || ($hash->{recordtype} eq '2'); # Credit Detail Record, will throw error in end_hook
+      return ($hash->{recordtype} eq '4');  # Client Trailer Record
   },
   'skip_condition' => sub {
       my $hash = shift;

commit 6f08493827f30fe18fd99c32bbb1625b064017ec
Author: Christopher Burger <burgerc at freeside.biz>
Date:   Sun Mar 10 19:12:20 2019 -0400

    RT# 82988 - Fixed so only formats that can handle electronic refunds can download those files

diff --git a/FS/FS/Cron/pay_batch.pm b/FS/FS/Cron/pay_batch.pm
index 1e110f2da..18532aca8 100644
--- a/FS/FS/Cron/pay_batch.pm
+++ b/FS/FS/Cron/pay_batch.pm
@@ -67,7 +67,7 @@ sub pay_batch_submit {
     my ($gateway, $payby, $agentnum) = @$config;
     if ( $gateway->batch_processor->can('default_transport') ) {
 
-      my $search = { status => 'O', payby => $payby };
+      my $search = { status => 'O', payby => $payby, type => 'DEBIT' };
       $search->{agentnum} = $agentnum if $agentnum;
 
       foreach my $pay_batch ( qsearch('pay_batch', $search) ) {
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index a376dd9b4..ec3340b71 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -2682,6 +2682,7 @@ sub tables_hashref {
         'upload',         @date_type,     '', '', 
         'title',   'varchar', 'NULL',255, '', '',
         'processor_id',   'varchar', 'NULL',255, '', '',
+        'type',      'char',  '',  6, 'DEBIT', '', # DEBIT/CREDIT
       ],
       'primary_key'  => 'batchnum',
       'unique'       => [],
diff --git a/FS/FS/cust_main/Billing_Batch.pm b/FS/FS/cust_main/Billing_Batch.pm
index 2975dff79..ed853182b 100644
--- a/FS/FS/cust_main/Billing_Batch.pm
+++ b/FS/FS/cust_main/Billing_Batch.pm
@@ -83,6 +83,10 @@ sub batch_card {
                               );
   }
 
+  my $paycode= $options{paycode} || '';
+  my $batch_type = "DEBIT";
+  $batch_type = "CREDIT" if $paycode eq 'C';
+
   my $oldAutoCommit = $FS::UID::AutoCommit;
   local $FS::UID::AutoCommit = 0;
   my $dbh = dbh;
@@ -95,6 +99,7 @@ sub batch_card {
   my %pay_batch = (
     'status' => 'O',
     'payby'  => FS::payby->payby2payment($payby),
+    'type'   => $batch_type,
   );
   $pay_batch{agentnum} = $self->agentnum if $conf->exists('batch-spoolagent');
 
diff --git a/FS/FS/pay_batch.pm b/FS/FS/pay_batch.pm
index 4aeb33169..e8ae6ec2c 100644
--- a/FS/FS/pay_batch.pm
+++ b/FS/FS/pay_batch.pm
@@ -56,6 +56,10 @@ from FS::Record.  The following fields are currently supported:
 
 =item title - unique batch identifier
 
+=item processor_id -
+
+=item type - batch type payents (DEBIT), or refunds (CREDIT)
+
 For incoming batches, the combination of 'title', 'payby', and 'agentnum'
 must be unique.
 
@@ -1154,7 +1158,136 @@ sub manual_approve {
   return;
 }
 
+=item batch_download_formats
+
+returns a hash of batch download formats.
+
+my %download_formats = FS::pay_batch::batch_download_formats;
+
+=cut
+
+sub batch_download_formats {
+
+  my @formats = (
+    ''              =>
+        'Default batch mode',
+    'NACHA'         =>
+        '94 byte NACHA',
+    'csv-td_canada_trust-merchant_pc_batch' =>
+        'CSV file for TD Canada Trust Merchant PC Batch',
+    'csv-chase_canada-E-xactBatch' =>
+        'CSV file for Chase Canada E-xactBatch',
+    'PAP'           =>
+        '80 byte file for TD Canada Trust PAP Batch',
+    'BoM'           =>
+        'Bank of Montreal ECA batch',
+    'ach-spiritone' =>
+        'Spiritone ACH batch',
+    'paymentech'    =>
+        'XML file for Chase Paymentech',
+    'RBC'           =>
+        'Royal Bank of Canada PDS batch',
+    'td_eft1464'    =>
+        '1464 byte file for TD Commercial Banking EFT',
+    'eft_canada'    =>
+        'EFT Canada CSV batch',
+    'CIBC'          =>
+        '80 byte file for Canadian Imperial Bank of Commerce',
+    # insert new batch formats here
+  );
+
+}
+
+=item batch_download_formats
+
+returns a hash of batch download formats.
+
+my %download_formats = FS::pay_batch::batch_download_formats;
+
+=cut
+
+sub can_handle_electronic_refunds {
+
+  my $self = shift;
+  my $format = shift;
+  my $conf = new FS::Conf;
+
+  tie my %download_formats, 'Tie::IxHash', batch_download_formats;
+
+  my %paybatch_mods = (
+    'NACHA'                                 => 'nacha',
+    'csv-td_canada_trust-merchant_pc_batch' => 'td_canada_trust',
+    'csv-chase_canada-E-xactBatch'          => 'chase-canada',
+    'PAP'                                   => 'PAP',
+    'BoM'                                   => 'BoM',
+    'ach-spiritone'                         => 'ach_spiritone',
+    'paymentech'                            => 'paymentech',
+    'RBC'                                   => 'RBC',
+    'td_eft1464'                            => 'td_eft1464',
+    'eft_canada'                            => 'eft_canada',
+    'CIBC'                                  => 'CIBC',
+  );
+
+  %download_formats = ( $format => $download_formats{$format}, ) if $format;
+
+  foreach my $key (keys %download_formats) {
+    my $mod = "FS::pay_batch::".$paybatch_mods{$key};
+    if ($mod->can('can_handle_credits')) {
+      return '1' if $conf->exists('batchconfig-'.$key);
+    }
+  }
+
+  return;
+
+}
+
+use FS::upgrade_journal;
 sub _upgrade_data {
+
+  # check if there are any pending batch refunds and no download format configured
+  # that allows electronic refunds.
+  unless ( FS::upgrade_journal->is_done('removed_refunds_nodownload_format') ) {
+
+    ## get a list of all refunds in batches.
+    my $extrasql = " LEFT JOIN pay_batch USING ( batchnum ) WHERE cust_pay_batch.paycode = 'C' AND pay_batch.download IS NULL";
+
+    my @batch_refunds = qsearch({
+      'table'   => 'cust_pay_batch',
+      'select'  => 'cust_pay_batch.*',
+      'extra_sql' => $extrasql,
+    });
+
+    warn "found ".scalar @batch_refunds." batch refunds.\n";
+    warn "Searching for their cust refunds...\n" if (scalar @batch_refunds > 0);
+    my ($delete_cust_refund_error, $delete_cust_pay_batch_error);
+
+    ## find the cust_pay_refund for all those
+    foreach (@batch_refunds) {
+      my $extra_batch_refund_sql = " WHERE custnum = '".$_->{Hash}->{custnum}."' AND refund = '".$_->{Hash}->{amount}."' ORDER BY _date DESC LIMIT 1";
+      my $cust_refund = qsearchs({
+        'table'  => 'cust_refund',
+        'extra_sql' => $extra_batch_refund_sql,
+      });
+
+      warn "found cust refund number ".$cust_refund->{Hash}->{refundnum}.", now to delete it.\n" if $cust_refund;
+
+      ## delete the cust_pay_refund
+      $delete_cust_refund_error = $cust_refund->delete if $cust_refund;
+      warn "could not delete cust refund $delete_cust_refund_error\n" if $delete_cust_refund_error;
+
+      ## delete the refund from the batch.
+      unless ($delete_cust_refund_error) {
+        $delete_cust_pay_batch_error = $_->unbatch_and_delete;
+        warn "could not delete cust refund $delete_cust_pay_batch_error\n" if $delete_cust_pay_batch_error;
+      }
+
+      if ($delete_cust_refund_error || $delete_cust_pay_batch_error) { die "Could no delete cust_pay_batch refund\n"; }
+      else { warn "cust refund ".$cust_refund->{Hash}->{refundnum}." deleted\n"; }
+    }
+
+    FS::upgrade_journal->set_done('removed_refunds_nodownload_format');
+  }
+
   # Set up configuration for gateways that have a Business::BatchPayment
   # module.
   
diff --git a/FS/FS/pay_batch/RBC.pm b/FS/FS/pay_batch/RBC.pm
index 22521e0e1..7c165a315 100644
--- a/FS/FS/pay_batch/RBC.pm
+++ b/FS/FS/pay_batch/RBC.pm
@@ -154,7 +154,8 @@ $name = 'RBC';
     my $pay_batch = shift;
     my $mode = $testmode ? 'TEST' : 'PROD';
     my $filenum = $testmode ? 'TEST' : sprintf("%04u", $pay_batch->batchnum);
-    '$$AAPASTD0152['.$mode.'[NL$$'."\n".
+    my $qualifier = $pay_batch->type eq 'CREDIT' ? 'D' : 'A';
+    '$$AAP'.$qualifier.'STD0152['.$mode.'[NL$$'."\n".
     '000001'.
     'A'.
     'HDR'.
@@ -219,13 +220,15 @@ $name = 'RBC';
   },
   footer => sub {
     my ($pay_batch, $batchcount, $batchtotal) = @_;
+
+    my $batch_info = '0' x 20 . sprintf("%06u", $batchcount) . sprintf("%014.0f", $batchtotal*100);
+    $batch_info = sprintf("%06u", $batchcount) . sprintf("%014.0f", $batchtotal*100) . '0' x 20 if ($pay_batch->type eq 'CREDIT');
+
     sprintf("%06u", $i + 1).
     'Z'.
     'TRL'.
     sprintf("%10s", $client_num).
-    '0' x 20 .
-    sprintf("%06u", $batchcount).
-    sprintf("%014.0f", $batchtotal*100).
+    $batch_info.
     '00' .
     '000000' . # total number of customer information records
     ' ' x 84
diff --git a/FS/bin/freeside-eftca-upload b/FS/bin/freeside-eftca-upload
index 503c7a35a..18656c97a 100755
--- a/FS/bin/freeside-eftca-upload
+++ b/FS/bin/freeside-eftca-upload
@@ -32,8 +32,12 @@ my @batches;
 
 if($opt_a) {
   local $@;
+
+  my %criteria= ( 'status' => 'O', 'payby' => 'CHEK' );
+  $criteria{'type'} = 'DEBIT' unless FS::pay_batch->can_handle_electronic_refunds('eft_canada');
+
   eval {
-    @batches = qsearch('pay_batch', { 'status' => 'O', 'payby' => 'CHEK' })
+    @batches = qsearch('pay_batch', \%criteria)
   };
   log_error_and_die ("Fatal database error: $@")
     if $@;
diff --git a/FS/bin/freeside-paymentech-upload b/FS/bin/freeside-paymentech-upload
index d6ca0cd28..8ec8a5dd4 100755
--- a/FS/bin/freeside-paymentech-upload
+++ b/FS/bin/freeside-paymentech-upload
@@ -41,6 +41,7 @@ my @batches;
 if($opt_a) {
   my %criteria = (status => 'O');
   $criteria{'payby'} = uc($opt_p) if $opt_p;
+  $criteria{'type'} = 'DEBIT' unless FS::pay_batch->can_handle_electronic_refunds('paymentech');
   @batches = qsearch('pay_batch', \%criteria);
   log_and_die("No open batches found".($opt_p ? " of type '$opt_p'" : '').".\n")
     if !@batches;
diff --git a/FS/bin/freeside-rbc-upload b/FS/bin/freeside-rbc-upload
index 3fff32a67..8f67a6e4f 100755
--- a/FS/bin/freeside-rbc-upload
+++ b/FS/bin/freeside-rbc-upload
@@ -33,6 +33,7 @@ my @batches;
 if($opt_a) {
   my %criteria = (status => 'O');
   $criteria{'payby'} = uc($opt_p) if $opt_p;
+  $criteria{'type'} = 'DEBIT' unless FS::pay_batch->can_handle_electronic_refunds('RBC');
   @batches = qsearch('pay_batch', \%criteria);
   die "No open batches found".($opt_p ? " of type '$opt_p'" : '').".\n" 
     if !@batches;
diff --git a/httemplate/edit/process/cust_refund.cgi b/httemplate/edit/process/cust_refund.cgi
index 9175eb136..25f6e00a1 100755
--- a/httemplate/edit/process/cust_refund.cgi
+++ b/httemplate/edit/process/cust_refund.cgi
@@ -39,6 +39,8 @@ $cgi->param('reasonnum') =~ /^(-?\d+)$/ or die "Illegal reasonnum";
 my ($reasonnum, $error) = $m->comp('/misc/process/elements/reason');
 $cgi->param('reasonnum', $reasonnum) unless $error;
 
+$error = "No batch download format configured that allows electronic refunds" unless (FS::pay_batch->can_handle_electronic_refunds && !$error);
+
 if ( $error ) {
   # do nothing
 } elsif ( $payby =~ /^(CARD|CHEK)$/ ) { 
diff --git a/httemplate/search/elements/cust_pay_batch_top.html b/httemplate/search/elements/cust_pay_batch_top.html
index 626d7c3ea..eee81dd5b 100644
--- a/httemplate/search/elements/cust_pay_batch_top.html
+++ b/httemplate/search/elements/cust_pay_batch_top.html
@@ -135,23 +135,7 @@ my $batchnum = $pay_batch->batchnum;
 
 my $fixed = $conf->config("batch-fixed_format-$payby");
 
-tie my %download_formats, 'Tie::IxHash', (
-  '' => 'Default batch mode',
-  'NACHA' => '94 byte NACHA',
-  'csv-td_canada_trust-merchant_pc_batch' => 
-                'CSV file for TD Canada Trust Merchant PC Batch',
-  'csv-chase_canada-E-xactBatch' =>
-                'CSV file for Chase Canada E-xactBatch',
-  'PAP' => '80 byte file for TD Canada Trust PAP Batch',
-  'BoM' => 'Bank of Montreal ECA batch',
-  'ach-spiritone' => 'Spiritone ACH batch',
-  'paymentech' => 'XML file for Chase Paymentech',
-  'RBC' => 'Royal Bank of Canada PDS batch',
-  'td_eft1464' => '1464 byte file for TD Commercial Banking EFT',
-  'eft_canada' => 'EFT Canada CSV batch',
-  'CIBC'       => '80 byte file for Canadian Imperial Bank of Commerce',
-# insert new batch formats here
-);
+tie my %download_formats, 'Tie::IxHash', FS::pay_batch::batch_download_formats;
 
 tie my %upload_formats, 'Tie::IxHash', (
   %download_formats,
@@ -160,7 +144,13 @@ tie my %upload_formats, 'Tie::IxHash', (
   'td_eftret' => 'TD EFT Returned Items',
 );
 delete $upload_formats{'td_eft1464'};
-$upload_formats{'PAP'} = '264 byte results for TD Canada Trust PAP Batch',
+$upload_formats{'PAP'} = '264 byte results for TD Canada Trust PAP Batch';
+
+if ($pay_batch->type eq "CREDIT") {
+  foreach my $key (keys %download_formats) {
+    delete $download_formats{$key} unless FS::pay_batch->can_handle_electronic_refunds($key);
+  }
+}
 
 my %statustext = ( 'O' => 'open', 'I' => 'in transit', 'R' => 'resolved' );
 
diff --git a/httemplate/search/pay_batch.cgi b/httemplate/search/pay_batch.cgi
index 40df5aa56..8fe435132 100755
--- a/httemplate/search/pay_batch.cgi
+++ b/httemplate/search/pay_batch.cgi
@@ -33,9 +33,11 @@
                                     ],
 		 'align'         => 'rcllrrrrc',
 		 'fields'        => [ 'batchnum',
-		                      sub { 
-				        FS::payby->shortname(shift->payby);
-				      },
+		                      sub {
+                my $self = shift;
+                my $type = $self->type eq 'CREDIT' ? 'CREDIT' : '';
+                $type ." " . FS::payby->shortname($self->payby);
+				                  },
                                       sub {
 				        my $self = shift;
 				        my $_date = $self->download;
diff --git a/httemplate/view/cust_main/menu.html b/httemplate/view/cust_main/menu.html
index cc9f1fc71..63d5c9abd 100644
--- a/httemplate/view/cust_main/menu.html
+++ b/httemplate/view/cust_main/menu.html
@@ -467,6 +467,9 @@ my @menu = (
            actionlabel => 'Enter electronic check refund',
            width       => 440,
            acl         => ['Post refund' ],
+           condition   => sub {
+             FS::pay_batch->can_handle_electronic_refunds
+           },
         },
 
       ],
diff --git a/httemplate/view/cust_main/payment_history/payment.html b/httemplate/view/cust_main/payment_history/payment.html
index 6402383d8..eeddc47b1 100644
--- a/httemplate/view/cust_main/payment_history/payment.html
+++ b/httemplate/view/cust_main/payment_history/payment.html
@@ -178,6 +178,7 @@ if (    $cust_pay->closed !~ /^Y/i
             qq! TITLE="! . $refundtitle
             . '">' . emt('refund') . '</A>)';
 }
+$refund = '' if ($cust_pay->batchnum && !FS::pay_batch->can_handle_electronic_refunds);
 
 my $void = '';
 my $voidmsg = $cust_pay->payby =~ /^(CARD|CHEK)$/

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

Summary of changes:
 FS/FS/Cron/pay_batch.pm                            |   2 +-
 FS/FS/Schema.pm                                    |   1 +
 FS/FS/cust_main/Billing_Batch.pm                   |   5 +
 FS/FS/pay_batch.pm                                 | 133 +++++++++++++++++++++
 FS/FS/pay_batch/RBC.pm                             |  23 ++--
 FS/bin/freeside-eftca-upload                       |   6 +-
 FS/bin/freeside-paymentech-upload                  |   1 +
 FS/bin/freeside-rbc-upload                         |   1 +
 httemplate/edit/process/cust_refund.cgi            |   2 +
 httemplate/search/elements/cust_pay_batch_top.html |  26 ++--
 httemplate/search/pay_batch.cgi                    |   8 +-
 httemplate/view/cust_main/menu.html                |   3 +
 .../view/cust_main/payment_history/payment.html    |   1 +
 13 files changed, 176 insertions(+), 36 deletions(-)




More information about the freeside-commits mailing list