477 report: improve browse-edit UI
[freeside.git] / FS / FS / deploy_zone.pm
1 package FS::deploy_zone;
2
3 use strict;
4 use base qw( FS::o2m_Common FS::Record );
5 use FS::Record qw( qsearch qsearchs dbh );
6
7 =head1 NAME
8
9 FS::deploy_zone - Object methods for deploy_zone records
10
11 =head1 SYNOPSIS
12
13   use FS::deploy_zone;
14
15   $record = new FS::deploy_zone \%hash;
16   $record = new FS::deploy_zone { 'column' => 'value' };
17
18   $error = $record->insert;
19
20   $error = $new_record->replace($old_record);
21
22   $error = $record->delete;
23
24   $error = $record->check;
25
26 =head1 DESCRIPTION
27
28 An FS::deploy_zone object represents a geographic zone where a certain kind
29 of service is available.  Currently we store this information to generate
30 the FCC Form 477 deployment reports, but it may find other uses later.
31
32 FS::deploy_zone inherits from FS::Record.  The following fields are currently
33 supported:
34
35 =over 4
36
37 =item zonenum
38
39 primary key
40
41 =item description
42
43 Optional text describing the zone.
44
45 =item agentnum
46
47 The agent that serves this zone.
48
49 =item dbaname
50
51 The name under which service is marketed in this zone.  If null, will 
52 default to the agent name.
53
54 =item zonetype
55
56 The way the zone geography is defined: "B" for a list of census blocks
57 (used by the FCC for fixed broadband service), "P" for a polygon (for 
58 mobile services).  See L<FS::deploy_zone_block> and L<FS::deploy_zone_vertex>.
59
60 =item technology
61
62 The FCC technology code for the type of service available.
63
64 =item spectrum
65
66 For mobile service zones, the FCC code for the RF band.
67
68 =item servicetype
69
70 "broadband" or "voice"
71
72 =item adv_speed_up
73
74 For broadband, the advertised upstream bandwidth in the zone.  If multiple
75 speed tiers are advertised, use the highest.
76
77 =item adv_speed_down
78
79 For broadband, the advertised downstream bandwidth in the zone.
80
81 =item cir_speed_up
82
83 For broadband, the contractually guaranteed upstream bandwidth, if that type
84 of service is sold.
85
86 =item cir_speed_down
87
88 For broadband, the contractually guaranteed downstream bandwidth, if that 
89 type of service is sold.
90
91 =item is_consumer
92
93 'Y' if this service is sold for consumer/household use.
94
95 =item is_business
96
97 'Y' if this service is sold to business or institutional use.  Not mutually
98 exclusive with is_consumer.
99
100 =item active_date
101
102 The date this zone became active.
103
104 =item expire_date
105
106 The date this zone became inactive, if any.
107
108 =back
109
110 =head1 METHODS
111
112 =over 4
113
114 =item new HASHREF
115
116 Creates a new zone.  To add the zone to the database, see L<"insert">.
117
118 =cut
119
120 # the new method can be inherited from FS::Record, if a table method is defined
121
122 sub table { 'deploy_zone'; }
123
124 =item insert ELEMENTS
125
126 Adds this record to the database.  If there is an error, returns the error,
127 otherwise returns false.
128
129 =cut
130
131 # the insert method can be inherited from FS::Record
132
133 =item delete
134
135 Delete this record from the database.
136
137 =cut
138
139 sub delete {
140   my $oldAutoCommit = $FS::UID::AutoCommit;
141   local $FS::UID::AutoCommit = 0;
142   # clean up linked records
143   my $self = shift;
144   my $error = $self->process_o2m(
145     'table'   => $self->element_table,
146     'num_col' => 'zonenum',
147     'fields'  => 'zonenum',
148     'params'  => {},
149   ) || $self->SUPER::delete(@_);
150   
151   if ($error) {
152     dbh->rollback if $oldAutoCommit;
153     return $error;
154   }
155   '';
156 }
157
158 =item replace OLD_RECORD
159
160 Replaces the OLD_RECORD with this one in the database.  If there is an error,
161 returns the error, otherwise returns false.
162
163 =cut
164
165 # the replace method can be inherited from FS::Record
166
167 =item check
168
169 Checks all fields to make sure this is a valid zone record.  If there is
170 an error, returns the error, otherwise returns false.  Called by the insert
171 and replace methods.
172
173 =cut
174
175 sub check {
176   my $self = shift;
177
178   my $error = 
179     $self->ut_numbern('zonenum')
180     || $self->ut_textn('description')
181     || $self->ut_number('agentnum')
182     || $self->ut_foreign_key('agentnum', 'agent', 'agentnum')
183     || $self->ut_alphan('dbaname')
184     || $self->ut_enum('zonetype', [ 'B', 'P' ])
185     || $self->ut_number('technology')
186     || $self->ut_numbern('spectrum')
187     || $self->ut_enum('servicetype', [ 'broadband', 'voice' ])
188     || $self->ut_decimaln('adv_speed_up', 3)
189     || $self->ut_decimaln('adv_speed_down', 3)
190     || $self->ut_decimaln('cir_speed_up', 3)
191     || $self->ut_decimaln('cir_speed_down', 3)
192     || $self->ut_flag('is_consumer')
193     || $self->ut_flag('is_business')
194     || $self->ut_numbern('active_date')
195     || $self->ut_numbern('expire_date')
196   ;
197   return $error if $error;
198
199   foreach(qw(adv_speed_down adv_speed_up cir_speed_down cir_speed_up)) {
200     if (!$self->get($_)) {
201       $self->set($_, 0);
202     }
203   }
204   if (!$self->get('active_date')) {
205     $self->set('active_date', time);
206   }
207
208   $self->SUPER::check;
209 }
210
211 =item element_table
212
213 Returns the name of the table that contains the zone's elements (blocks or
214 vertices).
215
216 =cut
217
218 sub element_table {
219   my $self = shift;
220   if ($self->zonetype eq 'B') {
221     return 'deploy_zone_block';
222   } elsif ( $self->zonetype eq 'P') {
223     return 'deploy_zone_vertex';
224   } else {
225     die 'unknown zonetype';
226   }
227 }
228
229 =back
230
231 =head1 BUGS
232
233 =head1 SEE ALSO
234
235 L<FS::Record>
236
237 =cut
238
239 1;
240