use FS::part_event;
use FS::part_event_condition;
use FS::pkg_category;
+use POSIX;
# 1 is mostly method/subroutine entry and options
# 2 traces progress of some operations
my $job = $options{'job'};
$job->update_statustext('0,cleaning expired packages') if $job;
- $error = $self->cancel_expired_pkgs( $options{actual_time} );
+ $error = $self->cancel_expired_pkgs( $self->day_end( $options{actual_time} ) );
if ( $error ) {
$error = "Error expiring custnum ". $self->custnum. ": $error";
if ( $options{fatal} && $options{fatal} eq 'return' ) { return $error; }
else { warn $error; }
}
- $error = $self->suspend_adjourned_pkgs( $options{actual_time} );
+ $error = $self->suspend_adjourned_pkgs( $self->day_end( $options{actual_time} ) );
if ( $error ) {
$error = "Error adjourning custnum ". $self->custnum. ": $error";
if ( $options{fatal} && $options{fatal} eq 'return' ) { return $error; }
}
+sub day_end {
+ # XXX: sometimes "incorrect" if crossing DST boundaries?
+
+ my $self = shift;
+ my $time = shift;
+
+ return $time unless $conf->exists('next-bill-ignore-time');
+
+ my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
+ localtime($time);
+ mktime(59,59,23,$mday,$mon,$year,$wday,$yday,$isdst);
+}
+
sub cancel_expired_pkgs {
my ( $self, $time, %options ) = @_;
-
+
my @cancel_pkgs = $self->ncancelled_pkgs( {
'extra_sql' => " AND expire IS NOT NULL AND expire > 0 AND expire <= $time "
} );
sub suspend_adjourned_pkgs {
my ( $self, $time, %options ) = @_;
-
+
my @susp_pkgs = $self->ncancelled_pkgs( {
'extra_sql' =>
" AND ( susp IS NULL OR susp = 0 )
my $setup = 0;
my $unitsetup = 0;
+ my %setup_param = ();
if ( ! $options{recurring_only}
and ! $options{cancel}
and ( $options{'resetup'}
|| ( ! $cust_pkg->setup
&& ( ! $cust_pkg->start_date
- || $cust_pkg->start_date <= $time
+ || $cust_pkg->start_date <= $self->day_end($time)
)
&& ( ! $conf->exists('disable_setup_suspended_pkgs')
|| ( $conf->exists('disable_setup_suspended_pkgs') &&
{
warn " bill setup\n" if $DEBUG > 1;
- $lineitems++;
- $setup = eval { $cust_pkg->calc_setup( $time, \@details ) };
- return "$@ running calc_setup for $cust_pkg\n"
- if $@;
+ unless ( $cust_pkg->waive_setup ) {
+ $lineitems++;
- $unitsetup = $cust_pkg->part_pkg->unit_setup || $setup; #XXX uuh
+ $setup = eval { $cust_pkg->calc_setup( $time, \@details, \%setup_param ) };
+ return "$@ running calc_setup for $cust_pkg\n"
+ if $@;
+
+ $unitsetup = $cust_pkg->part_pkg->unit_setup || $setup; #XXX uuh
+ }
$cust_pkg->setfield('setup', $time)
unless $cust_pkg->setup;
if ( ! $cust_pkg->start_date
and ( ! $cust_pkg->susp || $part_pkg->option('suspend_bill', 1) )
and
- ( $part_pkg->freq ne '0' && ( $cust_pkg->bill || 0 ) <= $time )
+ ( $part_pkg->freq ne '0' && ( $cust_pkg->bill || 0 ) <= $self->day_end($time) )
|| ( $part_pkg->plan eq 'voip_cdr'
&& $part_pkg->option('bill_every_call')
)
#over two params! lets at least switch to a hashref for the rest...
my $increment_next_bill = ( $part_pkg->freq ne '0'
- && ( $cust_pkg->getfield('bill') || 0 ) <= $time
+ && ( $cust_pkg->getfield('bill') || 0 ) <= $self->day_end($time)
&& !$options{cancel}
);
my %param = ( 'precommit_hooks' => $precommit_hooks,
'real_pkgpart' => $real_pkgpart,
'freq_override' => $options{freq_override} || '',
'setup_fee' => 0,
+ %setup_param,
);
my $method = $options{cancel} ? 'calc_cancel' : 'calc_recur';
$lineitems++;
}
+ if ( defined $param{'discount_left_setup'} ) {
+ foreach my $discount_setup ( values %{$param{'discount_left_setup'}} ) {
+ $setup -= $discount_setup;
+ }
+ }
+
}
warn "\$setup is undefined" unless defined($setup);