Merge branch 'calc-discount-rounding' of https://github.com/rvandam/Freeside
authorMark Wells <mark@freeside.biz>
Sat, 29 Aug 2015 23:06:12 +0000 (16:06 -0700)
committerMark Wells <mark@freeside.biz>
Sat, 29 Aug 2015 23:16:25 +0000 (16:16 -0700)
fix rounding error when calculating discounts on non-monthly recurring
fees, pull request #46, RT#37844

FS/FS/part_pkg/discount_Mixin.pm

index 3180275..abde93f 100644 (file)
@@ -40,9 +40,12 @@ sub calc_discount {
   my($self, $cust_pkg, $sdate, $details, $param ) = @_;
   my $conf = new FS::Conf;
 
-  my $br = $self->base_recur_permonth($cust_pkg, $sdate);
-  $br += $param->{'override_charges'} if $param->{'override_charges'};
+  my $br_permonth = $self->base_recur_permonth($cust_pkg, $sdate);
+  $br_permonth += $param->{'override_charges'} if $param->{'override_charges'};
+
+  my $br = $self->base_recur($cust_pkg, $sdate);
+  $br += $param->{'override_charges'} * ($cust_pkg->part_pkg->freq || 0) if $param->{'override_charges'};
+
   my $tot_discount = 0;
   #UI enforces just 1 for now, will need ordering when they can be stacked
 
@@ -83,7 +86,7 @@ sub calc_discount {
     my $amount = 0;
     $amount += $discount->amount
         if $cust_pkg->pkgpart == $param->{'real_pkgpart'};
-    $amount += sprintf('%.2f', $discount->percent * $br / 100 );
+    $amount += sprintf('%.2f', $discount->percent * $br_permonth / 100 ); # FIXME: should this use $br / $freq to avoid rounding errors?
     my $chg_months = defined($param->{'months'}) ?
                       $param->{'months'} :
                       $cust_pkg->part_pkg->freq;
@@ -133,8 +136,7 @@ sub calc_discount {
         };
       }
 
-      $amount = min($amount, $br);
-      $amount *= $months;
+      $amount = min($amount * $months, $br);
     }
 
     $amount = sprintf('%.2f', $amount + 0.00000001 ); #so 1.005 rounds to 1.01
@@ -147,9 +149,9 @@ sub calc_discount {
         && !defined $param->{'setup_charge'}
        )
     {
-      $discount_left = $br - $amount;
+      $discount_left = $br_permonth - $amount; # FIXME: $amount is no longer permonth at this point!
       if ( $discount_left < 0 ) {
-        $amount = $br;
+        $amount = $br_permonth; # FIXME: seems like this should *= $months
         $param->{'discount_left_setup'}{$discount->discountnum} = 
           0 - $discount_left;
       }
@@ -188,7 +190,7 @@ sub calc_discount {
     #}
 
     #push @$details, $d;
-    #push @$details, sprintf( $format, $money_char, $br );
+    #push @$details, sprintf( $format, $money_char, $br_permonth );
 
   }