From 89d30bbd2b79d9b1de0890eec86234bc9d3ce330 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 21 Dec 2016 15:25:35 -0800 Subject: [PATCH] fix payinfo_used on batch payments with encrypted payinfo, related to #19571 --- FS/FS/cust_pay.pm | 27 ++++++++++++++++++++++++++- FS/FS/cust_pay_batch.pm | 13 +++++++++++++ FS/FS/payinfo_Mixin.pm | 7 +++---- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/FS/FS/cust_pay.pm b/FS/FS/cust_pay.pm index d45d2e397..56de582b8 100644 --- a/FS/FS/cust_pay.pm +++ b/FS/FS/cust_pay.pm @@ -548,7 +548,8 @@ otherwise returns false. sub replace { my $self = shift; - return "Can't modify closed payment" if $self->closed =~ /^Y/i; + return "Can't modify closed payment" + if $self->closed =~ /^Y/i && !$FS::payinfo_Mixin::allow_closed_replace; $self->SUPER::replace(@_); } @@ -1252,6 +1253,30 @@ sub _upgrade_data { #class method ### #$class->upgrade_set_cardtype; + # for batch payments, make sure paymask is set + do { + local $FS::payinfo_Mixin::allow_closed_replace = 1; + local $FS::payinfo_Mixin::ignore_masked_payinfo = 1; + + my $cursor = FS::Cursor->new({ + table => 'cust_pay', + extra_sql => ' WHERE paymask IS NULL AND payinfo IS NOT NULL + AND payby IN(\'CARD\', \'CHEK\') + AND batchnum IS NOT NULL', + }); + + # records from cursors for some reason don't decrypt payinfo, so + # call replace_old to fetch the record "normally" + while (my $cust_pay = $cursor->fetch) { + $cust_pay = $cust_pay->replace_old; + $cust_pay->set('paymask', $cust_pay->mask_payinfo); + my $error = $cust_pay->replace; + if ($error) { + die "$error (setting masked payinfo on payment#". $cust_pay->paynum. + ")\n" + } + } + }; } sub process_upgrade_paybatch { diff --git a/FS/FS/cust_pay_batch.pm b/FS/FS/cust_pay_batch.pm index 774ea2961..a4129dc49 100644 --- a/FS/FS/cust_pay_batch.pm +++ b/FS/FS/cust_pay_batch.pm @@ -332,6 +332,7 @@ sub approve { 'custnum' => $new->custnum, 'payby' => $new->payby, 'payinfo' => $new->payinfo || $old->payinfo, + 'paymask' => $new->mask_payinfo, 'paid' => $new->paid, '_date' => $new->_date, 'usernum' => $new->usernum, @@ -458,6 +459,17 @@ sub request_item { die "unsupported BatchPayment method: ".$pay_batch->payby; } + my $recurring; + if ( $cust_main->status =~ /^active|suspended|ordered$/ ) { + if ( $self->payinfo_used ) { + $recurring = 'S'; # subsequent + } else { + $recurring = 'F'; # first use + } + } else { + $recurring = 'N'; # non-recurring + } + Business::BatchPayment->create(Item => # required action => 'payment', @@ -473,6 +485,7 @@ sub request_item { ( map { $_ => $location->$_ } qw(address2 city state country zip) ), invoice_number => $self->invnum, + recurring_billing => $recurring, %payment, ); } diff --git a/FS/FS/payinfo_Mixin.pm b/FS/FS/payinfo_Mixin.pm index 4da40e326..520b2458b 100644 --- a/FS/FS/payinfo_Mixin.pm +++ b/FS/FS/payinfo_Mixin.pm @@ -8,7 +8,7 @@ use FS::UID qw(driver_name); use FS::Cursor; use Time::Local qw(timelocal); -use vars qw($ignore_masked_payinfo); +use vars qw( $ignore_masked_payinfo $allow_closed_replace ); =head1 NAME @@ -308,13 +308,12 @@ sub payinfo_used { my $payinfo = shift || $self->payinfo; my %hash = ( 'custnum' => $self->custnum, - 'payby' => 'CARD', + 'payby' => $self->payby, ); return 1 if qsearch('cust_pay', { %hash, 'payinfo' => $payinfo } ) - || qsearch('cust_pay', - { %hash, 'paymask' => $self->mask_payinfo('CARD', $payinfo) } ) + || qsearch('cust_pay', { %hash, 'paymask' => $self->mask_payinfo } ) ; return 0; -- 2.11.0