From df676d82034cb63ff357f8d8ed0f95ce788fb98b Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 9 Feb 2009 01:49:28 +0000 Subject: [PATCH] further work on agents editing own packages: fix fallout on package customization from turning agent_virt on in edit/part_pkg.cgi, add a "clone package" to package browse, like clone service, and have agent type selection disappear when you set an agentnum. RT#1331 --- FS/FS/access_user.pm | 8 +-- FS/FS/part_pkg.pm | 101 +++++++++++++++++++++---------- httemplate/browse/access_group.html | 4 +- httemplate/browse/part_pkg.cgi | 23 +++---- httemplate/edit/elements/edit.html | 16 ++++- httemplate/edit/part_pkg.cgi | 85 +++++++++++++++++--------- httemplate/elements/select-part_pkg.html | 16 +---- 7 files changed, 149 insertions(+), 104 deletions(-) diff --git a/FS/FS/access_user.pm b/FS/FS/access_user.pm index e5c5ed155..63ae30d36 100644 --- a/FS/FS/access_user.pm +++ b/FS/FS/access_user.pm @@ -425,11 +425,7 @@ sub access_right { $self->{_ACLcache} = {}; } - my $has_right = ' ( '. join(' OR ', - map { 'rightname = '. dbh->quote($_) } - @$rightname - ). - ' ) '; + my $has_right = ' rightname IN ('. join(',', map '?', @$rightname ). ') '; my $sth = dbh->prepare(" SELECT groupnum FROM access_usergroup @@ -441,7 +437,7 @@ sub access_right { AND $has_right LIMIT 1 ") or die dbh->errstr; - $sth->execute($self->usernum) or die $sth->errstr; + $sth->execute($self->usernum, @$rightname) or die $sth->errstr; my $row = $sth->fetchrow_arrayref; #$row ? $row->[0] : ''; diff --git a/FS/FS/part_pkg.pm b/FS/FS/part_pkg.pm index e53d7b821..3308eadf4 100644 --- a/FS/FS/part_pkg.pm +++ b/FS/FS/part_pkg.pm @@ -1100,10 +1100,48 @@ sub calc_remain { 0; } sub calc_cancel { 0; } sub calc_units { 0; } +=item format OPTION DATA + +Returns data formatted according to the function 'format' described +in the plan info. Returns DATA if no such function exists. + +=cut + +sub format { + my ($self, $option, $data) = (shift, shift, shift); + if (exists($plans{$self->plan}->{fields}->{$option}{format})) { + &{$plans{$self->plan}->{fields}->{$option}{format}}($data); + }else{ + $data; + } +} + +=item parse OPTION DATA + +Returns data parsed according to the function 'parse' described +in the plan info. Returns DATA if no such function exists. + +=cut + +sub parse { + my ($self, $option, $data) = (shift, shift, shift); + if (exists($plans{$self->plan}->{fields}->{$option}{parse})) { + &{$plans{$self->plan}->{fields}->{$option}{parse}}($data); + }else{ + $data; + } +} + =back =cut +=head1 CLASS METHODS + +=over 4 + +=cut + # _upgrade_data # # Used by FS::Upgrade to migrate to a new database. @@ -1170,6 +1208,37 @@ sub _upgrade_data { # class method } +=item curuser_pkgs_sql + +Returns an SQL fragment for searching for packages the current user can +use, either via part_pkg.agentnum directly, or via agent type (see +L). + +=cut + +sub curuser_pkgs_sql { + #my($class) = shift; + + my $agentnums = join(',', $FS::CurrentUser::CurrentUser->agentnums); + + " + ( + agentnum IS NOT NULL + OR + 0 < ( SELECT COUNT(*) + FROM type_pkgs + LEFT JOIN agent_type USING ( typenum ) + LEFT JOIN agent AS typeagent USING ( typenum ) + WHERE type_pkgs.pkgpart = part_pkg.pkgpart + AND typeagent.agentnum IN ($agentnums) + ) + ) + "; + +} + +=back + =head1 SUBROUTINES =over 4 @@ -1217,38 +1286,6 @@ sub plan_info { \%plans; } -=item format OPTION DATA - -Returns data formatted according to the function 'format' described -in the plan info. Returns DATA if no such function exists. - -=cut - -sub format { - my ($self, $option, $data) = (shift, shift, shift); - if (exists($plans{$self->plan}->{fields}->{$option}{format})) { - &{$plans{$self->plan}->{fields}->{$option}{format}}($data); - }else{ - $data; - } -} - -=item parse OPTION DATA - -Returns data parsed according to the function 'parse' described -in the plan info. Returns DATA if no such function exists. - -=cut - -sub parse { - my ($self, $option, $data) = (shift, shift, shift); - if (exists($plans{$self->plan}->{fields}->{$option}{parse})) { - &{$plans{$self->plan}->{fields}->{$option}{parse}}($data); - }else{ - $data; - } -} - =back diff --git a/httemplate/browse/access_group.html b/httemplate/browse/access_group.html index cecf3d6e2..aa9097f36 100644 --- a/httemplate/browse/access_group.html +++ b/httemplate/browse/access_group.html @@ -81,9 +81,7 @@ my $rights_sub = sub { ''. $_. ''. ''. - join('
', grep { warn "$access_group->access_right($_): ". - $access_group->access_right($_). "\n"; - $access_group->access_right($_); } + join('
', grep { $access_group->access_right($_); } map { ref($_) ? $_->{'rightname'} : $_; } @{ $rights{$_} } ). diff --git a/httemplate/browse/part_pkg.cgi b/httemplate/browse/part_pkg.cgi index cdaa2c92a..1fed614a2 100755 --- a/httemplate/browse/part_pkg.cgi +++ b/httemplate/browse/part_pkg.cgi @@ -46,25 +46,11 @@ if ( $cgi->param('active') ) { my $extra_sql = ''; -#false laziness w/elements/select-part_pkg.html -my $agentnums = join(',', $curuser->agentnums); - unless ( $acl_edit_global ) { - $extra_sql .= " - WHERE ( - agentnum IS NOT NULL OR 0 < ( - SELECT COUNT(*) - FROM type_pkgs - LEFT JOIN agent_type USING ( typenum ) - LEFT JOIN agent AS typeagent USING ( typenum ) - WHERE type_pkgs.pkgpart = part_pkg.pkgpart - AND typeagent.agentnum IN ($agentnums) - ) - ) - "; + $extra_sql .= ' WHERE '. FS::part_pkg->curuser_pkgs_sql; } -#eofalse +my $agentnums = join(',', $curuser->agentnums); my $count_cust_pkg = " SELECT COUNT(*) FROM cust_pkg LEFT JOIN cust_main USING ( custnum ) WHERE cust_pkg.pkgpart = part_pkg.pkgpart @@ -97,7 +83,12 @@ my $html_init; One or more service definitions are grouped together into a package definition and given pricing information. Customers purchase packages rather than purchase services directly.

