fix 'Can't call method "setup" on an undefined value' error when using into rates...
[freeside.git] / FS / FS / rate_region.pm
1 package FS::rate_region;
2
3 use strict;
4 use vars qw( @ISA );
5 use FS::Record qw( qsearch qsearchs dbh );
6 use FS::rate_prefix;
7 use FS::rate_detail;
8
9 @ISA = qw(FS::Record);
10
11 =head1 NAME
12
13 FS::rate_region - Object methods for rate_region records
14
15 =head1 SYNOPSIS
16
17   use FS::rate_region;
18
19   $record = new FS::rate_region \%hash;
20   $record = new FS::rate_region { '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::rate_region object represents an call rating region.  FS::rate_region
33 inherits from FS::Record.  The following fields are currently supported:
34
35 =over 4
36
37 =item regionnum - primary key
38
39 =item regionname
40
41 =back
42
43 =head1 METHODS
44
45 =over 4
46
47 =item new HASHREF
48
49 Creates a new region.  To add the region to the database, see L<"insert">.
50
51 Note that this stores the hash reference, not a distinct copy of the hash it
52 points to.  You can ask the object for a copy with the I<hash> method.
53
54 =cut
55
56 # the new method can be inherited from FS::Record, if a table method is defined
57
58 sub table { 'rate_region'; }
59
60 =item insert [ , OPTION => VALUE ... ]
61
62 Adds this record to the database.  If there is an error, returns the error,
63 otherwise returns false.
64
65 Currently available options are: I<rate_prefix> and I<dest_detail>
66
67 If I<rate_prefix> is set to an array reference of FS::rate_prefix objects, the
68 objects will have their regionnum field set and will be inserted after this
69 record.
70
71 If I<dest_detail> is set to an array reference of FS::rate_detail objects, the
72 objects will have their dest_regionnum field set and will be inserted after
73 this record.
74
75
76 =cut
77
78 sub insert {
79   my $self = shift;
80   my %options = @_;
81
82   local $SIG{HUP} = 'IGNORE';
83   local $SIG{INT} = 'IGNORE';
84   local $SIG{QUIT} = 'IGNORE';
85   local $SIG{TERM} = 'IGNORE';
86   local $SIG{TSTP} = 'IGNORE';
87   local $SIG{PIPE} = 'IGNORE';
88
89   my $oldAutoCommit = $FS::UID::AutoCommit;
90   local $FS::UID::AutoCommit = 0;
91   my $dbh = dbh;
92
93   my $error = $self->check;
94   return $error if $error;
95
96   $error = $self->SUPER::insert;
97   if ( $error ) {
98     $dbh->rollback if $oldAutoCommit;
99     return $error;
100   }
101
102   if ( $options{'rate_prefix'} ) {
103     foreach my $rate_prefix ( @{$options{'rate_prefix'}} ) {
104       $rate_prefix->regionnum($self->regionnum);
105       $error = $rate_prefix->insert;
106       if ( $error ) {
107         $dbh->rollback if $oldAutoCommit;
108         return $error;
109       }
110     }
111   }
112
113   if ( $options{'dest_detail'} ) {
114     foreach my $rate_detail ( @{$options{'dest_detail'}} ) {
115       $rate_detail->dest_regionnum($self->regionnum);
116       $error = $rate_detail->insert;
117       if ( $error ) {
118         $dbh->rollback if $oldAutoCommit;
119         return $error;
120       }
121     }
122   }
123
124   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
125
126   '';
127 }
128
129 =item delete
130
131 Delete this record from the database.
132
133 =cut
134
135 # the delete method can be inherited from FS::Record
136
137 =item replace OLD_RECORD [ , OPTION => VALUE ... ]
138
139 Replaces the OLD_RECORD with this one in the database.  If there is an error,
140 returns the error, otherwise returns false.
141
142 Currently available options are: I<rate_prefix> and I<dest_detail>
143
144 If I<rate_prefix> is set to an array reference of FS::rate_prefix objects, the
145 objects will have their regionnum field set and will be inserted after this
146 record.  Any existing rate_prefix records associated with this record will be
147 deleted.
148
149 If I<dest_detail> is set to an array reference of FS::rate_detail objects, the
150 objects will have their dest_regionnum field set and will be inserted after
151 this record.  Any existing rate_detail records associated with this record will
152 be deleted.
153
154 =cut
155
156 sub replace {
157   my ($new, $old) = (shift, shift);
158   my %options = @_;
159
160   local $SIG{HUP} = 'IGNORE';
161   local $SIG{INT} = 'IGNORE';
162   local $SIG{QUIT} = 'IGNORE';
163   local $SIG{TERM} = 'IGNORE';
164   local $SIG{TSTP} = 'IGNORE';
165   local $SIG{PIPE} = 'IGNORE';
166
167   my $oldAutoCommit = $FS::UID::AutoCommit;
168   local $FS::UID::AutoCommit = 0;
169   my $dbh = dbh;
170
171   my @old_rate_prefix = ();
172   @old_rate_prefix = $old->rate_prefix if $options{'rate_prefix'};
173   my @old_dest_detail = ();
174   @old_dest_detail = $old->dest_detail if $options{'dest_detail'};
175
176   my $error = $new->SUPER::replace($old);
177   if ($error) {
178     $dbh->rollback if $oldAutoCommit;
179     return $error;
180   }
181
182   foreach my $old_rate_prefix ( @old_rate_prefix ) {
183     my $error = $old_rate_prefix->delete;
184     if ($error) {
185       $dbh->rollback if $oldAutoCommit;
186       return $error;
187     }
188   }
189   foreach my $old_dest_detail ( @old_dest_detail ) {
190     my $error = $old_dest_detail->delete;
191     if ($error) {
192       $dbh->rollback if $oldAutoCommit;
193       return $error;
194     }
195   }
196
197   foreach my $rate_prefix ( @{$options{'rate_prefix'}} ) {
198     $rate_prefix->regionnum($new->regionnum);
199     $error = $rate_prefix->insert;
200     if ( $error ) {
201       $dbh->rollback if $oldAutoCommit;
202       return $error;
203     }
204   }
205   foreach my $rate_detail ( @{$options{'dest_detail'}} ) {
206     $rate_detail->dest_regionnum($new->regionnum);
207     $error = $rate_detail->insert;
208     if ( $error ) {
209       $dbh->rollback if $oldAutoCommit;
210       return $error;
211     }
212   }
213
214   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
215   '';
216
217 }
218
219 =item check
220
221 Checks all fields to make sure this is a valid region.  If there is
222 an error, returns the error, otherwise returns false.  Called by the insert
223 and replace methods.
224
225 =cut
226
227 # the check method should currently be supplied - FS::Record contains some
228 # data checking routines
229
230 sub check {
231   my $self = shift;
232
233   my $error =
234        $self->ut_numbern('regionnum')
235     || $self->ut_text('regionname')
236   ;
237   return $error if $error;
238
239   $self->SUPER::check;
240 }
241
242 =item rate_prefix
243
244 Returns all prefixes (see L<FS::rate_prefix>) for this region.
245
246 =cut
247
248 sub rate_prefix {
249   my $self = shift;
250
251   sort {    $a->countrycode cmp $b->countrycode
252          or $a->npa         cmp $b->npa
253          or $a->nxx         cmp $b->nxx
254        }
255        qsearch( 'rate_prefix', { 'regionnum' => $self->regionnum } );
256 }
257
258 =item dest_detail
259
260 Returns all rate details (see L<FS::rate_detail>) for this region as a
261 destionation.
262
263 =cut
264
265 sub dest_detail {
266   my $self = shift;
267   qsearch( 'rate_detail', { 'dest_regionnum' => $self->regionnum, } );
268 }
269
270 =item prefixes_short
271
272 Returns a string representing all the prefixes for this region.
273
274 =cut
275
276 sub prefixes_short {
277   my $self = shift;
278
279   my $countrycode = '';
280   my $out = '';
281
282   foreach my $rate_prefix ( $self->rate_prefix ) {
283     if ( $countrycode ne $rate_prefix->countrycode ) {
284       $out =~ s/, $//;
285       $countrycode = $rate_prefix->countrycode;
286       $out.= " +$countrycode ";
287     }
288     my $npa = $rate_prefix->npa;
289     if ( $countrycode eq '1' ) {
290       #$out .= '('. substr( $npa, 0, 3 ). ')';
291       $out .= substr( $npa, 0, 3 );
292       $out .= ' '. substr( $npa, 3 ) if length($npa) > 3;
293     } else {
294       $out .= $rate_prefix->npa;
295     }
296     $out .= '-'. $rate_prefix->nxx if $rate_prefix->nxx;
297     $out .= ', ';
298   }
299   $out =~ s/, $//;
300
301   $out;
302 }
303
304 =back
305
306 =head1 BUGS
307
308 =head1 SEE ALSO
309
310 L<FS::Record>, schema.html from the base documentation.
311
312 =cut
313
314 1;
315