summaryrefslogtreecommitdiff
path: root/httemplate
diff options
context:
space:
mode:
authorMark Wells <mark@freeside.biz>2013-07-15 18:37:26 -0700
committerMark Wells <mark@freeside.biz>2013-07-15 18:37:26 -0700
commit2c62268f304f1ec6e8baf89043eb1bd1197bb9a6 (patch)
tree0be3cca186ab9b682181555c8602b1be30d2e670 /httemplate
parent53fbfad948c15a03e1939e3b81e2b5fca5796015 (diff)
future package change, #20687
Diffstat (limited to 'httemplate')
-rw-r--r--httemplate/edit/process/change-cust_pkg.html31
-rw-r--r--httemplate/elements/tr-select-cust-part_pkg.html5
-rwxr-xr-xhttemplate/misc/change_pkg.cgi29
-rwxr-xr-xhttemplate/view/cust_main/packages.html21
-rw-r--r--httemplate/view/cust_main/packages/location.html35
-rw-r--r--httemplate/view/cust_main/packages/package.html26
-rwxr-xr-xhttemplate/view/cust_main/packages/section.html4
-rw-r--r--httemplate/view/cust_main/packages/status.html125
8 files changed, 229 insertions, 47 deletions
diff --git a/httemplate/edit/process/change-cust_pkg.html b/httemplate/edit/process/change-cust_pkg.html
index c893f13a2..9d06d8e1a 100644
--- a/httemplate/edit/process/change-cust_pkg.html
+++ b/httemplate/edit/process/change-cust_pkg.html
@@ -40,8 +40,35 @@ if ( $cgi->param('locationnum') == -1 ) {
$change{'cust_location'} = $cust_location;
}
-my $pkg_or_error = $cust_pkg->change( \%change );
+my $error;
+if ( $cgi->param('delay') ) {
+ my $date = parse_datetime($cgi->param('start_date'));
+ if (!$date) {
+ $error = "Invalid change date '".$cgi->param('start_date')."'.";
+ } elsif ( $date < time ) {
+ $error = "Change date ".$cgi->param('start_date')." is in the past.";
+ } else {
+ # schedule the change
+ $change{'start_date'} = $date;
+ $error = $cust_pkg->change_later(\%change);
+ }
+} else {
+ # special case: if there's a package change scheduled, and it matches
+ # the parameters the user requested this time, then change to the existing
+ # future package.
+ if ( $cust_pkg->change_to_pkgnum ) {
+ my $change_to = FS::cust_pkg->by_key($cust_pkg->change_to_pkgnum);
+ if ( $change_to->pkgpart == $change{'pkgpart'} and
+ $change_to->locationnum == $change{'locationnum'} ) {
-my $error = ref($pkg_or_error) ? '' : $pkg_or_error;
+ %change = ( 'cust_pkg' => $change_to );
+
+ }
+ }
+
+ # do a package change right now
+ my $pkg_or_error = $cust_pkg->change( \%change );
+ $error = ref($pkg_or_error) ? '' : $pkg_or_error;
+}
</%init>
diff --git a/httemplate/elements/tr-select-cust-part_pkg.html b/httemplate/elements/tr-select-cust-part_pkg.html
index c9c50d27e..488f04a13 100644
--- a/httemplate/elements/tr-select-cust-part_pkg.html
+++ b/httemplate/elements/tr-select-cust-part_pkg.html
@@ -20,7 +20,7 @@
what.form.pkgpart.disabled = 'disabled'; //disable part_pkg dropdown
var submitButton = what.form.submitButton; // || what.form.submit;
- if ( submitButton ) {
+ if ( submitButton && <% $opt{'curr_value'} ? 0 : 1 %> ) {
submitButton.disabled = true; //disable the submit button
}
var discountnum = what.form.discountnum;
@@ -51,6 +51,9 @@
}
what.form.pkgpart.disabled = ''; //re-enable part_pkg dropdown
+% if ( $opt{'curr_value'} ) {
+ what.form.pkgpart.value = <% $opt{'curr_value'} %>;
+% }
}
diff --git a/httemplate/misc/change_pkg.cgi b/httemplate/misc/change_pkg.cgi
index 03e336cba..7425fbfaf 100755
--- a/httemplate/misc/change_pkg.cgi
+++ b/httemplate/misc/change_pkg.cgi
@@ -1,7 +1,6 @@
-<& /elements/header-popup.html, mt("Change Package") &>
+<& /elements/header-popup.html, mt($title) &>
<SCRIPT TYPE="text/javascript" SRC="../elements/order_pkg.js"></SCRIPT>
-
<& /elements/error.html &>
<FORM NAME="OrderPkgForm" ACTION="<% $p %>edit/process/change-cust_pkg.html" METHOD=POST>
@@ -30,6 +29,21 @@
</TABLE>
+<TABLE>
+ <TR>
+ <TD> Apply this change: </TD>
+ <TD> <INPUT TYPE="radio" NAME="delay" VALUE="0" \
+ <% !$cgi->param('delay') ? 'CHECKED' : '' %>> now </TD>
+ <TD> <INPUT TYPE="radio" NAME="delay" VALUE="1" \
+ <% $cgi->param('delay') ? 'CHECKED' : '' %>> in the future
+ <& /elements/input-date-field.html, {
+ 'name' => 'start_date',
+ 'value' => ($cgi->param('start_date') || $cust_main->next_bill_date),
+ } &>
+ </TD>
+ </TR>
+</TABLE>
+
<& /elements/standardize_locations.html,
'form' => "OrderPkgForm",
'callback' => 'document.OrderPkgForm.submit();',
@@ -74,4 +88,15 @@ my $cust_main = $cust_pkg->cust_main
my $part_pkg = $cust_pkg->part_pkg;
+my $title = "Change Package";
+
+# if there's already a package change ordered, preload it
+if ( $cust_pkg->change_to_pkgnum ) {
+ my $change_to = FS::cust_pkg->by_key($cust_pkg->change_to_pkgnum);
+ $cgi->param('delay', 1);
+ foreach(qw( start_date pkgpart locationnum )) {
+ $cgi->param($_, $change_to->get($_));
+ }
+ $title = "Edit Scheduled Package Change";
+}
</%init>
diff --git a/httemplate/view/cust_main/packages.html b/httemplate/view/cust_main/packages.html
index e32fe4c03..566ab2943 100755
--- a/httemplate/view/cust_main/packages.html
+++ b/httemplate/view/cust_main/packages.html
@@ -3,7 +3,6 @@ td.package {
vertical-align: top;
border-width: 0;
border-style: solid;
- border-color: #bbbbff;
}
table.package {
border: none;
@@ -199,11 +198,30 @@ sub get_packages {
} );
my $num_old_packages = scalar(@packages);
+ my %change_to_from; # target pkgnum => current cust_pkg, for future changes
+
foreach my $cust_pkg ( @packages ) {
my %hash = $cust_pkg->hash;
my %part_pkg = map { /^part_pkg_(.+)$/ or die; ( $1 => $hash{$_} ); }
grep { /^part_pkg_/ } keys %hash;
$cust_pkg->{'_pkgpart'} = new FS::part_pkg \%part_pkg;
+ if ( $cust_pkg->change_to_pkgnum ) {
+ $change_to_from{$cust_pkg->change_to_pkgnum} = $cust_pkg;
+ }
+ }
+
+ if ( keys %change_to_from ) {
+ my @not_future_packages;
+ foreach my $cust_pkg (@packages) {
+ if ( exists( $change_to_from{$cust_pkg->pkgnum} ) ) {
+ my $change_from = $change_to_from{ $cust_pkg->pkgnum };
+ $cust_pkg->set('change_from_pkg', $change_from);
+ $change_from->set('change_to_pkg', $cust_pkg);
+ } else {
+ push @not_future_packages, $cust_pkg;
+ }
+ }
+ @packages = @not_future_packages;
}
unless ( $cgi->param('showoldpackages') ) {
@@ -225,6 +243,7 @@ sub get_packages {
# don't include supplemental packages in this list; they'll be found from
# their main packages
+ # (as will change-target packages)
@packages = grep !$_->main_pkgnum, @packages;
( \@packages, $num_old_packages );
diff --git a/httemplate/view/cust_main/packages/location.html b/httemplate/view/cust_main/packages/location.html
index ab961b79e..01cbc0ffb 100644
--- a/httemplate/view/cust_main/packages/location.html
+++ b/httemplate/view/cust_main/packages/location.html
@@ -1,6 +1,11 @@
-% if ( $default ) {
- <DIV STYLE="font-style: italic; font-size: small">
-% }
+% if ( $cust_pkg->change_from_pkg
+% and $cust_pkg->change_from_pkg->locationnum == $cust_pkg->locationnum )
+% {
+% # don't show the location
+% } else {
+% if ( $default ) {
+ <DIV STYLE="font-style: italic; font-size: small">
+% }
<% $loc->location_label( 'join_string' => '<BR>',
'double_space' => ' &nbsp; ',
@@ -22,25 +27,25 @@
</FONT>
% }
-% if ( $default ) {
- </DIV>
-% }
+% if ( $default ) {
+ </DIV>
+% }
-% if ( ! $cust_pkg->get('cancel')
+% if ( ! $cust_pkg->get('cancel')
% && $FS::CurrentUser::CurrentUser->access_right('Change customer package')
-% )
-% {
+% )
+% {
<BR>
<FONT SIZE=-1>
-% unless ( $opt{no_links} ) {
+% unless ( $opt{no_links} or $opt{'change_from'} ) {
(&nbsp;<%pkg_change_location_link($cust_pkg)%>&nbsp;)
-% }
-% if ( $cust_pkg->locationnum && ! $opt{no_links} ) {
+% }
+% if ( $cust_pkg->locationnum && ! $opt{no_links} ) {
(&nbsp;<%edit_location_link($cust_pkg->locationnum)%>&nbsp;)
-% }
+% }
</FONT>
-% }
-
+% }
+% }
<%init>
my $conf = new FS::Conf;
diff --git a/httemplate/view/cust_main/packages/package.html b/httemplate/view/cust_main/packages/package.html
index 7aad9a44e..596a47391 100644
--- a/httemplate/view/cust_main/packages/package.html
+++ b/httemplate/view/cust_main/packages/package.html
@@ -1,5 +1,4 @@
-<TD CLASS="inv package" BGCOLOR="<% $bgcolor %>" VALIGN="top"
- STYLE="border-left-width: <% $supplemental * 30 %>px">
+<TD CLASS="inv package" BGCOLOR="<% $bgcolor %>" VALIGN="top" <%$style%>>
<TABLE CLASS="inv package">
<TR>
<TD COLSPAN=2>
@@ -30,7 +29,11 @@
% unless ( $cust_pkg->get('cancel') || $opt{no_links} ) {
%
-% if ( $supplemental or $part_pkg->freq eq '0' ) {
+% if ( $change_from ) {
+% # This is the target package for a future change.
+% # Nothing you can do with it besides modify/cancel the
+% # future change, and that's on the current package.
+% } elsif ( $supplemental or $part_pkg->freq eq '0' ) {
% # Supplemental packages can't be changed independently.
% # One-time charges don't need to be changed.
% # For both of those, we only show "Add comments",
@@ -185,6 +188,7 @@
% )
% {
<TR>
+% # yeah, I guess we'll let you do this on a future change package
% if ( FS::Conf->new->exists('invoice-unitprice') ) {
<TD><FONT SIZE="-1">
(&nbsp;<% pkg_change_quantity_link($cust_pkg) %>&nbsp;)
@@ -233,7 +237,21 @@ my $countrydefault = $opt{'countrydefault'} || 'US';
my $statedefault = $opt{'statedefault'}
|| ($countrydefault eq 'US' ? 'CA' : '');
+# put a marker on the left edge of this column
+# if this package is somehow special
my $supplemental = $opt{'supplemental'} || 0;
+my $change_from = $opt{'change_from'} || 0;
+my $style = '';
+if ( $supplemental or $change_from ) {
+ $style = 'border-left-width: '.($supplemental + $change_from)*30 . 'px; '.
+ 'border-color: ';
+ if ( $supplemental ) {
+ $style .= '#bbbbff';
+ } elsif ( $change_from ) {
+ $style .= '#bbffbb';
+ }
+ $style = qq!STYLE="$style"!;
+}
$cust_pkg->pkgnum =~ /^(\d+)$/;
my $pkgnum = $1;
@@ -263,7 +281,7 @@ sub pkg_change_link {
'actionlabel' => emt('Change'),
'cust_pkg' => $cust_pkg,
'width' => 763,
- 'height' => 380,
+ 'height' => 480,
);
}
diff --git a/httemplate/view/cust_main/packages/section.html b/httemplate/view/cust_main/packages/section.html
index 82d06203b..0383fe892 100755
--- a/httemplate/view/cust_main/packages/section.html
+++ b/httemplate/view/cust_main/packages/section.html
@@ -36,6 +36,10 @@
<& services.html, %iopt &>
</TR>
% $row++;
+% # show the change target, if there is one
+% if ( $cust_pkg->change_to_pkg ) {
+ <& .packagerow, $cust_pkg->change_to_pkg, %iopt, 'change_from' => 1 &>
+% }
% # include supplemental packages if any
% $iopt{'supplemental'} = ($iopt{'supplemental'} || 0) + 1;
% foreach my $supp_pkg ($cust_pkg->supplemental_pkgs) {
diff --git a/httemplate/view/cust_main/packages/status.html b/httemplate/view/cust_main/packages/status.html
index ed360cca4..6894a4e02 100644
--- a/httemplate/view/cust_main/packages/status.html
+++ b/httemplate/view/cust_main/packages/status.html
@@ -76,18 +76,29 @@
<% pkg_status_row_if( $cust_pkg, emt('Next bill'), 'bill', %opt, curuser=>$curuser ) %>
% }
<% pkg_status_row_if( $cust_pkg, emt('Will resume'), 'resume', %opt, curuser=>$curuser ) %>
- <% pkg_status_row_if( $cust_pkg, emt('Expires'), 'expire', %opt, curuser=>$curuser ) %>
+ <% pkg_status_row_expire($cust_pkg, %opt, curuser=>$curuser) %>
<% pkg_status_row_if( $cust_pkg, emt('Contract ends'), 'contract_end', %opt ) %>
-% if ( !$supplemental && ! $opt{no_links} ) {
+% if ( !$supplemental && ! $opt{no_links} && !$change_from ) {
<TR>
<TD COLSPAN=<%$opt{colspan}%>>
<FONT SIZE=-1>
+% if ( $cust_pkg->change_to_pkgnum ) {
+% # then you can modify the package change
+% if ( $curuser->access_right('Change customer package') ) {
+ (&nbsp;<% pkg_change_now_link($cust_pkg) %>&nbsp;)
+ (&nbsp;<% pkg_change_later_link($cust_pkg) %>&nbsp;)
+ (&nbsp;<% pkg_unchange_link($cust_pkg) %>&nbsp;)
+ <BR>
+% }
+% }
% if ( $curuser->access_right('Unsuspend customer package') ) {
(&nbsp;<% pkg_unsuspend_link($cust_pkg) %>&nbsp;)
(&nbsp;<% pkg_resume_link($cust_pkg) %>&nbsp;)
% }
-% if ( $curuser->access_right('Cancel customer package immediately') ) {
+% if ( !$cust_pkg->change_to_pkgnum and
+% $curuser->access_right('Cancel customer package immediately')
+% ) {
(&nbsp;<% pkg_cancel_link($cust_pkg) %>&nbsp;)
% }
</FONT>
@@ -97,9 +108,17 @@
%
% } else { #status: active
%
-% unless ( $cust_pkg->get('setup') ) { #not setup
+% if ( $change_from ) { # future change
+%
+ <% pkg_status_row_colspan( $cust_pkg, emt('Waiting for package change'), '', %opt ) %>
+ <% pkg_status_row( $cust_pkg,
+ emt('Will be activated on'),
+ 'start_date',
+ %opt ) %>
%
-% unless ( $part_pkg->freq ) {
+% } elsif ( ! $cust_pkg->get('setup') ) { # not setup
+%
+% unless ( $part_pkg->freq ) { # one-time charge
<% pkg_status_row_colspan( $cust_pkg, emt('Not yet billed (one-time charge)'), '', %opt ) %>
@@ -193,7 +212,7 @@
% }
%
-% }
+% }
%
% if ( $opt{'cust_pkg-show_autosuspend'} ) {
% my $autosuspend = pkg_autosuspend_time( $cust_pkg );
@@ -207,7 +226,7 @@
<% pkg_status_row_if($cust_pkg, emt('Automatic suspension delayed until'), 'dundate', %opt) %>
<% pkg_status_row_if( $cust_pkg, emt('Will suspend on'), 'adjourn', %opt, curuser=>$curuser ) %>
<% pkg_status_row_if( $cust_pkg, emt('Will resume on'), 'resume', %opt, curuser=>$curuser ) %>
- <% pkg_status_row_if( $cust_pkg, emt('Expires'), 'expire', %opt, curuser=>$curuser ) %>
+ <% pkg_status_row_expire($cust_pkg, %opt, curuser=>$curuser) %>
<% pkg_status_row_if( $cust_pkg, emt('Contract ends'), 'contract_end', %opt ) %>
% if ( $part_pkg->freq and !$supplemental && ! $opt{no_links} ) {
@@ -215,21 +234,41 @@
<TR>
<TD COLSPAN=<%$opt{colspan}%>>
<FONT SIZE=-1>
-% if ( $curuser->access_right('Suspend customer package') ) {
- (&nbsp;<% pkg_suspend_link($cust_pkg) %>&nbsp;)
-% }
-% if ( $curuser->access_right('Suspend customer package later') ) {
- (&nbsp;<% pkg_adjourn_link($cust_pkg) %>&nbsp;)
-% }
-% if ( $curuser->access_right('Delay suspension events') ) {
- (&nbsp;<% pkg_delay_link($cust_pkg) %>&nbsp;)
-% }
+% # action links
+% if ( $change_from ) {
+% # nothing
+% } elsif ( $cust_pkg->change_to_pkgnum ) {
+% # then you can modify the package change
+% if ( $curuser->access_right('Change customer package') ) {
+ (&nbsp;<% pkg_change_now_link($cust_pkg) %>&nbsp;)
+ (&nbsp;<% pkg_change_later_link($cust_pkg) %>&nbsp;)
+ (&nbsp;<% pkg_unchange_link($cust_pkg) %>&nbsp;)
+ <BR>
+% }
+% }
+
+% # suspension actions--always available
+% if ( $curuser->access_right('Suspend customer package') ) {
+ (&nbsp;<% pkg_suspend_link($cust_pkg) %>&nbsp;)
+% }
+% if ( $curuser->access_right('Suspend customer package later') ) {
+ (&nbsp;<% pkg_adjourn_link($cust_pkg) %>&nbsp;)
+% }
+% if ( $curuser->access_right('Delay suspension events') ) {
+ (&nbsp;<% pkg_delay_link($cust_pkg) %>&nbsp;)
+% }
+%
+% if ( $change_from or $cust_pkg->change_to_pkgnum ) {
+% # you can't cancel the package while in this state
+% } else { # the normal case: links to cancel the package
+ <BR>
% if ( $curuser->access_right('Cancel customer package immediately') ) {
(&nbsp;<% pkg_cancel_link($cust_pkg) %>&nbsp;)
-% }
+% }
% if ( $curuser->access_right('Cancel customer package later') ) {
(&nbsp;<% pkg_expire_link($cust_pkg) %>&nbsp;)
% }
+% }
<FONT>
</TD>
@@ -251,6 +290,7 @@ my $part_pkg = $opt{'part_pkg'};
my $curuser = $FS::CurrentUser::CurrentUser;
my $width = $opt{'cust_pkg-display_times'} ? '38%' : '56%';
my $supplemental = $opt{'supplemental'};
+my $change_from = $opt{'change_from'};
$opt{colspan} = $opt{'cust_pkg-display_times'} ? 8 : 4;
@@ -330,14 +370,41 @@ sub pkg_status_row_if {
$opt{curuser}->access_right('Suspend customer package later')
);
- $title = '<FONT SIZE=-1>(&nbsp;'. pkg_unexpire_link($cust_pkg). '&nbsp;)&nbsp;</FONT>'. $title
- if ( $field eq 'expire' &&
- $opt{curuser}->access_right('Cancel customer package later')
- );
-
$cust_pkg->get($field) ? pkg_status_row($cust_pkg, $title, $field, %opt) : '';
}
+sub pkg_status_row_expire {
+ my $cust_pkg = shift;
+ my %opt = @_;
+ return unless $cust_pkg->get('expire');
+
+ my $title;
+
+ if ( $cust_pkg->get('change_to_pkg') ) {
+ if ( $cust_pkg->change_to_pkg->pkgpart != $cust_pkg->pkgpart ) {
+ $title = mt('Will change to <b>[_1]</b> on',
+ $cust_pkg->change_to_pkg->part_pkg->pkg);
+ } elsif ( $cust_pkg->change_to_pkg->locationnum != $cust_pkg->locationnum )
+ {
+ $title = mt('Will <b>change location</b> on');
+ } else {
+ # FS::cust_pkg->change_later should have prevented this, but
+ # just so that we can display _something_
+ $title = '<font color="#ff0000">Unknown package change</font>';
+ }
+
+ } else {
+
+ $title = emt('Expires');
+ if ( $opt{curuser}->access_right('Cancel customer package later')) {
+ $title = '<FONT SIZE=-1>(&nbsp;'. pkg_unexpire_link($cust_pkg). '&nbsp;)&nbsp;</FONT>'. $title;
+ }
+
+ }
+
+ pkg_status_row( $cust_pkg, $title, 'expire', %opt );
+}
+
sub pkg_status_row_changed {
my( $cust_pkg, %opt ) = @_;
@@ -538,6 +605,8 @@ sub pkg_resume_link {
sub pkg_unsuspend_link { pkg_link('misc/unsusp_pkg', emt('Unsuspend now'), @_ ); }
sub pkg_unadjourn_link { pkg_link('misc/unadjourn_pkg', emt('Abort'), @_ ); }
sub pkg_unexpire_link { pkg_link('misc/unexpire_pkg', emt('Abort'), @_ ); }
+sub pkg_unchange_link { pkg_link('misc/do_not_change_pkg', emt('Abort change'), @_ ); }
+sub pkg_change_now_link { pkg_link('misc/change_pkg_now', emt('Change now'), @_ ); }
sub pkg_cancel_link {
include( '/elements/popup_link-cust_pkg.html',
@@ -569,6 +638,18 @@ sub pkg_expire_link {
)
}
+sub pkg_change_later_link {
+ my $cust_pkg = shift;
+ include( '/elements/popup_link-cust_pkg.html',
+ 'action' => $p . 'misc/change_pkg.cgi?',
+ 'label' => emt('Reschedule'),
+ 'actionlabel' => emt('Edit scheduled change for'),
+ 'cust_pkg' => $cust_pkg,
+ 'width' => 763,
+ 'height' => 480,
+ )
+}
+
sub svc_recharge_link {
include( '/elements/popup_link-cust_svc.html',
'action' => $p. 'misc/recharge_svc.html',