X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fpart_pkg%2Fflat.pm;h=762ecebc08be28c73f0f01c1b7faf11149f89aa5;hb=57bb423fe457ba4e13726877f53bcdf944f828f8;hp=84599ea8ade19a23467ba1ee6a8cc97d71b6304a;hpb=4b05b20576ddb14577d59c87c8257c6804449410;p=freeside.git diff --git a/FS/FS/part_pkg/flat.pm b/FS/FS/part_pkg/flat.pm index 84599ea8a..762ecebc0 100644 --- a/FS/FS/part_pkg/flat.pm +++ b/FS/FS/part_pkg/flat.pm @@ -15,6 +15,7 @@ use Tie::IxHash; use List::Util qw( min ); use FS::UI::bytecount; use FS::Conf; +use Time::Local 'timelocal'; #ask FS::UID to run this stuff for us later FS::UID->install_callback( sub { @@ -56,6 +57,12 @@ tie my %contract_years, 'Tie::IxHash', ( 'the customer\'s next bill date', 'type' => 'checkbox', }, + 'prorate_defer_change_bill' => { + 'name' => 'When synchronizing, defer bill for '. + 'package changes until the customer\'s '. + 'next bill date', + 'type' => 'checkbox', + }, 'prorate_round_day' => { 'name' => 'When synchronizing, round the prorated '. 'period', @@ -86,7 +93,8 @@ tie my %contract_years, 'Tie::IxHash', ( }, 'fieldorder' => [ qw( recur_temporality start_1st - sync_bill_date prorate_defer_bill prorate_round_day + sync_bill_date prorate_defer_bill + prorate_defer_change_bill prorate_round_day suspend_bill unsuspend_adjust_bill bill_recur_on_cancel bill_suspend_as_cancel @@ -113,9 +121,9 @@ sub price_info { } sub calc_setup { - my($self, $cust_pkg, $sdate, $details, $param ) = @_; + my($self, $cust_pkg, $time, $details, $param ) = @_; - return 0 if $self->prorate_setup($cust_pkg, $sdate); + return 0 if $self->prorate_setup($cust_pkg, $time); my $i = 0; my $count = $self->option( 'additional_count', 'quiet' ) || 0; @@ -123,12 +131,12 @@ sub calc_setup { push @$details, $self->option( 'additional_info' . $i++ ); } - my $charge = $self->base_setup($cust_pkg, $sdate, $details); + my $charge = $self->base_setup($cust_pkg, $time, $details); my $discount = 0; if ( $charge > 0 ) { $param->{'setup_charge'} = $charge; - $discount = $self->calc_discount($cust_pkg, $sdate, $details, $param); + $discount = $self->calc_discount($cust_pkg, \$time, $details, $param); delete $param->{'setup_charge'}; } @@ -136,7 +144,7 @@ sub calc_setup { } sub base_setup { - my($self, $cust_pkg, $sdate, $details ) = @_; + my($self, $cust_pkg, $time, $details ) = @_; $self->option('setup_fee', 1) || 0; } @@ -173,16 +181,36 @@ sub calc_recur { sub cutoff_day { my $self = shift; my $cust_pkg = shift; + my $cust_main = $cust_pkg->cust_main; + # force it to act like a prorate package, is what this means + # because we made a distinction once between prorate and flat packages + if ( $cust_main->force_prorate_day and $cust_main->prorate_day ) { + return ( $cust_main->prorate_day ); + } if ( $self->option('sync_bill_date',1) ) { my $next_bill = $cust_pkg->cust_main->next_bill_date; if ( $next_bill ) { - # careful here. if the prorate calculation is going to round to - # the nearest day, this needs to always return the same result - if ( $self->option('prorate_round_day', 1) ) { - my $hour = (localtime($next_bill))[2]; - $next_bill += 64800 if $hour >= 12; - } return (localtime($next_bill))[3]; + } else { + # This is the customer's only active package and hasn't been billed + # yet, so set the cutoff day to either today or tomorrow, whichever + # would result in a full period after rounding. + my $setup = $cust_pkg->setup; # because it's "now" + my $rounding_mode = $self->option('prorate_round_day',1); + return () if !$setup or !$rounding_mode; + my ($sec, $min, $hour, $mday, $mon, $year) = localtime($setup); + + if ( ( $rounding_mode == 1 and $hour >= 12 ) + or ( $rounding_mode == 3 and ( $sec > 0 or $min > 0 or $hour > 0 )) + ) { + # then the prorate period will be rounded down to start from + # midnight tomorrow, so the cutoff day should be the current day + + # 1. + $setup = timelocal(59,59,23,$mday,$mon,$year) + 1; + $mday = (localtime($setup))[3]; + } + # otherwise, it will be rounded up, so leave the cutoff day at today. + return $mday; } } return (); @@ -225,6 +253,8 @@ sub calc_cancel { } } +# no longer used; see credit_remaining in FS::cust_pkg + sub calc_remain { my ($self, $cust_pkg, %options) = @_;