summaryrefslogtreecommitdiff
path: root/FS
diff options
context:
space:
mode:
authormark <mark>2012-01-28 23:20:11 +0000
committermark <mark>2012-01-28 23:20:11 +0000
commit781f0ffcf560d3df0aec7ae349b57463d1c2518a (patch)
tree1c1c872d11d69b54370325786b2b2e72e2f009d8 /FS
parent45ecb21934e80c6f1dcc6e26284398995a04a8e6 (diff)
future package unsuspend date, #14144
Diffstat (limited to 'FS')
-rw-r--r--FS/FS/Cron/bill.pm3
-rw-r--r--FS/FS/Schema.pm1
-rw-r--r--FS/FS/cust_main/Billing.pm31
-rw-r--r--FS/FS/cust_pkg.pm68
4 files changed, 92 insertions, 11 deletions
diff --git a/FS/FS/Cron/bill.pm b/FS/FS/Cron/bill.pm
index 64979baec..8d1223b80 100644
--- a/FS/FS/Cron/bill.pm
+++ b/FS/FS/Cron/bill.pm
@@ -146,7 +146,7 @@ sub bill {
# (or now, if no -d switch was given).
#
# -n: When used with "-d" and/or "-y", specifies that invoices should be dated
-# with today's date, irregardless of the pretend date used to pre-generate
+# with today's date, regardless of the pretend date used to pre-generate
# the invoices.
#
# -p: Only process customers with the specified payby (I<CARD>, I<DCRD>, I<CHEK>, I<DCHK>, I<BILL>, I<COMP>, I<LECB>)
@@ -211,6 +211,7 @@ sub bill_where {
OR bill IS NULL OR bill <= $billtime
OR ( expire IS NOT NULL AND expire <= $^T )
OR ( adjourn IS NOT NULL AND adjourn <= $^T )
+ OR ( resume IS NOT NULL AND resume <= $^T )
)
)
END
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index 6727420ca..9de1b7f3f 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -1481,6 +1481,7 @@ sub tables_hashref {
'last_bill', @date_type, '', '',
'susp', @date_type, '', '',
'adjourn', @date_type, '', '',
+ 'resume', @date_type, '', '',
'cancel', @date_type, '', '',
'expire', @date_type, '', '',
'contract_end', @date_type, '', '',
diff --git a/FS/FS/cust_main/Billing.pm b/FS/FS/cust_main/Billing.pm
index 23d3b4933..ed7b0fa77 100644
--- a/FS/FS/cust_main/Billing.pm
+++ b/FS/FS/cust_main/Billing.pm
@@ -129,6 +129,14 @@ sub bill_and_collect {
else { warn $error; }
}
+ $error = $self->unsuspend_resumed_pkgs( day_end( $options{actual_time} ) );
+ if ( $error ) {
+ $error = "Error resuming custnum ".$self->custnum. ": $error";
+ if ( $options{fatal} && $options{fatal} eq 'return' ) { return $error; }
+ elsif ( $options{fatal} ) { die $error; }
+ else { warn $error; }
+ }
+
$job->update_statustext('20,billing packages') if $job;
$error = $self->bill( %options );
if ( $error ) {
@@ -185,7 +193,7 @@ sub cancel_expired_pkgs {
push @errors, 'pkgnum '.$cust_pkg->pkgnum.": $error" if $error;
}
- scalar(@errors) ? join(' / ', @errors) : '';
+ join(' / ', @errors);
}
@@ -227,7 +235,25 @@ sub suspend_adjourned_pkgs {
push @errors, 'pkgnum '.$cust_pkg->pkgnum.": $error" if $error;
}
- scalar(@errors) ? join(' / ', @errors) : '';
+ join(' / ', @errors);
+
+}
+
+sub unsuspend_resumed_pkgs {
+ my ( $self, $time, %options ) = @_;
+
+ my @unsusp_pkgs = $self->ncancelled_pkgs( {
+ 'extra_sql' => " AND resume IS NOT NULL AND resume > 0 AND resume <= $time "
+ } );
+
+ my @errors = ();
+
+ foreach my $cust_pkg ( @unsusp_pkgs ) {
+ my $error = $cust_pkg->unsuspend( 'time' => $time );
+ push @errors, 'pkgnum '.$cust_pkg->pkgnum.": $error" if $error;
+ }
+
+ join(' / ', @errors);
}
@@ -2168,6 +2194,7 @@ sub apply_payments {
cancel_expired_pkgs
suspend_adjourned_pkgs
+ unsuspend_resumed_pkgs
bill
(do_cust_event pre-bill)
diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm
index 469bd94ab..855accc0c 100644
--- a/FS/FS/cust_pkg.pm
+++ b/FS/FS/cust_pkg.pm
@@ -605,6 +605,7 @@ sub check {
|| $self->ut_numbern('susp')
|| $self->ut_numbern('cancel')
|| $self->ut_numbern('adjourn')
+ || $self->ut_numbern('resume')
|| $self->ut_numbern('expire')
|| $self->ut_numbern('dundate')
|| $self->ut_enum('no_auto', [ '', 'Y' ])
@@ -618,6 +619,9 @@ sub check {
return "A package with both start date (future start) and setup date (already started) will never bill"
if $self->start_date && $self->setup;
+ return "A future unsuspend date can only be set for a package with a suspend date"
+ if $self->resume and !$self->susp and !$self->adjourn;
+
$self->usernum($FS::CurrentUser::CurrentUser->usernum) unless $self->usernum;
if ( $self->dbdef_table->column('manual_flag') ) {
@@ -936,9 +940,21 @@ Available options are:
=over 4
-=item reason - can be set to a cancellation reason (see L<FS:reason>), either a reasonnum of an existing reason, or passing a hashref will create a new reason. The hashref should have the following keys: typenum - Reason type (see L<FS::reason_type>, reason - Text of the new reason.
+=item reason - can be set to a cancellation reason (see L<FS:reason>),
+either a reasonnum of an existing reason, or passing a hashref will create
+a new reason. The hashref should have the following keys:
+- typenum - Reason type (see L<FS::reason_type>
+- reason - Text of the new reason.
+
+=item date - can be set to a unix style timestamp to specify when to
+suspend (adjourn)
+
+=item time - can be set to override the current time, for calculation
+of final invoices or unused-time credits
-=item date - can be set to a unix style timestamp to specify when to suspend (adjourn)
+=item resume_date - can be set to a time when the package should be
+unsuspended. This may be more convenient than calling C<unsuspend()>
+separately.
=back
@@ -976,7 +992,7 @@ sub suspend {
my $suspend_time = $options{'time'} || time;
my $date = $options{date} if $options{date}; # adjourn/suspend later
- $date = '' if ($date && $date <= time); # complain instead?
+ $date = '' if ($date && $date <= $suspend_time); # complain instead?
if ( $date && $old->get('expire') && $old->get('expire') < $date ) {
dbh->rollback if $oldAutoCommit;
@@ -1019,6 +1035,12 @@ sub suspend {
} else {
$hash{'susp'} = $suspend_time;
}
+
+ my $resume_date = $options{'resume_date'} || 0;
+ if ( $resume_date > ($date || $suspend_time) ) {
+ $hash{'resume'} = $resume_date;
+ }
+
my $new = new FS::cust_pkg ( \%hash );
$error = $new->replace( $self, options => { $self->options } );
if ( $error ) {
@@ -1098,7 +1120,7 @@ sub suspend {
Generate a credit for this package for the time remaining in the current
billing period. MODE is either "suspend" or "cancel" (determines the
-credit type). TIME is the time of suspension/cancellation. Both options
+credit type). TIME is the time of suspension/cancellation. Both arguments
are mandatory.
=cut
@@ -1146,6 +1168,11 @@ Available options are:
=over 4
+=item date
+
+Can be set to a date to unsuspend the package in the future (the 'resume'
+field).
+
=item adjust_next_bill
Can be set true to adjust the next bill date forward by
@@ -1180,15 +1207,38 @@ sub unsuspend {
my $pkgnum = $old->pkgnum;
if ( $old->get('cancel') || $self->get('cancel') ) {
- dbh->rollback if $oldAutoCommit;
+ $dbh->rollback if $oldAutoCommit;
return "Can't unsuspend cancelled package $pkgnum";
}
unless ( $old->get('susp') && $self->get('susp') ) {
- dbh->rollback if $oldAutoCommit;
+ $dbh->rollback if $oldAutoCommit;
return ""; # no error # complain instead?
}
+ my $date = $opt{'date'};
+ if ( $date and $date > time ) { # return an error if $date <= time?
+
+ if ( $old->get('expire') && $old->get('expire') < $date ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "Package $pkgnum expires before it would be unsuspended.";
+ }
+
+ my $new = new FS::cust_pkg { $self->hash };
+ $new->set('resume', $date);
+ $error = $new->replace($self, options => $self->options);
+
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ else {
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+ return '';
+ }
+
+ } #if $date
+
foreach my $cust_svc (
qsearch('cust_svc',{'pkgnum'=> $self->pkgnum } )
) {
@@ -1229,7 +1279,8 @@ sub unsuspend {
}
$hash{'susp'} = '';
- $hash{'adjourn'} = '' if $hash{'adjourn'} < time;
+ $hash{'adjourn'} = '' if $hash{'adjourn'} and $hash{'adjourn'} < time;
+ $hash{'resume'} = '' if !$hash{'adjourn'};
my $new = new FS::cust_pkg ( \%hash );
$error = $new->replace( $self, options => { $self->options } );
if ( $error ) {
@@ -1287,6 +1338,7 @@ sub unadjourn {
my %hash = $self->hash;
$hash{'adjourn'} = '';
+ $hash{'resume'} = '';
my $new = new FS::cust_pkg ( \%hash );
$error = $new->replace( $self, options => { $self->options } );
if ( $error ) {
@@ -1409,7 +1461,7 @@ sub change {
if ( $keep_dates ) {
foreach my $date ( qw(setup bill last_bill susp adjourn cancel expire
- start_date contract_end ) ) {
+ resume start_date contract_end ) ) {
$hash{$date} = $self->getfield($date);
}
}