import torrus 1.0.9
[freeside.git] / FS / FS / cust_location.pm
1 package FS::cust_location;
2
3 use strict;
4 use base qw( FS::geocode_Mixin FS::Record );
5 use Locale::Country;
6 use FS::UID qw( dbh );
7 use FS::Record qw( qsearch ); #qsearchs );
8 use FS::prospect_main;
9 use FS::cust_main;
10 use FS::cust_main_county;
11
12 =head1 NAME
13
14 FS::cust_location - Object methods for cust_location records
15
16 =head1 SYNOPSIS
17
18   use FS::cust_location;
19
20   $record = new FS::cust_location \%hash;
21   $record = new FS::cust_location { 'column' => 'value' };
22
23   $error = $record->insert;
24
25   $error = $new_record->replace($old_record);
26
27   $error = $record->delete;
28
29   $error = $record->check;
30
31 =head1 DESCRIPTION
32
33 An FS::cust_location object represents a customer location.  FS::cust_location
34 inherits from FS::Record.  The following fields are currently supported:
35
36 =over 4
37
38 =item locationnum
39
40 primary key
41
42 =item custnum
43
44 custnum
45
46 =item address1
47
48 Address line one (required)
49
50 =item address2
51
52 Address line two (optional)
53
54 =item city
55
56 City
57
58 =item county
59
60 County (optional, see L<FS::cust_main_county>)
61
62 =item state
63
64 State (see L<FS::cust_main_county>)
65
66 =item zip
67
68 Zip
69
70 =item country
71
72 Country (see L<FS::cust_main_county>)
73
74 =item geocode
75
76 Geocode
77
78 =item disabled
79
80 Disabled flag; set to 'Y' to disable the location.
81
82 =back
83
84 =head1 METHODS
85
86 =over 4
87
88 =item new HASHREF
89
90 Creates a new location.  To add the location to the database, see L<"insert">.
91
92 Note that this stores the hash reference, not a distinct copy of the hash it
93 points to.  You can ask the object for a copy with the I<hash> method.
94
95 =cut
96
97 sub table { 'cust_location'; }
98
99 =item insert
100
101 Adds this record to the database.  If there is an error, returns the error,
102 otherwise returns false.
103
104 =item delete
105
106 Delete this record from the database.
107
108 =item replace OLD_RECORD
109
110 Replaces the OLD_RECORD with this one in the database.  If there is an error,
111 returns the error, otherwise returns false.
112
113 =item check
114
115 Checks all fields to make sure this is a valid location.  If there is
116 an error, returns the error, otherwise returns false.  Called by the insert
117 and replace methods.
118
119 =cut
120
121 #some false laziness w/cust_main, but since it should eventually lose these
122 #fields anyway...
123 sub check {
124   my $self = shift;
125
126   my $error = 
127     $self->ut_numbern('locationnum')
128     || $self->ut_foreign_keyn('prospectnum', 'prospect_main', 'prospectnum')
129     || $self->ut_foreign_keyn('custnum', 'cust_main', 'custnum')
130     || $self->ut_text('address1')
131     || $self->ut_textn('address2')
132     || $self->ut_text('city')
133     || $self->ut_textn('county')
134     || $self->ut_textn('state')
135     || $self->ut_country('country')
136     || $self->ut_zip('zip', $self->country)
137     || $self->ut_alphan('geocode')
138   ;
139   return $error if $error;
140
141   return "No prospect or customer!" unless $self->prospectnum || $self->custnum;
142   return "Prospect and customer!"       if $self->prospectnum && $self->custnum;
143
144   unless ( qsearch('cust_main_county', {
145     'country' => $self->country,
146     'state'   => '',
147    } ) ) {
148     return "Unknown state/county/country: ".
149       $self->state. "/". $self->county. "/". $self->country
150       unless qsearch('cust_main_county',{
151         'state'   => $self->state,
152         'county'  => $self->county,
153         'country' => $self->country,
154       } );
155   }
156
157   $self->SUPER::check;
158 }
159
160 =item country_full
161
162 Returns this locations's full country name
163
164 =cut
165
166 sub country_full {
167   my $self = shift;
168   code2country($self->country);
169 }
170
171 =item line
172
173 Synonym for location_label
174
175 =cut
176
177 sub line {
178   my $self = shift;
179   $self->location_label;
180 }
181
182 =item has_ship_address
183
184 Returns false since cust_location objects do not have a separate shipping
185 address.
186
187 =cut
188
189 sub has_ship_address {
190   '';
191 }
192
193 =item location_hash
194
195 Returns a list of key/value pairs, with the following keys: address1, address2,
196 city, county, state, zip, country, geocode.
197
198 =cut
199
200 =item move_to HASHREF
201
202 Takes a hashref with one or more cust_location fields.  Creates a duplicate 
203 of the existing location with all fields set to the values in the hashref.  
204 Moves all packages that use the existing location to the new one, then sets 
205 the "disabled" flag on the old location.  Returns nothing on success, an 
206 error message on error.
207
208 =cut
209
210 sub move_to {
211   my $old = shift;
212   my $hashref = shift;
213
214   local $SIG{HUP} = 'IGNORE';
215   local $SIG{INT} = 'IGNORE';
216   local $SIG{QUIT} = 'IGNORE';
217   local $SIG{TERM} = 'IGNORE';
218   local $SIG{TSTP} = 'IGNORE';
219   local $SIG{PIPE} = 'IGNORE';
220
221   my $oldAutoCommit = $FS::UID::AutoCommit;
222   local $FS::UID::AutoCommit = 0;
223   my $dbh = dbh;
224   my $error = '';
225
226   my $new = FS::cust_location->new({
227       $old->location_hash,
228       'custnum'     => $old->custnum,
229       'prospectnum' => $old->prospectnum,
230       %$hashref
231     });
232   $error = $new->insert;
233   if ( $error ) {
234     $dbh->rollback if $oldAutoCommit;
235     return "Error creating location: $error";
236   }
237
238   my @pkgs = qsearch('cust_pkg', { 
239       'locationnum' => $old->locationnum,
240       'cancel' => '' 
241     });
242   foreach my $cust_pkg (@pkgs) {
243     $error = $cust_pkg->change(
244       'locationnum' => $new->locationnum,
245       'keep_dates'  => 1
246     );
247     if ( $error and not ref($error) ) {
248       $dbh->rollback if $oldAutoCommit;
249       return "Error moving pkgnum ".$cust_pkg->pkgnum.": $error";
250     }
251   }
252
253   $old->disabled('Y');
254   $error = $old->replace;
255   if ( $error ) {
256     $dbh->rollback if $oldAutoCommit;
257     return "Error disabling old location: $error";
258   }
259
260   $dbh->commit if $oldAutoCommit;
261   return;
262 }
263
264 =back
265
266 =head1 BUGS
267
268 Not yet used for cust_main billing and shipping addresses.
269
270 =head1 SEE ALSO
271
272 L<FS::cust_main_county>, L<FS::cust_pkg>, L<FS::Record>,
273 schema.html from the base documentation.
274
275 =cut
276
277 1;
278