summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Prykop <jonathan@freeside.biz>2015-02-10 14:18:31 -0600
committerJonathan Prykop <jonathan@freeside.biz>2015-02-10 14:18:31 -0600
commit4d0db1129018d2f598091edbbffeb09b23c64d99 (patch)
treea8e1baf5c5e66fd330a7604710ebd0a5e987cad0
parent8c84e8692d48eff3b03822dcd18c1766fd0b9bca (diff)
RT#14671: Usage for current day when billing outstanding usage (for cancelling customers)
-rw-r--r--FS/FS/Conf.pm10
-rw-r--r--FS/FS/cust_main.pm21
-rw-r--r--FS/FS/cust_pkg.pm44
-rw-r--r--FS/FS/part_pkg/global_Mixin.pm5
-rw-r--r--httemplate/view/cust_main/misc.html7
5 files changed, 86 insertions, 1 deletions
diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm
index a4e26f7..091070e 100644
--- a/FS/FS/Conf.pm
+++ b/FS/FS/Conf.pm
@@ -4627,6 +4627,16 @@ and customer address. Include units.',
},
{
+ 'key' => 'part_pkg-delay_cancel-days',
+ 'section' => '',
+ 'description' => 'Expire packages in this many days when using delay_cancel (default is 1)',
+ 'type' => 'text',
+ 'validate' => sub { (($_[0] =~ /^\d*$/) && (($_[0] eq '') || $_[0]))
+ ? 'Must specify an integer number of days'
+ : '' }
+ },
+
+ {
'key' => 'mcp_svcpart',
'section' => '',
'description' => 'Master Control Program svcpart. Leave this blank.',
diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm
index d38f3d0..c3b141e 100644
--- a/FS/FS/cust_main.pm
+++ b/FS/FS/cust_main.pm
@@ -3900,6 +3900,27 @@ sub cust_status {
}
}
+=item is_status_delay_cancel
+
+Returns true if customer status is 'suspended'
+and all suspended cust_pkg return true for
+cust_pkg->is_status_delay_cancel.
+
+This is not a real status, this only meant for hacking display
+values, because otherwise treating the customer as suspended is
+really the whole point of the delay_cancel option.
+
+=cut
+
+sub is_status_delay_cancel {
+ my ($self) = @_;
+ return 0 unless $self->status eq 'suspended';
+ foreach my $cust_pkg ($self->ncancelled_pkgs) {
+ return 0 unless $cust_pkg->is_status_delay_cancel;
+ }
+ return 1;
+}
+
=item ucfirst_cust_status
=item ucfirst_status
diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm
index 56e4c90..1cc83b6 100644
--- a/FS/FS/cust_pkg.pm
+++ b/FS/FS/cust_pkg.pm
@@ -823,6 +823,20 @@ sub cancel {
my $date = $options{'date'} if $options{'date'}; # expire/cancel later
$date = '' if ($date && $date <= $cancel_time); # complain instead?
+ my $delay_cancel = undef;
+ if ( !$date && $self->part_pkg->option('delay_cancel',1)
+ && (($self->status eq 'active') || ($self->status eq 'suspended'))
+ ) {
+ my $expdays = $conf->config('part_pkg-delay_cancel-days') || 1;
+ my $expsecs = 60*60*24*$expdays;
+ my $suspfor = $self->susp ? $cancel_time - $self->susp : 0;
+ $expsecs = $expsecs - $suspfor if $suspfor;
+ unless ($expsecs <= 0) { #if it's already been suspended long enough, don't re-suspend
+ $delay_cancel = 1;
+ $date = $cancel_time + $expsecs;
+ }
+ }
+
#race condition: usage could be ongoing until unprovisioned
#resolved by performing a change package instead (which unprovisions) and
#later cancelling
@@ -893,6 +907,11 @@ sub cancel {
my %hash = $self->hash;
if ( $date ) {
$hash{'expire'} = $date;
+ if ($delay_cancel) {
+ $hash{'susp'} = $cancel_time unless $self->susp;
+ $hash{'adjourn'} = undef;
+ $hash{'resume'} = undef;
+ }
} else {
$hash{'cancel'} = $cancel_time;
}
@@ -3343,6 +3362,31 @@ sub statuscolor {
$statuscolor{$self->status};
}
+=item is_status_delay_cancel
+
+Returns true if part_pkg has option delay_cancel,
+cust_pkg status is 'suspended' and expire is set
+to cancel package within the next day (or however
+many days are set in global config part_pkg-delay_cancel-days.
+
+This is not a real status, this only meant for hacking display
+values, because otherwise treating the package as suspended is
+really the whole point of the delay_cancel option.
+
+=cut
+
+sub is_status_delay_cancel {
+ my ($self) = @_;
+ return 0 unless $self->part_pkg->option('delay_cancel',1);
+ return 0 unless $self->status eq 'suspended';
+ return 0 unless $self->expire;
+ my $conf = new FS::Conf;
+ my $expdays = $conf->config('part_pkg-delay_cancel-days') || 1;
+ my $expsecs = 60*60*24*$expdays;
+ return 0 unless $self->expire < time + $expsecs;
+ return 1;
+}
+
=item pkg_label
Returns a label for this package. (Currently "pkgnum: pkg - comment" or
diff --git a/FS/FS/part_pkg/global_Mixin.pm b/FS/FS/part_pkg/global_Mixin.pm
index 2637729..2318c3e 100644
--- a/FS/FS/part_pkg/global_Mixin.pm
+++ b/FS/FS/part_pkg/global_Mixin.pm
@@ -40,6 +40,10 @@ tie my %a2billing_simultaccess, 'Tie::IxHash', (
'changing packages',
'type' => 'checkbox',
},
+ 'delay_cancel' => {
+ 'name' => 'Automatically suspend for one day before cancelling',
+ 'type' => 'checkbox',
+ },
# miscellany--maybe put this in a separate module?
@@ -109,6 +113,7 @@ tie my %a2billing_simultaccess, 'Tie::IxHash', (
unused_credit_cancel
unused_credit_suspend
unused_credit_change
+ delay_cancel
a2billing_tariff
a2billing_type
diff --git a/httemplate/view/cust_main/misc.html b/httemplate/view/cust_main/misc.html
index 15def32..fe0e329 100644
--- a/httemplate/view/cust_main/misc.html
+++ b/httemplate/view/cust_main/misc.html
@@ -7,7 +7,7 @@
<TR>
<TD ALIGN="right"><% mt('Status') |h %></TD>
- <TD BGCOLOR="#ffffff"><FONT COLOR="#<% $cust_main->statuscolor %>"><B><% $cust_main->status_label %></B></FONT></TD>
+ <TD BGCOLOR="#ffffff"><FONT COLOR="#<% $cust_main->statuscolor %>"><B><% $status_label %></B></FONT></TD>
</TR>
% my @part_tag = $cust_main->part_tag;
@@ -204,4 +204,9 @@ my $curuser = $FS::CurrentUser::CurrentUser;
my @agentnums = $curuser->agentnums;
+my $status_label = $cust_main->status_label;
+if ($cust_main->is_status_delay_cancel) {
+ $status_label .= ' (Cancelled)';
+}
+
</%init>