diff options
-rw-r--r-- | FS/FS/Cron/bill.pm | 15 | ||||
-rw-r--r-- | FS/FS/Schema.pm | 1 | ||||
-rw-r--r-- | FS/FS/cust_pkg.pm | 366 | ||||
-rw-r--r-- | FS/FS/cust_pkg_reason.pm | 1 | ||||
-rw-r--r-- | FS/FS/part_export/shellcommands.pm | 4 | ||||
-rw-r--r-- | FS/FS/part_export/sqlradius.pm | 2 | ||||
-rwxr-xr-x | httemplate/edit/REAL_cust_pkg.cgi | 11 | ||||
-rwxr-xr-x | httemplate/misc/process/cancel_pkg.html | 11 | ||||
-rwxr-xr-x | httemplate/misc/unadjourn_pkg.cgi | 17 | ||||
-rwxr-xr-x | httemplate/misc/unexpire_pkg.cgi | 17 | ||||
-rwxr-xr-x | httemplate/search/cust_pkg.cgi | 9 | ||||
-rwxr-xr-x | httemplate/view/cust_main/packages.html | 29 |
12 files changed, 356 insertions, 127 deletions
diff --git a/FS/FS/Cron/bill.pm b/FS/FS/Cron/bill.pm index 23fa064c6..df446d882 100644 --- a/FS/FS/Cron/bill.pm +++ b/FS/FS/Cron/bill.pm @@ -87,7 +87,12 @@ END foreach my $cust_pkg ( grep { $_->expire && $_->expire <= $^T } $cust_main->ncancelled_pkgs ) { - my $error = $cust_pkg->cancel; + my $cpr = $cust_pkg->last_cust_pkg_reason('expire'); + my $error = $cust_pkg->cancel($cpr ? ( 'reason' => $cpr->reasonnum, + 'reason_otaker' => $cpr->otaker + ) + : () + ); warn "Error cancelling expired pkg ". $cust_pkg->pkgnum. " for custnum $custnum: $error" if $error; @@ -101,7 +106,13 @@ END } $cust_main->ncancelled_pkgs ) { - my $error = $cust_pkg->suspend; + my $cpr = $cust_pkg->last_cust_pkg_reason('adjourn') + if ($cust_pkg->adjourn && $cust_pkg->adjourn < $^T); + my $error = $cust_pkg->suspend($cpr ? ( 'reason' => $cpr->reasonnum, + 'reason_otaker' => $cpr->otaker + ) + : () + ); warn "Error suspending package ". $cust_pkg->pkgnum. " for custnum $custnum: $error" if $error; diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 242bc0260..956aedd92 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -795,6 +795,7 @@ sub tables_hashref { 'num', 'serial', '', '', '', '', 'pkgnum', 'int', '', '', '', '', 'reasonnum','int', '', '', '', '', + 'action', 'char', 'NULL', 1, '', '', #should not be nullable 'otaker', 'varchar', '', 32, '', '', 'date', @date_type, '', '', ], diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index 91a9b8114..42c3aca8c 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -320,7 +320,9 @@ sub replace { foreach my $method ( qw(adjourn expire) ) { # How many reasons? if ($options{'reason'} && $new->$method && $old->$method ne $new->$method) { my $error = $new->insert_reason( 'reason' => $options{'reason'}, - 'date' => $new->$method, + 'date' => $new->$method, + 'action' => $method, + 'reason_otaker' => $options{'reason_otaker'}, ); if ( $error ) { dbh->rollback if $oldAutoCommit; @@ -446,9 +448,11 @@ Cancels and removes all services (see L<FS::cust_svc> and L<FS::part_svc>) in this package, then cancels the package itself (sets the cancel field to now). -Available options are: I<quiet> +Available options are: I<quiet> I<reason> I<date> I<quiet> can be set true to supress email cancellation notices. +I<reason> can be set to a reasonnum (see L<FS::reason>) explaining the action +I<date> can be set to a unix style timestamp to specify when to cancel (expire) If there is an error, returns the error, otherwise returns false. @@ -469,8 +473,21 @@ sub cancel { local $FS::UID::AutoCommit = 0; my $dbh = dbh; + my $old = $self->select_for_update; + + if ( $old->get('cancel') || $self->get('cancel') ) { + dbh->rollback if $oldAutoCommit; + return ""; # no error + } + + my $date = $options{date} if $options{date}; # expire/cancel later + $date = '' if ($date && $date <= time); # complain instead? + if ($options{'reason'}) { - $error = $self->insert_reason( 'reason' => $options{'reason'} ); + $error = $self->insert_reason( 'reason' => $options{'reason'}, + 'action' => $date ? 'expire' : 'cancel', + 'reason_otaker' => $options{'reason_otaker'}, + ); if ( $error ) { dbh->rollback if $oldAutoCommit; return "Error inserting cust_pkg_reason: $error"; @@ -478,50 +495,51 @@ sub cancel { } my %svc; - 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 } ) - ) { + unless ( $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; + my $error = $cust_svc->cancel; - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "Error cancelling cust_svc: $error"; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Error cancelling cust_svc: $error"; + } } - } - # Add a credit for remaining service - my $remaining_value = $self->calc_remain(); - if ( $remaining_value > 0 ) { - my $conf = new FS::Conf; - my $error = $self->cust_main->credit( - $remaining_value, - 'Credit for unused time on '. $self->part_pkg->pkg, - 'reason_type' => $conf->config('cancel_credit_type'), - ); - if ($error) { - $dbh->rollback if $oldAutoCommit; - return "Error crediting customer \$$remaining_value for unused time on". - $self->part_pkg->pkg. ": $error"; - } - } - - unless ( $self->getfield('cancel') ) { - my %hash = $self->hash; - $hash{'cancel'} = time; - my $new = new FS::cust_pkg ( \%hash ); - $error = $new->replace( $self, options => { $self->options } ); - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return $error; + # Add a credit for remaining service + my $remaining_value = $self->calc_remain(); + if ( $remaining_value > 0 ) { + my $conf = new FS::Conf; + my $error = $self->cust_main->credit( + $remaining_value, + 'Credit for unused time on '. $self->part_pkg->pkg, + 'reason_type' => $conf->config('cancel_credit_type'), + ); + if ($error) { + $dbh->rollback if $oldAutoCommit; + return "Error crediting customer \$$remaining_value for unused time on". + $self->part_pkg->pkg. ": $error"; + } } } + my %hash = $self->hash; + $date ? ($hash{'expire'} = $date) : ($hash{'cancel'} = time); + my $new = new FS::cust_pkg ( \%hash ); + $error = $new->replace( $self, options => { $self->options } ); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + return '' if $date; #no errors my $conf = new FS::Conf; my @invoicing_list = grep { $_ !~ /^(POST|FAX)$/ } $self->cust_main->invoicing_list; @@ -540,11 +558,68 @@ sub cancel { } -=item suspend +=item unexpire + +Cancels any pending expiration (sets the expire field to null). + +If there is an error, returns the error, otherwise returns false. + +=cut + +sub unexpire { + my( $self, %options ) = @_; + my $error; + + local $SIG{HUP} = 'IGNORE'; + local $SIG{INT} = 'IGNORE'; + local $SIG{QUIT} = 'IGNORE'; + local $SIG{TERM} = 'IGNORE'; + local $SIG{TSTP} = 'IGNORE'; + local $SIG{PIPE} = 'IGNORE'; + + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + my $old = $self->select_for_update; + + my $pkgnum = $old->pkgnum; + if ( $old->get('cancel') || $self->get('cancel') ) { + dbh->rollback if $oldAutoCommit; + return "Can't unexpire cancelled package $pkgnum"; + # or at least it's pointless + } + + unless ( $old->get('expire') && $self->get('expire') ) { + dbh->rollback if $oldAutoCommit; + return ""; # no error + } + + my %hash = $self->hash; + $hash{'expire'} = ''; + my $new = new FS::cust_pkg ( \%hash ); + $error = $new->replace( $self, options => { $self->options } ); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + + ''; #no errors + +} + +=item suspend [ OPTION => VALUE ... ] Suspends all services (see L<FS::cust_svc> and L<FS::part_svc>) in this package, then suspends the package itself (sets the susp field to now). +Available options are: I<reason> I<date> + +I<date> can be set to a unix style timestamp to specify when to suspend (adjourn) +I<reason> can be set to a reasonnum (see L<FS::reason>) explaining the action + If there is an error, returns the error, otherwise returns false. =cut @@ -564,46 +639,69 @@ sub suspend { local $FS::UID::AutoCommit = 0; my $dbh = dbh; + my $old = $self->select_for_update; + + my $pkgnum = $old->pkgnum; + if ( $old->get('cancel') || $self->get('cancel') ) { + dbh->rollback if $oldAutoCommit; + return "Can't suspend cancelled package $pkgnum"; + } + + if ( $old->get('susp') || $self->get('susp') ) { + dbh->rollback if $oldAutoCommit; + return ""; # no error # complain on adjourn? + } + + my $date = $options{date} if $options{date}; # adjourn/suspend later + $date = '' if ($date && $date <= 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."; + } + if ($options{'reason'}) { - $error = $self->insert_reason( 'reason' => $options{'reason'} ); + $error = $self->insert_reason( 'reason' => $options{'reason'}, + 'action' => $date ? 'adjourn' : 'suspend', + 'reason_otaker' => $options{'reason_otaker'}, + ); if ( $error ) { dbh->rollback if $oldAutoCommit; return "Error inserting cust_pkg_reason: $error"; } } - 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"; + unless ( $date ) { + foreach my $cust_svc ( + qsearch( 'cust_svc', { 'pkgnum' => $self->pkgnum } ) + ) { + my $part_svc = qsearchs( 'part_svc', { 'svcpart' => $cust_svc->svcpart } ); - my $svc = qsearchs( $svcdb, { 'svcnum' => $cust_svc->svcnum } ); - if ($svc) { - $error = $svc->suspend; - if ( $error ) { + $part_svc->svcdb =~ /^([\w\-]+)$/ or do { $dbh->rollback if $oldAutoCommit; - return $error; + 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; + } } } - } - unless ( $self->getfield('susp') ) { - my %hash = $self->hash; - $hash{'susp'} = time; - my $new = new FS::cust_pkg ( \%hash ); - $error = $new->replace( $self, options => { $self->options } ); - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return $error; - } + my %hash = $self->hash; + $date ? ($hash{'adjourn'} = $date) : ($hash{'susp'} = time); + my $new = new FS::cust_pkg ( \%hash ); + $error = $new->replace( $self, options => { $self->options } ); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; } $dbh->commit or die $dbh->errstr if $oldAutoCommit; @@ -645,6 +743,19 @@ sub unsuspend { local $FS::UID::AutoCommit = 0; my $dbh = dbh; + my $old = $self->select_for_update; + + my $pkgnum = $old->pkgnum; + if ( $old->get('cancel') || $self->get('cancel') ) { + dbh->rollback if $oldAutoCommit; + return "Can't unsuspend cancelled package $pkgnum"; + } + + unless ( $old->get('susp') && $self->get('susp') ) { + dbh->rollback if $oldAutoCommit; + return ""; # no error # complain instead? + } + foreach my $cust_svc ( qsearch('cust_svc',{'pkgnum'=> $self->pkgnum } ) ) { @@ -668,25 +779,23 @@ sub unsuspend { } - unless ( ! $self->getfield('susp') ) { - my %hash = $self->hash; - my $inactive = time - $hash{'susp'}; + my %hash = $self->hash; + my $inactive = time - $hash{'susp'}; - my $conf = new FS::Conf; + my $conf = new FS::Conf; - $hash{'bill'} = ( $hash{'bill'} || $hash{'setup'} ) + $inactive - if ( $opt{'adjust_next_bill'} - || $conf->config('unsuspend-always_adjust_next_bill_date') ) - && $inactive > 0 && ( $hash{'bill'} || $hash{'setup'} ); + $hash{'bill'} = ( $hash{'bill'} || $hash{'setup'} ) + $inactive + if ( $opt{'adjust_next_bill'} + || $conf->config('unsuspend-always_adjust_next_bill_date') ) + && $inactive > 0 && ( $hash{'bill'} || $hash{'setup'} ); - $hash{'susp'} = ''; - $hash{'adjourn'} = '' if $hash{'adjourn'} < time; - my $new = new FS::cust_pkg ( \%hash ); - $error = $new->replace( $self, options => { $self->options } ); - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return $error; - } + $hash{'susp'} = ''; + $hash{'adjourn'} = '' if $hash{'adjourn'} < time; + my $new = new FS::cust_pkg ( \%hash ); + $error = $new->replace( $self, options => { $self->options } ); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; } $dbh->commit or die $dbh->errstr if $oldAutoCommit; @@ -694,6 +803,64 @@ sub unsuspend { ''; #no errors } +=item unadjourn + +Cancels any pending suspension (sets the adjourn field to null). + +If there is an error, returns the error, otherwise returns false. + +=cut + +sub unadjourn { + my( $self, %options ) = @_; + my $error; + + local $SIG{HUP} = 'IGNORE'; + local $SIG{INT} = 'IGNORE'; + local $SIG{QUIT} = 'IGNORE'; + local $SIG{TERM} = 'IGNORE'; + local $SIG{TSTP} = 'IGNORE'; + local $SIG{PIPE} = 'IGNORE'; + + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + my $old = $self->select_for_update; + + my $pkgnum = $old->pkgnum; + if ( $old->get('cancel') || $self->get('cancel') ) { + dbh->rollback if $oldAutoCommit; + return "Can't unadjourn cancelled package $pkgnum"; + # or at least it's pointless + } + + if ( $old->get('susp') || $self->get('susp') ) { + dbh->rollback if $oldAutoCommit; + return "Can't unadjourn suspended package $pkgnum"; + # perhaps this is arbitrary + } + + unless ( $old->get('adjourn') && $self->get('adjourn') ) { + dbh->rollback if $oldAutoCommit; + return ""; # no error + } + + my %hash = $self->hash; + $hash{'adjourn'} = ''; + my $new = new FS::cust_pkg ( \%hash ); + $error = $new->replace( $self, options => { $self->options } ); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + + ''; #no errors + +} + =item last_bill Returns the last bill date, or if there is no last bill date, the setup date. @@ -712,30 +879,37 @@ sub last_bill { $cust_bill_pkg ? $cust_bill_pkg->sdate : $self->setup || 0; } -=item last_cust_pkg_reason +=item last_cust_pkg_reason ACTION -Returns the most recent FS::reason associated with the package. +Returns the most recent ACTION FS::cust_pkg_reason associated with the package. +Returns false if there is no reason or the package is not currenly ACTION'd +ACTION is one of adjourn, susp, cancel, or expire. =cut sub last_cust_pkg_reason { - my $self = shift; + my ( $self, $action ) = ( shift, shift ); + my $date = $self->get($action); qsearchs( { 'table' => 'cust_pkg_reason', - 'hashref' => { 'pkgnum' => $self->pkgnum, }, - 'extra_sql'=> "AND date <= ". time, - 'order_by' => 'ORDER BY date DESC LIMIT 1', + 'hashref' => { 'pkgnum' => $self->pkgnum, + 'action' => substr(uc($action), 0, 1), + 'date' => $date, + }, + 'order_by' => 'ORDER BY num DESC LIMIT 1', } ); } -=item last_reason +=item last_reason ACTION -Returns the most recent FS::reason associated with the package. +Returns the most recent ACTION FS::reason associated with the package. +Returns false if there is no reason or the package is not currenly ACTION'd +ACTION is one of adjourn, susp, cancel, or expire. =cut sub last_reason { - my $cust_pkg_reason = shift->last_cust_pkg_reason; + my $cust_pkg_reason = shift->last_cust_pkg_reason(@_); $cust_pkg_reason->reason if $cust_pkg_reason; } @@ -1718,12 +1892,12 @@ sub search_sql { qsearchs('access_user', { username => $params->{CurrentUser} }); if ($access_user) { - push @where, $access_user->agentnums_sql; + push @where, $access_user->agentnums_sql('table' => 'cust_main'); }else{ push @where, "1=0"; } }else{ - push @where, $FS::CurrentUser::CurrentUser->agentnums_sql; + push @where, $FS::CurrentUser::CurrentUser->agentnums_sql('table' => 'cust_main'); } my $extra_sql = scalar(@where) ? ' WHERE '. join(' AND ', @where) : ''; @@ -1954,7 +2128,8 @@ sub bulk_change { sub insert_reason { my ($self, %options) = @_; - my $otaker = $FS::CurrentUser::CurrentUser->username; + my $otaker = $options{reason_otaker} || + $FS::CurrentUser::CurrentUser->username; my $reasonnum; if ( $options{'reason'} =~ /^(\d+)$/ ) { @@ -1983,6 +2158,7 @@ sub insert_reason { new FS::cust_pkg_reason({ 'pkgnum' => $self->pkgnum, 'reasonnum' => $reasonnum, 'otaker' => $otaker, + 'action' => substr(uc($options{'action'}),0,1), 'date' => $options{'date'} ? $options{'date'} : time, diff --git a/FS/FS/cust_pkg_reason.pm b/FS/FS/cust_pkg_reason.pm index 24808f944..92cd4a1f9 100644 --- a/FS/FS/cust_pkg_reason.pm +++ b/FS/FS/cust_pkg_reason.pm @@ -98,6 +98,7 @@ sub check { $self->ut_numbern('num') || $self->ut_number('pkgnum') || $self->ut_number('reasonnum') + || $self->ut_enum('action', [ 'A', 'C', 'E', 'S' ]) || $self->ut_text('otaker') || $self->ut_numbern('date') ; diff --git a/FS/FS/part_export/shellcommands.pm b/FS/FS/part_export/shellcommands.pm index b43033405..107106897 100644 --- a/FS/FS/part_export/shellcommands.pm +++ b/FS/FS/part_export/shellcommands.pm @@ -253,7 +253,9 @@ sub _export_command { @radius_groups = $svc_acct->radius_groups; my ($reasonnum, $reasontext, $reasontypenum, $reasontypetext); - if ( $cust_pkg && $action eq 'suspend' && (my $r = $cust_pkg->last_reason) ) { + if ( $cust_pkg && $action eq 'suspend' && + (my $r = $cust_pkg->last_reason('susp')) ) + { $reasonnum = $r->reasonnum; $reasontext = $r->reason; $reasontypenum = $r->reason_type; diff --git a/FS/FS/part_export/sqlradius.pm b/FS/FS/part_export/sqlradius.pm index 3c25a99ee..88b7ed399 100644 --- a/FS/FS/part_export/sqlradius.pm +++ b/FS/FS/part_export/sqlradius.pm @@ -311,7 +311,7 @@ sub suspended_usergroups { #false laziness with FS::part_export::shellcommands #subclass part_export? - my $r = $svc_acct->cust_svc->cust_pkg->last_reason; + my $r = $svc_acct->cust_svc->cust_pkg->last_reason('susp'); my %reasonmap = $self->_groups_susp_reason_map; my $userspec = ''; if ($r) { diff --git a/httemplate/edit/REAL_cust_pkg.cgi b/httemplate/edit/REAL_cust_pkg.cgi index 6f7f0d7db..b2c89c32c 100755 --- a/httemplate/edit/REAL_cust_pkg.cgi +++ b/httemplate/edit/REAL_cust_pkg.cgi @@ -44,10 +44,10 @@ <& .row_edit, cust_pkg=>$cust_pkg, column=>'setup', label=>'Setup' &> <& .row_edit, cust_pkg=>$cust_pkg, column=>'last_bill', label=>$last_bill_or_renewed &> <& .row_edit, cust_pkg=>$cust_pkg, column=>'bill', label=>$next_bill_or_prepaid_until &> - <& .row_edit, cust_pkg=>$cust_pkg, column=>'adjourn', label=>'Adjournment', note=>'(will <b>suspend</b> this package when the date is reached)' &> + <& .row_display, cust_pkg=>$cust_pkg, column=>'adjourn', label=>'Adjournment', note=>'(will <b>suspend</b> this package when the date is reached)' &> <& .row_display, cust_pkg=>$cust_pkg, column=>'susp', label=>'Suspension' &> - <& .row_edit, cust_pkg=>$cust_pkg, column=>'expire', label=>'Expiration', note=>'(will <b>cancel</b> this package when the date is reached)' &> + <& .row_display, cust_pkg=>$cust_pkg, column=>'expire', label=>'Expiration', note=>'(will <b>cancel</b> this package when the date is reached)' &> <& .row_display, cust_pkg=>$cust_pkg, column=>'cancel', label=>'Cancellation' &> <%def .row_edit> @@ -96,11 +96,16 @@ $cust_pkg $column $label + $note => '' </%args> % if ( $cust_pkg->get($column) ) { <TR> <TD ALIGN="right"><% $label %> date</TD> - <TD BGCOLOR="#ffffff"><% time2str($format,$cust_pkg->get($column)) %></TD> + <TD BGCOLOR="#ffffff"><% time2str($format,$cust_pkg->get($column)) %> +% if ( $note ) { + <BR><FONT SIZE=-1><% $note %></FONT> +% } + </TD> </TR> % } </%def> diff --git a/httemplate/misc/process/cancel_pkg.html b/httemplate/misc/process/cancel_pkg.html index d265c1849..669af9c87 100755 --- a/httemplate/misc/process/cancel_pkg.html +++ b/httemplate/misc/process/cancel_pkg.html @@ -46,6 +46,7 @@ if ($method eq 'expire' || $method eq 'adjourn'){ $date = $cgi->param('date'); str2time($cgi->param('date')) =~ /^(\d+)$/ or die "Illegal date"; $date = $1; + $method = ($method eq 'expire') ? 'cancel' : 'suspend'; } my $cust_pkg = qsearchs( 'cust_pkg', {'pkgnum'=>$pkgnum} ); @@ -61,15 +62,7 @@ if ($reasonnum == -1) { }; } -my $error; -if ($method eq 'expire' || $method eq 'adjourn'){ - my %hash = $cust_pkg->hash; - $hash{$method} = $date; - my $new = new FS::cust_pkg \%hash; - $error = $new->replace($cust_pkg, 'reason' => $reasonnum); -} else { - $error = $cust_pkg->$method( 'reason' => $reasonnum ); -} +my $error = $cust_pkg->$method( 'reason' => $reasonnum, 'date' => $date ); if ($error) { $cgi->param('error', $error); diff --git a/httemplate/misc/unadjourn_pkg.cgi b/httemplate/misc/unadjourn_pkg.cgi new file mode 100755 index 000000000..356b49cb3 --- /dev/null +++ b/httemplate/misc/unadjourn_pkg.cgi @@ -0,0 +1,17 @@ +%if ( $error ) { +% errorpage($error); +%} else { +<% $cgi->redirect(popurl(2). "view/cust_main.cgi?".$cust_pkg->getfield('custnum')) %> +%} +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Suspend customer package later'); + +my ($pkgnum) = $cgi->keywords; +my $cust_pkg = qsearchs( 'cust_pkg', { 'pkgnum' => $pkgnum } ); +my $error = "No package $pkgnum" unless $cust_pkg; + +$error ||= $cust_pkg->unadjourn; + +</%init> diff --git a/httemplate/misc/unexpire_pkg.cgi b/httemplate/misc/unexpire_pkg.cgi new file mode 100755 index 000000000..445025524 --- /dev/null +++ b/httemplate/misc/unexpire_pkg.cgi @@ -0,0 +1,17 @@ +%if ( $error ) { +% errorpage($error); +%} else { +<% $cgi->redirect(popurl(2). "view/cust_main.cgi?".$cust_pkg->getfield('custnum')) %> +%} +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Cancel customer package later'); + +my ($pkgnum) = $cgi->keywords; +my $cust_pkg = qsearchs( 'cust_pkg', { 'pkgnum' => $pkgnum } ); +my $error = "No package $pkgnum" unless $cust_pkg; + +$error ||= $cust_pkg->unexpire; + +</%init> diff --git a/httemplate/search/cust_pkg.cgi b/httemplate/search/cust_pkg.cgi index d9ed39116..8ad3dc5e1 100755 --- a/httemplate/search/cust_pkg.cgi +++ b/httemplate/search/cust_pkg.cgi @@ -52,11 +52,10 @@ sub { my $self = shift; my $return = ''; - if ($self->getfield('cancel') || - $self->getfield('suspend')) { - my $reason = $self->last_reason;# too inefficient? - $return = $reason->reason if $reason; - + foreach my $action ( qw ( cancel susp ) ) { + my $reason = $self->last_reason($action); + $return = $reason->reason if $reason; + last if $return; } $return; }, diff --git a/httemplate/view/cust_main/packages.html b/httemplate/view/cust_main/packages.html index e11cd5bcc..94ef88a8a 100755 --- a/httemplate/view/cust_main/packages.html +++ b/httemplate/view/cust_main/packages.html @@ -131,15 +131,12 @@ Current packages % % % if ( $cust_pkg->get('cancel') ) { #status: cancelled -% my $cpr = $cust_pkg->last_cust_pkg_reason; +% my $cpr = $cust_pkg->last_cust_pkg_reason('cancel'); <% pkg_status_row($cust_pkg, 'Cancelled', 'cancel', 'color'=>'FF0000', conf=>$conf ) %> <% pkg_status_row_colspan( - ( ( $cpr && ( $cpr->date == $cust_pkg->get('cancel') || - $cpr->date == $cust_pkg->expire - ) - ) ? $cpr->reasontext. ' by '. $cpr->otaker : '' ), '', + ( $cpr ? $cpr->reasontext. ' by '. $cpr->otaker : '' ), '', 'align' => 'right', 'color' => 'ff0000', 'size' => '-2', ) %> @@ -160,15 +157,12 @@ Current packages % } else { % % if ( $cust_pkg->get('susp') ) { #status: suspended -% my $cpr = $cust_pkg->last_cust_pkg_reason; +% my $cpr = $cust_pkg->last_cust_pkg_reason('susp'); <% pkg_status_row( $cust_pkg, 'Suspended', 'susp', 'color'=>'FF9900', conf=>$conf ) %> <% pkg_status_row_colspan( - ( ( $cpr && ( $cpr->date == $cust_pkg->susp || - $cpr->date == $cust_pkg->adjourn - ) - ) ? $cpr->reasontext. ' by '. $cpr->otaker : '' ), '', + ( $cpr ? $cpr->reasontext. ' by '. $cpr->otaker : '' ), '', 'align' => 'right', 'color' => 'FF9900', 'size' => '-2', ) %> @@ -391,7 +385,18 @@ sub pkg_status_row { sub pkg_status_row_if { my( $cust_pkg, $title, $field, %opt ) = @_; - $cust_pkg->get($field) ? pkg_status_row(@_) : ''; + + $title = '<FONT SIZE=-1>( '. pkg_unadjourn_link($cust_pkg). ' ) </FONT>'. $title + if ( $field eq 'adjourn' && + $curuser->access_right('Suspend customer package later') + ); + + $title = '<FONT SIZE=-1>( '. pkg_unexpire_link($cust_pkg). ' ) </FONT>'. $title + if ( $field eq 'expire' && + $curuser->access_right('Cancel customer package later') + ); + + $cust_pkg->get($field) ? pkg_status_row($cust_pkg, $title, $field, %opt) : ''; } sub pkg_status_row_changed { @@ -527,6 +532,8 @@ sub pkg_suspend_link { include( '/elements/popup_link-cust_pkg.html', sub pkg_unsuspend_link { pkg_link('misc/unsusp_pkg', 'Unsuspend', @_ ); } sub pkg_expire_link { pkg_link('misc/expire_pkg', 'Cancel later', @_ ); } +sub pkg_unadjourn_link { pkg_link('misc/unadjourn_pkg', 'Abort', @_ ); } +sub pkg_unexpire_link { pkg_link('misc/unexpire_pkg', 'Abort', @_ ); } sub pkg_dates_link { pkg_link('edit/REAL_cust_pkg', 'Edit dates', @_ ); } sub pkg_cancel_link { include( '/elements/popup_link-cust_pkg.html', |