summaryrefslogtreecommitdiff
path: root/FS
diff options
context:
space:
mode:
authorMark Wells <mark@freeside.biz>2015-10-27 16:20:31 -0700
committerMark Wells <mark@freeside.biz>2015-10-27 16:40:02 -0700
commite26187f37c2a2ad4ad199422faf9f32a0454b923 (patch)
treed1853014d0a66146bc496c9e7030e4728ca31f52 /FS
parent1f1aaa835523e8c8a615f1d205c3cf2ca021c287 (diff)
separate setup/recur quotation discounts, #14092
Diffstat (limited to 'FS')
-rw-r--r--FS/FS/Schema.pm4
-rw-r--r--FS/FS/quotation.pm51
-rw-r--r--FS/FS/quotation_pkg.pm61
-rw-r--r--FS/FS/quotation_pkg_discount.pm14
4 files changed, 77 insertions, 53 deletions
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index 5240424..4fda5eb 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -1967,8 +1967,8 @@ sub tables_hashref {
'quotationpkgdiscountnum', 'serial', '', '', '', '',
'quotationpkgnum', 'int', '', '', '', '',
'discountnum', 'int', '', '', '', '',
- 'setup_amount', @money_typen, '', '',
- 'recur_amount', @money_typen, '', '',
+ 'setuprecur', 'varchar', 'NULL', $char_d, '', '',
+ 'amount', @money_typen, '', '',
#'end_date', @date_type, '', '',
],
'primary_key' => 'quotationpkgdiscountnum',
diff --git a/FS/FS/quotation.pm b/FS/FS/quotation.pm
index f820510..5bda2d9 100644
--- a/FS/FS/quotation.pm
+++ b/FS/FS/quotation.pm
@@ -260,6 +260,7 @@ sub _items_sections {
my %opt = @_;
my $escape = $opt{escape}; # the only one we care about
+ my %show; # package frequency => 1 if there's anything to display
my %subtotals = (); # package frequency => subtotal
my $disable_total = 0;
foreach my $pkg ($self->quotation_pkg) {
@@ -267,6 +268,8 @@ sub _items_sections {
my $part_pkg = $pkg->part_pkg;
my $recur_freq = $part_pkg->freq;
+ $show{$recur_freq} = 1 if $pkg->unitrecur > 0;
+ $show{0} = 1 if $pkg->unitsetup > 0;
($subtotals{0} ||= 0) += $pkg->setup + $pkg->setup_tax;
($subtotals{$recur_freq} ||= 0) += $pkg->recur + $pkg->recur_tax;
@@ -288,7 +291,8 @@ sub _items_sections {
my $no_recurring = 0;
foreach my $freq (keys %subtotals) {
- next if $subtotals{$freq} == 0;
+ #next if $subtotals{$freq} == 0;
+ next if !$show{$freq};
my $weight =
List::MoreUtils::first_index { $_ eq $freq } @pkg_freq_order;
@@ -405,10 +409,10 @@ sub order {
$cust_pkg->set( $_, $quotation_pkg->get($_) );
}
- # currently only one discount each
- my ($pkg_discount) = $quotation_pkg->quotation_pkg_discount;
- if ( $pkg_discount ) {
- $cust_pkg->set('discountnum', $pkg_discount->discountnum);
+ # can now have two discounts each (setup and recur)
+ foreach my $pkg_discount ($quotation_pkg->quotation_pkg_discount) {
+ my $field = $pkg_discount->setuprecur . '_discountnum';
+ $cust_pkg->set($field, $pkg_discount->discountnum);
}
$all_cust_pkg{$cust_pkg} = []; # no services
@@ -685,7 +689,7 @@ sub estimate {
}
my %quotation_pkg_tax; # quotationpkgnum => tax name => quotation_pkg_tax obj
- my %quotation_pkg_discount; # quotationpkgnum => quotation_pkg_discount obj
+ my %quotation_pkg_discount; # quotationpkgnum => setuprecur => quotation_pkg_discount obj
for (my $i = 0; $i < scalar(@return_bill); $i++) {
my $this_bill = $return_bill[$i]->[0];
@@ -725,25 +729,25 @@ sub estimate {
# discounts
if ( $cust_bill_pkg->get('discounts') ) {
+ # discount records are generated as (setup, recur).
+ # well, not always, sometimes it's just (recur), but fixing this
+ # is horribly invasive.
my $discount = $cust_bill_pkg->get('discounts')->[0];
+
if ( $discount ) {
- # discount records are generated as (setup, recur).
- # well, not always, sometimes it's just (recur), but fixing this
- # is horribly invasive.
- my $qpd = $quotation_pkg_discount{$quotationpkgnum}
+ # find the quotation_pkg_discount record for this billing pass...
+ my $setuprecur = $i ? 'recur' : 'setup';
+ my $qpd = $quotation_pkg_discount{$quotationpkgnum}{$setuprecur}
||= qsearchs('quotation_pkg_discount', {
- 'quotationpkgnum' => $quotationpkgnum
+ 'quotationpkgnum' => $quotationpkgnum,
+ 'setuprecur' => $setuprecur,
});
if (!$qpd) { #can't happen
- warn "$me simulated bill returned a discount but no discount is in effect.\n";
+ warn "$me simulated bill returned a $setuprecur discount but no discount is in effect.\n";
}
- if ($discount and $qpd) {
- if ( $i == 0 ) {
- $qpd->set('setup_amount', $discount->amount);
- } else {
- $qpd->set('recur_amount', $discount->amount);
- }
+ if ($qpd) {
+ $qpd->set('amount', $discount->amount);
}
}
} # end of discount stuff
@@ -812,10 +816,13 @@ sub estimate {
return "$error (recording estimate for ".$quotation_pkg->part_pkg->pkg.")"
if $error;
}
- foreach my $quotation_pkg_discount (values %quotation_pkg_discount) {
- $error = $quotation_pkg_discount->replace;
- return "$error (recording estimated discount)"
- if $error;
+ foreach (values %quotation_pkg_discount) {
+ # { setup => one, recur => another }
+ foreach my $quotation_pkg_discount (values %$_) {
+ $error = $quotation_pkg_discount->replace;
+ return "$error (recording estimated discount)"
+ if $error;
+ }
}
foreach my $quotation_pkg_tax (map { values %$_ } values %quotation_pkg_tax) {
$error = $quotation_pkg_tax->insert;
diff --git a/FS/FS/quotation_pkg.pm b/FS/FS/quotation_pkg.pm
index 4c78be7..60b4bdb 100644
--- a/FS/FS/quotation_pkg.pm
+++ b/FS/FS/quotation_pkg.pm
@@ -117,8 +117,8 @@ sub insert {
my $error = $self->SUPER::insert;
- if ( !$error and $self->discountnum ) {
- warn "inserting discount #".$self->discountnum."\n";
+ if ( !$error and ($self->setup_discountnum || $self->recur_discountnum) ) {
+ #warn "inserting discount\n";
$error = $self->insert_discount;
$error .= ' (setting discount)' if $error;
}
@@ -241,28 +241,37 @@ sub insert_discount {
#my ($self, %options) = @_;
my $self = shift;
- my $quotation_pkg_discount = FS::quotation_pkg_discount->new( {
- 'quotationpkgnum' => $self->quotationpkgnum,
- 'discountnum' => $self->discountnum,
- #for the create a new discount case
- '_type' => $self->discountnum__type,
- 'amount' => $self->discountnum_amount,
- 'percent' => $self->discountnum_percent,
- 'months' => $self->discountnum_months,
- 'setup' => $self->discountnum_setup,
- } );
-
- $quotation_pkg_discount->insert;
+ foreach my $x (qw(setup recur)) {
+ if ( my $discountnum = $self->get("${x}_discountnum") ) {
+ my $cust_pkg_discount = FS::quotation_pkg_discount->new( {
+ 'quotationpkgnum' => $self->quotationpkgnum,
+ 'discountnum' => $discountnum,
+ 'setuprecur' => $x,
+ #for the create a new discount case
+ 'amount' => $self->get("${x}_discountnum_amount"),
+ 'percent' => $self->get("${x}_discountnum_percent"),
+ 'months' => $self->get("${x}_discountnum_months"),
+ } );
+ if ( $x eq 'setup' ) {
+ $cust_pkg_discount->setup('Y');
+ $cust_pkg_discount->months('');
+ }
+ my $error = $cust_pkg_discount->insert;
+ return $error if $error;
+ }
+ }
}
sub _item_discount {
my $self = shift;
my %options = @_;
my $setuprecur = $options{'setuprecur'};
+ # a little different from cust_bill_pkg::_item_discount, in that this one
+ # is asked specifically whether to show setup or recur discounts (because
+ # on the quotation they're separate sections entirely)
- # kind of silly treating this as multiple records, but it works, and will
- # work if we allow multiple discounts at some point
- my @pkg_discounts = $self->pkg_discount;
+ my @pkg_discounts = grep { $_->setuprecur eq $setuprecur }
+ $self->pkg_discount;
return if @pkg_discounts == 0;
my @ext;
@@ -275,7 +284,7 @@ sub _item_discount {
};
foreach my $pkg_discount (@pkg_discounts) {
push @ext, $pkg_discount->description;
- my $amount = $pkg_discount->get($setuprecur.'_amount');
+ my $amount = $pkg_discount->get('amount');
$d->{amount} -= $amount;
}
$d->{amount} = sprintf('%.2f', $d->{amount} * $self->quantity);
@@ -285,8 +294,12 @@ sub _item_discount {
sub setup {
my $self = shift;
- ($self->unitsetup - sum(0, map { $_->setup_amount } $self->pkg_discount))
- * ($self->quantity || 1);
+ return '0.00' if $self->waive_setup eq 'Y';;
+ my $discount_amount = sum(0, map { $_->amount }
+ grep { $_->setuprecur eq 'setup' }
+ $self->pkg_discount
+ );
+ ($self->unitsetup - $discount_amount) * ($self->quantity || 1);
}
@@ -297,8 +310,12 @@ sub setup_tax {
sub recur {
my $self = shift;
- ($self->unitrecur - sum(0, map { $_->recur_amount } $self->pkg_discount))
- * ($self->quantity || 1)
+ my $discount_amount = sum(0, map { $_->amount }
+ grep { $_->setuprecur eq 'recur' }
+ $self->pkg_discount
+ );
+ ($self->unitrecur - $discount_amount) * ($self->quantity || 1);
+
}
sub recur_tax {
diff --git a/FS/FS/quotation_pkg_discount.pm b/FS/FS/quotation_pkg_discount.pm
index 4389db2..1815294 100644
--- a/FS/FS/quotation_pkg_discount.pm
+++ b/FS/FS/quotation_pkg_discount.pm
@@ -45,14 +45,14 @@ for.
discountnum (L<FS::discount>)
-=item setup_amount
+=item setuprecur
-Amount that will be discounted from setup fees, per package quantity.
+Whether this is a setup or recur discount.
-=item recur_amount
+=item amount
-Amount that will be discounted from recurring fees in the first billing
-cycle, per package quantity.
+Amount that will be discounted from either setup or recur fees, per package
+quantity.
=back
@@ -106,8 +106,8 @@ sub check {
$self->ut_numbern('quotationpkgdiscountnum')
|| $self->ut_foreign_key('quotationpkgnum', 'quotation_pkg', 'quotationpkgnum' )
|| $self->ut_foreign_key('discountnum', 'discount', 'discountnum' )
- || $self->ut_moneyn('setup_amount')
- || $self->ut_moneyn('recur_amount')
+ || $self->ut_enum('setuprecur', ['setup', 'recur'])
+ || $self->ut_moneyn('amount')
;
return $error if $error;