X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_main.pm;h=be02f9c9b9565021980e097dfa8a53fff44f750d;hb=84e973ebe4c82881c62b71f996ec9ca124a5dce5;hp=a15a36967c9e0c3231c99ceadfad810a963f689e;hpb=1afbcb85759ea27fc48502be19c00b35461db13e;p=freeside.git diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index a15a36967..be02f9c9b 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -28,6 +28,7 @@ use Date::Format; #use Date::Manip; use File::Temp; #qw( tempfile ); use Business::CreditCard 0.28; +use List::Util qw(min); use FS::UID qw( dbh driver_name ); use FS::Record qw( qsearchs qsearch dbdef regexp_sql ); use FS::Cursor; @@ -2701,64 +2702,34 @@ sub payment_info { =item paydate_epoch -Returns the exact time in seconds corresponding to the payment method -expiration date. For CARD/DCRD customers this is the end of the month; -for others (COMP is the only other payby that uses paydate) it's the start. -Returns 0 if the paydate is empty or set to the far future. +Returns the next payment expiration date for this customer. If they have no +payment methods that will expire, returns 0. =cut -#XXX i need to be updated for 4.x+ sub paydate_epoch { my $self = shift; - my ($month, $year) = $self->paydate_monthyear; - return 0 if !$year or $year >= 2037; - if ( $self->payby eq 'CARD' or $self->payby eq 'DCRD' ) { - $month++; - if ( $month == 13 ) { - $month = 1; - $year++; - } - return timelocal(0,0,0,1,$month-1,$year) - 1; - } - else { - return timelocal(0,0,0,1,$month-1,$year); - } + # filter out the ones that individually return 0, but then return 0 if + # there are no results + my @epochs = grep { $_ > 0 } map { $_->paydate_epoch } $self->cust_payby; + min( @epochs ) || 0; } =item paydate_epoch_sql -Class method. Returns an SQL expression to obtain the payment expiration date -as a number of seconds. +Returns an SQL expression to get the next payment expiration date for a +customer. Returns 2143260000 (2037-12-01) if there are no payment expiration +dates, so that it's safe to test for "will it expire before date X" for any +date up to then. =cut -# XXX i need to be updated for 4.x+ -# Special expiration date behavior for non-CARD/DCRD customers has been -# carefully preserved. Do we really use that? sub paydate_epoch_sql { my $class = shift; - my $table = shift || 'cust_main'; - my ($case1, $case2); - if ( driver_name eq 'Pg' ) { - $case1 = "EXTRACT( EPOCH FROM CAST( $table.paydate AS TIMESTAMP ) + INTERVAL '1 month') - 1"; - $case2 = "EXTRACT( EPOCH FROM CAST( $table.paydate AS TIMESTAMP ) )"; - } - elsif ( lc(driver_name) eq 'mysql' ) { - $case1 = "UNIX_TIMESTAMP( DATE_ADD( CAST( $table.paydate AS DATETIME ), INTERVAL 1 month ) ) - 1"; - $case2 = "UNIX_TIMESTAMP( CAST( $table.paydate AS DATETIME ) )"; - } - else { return '' } - return "CASE WHEN $table.payby IN('CARD','DCRD') - THEN ($case1) - ELSE ($case2) - END" + my $paydate = FS::cust_payby->paydate_epoch_sql; + "(SELECT COALESCE(MIN($paydate), 2143260000) FROM cust_payby WHERE cust_payby.custnum = cust_main.custnum)"; } -=item tax_exemption TAXNAME - -=cut - sub tax_exemption { my( $self, $taxname ) = @_; @@ -5144,71 +5115,6 @@ sub _upgrade_data { #class method } - unless ( FS::upgrade_journal->is_done('cust_main__cust_payby') ) { - - #we don't want to decrypt them, just stuff them as-is into cust_payby - local(@encrypted_fields) = (); - - local($FS::cust_payby::ignore_expired_card) = 1; - local($FS::cust_payby::ignore_banned_card) = 1; - - my @payfields = qw( payby payinfo paycvv paymask - paydate paystart_month paystart_year payissue - payname paystate paytype payip - ); - - my $search = new FS::Cursor { - 'table' => 'cust_main', - 'extra_sql' => " WHERE ( payby IS NOT NULL AND payby != '' ) ", - }; - - while (my $cust_main = $search->fetch) { - - unless ( $cust_main->payby =~ /^(BILL|COMP)$/ ) { - - my $cust_payby = new FS::cust_payby { - 'custnum' => $cust_main->custnum, - 'weight' => 1, - map { $_ => $cust_main->$_(); } @payfields - }; - - my $error = $cust_payby->insert; - die $error if $error; - - } - - # at the time we do this, also migrate paytype into cust_pay_batch - # so that batches that are open before the migration can still be - # processed - my @cust_pay_batch = qsearch('cust_pay_batch', { - 'custnum' => $cust_main->custnum, - 'payby' => 'CHEK', - 'paytype' => '', - }); - foreach my $cust_pay_batch (@cust_pay_batch) { - $cust_pay_batch->set('paytype', $cust_main->get('paytype')); - my $error = $cust_pay_batch->replace; - die "$error (setting cust_pay_batch.paytype)" if $error; - } - - $cust_main->complimentary('Y') if $cust_main->payby eq 'COMP'; - - $cust_main->invoice_attn( $cust_main->payname ) - if $cust_main->payby eq 'BILL' && $cust_main->payname; - $cust_main->po_number( $cust_main->payinfo ) - if $cust_main->payby eq 'BILL' && $cust_main->payinfo; - - $cust_main->setfield($_, '') foreach @payfields; - my $error = $cust_main->replace; - die "Error upgradging payment information for custnum ". - $cust_main->custnum. ": $error" - if $error; - - }; - - FS::upgrade_journal->set_done('cust_main__cust_payby'); - } - $class->_upgrade_otaker(%opts); }