[freeside-commits] branch master updated. 61097b876e692dbf5571a17b9aa415949607085f

Mark Wells mark at 420.am
Wed Jan 30 12:09:51 PST 2013


The branch, master has been updated
       via  61097b876e692dbf5571a17b9aa415949607085f (commit)
       via  6bd91fa5feb41ea3294bdaee5fe1c1134f19c330 (commit)
      from  30ee235522ce53a21dd3c1597000663d25685ac4 (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 61097b876e692dbf5571a17b9aa415949607085f
Author: Mark Wells <mark at freeside.biz>
Date:   Tue Jan 29 16:28:26 2013 -0800

    record and show batch payment status info, #21117

diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index 70928a8..de3659a 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -1695,6 +1695,7 @@ sub tables_hashref {
         'payname',  'varchar', 'NULL', $char_d, '', '', 
         'amount',   @money_type, '', '', 
         'status',   'varchar', 'NULL', $char_d, '', '', 
+        'error_message',   'varchar', 'NULL', $char_d, '', '',
       ],
       'primary_key' => 'paybatchnum',
       'unique' => [],
diff --git a/FS/FS/cust_pay_batch.pm b/FS/FS/cust_pay_batch.pm
index 9f2e9dd..4138436 100644
--- a/FS/FS/cust_pay_batch.pm
+++ b/FS/FS/cust_pay_batch.pm
@@ -9,7 +9,7 @@ use FS::payinfo_Mixin;
 use FS::cust_main;
 use FS::cust_bill;
 
- at ISA = qw( FS::payinfo_Mixin FS::Record );
+ at ISA = qw( FS::payinfo_Mixin FS::cust_main_Mixin FS::Record );
 
 # 1 is mostly method/subroutine entry and options
 # 2 traces progress of some operations
@@ -80,7 +80,9 @@ following fields are currently supported:
 
 =item country 
 
-=item status
+=item status - 'Approved' or 'Declined'
+
+=item error_message - the error returned by the gateway if any
 
 =back
 
@@ -289,19 +291,21 @@ sub retriable {
   '';
 }
 
-=item approve PAYBATCH
+=item approve OPTIONS
 
 Approve this payment.  This will replace the existing record with the 
 same paybatchnum, set its status to 'Approved', and generate a payment 
 record (L<FS::cust_pay>).  This should only be called from the batch 
 import process.
 
+OPTIONS may contain "gatewaynum", "processor", "auth", and "order_number".
+
 =cut
 
 sub approve {
   # to break up the Big Wall of Code that is import_results
   my $new = shift;
-  my $paybatch = shift;
+  my %opt = @_;
   my $paybatchnum = $new->paybatchnum;
   my $old = qsearchs('cust_pay_batch', { paybatchnum => $paybatchnum })
     or return "paybatchnum $paybatchnum not found";
@@ -317,13 +321,17 @@ sub approve {
   my $cust_pay = new FS::cust_pay ( {
       'custnum'   => $new->custnum,
       'payby'     => $new->payby,
-      'paybatch'  => $paybatch,
       'payinfo'   => $new->payinfo || $old->payinfo,
       'paid'      => $new->paid,
       '_date'     => $new->_date,
       'usernum'   => $new->usernum,
       'batchnum'  => $new->batchnum,
+      'gatewaynum'    => $opt{'gatewaynum'},
+      'processor'     => $opt{'processor'},
+      'auth'          => $opt{'auth'},
+      'order_number'  => $opt{'order_number'} 
     } );
+
   $error = $cust_pay->insert;
   if ( $error ) {
     return "error inserting payment for paybatchnum $paybatchnum: $error\n";
@@ -375,6 +383,7 @@ sub decline {
     }
   } # !$old->status
   $new->status('Declined');
+  $new->error_message($reason);
   my $error = $new->replace($old);
   if ( $error ) {
     return "error updating status of paybatchnum $paybatchnum: $error\n";
diff --git a/FS/FS/pay_batch.pm b/FS/FS/pay_batch.pm
index 0274914..2a048a1 100644
--- a/FS/FS/pay_batch.pm
+++ b/FS/FS/pay_batch.pm
@@ -401,12 +401,12 @@ sub import_results {
       foreach ('paid', '_date', 'payinfo') {
         $new_cust_pay_batch->$_($hash{$_}) if $hash{$_};
       }
-      $error = $new_cust_pay_batch->approve($hash{'paybatch'} || $self->batchnum);
+      $error = $new_cust_pay_batch->approve(%hash);
       $total += $hash{'paid'};
 
     } elsif ( &{$declined_condition}(\%hash) ) {
 
-      $error = $new_cust_pay_batch->decline;
+      $error = $new_cust_pay_batch->decline($hash{'error_message'});;
 
     }
 
@@ -572,8 +572,6 @@ sub import_from_gateway {
       my $payby; # CARD or CHEK
       my $error;
 
-      # follow realtime gateway practice here
-      # though eventually this stuff should go into separate fields...
       my $paybatch = $gateway->gatewaynum .  '-' .  $gateway->gateway_module .
         ':' . $item->authorization .  ':' . $item->order_number;
 
@@ -644,8 +642,11 @@ sub import_from_gateway {
             payby       => $payby,
             invnum      => $item->invoice_number,
             batchnum    => $pay_batch->batchnum,
-            paybatch    => $paybatch,
             payinfo     => $payinfo,
+            gatewaynum  => $gateway->gatewaynum,
+            processor   => $gateway->gateway_module,
+            auth        => $item->authorization,
+            order_number => $item->order_number,
           }
         );
         $error ||= $cust_pay->insert;
@@ -725,7 +726,12 @@ sub import_from_gateway {
         # approval status
         if ( $item->approved ) {
           # follow Billing_Realtime format for paybatch
-          $error = $cust_pay_batch->approve($paybatch);
+          $error = $cust_pay_batch->approve(
+            'gatewaynum'    => $gateway->gatewaynum,
+            'processor'     => $gateway->gateway_module,
+            'auth'          => $item->authorization,
+            'order_number'  => $item->order_number,
+          );
           $total += $cust_pay_batch->paid;
         }
         else {
@@ -829,6 +835,9 @@ sub try_to_resolve {
       }
       return $error if $error;
     }
+  } elsif ( @unresolved ) {
+    # auto resolve is not enabled, and we're not ready to resolve
+    return;
   }
 
   $self->set_status('R');
@@ -1028,7 +1037,6 @@ sub manual_approve {
   my $self = shift;
   my $date = time;
   my %opt = @_;
-  my $paybatch = $opt{'paybatch'} || $self->batchnum;
   my $usernum = $opt{'usernum'} || die "manual approval requires a usernum";
   my $conf = FS::Conf->new;
   return 'manual batch approval disabled' 
@@ -1058,7 +1066,9 @@ sub manual_approve {
       '_date'   => $date,
       'usernum' => $usernum,
     };
-    my $error = $new_cust_pay_batch->approve($paybatch);
+    my $error = $new_cust_pay_batch->approve();
+    # there are no approval options here (authorization, order_number, etc.)
+    # because the transaction wasn't really approved
     if ( $error ) {
       $dbh->rollback;
       return 'paybatchnum '.$cust_pay_batch->paybatchnum.": $error";
diff --git a/FS/FS/pay_batch/paymentech.pm b/FS/FS/pay_batch/paymentech.pm
index c75903d..47be4eb 100644
--- a/FS/FS/pay_batch/paymentech.pm
+++ b/FS/FS/pay_batch/paymentech.pm
@@ -23,7 +23,10 @@ my $gateway;
     '_date',
     'approvalStatus',
     'order_number',
-    'authorization',
+    'auth',
+    'procStatus',
+    'procStatusMessage',
+    'respCodeMessage',
     ],
   xmlkeys     => [
     'orderID',
@@ -31,6 +34,9 @@ my $gateway;
     'approvalStatus',
     'txRefNum',
     'authorizationCode',
+    'procStatus',
+    'procStatusMessage',
+    'respCodeMessage',
     ],
   'hook'        => sub {
       if ( !$gateway ) {
@@ -38,7 +44,7 @@ my $gateway;
         # as the batch config, if there is one.  If not, leave 
         # gateway out entirely.
         my $merchant = (FS::Conf->new->config('batchconfig-paymentech'))[2];
-        my $g = qsearchs({
+        $gateway = qsearchs({
               'table'     => 'payment_gateway',
               'addl_from' => ' JOIN payment_gateway_option USING (gatewaynum) ',
               'hashref'   => {  disabled    => '',
@@ -46,18 +52,19 @@ my $gateway;
                                 optionvalue => $merchant,
                               },
               });
-        $gateway = ($g ? $g->gatewaynum . '-' : '') . 'PaymenTech';
       }
       my ($hash, $oldhash) = @_;
+      $hash->{'gatewaynum'} = $gateway->gatewaynum if $gateway;
+      $hash->{'processor'} = 'PaymenTech';
       my ($mon, $day, $year, $hour, $min, $sec) = 
         $hash->{'_date'} =~ /^(..)(..)(....)(..)(..)(..)$/;
       $hash->{'_date'} = timelocal($sec, $min, $hour, $day, $mon-1, $year);
       $hash->{'paid'} = $oldhash->{'amount'};
-      $hash->{'paybatch'} = join(':', 
-        $gateway,
-        $hash->{'authorization'},
-        $hash->{'order_number'},
-      );
+      if ( $hash->{'procStatus'} == 0 ) {
+        $hash->{'error_message'} = $hash->{'respCodeMessage'};
+      } else {
+        $hash->{'error_message'} = $hash->{'procStatusMessage'};
+      }
     },
   'approved'    => sub { my $hash = shift;
                             $hash->{'approvalStatus'} 
diff --git a/httemplate/search/cust_pay_batch.cgi b/httemplate/search/cust_pay_batch.cgi
index 800df87..830a6c6 100755
--- a/httemplate/search/cust_pay_batch.cgi
+++ b/httemplate/search/cust_pay_batch.cgi
@@ -7,53 +7,40 @@
               'disable_download' => 1,
 	      'header'      => [ '#',
 	                         'Inv #',
-	                         'Customer',
+                                 'Cust #',
 	                         'Customer',
 	                         'Card Name',
 	                         'Card',
 	                         'Exp',
 	                         'Amount',
 	                         'Status',
+                                 '', # error_message
 			       ],
-	      'fields'      => [ sub {
-	                           shift->[0];
-				 },
-	                         sub {
-	                           shift->[1];
-				 },
-	                         sub {
-	                           shift->[2];
-				 },
-			  	 sub {
-	                           my $cpb = shift;
-				   $cpb->[3] . ', ' . $cpb->[4];
-				 },
-	                         sub {
-	                           shift->[5];
-				 },
-				 sub {
-	                           my $cardnum = shift->[6];
-                                   'x'x(length($cardnum)-4). substr($cardnum,(length($cardnum)-4));
-				 },
-				 sub {
-				   shift->[7] =~ /^\d{2}(\d{2})[\/\-](\d+)[\/\-]\d+$/;
-                                   my( $mon, $year ) = ( $2, $1 );
-                                   $mon = "0$mon" if length($mon) == 1;
-                                   "$mon/$year";
-				 },
-	                         sub {
-	                           shift->[8];
-				 },
-	                         sub {
-	                           shift->[9];
-				 },
-			       ],
-	      'align'       => 'lllllllrl',
-	      'links'       => [ ['', sub{'#';}],
-	                         ["${p}view/cust_bill.cgi?", sub{shift->[1];},],
-	                         ["${p}view/cust_main.cgi?", sub{shift->[2];},],
-	                         ["${p}view/cust_main.cgi?", sub{shift->[2];},],
+              'fields'      => [  'paybatchnum',
+                                  'invnum',
+                                  'custnum',
+                                  sub { $_[0]->cust_main->name_short },
+                                  'payname',
+                                  'mask_payinfo',
+                                  sub {
+                                    return('') if $_[0]->payby ne 'CARD';
+                                    $_[0]->get('exp') =~ /^\d\d(\d\d)-(\d\d)/;
+                                    sprintf('%02d/%02d',$1,$2);
+                                  },
+                                  sub {
+                                    sprintf('%.02f', $_[0]->amount)
+                                  },
+                                  'status',
+                                  'error_message',
+                                ],
+	      'align'       => 'rrrlllcrll',
+	      'links'       => [ '',
+	                         ["${p}view/cust_bill.cgi?", 'invnum'],
+	                         (["${p}view/cust_main.cgi?", 'custnum']) x 2,
 			       ],
+              'link_onclicks' => [ ('') x 8,
+                                   $sub_receipt
+                                 ],
       )
 %>
 <%init>
@@ -124,13 +111,25 @@ $count_query = 'SELECT COUNT(*) FROM cust_pay_batch AS cpb ' .
                   'LEFT JOIN pay_batch USING ( batchnum )' .
 		  $search;
 
-#grr
-$sql_query = "SELECT paybatchnum,invnum,custnum,cpb.last,cpb.first," .
-             "cpb.payname,cpb.payinfo,cpb.exp,amount,cpb.status " .
-	     "FROM cust_pay_batch AS cpb " .
-             'LEFT JOIN cust_main USING ( custnum ) ' .
-             'LEFT JOIN pay_batch USING ( batchnum ) ' .
-             "$search ORDER BY $orderby";
+$sql_query = {
+  'table'     => 'cust_pay_batch',
+  'select'    => 'cust_pay_batch.*, cust_main.*, cust_pay.paynum',
+  'hashref'   => {},
+  'addl_from' => 'LEFT JOIN pay_batch USING ( batchnum ) '.
+                 'LEFT JOIN cust_main USING ( custnum ) '.
+                 
+                 'LEFT JOIN cust_pay  USING ( batchnum, custnum ) ',
+  'extra_sql' => $search,
+  'order_by'  => "ORDER BY $orderby",
+};
+
+my $sub_receipt = sub {
+  my $paynum = shift->paynum or return '';
+  include('/elements/popup_link_onclick.html',
+    'action'  => $p.'view/cust_pay.html?link=popup;paynum='.$paynum,
+    'actionlabel' => emt('Payment Receipt'),
+  );
+};
 
 my $html_init = '';
 if ( $pay_batch ) {
diff --git a/httemplate/search/elements/cust_pay_or_refund.html b/httemplate/search/elements/cust_pay_or_refund.html
index eeef0c0..b9da7ef 100755
--- a/httemplate/search/elements/cust_pay_or_refund.html
+++ b/httemplate/search/elements/cust_pay_or_refund.html
@@ -51,6 +51,7 @@ Examples:
                 'sort_fields'    => \@sort_fields,
                 'align'          => $align,
                 'links'          => \@links,
+                'link_onclicks'  => \@link_onclicks,
                 'color'          => \@color,
                 'style'          => \@style,
 &>
@@ -134,11 +135,12 @@ if ( $cgi->param('tax_names') ) {
   }
 }
 
-my @header = ();
-my @fields = ();
-my @sort_fields = ();
+my @header;
+my @fields;
+my @sort_fields;
 my $align = '';
-my @links = ();
+my @links;
+my @link_onclicks;
 if ( $opt{'pre_header'} ) {
   push @header, @{ $opt{'pre_header'} };
   $align .= 'c' x scalar(@{ $opt{'pre_header'} });
@@ -147,6 +149,16 @@ if ( $opt{'pre_header'} ) {
   push @sort_fields, @{ $opt{'pre_fields'} };
 }
 
+my $sub_receipt = sub {
+  my $obj = shift;
+  my $objnum = $obj->primary_key . '=' . $obj->get($obj->primary_key);
+
+  include('/elements/popup_link_onclick.html',
+    'action'  => $p.'view/cust_pay.html?link=popup;'.$objnum,
+    'actionlabel' => emt('Payment Receipt'),
+  );
+};
+
 push @header, "\u$name_singular",
               'Amount',
 ;
@@ -155,6 +167,7 @@ push @links, '', '';
 push @fields, 'payby_payinfo_pretty',
               sub { sprintf('$%.2f', shift->$amount_field() ) },
 ;
+push @link_onclicks, $sub_receipt, '',
 push @sort_fields, '', $amount_field;
 
 if ( $unapplied ) {

commit 6bd91fa5feb41ea3294bdaee5fe1c1134f19c330
Author: Mark Wells <mark at freeside.biz>
Date:   Tue Jan 29 16:27:17 2013 -0800

    fix warning

diff --git a/FS/FS/cust_main/Billing.pm b/FS/FS/cust_main/Billing.pm
index deb5e84..69fbda4 100644
--- a/FS/FS/cust_main/Billing.pm
+++ b/FS/FS/cust_main/Billing.pm
@@ -1819,8 +1819,9 @@ sub due_cust_event {
 
   #???
   #my $DEBUG = $opt{'debug'}
+  $opt{'debug'} ||= 0; # silence some warnings
   local($DEBUG) = $opt{'debug'}
-    if defined($opt{'debug'}) && $opt{'debug'} > $DEBUG;
+    if $opt{'debug'} > $DEBUG;
   $DEBUG = $FS::cust_main::DEBUG if $FS::cust_main::DEBUG > $DEBUG;
 
   warn "$me due_cust_event called with options ".

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

Summary of changes:
 FS/FS/Schema.pm                                    |    1 +
 FS/FS/cust_main/Billing.pm                         |    3 +-
 FS/FS/cust_pay_batch.pm                            |   19 +++-
 FS/FS/pay_batch.pm                                 |   26 ++++--
 FS/FS/pay_batch/paymentech.pm                      |   23 +++--
 httemplate/search/cust_pay_batch.cgi               |   91 ++++++++++----------
 httemplate/search/elements/cust_pay_or_refund.html |   21 ++++-
 7 files changed, 112 insertions(+), 72 deletions(-)




More information about the freeside-commits mailing list