default to a session cookie instead of setting an explicit timeout, weird timezone...
[freeside.git] / FS / FS / cust_payby.pm
index 301eb61..03864ef 100644 (file)
@@ -1,5 +1,6 @@
 package FS::cust_payby;
 use base qw( FS::payinfo_Mixin FS::cust_main_Mixin FS::Record );
+use feature 'state';
 
 use strict;
 use Scalar::Util qw( blessed );
@@ -159,9 +160,8 @@ sub insert {
   local $FS::UID::AutoCommit = 0;
   my $dbh = dbh;
 
-  my $error =  $self->check_payinfo_cardtype if $self->payby =~/^(CARD|DCRD)$/;
-  $self->SUPER::insert unless $error;
-
+  my $error =  $self->check_payinfo_cardtype
+            || $self->SUPER::insert;
   if ( $error ) {
     $dbh->rollback if $oldAutoCommit;
     return $error;
@@ -347,14 +347,16 @@ sub check {
   if ( !$ignore_invalid_card && 
     $check_payinfo && $self->payby =~ /^(CARD|DCRD)$/ ) {
 
-    my $payinfo = $self->payinfo;
-    $payinfo =~ s/\D//g;
-    $payinfo =~ /^(\d{13,19}|\d{8,9})$/
-      or return gettext('invalid_card'); #. ": ". $self->payinfo;
-    $payinfo = $1;
-    $self->payinfo($payinfo);
-    validate($payinfo)
-      or return gettext('invalid_card'); # . ": ". $self->payinfo;
+    unless ( $self->tokenized ) {
+      my $payinfo = $self->payinfo;
+      $payinfo =~ s/\D//g;
+      $payinfo =~ /^(\d{13,19}|\d{8,9})$/
+        or return gettext('invalid_card'); #. ": ". $self->payinfo;
+      $payinfo = $1;
+      $self->payinfo($payinfo);
+      validate($payinfo)
+        or return gettext('invalid_card'); # . ": ". $self->payinfo;
+    }
 
     # see parallel checks in check_payinfo_cardtype & payinfo_Mixin::payinfo_check
     my $cardtype = $self->paycardtype;
@@ -556,7 +558,7 @@ sub check_payinfo_cardtype {
 
   return '' if $ignore_cardtype;
 
-  return '' unless $self->payby =~ /^(CARD|CHEK)$/;
+  return '' unless $self->payby =~ /^(CARD|DCRD)$/;
 
   my $payinfo = $self->payinfo;
   $payinfo =~ s/\D//g;
@@ -667,7 +669,7 @@ sub label {
 
 =item realtime_bop
 
-Runs a L<realtime_bop|FS::cust_main::Billing_Realtime::realtime_bop> transaction on this card
+Runs a L<FS::cust_main::Billing_Realtime/realtime_bop> transaction on this card
 
 =cut
 
@@ -683,7 +685,7 @@ sub realtime_bop {
 
 =item tokenize
 
-Runs a L<realtime_tokenize|FS::cust_main::Billing_Realtime::realtime_tokenize> transaction on this card
+Runs a L<FS::cust_main::Billing_Realtime/realtime_tokenize> transaction on this card
 
 =cut
 
@@ -914,31 +916,79 @@ sub search_sql {
 
 =back
 
-=item count_autobill_cards
+=item has_autobill_cards
 
 Returns the number of unexpired cards configured for autobill
 
 =cut
 
-sub count_autobill_cards {
-  shift->count("
-    weight > 0
-    AND payby IN ('CARD','DCRD')
-    AND paydate > '".DateTime->now->ymd."'
-  ");
+sub has_autobill_cards {
+  scalar FS::Record::qsearch({
+    table     => 'cust_payby',
+    addl_from => 'JOIN cust_main USING (custnum)',
+    order_by  => 'LIMIT 1',
+    hashref   => {
+        paydate => { op => '>', value => DateTime->now->ymd },
+        weight  => { op => '>',  value => 0 },
+    },
+    extra_sql =>
+      "AND cust_payby.payby IN ('CARD', 'DCRD') ".
+      'AND '.
+      $FS::CurrentUser::CurrentUser->agentnums_sql( table => 'cust_main' ),
+  });
 }
 
-=item count_autobill_checks
+=item has_autobill_checks
 
 Returns the number of check accounts configured for autobill
 
 =cut
 
-sub count_autobill_checks {
-  shift->count("
-    weight > 0
-    AND payby IN ('CHEK','DCHEK')
-  ");
+sub has_autobill_checks {
+  scalar FS::Record::qsearch({
+    table     => 'cust_payby',
+    addl_from => 'JOIN cust_main USING (custnum)',
+    order_by  => 'LIMIT 1',
+    hashref   => {
+        weight  => { op => '>',  value => 0 },
+    },
+    extra_sql =>
+      "AND cust_payby.payby IN ('CHEK','DCHEK','DCHK') ".
+      'AND '.
+      $FS::CurrentUser::CurrentUser->agentnums_sql( table => 'cust_main' ),
+  });
+}
+
+=item future_autobill_report_title
+
+Determine if the future_autobill report should be available.
+If so, return a dynamic title for it
+
+=cut
+
+sub future_autobill_report_title {
+  # Perhaps this function belongs somewhere else
+  state $title;
+  return $title if defined $title;
+
+  # Report incompatible with tax engines
+  return $title = '' if FS::TaxEngine->new->info->{batch};
+
+  my $has_cards  = has_autobill_cards();
+  my $has_checks = has_autobill_checks();
+  my $_title = 'Future %s transactions';
+
+  if ( $has_cards && $has_checks ) {
+    $title = sprintf $_title, 'credit card and electronic check';
+  } elsif ( $has_cards ) {
+    $title = sprintf $_title, 'credit card';
+  } elsif ( $has_checks ) {
+    $title = sprintf $_title, 'electronic check';
+  } else {
+    $title = '';
+  }
+
+  $title;
 }
 
 sub _upgrade_data {