summaryrefslogtreecommitdiff
path: root/FS/FS/part_pkg/prorate_Mixin.pm
diff options
context:
space:
mode:
authorcvs2git <cvs2git>2010-11-05 19:05:57 +0000
committercvs2git <cvs2git>2010-11-05 19:05:57 +0000
commitaaf8baf3662e16e9414de236a39f8801a8c41b01 (patch)
tree2cda603e4311b3e80f79b93d9bcce3a7c7c2d053 /FS/FS/part_pkg/prorate_Mixin.pm
parent995a145c931164347683071c95c6754379d36604 (diff)
parent9b2de4257b6a2877434008188e52b8ef71ff339d (diff)
This commit was manufactured by cvs2svn to create branch
'FREESIDE_2_1_BRANCH'.
Diffstat (limited to 'FS/FS/part_pkg/prorate_Mixin.pm')
-rw-r--r--FS/FS/part_pkg/prorate_Mixin.pm94
1 files changed, 94 insertions, 0 deletions
diff --git a/FS/FS/part_pkg/prorate_Mixin.pm b/FS/FS/part_pkg/prorate_Mixin.pm
new file mode 100644
index 0000000..9c0c266
--- /dev/null
+++ b/FS/FS/part_pkg/prorate_Mixin.pm
@@ -0,0 +1,94 @@
+package FS::part_pkg::prorate_Mixin;
+
+use strict;
+use vars qw(@ISA %info);
+use Time::Local qw(timelocal);
+
+@ISA = qw(FS::part_pkg);
+%info = (
+ 'disabled' => 1,
+);
+
+=head1 NAME
+
+FS::part_pkg::prorate_Mixin - Mixin class for part_pkg:: classes that
+need to prorate partial months
+
+=head1 SYNOPSIS
+
+package FS::part_pkg::...;
+use base qw( FS::part_pkg::prorate_Mixin );
+
+sub calc_recur {
+ ...
+ if( conditions that trigger prorate ) {
+ # sets $$sdate and $param->{'months'}, returns the prorated charge
+ $charges = $self->calc_prorate($cust_pkg, $sdate, $param, $cutoff_day);
+ }
+ ...
+}
+
+=head METHODS
+
+=item calc_prorate CUST_PKG
+
+Takes all the arguments of calc_recur, followed by a day of the month
+to prorate to. Calculates a prorated charge from the $sdate to that day,
+and sets the $sdate and $param->{months} accordingly.
+
+Options:
+- recur_fee: The charge to use for a complete billing period.
+- add_full_period: Bill for the time up to the prorate day plus one full
+billing period after that.
+- prorate_round_day: Round the current time to the nearest full day,
+instead of using the exact time.
+
+=cut
+
+sub calc_prorate {
+ my $self = shift;
+ my ($cust_pkg, $sdate, $details, $param, $cutoff_day) = @_;
+
+ my $charge = $self->option('recur_fee',1) || 0;
+ if($cutoff_day) {
+ # only works for freq >= 1 month; probably can't be fixed
+ my $mnow = $$sdate;
+ my ($sec, $min, $hour, $mday, $mon, $year) = (localtime($mnow))[0..5];
+ if( $self->option('prorate_round_day',1) ) {
+ $mday++ if $hour >= 12;
+ $mnow = timelocal(0,0,0,$mday,$mon,$year);
+ }
+ my $mend;
+ my $mstart;
+ if ( $mday >= $cutoff_day ) {
+ $mend =
+ timelocal(0,0,0,$cutoff_day,$mon == 11 ? 0 : $mon + 1,$year+($mon==11));
+ $mstart =
+ timelocal(0,0,0,$cutoff_day,$mon,$year);
+ }
+ else {
+ $mend =
+ timelocal(0,0,0,$cutoff_day,$mon,$year);
+ $mstart =
+ timelocal(0,0,0,$cutoff_day,$mon == 0 ? 11 : $mon - 1,$year-($mon==11));
+ }
+
+ # next bill date will be figured as $$sdate + one period
+ $$sdate = $mstart;
+
+ my $permonth = $charge / $self->freq;
+ my $months = ( ( $self->freq - 1 ) + ($mend-$mnow) / ($mend-$mstart) );
+
+ if ( $self->option('add_full_period',1) ) {
+ # charge a full period in addition to the partial month
+ $months += $self->freq;
+ $$sdate = $self->add_freq($mstart);
+ }
+
+ $param->{'months'} = $months;
+ $charge = sprintf('%.2f', $permonth * $months);
+ }
+ return $charge;
+}
+
+1;