X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fpart_pkg%2Fprorate_Mixin.pm;h=78a089313ecd574dbb68a972b4acc7c8aa60e4e9;hb=b8baeb2b7fb88b2b17740bedb379ec41d04de358;hp=29409fa7617265bb64c091e631ecdf8263950c59;hpb=ca3c2d180e6005dc10c1492b60e847ad32c99c57;p=freeside.git diff --git a/FS/FS/part_pkg/prorate_Mixin.pm b/FS/FS/part_pkg/prorate_Mixin.pm index 29409fa76..78a089313 100644 --- a/FS/FS/part_pkg/prorate_Mixin.pm +++ b/FS/FS/part_pkg/prorate_Mixin.pm @@ -1,14 +1,35 @@ package FS::part_pkg::prorate_Mixin; use strict; -use vars qw(@ISA %info); -use Time::Local qw(timelocal); +use vars qw( %info ); +use Time::Local qw( timelocal ); -@ISA = qw(FS::part_pkg); %info = ( 'disabled' => 1, + # define all fields that are referenced in this code + 'fields' => { + 'add_full_period' => { + 'name' => 'When prorating first month, also bill for one full '. + 'period after that', + 'type' => 'checkbox', + }, + 'prorate_round_day' => { + 'name' => 'When prorating, round to the nearest full day', + 'type' => 'checkbox', + }, + 'prorate_defer_bill' => { + 'name' => 'When prorating, defer the first bill until the '. + 'billing day', + 'type' => 'checkbox', + }, + }, + 'fieldorder' => [ qw(prorate_defer_bill prorate_round_day add_full_period) ], ); +sub fieldorder { + @{ $info{'fieldorder'} } +} + =head1 NAME FS::part_pkg::prorate_Mixin - Mixin class for part_pkg:: classes that @@ -50,6 +71,7 @@ day arrives. sub calc_prorate { my ($self, $cust_pkg, $sdate, $details, $param, $cutoff_day) = @_; die "no cutoff_day" unless $cutoff_day; + die "can't prorate non-monthly package\n" if $self->freq =~ /\D/; my $charge = $self->base_recur($cust_pkg, $sdate) || 0; @@ -76,8 +98,12 @@ sub calc_prorate { my $months = ( ( $self->freq - 1 ) + ($mend-$mnow) / ($mend-$mstart) ); # add a full period if currently billing for a partial period - if ( ( $self->option('add_full_period',1) - or $self->option('prorate_defer_bill',1) ) # necessary + # or periods up to freq_override if billing for an override interval + if ( ($param->{'freq_override'} || 0) > 1 ) { + $months += $param->{'freq_override'} - 1; + } + elsif ( ( $self->option('add_full_period',1) + or $self->option('prorate_defer_bill',1) ) and $months < $self->freq ) { $months += $self->freq; $$sdate = $self->add_freq($mstart); @@ -105,10 +131,12 @@ sub prorate_setup { and $cutoff_day ) { my ($mnow, $mend, $mstart) = $self->_endpoints($sdate, $cutoff_day); - # if today is the cutoff day, set the next bill to right now instead - # of waiting a month. + # If today is the cutoff day, set the next bill and setup both to + # midnight today, so that the customer will be billed normally for a + # month starting today. if ( $mnow - $mstart < 86400 ) { - $cust_pkg->bill($mnow); + $cust_pkg->setup($mstart); + $cust_pkg->bill($mstart); } else { $cust_pkg->bill($mend); @@ -133,7 +161,13 @@ sub _endpoints { # only works for freq >= 1 month; probably can't be fixed my ($sec, $min, $hour, $mday, $mon, $year) = (localtime($mnow))[0..5]; if( $self->option('prorate_round_day',1) ) { - $mday++ if $hour >= 12; + # If the time is 12:00-23:59, move to the next day by adding 18 + # hours to $mnow. Because of DST this can end up from 05:00 to 18:59 + # but it's always within the next day. + $mnow += 64800 if $hour >= 12; + # Get the new day, month, and year. + ($mday,$mon,$year) = (localtime($mnow))[3..5]; + # Then set $mnow to midnight on that day. $mnow = timelocal(0,0,0,$mday,$mon,$year); } my $mend;