new 477 report: deployment info, combined browse-edit UI, #24047
[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 =back
101
102 =head1 METHODS
103
104 =over 4
105
106 =item new HASHREF
107
108 Creates a new zone.  To add the zone to the database, see L<"insert">.
109
110 =cut
111
112 # the new method can be inherited from FS::Record, if a table method is defined
113
114 sub table { 'deploy_zone'; }
115
116 =item insert ELEMENTS
117
118 Adds this record to the database.  If there is an error, returns the error,
119 otherwise returns false.
120
121 =cut
122
123 # the insert method can be inherited from FS::Record
124
125 =item delete
126
127 Delete this record from the database.
128
129 =cut
130
131 sub delete {
132   my $oldAutoCommit = $FS::UID::AutoCommit;
133   local $FS::UID::AutoCommit = 0;
134   # clean up linked records
135   my $self = shift;
136   my $error = $self->process_o2m(
137     'table'   => $self->element_table,
138     'num_col' => 'zonenum',
139     'fields'  => 'zonenum',
140     'params'  => {},
141   ) || $self->SUPER::delete(@_);
142   
143   if ($error) {
144     dbh->rollback if $oldAutoCommit;
145     return $error;
146   }
147   '';
148 }
149
150 =item replace OLD_RECORD
151
152 Replaces the OLD_RECORD with this one in the database.  If there is an error,
153 returns the error, otherwise returns false.
154
155 =cut
156
157 # the replace method can be inherited from FS::Record
158
159 =item check
160
161 Checks all fields to make sure this is a valid zone record.  If there is
162 an error, returns the error, otherwise returns false.  Called by the insert
163 and replace methods.
164
165 =cut
166
167 sub check {
168   my $self = shift;
169
170   my $error = 
171     $self->ut_numbern('zonenum')
172     || $self->ut_textn('description')
173     || $self->ut_number('agentnum')
174     || $self->ut_foreign_key('agentnum', 'agent', 'agentnum')
175     || $self->ut_alphan('dbaname')
176     || $self->ut_enum('zonetype', [ 'B', 'P' ])
177     || $self->ut_number('technology')
178     || $self->ut_numbern('spectrum')
179     || $self->ut_enum('servicetype', [ 'broadband', 'voice' ])
180     || $self->ut_decimaln('adv_speed_up', 3)
181     || $self->ut_decimaln('adv_speed_down', 3)
182     || $self->ut_decimaln('cir_speed_up', 3)
183     || $self->ut_decimaln('cir_speed_down', 3)
184     || $self->ut_flag('is_consumer')
185     || $self->ut_flag('is_business')
186   ;
187   return $error if $error;
188
189   $self->SUPER::check;
190 }
191
192 =item element_table
193
194 Returns the name of the table that contains the zone's elements (blocks or
195 vertices).
196
197 =cut
198
199 sub element_table {
200   my $self = shift;
201   if ($self->zonetype eq 'B') {
202     return 'deploy_zone_block';
203   } elsif ( $self->zonetype eq 'P') {
204     return 'deploy_zone_vertex';
205   } else {
206     die 'unknown zonetype';
207   }
208 }
209
210 =back
211
212 =head1 BUGS
213
214 =head1 SEE ALSO
215
216 L<FS::Record>
217
218 =cut
219
220 1;
221