[freeside-commits] branch master updated. b48c02a92562395c84dbfe8c47db5c4ba14891a0

Christopher Burger burgerc at freeside.biz
Sun Mar 10 16:21:34 PDT 2019


The branch, master has been updated
       via  b48c02a92562395c84dbfe8c47db5c4ba14891a0 (commit)
      from  765aac1902113738afd1bcaee8eb25b44ee92e63 (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 b48c02a92562395c84dbfe8c47db5c4ba14891a0
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 fc22d6c4f..8cc8416de 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -2711,6 +2711,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 0e713e937..c1bb35f04 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                             |  11 +-
 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, 173 insertions(+), 27 deletions(-)




More information about the freeside-commits mailing list