From: levinse Date: Fri, 6 May 2011 00:30:07 +0000 (+0000) Subject: discounts on setup fees, part 2 of 2, RT11512 X-Git-Tag: freeside_2_3_0~289 X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=commitdiff_plain;h=e8ded8195d035d2f32fe84982ce5d382c5e53047 discounts on setup fees, part 2 of 2, RT11512 --- diff --git a/FS/FS/cust_main/Billing.pm b/FS/FS/cust_main/Billing.pm index 5647ef014..4c8d40f27 100644 --- a/FS/FS/cust_main/Billing.pm +++ b/FS/FS/cust_main/Billing.pm @@ -842,6 +842,7 @@ sub _make_lines { my $setup = 0; my $unitsetup = 0; + my %setup_param = (); if ( ! $options{recurring_only} and ! $options{cancel} and ( $options{'resetup'} @@ -864,7 +865,7 @@ sub _make_lines { unless ( $cust_pkg->waive_setup ) { $lineitems++; - $setup = eval { $cust_pkg->calc_setup( $time, \@details ) }; + $setup = eval { $cust_pkg->calc_setup( $time, \@details, \%setup_param ) }; return "$@ running calc_setup for $cust_pkg\n" if $@; @@ -925,6 +926,7 @@ sub _make_lines { 'real_pkgpart' => $real_pkgpart, 'freq_override' => $options{freq_override} || '', 'setup_fee' => 0, + %setup_param, ); my $method = $options{cancel} ? 'calc_cancel' : 'calc_recur'; @@ -967,6 +969,12 @@ sub _make_lines { $lineitems++; } + if ( defined $param{'discount_left_setup'} ) { + foreach my $discount_setup ( values %{$param{'discount_left_setup'}} ) { + $setup -= $discount_setup; + } + } + } warn "\$setup is undefined" unless defined($setup); diff --git a/FS/FS/part_pkg/discount_Mixin.pm b/FS/FS/part_pkg/discount_Mixin.pm index 8ce5ba875..d97e18042 100644 --- a/FS/FS/part_pkg/discount_Mixin.pm +++ b/FS/FS/part_pkg/discount_Mixin.pm @@ -44,8 +44,6 @@ sub calc_discount { my $br = $self->base_recur($cust_pkg, $sdate); $br += $param->{'override_charges'} if $param->{'override_charges'}; - return 0 if defined $param->{'setup_charge'} && $param->{'setup_charge'} == 0; - my $tot_discount = 0; #UI enforces just 1 for now, will need ordering when they can be stacked @@ -80,11 +78,12 @@ sub calc_discount { my @cust_pkg_discount = $cust_pkg->cust_pkg_discount_active; foreach my $cust_pkg_discount ( @cust_pkg_discount ) { + my $discount_left; my $discount = $cust_pkg_discount->discount; #UI enforces one or the other (for now? probably for good) my $amount = 0; $amount += $discount->amount - if $cust_pkg->pkgpart == $param->{real_pkgpart}; + if defined $param->{'real_pkgpart'} && $cust_pkg->pkgpart == $param->{'real_pkgpart'}; $amount += sprintf('%.2f', $discount->percent * $br / 100 ); my $chg_months = $param->{'months'} || $cust_pkg->part_pkg->freq; @@ -92,7 +91,7 @@ sub calc_discount { ? min( $chg_months, $discount->months - $cust_pkg_discount->months_used ) : $chg_months; - + if(defined $param->{'setup_charge'}) { next unless $discount->setup; @@ -100,10 +99,31 @@ sub calc_discount { $amount = sprintf('%.2f', $discount->percent * $param->{'setup_charge'} / 100 ); $months = 1; } + elsif ( $discount->amount && $discount->months == 1) { + $discount_left = $param->{'setup_charge'} - $discount->amount; + $amount = $param->{'setup_charge'} if $discount_left < 0; + $amount = $discount->amount if $discount_left >= 0; + $months = 1; + + # transfer remainder of discount, if any, to recur + $param->{'discount_left_recur'}{$discount->discountnum} = + 0 - $discount_left if $discount_left < 0; + } + else { + next; + } + } + elsif ( defined $param->{'discount_left_recur'}{$discount->discountnum} + && $param->{'discount_left_recur'}{$discount->discountnum} > 0) { + # use up transferred remainder of discount from setup + $amount = $param->{'discount_left_recur'}{$discount->discountnum}; + $param->{'discount_left_recur'}{$discount->discountnum} = 0; + $months = 1; } my $error = $cust_pkg_discount->increment_months_used($months) - if ($cust_pkg->pkgpart == $param->{real_pkgpart} + if (defined $param->{'real_pkgpart'} + && $cust_pkg->pkgpart == $param->{'real_pkgpart'} && ! defined $param->{'setup_charge'}); die "error discounting: $error" if $error; @@ -111,6 +131,16 @@ sub calc_discount { $amount = sprintf('%.2f', $amount); next unless $amount > 0; + + # transfer remainder of discount, if any, to setup + if ( $discount->setup && $discount->amount + && (!$discount->months || $discount->months != 1) + && !defined $param->{'setup_charge'}) { + $discount_left = $br - $amount; + $amount = $br if $discount_left < 0; + $param->{'discount_left_setup'}{$discount->discountnum} = + 0 - $discount_left if $discount_left < 0; + } #record details in cust_bill_pkg_discount my $cust_bill_pkg_discount = new FS::cust_bill_pkg_discount { diff --git a/FS/FS/part_pkg/flat.pm b/FS/FS/part_pkg/flat.pm index 78c576424..e7220f6b3 100644 --- a/FS/FS/part_pkg/flat.pm +++ b/FS/FS/part_pkg/flat.pm @@ -93,7 +93,7 @@ sub price_info { } sub calc_setup { - my($self, $cust_pkg, $sdate, $details ) = @_; + my($self, $cust_pkg, $sdate, $details, $param ) = @_; return 0 if $self->prorate_setup($cust_pkg, $sdate); @@ -107,8 +107,12 @@ sub calc_setup { my $charge = $quantity * $self->unit_setup($cust_pkg, $sdate, $details); - my $param = { 'setup_charge' => $charge }; - my $discount = $self->calc_discount($cust_pkg, $sdate, $details, $param); + my $discount = 0; + if ( $charge > 0 ) { + $param->{'setup_charge'} = $charge; + $discount = $self->calc_discount($cust_pkg, $sdate, $details, $param); + delete $param->{'setup_charge'}; + } sprintf('%.2f', $charge - $discount); }