diff options
author | mark <mark> | 2012-02-08 02:17:58 +0000 |
---|---|---|
committer | mark <mark> | 2012-02-08 02:17:58 +0000 |
commit | 7fbe88a91e80c40c70f3e666ce1965586544c181 (patch) | |
tree | a2058bac9aa331b1d8355a775aee9bcf6f7fa6a3 /FS/FS/part_pkg | |
parent | 8f3fc38083332407e7ea1ef6c01ea547947c98e7 (diff) |
correct unused-time credits for discounted packages, #16352
Diffstat (limited to 'FS/FS/part_pkg')
-rw-r--r-- | FS/FS/part_pkg/flat.pm | 52 |
1 files changed, 39 insertions, 13 deletions
diff --git a/FS/FS/part_pkg/flat.pm b/FS/FS/part_pkg/flat.pm index 531a6a80e..0e44f5db5 100644 --- a/FS/FS/part_pkg/flat.pm +++ b/FS/FS/part_pkg/flat.pm @@ -6,6 +6,7 @@ use base qw( FS::part_pkg::prorate_Mixin use strict; use vars qw( %info %usage_recharge_fields @usage_recharge_fieldorder ); +use FS::Record qw( qsearch ); use Tie::IxHash; use List::Util qw( min ); use FS::UI::bytecount; @@ -189,6 +190,22 @@ sub base_recur_permonth { sprintf('%.2f', $self->base_recur($cust_pkg) / $self->freq ); } +sub calc_cancel { + my $self = shift; + my $conf = new FS::Conf; + if ( $self->recur_temporality eq 'preceding' + and $self->option('bill_recur_on_cancel', 1) ) { + # run another recurring cycle + return $self->calc_recur(@_); + } + elsif ( $conf->exists('bill_usage_on_cancel') # should be a package option? + and $self->can('calc_usage') ) { + # bill for outstanding usage + return $self->calc_usage(@_); + } + 0; +} + sub calc_remain { my ($self, $cust_pkg, %options) = @_; @@ -205,19 +222,28 @@ sub calc_remain { || ! $next_bill || $next_bill < $time; - my %sec = ( - 'h' => 3600, # 60 * 60 - 'd' => 86400, # 60 * 60 * 24 - 'w' => 604800, # 60 * 60 * 24 * 7 - 'm' => 2629744, # 60 * 60 * 24 * 365.2422 / 12 - ); - - $self->freq =~ /^(\d+)([hdwm]?)$/ - or die 'unparsable frequency: '. $self->freq; - my $freq_sec = $1 * $sec{$2||'m'}; - return 0 unless $freq_sec; - - sprintf("%.2f", $self->base_recur($cust_pkg, \$time) * ( $next_bill - $time ) / $freq_sec ); + # Use actual charge for this period, not base_recur (for discounts). + # Use sdate < $time and edate >= $time because when billing on + # cancellation, edate = $time. + my $credit = 0; + foreach my $item ( + qsearch('cust_bill_pkg', { + pkgnum => $cust_pkg->pkgnum, + sdate => {op => '<' , value => $time}, + edate => {op => '>=', value => $time}, + recur => {op => '>' , value => 0}, + }) + ) { + # hack to deal with the weird behavior of edate on package cancellation + my $edate = $item->edate; + if ( $self->recur_temporality eq 'preceding' ) { + $edate = $self->add_freq($item->sdate); + } + $credit += ($item->recur - $item->usage) * + ($edate - $time) / ($edate - $item->sdate); + } + sprintf('%.2f', $credit); + #sprintf("%.2f", $self->base_recur($cust_pkg, \$time) * ( $next_bill - $time ) / $freq_sec ); } |