From: ivan Date: Fri, 23 Dec 2011 00:02:34 +0000 (+0000) Subject: fix edge case with prorated packages discounted 100% causing discounts to be off... X-Git-Tag: freeside_2_3_1~57 X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=commitdiff_plain;h=a58af29105ebefb04c0abbcee6d392446fff9eb0 fix edge case with prorated packages discounted 100% causing discounts to be off by +- $0.01, RT#15590 --- diff --git a/FS/FS/part_pkg/discount_Mixin.pm b/FS/FS/part_pkg/discount_Mixin.pm index 0657f3e1c..63909b382 100644 --- a/FS/FS/part_pkg/discount_Mixin.pm +++ b/FS/FS/part_pkg/discount_Mixin.pm @@ -133,7 +133,7 @@ sub calc_discount { $amount *= $months; } - $amount = sprintf('%.2f', $amount); + $amount = sprintf('%.2f', $amount + 0.00000001 ); #so 1.005 rounds to 1.01 next unless $amount > 0; @@ -155,7 +155,7 @@ sub calc_discount { my $cust_bill_pkg_discount = new FS::cust_bill_pkg_discount { 'pkgdiscountnum' => $cust_pkg_discount->pkgdiscountnum, 'amount' => $amount, - 'months' => $months, + 'months' => ( defined($param->{'setup_charge'}) ? 0 : $months ), }; push @{ $param->{'discounts'} }, $cust_bill_pkg_discount; diff --git a/FS/FS/part_pkg/prorate_Mixin.pm b/FS/FS/part_pkg/prorate_Mixin.pm index 78a089313..33879d907 100644 --- a/FS/FS/part_pkg/prorate_Mixin.pm +++ b/FS/FS/part_pkg/prorate_Mixin.pm @@ -75,42 +75,47 @@ sub calc_prorate { my $charge = $self->base_recur($cust_pkg, $sdate) || 0; - my $mnow = $$sdate; - - # if this is the first bill but the bill date has been set - # (by prorate_defer_bill), calculate from the setup date, - # and append the setup fee to @$details. - if ( $self->option('prorate_defer_bill',1) - and ! $cust_pkg->getfield('last_bill') - and $cust_pkg->setup ) { - #warn "[calc_prorate] #".$cust_pkg->pkgnum.": running deferred setup\n"; - $param->{'setup_fee'} = $self->calc_setup($cust_pkg, $$sdate, $details); - $mnow = $cust_pkg->setup; - } - - my ($mend, $mstart); - ($mnow, $mend, $mstart) = $self->_endpoints($mnow, $cutoff_day); - - # 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) ); + my $mnow = $$sdate; + + # if this is the first bill but the bill date has been set + # (by prorate_defer_bill), calculate from the setup date, + # and append the setup fee to @$details. + if ( $self->option('prorate_defer_bill',1) + && ! $cust_pkg->getfield('last_bill') + && $cust_pkg->setup + ) + { + #warn "[calc_prorate] #".$cust_pkg->pkgnum.": running deferred setup\n"; + $param->{'setup_fee'} = $self->calc_setup($cust_pkg, $$sdate, $details); + $mnow = $cust_pkg->setup; + } - # add a full period if currently billing for a partial period - # or periods up to freq_override if billing for an override interval - if ( ($param->{'freq_override'} || 0) > 1 ) { - $months += $param->{'freq_override'} - 1; - } - elsif ( ( $self->option('add_full_period',1) - or $self->option('prorate_defer_bill',1) ) - and $months < $self->freq ) { - $months += $self->freq; - $$sdate = $self->add_freq($mstart); - } + my ($mend, $mstart); + ($mnow, $mend, $mstart) = $self->_endpoints($mnow, $cutoff_day); + + # 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) ); + + # add a full period if currently billing for a partial period + # or periods up to freq_override if billing for an override interval + if ( ($param->{'freq_override'} || 0) > 1 ) { + $months += $param->{'freq_override'} - 1; + } elsif ( ( $self->option('add_full_period',1) + || $self->option('prorate_defer_bill',1) # necessary + ) + && $months < $self->freq + ) + { + $months += $self->freq; + $$sdate = $self->add_freq($mstart); + } - $param->{'months'} = $months; - $charge = sprintf('%.2f', $permonth * $months); + $param->{'months'} = $months; + #so 1.005 rounds to 1.01 + $charge = sprintf('%.2f', $permonth * $months + 0.00000001 ); return $charge; }