[freeside-commits] branch FREESIDE_4_BRANCH updated. c46aa55bdeb3e09437c7ab18288f209a6fa44796
Mitch Jackson
mitch at freeside.biz
Fri Feb 23 16:16:00 PST 2018
The branch, FREESIDE_4_BRANCH has been updated
via c46aa55bdeb3e09437c7ab18288f209a6fa44796 (commit)
via db13eb8cb9645a6fd8979541e831fe60ee771e7d (commit)
via 538be6f5067b982715c1ad062f2201fe1a44ccba (commit)
from 4df06d48a1f7ae016e7bb02654e7820c8cd27975 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit c46aa55bdeb3e09437c7ab18288f209a6fa44796
Author: Mitch Jackson <mitch at freeside.biz>
Date: Sat Feb 24 00:09:38 2018 +0000
RT# 79284 Fix UI bug for Change Package screen
diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm
index 9accc3407..604b49941 100644
--- a/FS/FS/cust_pkg.pm
+++ b/FS/FS/cust_pkg.pm
@@ -3017,6 +3017,7 @@ sub _parse_new_discounts {
discountnum => $opt->{"${type}_discountnum"},
amount => $opt->{"${type}_discountnum_amount"},
percent => $opt->{"${type}_discountnum_percent"},
+ months => $opt->{"${type}_discountnum_months"},
};
}
diff --git a/httemplate/edit/process/change-cust_pkg.html b/httemplate/edit/process/change-cust_pkg.html
index 02b01f8de..c8c623641 100644
--- a/httemplate/edit/process/change-cust_pkg.html
+++ b/httemplate/edit/process/change-cust_pkg.html
@@ -80,6 +80,7 @@ for my $type (qw|setup_discountnum recur_discountnum|) {
$change{$type} = $dnum;
$change{"${type}_amount"} = $cgi->param("${type}_amount");
$change{"${type}_percent"} = $cgi->param("${type}_percent");
+ $change{"${type}_months"} = $cgi->param("${type}_months");
} elsif ($dnum eq '') {
# Set discount as no discount
$change{"${type}"} = 0;
commit db13eb8cb9645a6fd8979541e831fe60ee771e7d
Author: Mitch Jackson <mitch at freeside.biz>
Date: Tue Feb 13 18:11:03 2018 -0600
RT# 79284 Updated discounts UI for Change Package screen
diff --git a/httemplate/elements/select-table.html b/httemplate/elements/select-table.html
index 6fb6b388b..a52fdfaaa 100644
--- a/httemplate/elements/select-table.html
+++ b/httemplate/elements/select-table.html
@@ -195,13 +195,22 @@ if ( ref( $value ) eq 'ARRAY' ) {
$value = { map { $_ => 1 } @$value };
}
-unless ( !ref($value) && $value < 1 # !$value #ignore negatives too
- or ! exists( $opt{hashref}->{disabled} ) #??
- #or grep { $value == $_->$key() } @records
- ) {
+
+if (
+ (ref $value && $value)
+ or (ref $opt{hashref} && exists $opt{hashref}->{disabled})
+ or $opt{also_show_option}
+) {
+
delete $opt{hashref}->{disabled};
- foreach my $v ( ref($value) ? keys %$value : ($value) ) {
+ # also_show_option: (hack for change_pkg form):
+ # Include an absent select option, without selecting it
+ # as the curr_value
+ my @also_show = ref($value) ? keys %$value : ($value);
+ push @also_show, $opt{also_show_option} if $opt{also_show_option};
+
+ foreach my $v ( @also_show ) {
next if grep { $v == $_->$key() } @records;
$opt{hashref}->{$key} = $v;
diff --git a/httemplate/elements/tr-select-pkg-discount.html b/httemplate/elements/tr-select-pkg-discount.html
index 39b0ff31f..810e46230 100644
--- a/httemplate/elements/tr-select-pkg-discount.html
+++ b/httemplate/elements/tr-select-pkg-discount.html
@@ -7,7 +7,9 @@ In order_pkg.html or similar:
curr_value_recur => ($cgi->param('recur_discountnum') || ''),
disable_setup => 0,
disable_recur => 0,
- disable_waive_setup => 0
+ disable_waive_setup => 0,
+ carry_value_setup => $carry_setup_discountnum,
+ carry_value_recur => $carry_recur_discountnum,
&>
This provides the following:
@@ -20,6 +22,8 @@ This provides the following:
checkbox to waive setup fee.
- Same for recurring fee, but without the "waive setup fee" stuff, obviously.
- Custom recurring discounts also have an option for a duration in months.
+- When changing a package, the original package's discount option is
+ labeled in the select options
"disable_setup" locks the setup discount, but will still show a static
description if curr_value_setup is set. Likewise "disable_recur".
@@ -47,6 +51,8 @@ description if curr_value_setup is set. Likewise "disable_recur".
curr_value => $opt{'curr_value_setup'},
disable_empty => 1,
pre_options => $pre_options,
+ also_show_option => $opt{carry_value_setup},
+ label_callback => $opt{carry_value_setup} ? $carry_setup_sub : undef,
&>
</td>
</tr>
@@ -107,6 +113,8 @@ description if curr_value_setup is set. Likewise "disable_recur".
id => 'recur_discountnum',
hashref => { disabled => '' },
curr_value => $opt{'curr_value_recur'},
+ also_show_option => $opt{carry_value_recur},
+ label_callback => $opt{carry_value_recur} ? $carry_recur_sub : undef,
&>
</td>
@@ -196,4 +204,18 @@ my %opt = (
my $curuser = $FS::CurrentUser::CurrentUser;
my $money_char = FS::Conf->new->config('money_char') || '$';
+# Change the label for the select-option when it matches the carryover
+# discountnum
+my $carry_recur_sub = sub {
+ my ($rec) = @_;
+ $rec->discountnum eq $opt{carry_value_recur}
+ ? $rec->description() . ' [Continues existing discount]'
+ : $rec->description();
+};
+my $carry_setup_sub = sub {
+ my ($rec) = @_;
+ $rec->discountnum eq $opt{carry_value_setup}
+ ? $rec->description() . ' [Continues existing discount]'
+ : $rec->description();
+};
</%init>
diff --git a/httemplate/misc/change_pkg.cgi b/httemplate/misc/change_pkg.cgi
index 2470ee135..c588c9e6c 100755
--- a/httemplate/misc/change_pkg.cgi
+++ b/httemplate/misc/change_pkg.cgi
@@ -91,11 +91,13 @@
<FONT CLASS="fsinnerbox-title"><% mt('Discounting') |h %></FONT>
<TABLE CLASS="fsinnerbox">
<& /elements/tr-select-pkg-discount.html,
- curr_value_setup => $discount{setup},
- curr_value_recur => $discount{recur},
+ # curr_value_setup => $discount{setup},
+ # curr_value_recur => $discount{recur},
disable_setup => 0,
disable_recur => 0,
- disable_waive_setup => 0
+ disable_waive_setup => 0,
+ carry_value_setup => $discount{setup},
+ carry_value_recur => $discount{recur},
&>
</TABLE><BR>
commit 538be6f5067b982715c1ad062f2201fe1a44ccba
Author: Mitch Jackson <mitch at freeside.biz>
Date: Sat Feb 10 00:05:16 2018 -0600
RT# 79284 Option to set/carry recur discount at Change Package
diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm
index e1fa2ae93..9accc3407 100644
--- a/FS/FS/cust_pkg.pm
+++ b/FS/FS/cust_pkg.pm
@@ -6,7 +6,7 @@ use base qw( FS::cust_pkg::Search FS::cust_pkg::API
);
use strict;
-use Carp qw(cluck);
+use Carp qw(cluck croak);
use Scalar::Util qw( blessed );
use List::Util qw(min max sum);
use Tie::IxHash;
@@ -2379,8 +2379,20 @@ sub change {
$same_pkgpart = 0;
}
- if ($opt->{'waive_setup'}) { $self->set('waive_setup', $opt->{'waive_setup'}) }
- else { $self->set('waive_setup', ''); }
+ # Discounts:
+ # When a new discount level is specified in $opt:
+ # If new discountnum matches old discountnum, months_used/end_date are
+ # carried over as the discount is applied to the new cust_pkg
+ #
+ # Legacy behavior:
+ # Unless discount-related fields have been set within $opt, change()
+ # sets no discounts on the changed packages unless the new pkgpart is the
+ # same as the old pkgpart. In that case, discounts from the old cust_pkg
+ # are copied onto the new cust_pkg
+
+ # Read discount fields from $opt
+ my %new_discount = $self->_parse_new_discounts($opt);
+ $self->set(waive_setup => $opt->{waive_setup} ? $opt->{waive_setup} : '');
# Before going any further here: if the package is still in the pre-setup
# state, it's safe to modify it in place. No need to charge/credit for
@@ -2436,6 +2448,22 @@ sub change {
} # done transferring services
+ # Set waive_setup as directed
+ if ( !$error && exists $opt->{waive_setup} ) {
+ $self->set(waive_setup => $opt->{waive_setup});
+ $error = $self->replace;
+ }
+
+ # Set discounts if explicitly specified in $opt
+ if ( !$error && %new_discount ) {
+ $error = $self->change_discount(%new_discount);
+ }
+
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+
$dbh->commit if $oldAutoCommit;
return $self;
@@ -2625,8 +2653,18 @@ sub change {
}
}
- # transfer discounts, if we're not changing pkgpart
- if ( $same_pkgpart ) {
+ if (%new_discount && !$error) {
+
+ # If discounts were explicitly specified in $opt
+ $error = $cust_pkg->change_discount(%new_discount);
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "applying discounts: $error";
+ }
+
+ } elsif ( $same_pkgpart ) {
+
+ # transfer discounts, if we're not changing pkgpart
foreach my $old_discount ($self->cust_pkg_discount_active) {
# don't remove the old discount, we may still need to bill that package.
my $new_discount = new FS::cust_pkg_discount {
@@ -2843,6 +2881,20 @@ sub change_later {
$opt->{'locationnum'} = $opt->{'cust_location'}->locationnum;
}
+ # Discounts:
+ # Applies discounts to the newly created future_change package
+ #
+ # If a new discount is the same as the old discount, carry over the
+ # old discount's months_used/end_date fields too
+ #
+ # Legacy behavior:
+ # Legacy behavior was to create the next package with no discount.
+ # This behavior is preserved. Without the discount fields in $opt,
+ # the new package will be created with no discounts.
+
+ # parse discount information from $opt
+ my %new_discount = $self->_parse_new_discounts($opt);
+
if ( $self->change_to_pkgnum ) {
my $change_to = FS::cust_pkg->by_key($self->change_to_pkgnum);
my $new_pkgpart = $opt->{'pkgpart'}
@@ -2880,6 +2932,16 @@ sub change_later {
$change_to->set('start_date', $date);
$error = $self->replace || $change_to->replace;
}
+
+ if ( !$error && exists $opt->{waive_setup} ) {
+ $change_to->set(waive_setup => $opt->{waive_setup} );
+ $error = $change_to->insert();
+ }
+
+ if ( !$error && %new_discount ) {
+ $error = $change_to->change_discount(%new_discount);
+ }
+
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
return $error;
@@ -2913,11 +2975,17 @@ sub change_later {
} );
$error = $new->insert('change' => 1,
'allow_pkgpart' => ($new_pkgpart ? 0 : 1));
+
+ if ( !$error && %new_discount ) {
+ $error = $new->change_discount(%new_discount);
+ }
+
if ( !$error ) {
$self->set('change_to_pkgnum', $new->pkgnum);
$self->set('expire', $date);
$error = $self->replace;
}
+
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
} else {
@@ -2927,6 +2995,66 @@ sub change_later {
$error;
}
+# Helper method reads $opt hashref from change() and change_later()
+# Returns a hash of %new_discount suitable for passing to change_discount()
+sub _parse_new_discounts {
+ my ($self, $opt) = @_;
+
+ croak "Bad parameter list" unless ref $opt;
+
+ my %old_discount =
+ map { $_->setuprecur => $_ }
+ qsearch('cust_pkg_discount', {
+ pkgnum => $self->pkgnum,
+ disabled => '',
+ });
+
+ my %new_discount;
+ for my $type(qw|setup recur|) {
+
+ if (exists $opt->{"${type}_discountnum"}) {
+ $new_discount{$type} = {
+ discountnum => $opt->{"${type}_discountnum"},
+ amount => $opt->{"${type}_discountnum_amount"},
+ percent => $opt->{"${type}_discountnum_percent"},
+ };
+ }
+
+ # Specified discountnum same as old discountnum, carry over addl fields
+ if (
+ exists $opt->{"${type}_discountnum"}
+ && exists $old_discount{$type}
+ && $opt->{"${type}_discountnum"} eq $old_discount{$type}->discountnum
+ ){
+ $new_discount{$type}->{months} = $old_discount{$type}->months;
+ $new_discount{$type}->{end_date} = $old_discount{$type}->end_date;
+ }
+
+ # No new discount specified, carryover old discount
+ # If we wanted to abandon legacy behavior, and always carry old discounts
+ # uncomment this:
+
+ # if (!exists $new_discount{$type} && $old_discount{$type}) {
+ # $new_discount{$type} = {
+ # discountnum => $old_discount{$type}->discountnum,
+ # amount => $old_discount{$type}->amount,
+ # percent => $old_discount{$type}->percent,
+ # months => $old_discount{$type}->months,
+ # end_date => $old_discount{$type}->end_date,
+ # };
+ # }
+ }
+
+ if ($DEBUG) {
+ warn "_parse_new_discounts(), pkgnum: ".$self->pkgnum." \n";
+ warn "Determine \%old_discount, \%new_discount: \n";
+ warn Dumper(\%old_discount);
+ warn Dumper(\%new_discount);
+ }
+
+ %new_discount;
+}
+
=item abort_change
Cancels a future package change scheduled by C<change_later>.
@@ -4738,6 +4866,149 @@ sub insert_discount {
'';
}
+=item change_discount %opt
+
+Method checks if the given values represent a change in either setup or
+discount level. If so, the existing discounts are revoked, the new
+discounts are recorded.
+
+Usage:
+
+$error = change_discount(
+ setup => {
+
+ # -1: Indicates a "custom discount"
+ # 0: Indicates to remove any discount
+ # >0: discountnum to apply
+ discountnum => [-1, 0, discountnum],
+
+ # When discountnum is "-1" to indicate custom discount, include
+ # the additional fields:
+ amount => AMOUNT_DISCOUNT
+ percent => PERCENTAGE_DISCOUNT
+ months => -1,
+ },
+
+ recur => {...}
+);
+
+
+=cut
+
+sub change_discount {
+ my ($self, %opt) = @_;
+ return "change_discount() called with bad \%opt"
+ unless %opt;
+
+ for (keys %opt) {
+ return "change_discount() called with unknown bad key $_"
+ unless $_ eq 'setup' || $_ eq 'recur';
+ }
+
+ my @old_discount =
+ qsearch('cust_pkg_discount',{
+ pkgnum => $self->pkgnum,
+ disabled => '',
+ });
+
+ if ($DEBUG) {
+ warn "change_discount() pkgnum: ".$self->pkgnum." \n";
+ warn "change_discount() \%opt: \n";
+ warn Dumper(\%opt);
+ }
+
+ my @to_be_disabled;
+
+ for my $type (qw|setup recur|) {
+ next unless ref $opt{$type};
+ my %change = %{$opt{$type}};
+
+ return "change_discount() called with bad \$opt($type)"
+ unless $change{discountnum} =~ /^-?\d+$/;
+
+ if ($change{discountnum} eq 0) {
+ # Removing old discount
+
+ delete $opt{$type};
+ push @to_be_disabled, grep {$_->setuprecur eq $type} @old_discount;
+ } else {
+
+ if (
+ grep {
+ $_->discountnum eq $change{discountnum}
+ && $_->setuprecur eq $type
+ } @old_discount
+ ){
+ # Duplicate, disregard this entry
+ delete $opt{$type};
+ next;
+ } else {
+ # Mark any discounts we're replacing
+ push @to_be_disabled, grep{ $_->setuprecur eq $type} @old_discount;
+ }
+
+ }
+ }
+
+
+ # If we still have changes queued, pass them to insert_discount()
+ # by setting values into object fields
+ for my $type (keys %opt) {
+ $self->set("${type}_discountnum", $opt{$type}->{discountnum});
+
+ if ($opt{$type}->{discountnum} eq '-1') {
+ $self->set("${type}_discountnum_${_}", $opt{$type}->{$_})
+ for qw(amount percent months);
+ }
+
+ }
+
+ if ($DEBUG) {
+ warn "change_discount() \% opt before insert \n";
+ warn Dumper \%opt;
+ warn "\@to_be_disabled \n";
+ warn Dumper \@to_be_disabled;
+ }
+
+ # Roll these updates into a transaction
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
+ my $error;
+
+ # The "waive setup fee" flag has traditionally been handled by setting
+ # $cust_pkg->waive_setup_fee = Y. This has been appropriately, and separately
+ # handled, and it operates on a differetnt table than cust_pkg_discount,
+ # so the "-2 for waive setup fee" option is not being reimplemented
+ # here. Perhaps this may change later.
+ #
+ # When a setup discount is entered, we still need unset waive_setup
+ if ( $opt{setup} && $opt{setup} > -2 && $self->waive_setup ) {
+ $self->set(waive_setup => '');
+ $error = $self->replace();
+ }
+
+ # Create new discounts
+ $error ||= $self->insert_discount();
+
+ # Disabling old discounts
+ for my $tbd (@to_be_disabled) {
+ unless ($error) {
+ $tbd->set(disabled => 'Y');
+ $error = $tbd->replace();
+ }
+ }
+
+ if ($error) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+
+ $dbh->commit if $oldAutoCommit;
+ return undef;
+}
+
=item set_usage USAGE_VALUE_HASHREF
USAGE_VALUE_HASHREF is a hashref of svc_acct usage columns and the amounts
@@ -5707,4 +5978,3 @@ L<FS::pkg_svc>, schema.html from the base documentation
=cut
1;
-
diff --git a/httemplate/edit/process/change-cust_pkg.html b/httemplate/edit/process/change-cust_pkg.html
index 7fcc1da07..02b01f8de 100644
--- a/httemplate/edit/process/change-cust_pkg.html
+++ b/httemplate/edit/process/change-cust_pkg.html
@@ -40,19 +40,54 @@ if ( $cgi->param('locationnum') == -1 ) {
$change{'cust_location'} = $cust_location;
}
+my $error;
+
+# Discounts:
+# setup_discountnum and change_discountnum may contain one of the following:
+# - "-1" Represents the 'other' option. Results in a new entry to the
+# discount table.
+# - "-2" Represents the "waive setup fee" option. Sets cust_pkg.waive_setup = Y
+# - int Represents the id for a discount row: discount.discountnum
+# my %discount;
+# $change{waive_setup} = '';
+# for my $type (qw|setup recur|) {
+# my $dnum = $cgi->param("${type}_discountnum");
+
+# if ($dnum eq '-2' && $type eq 'setup') {
+# $change{waive_setup} = 'Y';
+# } elsif ($val =~ /^-?\d+$/) {
+# $discount{$type} = {discountnum => $dnum};
+# if ($dnum eq '-1') {
+# $discount{$type}->{amount} = $cgi->param("${type}_discountnum_amount");
+# $discount{$type}->{percent} = $cgi->param("${type}_discountnum_percent");
+# }
+# } else {
+# # Shouldn't happen without funny business
+# $error = "Bad value ${type}_discountnum ($val)";
+# }
+# }
+
+
$change{waive_setup} = '';
+for my $type (qw|setup_discountnum recur_discountnum|) {
+ my $dnum = $cgi->param($type);
-if ( $cgi->param('setup_discountnum') =~ /^(-?\d+)$/ ) {
- if ( $1 == -2 ) {
+ if ($dnum eq '-2' && $type eq 'setup_discountnum') {
+ # Waive Discount
$change{waive_setup} = 'Y';
+ } elsif ($dnum =~ /^-?\d+$/) {
+ # Set discountnum
+ $change{$type} = $dnum;
+ $change{"${type}_amount"} = $cgi->param("${type}_amount");
+ $change{"${type}_percent"} = $cgi->param("${type}_percent");
+ } elsif ($dnum eq '') {
+ # Set discount as no discount
+ $change{"${type}"} = 0;
} else {
- $change{setup_discountnum} = $1;
- $change{setup_discountnum_amount} = $cgi->param('setup_discountnum_amount');
- $change{setup_discountnum_percent} = $cgi->param('setup_discountnum_percent');
+ $error = "Bad value ${type}_discountnum ($dnum)";
}
}
-my $error;
my $now = time;
if (defined($cgi->param('contract_end'))) {
$change{'contract_end'} = parse_datetime($cgi->param('contract_end'));
diff --git a/httemplate/misc/change_pkg.cgi b/httemplate/misc/change_pkg.cgi
index 121df40cb..2470ee135 100755
--- a/httemplate/misc/change_pkg.cgi
+++ b/httemplate/misc/change_pkg.cgi
@@ -89,8 +89,14 @@
%
% if ( $discount_cust_pkg || $waive_setup_fee ) {
<FONT CLASS="fsinnerbox-title"><% mt('Discounting') |h %></FONT>
- <% ntable("#cccccc") %>
- <& /elements/tr-select-pkg-discount.html, disable_recur => 1, &>
+ <TABLE CLASS="fsinnerbox">
+ <& /elements/tr-select-pkg-discount.html,
+ curr_value_setup => $discount{setup},
+ curr_value_recur => $discount{recur},
+ disable_setup => 0,
+ disable_recur => 0,
+ disable_waive_setup => 0
+ &>
</TABLE><BR>
% }
@@ -168,4 +174,14 @@ if ( $cust_pkg->change_to_pkgnum ) {
}
$title = "Edit Scheduled Package Change";
}
+
+# Get current values of discounts for selectboxes
+my %discount = (setup => undef, recur => undef);
+$discount{$_->setuprecur} = $_->discountnum
+ for qsearch('cust_pkg_discount', {
+ pkgnum => $cust_pkg->pkgnum,
+ disabled => '',
+ });
+$discount{setup} = '-2' if $cust_pkg->waive_setup;
+
</%init>
-----------------------------------------------------------------------
Summary of changes:
FS/FS/cust_pkg.pm | 283 +++++++++++++++++++++++-
httemplate/edit/process/change-cust_pkg.html | 48 +++-
httemplate/elements/select-table.html | 19 +-
httemplate/elements/tr-select-pkg-discount.html | 24 +-
httemplate/misc/change_pkg.cgi | 22 +-
5 files changed, 376 insertions(+), 20 deletions(-)
More information about the freeside-commits
mailing list