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