use vars qw( @ISA $conf $Debug $import );
use Safe;
use Carp;
-use Time::Local;
+BEGIN {
+ eval "use Time::Local;";
+ die "Time::Local version 1.05 required with Perl versions before 5.6"
+ if $] < 5.006 && !defined($Time::Local::VERSION);
+ eval "use Time::Local qw(timelocal timelocal_nocheck);";
+}
use Date::Format;
#use Date::Manip;
use Business::CreditCard;
=item comments - comments (optional)
-=item referral_custnum - referring customer number
-
=back
=head1 METHODS
}
}
- #false laziness with sub replace
- my $queue = new FS::queue { 'job' => 'FS::cust_main::append_fuzzyfiles' };
- $error = $queue->insert($self->getfield('last'), $self->company);
+ $error = $self->queue_fuzzyfiles_update;
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
- return "queueing job (transaction rolled back): $error";
- }
-
- if ( defined $self->dbdef_table->column('ship_last') && $self->ship_last ) {
- $queue = new FS::queue { 'job' => 'FS::cust_main::append_fuzzyfiles' };
- $error = $queue->insert($self->getfield('last'), $self->company);
- if ( $error ) {
- $dbh->rollback if $oldAutoCommit;
- return "queueing job (transaction rolled back): $error";
- }
+ return "updating fuzzy search cache: $error";
}
- #eslaf
$dbh->commit or die $dbh->errstr if $oldAutoCommit;
'';
if ( $self->payby =~ /^(CARD|CHEK|LECB)$/ &&
grep { $self->get($_) ne $old->get($_) } qw(payinfo paydate payname) ) {
- # card/check info has changed, want to retry realtime_card invoice events
- #false laziness w/collect
- foreach my $cust_bill_event (
- grep {
- #$_->part_bill_event->plan eq 'realtime-card'
- $_->part_bill_event->eventcode =~
- /^\$cust_bill\->realtime_(card|ach|lec)\(\);$/
- && $_->status eq 'done'
- && $_->statustext
- }
- map { $_->cust_bill_event }
- grep { $_->cust_bill_event }
- $self->open_cust_bill
-
- ) {
- my $error = $cust_bill_event->retry;
- if ( $error ) {
- $dbh->rollback if $oldAutoCommit;
- return "error scheduling invoice events for retry: $error";
- }
+ # card/check/lec info has changed, want to retry realtime_ invoice events
+ my $error = $self->retry_realtime;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
}
- #eslaf
+ }
+ $error = $self->queue_fuzzyfiles_update;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "updating fuzzy search cache: $error";
}
- #false laziness with sub insert
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+ '';
+
+}
+
+=item queue_fuzzyfiles_update
+
+Used by insert & replace to update the fuzzy search cache
+
+=cut
+
+sub queue_fuzzyfiles_update {
+ my $self = shift;
+
+ local $SIG{HUP} = 'IGNORE';
+ local $SIG{INT} = 'IGNORE';
+ local $SIG{QUIT} = 'IGNORE';
+ local $SIG{TERM} = 'IGNORE';
+ local $SIG{TSTP} = 'IGNORE';
+ local $SIG{PIPE} = 'IGNORE';
+
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
my $queue = new FS::queue { 'job' => 'FS::cust_main::append_fuzzyfiles' };
- $error = $queue->insert($self->getfield('last'), $self->company);
+ my $error = $queue->insert($self->getfield('last'), $self->company);
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
return "queueing job (transaction rolled back): $error";
if ( defined $self->dbdef_table->column('ship_last') && $self->ship_last ) {
$queue = new FS::queue { 'job' => 'FS::cust_main::append_fuzzyfiles' };
- $error = $queue->insert($self->getfield('last'), $self->company);
+ $error = $queue->insert($self->getfield('ship_last'), $self->ship_company);
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
return "queueing job (transaction rolled back): $error";
}
}
- #eslaf
$dbh->commit or die $dbh->errstr if $oldAutoCommit;
'';
my( $total_setup, $total_recur ) = ( 0, 0 );
#my( $taxable_setup, $taxable_recur ) = ( 0, 0 );
my @cust_bill_pkg = ();
- #my $tax = 0;##
+ my $tax = 0;##
#my $taxable_charged = 0;##
#my $charged = 0;##
- my %tax;
-
foreach my $cust_pkg (
qsearch('cust_pkg', { 'custnum' => $self->custnum } )
) {
": $setup_prog";
};
$setup_prog = $1;
+ $setup_prog = '0' if $setup_prog =~ /^\s*$/;
#my $cpt = new Safe;
##$cpt->permit(); #what is necessary?
my $sdate;
if ( $part_pkg->getfield('freq') > 0 &&
! $cust_pkg->getfield('susp') &&
- ( $cust_pkg->getfield('bill') || 0 ) < $time
+ ( $cust_pkg->getfield('bill') || 0 ) <= $time
) {
my $recur_prog = $part_pkg->getfield('recur');
$recur_prog =~ /^(.*)$/ or do {
": $recur_prog";
};
$recur_prog = $1;
+ $recur_prog = '0' if $recur_prog =~ /^\s*$/;
# shared with $recur_prog
$sdate = $cust_pkg->bill || $cust_pkg->setup || $time;
# only for figuring next bill date, nothing else, so, reset $sdate again
# here
$sdate = $cust_pkg->bill || $cust_pkg->setup || $time;
+ $cust_pkg->last_bill($sdate)
+ if $cust_pkg->dbdef_table->column('last_bill');
$mon += $part_pkg->freq;
until ( $mon < 12 ) { $mon -= 12; $year++; }
$cust_pkg->setfield('bill',
- timelocal($sec,$min,$hour,$mday,$mon,$year));
+ timelocal_nocheck($sec,$min,$hour,$mday,$mon,$year));
$cust_pkg_mod_flag = 1;
}
} #if $cust_main_county->exempt_amount
$taxable_charged = sprintf( "%.2f", $taxable_charged);
-
- #$tax += $taxable_charged * $cust_main_county->tax / 100
- $tax{ $cust_main_county->taxname || 'Tax' } +=
- $taxable_charged * $cust_main_county->tax / 100
+ $tax += $taxable_charged * $cust_main_county->tax / 100
} #unless $self->tax =~ /Y/i
# || $self->payby eq 'COMP'
# $taxable_charged * ( $cust_main_county->getfield('tax') / 100 )
# );
- foreach my $taxname ( grep { $tax{$_} > 0 } keys %tax ) {
- my $tax = sprintf("%.2f", $tax{$taxname} );
+ $tax = sprintf("%.2f", $tax);
+ if ( $tax > 0 ) {
$charged = sprintf( "%.2f", $charged+$tax );
my $cust_bill_pkg = new FS::cust_bill_pkg ({
- 'pkgnum' => 0,
- 'setup' => $tax,
- 'recur' => 0,
- 'sdate' => '',
- 'edate' => '',
- 'itemdesc' => $taxname,
+ 'pkgnum' => 0,
+ 'setup' => $tax,
+ 'recur' => 0,
+ 'sdate' => '',
+ 'edate' => '',
});
push @cust_bill_pkg, $cust_bill_pkg;
}
late notices on those invoices. The default is now. It is specified as a UNIX timestamp; see L<perlfunc/"time">). Also see L<Time::Local> and L<Date::Parse>
for conversion functions.
-retry_card - Retry cards even when not scheduled by invoice events.
+retry - Retry card/echeck/LEC transactions even when not scheduled by invoice
+events.
+
+retry_card - Deprecated alias for 'retry'
batch_card - This option is deprecated. See the invoice events web interface
to control whether cards are batched or run against a realtime gateway.
return '';
}
- if ( exists($options{'retry_card'}) && $options{'retry_card'} ) {
- #false laziness w/replace
- foreach my $cust_bill_event (
- grep {
- #$_->part_bill_event->plan eq 'realtime-card'
- $_->part_bill_event->eventcode eq '$cust_bill->realtime_card();'
- && $_->status eq 'done'
- && $_->statustext
- }
- map { $_->cust_bill_event }
- grep { $_->cust_bill_event }
- $self->open_cust_bill
- ) {
- my $error = $cust_bill_event->retry;
- if ( $error ) {
- $dbh->rollback if $oldAutoCommit;
- return "error scheduling invoice events for retry: $error";
- }
+ if ( exists($options{'retry_card'}) ) {
+ carp 'retry_card option passed to collect is deprecated; use retry';
+ $options{'retry'} ||= $options{'retry_card'};
+ }
+ if ( exists($options{'retry'}) && $options{'retry'} ) {
+ my $error = $self->retry_realtime;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
}
- #eslaf
}
foreach my $cust_bill ( $self->cust_bill ) {
}
+=item retry_realtime
+
+Schedules realtime credit card / electronic check / LEC billing events for
+for retry. Useful if card information has changed or manual retry is desired.
+The 'collect' method must be called to actually retry the transaction.
+
+Implementation details: For each of this customer's open invoices, changes
+the status of the first "done" (with statustext error) realtime processing
+event to "failed".
+
+=cut
+
+sub retry_realtime {
+ my $self = shift;
+
+ local $SIG{HUP} = 'IGNORE';
+ local $SIG{INT} = 'IGNORE';
+ local $SIG{QUIT} = 'IGNORE';
+ local $SIG{TERM} = 'IGNORE';
+ local $SIG{TSTP} = 'IGNORE';
+ local $SIG{PIPE} = 'IGNORE';
+
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
+ foreach my $cust_bill (
+ grep { $_->cust_bill_event }
+ $self->open_cust_bill
+ ) {
+ my @cust_bill_event =
+ sort { $a->part_bill_event->seconds <=> $b->part_bill_event->seconds }
+ grep {
+ #$_->part_bill_event->plan eq 'realtime-card'
+ $_->part_bill_event->eventcode =~
+ /\$cust_bill\->realtime_(card|ach|lec)/
+ && $_->status eq 'done'
+ && $_->statustext
+ }
+ $cust_bill->cust_bill_event;
+ next unless @cust_bill_event;
+ my $error = $cust_bill_event[0]->retry;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "error scheduling invoice event for retry: $error";
+ }
+
+ }
+
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+ '';
+
+}
+
=item total_owed
Returns the total owed for this customer on all invoices
1;
-