diff options
| author | mark <mark> | 2012-01-28 23:20:33 +0000 |
|---|---|---|
| committer | mark <mark> | 2012-01-28 23:20:33 +0000 |
| commit | 396e18e8b0b43fd6b7bf4c2f1e0465d16371441f (patch) | |
| tree | f506bb3f7fa2e8246f1e5bdbe020916a85f5c23f /FS | |
| parent | f22d7f0c3b27d10450961090f755be8b2b22eb22 (diff) | |
future package unsuspend date, #14144
Diffstat (limited to 'FS')
| -rw-r--r-- | FS/FS/Cron/bill.pm | 3 | ||||
| -rw-r--r-- | FS/FS/Schema.pm | 1 | ||||
| -rw-r--r-- | FS/FS/cust_main/Billing.pm | 31 | ||||
| -rw-r--r-- | FS/FS/cust_pkg.pm | 70 |
4 files changed, 93 insertions, 12 deletions
diff --git a/FS/FS/Cron/bill.pm b/FS/FS/Cron/bill.pm index 1569ef6a2..cb617a05e 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>) @@ -202,6 +202,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 be46f24e3..7975a302a 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 850ffaa3a..4c77721db 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 ) { @@ -184,7 +192,7 @@ sub cancel_expired_pkgs { push @errors, 'pkgnum '.$cust_pkg->pkgnum.": $error" if $error; } - scalar(@errors) ? join(' / ', @errors) : ''; + join(' / ', @errors); } @@ -226,7 +234,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); } @@ -2158,6 +2184,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 349f20e1e..88ce3a0e1 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') ) { @@ -940,9 +944,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 @@ -978,16 +994,16 @@ sub suspend { return ""; # no error # complain on adjourn? } + 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; return "Package $pkgnum expires before it would be suspended."; } - my $suspend_time = $options{'time'} || time; - if ( $options{'reason'} ) { $error = $self->insert_reason( 'reason' => $options{'reason'}, 'action' => $date ? 'adjourn' : 'suspend', @@ -1006,6 +1022,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 ) { @@ -1083,6 +1105,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 @@ -1117,15 +1144,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 } ) ) { @@ -1166,7 +1216,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 ) { @@ -1224,6 +1275,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 ) { @@ -1335,7 +1387,7 @@ sub change { my $unused_credit = 0; if ( $opt->{'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); } } |
