summaryrefslogtreecommitdiff
path: root/FS/FS
diff options
context:
space:
mode:
authorMark Wells <mark@freeside.biz>2016-05-16 20:58:12 -0700
committerMark Wells <mark@freeside.biz>2016-05-16 21:07:16 -0700
commit296ed635739f362ee077eac1bcb67c408f600a31 (patch)
tree8fbce49e684ffbb50ead3306bfe9935e989c4778 /FS/FS
parenta0877673b88d523c3c4ede51ff2c238285d8aeea (diff)
prorate_round_day options to round up / down only, #42108
Diffstat (limited to 'FS/FS')
-rw-r--r--FS/FS/part_pkg/flat.pm5
-rw-r--r--FS/FS/part_pkg/prorate.pm6
-rw-r--r--FS/FS/part_pkg/prorate_Mixin.pm28
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;