3e018ffeee287c436a62e68d45b7d063a9b392bb
[freeside.git] / FS / FS / access_right.pm
1 package FS::access_right;
2
3 use strict;
4 use vars qw( @ISA );
5 use Tie::IxHash;
6 use FS::Record qw( qsearch qsearchs );
7 use FS::upgrade_journal;
8
9 @ISA = qw(FS::Record);
10
11 =head1 NAME
12
13 FS::access_right - Object methods for access_right records
14
15 =head1 SYNOPSIS
16
17   use FS::access_right;
18
19   $record = new FS::access_right \%hash;
20   $record = new FS::access_right { 'column' => 'value' };
21
22   $error = $record->insert;
23
24   $error = $new_record->replace($old_record);
25
26   $error = $record->delete;
27
28   $error = $record->check;
29
30 =head1 DESCRIPTION
31
32 An FS::access_right object represents a granted access right.  FS::access_right
33 inherits from FS::Record.  The following fields are currently supported:
34
35 =over 4
36
37 =item rightnum - primary key
38
39 =item righttype - 
40
41 =item rightobjnum - 
42
43 =item rightname - 
44
45
46 =back
47
48 =head1 METHODS
49
50 =over 4
51
52 =item new HASHREF
53
54 Creates a new right.  To add the right to the database, see L<"insert">.
55
56 Note that this stores the hash reference, not a distinct copy of the hash it
57 points to.  You can ask the object for a copy with the I<hash> method.
58
59 =cut
60
61 # the new method can be inherited from FS::Record, if a table method is defined
62
63 sub table { 'access_right'; }
64
65 =item insert
66
67 Adds this record to the database.  If there is an error, returns the error,
68 otherwise returns false.
69
70 =cut
71
72 # the insert method can be inherited from FS::Record
73
74 =item delete
75
76 Delete this record from the database.
77
78 =cut
79
80 # the delete method can be inherited from FS::Record
81
82 =item replace OLD_RECORD
83
84 Replaces the OLD_RECORD with this one in the database.  If there is an error,
85 returns the error, otherwise returns false.
86
87 =cut
88
89 # the replace method can be inherited from FS::Record
90
91 =item check
92
93 Checks all fields to make sure this is a valid right.  If there is
94 an error, returns the error, otherwise returns false.  Called by the insert
95 and replace methods.
96
97 =cut
98
99 # the check method should currently be supplied - FS::Record contains some
100 # data checking routines
101
102 sub check {
103   my $self = shift;
104
105   my $error = 
106     $self->ut_numbern('rightnum')
107     || $self->ut_text('righttype')
108     || $self->ut_text('rightobjnum')
109     || $self->ut_text('rightname')
110   ;
111   return $error if $error;
112
113   $self->SUPER::check;
114 }
115
116 # _upgrade_data
117 #
118 # Used by FS::Upgrade to migrate to a new database.
119
120 sub _upgrade_data { # class method
121   my ($class, %opts) = @_;
122
123   my @unmigrated = ( qsearch( 'access_right',
124                               { 'righttype'=>'FS::access_group',
125                                 'rightname'=>'Engineering configuration',
126                               }
127                             ), 
128                      qsearch( 'access_right',
129                               { 'righttype'=>'FS::access_group',
130                                 'rightname'=>'Engineering global configuration',
131                               }
132                             )
133                    ); 
134   foreach ( @unmigrated ) {
135     my $rightname = $_->rightname;
136     $rightname =~ s/Engineering/Dialup/;
137     $_->rightname($rightname);
138     my $error = $_->replace;
139     die "Failed to update access right: $error"
140       if $error;
141     my $broadband = new FS::access_right { $_->hash };
142     $rightname =~ s/Dialup/Broadband/;
143     $broadband->rightnum('');
144     $broadband->rightname($rightname);
145     $error = $broadband->insert;
146     die "Failed to insert access right: $error"
147       if $error;
148   }
149
150   my %migrate = (
151     'Post payment'    => [ 'Post check payment', 'Post cash payment' ],
152     'Process payment' => [ 'Process credit card payment', 'Process Echeck payment' ],
153     'Post refund'     => [ 'Post check refund', 'Post cash refund' ],
154     'Refund payment'  => [ 'Refund credit card payment', 'Refund Echeck payment' ],
155   );
156
157   foreach my $oldright (keys %migrate) {
158     my @old = qsearch('access_right', { 'righttype'=>'FS::access_group',
159                                         'rightname'=>$oldright,
160                                       }
161                      );
162
163     foreach my $old ( @old ) {
164
165       foreach my $newright ( @{ $migrate{$oldright} } ) {
166         my %hash = (
167           'righttype'   => 'FS::access_group',
168           'rightobjnum' => $old->rightobjnum,
169           'rightname'   => $newright,
170         );
171         next if qsearchs('access_right', \%hash);
172         my $access_right = new FS::access_right \%hash;
173         my $error = $access_right->insert;
174         die $error if $error;
175       }
176
177       #after the WEST stuff is sorted, etc.
178       #my $error = $old->delete;
179       #die $error if $error;
180
181     }
182
183   }
184
185   my @all_groups = qsearch('access_group', {});
186
187   tie my %onetime, 'Tie::IxHash',
188     'List customers'                      => 'List all customers',
189     'List all customers'                  => 'Advanced customer search',
190     'List packages'                       => 'Summarize packages',
191     'Post payment'                        => 'Backdate payment',
192     'Cancel customer package immediately' => 'Un-cancel customer package',
193     'Suspend customer package'            => 'Suspend customer',
194     'Unsuspend customer package'          => 'Unsuspend customer',
195     'Post credit'                         => 'Credit line items',
196     #'View customer tax exemptions'        => 'Edit customer tax exemptions',
197     'Edit customer'                       => 'Edit customer tax exemptions',
198     'Edit package definitions'            => 'Bulk edit package definitions',
199
200     'List services'    => [ 'Services: Accounts',
201                             'Services: Domains',
202                             'Services: Certificates',
203                             'Services: Mail forwards',
204                             'Services: Virtual hosting services',
205                             'Services: Wireless broadband services',
206                             'Services: DSLs',
207                             'Services: Dish services',
208                             'Services: Hardware',
209                             'Services: Phone numbers',
210                             'Services: PBXs',
211                             'Services: Ports',
212                             'Services: Mailing lists',
213                             'Services: External services',
214                           ],
215
216     'Services: Accounts' => 'Services: Accounts: Advanced search',
217     'Services: Wireless broadband services' => 'Services: Wireless broadband services: Advanced search',
218     'Services: Hardware' => 'Services: Hardware: Advanced search',
219     'Services: Phone numbers' => 'Services: Phone numbers: Advanced search',
220
221     'List rating data' => [ 'Usage: RADIUS sessions',
222                             'Usage: Call Detail Records (CDRs)',
223                             'Usage: Unrateable CDRs',
224                           ],
225
226     'Edit customer' => [ 'Edit customer basics',
227                          'Edit customer addresses',
228                          'Edit customer contacts',
229                        ],
230
231     'Provision customer service' => [ 'Edit password' ],
232
233     'Financial reports' => [ 'Employees: Commission Report',
234                              'Employees: Audit Report',
235                            ],
236     'Services: Accounts' => 'Services: Cable Subscribers',
237 ;
238
239   foreach my $old_acl ( keys %onetime ) {
240
241     my @new_acl = ref($onetime{$old_acl})
242                     ? @{ $onetime{$old_acl} }
243                     :  ( $onetime{$old_acl} );
244
245     foreach my $new_acl ( @new_acl ) {
246
247       ( my $journal = 'ACL_'.lc($new_acl) ) =~ s/\W/_/g;
248       next if FS::upgrade_journal->is_done($journal);
249
250       # grant $new_acl to all groups who have $old_acl
251       for my $group (@all_groups) {
252         next unless $group->access_right($old_acl);
253         next if     $group->access_right($new_acl);
254         my $access_right = FS::access_right->new( {
255             'righttype'   => 'FS::access_group',
256             'rightobjnum' => $group->groupnum,
257             'rightname'   => $new_acl,
258         } );
259         my $error = $access_right->insert;
260         die $error if $error;
261       }
262     
263       FS::upgrade_journal->set_done($journal);
264
265     }
266
267   }
268
269   ### ACL_download_report_data
270   if ( !FS::upgrade_journal->is_done('ACL_download_report_data') ) {
271
272     # grant to everyone
273     for my $group (@all_groups) {
274       my $access_right = FS::access_right->new( {
275           'righttype'   => 'FS::access_group',
276           'rightobjnum' => $group->groupnum,
277           'rightname'   => 'Download report data',
278       } );
279       my $error = $access_right->insert;
280       warn $error if $error;
281     }
282
283     FS::upgrade_journal->set_done('ACL_download_report_data');
284   }
285
286   '';
287
288 }
289
290 =back
291
292 =head1 BUGS
293
294 =head1 SEE ALSO
295
296 L<FS::Record>, schema.html from the base documentation.
297
298 =cut
299
300 1;
301