@fuzzyfields = ( 'first', 'last', 'company', 'address1' );
@encrypted_fields = ('payinfo', 'paycvv');
-sub nohistory_fields { ('paycvv'); }
+sub nohistory_fields { ('payinfo', 'paycvv'); }
@paytypes = ('', 'Personal checking', 'Personal savings', 'Business checking', 'Business savings');
}
- if ( $self->payby =~ /^(CARD|CHEK|LECB)$/ &&
- grep { $self->get($_) ne $old->get($_) } qw(payinfo paydate payname) ) {
+ if ( $self->payby =~ /^(CARD|CHEK|LECB)$/
+ && ( ( $self->get('payinfo') ne $old->get('payinfo')
+ && $self->get('payinfo') !~ /^99\d{14}$/
+ )
+ || grep { $self->get($_) ne $old->get($_) } qw(paydate payname)
+ )
+ )
+ {
+
# card/check/lec info has changed, want to retry realtime_ invoice events
my $error = $self->retry_realtime;
if ( $error ) {
# If it is encrypted and the private key is not availaible then we can't
# check the credit card.
-
- my $check_payinfo = 1;
-
- if ($self->is_encrypted($self->payinfo)) {
- $check_payinfo = 0;
- }
+ my $check_payinfo = ! $self->is_encrypted($self->payinfo);
if ( $check_payinfo && $self->payby =~ /^(CARD|DCRD)$/ ) {
or return gettext('invalid_card'); # . ": ". $self->payinfo;
return gettext('unknown_card_type')
- if cardtype($self->payinfo) eq "Unknown";
+ if $self->payinfo !~ /^99\d{14}$/ #token
+ && cardtype($self->payinfo) eq "Unknown";
my $ban = qsearchs('banned_pay', $self->_banned_pay_hashref);
if ( $ban ) {
$options->{payment_gateway}->gatewaynum
? $options->{payment_gateway}->options
: @{ $options->{payment_gateway}->get('options') };
+
}
sub _bop_defaults {
my $BOP_TESTING_SUCCESS = 1;
unless ( $BOP_TESTING ) {
+ $transaction->test_transaction(1)
+ if $conf->exists('business-onlinepayment-test_transaction');
$transaction->submit();
} else {
if ( $BOP_TESTING_SUCCESS ) {
$capture->content( %capture );
+ $capture->test_transaction(1)
+ if $conf->exists('business-onlinepayment-test_transaction');
$capture->submit();
unless ( $capture->is_success ) {
}
###
+ # Tokenize
+ ###
+
+
+ if ( $transaction->can('card_token') && $transaction->card_token ) {
+
+ $self->card_token($transaction->card_token);
+
+ if ( $options{'payinfo'} eq $self->payinfo ) {
+ $self->payinfo($transaction->card_token);
+ my $error = $self->replace;
+ if ( $error ) {
+ warn "WARNING: error storing token: $error, but proceeding anyway\n";
+ }
+ }
+
+ }
+
+ ###
# result handling
###
'paid' => $cust_pay_pending->paid,
'_date' => '',
'payby' => $cust_pay_pending->payby,
- #'payinfo' => $payinfo,
+ 'payinfo' => $options{'payinfo'},
'paybatch' => $paybatch,
'paydate' => $cust_pay_pending->paydate,
'pkgnum' => $cust_pay_pending->pkgnum,
my $self = shift;
my %options = ();
- if (ref($_[0]) ne 'HASH') {
+ if (ref($_[0]) eq 'HASH') {
%options = %{$_[0]};
} else {
my $method = shift;
}
}
$void->content( 'action' => 'void', %content );
+ $void->test_transaction(1)
+ if $conf->exists('business-onlinepayment-test_transaction');
$void->submit();
if ( $void->is_success ) {
my $error = $cust_pay->void($options{'reason'});
);
warn join('', map { " $_ => $sub_content{$_}\n" } keys %sub_content )
if $DEBUG > 1;
+ $refund->test_transaction(1)
+ if $conf->exists('business-onlinepayment-test_transaction');
$refund->submit();
return "$processor error: ". $refund->error_message
my $self = shift;
my $time = shift;
-# my $custnum = $self->custnum;
-#
-# my $owed_sql = FS::cust_bill->owed_sql;
-#
-# my $sql = "
-# SELECT SUM($owed_sql) FROM cust_bill
-# WHERE custnum = $custnum
-# AND _date <= $time
-# ";
-#
-# my $sth = dbh->prepare($sql) or die dbh->errstr;
-# $sth->execute() or die $sth->errstr;
-#
-# return sprintf( '%.2f', $sth->fetchrow_arrayref->[0] );
+ my $custnum = $self->custnum;
- my $total_bill = 0;
- foreach my $cust_bill (
- grep { $_->_date <= $time }
- qsearch('cust_bill', { 'custnum' => $self->custnum, } )
- ) {
- $total_bill += $cust_bill->owed;
- }
- sprintf( "%.2f", $total_bill );
+ my $owed_sql = FS::cust_bill->owed_sql;
+
+ my $sql = "
+ SELECT SUM($owed_sql) FROM cust_bill
+ WHERE custnum = $custnum
+ AND _date <= $time
+ ";
+
+ sprintf( "%.2f", $self->scalar_sql($sql) );
}
sub total_unapplied_credits {
my $self = shift;
- my $total_credit = 0;
- $total_credit += $_->credited foreach $self->cust_credit;
- sprintf( "%.2f", $total_credit );
+
+ my $custnum = $self->custnum;
+
+ my $unapplied_sql = FS::cust_credit->unapplied_sql;
+
+ my $sql = "
+ SELECT SUM($unapplied_sql) FROM cust_credit
+ WHERE custnum = $custnum
+ ";
+
+ sprintf( "%.2f", $self->scalar_sql($sql) );
+
}
=item total_unapplied_credits_pkgnum PKGNUM
sub total_unapplied_payments {
my $self = shift;
- my $total_unapplied = 0;
- $total_unapplied += $_->unapplied foreach $self->cust_pay;
- sprintf( "%.2f", $total_unapplied );
+
+ my $custnum = $self->custnum;
+
+ my $unapplied_sql = FS::cust_pay->unapplied_sql;
+
+ my $sql = "
+ SELECT SUM($unapplied_sql) FROM cust_pay
+ WHERE custnum = $custnum
+ ";
+
+ sprintf( "%.2f", $self->scalar_sql($sql) );
+
}
=item total_unapplied_payments_pkgnum PKGNUM
sub total_unapplied_refunds {
my $self = shift;
- my $total_unapplied = 0;
- $total_unapplied += $_->unapplied foreach $self->cust_refund;
- sprintf( "%.2f", $total_unapplied );
+ my $custnum = $self->custnum;
+
+ my $unapplied_sql = FS::cust_refund->unapplied_sql;
+
+ my $sql = "
+ SELECT SUM($unapplied_sql) FROM cust_refund
+ WHERE custnum = $custnum
+ ";
+
+ sprintf( "%.2f", $self->scalar_sql($sql) );
+
}
=item balance
sub balance {
my $self = shift;
- sprintf( "%.2f",
- $self->total_owed
- + $self->total_unapplied_refunds
- - $self->total_unapplied_credits
- - $self->total_unapplied_payments
- );
+ $self->balance_date_range;
}
=item balance_date TIME
sub balance_date {
my $self = shift;
- my $time = shift;
- sprintf( "%.2f",
- $self->total_owed_date($time)
- + $self->total_unapplied_refunds
- - $self->total_unapplied_credits
- - $self->total_unapplied_payments
- );
+ $self->balance_date_range(shift);
}
-=item balance_date_range START_TIME [ END_TIME [ OPTION => VALUE ... ] ]
+=item balance_date_range [ START_TIME [ END_TIME [ OPTION => VALUE ... ] ] ]
-Returns the balance for this customer, only considering invoices with date
-earlier than START_TIME, and optionally not later than END_TIME
+Returns the balance for this customer, optionally considering invoices with
+date earlier than START_TIME, and not later than END_TIME
(total_owed_date minus total_unapplied_credits minus total_unapplied_payments).
Times are specified as SQL fragments or numeric
WHERE cust_refund.custnum = cust_main.custnum )
"; }
-=item balance_date_sql START_TIME [ END_TIME [ OPTION => VALUE ... ] ]
+=item balance_date_sql [ START_TIME [ END_TIME [ OPTION => VALUE ... ] ] ]
-Returns an SQL fragment to retreive the balance for this customer, only
-considering invoices with date earlier than START_TIME, and optionally not
+Returns an SQL fragment to retreive the balance for this customer, optionally
+considering invoices with date earlier than START_TIME, and not
later than END_TIME (total_owed_date minus total_unapplied_credits minus
total_unapplied_payments).
=cut
sub unapplied_payments_date_sql {
- my( $class, $start, $end, ) = @_;
+ my( $class, $start, $end, %opt ) = @_;
+
+ my $cutoff = $opt{'cutoff'};
- my $unapp_pay = FS::cust_pay->unapplied_sql;
+ my $unapp_pay = FS::cust_pay->unapplied_sql($cutoff);
my $pay_where = $class->_money_table_where( 'cust_pay', $start, $end,
'unapplied_date'=>1 );
}
+=item queued_bill 'custnum' => CUSTNUM [ , OPTION => VALUE ... ]
+
+Subroutine (not a method), designed to be called from the queue.
+
+Takes a list of options and values.
+
+Pulls up the customer record via the custnum option and calls bill_and_collect.
+
+=cut
+
sub queued_bill {
- ## actual sub, not a method, designed to be called from the queue.
- ## sets up the customer, and calls the bill_and_collect
my (%args) = @_; #, ($time, $invoice_time, $check_freq, $resetup) = @_;
+
my $cust_main = qsearchs( 'cust_main', { custnum => $args{'custnum'} } );
- $cust_main->bill_and_collect(
- %args,
- );
+ warn 'bill_and_collect custnum#'. $cust_main->custnum. "\n";#log custnum w/pid
+
+ $cust_main->bill_and_collect( %args );
}
sub _upgrade_data { #class method