diff options
-rw-r--r-- | FS/FS/cust_pkg.pm | 54 | ||||
-rwxr-xr-x | httemplate/browse/part_pkg.cgi | 23 | ||||
-rw-r--r-- | httemplate/edit/bulk-cust_pkg.html | 62 | ||||
-rw-r--r-- | httemplate/edit/process/bulk-cust_pkg.cgi | 9 |
4 files changed, 145 insertions, 3 deletions
diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index c327ec635..2b512a73b 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -1287,6 +1287,60 @@ sub change { } +use Data::Dumper; +use Storable 'thaw'; +use MIME::Base64; +sub process_bulk_cust_pkg { + local $DEBUG = 1; + my $job = shift; + my $param = thaw(decode_base64(shift)); + warn Dumper($param) if $DEBUG; + + my $old_part_pkg = qsearchs('part_pkg', + { pkgpart => $param->{'old_pkgpart'} }); + my $new_part_pkg = qsearchs('part_pkg', + { pkgpart => $param->{'new_pkgpart'} }); + die "Must select a new package type\n" unless $new_part_pkg; + my $keep_dates = $param->{'keep_dates'} || 0; + + 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 @cust_pkgs = qsearch('cust_pkg', { 'pkgpart' => $param->{'old_pkgpart'} } ); + + my $i = 0; + foreach my $old_cust_pkg ( @cust_pkgs ) { + $i++; + $job->update_statustext(int(100*$i/(scalar @cust_pkgs))); + if ( $old_cust_pkg->getfield('cancel') ) { + warn '[process_bulk_cust_pkg ] skipping canceled pkgnum '. + $old_cust_pkg->pkgnum."\n" + if $DEBUG; + next; + } + warn '[process_bulk_cust_pkg] changing pkgnum '.$old_cust_pkg->pkgnum."\n" + if $DEBUG; + my $error = $old_cust_pkg->change( + 'pkgpart' => $param->{'new_pkgpart'}, + 'keep_dates' => $keep_dates + ); + if ( !ref($error) ) { # change returns the cust_pkg on success + $dbh->rollback; + die "Error changing pkgnum ".$old_cust_pkg->pkgnum.": '$error'\n"; + } + } + $dbh->commit if $oldAutoCommit; + return; +} + =item last_bill Returns the last bill date, or if there is no last bill date, the setup date. diff --git a/httemplate/browse/part_pkg.cgi b/httemplate/browse/part_pkg.cgi index 3881606d9..26e01700a 100755 --- a/httemplate/browse/part_pkg.cgi +++ b/httemplate/browse/part_pkg.cgi @@ -32,6 +32,7 @@ my $acl_edit = $curuser->access_right($edit); my $acl_edit_global = $curuser->access_right($edit_global); my $acl_config = $curuser->access_right('Configuration'); #to edit services #and agent types + #and bulk change die "access denied" unless $acl_edit || $acl_edit_global; @@ -325,8 +326,8 @@ if ( $acl_edit_global ) { ); my $cust_pkg_link = $p. 'search/cust_pkg.cgi?pkgpart='; push @fields, sub { my $part_pkg = shift; - [ - map { + [ + map( { my $magic = $_; my $label = $_; if ( $magic eq 'active' && $part_pkg->freq == 0 ) { @@ -360,7 +361,23 @@ if ( $acl_edit_global ) { }, ], } (qw( not_yet_billed active suspended cancelled )) - ]; }; + ), + ($acl_config ? + [ {}, + { 'data' => '<FONT SIZE="-1">[ '. + include('/elements/popup_link.html', + 'label' => 'change', + 'action' => "${p}edit/bulk-cust_pkg.html?". + 'pkgpart='.$part_pkg->pkgpart, + 'actionlabel' => 'Change Packages', + 'width' => 569, + 'height' => 210, + ).' ]</FONT>', + 'align' => 'left', + } + ] : () ), + ]; + }; $align .= 'r'; #} diff --git a/httemplate/edit/bulk-cust_pkg.html b/httemplate/edit/bulk-cust_pkg.html new file mode 100644 index 000000000..ab419215e --- /dev/null +++ b/httemplate/edit/bulk-cust_pkg.html @@ -0,0 +1,62 @@ +<% include('/elements/header-popup.html', 'Bulk package change') %> + +<% include('/elements/init_overlib.html') %> + +<% include('/elements/progress-init.html', + 'OneTrueForm', + [qw( old_pkgpart new_pkgpart keep_dates)], + 'process/bulk-cust_pkg.cgi', + $p.'browse/part_pkg.cgi', + ) +%> + +<SCRIPT TYPE="text/javascript"> +function areyousure() { + if(confirm('Change these packages?')) { + process(); + } +} +</SCRIPT> +<FORM NAME="OneTrueForm"> +% #false laziness with bulk-cust_svc.html +% $cgi->param('pkgpart') =~ /^(\d+)$/ +% or die "illegal pkgpart: ". $cgi->param('pkgpart'); +% +% my $old_pkgpart = $1; +% my $src_part_pkg = qsearchs('part_pkg', { 'pkgpart' => $old_pkgpart } ) +% or die "unknown pkgpart: $old_pkgpart"; +% + + +<INPUT NAME="old_pkgpart" TYPE="hidden" VALUE="<% $old_pkgpart %>"> +Change <B><% $src_part_pkg->pkg_comment %></B><BR> + +to new package definition +<SELECT NAME="new_pkgpart"> +% foreach my $dest_part_pkg ( qsearch('part_pkg', { 'disabled' => '' } ) ) { +% # XXX probably no way to prevent packages from violating agent restrictions +% # maybe something like what bulk-cust_svc does with changing services +% # under specific pkgparts? + + <OPTION VALUE="<% $dest_part_pkg->pkgpart %>"><% $dest_part_pkg->pkgpart %>: <% $dest_part_pkg->pkg %> +% } + +</SELECT> +<BR> +<BR> +<INPUT TYPE="checkbox" NAME="keep_dates" CHECKED> Preserve all billing dates +<BR> +<BR> + +<INPUT TYPE="button" VALUE="Bulk change packages" onclick="areyousure()"> + +</FORM> + +<% include('/elements/footer.html') %> + +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +</%init> diff --git a/httemplate/edit/process/bulk-cust_pkg.cgi b/httemplate/edit/process/bulk-cust_pkg.cgi new file mode 100644 index 000000000..ede3ee8cd --- /dev/null +++ b/httemplate/edit/process/bulk-cust_pkg.cgi @@ -0,0 +1,9 @@ +<% $server->process %> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $server = new FS::UI::Web::JSRPC 'FS::cust_pkg::process_bulk_cust_pkg', $cgi; + +</%init> |