X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_pkg.pm;h=c3d3cb98e5308f860b89f92015183e20a49c76b0;hb=e5fc4f01cca3de11b2f1114efb1ff3c4cf0acc47;hp=5bb07d4ff5e663e7c6fd6e02638a3fbf7786e252;hpb=46e04077cc22ff9d31e8e9896cbf97e31f1b0e7d;p=freeside.git diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index 5bb07d4ff..c3d3cb98e 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -125,6 +125,10 @@ Billing item definition (see L) Optional link to package location (see L) +=item order_date + +date package was ordered (also remains same on changes) + =item start_date date @@ -271,6 +275,8 @@ sub insert { } } + $self->order_date(time); + local $SIG{HUP} = 'IGNORE'; local $SIG{INT} = 'IGNORE'; local $SIG{QUIT} = 'IGNORE'; @@ -487,7 +493,10 @@ sub replace { #trigger export of new RADIUS Expiration attribute when cust_pkg.bill changes foreach my $old_svc_acct ( @svc_acct ) { my $new_svc_acct = new FS::svc_acct { $old_svc_acct->hash }; - my $s_error = $new_svc_acct->replace($old_svc_acct); + my $s_error = + $new_svc_acct->replace( $old_svc_acct, + 'depend_jobnum' => $options->{depend_jobnum}, + ); if ( $s_error ) { $dbh->rollback if $oldAutoCommit; return $s_error; @@ -595,6 +604,12 @@ Available options are: =item nobill - can be set true to skip billing if it might otherwise be done. +=item unused_credit - can be set to 1 to credit the remaining time, or 0 to +not credit it. This must be set (by change()) when changing the package +to a different pkgpart or location, and probably shouldn't be in any other +case. If it's not set, the 'unused_credit_cancel' part_pkg option will +be used. + =back If there is an error, returns the error, otherwise returns false. @@ -645,7 +660,6 @@ sub cancel { if $error; } - my $cancel_time = $options{'time'} || time; if ( $options{'reason'} ) { @@ -662,24 +676,7 @@ sub cancel { my %svc; if ( $date ) { - # copied from below - foreach my $cust_svc ( - #schwartz - map { $_->[0] } - sort { $a->[1] <=> $b->[1] } - map { [ $_, $_->svc_x->table_info->{'cancel_weight'} ]; } - qsearch( 'cust_svc', { 'pkgnum' => $self->pkgnum } ) - ) { - - my $error = $cust_svc->cancel( ('date' => $date) ); - - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "Error expiring cust_svc: $error"; - } - } - - } else { +# copied from below foreach my $cust_svc ( #schwartz map { $_->[0] } @@ -687,7 +684,21 @@ sub cancel { map { [ $_, $_->svc_x->table_info->{'cancel_weight'} ]; } qsearch( 'cust_svc', { 'pkgnum' => $self->pkgnum } ) ) { + my $error = $cust_svc->cancel( ('date' => $date) ); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Error expiring cust_svc: $error"; + } + } + } else { #!date + foreach my $cust_svc ( + #schwartz + map { $_->[0] } + sort { $a->[1] <=> $b->[1] } + map { [ $_, $_->svc_x->table_info->{'cancel_weight'} ]; } + qsearch( 'cust_svc', { 'pkgnum' => $self->pkgnum } ) + ) { my $error = $cust_svc->cancel; if ( $error ) { @@ -695,10 +706,28 @@ sub cancel { return "Error cancelling cust_svc: $error"; } } + } #if $date - # Add a credit for remaining service - my $remaining_value = $self->calc_remain(time=>$cancel_time); - if ( $remaining_value > 0 && !$options{'no_credit'} ) { + # Add a credit for remaining service + my $last_bill = $self->getfield('last_bill') || 0; + my $next_bill = $self->getfield('bill') || 0; + my $do_credit; + if ( exists($options{'unused_credit'}) ) { + $do_credit = $options{'unused_credit'}; + } + else { + $do_credit = $self->part_pkg->option('unused_credit_cancel', 1); + } + if ( $do_credit + and $last_bill > 0 # the package has been billed + and $next_bill > 0 # the package has a next bill date + and $next_bill >= $cancel_time # which is in the future + ) { + my $remaining_value = $self->calc_remain('time' => $cancel_time); + if ( $remaining_value > 0 ) { + # && !$options{'no_credit'} ) { + # Undocumented, unused option. + # part_pkg configuration should decide this anyway. my $error = $self->cust_main->credit( $remaining_value, 'Credit for unused time on '. $self->part_pkg->pkg, @@ -709,8 +738,8 @@ sub cancel { return "Error crediting customer \$$remaining_value for unused time on". $self->part_pkg->pkg. ": $error"; } - } - } + } #if $remaining_value + } #if $do_credit my %hash = $self->hash; $date ? ($hash{'expire'} = $date) : ($hash{'cancel'} = $cancel_time); @@ -1221,12 +1250,23 @@ sub change { $opt->{'locationnum'} = $opt->{'cust_location'}->locationnum; } + my $unused_credit = 0; if ( $opt->{'keep_dates'} ) { foreach my $date ( qw(setup bill last_bill susp adjourn cancel expire start_date contract_end ) ) { $hash{$date} = $self->getfield($date); } } + # Special case. If the pkgpart is changing, and the customer is + # going to be credited for remaining time, don't keep setup, bill, + # or last_bill dates, and DO pass the flag to cancel() to credit + # the customer. + if ( $opt->{'pkgpart'} + and $opt->{'pkgpart'} != $self->pkgpart + and $self->part_pkg->option('unused_credit_change', 1) ) { + $unused_credit = 1; + $hash{$_} = '' foreach qw(setup bill last_bill); + } # Create the new package. my $cust_pkg = new FS::cust_pkg { @@ -1285,8 +1325,9 @@ sub change { } } - #Good to go, cancel old package. - $error = $self->cancel( quiet=>1 ); + #Good to go, cancel old package. Notify 'cancel' of whether to credit + #remaining time. + $error = $self->cancel( quiet=>1, unused_credit => $unused_credit ); if ($error) { $dbh->rollback if $oldAutoCommit; return $error; @@ -2468,7 +2509,6 @@ sub insert_discount { 'discountnum' => $self->discountnum, 'months_used' => 0, 'end_date' => '', #XXX - 'otaker' => $self->otaker, #for the create a new discount case '_type' => $self->discountnum__type, 'amount' => $self->discountnum_amount, @@ -3364,6 +3404,10 @@ sub _upgrade_data { # class method 'UPDATE cust_pkg SET bill = bill + (365*24*60*60) WHERE bill < last_bill AND bill > 1259654400 AND bill < 1262332800 AND (SELECT plan FROM part_pkg WHERE part_pkg.pkgpart = cust_pkg.pkgpart) = \'prorate\'', + # RT6628, add order_date to cust_pkg + 'update cust_pkg set order_date = (select history_date from h_cust_pkg + where h_cust_pkg.pkgnum = cust_pkg.pkgnum and + history_action = \'insert\') where order_date is null', ); foreach my $sql (@statements) { my $sth = dbh->prepare($sql);