summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjeff <jeff>2008-06-28 19:25:24 +0000
committerjeff <jeff>2008-06-28 19:25:24 +0000
commita1871d3d13c1dafa93b956762c0d23728d261da7 (patch)
treeecd799ff28ca27d5e2ef07a615bcac49621dd391
parent7588be4eb948426b972d0238dcdbb1537dc6a72a (diff)
agent virtualize address blocks and routers
-rw-r--r--FS/FS/AccessRight.pm3
-rwxr-xr-xFS/FS/addr_block.pm68
-rwxr-xr-xFS/FS/router.pm16
-rwxr-xr-xFS/FS/svc_broadband.pm21
-rw-r--r--httemplate/browse/addr_block.cgi25
-rw-r--r--httemplate/browse/router.cgi13
-rwxr-xr-xhttemplate/browse/svc_acct_pop.cgi5
-rw-r--r--httemplate/edit/allocate.html9
-rw-r--r--httemplate/edit/elements/edit.html16
-rw-r--r--httemplate/edit/elements/svc_Common.html21
-rwxr-xr-xhttemplate/edit/process/addr_block/add.cgi36
-rwxr-xr-xhttemplate/edit/process/addr_block/allocate.cgi4
-rwxr-xr-xhttemplate/edit/process/addr_block/deallocate.cgi40
-rwxr-xr-xhttemplate/edit/process/addr_block/split.cgi44
-rw-r--r--httemplate/edit/process/elements/process.html17
-rw-r--r--httemplate/edit/process/router.cgi80
-rwxr-xr-xhttemplate/edit/process/svc_acct_pop.cgi5
-rw-r--r--httemplate/edit/process/svc_broadband.cgi36
-rwxr-xr-xhttemplate/edit/router.cgi110
-rwxr-xr-xhttemplate/edit/svc_acct_pop.cgi5
-rw-r--r--httemplate/edit/svc_broadband.cgi310
-rw-r--r--httemplate/elements/checkboxes-table.html12
-rw-r--r--httemplate/elements/menu.html2
-rw-r--r--httemplate/elements/select-agent.html14
-rw-r--r--httemplate/elements/select-table.html17
-rw-r--r--httemplate/elements/tr-checkboxes-table.html20
26 files changed, 417 insertions, 532 deletions
diff --git a/FS/FS/AccessRight.pm b/FS/FS/AccessRight.pm
index 5621a97..4e6eaaf 100644
--- a/FS/FS/AccessRight.pm
+++ b/FS/FS/AccessRight.pm
@@ -238,6 +238,9 @@ tie my %rights, 'Tie::IxHash',
'Edit billing events',
{ rightname=>'Edit global billing events', global=>1 },
+ { rightname=>'Engineering configuration' },
+ { rightname=>'Engineering global configuration', global=>1 },
+
{ rightname=>'Configuration', global=>1 }, #most of the rest of the configuraiton is not agent-virtualized
],
diff --git a/FS/FS/addr_block.pm b/FS/FS/addr_block.pm
index 208684b..5815f1a 100755
--- a/FS/FS/addr_block.pm
+++ b/FS/FS/addr_block.pm
@@ -7,6 +7,7 @@ use FS::router;
use FS::svc_broadband;
use FS::Conf;
use NetAddr::IP;
+use Carp qw( carp );
@ISA = qw( FS::Record );
@@ -47,6 +48,8 @@ block is assigned.
=item ip_netmask - the netmask of the block, expressed as an integer.
+=item agentnum - optional agent number (see L<FS::agent>)
+
=back
=head1 METHODS
@@ -84,6 +87,28 @@ sub delete {
Replaces OLD_RECORD with this one in the database. If there is an error,
returns the error, otherwise returns false.
+At present it's not possible to reallocate a block to a different router
+except by deallocating it first, which requires that none of its addresses
+be assigned. This is probably as it should be.
+
+sub replace_check {
+ my ( $new, $old ) = ( shift, shift );
+
+ unless($new->routernum == $old->routernum) {
+ my @svc = $self->svc_broadband;
+ if (@svc) {
+ return 'Block has assigned addresses: '.
+ join ', ', map {$_->ip_addr} @svc;
+ }
+
+ return 'Block is already allocated'
+ if($new->routernum && $old->routernum);
+
+ }
+
+ '';
+}
+
=item check
Checks all fields to make sure this is a valid record. If there is an error,
@@ -99,6 +124,7 @@ sub check {
$self->ut_number('routernum')
|| $self->ut_ip('ip_gateway')
|| $self->ut_number('ip_netmask')
+ || $self->ut_agentnum_acl('agentnum', 'Engineering global configuration')
;
return $error if $error;
@@ -202,7 +228,7 @@ my @used =
}
-=item allocate
+=item allocate -- deprecated
Allocates this address block to a router. Takes an FS::router object
as an argument.
@@ -215,25 +241,18 @@ be assigned. This is probably as it should be.
sub allocate {
my ($self, $router) = @_;
-
- return 'Block is already allocated'
- if($self->router);
+ carp "deallocate deprecated -- use replace";
return 'Block must be allocated to a router'
unless(ref $router eq 'FS::router');
- my @svc = $self->svc_broadband;
- if (@svc) {
- return 'Block has assigned addresses: '. join ', ', map {$_->ip_addr} @svc;
- }
-
my $new = new FS::addr_block {$self->hash};
$new->routernum($router->routernum);
return $new->replace($self);
}
-=item deallocate
+=item deallocate -- deprecated
Deallocates the block (i.e. sets the routernum to 0). If any addresses in the
block are assigned to services, it fails.
@@ -241,13 +260,9 @@ block are assigned to services, it fails.
=cut
sub deallocate {
+ carp "deallocate deprecated -- use replace";
my $self = shift;
- my @svc = $self->svc_broadband;
- if (@svc) {
- return 'Block has assigned addresses: '. join ', ', map {$_->ip_addr} @svc;
- }
-
my $new = new FS::addr_block {$self->hash};
$new->routernum(0);
return $new->replace($self);
@@ -328,6 +343,29 @@ sub split_block {
To be implemented.
+=item agent
+
+Returns the agent (see L<FS::agent>) for this address block, if one exists.
+
+=cut
+
+sub agent {
+ qsearchs('agent', { 'agentnum' => shift->agentnum } );
+}
+
+=item label
+
+Returns text including the router name, gateway ip, and netmask for this
+block.
+
+=cut
+
+sub label {
+ my $self = shift;
+ my $router = $self->router;
+ ($router ? $router->routername : '(unallocated)'). ':'. $self->NetAddr;
+}
+
=back
=head1 BUGS
diff --git a/FS/FS/router.pm b/FS/FS/router.pm
index 88ba990..bfc5530 100755
--- a/FS/FS/router.pm
+++ b/FS/FS/router.pm
@@ -5,7 +5,7 @@ use vars qw( @ISA );
use FS::Record qw( qsearchs qsearch );
use FS::addr_block;
-@ISA = qw( FS::Record );
+@ISA = qw( FS::Record FS::m2m_Common );
=head1 NAME
@@ -82,7 +82,9 @@ sub check {
my $error =
$self->ut_numbern('routernum')
- || $self->ut_text('routername');
+ || $self->ut_text('routername')
+ || $self->ut_agentnum_acl('agentnum', 'Engineering global configuration')
+ ;
return $error if $error;
$self->SUPER::check;
@@ -125,6 +127,16 @@ sub part_svc {
$self->part_svc_router;
}
+=item agent
+
+Returns the agent associated with this router, if any.
+
+=cut
+
+sub agent {
+ qsearchs('agent', { 'agentnum' => shift->agentnum });
+}
+
=back
=head1 BUGS
diff --git a/FS/FS/svc_broadband.pm b/FS/FS/svc_broadband.pm
index d123524..fa90437 100755
--- a/FS/FS/svc_broadband.pm
+++ b/FS/FS/svc_broadband.pm
@@ -220,6 +220,24 @@ sub check {
if($self->speed_up < 0) { return 'speed_up must be positive'; }
if($self->speed_down < 0) { return 'speed_down must be positive'; }
+ my $cust_svc = $self->svcnum
+ ? qsearchs('cust_svc', { 'svcnum' => $self->svcnum } )
+ : '';
+ my $cust_pkg;
+ if ($cust_svc) {
+ $cust_pkg = $cust_svc->cust_pkg;
+ }else{
+ $cust_pkg = qsearchs('cust_pkg', { 'pkgnum' => $self->pkgnum } );
+ return "Invalid pkgnum" unless $cust_pkg;
+ }
+
+ if ($cust_pkg) {
+ my $addr_agentnum = $self->addr_block->agentnum;
+ if ($addr_agentnum && $addr_agentnum != $cust_pkg->cust_main->agentnum) {
+ return "Address block does not service this customer";
+ }
+ }
+
if (not($self->ip_addr) or $self->ip_addr eq '0.0.0.0') {
my $next_addr = $self->addr_block->next_free_addr;
if ($next_addr) {
@@ -290,6 +308,9 @@ sub allowed_routers {
The business with sb_field has been 'fixed', in a manner of speaking.
+allowed_routers isn't agent virtualized because part_svc isn't agent
+virtualized
+
=head1 SEE ALSO
FS::svc_Common, FS::Record, FS::addr_block,
diff --git a/httemplate/browse/addr_block.cgi b/httemplate/browse/addr_block.cgi
index d597ee1..917f94c 100644
--- a/httemplate/browse/addr_block.cgi
+++ b/httemplate/browse/addr_block.cgi
@@ -2,13 +2,13 @@
'title' => 'Address Blocks',
'name' => 'address block',
'html_init' => $html_init,
- 'html_form' => $html_form,
+ 'html_foot' => $html_foot,
'query' => { 'table' => 'addr_block',
'hashref' => {},
'extra_sql' => $extra_sql,
'order_by' => $order_by,
},
- 'count_query' => "SELECT count(*) from addr_block $extra_sql",
+ 'count_query' => "SELECT count(*) from addr_block $count_sql",
'header' => [ 'Address Block',
'Router',
'Action(s)',
@@ -42,17 +42,26 @@
'border-right:none;',
'border-left:none;',
],
+ 'agent_virt' => 1,
+ 'agent_null_right' => 'Engineering global configuration',
+ 'agent_pos' => 1,
)
%>
<%init>
die "access denied"
- unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+ unless $FS::CurrentUser::CurrentUser->access_right('Engineering configuration')
+ || $FS::CurrentUser::CurrentUser->access_right('Engineering global configuration');
my $p2 = popurl(2);
my $path = $p2 . "edit/process/addr_block";
-my $extra_sql = " ";
+my $extra_sql = "";
+
+my $count_sql = "WHERE ". $FS::CurrentUser::CurrentUser->agentnums_sql(
+ 'null_right' => 'Engineering global configuration',
+);
+
my $order_by = "ORDER BY ";
$order_by .= "inet(ip_gateway), " if driver_name =~ /^Pg/i;
$order_by .= "inet_aton(ip_gateway), " if driver_name =~ /^mysql/i;
@@ -74,10 +83,16 @@ my $confirm = sub {
"javascript:addr_block_areyousure('$path/$verb.cgi?blocknum=$num', '$verb')";
};
-my $html_form = qq(
+my $html_foot = qq(
<FORM ACTION="$path/add.cgi" METHOD="POST">
Gateway/Netmask:
<INPUT TYPE="text" NAME="ip_gateway" SIZE="15">/<INPUT TYPE="text" NAME="ip_netmask" SIZE="2">
+);
+$html_foot .= include( '/elements/select-agent.html',
+ 'agent_virt' => 1,
+ 'agent_null_right' => 'Engineering global configuration',
+ );
+$html_foot .= qq(
<INPUT TYPE="submit" NAME="submit" VALUE="Add">
</FORM>
);
diff --git a/httemplate/browse/router.cgi b/httemplate/browse/router.cgi
index 9d856f6..9f71673 100644
--- a/httemplate/browse/router.cgi
+++ b/httemplate/browse/router.cgi
@@ -6,7 +6,7 @@
'hashref' => {},
'extra_sql' => $extra_sql,
},
- 'count_query' => "SELECT count(*) from router $extra_sql",
+ 'count_query' => "SELECT count(*) from router $count_sql",
'header' => [ 'Router name',
'Address block(s)',
],
@@ -19,12 +19,16 @@
'links' => [ [ "${p2}edit/router.cgi?", 'routernum' ],
'',
],
+ 'agent_virt' => 1,
+ 'agent_null_right'=> "Engineering global configuration",
+ 'agent_pos' => 1,
)
%>
<%init>
die "access denied"
- unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+ unless $FS::CurrentUser::CurrentUser->access_right('Engineering configuration')
+ || $FS::CurrentUser::CurrentUser->access_right('Engineering global configuration');
my $p2 = popurl(2);
my $extra_sql = '';
@@ -40,4 +44,9 @@ if ($cgi->param('hidecustomerrouters') eq '1') {
push @menubar, 'Hide customer routers', $cgi->self_url();
}
+my $count_sql = $extra_sql. ( $extra_sql =~ /WHERE/ ? ' AND' : 'WHERE' ).
+ $FS::CurrentUser::CurrentUser->agentnums_sql(
+ 'null_right' => 'Engineering global configuration',
+ );
+
</%init>
diff --git a/httemplate/browse/svc_acct_pop.cgi b/httemplate/browse/svc_acct_pop.cgi
index 44bc651..4e49371 100755
--- a/httemplate/browse/svc_acct_pop.cgi
+++ b/httemplate/browse/svc_acct_pop.cgi
@@ -27,8 +27,11 @@
%>
<%init>
+my $curuser = $FS::CurrentUser::CurrentUser;
+
die "access denied"
- unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+ unless $curuser->access_right('Engineering configuration')
+ || $curuser->access_right('Engineering global configuration');
my $html_init = qq!
<A HREF="${p}edit/svc_acct_pop.cgi"><I>Add new Access Number</I></A>
diff --git a/httemplate/edit/allocate.html b/httemplate/edit/allocate.html
index 29c16ae..0f05fcc 100644
--- a/httemplate/edit/allocate.html
+++ b/httemplate/edit/allocate.html
@@ -12,15 +12,22 @@
'table' => 'router',
'name_col' => 'routername',
'disable_empty' => 1,
+ 'agent_virt' => 1,
+ 'agent_null_right' =>
+ 'Engineering global configuration',
},
],
'post_url' => "process/addr_block/allocate.cgi",
'popup' => 1,
+ 'agent_virt' => 1,
+ 'agent_null_right' => 'Engineering global configuration',
)
%>
<%init>
+my $curuser = $FS::CurrentUser::CurrentUser;
die "access denied"
- unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+ unless $curuser->access_right('Engineering configuration')
+ || $curuser->access_right('Engineering global configuration');
</%init>
diff --git a/httemplate/edit/elements/edit.html b/httemplate/edit/elements/edit.html
index 86eb2b3..47b2464 100644
--- a/httemplate/edit/elements/edit.html
+++ b/httemplate/edit/elements/edit.html
@@ -108,8 +108,8 @@ Example:
#run before display to return a different value
'value_callback' => sub { my( $columname, $value ) = @_; },
- #XXX describe
- 'field_callback' => sub { },
+ #run before display to manipulate element of the 'fields' arrayref
+ 'field_callback' => sub { my( $cgi, $object, $field_hashref ) = @_; },
'viewall_dir' => '', #'search' or 'browse', defaults to 'search'
@@ -179,7 +179,7 @@ Example:
% @$fields
% ) {
%
-% &{ $opt{'field_callback'} }( $f )
+% my $trash = &{ $opt{'field_callback'} }( $cgi, $object, $f )
% if $opt{'field_callback'};
%
% my $field = $f->{'field'};
@@ -227,10 +227,18 @@ Example:
% 'disabled' => $f->{'disabled'},
% );
%
-% #select-table
+% #select-table, checkboxes-table
% $include_common{$_} = $f->{$_}
% foreach grep exists($f->{$_}), qw( table name_col );
%
+% #checkboxes-table
+% $include_common{$_} = $f->{$_}
+% foreach grep exists($f->{$_}), qw( target_table link_table );
+%
+% #*-table
+% $include_common{$_} = $f->{$_}
+% foreach grep exists($f->{$_}), qw( hashref agent_virt agent_null_right );
+%
% if ( $type eq 'tablebreak-tr-title' ) {
% $include_common{'table_id'} = 'TableNumber'. $tablenum++
% }
diff --git a/httemplate/edit/elements/svc_Common.html b/httemplate/edit/elements/svc_Common.html
index 72abcba..b6737c1 100644
--- a/httemplate/edit/elements/svc_Common.html
+++ b/httemplate/edit/elements/svc_Common.html
@@ -13,7 +13,7 @@
% $pkgnum = $1;
% $cgi->param('svcpart') =~ /^(\d+)$/ or die 'unparsable svcpart';
% $svcpart = $1;
-% $cgi->delete_all(); #so edit.html treats this correctly as new??
+% #$cgi->delete_all(); #so edit.html treats this correctly as new??
% }
%
<% include( 'edit.html',
@@ -63,7 +63,7 @@
},
'field_callback' => sub {
- my $f = shift;
+ my ($cgi, $object, $f) = @_;
my $columndef = $part_svc->part_svc_column($f->{'field'});
my $flag = $columndef->columnflag;
if ( $flag eq 'F' ) {
@@ -72,6 +72,23 @@
}
},
+ 'html_init' => sub {
+ my $cust_main;
+ if ( $pkgnum ) {
+ my $cust_pkg = qsearchs('cust_pkg', {'pkgnum' => $pkgnum});
+ $cust_main = $cust_pkg->cust_main if $cust_pkg;
+ }
+ $cust_main
+ ? include( '/elements/small_custview.html',
+ $cust_main,
+ '',
+ 1,
+ popurl(2). "view/cust_main.cgi"
+ ). '<BR>'
+ : '';
+
+ },
+
'html_table_bottom' => sub {
my $svc_x = shift;
my $html = '';
diff --git a/httemplate/edit/process/addr_block/add.cgi b/httemplate/edit/process/addr_block/add.cgi
index e9f9b97..4321f94 100755
--- a/httemplate/edit/process/addr_block/add.cgi
+++ b/httemplate/edit/process/addr_block/add.cgi
@@ -1,28 +1,20 @@
-%
-%
-%my $error = '';
-%my $ip_gateway = $cgi->param('ip_gateway');
-%my $ip_netmask = $cgi->param('ip_netmask');
-%
-%my $new = new FS::addr_block {
-% ip_gateway => $ip_gateway,
-% ip_netmask => $ip_netmask,
-% routernum => 0 };
-%
-%$error = $new->insert;
-%
-%if ( $error ) {
-% $cgi->param('error', $error);
-% print $cgi->redirect(popurl(4). "browse/addr_block.cgi?". $cgi->query_string );
-%} else {
-% print $cgi->redirect(popurl(4). "browse/addr_block.cgi");
-%}
-%
+<% include( '../elements/process.html',
+ 'table' => 'addr_block',
+ 'redirect' => popurl(4). 'browse/addr_block.cgi?dummy=',
+ 'error_redirect' => popurl(4). 'browse/addr_block.cgi?',
+ 'agent_virt' => 1,
+ 'agent_null_right' => 'Engineering global configuration',
+ )
+%>
<%init>
-my $conf = new FS::Conf;
+my $curuser = $FS::CurrentUser::CurrentUser;
die "access denied"
- unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+ unless $curuser->access_right('Engineering configuration')
+ || $curuser->access_right('Engineering global configuration');
+
+$cgi->param('routernum', 0) # in FS::addr_block::check instead?
+ unless $cgi->param('routernum');
</%init>
diff --git a/httemplate/edit/process/addr_block/allocate.cgi b/httemplate/edit/process/addr_block/allocate.cgi
index d1bd73f..f377d81 100755
--- a/httemplate/edit/process/addr_block/allocate.cgi
+++ b/httemplate/edit/process/addr_block/allocate.cgi
@@ -8,7 +8,9 @@
<%init>
my $conf = new FS::Conf;
+my $curuser = $FS::CurrentUser::CurrentUser;
die "access denied"
- unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+ unless $curuser->access_right('Engineering configuration')
+ || $curuser->access_right('Engineering global configuration');
</%init>
diff --git a/httemplate/edit/process/addr_block/deallocate.cgi b/httemplate/edit/process/addr_block/deallocate.cgi
index 95e1b7e..91184b3 100755
--- a/httemplate/edit/process/addr_block/deallocate.cgi
+++ b/httemplate/edit/process/addr_block/deallocate.cgi
@@ -1,32 +1,20 @@
-%
-%my $error = '';
-%my $blocknum = $cgi->param('blocknum');
-%
-%my $addr_block = qsearchs('addr_block', { blocknum => $blocknum });
-%
-%if($addr_block) {
-% my $router = $addr_block->router;
-% if ($router) {
-% $error = $addr_block->deallocate($router);
-% } else {
-% $error = "Block is not allocated to a router";
-% }
-%} else {
-% $error = "Cannot find block with blocknum $blocknum";
-%}
-%
-%if ( $error ) {
-% $cgi->param('error', $error);
-% print $cgi->redirect(popurl(4). "browse/addr_block.cgi?" . $cgi->query_string);
-%} else {
-% print $cgi->redirect(popurl(4). "browse/addr_block.cgi");
-%}
-%
-
+<% include( '../elements/process.html',
+ 'table' => 'addr_block',
+ 'copy_on_empty' => [ grep { $_ ne 'routernum' }
+ fields 'addr_block' ],
+ 'redirect' => popurl(4). 'browse/addr_block.cgi?',
+ 'error_redirect' => popurl(4). 'browse/addr_block.cgi?',
+ 'agent_virt' => 1,
+ 'agent_null_right' => 'Engineering global configuration',
+ )
+%>
<%init>
my $conf = new FS::Conf;
+my $curuser = $FS::CurrentUser::CurrentUser;
die "access denied"
- unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+ unless $curuser->access_right('Engineering configuration')
+ || $curuser->access_right('Engineering global configuration');
+$cgi->param('routernum', 0); # just to be explicit about what we are doing
</%init>
diff --git a/httemplate/edit/process/addr_block/split.cgi b/httemplate/edit/process/addr_block/split.cgi
index b3a33b1..eb55d00 100755
--- a/httemplate/edit/process/addr_block/split.cgi
+++ b/httemplate/edit/process/addr_block/split.cgi
@@ -1,27 +1,27 @@
-%
-%my $error = '';
-%my $blocknum = $cgi->param('blocknum');
-%my $addr_block = qsearchs('addr_block', { blocknum => $blocknum });
-%
-%if ( $addr_block) {
-% $error = $addr_block->split_block;
-%} else {
-% $error = "Unknown blocknum: $blocknum";
-%}
-%
-%
-%if ( $error ) {
-% $cgi->param('error', $error);
-% print $cgi->redirect(popurl(4). "browse/addr_block.cgi?". $cgi->query_string );
-%} else {
-% print $cgi->redirect(popurl(4). "browse/addr_block.cgi");
-%}
-%
-
+<% $cgi->redirect(popurl(4). "browse/addr_block.cgi?". $cgi->query_string ) %>
<%init>
-my $conf = new FS::Conf;
+my $curuser = $FS::CurrentUser::CurrentUser;
+
die "access denied"
- unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+ unless $curuser->access_right('Engineering configuration')
+ || $curuser->access_right('Engineering global configuration');
+
+my $error = '';
+$cgi->param('blocknum') =~ /^(\d+)$/ or die "invalid blocknum";
+my $blocknum = $1;
+
+my $addr_block = qsearchs({ 'table' => 'addr_block',
+ 'hashref' => { blocknum => $blocknum },
+ 'extra_sql' => ' AND '. $curuser->agentnums_sql(
+ 'null_right' => 'Engineering global configuration'
+ ),
+ })
+ or $error = "Unknown blocknum: $blocknum";
+
+$error ||= $addr_block->split_block;
+
+$cgi->param('error', $error)
+ if $error;
</%init>
diff --git a/httemplate/edit/process/elements/process.html b/httemplate/edit/process/elements/process.html
index 6f271ee..de0304a 100644
--- a/httemplate/edit/process/elements/process.html
+++ b/httemplate/edit/process/elements/process.html
@@ -33,7 +33,8 @@ Example:
'clear_on_error' => [ 'form_field1', 'form_field2', ... ],
- #pass an arrayref of hashrefs for multiple m2ms or m2names
+ #pass an arrayref of hashrefs for multiple m2ms or m2names
+ #be certain you incorporate m2m_Common if you see error: param
'process_m2m' => { 'link_table' => 'link_table_name',
'target_table' => 'target_table_name',
@@ -176,6 +177,13 @@ my %hash =
my $new = $class->new( \%hash );
+if ($old && exists($opt{'copy_on_empty'})) {
+ foreach my $field (@{$opt{'copy_on_empty'}}) {
+ $new->set($field, $old->get($field))
+ unless scalar($cgi->param($field));
+ }
+}
+
if ( $opt{'agent_virt'} ) {
die "illegal agentnum"
unless $curuser->agentnums_href->{$new->agentnum}
@@ -184,13 +192,6 @@ if ( $opt{'agent_virt'} ) {
&& $curuser->access_right($opt{'agent_null_right'});
}
-if ($old && exists($opt{'copy_on_empty'})) {
- foreach my $field (@{$opt{'copy_on_empty'}}) {
- $new->set($field, $old->get($field))
- unless scalar($cgi->param($field));
- }
-}
-
$error ||= $new->check;
my @args = ();
diff --git a/httemplate/edit/process/router.cgi b/httemplate/edit/process/router.cgi
index 7e0baf7..6e717d1 100644
--- a/httemplate/edit/process/router.cgi
+++ b/httemplate/edit/process/router.cgi
@@ -1,70 +1,20 @@
-%local $FS::UID::AutoCommit=0;
-%
-%sub check {
-% my $error = shift;
-% if($error) {
-% $cgi->param('error', $error);
-% print $cgi->redirect(popurl(3) . "edit/router.cgi?". $cgi->query_string);
-% dbh->rollback;
-% exit;
-% }
-%}
-%
-%my $error = '';
-%my $routernum = $cgi->param('routernum');
-%my $routername = $cgi->param('routername');
-%my $old = qsearchs('router', { routernum => $routernum });
-%my @old_psr;
-%
-%my $new = new FS::router {
-% map {
-% ($_, scalar($cgi->param($_)));
-% } fields('router')
-%};
-%
-%if($old) {
-% $error = $new->replace($old);
-%} else {
-% $error = $new->insert;
-% $routernum = $new->routernum;
-%}
-%
-%check($error);
-%
-%if ($old) {
-% @old_psr = $old->part_svc_router;
-% foreach my $psr (@old_psr) {
-% if($cgi->param('svcpart_'.$psr->svcpart) eq 'ON') {
-% # do nothing
-% } else {
-% $error = $psr->delete;
-% }
-% }
-% check($error);
-%}
-%
-%foreach($cgi->param) {
-% if($cgi->param($_) eq 'ON' and /^svcpart_(\d+)$/) {
-% my $svcpart = $1;
-% if(grep {$_->svcpart == $svcpart} @old_psr) {
-% # do nothing
-% } else {
-% my $new_psr = new FS::part_svc_router { svcpart => $svcpart,
-% routernum => $routernum };
-% $error = $new_psr->insert;
-% }
-% check($error);
-% }
-%}
-%
-%
-%# Yay, everything worked!
-%dbh->commit or die dbh->errstr;
-%print $cgi->redirect(popurl(3). "browse/router.cgi");
-%
+<% include('elements/process.html',
+ 'table' => 'router',
+ 'viewall_dir' => 'browse',
+ 'viewall_ext' => 'cgi',
+ 'edit_ext' => 'cgi',
+ 'process_m2m' => { 'link_table' => 'part_svc_router',
+ 'target_table' => 'part_svc',
+ },
+ 'agent_virt' => 1,
+ 'agent_null_right' => 'Engineering global configuration',
+ )
+%>
<%init>
+my $curuser = $FS::CurrentUser::CurrentUser;
die "access denied"
- unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+ unless $curuser->access_right('Engineering configuration')
+ || $curuser->access_right('Engineering global configuration');
</%init>
diff --git a/httemplate/edit/process/svc_acct_pop.cgi b/httemplate/edit/process/svc_acct_pop.cgi
index 75b89c8..522e949 100755
--- a/httemplate/edit/process/svc_acct_pop.cgi
+++ b/httemplate/edit/process/svc_acct_pop.cgi
@@ -6,8 +6,11 @@
%}
<%init>
+my $curuser = $FS::CurrentUser::CurrentUser;
+
die "access denied"
- unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+ unless $curuser->access_right('Engineering configuration')
+ || $curuser->access_right('Engineering global configuration');
my $popnum = $cgi->param('popnum');
diff --git a/httemplate/edit/process/svc_broadband.cgi b/httemplate/edit/process/svc_broadband.cgi
index 8600da3..d5c9820 100644
--- a/httemplate/edit/process/svc_broadband.cgi
+++ b/httemplate/edit/process/svc_broadband.cgi
@@ -1,38 +1,8 @@
-%if ( $error ) {
-% $cgi->param('error', $error);
-% $cgi->param('ip_addr', $new->ip_addr);
-<% $cgi->redirect(popurl(2). "svc_broadband.cgi?". $cgi->query_string ) %>
-%} else {
-<% $cgi->redirect(popurl(3). "view/svc_broadband.cgi?" . $svcnum ) %>
-%}
+<% include('elements/svc_Common.html', 'table' => 'svc_broadband') %>
<%init>
+my $curuser = $FS::CurrentUser::CurrentUser;
die "access denied"
- unless $FS::CurrentUser::CurrentUser->access_right('Provision customer service'); #something else more specific?
-
-$cgi->param('svcnum') =~ /^(\d*)$/ or die "Illegal svcnum!";
-my $svcnum = $1;
-
-my $old;
-if ( $svcnum ) {
- $old = qsearchs('svc_broadband', { 'svcnum' => $svcnum } )
- or die "fatal: can't find broadband service (svcnum $svcnum)!";
-} else {
- $old = '';
-}
-
-my $new = new FS::svc_broadband ( {
- map {
- ($_, scalar($cgi->param($_)));
- } ( fields('svc_broadband'), qw( pkgnum svcpart ) )
-} );
-
-my $error;
-if ( $svcnum ) {
- $error = $new->replace($old);
-} else {
- $error = $new->insert;
- $svcnum = $new->svcnum;
-}
+ unless $curuser->access_right('Provision customer service'); #something else more specific?
</%init>
diff --git a/httemplate/edit/router.cgi b/httemplate/edit/router.cgi
index c08e544..180dcb7 100755
--- a/httemplate/edit/router.cgi
+++ b/httemplate/edit/router.cgi
@@ -1,78 +1,44 @@
-<% include('/elements/header.html', "$action Router", menubar(
- 'View all routers' => "${p}browse/router.cgi",
- ))
+<% include('elements/edit.html',
+ 'post_url' => popurl(1).'process/router.cgi',
+ 'name' => 'router',
+ 'table' => 'router',
+ 'viewall_url' => "${p}browse/router.cgi",
+ 'labels' => { 'routernum' => 'Router',
+ 'routername' => 'Name',
+ 'svc_part' => 'Service',
+ },
+ 'fields' => [
+ { 'field'=>'routername', 'type'=>'text', 'size'=>32 },
+ { 'field'=>'agentnum', 'type'=>'select-agent' },
+ ],
+ 'error_callback' => $callback,
+ 'edit_callback' => $callback,
+ 'new_callback' => $callback,
+ )
%>
-
-<% include('/elements/error.html') %>
-
-<FORM ACTION="<%popurl(1)%>process/router.cgi" METHOD=POST>
- <INPUT TYPE="hidden" NAME="table" VALUE="router">
- <INPUT TYPE="hidden" NAME="redirect_ok" VALUE="<%$p3%>/browse/router.cgi">
- <INPUT TYPE="hidden" NAME="redirect_error" VALUE="<%$p3%>/edit/router.cgi">
- <INPUT TYPE="hidden" NAME="routernum" VALUE="<%$routernum%>">
- <INPUT TYPE="hidden" NAME="svcnum" VALUE="<%$router->svcnum%>">
- Router #<%$routernum or "(NEW)"%>
-
-<BR><BR>Name <INPUT TYPE="text" NAME="routername" SIZE=32 VALUE="<%$router->routername%>">
-
-<BR><BR>
-Custom fields:
-<BR>
-<%table() %>
-%
-%foreach my $field ($router->virtual_fields) {
-% print $router->pvf($field)->widget('HTML', 'edit',
-% $router->getfield($field));
-%}
-%
-
-</TABLE>
-%
-%unless ($router->svcnum) {
-%
-
-<BR><BR>Select the service types available on this router<BR>
-%
-%
-% foreach my $part_svc ( qsearch('part_svc', { svcdb => 'svc_broadband',
-% disabled => '' }) ) {
-%
-
- <BR>
- <INPUT TYPE="checkbox" NAME="svcpart_<%$part_svc->svcpart%>"<%
- qsearchs('part_svc_router', { svcpart => $part_svc->svcpart,
- routernum => $routernum } ) ? ' CHECKED' : ''%> VALUE="ON">
- <A HREF="<%${p}%>edit/part_svc.cgi?<%$part_svc->svcpart%>">
- <%$part_svc->svcpart%>: <%$part_svc->svc%></A>
-% }
-% }
-
-
- <BR><BR><INPUT TYPE="submit" VALUE="Apply changes">
- </FORM>
-
-<% include('/elements/footer.html') %>
-
<%init>
-die "access denied"
- unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+my $curuser = $FS::CurrentUser::CurrentUser;
-my $router;
-if ( $cgi->keywords ) {
- my($query) = $cgi->keywords;
- $query =~ /^(\d+)$/;
- $router = qsearchs('router', { routernum => $1 })
- or print $cgi->redirect(popurl(2)."browse/router.cgi") ;
-} else {
- $router = new FS::router ( {
- map { $_, scalar($cgi->param($_)) } fields('router')
- } );
-}
-
-my $routernum = $router->routernum;
-my $action = $routernum ? 'Edit' : 'Add';
-
-my $p3 = popurl(3);
+die "access denied"
+ unless $curuser->access_right('Engineering configuration')
+ || $curuser->access_right('Engineering global configuration');
+
+my $callback = sub {
+ my ($cgi, $object, $fields) = (shift, shift, shift);
+ unless ($object->svcnum) {
+ push @{$fields},
+ { 'type' => 'tablebreak-tr-title',
+ 'value' => 'Select the service types available on this router',
+ },
+ { 'field' => 'svc_part',
+ 'type' => 'checkboxes-table',
+ 'target_table' => 'part_svc',
+ 'link_table' => 'part_svc_router',
+ 'name_col' => 'svc',
+ 'hashref' => { 'svcdb' => 'svc_broadband', 'disabled' => '' },
+ };
+ }
+};
</%init>
diff --git a/httemplate/edit/svc_acct_pop.cgi b/httemplate/edit/svc_acct_pop.cgi
index 3c16a1f..b0ae1c3 100755
--- a/httemplate/edit/svc_acct_pop.cgi
+++ b/httemplate/edit/svc_acct_pop.cgi
@@ -27,8 +27,11 @@ Local <INPUT TYPE="text" NAME="loc" SIZE=5 MAXLENGTH=4 VALUE="<% $hashref->{
<%init>
+my $curuser = $FS::CurrentUser::CurrentUser;
+
die "access denied"
- unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+ unless $curuser->access_right('Engineering configuration')
+ || $curuser->access_right('Engineering global configuration');
my $svc_acct_pop;
if ( $cgi->param('error') ) {
diff --git a/httemplate/edit/svc_broadband.cgi b/httemplate/edit/svc_broadband.cgi
index c2fb58d..25fb009 100644
--- a/httemplate/edit/svc_broadband.cgi
+++ b/httemplate/edit/svc_broadband.cgi
@@ -1,167 +1,26 @@
-<% include('/elements/header.html', "Broadband Service $action") %>
-
-<% include('/elements/error.html') %>
-
-Service #<B><%$svcnum ? $svcnum : "(NEW)"%></B><BR><BR>
-
-<FORM ACTION="<%${p1}%>process/svc_broadband.cgi" METHOD=POST>
- <INPUT TYPE="hidden" NAME="svcnum" VALUE="<%$svcnum%>">
- <INPUT TYPE="hidden" NAME="pkgnum" VALUE="<%$pkgnum%>">
- <INPUT TYPE="hidden" NAME="svcpart" VALUE="<%$svcpart%>">
-
- <%&ntable("#cccccc",2)%>
- <TR>
- <TD ALIGN="right">Description</TD>
- <TD BGCOLOR="#ffffff">
-% if ( $part_svc->part_svc_column('description')->columnflag eq 'F' ) {
-
- <INPUT TYPE="hidden" NAME="description" VALUE="<%$description%>"><%$description%>
-% } else {
-
- <INPUT TYPE="text" NAME="description" VALUE="<%$description%>">
-% }
-
- </TD>
- </TR>
- <TR>
- <TD ALIGN="right">IP Address</TD>
- <TD BGCOLOR="#ffffff">
-% if ( $part_svc->part_svc_column('ip_addr')->columnflag eq 'F' ) {
-
- <INPUT TYPE="hidden" NAME="ip_addr" VALUE="<%$ip_addr%>"><%$ip_addr%>
-% } else {
-
- <INPUT TYPE="text" NAME="ip_addr" VALUE="<%$ip_addr%>">
-% }
-
- </TD>
- </TR>
- <TR>
- <TD ALIGN="right">Download speed</TD>
- <TD BGCOLOR="#ffffff">
-% if ( $part_svc->part_svc_column('speed_down')->columnflag eq 'F' ) {
-
- <INPUT TYPE="hidden" NAME="speed_down" VALUE="<%$speed_down%>"><%$speed_down%>Kbps
-% } else {
-
- <INPUT TYPE="text" NAME="speed_down" SIZE=5 VALUE="<%$speed_down%>">Kbps
-% }
-
- </TD>
- </TR>
- <TR>
- <TD ALIGN="right">Upload speed</TD>
- <TD BGCOLOR="#ffffff">
-% if ( $part_svc->part_svc_column('speed_up')->columnflag eq 'F' ) {
-
- <INPUT TYPE="hidden" NAME="speed_up" VALUE="<%$speed_up%>"><%$speed_up%>Kbps
-% } else {
-
- <INPUT TYPE="text" NAME="speed_up" SIZE=5 VALUE="<%$speed_up%>">Kbps
-% }
-
- </TD>
- </TR>
-% if ($action eq 'Add') {
-
- <TR>
- <TD ALIGN="right">Router/Block</TD>
- <TD BGCOLOR="#ffffff">
- <SELECT NAME="blocknum">
-%
-% warn $svc_broadband->svcpart;
-% foreach my $router ($svc_broadband->allowed_routers) {
-% warn $router->routername;
-% foreach my $addr_block ($router->addr_block) {
-%
-
- <OPTION VALUE="<%$addr_block->blocknum%>"<%($addr_block->blocknum eq $blocknum) ? ' SELECTED' : ''%>>
- <%$router->routername%>:<%$addr_block->ip_gateway%>/<%$addr_block->ip_netmask%></OPTION>
-%
-% }
-% }
-%
-
- </SELECT>
- </TD>
- </TR>
-% } else {
-
-
- <TR>
- <TD ALIGN="right">Router/Block</TD>
- <TD BGCOLOR="#ffffff">
- <%$svc_broadband->addr_block->router->routername%>:<%$svc_broadband->addr_block->NetAddr%>
- <INPUT TYPE="hidden" NAME="blocknum" VALUE="<%$svc_broadband->blocknum%>">
- </TD>
- </TR>
-% }
- <TR>
- <TD ALIGN="right">MAC Address</TD>
- <TD BGCOLOR="#ffffff">
- <INPUT TYPE="text" NAME="mac_addr" VALUE="<%$mac_addr%>">
- </TD>
- </TR>
- <TR>
- <TD ALIGN="right">Latitude</TD>
- <TD BGCOLOR="#ffffff">
- <INPUT TYPE="text" NAME="latitude" VALUE="<%$latitude%>">
- </TD>
- </TR>
- <TR>
- <TD ALIGN="right">Longitude</TD>
- <TD BGCOLOR="#ffffff">
- <INPUT TYPE="text" NAME="longitude" VALUE="<%$longitude%>">
- </TD>
- </TR>
- <TR>
- <TD ALIGN="right">Altitude</TD>
- <TD BGCOLOR="#ffffff">
- <INPUT TYPE="text" NAME="altitude" VALUE="<%$altitude%>">
- </TD>
- </TR>
- <TR>
- <TD ALIGN="right">VLAN Profile</TD>
- <TD BGCOLOR="#ffffff">
-% if ( $part_svc->part_svc_column('vlan_profile')->columnflag eq 'F' ) {
-
- <INPUT TYPE="hidden" NAME="vlan_profile" VALUE="<%$vlan_profile%>"><%$vlan_profile%>
-% } else {
-
- <INPUT TYPE="text" NAME="vlan_profile" VALUE="<%$vlan_profile%>">
-% }
-
- </TD>
- </TR>
- <TR>
- <TD ALIGN="right">Authentication Key</TD>
- <TD BGCOLOR="#ffffff">
-% if ( $part_svc->part_svc_column('auth_key')->columnflag eq 'F' ) {
-
- <INPUT TYPE="hidden" NAME="auth_key" VALUE="<%$auth_key%>"><%$auth_key%>
-% } else {
-
- <INPUT TYPE="text" NAME="auth_key" VALUE="<%$auth_key%>">
-% }
-
- </TD>
- </TR>
-%
-%foreach my $field ($svc_broadband->virtual_fields) {
-% if ( $part_svc->part_svc_column($field)->columnflag ne 'F' &&
-% $part_svc->part_svc_column($field)->columnflag ne 'X') {
-% print $svc_broadband->pvf($field)->widget('HTML', 'edit',
-% $svc_broadband->getfield($field));
-% }
-%}
-
- </TABLE>
- <BR>
- <INPUT TYPE="submit" NAME="submit" VALUE="Submit">
-</FORM>
-
-<% include('/elements/footer.html') %>
-
+<% include('elements/svc_Common.html',
+ 'post_url' => popurl(1). 'process/svc_broadband.cgi',
+ 'name' => 'broadband service',
+ 'table' => 'svc_broadband',
+ 'labels' => { 'svcnum' => 'Service #',
+ 'description' => 'Description',
+ 'ip_addr' => 'IP address',
+ 'speed_down' => 'Download speed',
+ 'speed_up' => 'Upload speed',
+ 'blocknum' => 'Router/Block',
+ 'block_disp' => 'Router/Block',
+ 'mac_addr' => 'MAC address',
+ 'latitude' => 'Latitude',
+ 'longitude' => 'Longitude',
+ 'altitude' => 'Altitude',
+ 'vlan_profile' => 'VLAN profile',
+ 'authkey' => 'Authentication key',
+ },
+ 'fields' => \@fields,
+ 'field_callback' => $callback,
+ 'dummy' => $cgi->query_string,
+ )
+%>
<%init>
die "access denied"
@@ -170,85 +29,58 @@ die "access denied"
# If it's stupid but it works, it's still stupid.
# -Kristian
-use HTML::Widgets::SelectLayers;
-use Tie::IxHash;
-
-my( $svcnum, $pkgnum, $svcpart, $part_svc, $svc_broadband );
-if ( $cgi->param('error') ) {
-
- $svc_broadband = new FS::svc_broadband ( {
- map { $_, scalar($cgi->param($_)) } fields('svc_broadband'), qw(svcpart)
- } );
- $svcnum = $svc_broadband->svcnum;
- $pkgnum = $cgi->param('pkgnum');
- $svcpart = $svc_broadband->svcpart;
- $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
- die "No part_svc entry!" unless $part_svc;
-
-} elsif ( $cgi->param('pkgnum') && $cgi->param('svcpart') ) { #adding
-
- $cgi->param('pkgnum') =~ /^(\d+)$/ or die 'unparsable pkgnum';
- $pkgnum = $1;
- $cgi->param('svcpart') =~ /^(\d+)$/ or die 'unparsable svcpart';
- $svcpart = $1;
-
- $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
- die "No part_svc entry!" unless $part_svc;
-
- $svc_broadband = new FS::svc_broadband({ svcpart => $svcpart });
-
- $svcnum='';
+my @fields = (
+ qw( description ip_addr speed_down speed_up blocknum ),
+ { field=>'block_label', type=>'fixed' },
+ qw( mac_addr latitude longitude altitude vlan_profile authkey )
+);
- $svc_broadband->set_default_and_fixed;
+my $callback = sub {
+ my ($cgi, $object, $fieldref) = @_;
-} else { #editing
+ my $svcpart = $object->svcnum ? $object->cust_svc->svcpart
+ : $cgi->param('svcpart');
- my($query) = $cgi->keywords;
- $query =~ /^(\d+)$/ or die "unparsable svcnum";
- $svcnum=$1;
- $svc_broadband=qsearchs('svc_broadband',{'svcnum'=>$svcnum})
- or die "Unknown (svc_broadband) svcnum!";
-
- my($cust_svc)=qsearchs('cust_svc',{'svcnum'=>$svcnum})
- or die "Unknown (cust_svc) svcnum!";
-
- $pkgnum=$cust_svc->pkgnum;
- $svcpart=$cust_svc->svcpart;
-
- $part_svc=qsearchs('part_svc',{'svcpart'=>$svcpart});
+ my $part_svc = qsearchs( 'part_svc', { svcpart => $svcpart } );
die "No part_svc entry!" unless $part_svc;
-}
-my $action = $svc_broadband->svcnum ? 'Edit' : 'Add';
-
-if ($pkgnum) {
-
- #Nothing?
-
-} elsif ( $action eq 'Edit' ) {
-
- #Nothing?
-
-} else {
- die "\$action eq Add, but \$pkgnum is null!\n";
-}
-
-my $p1 = popurl(1);
-
-my ($ip_addr, $speed_up, $speed_down, $blocknum, $mac_addr,
- $latitude, $longitude, $altitude, $vlan_profile, $auth_key,
- $description) =
- ($svc_broadband->ip_addr,
- $svc_broadband->speed_up,
- $svc_broadband->speed_down,
- $svc_broadband->blocknum,
- $svc_broadband->mac_addr,
- $svc_broadband->latitude,
- $svc_broadband->longitude,
- $svc_broadband->altitude,
- $svc_broadband->vlan_profile,
- $svc_broadband->auth_key,
- $svc_broadband->description,
- );
+ my $columndef = $part_svc->part_svc_column($fieldref->{'field'});
+ if ($columndef->columnflag eq 'F') {
+ $fieldref->{'type'} = 'fixed';
+ $fieldref->{'value'} = $columndef->columnvalue;
+ }
+
+ if ($object->svcnum) {
+
+ $fieldref->{type} = 'hidden'
+ if $fieldref->{field} eq 'blocknum';
+
+ $fieldref->{value} = $object->addr_block->label
+ if $fieldref->{field} eq 'block_label';
+
+ } else {
+
+ $fieldref->{type} = 'hidden' if $fieldref->{field} eq 'block_label';
+
+ if ($fieldref->{field} eq 'blocknum') {
+ my $cust_pkg = qsearchs( 'cust_pkg', {pkgnum => $cgi->param('pkgnum')} );
+ die "No cust_pkg entry!" unless $cust_pkg;
+
+ $object->svcpart($part_svc->svcpart);
+ my @addr_block =
+ grep { ! $_->agentnum
+ || $cust_pkg->cust_main->agentnum == $_->agentnum
+ && $FS::CurrentUser::CurrentUser->agentnum($_->agentnum)
+ }
+ map { $_->addr_block } $object->allowed_routers;
+ my @options = map { $_->blocknum } @addr_block;
+ my %option_labels = map { ( $_->blocknum => $_->label ) } @addr_block;
+ $fieldref->{type} = 'select';
+ $fieldref->{options} = \@options;
+ $fieldref->{labels} = \%option_labels;
+ }
+
+ }
+};
</%init>
diff --git a/httemplate/elements/checkboxes-table.html b/httemplate/elements/checkboxes-table.html
index cdfa58e..b6b04d1 100644
--- a/httemplate/elements/checkboxes-table.html
+++ b/httemplate/elements/checkboxes-table.html
@@ -28,9 +28,9 @@
% my $target_pkey = dbdef->table($opt{'target_table'})->primary_key;
%
% my( $source_pkey, $sourcenum, $source_obj );
-% if ( $opt{'source_obj'} ) {
+% if ( $opt{'source_obj'} || $opt{'object'} ) {
%
-% $source_obj = $opt{'source_obj'};
+% $source_obj = $opt{'source_obj'} || $opt{'object'};
% #$source_table = $source_obj->dbdef_table->table;
% $source_pkey = $source_obj->dbdef_table->primary_key;
% $sourcenum = $source_obj->$source_pkey();
@@ -48,11 +48,17 @@
%
% my $extra_sql = '';
%
+% if ( $opt{'agent_virt'} ) {
+% $extra_sql .= ' AND' . $FS::CurrentUser::CurrentUser->agentnums_sql(
+% 'null_right' => $opt{'agent_null_right'}
+% );
+% }
+%
% if ( $opt{'disable-able'} ) {
% $hashref->{'disabled'} = '';
%
% $extra_sql .= ( $sourcenum && $source_pkey )
-% ? "OR $source_pkey = $sourcenum"
+% ? " OR $source_pkey = $sourcenum"
% : '';
% }
%
diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html
index 9ace19e..5a947ea 100644
--- a/httemplate/elements/menu.html
+++ b/httemplate/elements/menu.html
@@ -334,7 +334,7 @@ $config_menu{'Resellers'} = [ \%config_agent, '' ]
$config_menu{'Billing'} = [ \%config_billing, '' ]
if $curuser->access_right('Edit billing events')
|| $curuser->access_right('Edit global billing events');
-if ( $curuser->access_right('Configuration') ) {
+if ( $curuser->access_right('Engineering configuration') ) {
$config_menu{'Dialup'} = [ \%config_dialup, '' ];
$config_menu{'Fixed (username-less) broadband'} =
[ \%config_broadband, '' ];
diff --git a/httemplate/elements/select-agent.html b/httemplate/elements/select-agent.html
index 54069a5..d8ab500 100644
--- a/httemplate/elements/select-agent.html
+++ b/httemplate/elements/select-agent.html
@@ -4,9 +4,8 @@
'value' => $agentnum || '',
'empty_label' => 'all',
'hashref' => { 'disabled' => '' },
- 'extra_sql' => ' AND '.
- $FS::CurrentUser::CurrentUser->agentnums_sql.
- ' ORDER BY agent',
+ 'order_by' => ' ORDER BY agent',
+ 'disable_empty' => $disable_empty,
%opt,
)
%>
@@ -18,4 +17,13 @@ my $agentnum = $opt{'curr_value'} || $opt{'value'};
$opt{'records'} = delete $opt{'agents'}
if $opt{'agents'};
+my $curuser = $FS::CurrentUser::CurrentUser;
+my $disable_empty = 1;
+if ( $opt{'agent_null_right'} &&
+ $curuser->access_right($opt{'agent_null_right'})
+ )
+{
+ $disable_empty--;
+}
+
</%init>
diff --git a/httemplate/elements/select-table.html b/httemplate/elements/select-table.html
index 7339f36..d24c9ab 100644
--- a/httemplate/elements/select-table.html
+++ b/httemplate/elements/select-table.html
@@ -92,14 +92,25 @@ my $name_col = $opt{'name_col'};
my $value = $opt{'curr_value'} || $opt{'value'};
$value = [ split(/\s*,\s*/, $value) ] if $opt{'multiple'} && $value =~ /,/;
+my $extra_sql = $opt{'extra_sql'} || '';
+my $hashref = $opt{'hashref'} || {};
+
+if ( $opt{'agent_virt'} ) {
+ $extra_sql .=
+ ( $extra_sql =~ /WHERE/i || scalar(keys %$hashref ) ? ' AND ' : ' WHERE ' ).
+ $FS::CurrentUser::CurrentUser->agentnums_sql(
+ 'null_right' => $opt{'agent_null_right'}
+ );
+}
+
my @records = ();
if ( $opt{'records'} ) {
@records = @{ $opt{'records'} };
} else {
@records = qsearch( {
'table' => $opt{'table'},
- 'hashref' => ( $opt{'hashref'} || {} ),
- 'extra_sql' => ( $opt{'extra_sql'} || '' ),
+ 'hashref' => $hashref,
+ 'extra_sql' => $extra_sql,
'order_by' => ( $opt{'order_by'} || "ORDER BY $name_col" ),
});
}
@@ -113,7 +124,7 @@ unless ( ! $value
$opt{hashref}->{$key} = $value;
my $record = qsearchs( {
'table' => $opt{table},
- 'hashref' => $opt{hashref},
+ 'hashref' => $hashref,
'extra_sql' => ( $opt{extra_sql} || '' ),
});
push @records, $record if $record;
diff --git a/httemplate/elements/tr-checkboxes-table.html b/httemplate/elements/tr-checkboxes-table.html
new file mode 100644
index 0000000..0099427
--- /dev/null
+++ b/httemplate/elements/tr-checkboxes-table.html
@@ -0,0 +1,20 @@
+% unless ( $opt{'js_only'} ) {
+
+ <% include('tr-td-label.html', @_ ) %>
+
+ <TD <% $style %>>
+% }
+
+ <% include( '/elements/checkboxes-table.html', %opt ) %>
+
+% unless ( $opt{'js_only'} ) {
+ </TD>
+ </TR>
+% }
+<%init>
+
+my( %opt ) = @_;
+
+my $style = $opt{'cell_style'} ? 'STYLE="'. $opt{'cell_style'}. '"' : '';
+
+</%init>