+
Add a new package definition + or + !.include('/elements/select-part_pkg.html', 'element_name' => 'clone' ). qq! + +


!; #} diff --git a/httemplate/edit/elements/edit.html b/httemplate/edit/elements/edit.html index 76fcd384b..d18a37d5a 100644 --- a/httemplate/edit/elements/edit.html +++ b/httemplate/edit/elements/edit.html @@ -91,8 +91,12 @@ Example: 'menubar' => '', #menubar arrayref #agent virtualization - 'agent_virt' => 1, - 'agent_null_right' => 'Access Right Name', + 'agent_virt' => 1, + 'agent_null_right' => 'Access Right Name', + 'agent_clone_extra_sql' => '', #if provided, this overrides the extra_sql + #implementing agent virt, for clone + #operations. i.e. pass "1=1" to allow + #cloning anything 'viewall_dir' => '', #'search' or 'browse', defaults to 'search' @@ -106,6 +110,8 @@ Example: # HTML callbacks ### + 'body_etc' => '', # Additional BODY attributes, i.e. onLoad="" + 'html_init' => '', #after the header/menubar #string or coderef of additional HTML to add before @@ -172,7 +178,8 @@ Example: <% include('/elements/header'. ( $opt{popup} ? '-popup' : '' ). '.html', $title, - include( '/elements/menubar.html', @menubar ) + include( '/elements/menubar.html', @menubar ), + $opt{'body_etc'}, ) %> @@ -620,6 +627,9 @@ if ( $cgi->param('error') ) { $clone = $1; + $qsearch{'extra_sql'} = ' AND '. $opt{'agent_clone_extra_sql'} + if $opt{'agent_clone_extra_sql'}; + $object = qsearchs({ %qsearch, 'hashref' => { $pkey => $clone } }); &{$opt{'clone_callback'}}($cgi, $object, $fields, \%opt ) diff --git a/httemplate/edit/part_pkg.cgi b/httemplate/edit/part_pkg.cgi index 3efc26cc3..5a9bb109f 100755 --- a/httemplate/edit/part_pkg.cgi +++ b/httemplate/edit/part_pkg.cgi @@ -1,25 +1,28 @@ <% include( 'elements/edit.html', - 'post_url' => popurl(1).'process/part_pkg.cgi', - 'name' => "Package definition", - 'table' => 'part_pkg', - - 'agent_virt' => 1, - 'agent_null_right' => $edit_global, - - #'viewall_dir' => 'browse', - 'viewall_url' => $p.'browse/part_pkg.cgi', - 'html_init' => include('/elements/init_overlib.html'). - $freq_changed, - 'html_bottom' => $html_bottom, - - 'begin_callback' => $begin_callback, - 'end_callback' => $end_callback, - 'new_hashref_callback' => $new_hashref_callback, - 'new_object_callback' => $new_object_callback, - 'new_callback' => $new_callback, - 'clone_callback' => $clone_callback, - 'edit_callback' => $edit_callback, - 'error_callback' => $error_callback, + 'post_url' => popurl(1).'process/part_pkg.cgi', + 'name' => "Package definition", + 'table' => 'part_pkg', + + 'agent_virt' => 1, + 'agent_null_right' => $edit_global, + 'agent_clone_extra_sql' => FS::part_pkg->curuser_pkgs_sql, + + #'viewall_dir' => 'browse', + 'viewall_url' => $p.'browse/part_pkg.cgi', + 'html_init' => include('/elements/init_overlib.html'). + $javascript, + 'html_bottom' => $html_bottom, + 'body_etc' => + 'onLoad="agent_changed(document.edit_topform.agentnum)"', + + 'begin_callback' => $begin_callback, + 'end_callback' => $end_callback, + 'new_hashref_callback' => $new_hashref_callback, + 'new_object_callback' => $new_object_callback, + 'new_callback' => $new_callback, + 'clone_callback' => $clone_callback, + 'edit_callback' => $edit_callback, + 'error_callback' => $error_callback, 'labels' => { 'pkgpart' => 'Package Definition', @@ -65,6 +68,7 @@ type => 'select-agent', disable_empty => ! $acl_edit_global, empty_label => '(global)', + onchange => 'agent_changed', }, {field=>'classnum', type=>'select-pkg_class' }, {field=>'disabled', type=>$disabled_type, value=>'Y'}, @@ -230,7 +234,7 @@ my $error_callback = sub { (@agent_type) = $cgi->param('agent_type'); - $opt->{action} = 'Custom' if $cgi->param('clone'); + $opt->{action} = 'Custom' if $cgi->param('pkgnum'); $recur_disabled = $cgi->param('freq') ? 0 : 1; @@ -309,14 +313,21 @@ my $new_callback = sub { my $clone_callback = sub { my( $cgi, $object, $fields, $opt ) = @_; - $opt->{action} = 'Custom'; + if ( $cgi->param('pkgnum') ) { - #my $part_pkg = $clone_part_pkg->clone; - #this is all clone did anyway - $object->comment( '(CUSTOM) '. $object->comment ) - unless $object->comment =~ /^\(CUSTOM\) /; + my $cust_pkg = qsearchs('cust_pkg', { 'pkgnum' => $cgi->param('pkgnum') } ); + $object->agentnum( $cust_pkg->cust_main->agentnum ); - $object->disabled('Y'); + $opt->{action} = 'Custom'; + + #my $part_pkg = $clone_part_pkg->clone; + #this is all clone did anyway + $object->comment( '(CUSTOM) '. $object->comment ) + unless $object->comment =~ /^\(CUSTOM\) /; + + $object->disabled('Y'); + + } %options = $object->options; @@ -343,7 +354,7 @@ my $m2_error_callback_maker = sub { }; }; -my $freq_changed = <<'END'; +my $javascript = <<'END'; END diff --git a/httemplate/elements/select-part_pkg.html b/httemplate/elements/select-part_pkg.html index cd6d24c28..52b1ccaf1 100644 --- a/httemplate/elements/select-part_pkg.html +++ b/httemplate/elements/select-part_pkg.html @@ -33,20 +33,6 @@ my( %opt ) = @_; $opt{'records'} = delete $opt{'part_pkg'} if $opt{'part_pkg'}; -#false laziness w/browse/part_pkg.cgi -my $agentnums = join(',', $FS::CurrentUser::CurrentUser->agentnums); - -$opt{'extra_sql'} .= - " AND ( agentnum IS NOT NULL - OR 0 < ( SELECT COUNT(*) - FROM type_pkgs - LEFT JOIN agent_type USING ( typenum ) - LEFT JOIN agent AS typeagent USING ( typenum ) - WHERE type_pkgs.pkgpart = part_pkg.pkgpart - AND typeagent.agentnum IN ($agentnums) - ) - ) - "; -#eofalse +$opt{'extra_sql'} .= ' AND '. FS::part_pkg->curuser_pkgs_sql; -- 2.11.0