fix recording of BOP refunds, fallout from #39398
authorMark Wells <mark@freeside.biz>
Tue, 2 Feb 2016 23:51:58 +0000 (15:51 -0800)
committerMark Wells <mark@freeside.biz>
Tue, 2 Feb 2016 23:53:44 +0000 (15:53 -0800)
FS/FS/cust_main/Billing_Realtime.pm
FS/FS/cust_refund.pm
httemplate/edit/process/cust_refund.cgi

index f33c454..61acb1d 100644 (file)
@@ -1311,14 +1311,14 @@ L<http://420.am/business-onlinepayment> for supported gateways.
 
 Available methods are: I<CC>, I<ECHECK> and I<LEC>
 
-Available options are: I<amount>, I<reason>, I<paynum>, I<paydate>
+Available options are: I<amount>, I<reasonnum>, I<paynum>, I<paydate>
 
 Most gateways require a reference to an original payment transaction to refund,
 so you probably need to specify a I<paynum>.
 
 I<amount> defaults to the original amount of the payment if not specified.
 
-I<reason> specifies a reason for the refund.
+I<reasonnum> specifies a reason for the refund.
 
 I<paydate> specifies the expiration date for a credit card overriding the
 value from the customer record or the payment record. Specified as yyyy-mm-dd
@@ -1356,6 +1356,27 @@ sub realtime_refund_bop {
     $options{method} = $method;
   }
 
+  my ($reason, $reason_text);
+  if ( $options{'reasonnum'} ) {
+    # do this here, because we need the plain text reason string in case we
+    # void the payment
+    $reason = FS::reason->by_key($options{'reasonnum'});
+    $reason_text = $reason->reason;
+  } else {
+    # support old 'reason' string parameter in case it's still used,
+    # or else set a default
+    $reason_text = $options{'reason'} || 'card or ACH refund';
+    local $@;
+    $reason = FS::reason->new_or_existing(
+      reason  => $reason_text,
+      type    => 'Refund reason',
+      class   => 'F',
+    );
+    if ($@) {
+      return "failed to add refund reason: $@";
+    }
+  }
+
   if ( $DEBUG ) {
     warn "$me realtime_refund_bop (new): $options{method} refund\n";
     warn "  $_ => $options{$_}\n" foreach keys %options;
@@ -1523,7 +1544,7 @@ sub realtime_refund_bop {
       if $conf->exists('business-onlinepayment-test_transaction');
     $void->submit();
     if ( $void->is_success ) {
-      my $error = $cust_pay->void($options{'reason'});
+      my $error = $cust_pay->void($reason_text);
       if ( $error ) {
         # gah, even with transactions.
         my $e = 'WARNING: Card/ACH voided but database not updated - '.
@@ -1648,7 +1669,7 @@ sub realtime_refund_bop {
     '_date'    => '',
     'payby'    => $bop_method2payby{$options{method}},
     'payinfo'  => $payinfo,
-    'reason'   => $options{'reason'} || 'card or ACH refund',
+    'reasonnum'   => $reason->reasonnum,
     'gatewaynum'    => $gatewaynum, # may be null
     'processor'     => $processor,
     'auth'          => $refund->authorization,
index 15335a4..74728a6 100644 (file)
@@ -145,19 +145,21 @@ sub insert {
   my $dbh = dbh;
 
   unless ($self->reasonnum) {
-    my $result = $self->reason( $self->getfield('reason'),
-                                exists($options{ 'reason_type' })
-                                  ? ('reason_type' => $options{ 'reason_type' })
-                                  : (),
-                              );
-    unless($result) {
-      $dbh->rollback if $oldAutoCommit;
-      return "failed to set reason for $me"; #: ". $dbh->errstr;
+    local $@;
+    if ( $self->get('reason') ) {
+      my $reason = FS::reason->new_or_existing(
+        reason  => $self->get('reason'),
+        class   => 'F',
+        type    => 'Refund reason',
+      );
+      if ($@) {
+        return "failed to add refund reason: $@";
+      }
+      $self->set('reasonnum', $reason->get('reasonnum'));
+      $self->set('reason', '');
     }
   }
 
-  $self->setfield('reason', '');
-
   if ( $self->crednum ) {
     my $cust_credit = qsearchs('cust_credit', { 'crednum' => $self->crednum } )
       or do {
index 6ad468b..764f2de 100755 (executable)
@@ -47,12 +47,11 @@ if ( $error ) {
   my $refund = "$1$2";
   $cgi->param('paynum') =~ /^(\d*)$/ or die "Illegal paynum!";
   my $paynum = $1;
-  my $reason = $cgi->param('reason');
   my $paydate = $cgi->param('exp_year'). '-'. $cgi->param('exp_month'). '-01';
   $options{'paydate'} = $paydate if $paydate =~ /^\d{2,4}-\d{1,2}-01$/;
   $error = $cust_main->realtime_refund_bop( $bop, 'amount' => $refund,
                                                   'paynum' => $paynum,
-                                                  'reason' => $reason,
+                                                  'reasonnum' => $reasonnum,
                                                   %options );
 } else {
   my %hash = map {