summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Kohler <ivan@freeside.biz>2014-04-27 14:19:59 -0700
committerIvan Kohler <ivan@freeside.biz>2014-04-27 14:19:59 -0700
commita7d8494c57376bfc493fbaa234b250cc86a79a94 (patch)
tree71c2443321738bccb4c6bbaa0e4f1495e6c099da
parent14b88b83f22a15b5abb5ba94328f213923a3bb95 (diff)
"on hold" package ordering and status, RT#28508
also even with flag set to do so, don't adjust bill dates forward on a package which is billing while suspended, RT#27882
-rw-r--r--FS/FS/cust_main/Billing.pm14
-rw-r--r--FS/FS/cust_pkg.pm47
-rw-r--r--FS/FS/cust_pkg/Search.pm10
-rwxr-xr-xhttemplate/browse/part_pkg.cgi15
-rw-r--r--httemplate/edit/process/quick-cust_pkg.cgi12
-rw-r--r--httemplate/elements/order_pkg.js19
-rwxr-xr-xhttemplate/misc/change_pkg.cgi2
-rw-r--r--httemplate/misc/order_pkg.html18
-rwxr-xr-xhttemplate/search/report_cust_pkg.html3
-rw-r--r--httemplate/view/cust_main/packages/status.html33
10 files changed, 126 insertions, 47 deletions
diff --git a/FS/FS/cust_main/Billing.pm b/FS/FS/cust_main/Billing.pm
index 63c7f2b58..2878276cc 100644
--- a/FS/FS/cust_main/Billing.pm
+++ b/FS/FS/cust_main/Billing.pm
@@ -1127,10 +1127,16 @@ sub _make_lines {
my $recur_billed_amount = 0;
my $sdate;
if ( ! $cust_pkg->start_date
- and ( ! $cust_pkg->susp || $cust_pkg->option('suspend_bill',1)
- || ( $part_pkg->option('suspend_bill', 1) )
- && ! $cust_pkg->option('no_suspend_bill',1)
- )
+ and
+ ( ! $cust_pkg->susp
+ || ( $cust_pkg->susp != $cust_pkg->order_date
+ && ( $cust_pkg->option('suspend_bill',1)
+ || ( $part_pkg->option('suspend_bill', 1)
+ && ! $cust_pkg->option('no_suspend_bill',1)
+ )
+ )
+ )
+ )
and
( $part_pkg->freq ne '0' && ( $cust_pkg->bill || 0 ) <= $cmp_time )
|| ( $part_pkg->plan eq 'voip_cdr'
diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm
index a893e5cbe..d546e555d 100644
--- a/FS/FS/cust_pkg.pm
+++ b/FS/FS/cust_pkg.pm
@@ -341,6 +341,8 @@ sub insert {
$self->order_date(time) unless ($import && $self->order_date)
or $self->change_pkgnum;
+ $self->susp( $self->order_date ) if $self->susp eq 'now';
+
my $oldAutoCommit = $FS::UID::AutoCommit;
local $FS::UID::AutoCommit = 0;
my $dbh = dbh;
@@ -1526,16 +1528,20 @@ sub unsuspend {
my $conf = new FS::Conf;
- if ( $inactive > 0 &&
- ( $hash{'bill'} || $hash{'setup'} ) &&
- ( $opt{'adjust_next_bill'} ||
- $conf->exists('unsuspend-always_adjust_next_bill_date') ||
- $self->part_pkg->option('unsuspend_adjust_bill', 1) )
- ) {
-
- $hash{'bill'} = ( $hash{'bill'} || $hash{'setup'} ) + $inactive;
-
- }
+ #adjust the next bill date forward
+ $hash{'bill'} = ( $hash{'bill'} || $hash{'setup'} ) + $inactive
+ if $inactive > 0
+ && ( $hash{'bill'} || $hash{'setup'} )
+ && ( $opt{'adjust_next_bill'}
+ || $conf->exists('unsuspend-always_adjust_next_bill_date')
+ || $self->part_pkg->option('unsuspend_adjust_bill', 1)
+ )
+ && ! $self->option('suspend_bill',1)
+ && ( ! $self->part_pkg->option('suspend_bill',1)
+ || $self->option('no_suspend_bill',1)
+ )
+ && $hash{'order_date'} != $hash{'susp'}
+ ;
$hash{'susp'} = '';
$hash{'adjourn'} = '' if $hash{'adjourn'} and $hash{'adjourn'} < time;
@@ -3086,6 +3092,8 @@ Returns a short status string for this package, currently:
=over 4
+=item on hold
+
=item not yet billed
=item one-time charge
@@ -3106,6 +3114,7 @@ sub status {
my $freq = length($self->freq) ? $self->freq : $self->part_pkg->freq;
return 'cancelled' if $self->get('cancel');
+ return 'on hold' if $self->susp && ! $self->setup;
return 'suspended' if $self->susp;
return 'not yet billed' unless $self->setup;
return 'one-time charge' if $freq =~ /^(0|$)/;
@@ -3132,6 +3141,7 @@ Class method that returns the list of possible status strings for packages
=cut
tie my %statuscolor, 'Tie::IxHash',
+ 'on hold' => '7E0079', #purple!
'not yet billed' => '009999', #teal? cyan?
'one-time charge' => '000000',
'active' => '00CC00',
@@ -4176,6 +4186,21 @@ sub inactive_sql { "
AND ( cust_pkg.susp IS NULL OR cust_pkg.susp = 0 )
"; }
+=item on_hold_sql
+
+Returns an SQL expression identifying on-hold packages.
+
+=cut
+
+sub on_hold_sql {
+ #$_[0]->recurring_sql(). ' AND '.
+ "
+ ( cust_pkg.cancel IS NULL OR cust_pkg.cancel = 0 )
+ AND cust_pkg.susp IS NOT NULL AND cust_pkg.susp != 0
+ AND ( cust_pkg.setup IS NULL OR cust_pkg.setup = 0 )
+ ";
+}
+
=item susp_sql
=item suspended_sql
@@ -4189,6 +4214,7 @@ sub susp_sql {
"
( cust_pkg.cancel IS NULL OR cust_pkg.cancel = 0 )
AND cust_pkg.susp IS NOT NULL AND cust_pkg.susp != 0
+ AND cust_pkg.setup IS NOT NULL AND cust_pkg.setup != 0
";
}
@@ -4214,6 +4240,7 @@ Returns an SQL expression to give the package status as a string.
sub status_sql {
"CASE
WHEN cust_pkg.cancel IS NOT NULL THEN 'cancelled'
+ WHEN ( cust_pkg.susp IS NOT NULL AND cust_pkg.setup IS NULL ) THEN 'on hold'
WHEN cust_pkg.susp IS NOT NULL THEN 'suspended'
WHEN cust_pkg.setup IS NULL THEN 'not yet billed'
WHEN ".onetime_sql()." THEN 'one-time charge'
diff --git a/FS/FS/cust_pkg/Search.pm b/FS/FS/cust_pkg/Search.pm
index 47efd3140..543ef1a61 100644
--- a/FS/FS/cust_pkg/Search.pm
+++ b/FS/FS/cust_pkg/Search.pm
@@ -19,11 +19,11 @@ Valid parameters are
=item magic
-active, inactive, suspended, cancel (or cancelled)
+on hold, active, inactive (or one-time charge), suspended, cancel (or cancelled)
=item status
-active, inactive, suspended, one-time charge, inactive, cancel (or cancelled)
+on hold, active, inactive (or one-time charge), suspended, cancel (or cancelled)
=item custom
@@ -191,6 +191,12 @@ sub search {
push @where, FS::cust_pkg->inactive_sql();
+ } elsif ( $params->{'magic'} =~ /^on[ _]hold$/
+ || $params->{'status'} =~ /^on[ _]hold$/ ) {
+
+ push @where, FS::cust_pkg->on_hold_sql();
+
+
} elsif ( $params->{'magic'} eq 'suspended'
|| $params->{'status'} eq 'suspended' ) {
diff --git a/httemplate/browse/part_pkg.cgi b/httemplate/browse/part_pkg.cgi
index 574cf7af3..d0c14da4c 100755
--- a/httemplate/browse/part_pkg.cgi
+++ b/httemplate/browse/part_pkg.cgi
@@ -128,9 +128,16 @@ $select = "
( $count_cust_pkg
AND ( cancel IS NULL OR cancel = 0 )
AND susp IS NOT NULL AND susp != 0
+ AND setup IS NOT NULL AND setup != 0
) AS num_suspended,
( $count_cust_pkg
+ AND ( cancel IS NULL OR cancel = 0 )
+ AND susp IS NOT NULL AND susp != 0
+ AND ( setup IS NULL OR setup = 0 )
+ ) AS num_on_hold,
+
+ ( $count_cust_pkg
AND cancel IS NOT NULL AND cancel != 0
) AS num_cancelled
@@ -382,6 +389,7 @@ if ( $acl_edit_global ) {
#if ( $cgi->param('active') ) {
push @header, 'Customer<BR>packages';
my %col = (
+ 'on hold' => '7E0079', #purple!
'not yet billed' => '009999', #teal? cyan?
'active' => '00CC00',
'suspended' => 'FF9900',
@@ -397,10 +405,11 @@ if ( $acl_edit_global ) {
my $label = $_;
if ( $magic eq 'active' && $part_pkg->freq == 0 ) {
$magic = 'inactive';
- #$label = 'one-time charge',
- $label = 'charge',
+ #$label = 'one-time charge';
+ $label = 'charge';
}
$label= 'not yet billed' if $magic eq 'not_yet_billed';
+ $label= 'on hold' if $magic eq 'on_hold';
[
{
@@ -425,7 +434,7 @@ if ( $acl_edit_global ) {
),
},
],
- } (qw( not_yet_billed active suspended cancelled ))
+ } (qw( on_hold not_yet_billed active suspended cancelled ))
),
($acl_config ?
[ {},
diff --git a/httemplate/edit/process/quick-cust_pkg.cgi b/httemplate/edit/process/quick-cust_pkg.cgi
index c3ab6fec3..f1d8c2696 100644
--- a/httemplate/edit/process/quick-cust_pkg.cgi
+++ b/httemplate/edit/process/quick-cust_pkg.cgi
@@ -110,10 +110,6 @@ my $error = '';
my %hash = (
'pkgpart' => $pkgpart,
'quantity' => $quantity,
- 'start_date' => ( scalar($cgi->param('start_date'))
- ? parse_datetime($cgi->param('start_date'))
- : ''
- ),
'salesnum' => $salesnum,
'refnum' => $refnum,
'contactnum' => $contactnum,
@@ -133,6 +129,14 @@ my %hash = (
);
$hash{'custnum'} = $cust_main->custnum if $cust_main;
+if ( $cgi->param('start') eq 'on_hold' ) {
+ $hash{'susp'} = 'now';
+} elsif ( $cgi->param('start') eq 'on_date' ) {
+ $hash{'start_date'} = scalar($cgi->param('start_date'))
+ ? parse_datetime($cgi->param('start_date'))
+ : '';
+}
+
my @cust_pkg_usageprice = ();
foreach my $quantity_param ( grep { $cgi->param($_) && $cgi->param($_) > 0 }
grep /^usagepricenum(\d+)_quantity$/,
diff --git a/httemplate/elements/order_pkg.js b/httemplate/elements/order_pkg.js
index 393b845c9..a145cbb03 100644
--- a/httemplate/elements/order_pkg.js
+++ b/httemplate/elements/order_pkg.js
@@ -6,9 +6,12 @@ function pkg_changed () {
var opt = form.pkgpart.options[form.pkgpart.selectedIndex];
var date_button = document.getElementById('start_date_button');
- var date_button_disabled = document.getElementById('start_date_button_disabled');
+ var date_button_disabled = document.getElementById('start_date_disabled');
var date_text = document.getElementById('start_date_text');
+ var radio_now = document.getElementById('start_now');
+ //var radio_on_hold = document.getElementById('start_on_hold');
+ var radio_on_date = document.getElementById('start_on_date');
form.submitButton.disabled = false;
if ( discountnum ) {
@@ -32,11 +35,25 @@ function pkg_changed () {
date_text.disabled = false;
date_button.style.display = '';
date_button_disabled.style.display = 'none';
+ if ( radio_on_date ) {
+ radio_on_date.disabled = false;
+ if ( form.start_date_text.value.length > 0 && radio_now.checked ) {
+ radio_now.checked = false;
+ radio_on_date.checked = true;
+ }
+ }
} else {
date_text.style.backgroundColor = '#dddddd';
date_text.disabled = true;
date_button.style.display = 'none';
date_button_disabled.style.display = '';
+ if ( radio_on_date ) {
+ if ( radio_on_date.checked ) {
+ radio_on_date.checked = false;
+ radio_now.checked = true;
+ }
+ radio_on_date.disabled = true;
+ }
}
get_part_pkg_usageprice( opt.value, update_part_pkg_usageprice );
diff --git a/httemplate/misc/change_pkg.cgi b/httemplate/misc/change_pkg.cgi
index 5b4a3dea9..1b4a94e81 100755
--- a/httemplate/misc/change_pkg.cgi
+++ b/httemplate/misc/change_pkg.cgi
@@ -59,8 +59,6 @@
'name' => 'start_date',
'value' => ($cgi->param('start_date') || $cust_main->next_bill_date),
} &>
- <IMG SRC="<%$fsurl%>images/calendar-disabled.png" \
- ID="start_date_button_disabled" STYLE="display:none">
</TD>
</TR>
</TABLE>
diff --git a/httemplate/misc/order_pkg.html b/httemplate/misc/order_pkg.html
index 080ba41d9..672e142c7 100644
--- a/httemplate/misc/order_pkg.html
+++ b/httemplate/misc/order_pkg.html
@@ -10,11 +10,7 @@
'subs' => [ 'get_part_pkg_usageprice' ],
&>
-
-<LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2">
-<SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT>
-<SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT>
-<SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT>
+<& /elements/init_calendar.html &>
<SCRIPT TYPE="text/javascript" SRC="../elements/order_pkg.js"></SCRIPT>
@@ -90,18 +86,20 @@
% }
<TR>
- <TH ALIGN="right"><% mt('Start date') |h %> </TD>
+ <TH ALIGN="right"><% mt('Start') |h %> </TD>
<TD COLSPAN=6>
+ <INPUT TYPE="radio" NAME="start" ID="start_now" VALUE="" <% $cgi->param('start') eq '' ? 'CHECKED' : ''%>>Now
+ &emsp;
+ <INPUT TYPE="radio" NAME="start" ID="start_on_hold" VALUE="on_hold" <% $cgi->param('start') eq 'on_hold' ? 'CHECKED' : ''%>>On hold
+ &emsp;
+ <INPUT TYPE="radio" NAME="start" ID="start_on_date" VALUE="on_date" <% $cgi->param('start') eq 'date' ? 'CHECKED' : ''%>>On date
+
<& /elements/input-date-field.html,{
'name' => 'start_date',
'format' => $date_format,
'value' => '',
'noinit' => 1,
} &>
- <IMG SRC = "<%$fsurl%>images/calendar-disabled.png"
- ID = "start_date_button_disabled"
- STYLE = "display:none">
- <FONT SIZE=-1>(<% mt('leave blank to start immediately') |h %>)</FONT>
</TD>
</TR>
diff --git a/httemplate/search/report_cust_pkg.html b/httemplate/search/report_cust_pkg.html
index e75a0985b..f124f0f87 100755
--- a/httemplate/search/report_cust_pkg.html
+++ b/httemplate/search/report_cust_pkg.html
@@ -260,7 +260,8 @@ my @date_fields = keys %label;
#false laziness w/cust_pkg.cgi
my %disable = (
'all' => {},
- 'not yet billed' => { 'setup'=>1, 'last_bill'=>1, 'bill'=>1, 'adjourn'=>1, 'susp'=>1, 'expire'=>1, 'cancel'=>1, },
+ 'on hold' => { 'setup'=>1, 'last_bill'=>1, 'bill'=>1, 'adjourn'=>1, 'expire'=>1, 'cancel'=>1, 'dundate'=> 1, },
+ 'not yet billed' => { 'setup'=>1, 'last_bill'=>1, 'bill'=>1, 'adjourn'=>1, 'susp'=>1, 'expire'=>1, 'cancel'=>1, 'dundate'=>1, },
'one-time charge' => { 'last_bill'=>1, 'bill'=>1, 'adjourn'=>1, 'susp'=>1, 'expire'=>1, 'cancel'=>1, 'contract_end'=>1, 'dundate'=>1, },
'active' => { 'susp'=>1, 'cancel'=>1 },
'suspended' => { 'cancel'=>1, 'dundate'=>1, },
diff --git a/httemplate/view/cust_main/packages/status.html b/httemplate/view/cust_main/packages/status.html
index 3ebdf22dc..689ee45c0 100644
--- a/httemplate/view/cust_main/packages/status.html
+++ b/httemplate/view/cust_main/packages/status.html
@@ -46,21 +46,30 @@
%
% } else {
%
-% if ( $cust_pkg->get('susp') ) { #status: suspended
-% my $cpr = $cust_pkg->last_cust_pkg_reason('susp');
+% if ( $cust_pkg->get('susp') ) { #suspended or on hold
+%
+% if ( $cust_pkg->order_date eq $cust_pkg->get('susp') ) { #status: on hold
+
+ <% pkg_status_row( $cust_pkg, emt('On Hold'), '', 'color'=>'7E0079', %opt ) %>
- <% pkg_status_row( $cust_pkg, emt('Suspended'), 'susp', 'color'=>'FF9900', %opt ) %>
+% } else { #status: suspended
- <% pkg_reason_row( $cust_pkg, $cpr, 'color' => 'FF9900', %opt ) %>
+ <% pkg_status_row( $cust_pkg, emt('Suspended'), 'susp', 'color'=>'FF9900', %opt ) %>
+% my $cpr = $cust_pkg->last_cust_pkg_reason('susp');
+ <% pkg_reason_row( $cust_pkg, $cpr, 'color' => 'FF9900', %opt ) %>
+
+% }
<% pkg_status_row_noauto( $cust_pkg, %opt ) %>
<% pkg_status_row_discount( $cust_pkg, %opt ) %>
-% unless ( $cust_pkg->get('setup') ) {
- <% pkg_status_row_colspan( $cust_pkg, emt('Never billed'), '', %opt ) %>
-% } else {
- <% pkg_status_row($cust_pkg, emt('Setup'), 'setup', %opt ) %>
+% unless ( $cust_pkg->order_date eq $cust_pkg->get('susp') ) { #on hold
+% unless ( $cust_pkg->get('setup') ) {
+ <% pkg_status_row_colspan( $cust_pkg, emt('Never billed'), '', %opt ) %>
+% } else {
+ <% pkg_status_row($cust_pkg, emt('Setup'), 'setup', %opt ) %>
+% }
% }
<% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %>
@@ -93,8 +102,12 @@
% }
% }
% if ( $curuser->access_right('Unsuspend customer package') ) {
- (&nbsp;<% pkg_unsuspend_link($cust_pkg) %>&nbsp;)
- (&nbsp;<% pkg_resume_link($cust_pkg) %>&nbsp;)
+% if ( $cust_pkg->order_date eq $cust_pkg->get('susp') ) { #on hold
+ (&nbsp;<% pkg_link('misc/unsusp_pkg', emt('Start bililng now'), $cust_pkg) %>&nbsp;)
+% } else {
+ (&nbsp;<% pkg_unsuspend_link($cust_pkg) %>&nbsp;)
+ (&nbsp;<% pkg_resume_link($cust_pkg) %>&nbsp;)
+% }
% }
% if ( !$cust_pkg->change_to_pkgnum and
% $curuser->access_right('Cancel customer package immediately')