summaryrefslogtreecommitdiff
path: root/FS/FS
diff options
context:
space:
mode:
authorivan <ivan>2006-06-18 12:54:49 +0000
committerivan <ivan>2006-06-18 12:54:49 +0000
commitc738a3c4923774b64960aa87fa58bd0751487edb (patch)
treee037c5c2e1211dd16c8024f16c9ce4d1fe589efb /FS/FS
parentaaad08cae3a0d46d012de5b78360101cda836c30 (diff)
ACLs: finish group edit (agents + rights) & browse
Diffstat (limited to 'FS/FS')
-rw-r--r--FS/FS/AccessRight.pm139
-rw-r--r--FS/FS/access_group.pm57
-rw-r--r--FS/FS/access_groupagent.pm24
-rw-r--r--FS/FS/m2name_Common.pm95
-rw-r--r--FS/FS/part_pkg.pm53
5 files changed, 280 insertions, 88 deletions
diff --git a/FS/FS/AccessRight.pm b/FS/FS/AccessRight.pm
index 01d63e35d..5229e1e65 100644
--- a/FS/FS/AccessRight.pm
+++ b/FS/FS/AccessRight.pm
@@ -1,7 +1,7 @@
package FS::AccessRight;
use strict;
-user vars qw(@rights %rights);
+use vars qw(@rights); # %rights);
use Tie::IxHash;
=head1 NAME
@@ -19,59 +19,94 @@ assigned to users and/or groups.
=cut
+#@rights = (
+# 'Reports' => [
+# '_desc' => 'Access to high-level reporting',
+# ],
+# 'Configuration' => [
+# '_desc' => 'Access to configuration',
+#
+# 'Settings' => {},
+#
+# 'agent' => [
+# '_desc' => 'Master access to reseller configuration',
+# 'agent_type' => {},
+# 'agent' => {},
+# ],
+#
+# 'export_svc_pkg' => [
+# '_desc' => 'Access to export, service and package configuration',
+# 'part_export' => {},
+# 'part_svc' => {},
+# 'part_pkg' => {},
+# 'pkg_class' => {},
+# ],
+#
+# 'billing' => [
+# '_desc' => 'Access to billing configuration',
+# 'payment_gateway' => {},
+# 'part_bill_event' => {},
+# 'prepay_credit' => {},
+# 'rate' => {},
+# 'cust_main_county' => {},
+# ],
+#
+# 'dialup' => [
+# '_desc' => 'Access to dialup configuraiton',
+# 'svc_acct_pop' => {},
+# ],
+#
+# 'broadband' => [
+# '_desc' => 'Access to broadband configuration',
+# 'router' => {},
+# 'addr_block' => {},
+# ],
+#
+# 'misc' => [
+# 'part_referral' => {},
+# 'part_virtual_field' => {},
+# 'msgcat' => {},
+# 'inventory_class' => {},
+# ],
+#
+# },
+#
+#);
+#
+##turn it into a more hash-like structure, but ordered via IxHash
+
+#well, this is what we have for now. could be ordered better, could be lots of
+# things better, but this ACL system does 99% of what folks need and the UI
+# isn't *that* bad
@rights = (
- 'Reports' => [
- '_desc' => 'Access to high-level reporting',
- ],
- 'Configuration' => [
- '_desc' => 'Access to configuration',
-
- 'Settings' => {},
-
- 'agent' => [
- '_desc' => 'Master access to reseller configuration',
- 'agent_type' => {},
- 'agent' => {},
- ],
-
- 'export_svc_pkg' => [
- '_desc' => 'Access to export, service and package configuration',
- 'part_export' => {},
- 'part_svc' => {},
- 'part_pkg' => {},
- 'pkg_class' => {},
- ],
-
- 'billing' => [
- '_desc' => 'Access to billing configuration',
- 'payment_gateway' => {},
- 'part_bill_event' => {},
- 'prepay_credit' => {},
- 'rate' => {},
- 'cust_main_county' => {},
- ],
-
- 'dialup' => [
- '_desc' => 'Access to dialup configuraiton',
- 'svc_acct_pop' => {},
- ],
-
- 'broadband' => [
- '_desc' => 'Access to broadband configuration',
- 'router' => {},
- 'addr_block' => {},
- ],
-
- 'misc' => [
- 'part_referral' => {},
- 'part_virtual_field' => {},
- 'msgcat' => {},
- 'inventory_class' => {},
- ],
-
- },
+ 'New customer',
+ 'View customer',
+ #'View Customer | View tickets',
+ 'Edit customer',
+ 'Cancel customer',
+ 'Delete customer',
+
+ 'Order customer package',
+ 'Change customer package',
+ 'Edit customer package dates',
+ 'Customize customer package',
+ 'Suspend customer package',
+ 'Unsuspend customer package',
+ 'Cancel customer package immediately',
+ 'Cancel customer package later',
+
+ 'Provision service',
+ 'Unprovision service',
+ #legacy link stuff
+
+ 'Post payment',
+ 'Process payment',
+ 'Post credit',
+ #more financial stuff
);
-#turn it into a more hash-like structure, but ordered via IxHash
+sub rights {
+ @rights;
+}
diff --git a/FS/FS/access_group.pm b/FS/FS/access_group.pm
index 9d870e57f..25190406f 100644
--- a/FS/FS/access_group.pm
+++ b/FS/FS/access_group.pm
@@ -3,8 +3,11 @@ package FS::access_group;
use strict;
use vars qw( @ISA );
use FS::Record qw( qsearch qsearchs );
+use FS::m2name_Common;
+use FS::access_groupagent;
+use FS::access_right;
-@ISA = qw(FS::Record);
+@ISA = qw(FS::m2m_Common FS::m2name_Common FS::Record);
=head1 NAME
@@ -27,15 +30,14 @@ FS::access_group - Object methods for access_group records
=head1 DESCRIPTION
-An FS::access_group object represents an example. FS::access_group inherits from
+An FS::access_group object represents an access group. FS::access_group inherits from
FS::Record. The following fields are currently supported:
=over 4
=item groupnum - primary key
-=item groupname -
-
+=item groupname - Access group name
=back
@@ -45,7 +47,7 @@ FS::Record. The following fields are currently supported:
=item new HASHREF
-Creates a new example. To add the example to the database, see L<"insert">.
+Creates a new access group. To add the access group to the database, see L<"insert">.
Note that this stores the hash reference, not a distinct copy of the hash it
points to. You can ask the object for a copy with the I<hash> method.
@@ -84,7 +86,7 @@ returns the error, otherwise returns false.
=item check
-Checks all fields to make sure this is a valid example. If there is
+Checks all fields to make sure this is a valid access group. If there is
an error, returns the error, otherwise returns false. Called by the insert
and replace methods.
@@ -105,12 +107,51 @@ sub check {
$self->SUPER::check;
}
+=item access_groupagent
+
+Returns all associated FS::access_groupagent records.
+
+=cut
+
+sub access_groupagent {
+ my $self = shift;
+ qsearch('access_groupagent', { 'groupnum' => $self->groupnum } );
+}
+
+=item access_rights
+
+Returns all associated FS::access_right records.
+
+=cut
+
+sub access_rights {
+ my $self = shift;
+ qsearch('access_right', { 'righttype' => 'FS::access_group',
+ 'rightobjnum' => $self->groupnum
+ }
+ );
+}
+
+=item access_right RIGHTNAME
+
+Returns the specified FS::access_right record. Can be used as a boolean, to
+test if this group has the given RIGHTNAME.
+
+=cut
+
+sub access_right {
+ my( $self, $name ) = shift;
+ qsearchs('access_right', { 'righttype' => 'FS::access_group',
+ 'rightobjnum' => $self->groupnum,
+ 'rightname' => $name,
+ }
+ );
+}
+
=back
=head1 BUGS
-The author forgot to customize this manpage.
-
=head1 SEE ALSO
L<FS::Record>, schema.html from the base documentation.
diff --git a/FS/FS/access_groupagent.pm b/FS/FS/access_groupagent.pm
index 6b5def1a3..3de8feeed 100644
--- a/FS/FS/access_groupagent.pm
+++ b/FS/FS/access_groupagent.pm
@@ -3,6 +3,7 @@ package FS::access_groupagent;
use strict;
use vars qw( @ISA );
use FS::Record qw( qsearch qsearchs );
+use FS::agent;
@ISA = qw(FS::Record);
@@ -27,7 +28,7 @@ FS::access_groupagent - Object methods for access_groupagent records
=head1 DESCRIPTION
-An FS::access_groupagent object represents an example. FS::access_groupagent inherits from
+An FS::access_groupagent object represents an group reseller virtualization. FS::access_groupagent inherits from
FS::Record. The following fields are currently supported:
=over 4
@@ -47,7 +48,7 @@ FS::Record. The following fields are currently supported:
=item new HASHREF
-Creates a new example. To add the example to the database, see L<"insert">.
+Creates a new group reseller virtualization. To add the record to the database, see L<"insert">.
Note that this stores the hash reference, not a distinct copy of the hash it
points to. You can ask the object for a copy with the I<hash> method.
@@ -86,7 +87,7 @@ returns the error, otherwise returns false.
=item check
-Checks all fields to make sure this is a valid example. If there is
+Checks all fields to make sure this is a valid group reseller virtualization. If there is
an error, returns the error, otherwise returns false. Called by the insert
and replace methods.
@@ -100,20 +101,29 @@ sub check {
my $error =
$self->ut_numbern('groupagentnum')
- || $self->ut_number('groupnum')
- || $self->ut_number('agentnum')
+ || $self->ut_foreign_key('groupnum', 'access_group', 'groupnum')
+ || $self->ut_foreign_key('agentnum', 'agent', 'agentnum')
;
return $error if $error;
$self->SUPER::check;
}
+=item agent
+
+Returns the associated FS::agent object.
+
+=cut
+
+sub agent {
+ my $self = shift;
+ qsearchs('agent', { 'agentnum' => $self->agentnum } );
+}
+
=back
=head1 BUGS
-The author forgot to customize this manpage.
-
=head1 SEE ALSO
L<FS::Record>, schema.html from the base documentation.
diff --git a/FS/FS/m2name_Common.pm b/FS/FS/m2name_Common.pm
new file mode 100644
index 000000000..7c9637e27
--- /dev/null
+++ b/FS/FS/m2name_Common.pm
@@ -0,0 +1,95 @@
+package FS::m2name_Common;
+
+use strict;
+use vars qw( @ISA $DEBUG );
+use FS::Schema qw( dbdef );
+use FS::Record qw( qsearch qsearchs ); #dbh );
+
+@ISA = qw( FS::Record );
+
+$DEBUG = 0;
+
+=head1 NAME
+
+FS::m2name_Common - Base class for tables with a related table listing names
+
+=head1 SYNOPSIS
+
+use FS::m2name_Common;
+
+@ISA = qw( FS::m2name_Common );
+
+=head1 DESCRIPTION
+
+FS::m2name_Common is intended as a base class for classes which have a
+related table that lists names.
+
+=head1 METHODS
+
+=over 4
+
+=item process_m2name
+
+=cut
+
+sub process_m2name {
+ my( $self, %opt ) = @_;
+
+ my $self_pkey = $self->dbdef_table->primary_key;
+ my $link_sourcekey = $opt{'num_col'} || $self_pkey;
+
+ my $link_table = $self->_load_table($opt{'link_table'});
+
+ my $link_static = $opt{'link_static'} || {};
+
+ foreach my $name ( @{ $opt{'names_list'} } ) {
+
+ my $obj = qsearchs( $link_table, {
+ $link_sourcekey => $self->$self_pkey(),
+ $opt{'name_col'} => $name,
+ %$link_static,
+ });
+
+ if ( $obj && ! $opt{'params'}->{"$link_table.$name"} ) {
+
+ my $d_obj = $obj; #need to save $obj for below.
+ my $error = $d_obj->delete;
+ die "error deleting $d_obj for $link_table.$name: $error" if $error;
+
+ } elsif ( $opt{'params'}->{"$link_table.$name"} && ! $obj ) {
+
+ #ok to clobber it now (but bad form nonetheless?)
+ #$obj = new "FS::$link_table" ( {
+ $obj = "FS::$link_table"->new( {
+ $link_sourcekey => $self->$self_pkey(),
+ $opt{'name_col'} => $name,
+ %$link_static,
+ });
+ my $error = $obj->insert;
+ die "error inserting $obj for $link_table.$name: $error" if $error;
+ }
+
+ }
+
+ '';
+}
+
+sub _load_table {
+ my( $self, $table ) = @_;
+ eval "use FS::$table";
+ die $@ if $@;
+ $table;
+}
+
+=back
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::Record>
+
+=cut
+
+1;
+
diff --git a/FS/FS/part_pkg.pm b/FS/FS/part_pkg.pm
index 05dc59913..de4d047de 100644
--- a/FS/FS/part_pkg.pm
+++ b/FS/FS/part_pkg.pm
@@ -1,7 +1,7 @@
package FS::part_pkg;
use strict;
-use vars qw( @ISA %freq %plans $DEBUG );
+use vars qw( @ISA %plans $DEBUG );
use Carp qw(carp cluck confess);
use Tie::IxHash;
use FS::Conf;
@@ -571,6 +571,32 @@ sub is_free {
}
}
+
+sub freqs_href {
+ #method, class method or sub? #my $self = shift;
+
+ tie my %freq, 'Tie::IxHash',
+ '0' => '(no recurring fee)',
+ '1h' => 'hourly',
+ '1d' => 'daily',
+ '1w' => 'weekly',
+ '2w' => 'biweekly (every 2 weeks)',
+ '1' => 'monthly',
+ '2' => 'bimonthly (every 2 months)',
+ '3' => 'quarterly (every 3 months)',
+ '6' => 'semiannually (every 6 months)',
+ '12' => 'annually',
+ '24' => 'biannually (every 2 years)',
+ '36' => 'triannually (every 3 years)',
+ '48' => '(every 4 years)',
+ '60' => '(every 5 years)',
+ '120' => '(every 10 years)',
+ ;
+
+ \%freq;
+
+}
+
=item freq_pretty
Returns an english representation of the I<freq> field, such as "monthly",
@@ -578,29 +604,14 @@ Returns an english representation of the I<freq> field, such as "monthly",
=cut
-tie %freq, 'Tie::IxHash',
- '0' => '(no recurring fee)',
- '1h' => 'hourly',
- '1d' => 'daily',
- '1w' => 'weekly',
- '2w' => 'biweekly (every 2 weeks)',
- '1' => 'monthly',
- '2' => 'bimonthly (every 2 months)',
- '3' => 'quarterly (every 3 months)',
- '6' => 'semiannually (every 6 months)',
- '12' => 'annually',
- '24' => 'biannually (every 2 years)',
- '36' => 'triannually (every 3 years)',
- '48' => '(every 4 years)',
- '60' => '(every 5 years)',
- '120' => '(every 10 years)',
-;
-
sub freq_pretty {
my $self = shift;
my $freq = $self->freq;
- if ( exists($freq{$freq}) ) {
- $freq{$freq};
+
+ my $freqs_href = $self->freqs_href;
+
+ if ( exists($freqs_href->{$freq}) ) {
+ $freqs_href->{$freq};
} else {
my $interval = 'month';
if ( $freq =~ /^(\d+)([hdw])$/ ) {