X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_pkg.pm;h=9352362457f911f07879dcab67521f8f977e9d1e;hb=a9bd30b5b5231db37360e285fbbfa237195cd064;hp=3e87aadf57d4849132bd33bb885ade761dbc1785;hpb=a179189cab28d3c1b7ae0101df5c1a95c4a72003;p=freeside.git diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index 3e87aadf5..935236245 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -1404,31 +1404,34 @@ sub suspend { } } - my @labels = (); - - foreach my $cust_svc ( - qsearch( 'cust_svc', { 'pkgnum' => $self->pkgnum } ) - ) { - my $part_svc = qsearchs( 'part_svc', { 'svcpart' => $cust_svc->svcpart } ); - - $part_svc->svcdb =~ /^([\w\-]+)$/ or do { - $dbh->rollback if $oldAutoCommit; - return "Illegal svcdb value in part_svc!"; - }; - my $svcdb = $1; - require "FS/$svcdb.pm"; - - my $svc = qsearchs( $svcdb, { 'svcnum' => $cust_svc->svcnum } ); - if ($svc) { - $error = $svc->suspend; - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return $error; - } - my( $label, $value ) = $cust_svc->label; - push @labels, "$label: $value"; + my @cust_svc = qsearch( 'cust_svc', { 'pkgnum' => $self->pkgnum } ) + + #attempt ordering ala cust_svc_suspend_cascade (without infinite-looping + # on the circular dep case) + # (this is too simple for multi-level deps, we need to use something + # to resolve the DAG properly when possible) + my %svcpart = (); + $svcpart{$_->svcpart} = 0 foreach @cust_svc; + foreach my $svcpart ( keys %svcpart ) { + foreach my $part_pkg_link ( + FS::part_svc_link->by_agentnum($self->cust_main->agentnum, + src_svcpart => $svcpart, + link_type => 'cust_svc_suspend_cascade' + ) + ) { + $svcpart{$part_svc_link->dst_svcpart} = max( + $svcpart{$part_svc_link->dst_svcpart}, + $svcpart{$part_svc_link->src_svcpart} + 1 + ); } } + @cust_svc = sort { $svcpart{ $a->svcpart } <=> $svcpart{ $b->svcpart } } + @cust_svc; + + my @labels = (); + foreach my $cust_svc ( @cust_svc ) { + $cust_svc->suspend( 'labels_arrayref' => \@labels ); + } # suspension fees: if there is a feepart, and it's not an unsuspend fee, # and this is not a suspend-before-cancel @@ -2039,14 +2042,15 @@ sub change { } if ( $keep_dates ) { - foreach my $date ( qw(setup bill last_bill susp adjourn cancel expire - resume start_date contract_end ) ) { + foreach my $date ( qw(setup bill last_bill) ) { $hash{$date} = $self->getfield($date); } } - # always keep this date, regardless of anything - # (the date of the package change is in a different field) - $hash{'order_date'} = $self->getfield('order_date'); + # always keep the following dates + foreach my $date (qw(order_date susp adjourn cancel expire resume + start_date contract_end)) { + $hash{$date} = $self->getfield($date); + } # allow $opt->{'locationnum'} = '' to specifically set it to null # (i.e. customer default location) @@ -2082,19 +2086,15 @@ sub change { # changed from this package. $cust_pkg = $opt->{'cust_pkg'}; - foreach ( qw( pkgnum pkgpart locationnum ) ) { - $cust_pkg->set("change_$_", $self->get($_)); + # follow all the above rules for date changes, etc. + foreach (keys %hash) { + $cust_pkg->set($_, $hash{$_}); } - $cust_pkg->set('change_date', $time); - $cust_pkg->set('start_date', ''); # it's starting now - # if we are crediting unused time, then create the new package as a new - # package, charge its setup fee, etc. (same as an immediate change) - if (! $unused_credit) { - foreach my $date ( qw(setup bill last_bill susp adjourn resume - contract_end ) ) { - $cust_pkg->set($date, $self->getfield($date)); - } + # except those that implement the future package change behavior + foreach (qw(change_to_pkgnum start_date expire)) { + $cust_pkg->set($_, ''); } + $error = $cust_pkg->replace; } else { @@ -3498,6 +3498,9 @@ 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. +Accepts option I which should be +the value of the config setting, to avoid looking it up again. + 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. @@ -3505,15 +3508,18 @@ really the whole point of the delay_cancel option. =cut sub is_status_delay_cancel { - my ($self) = @_; + my ($self,%opt) = @_; if ( $self->main_pkgnum and $self->pkglinknum ) { return $self->main_pkg->is_status_delay_cancel; } 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 $expdays = $opt{'part_pkg-delay_cancel-days'}; + unless ($expdays) { + my $conf = new FS::Conf; + $expdays = $conf->config('part_pkg-delay_cancel-days') || 1; + } my $expsecs = 60*60*24*$expdays; return 0 unless $self->expire < time + $expsecs; return 1;