1 package FS::access_right;
6 use FS::Record qw( qsearch qsearchs );
7 use FS::upgrade_journal;
10 @ISA = qw(FS::Record);
14 FS::access_right - Object methods for access_right records
20 $record = new FS::access_right \%hash;
21 $record = new FS::access_right { 'column' => 'value' };
23 $error = $record->insert;
25 $error = $new_record->replace($old_record);
27 $error = $record->delete;
29 $error = $record->check;
33 An FS::access_right object represents a granted access right. FS::access_right
34 inherits from FS::Record. The following fields are currently supported:
38 =item rightnum - primary key
55 Creates a new right. To add the right to the database, see L<"insert">.
57 Note that this stores the hash reference, not a distinct copy of the hash it
58 points to. You can ask the object for a copy with the I<hash> method.
62 # the new method can be inherited from FS::Record, if a table method is defined
64 sub table { 'access_right'; }
68 Adds this record to the database. If there is an error, returns the error,
69 otherwise returns false.
73 # the insert method can be inherited from FS::Record
77 Delete this record from the database.
81 # the delete method can be inherited from FS::Record
83 =item replace OLD_RECORD
85 Replaces the OLD_RECORD with this one in the database. If there is an error,
86 returns the error, otherwise returns false.
90 # the replace method can be inherited from FS::Record
94 Checks all fields to make sure this is a valid right. If there is
95 an error, returns the error, otherwise returns false. Called by the insert
100 # the check method should currently be supplied - FS::Record contains some
101 # data checking routines
107 $self->ut_numbern('rightnum')
108 || $self->ut_text('righttype')
109 || $self->ut_text('rightobjnum')
110 || $self->ut_text('rightname')
112 return $error if $error;
119 # Used by FS::Upgrade to migrate to a new database.
121 sub _upgrade_data { # class method
122 my ($class, %opts) = @_;
124 my @unmigrated = ( qsearch( 'access_right',
125 { 'righttype'=>'FS::access_group',
126 'rightname'=>'Engineering configuration',
129 qsearch( 'access_right',
130 { 'righttype'=>'FS::access_group',
131 'rightname'=>'Engineering global configuration',
135 foreach ( @unmigrated ) {
136 my $rightname = $_->rightname;
137 $rightname =~ s/Engineering/Dialup/;
138 $_->rightname($rightname);
139 my $error = $_->replace;
140 die "Failed to update access right: $error"
142 my $broadband = new FS::access_right { $_->hash };
143 $rightname =~ s/Dialup/Broadband/;
144 $broadband->rightnum('');
145 $broadband->rightname($rightname);
146 $error = $broadband->insert;
147 die "Failed to insert access right: $error"
152 'Post payment' => [ 'Post check payment', 'Post cash payment' ],
153 'Process payment' => [ 'Process credit card payment', 'Process Echeck payment' ],
154 'Post refund' => [ 'Post check refund', 'Post cash refund' ],
155 'Refund payment' => [ 'Refund credit card payment', 'Refund Echeck payment' ],
156 'Regular void' => [ 'Void payments' ],
157 'Unvoid' => [ 'Unvoid payments', 'Unvoid invoices' ],
158 'Employees: Audit Report' => [ 'Employee Reports' ],
161 foreach my $oldright (keys %migrate) {
162 my @old = qsearch('access_right', { 'righttype'=>'FS::access_group',
163 'rightname'=>$oldright,
167 foreach my $old ( @old ) {
169 foreach my $newright ( @{ $migrate{$oldright} } ) {
171 'righttype' => 'FS::access_group',
172 'rightobjnum' => $old->rightobjnum,
173 'rightname' => $newright,
175 next if qsearchs('access_right', \%hash);
176 my $access_right = new FS::access_right \%hash;
177 my $error = $access_right->insert;
178 die $error if $error;
181 unless ( $oldright =~ / (payment|refund)$/ ) { #after the WEST stuff is sorted
182 my $error = $old->delete;
183 die $error if $error;
190 my @all_groups = qsearch('access_group', {});
192 #tie my %onetime, 'Tie::IxHash',
194 'List customers' => 'List all customers',
195 'List all customers' => 'Advanced customer search',
196 'List packages' => 'Summarize packages',
197 'Post payment' => 'Backdate payment',
198 'Cancel customer package immediately' => 'Un-cancel customer package',
199 'Suspend customer package' => 'Suspend customer',
200 'Unsuspend customer package' => 'Unsuspend customer',
201 'New prospect' => 'Generate quotation',
202 'Delete invoices' => 'Void invoices',
203 'List invoices' => 'List quotations',
204 'Post credit' => 'Credit line items',
205 #'View customer tax exemptions' => 'Edit customer tax exemptions',
206 'Edit customer' => 'Edit customer tax exemptions',
207 'Edit package definitions' => 'Bulk edit package definitions',
209 'List services' => [ 'Services: Accounts',
211 'Services: Certificates',
212 'Services: Mail forwards',
213 'Services: Virtual hosting services',
214 'Services: Wireless broadband services',
216 'Services: Dish services',
217 'Services: Hardware',
218 'Services: Phone numbers',
221 'Services: Mailing lists',
222 'Services: External services',
225 'Services: Accounts' => 'Services: Accounts: Advanced search',
226 'Services: Wireless broadband services' => 'Services: Wireless broadband services: Advanced search',
227 'Services: Hardware' => 'Services: Hardware: Advanced search',
228 'Services: Phone numbers' => 'Services: Phone numbers: Advanced search',
230 'Services: Accounts' => 'Services: Alarm services',
232 'List rating data' => [ 'Usage: RADIUS sessions',
233 'Usage: Call Detail Records (CDRs)',
234 'Usage: Unrateable CDRs',
236 'Provision customer service' => [ 'Edit password' ],
237 'Financial reports' => 'Employee Reports',
238 'Change customer package' => 'Detach customer package',
239 'Services: Accounts' => 'Services: Cable Subscribers',
240 'Bulk change customer packages' => 'Bulk move customer services',
241 'Configuration' => 'Edit sales people',
242 'Configuration' => 'Alarm global configuration',
243 'Services: Accounts' => 'Services: Conferencing',
244 'Services: Accounts' => 'Services: Video',
245 'Edit global package definitions' => 'Edit package definition costs',
246 'Add on-the-fly credit reason' => 'Add on-the-fly refund reason',
247 'Configuration' => 'Edit global fee definitions',
248 'Edit package definition costs' => 'View package definition costs',
249 'List prospects' => 'List contacts',
250 'List customers' => 'List contacts',
251 'Backdate payment' => 'Backdate credit',
252 'Generate quotation' => 'Disable quotation',
253 'Add on-the-fly void credit reason' => 'Add on-the-fly void reason',
254 '_ALL' => 'Employee preference telephony integration',
255 '_ALL' => 'RT activity notification',
256 'Edit customer package dates' => [ 'Change package start date', #4.x
257 'Change package contract end date',
259 'Resend invoices' => 'Print and mail invoices',
260 'List customers' => 'Customers: Customer churn report',
261 'Edit customer note' => 'Delete customer note',
262 'Edit customer' => 'Edit customer invoice terms',
263 'Financial reports' => 'Basic payment and refund reports',
266 # foreach my $old_acl ( keys %onetime ) {
268 # my @new_acl = ref($onetime{$old_acl})
269 # ? @{ $onetime{$old_acl} }
270 # : ( $onetime{$old_acl} );
274 my( $old_acl, $new_acl ) = splice(@onetime, 0, 2);
275 my @new_acl = ref($new_acl) ? @$new_acl : ( $new_acl );
277 foreach my $new_acl ( @new_acl ) {
279 ( my $journal = 'ACL_'.lc($new_acl) ) =~ s/\W/_/g;
280 next if FS::upgrade_journal->is_done($journal);
282 # grant $new_acl to all groups who have $old_acl
283 for my $group (@all_groups) {
284 next unless $old_acl eq '_ALL' || $group->access_right($old_acl);
285 next if $group->access_right($new_acl);
286 my $access_right = FS::access_right->new( {
287 'righttype' => 'FS::access_group',
288 'rightobjnum' => $group->groupnum,
289 'rightname' => $new_acl,
291 my $error = $access_right->insert;
292 die $error if $error;
295 FS::upgrade_journal->set_done($journal);
301 # some false laziness with @onetime above,
302 # but for use when multiple old acls trigger a single new acl
303 # (keys/values reversed from @onetime, expects arrayref value)
304 my @onetime_bynew = (
305 'Customize billing during suspension' => [ 'Suspend customer package', 'Suspend customer package later' ],
307 while ( @onetime_bynew ) {
308 my( $new_acl, $old_acl ) = splice(@onetime_bynew, 0, 2);
309 ( my $journal = 'ACL_'.lc($new_acl) ) =~ s/\W/_/g;
310 next if FS::upgrade_journal->is_done($journal);
311 # grant $new_acl to all groups who have one of @old_acl
312 for my $group (@all_groups) {
313 next unless grep { $group->access_right($_) } @$old_acl;
314 next if $group->access_right($new_acl);
315 my $access_right = FS::access_right->new( {
316 'righttype' => 'FS::access_group',
317 'rightobjnum' => $group->groupnum,
318 'rightname' => $new_acl,
320 my $error = $access_right->insert;
321 die $error if $error;
324 FS::upgrade_journal->set_done($journal);
328 ### ACL_download_report_data
329 if ( !FS::upgrade_journal->is_done('ACL_download_report_data') ) {
332 for my $group (@all_groups) {
333 next if $group->access_right('Download report data');
334 my $access_right = FS::access_right->new( {
335 'righttype' => 'FS::access_group',
336 'rightobjnum' => $group->groupnum,
337 'rightname' => 'Download report data',
339 my $error = $access_right->insert;
340 warn $error if $error;
343 FS::upgrade_journal->set_done('ACL_download_report_data');
356 L<FS::Record>, schema.html from the base documentation.