summaryrefslogtreecommitdiff
path: root/FS/FS/part_pkg
diff options
context:
space:
mode:
authormark <mark>2012-02-08 02:17:58 +0000
committermark <mark>2012-02-08 02:17:58 +0000
commit7fbe88a91e80c40c70f3e666ce1965586544c181 (patch)
treea2058bac9aa331b1d8355a775aee9bcf6f7fa6a3 /FS/FS/part_pkg
parent8f3fc38083332407e7ea1ef6c01ea547947c98e7 (diff)
correct unused-time credits for discounted packages, #16352
Diffstat (limited to 'FS/FS/part_pkg')
-rw-r--r--FS/FS/part_pkg/flat.pm52
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 );
}