diff options
author | Mark Wells <mark@freeside.biz> | 2016-05-16 20:58:12 -0700 |
---|---|---|
committer | Mark Wells <mark@freeside.biz> | 2016-05-16 21:07:16 -0700 |
commit | 296ed635739f362ee077eac1bcb67c408f600a31 (patch) | |
tree | 8fbce49e684ffbb50ead3306bfe9935e989c4778 /FS/FS | |
parent | a0877673b88d523c3c4ede51ff2c238285d8aeea (diff) |
prorate_round_day options to round up / down only, #42108
Diffstat (limited to 'FS/FS')
-rw-r--r-- | FS/FS/part_pkg/flat.pm | 5 | ||||
-rw-r--r-- | FS/FS/part_pkg/prorate.pm | 6 | ||||
-rw-r--r-- | FS/FS/part_pkg/prorate_Mixin.pm | 28 |
3 files changed, 31 insertions, 8 deletions
diff --git a/FS/FS/part_pkg/flat.pm b/FS/FS/part_pkg/flat.pm index 2c69432b5..e10094e8e 100644 --- a/FS/FS/part_pkg/flat.pm +++ b/FS/FS/part_pkg/flat.pm @@ -67,8 +67,9 @@ tie my %contract_years, 'Tie::IxHash', ( }, 'prorate_round_day' => { 'name' => 'When synchronizing, round the prorated '. - 'period to the nearest full day', - 'type' => 'checkbox', + 'period', + 'type' => 'select', + 'select_options' => \%FS::part_pkg::prorate_Mixin::prorate_round_day_opts, }, 'add_full_period' => { 'disabled' => 1 }, # doesn't make sense with sync? diff --git a/FS/FS/part_pkg/prorate.pm b/FS/FS/part_pkg/prorate.pm index a5f9ef6b6..44f2f2582 100644 --- a/FS/FS/part_pkg/prorate.pm +++ b/FS/FS/part_pkg/prorate.pm @@ -24,9 +24,9 @@ use FS::part_pkg::flat; 'type' => 'checkbox', }, 'prorate_round_day'=> { - 'name' => 'Round the prorated period to the nearest '. - 'full day', - 'type' => 'checkbox', + 'name' => 'Round the prorated period', + 'type' => 'select', + 'select_options' => \%FS::part_pkg::prorate_Mixin::prorate_round_day_opts, }, 'prorate_defer_bill'=> { 'name' => 'Defer the first bill until the billing day', diff --git a/FS/FS/part_pkg/prorate_Mixin.pm b/FS/FS/part_pkg/prorate_Mixin.pm index e8d42b9ca..26fdc3558 100644 --- a/FS/FS/part_pkg/prorate_Mixin.pm +++ b/FS/FS/part_pkg/prorate_Mixin.pm @@ -6,6 +6,13 @@ use Time::Local qw( timelocal timelocal_nocheck ); use Date::Format qw( time2str ); use List::Util qw( min ); +tie our %prorate_round_day_opts, 'Tie::IxHash', + 0 => 'no', + 1 => 'to the nearest day', + 2 => 'up to a full day', + 3 => 'down to a full day', +; + %info = ( 'disabled' => 1, # define all fields that are referenced in this code @@ -16,8 +23,9 @@ use List::Util qw( min ); 'type' => 'checkbox', }, 'prorate_round_day' => { - 'name' => 'When prorating, round to the nearest full day', - 'type' => 'checkbox', + 'name' => 'When prorating, round the prorated period', + 'type' => 'select', + 'select_options' => \%prorate_round_day_opts, }, 'prorate_defer_bill' => { 'name' => 'When prorating, defer the first bill until the '. @@ -219,7 +227,8 @@ 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) ) { + my $rounding_mode = $self->option('prorate_round_day',1); + if ( $rounding_mode == 1 ) { # 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. @@ -228,6 +237,19 @@ sub _endpoints { ($mday,$mon,$year) = (localtime($mnow))[3..5]; # Then set $mnow to midnight on that day. $mnow = timelocal(0,0,0,$mday,$mon,$year); + } elsif ( $rounding_mode == 2 ) { + # Move the time back to midnight. This increases the length of the + # prorate interval. + $mnow = timelocal(0,0,0,$mday,$mon,$year); + ($mday,$mon,$year) = (localtime($mnow))[3..5]; + } elsif ( $rounding_mode == 3 ) { + # If the time is after midnight, move it forward to the next midnight. + # This decreases the length of the prorate interval. + if ( $sec > 0 or $min > 0 or $hour > 0 ) { + # move to one second before midnight, then tick forward + $mnow = timelocal(59,59,23,$mday,$mon,$year) + 1; + ($mday,$mon,$year) = (localtime($mnow))[3..5]; + } } my $mend; my $mstart; |