X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_pkg.pm;h=69f7bc0a83ee306d24520fef8c89225a5d4aafdd;hb=598f5364ffaab833463442f910fc9c533975e317;hp=944be53d5d7915acf576971b56c7832cd481a5d9;hpb=fed764feca62cb39d0e33099229c40bbfed102fd;p=freeside.git diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index 944be53d5..69f7bc0a8 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -673,8 +673,9 @@ sub check { || $self->ut_numbern('resume') || $self->ut_numbern('expire') || $self->ut_numbern('dundate') - || $self->ut_enum('no_auto', [ '', 'Y' ]) - || $self->ut_enum('waive_setup', [ '', 'Y' ]) + || $self->ut_flag('no_auto', [ '', 'Y' ]) + || $self->ut_flag('waive_setup', [ '', 'Y' ]) + || $self->ut_flag('separate_bill') || $self->ut_textn('agent_pkgid') || $self->ut_enum('recur_show_zero', [ '', 'Y', 'N', ]) || $self->ut_enum('setup_show_zero', [ '', 'Y', 'N', ]) @@ -836,6 +837,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 @@ -906,6 +921,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; } @@ -929,7 +949,11 @@ sub cancel { } foreach my $supp_pkg ( $self->supplemental_pkgs ) { - $error = $supp_pkg->cancel(%options, 'from_main' => 1); + if ($delay_cancel) { + $error = $supp_pkg->suspend(%options, 'from_main' => 1, 'reason' => undef); + } else { + $error = $supp_pkg->cancel(%options, 'from_main' => 1); + } if ( $error ) { $dbh->rollback if $oldAutoCommit; return "canceling supplemental pkg#".$supp_pkg->pkgnum.": $error"; @@ -1050,7 +1074,8 @@ sub uncancel { setup susp adjourn resume expire start_date contract_end dundate change_date change_pkgpart change_locationnum - manual_flag no_auto quantity agent_pkgid recur_show_zero setup_show_zero + manual_flag no_auto separate_bill quantity agent_pkgid + recur_show_zero setup_show_zero ), }; @@ -1674,15 +1699,20 @@ sub unsuspend { and ! $self->option('no_suspend_bill',1) ) or $hash{'order_date'} == $hash{'susp'} - or $self->part_pkg->option('unused_credit_suspend') - or ( defined($reason) and $reason->unused_credit ) ) { $adjust_bill = 0; } - # then add the length of time suspended to the bill date if ( $adjust_bill ) { - $hash{'bill'} = ( $hash{'bill'} || $hash{'setup'} ) + $inactive + if ( $self->part_pkg->option('unused_credit_suspend') + or ( $reason and $reason->unused_credit ) ) { + # then the customer was credited for the unused time before suspending, + # so their next bill should be immediate. + $hash{'bill'} = time; + } else { + # add the length of time suspended to the bill date + $hash{'bill'} = ( $hash{'bill'} || $hash{'setup'} ) + $inactive; + } } $hash{'susp'} = ''; @@ -2398,6 +2428,7 @@ and, I: - start_date: the date when it will be billed - amount: the setup fee to be charged - quantity: the multiplier for the setup fee +- separate_bill: whether to put the charge on a separate invoice If you pass 'adjust_commission' => 1, and the classnum changes, and there are commission credits linked to this charge, they will be recalculated. @@ -2453,7 +2484,8 @@ sub modify_charge { } if ( !$self->get('setup') ) { - # not yet billed, so allow amount, setup_cost, quantity and start_date + # not yet billed, so allow amount, setup_cost, quantity, start_date, + # and separate_bill if ( exists($opt{'amount'}) and $part_pkg->option('setup_fee') != $opt{'amount'} @@ -2483,6 +2515,12 @@ sub modify_charge { $self->set('start_date', $opt{'start_date'}); } + if ( exists($opt{'separate_bill'}) + and $opt{'separate_bill'} ne $self->separate_bill ) { + + $self->set('separate_bill', $opt{'separate_bill'}); + } + } # else simply ignore them; the UI shouldn't allow editing the fields @@ -3352,6 +3390,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