4 use base qw( FS::Record );
5 use FS::Record qw( qsearch qsearchs dbh );
10 use FS::contact_phone;
11 use FS::contact_email;
15 FS::contact - Object methods for contact records
21 $record = new FS::contact \%hash;
22 $record = new FS::contact { 'column' => 'value' };
24 $error = $record->insert;
26 $error = $new_record->replace($old_record);
28 $error = $record->delete;
30 $error = $record->check;
34 An FS::contact object represents an example. FS::contact inherits from
35 FS::Record. The following fields are currently supported:
84 Creates a new example. To add the example to the database, see L<"insert">.
86 Note that this stores the hash reference, not a distinct copy of the hash it
87 points to. You can ask the object for a copy with the I<hash> method.
91 # the new method can be inherited from FS::Record, if a table method is defined
93 sub table { 'contact'; }
97 Adds this record to the database. If there is an error, returns the error,
98 otherwise returns false.
105 local $SIG{INT} = 'IGNORE';
106 local $SIG{QUIT} = 'IGNORE';
107 local $SIG{TERM} = 'IGNORE';
108 local $SIG{TSTP} = 'IGNORE';
109 local $SIG{PIPE} = 'IGNORE';
111 my $oldAutoCommit = $FS::UID::AutoCommit;
112 local $FS::UID::AutoCommit = 0;
115 my $error = $self->SUPER::insert;
117 $dbh->rollback if $oldAutoCommit;
121 foreach my $pf ( grep { /^phonetypenum(\d+)$/ && $self->get($_) =~ /\S/ }
122 keys %{ $self->hashref } ) {
123 $pf =~ /^phonetypenum(\d+)$/ or die "wtf (daily, the)";
124 my $phonetypenum = $1;
126 my $contact_phone = new FS::contact_phone {
127 'contactnum' => $self->contactnum,
128 'phonetypenum' => $phonetypenum,
129 _parse_phonestring( $self->get($pf) ),
131 $error = $contact_phone->insert;
133 $dbh->rollback if $oldAutoCommit;
138 if ( $self->get('emailaddress') =~ /\S/ ) {
140 foreach my $email ( split(/\s*,\s*/, $self->get('emailaddress') ) ) {
142 my $contact_email = new FS::contact_email {
143 'contactnum' => $self->contactnum,
144 'emailaddress' => $email,
146 $error = $contact_email->insert;
148 $dbh->rollback if $oldAutoCommit;
156 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
164 Delete this record from the database.
168 # the delete method can be inherited from FS::Record
173 local $SIG{HUP} = 'IGNORE';
174 local $SIG{INT} = 'IGNORE';
175 local $SIG{QUIT} = 'IGNORE';
176 local $SIG{TERM} = 'IGNORE';
177 local $SIG{TSTP} = 'IGNORE';
178 local $SIG{PIPE} = 'IGNORE';
180 my $oldAutoCommit = $FS::UID::AutoCommit;
181 local $FS::UID::AutoCommit = 0;
184 foreach my $object ( $self->contact_phone, $self->contact_email ) {
185 my $error = $object->delete;
187 $dbh->rollback if $oldAutoCommit;
192 my $error = $self->SUPER::delete;
194 $dbh->rollback if $oldAutoCommit;
198 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
203 =item replace OLD_RECORD
205 Replaces the OLD_RECORD with this one in the database. If there is an error,
206 returns the error, otherwise returns false.
213 local $SIG{INT} = 'IGNORE';
214 local $SIG{QUIT} = 'IGNORE';
215 local $SIG{TERM} = 'IGNORE';
216 local $SIG{TSTP} = 'IGNORE';
217 local $SIG{PIPE} = 'IGNORE';
219 my $oldAutoCommit = $FS::UID::AutoCommit;
220 local $FS::UID::AutoCommit = 0;
223 my $error = $self->SUPER::replace(@_);
225 $dbh->rollback if $oldAutoCommit;
229 foreach my $pf ( grep { /^phonetypenum(\d+)$/ && $self->get($_) }
230 keys %{ $self->hashref } ) {
231 $pf =~ /^phonetypenum(\d+)$/ or die "wtf (daily, the)";
232 my $phonetypenum = $1;
234 my %cp = ( 'contactnum' => $self->contactnum,
235 'phonetypenum' => $phonetypenum,
237 my $contact_phone = qsearchs('contact_phone', \%cp)
238 || new FS::contact_phone \%cp;
240 my %cpd = _parse_phonestring( $self->get($pf) );
241 $contact_phone->set( $_ => $cpd{$_} ) foreach keys %cpd;
243 my $method = $contact_phone->contactphonenum ? 'replace' : 'insert';
245 $error = $contact_phone->$method;
247 $dbh->rollback if $oldAutoCommit;
252 if ( defined($self->get('emailaddress')) ) {
254 #ineffecient but whatever, how many email addresses can there be?
256 foreach my $contact_email ( $self->contact_email ) {
257 my $error = $contact_email->delete;
259 $dbh->rollback if $oldAutoCommit;
264 foreach my $email ( split(/\s*,\s*/, $self->get('emailaddress') ) ) {
266 my $contact_email = new FS::contact_email {
267 'contactnum' => $self->contactnum,
268 'emailaddress' => $email,
270 $error = $contact_email->insert;
272 $dbh->rollback if $oldAutoCommit;
280 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
286 #i probably belong in contact_phone.pm
287 sub _parse_phonestring {
290 my($countrycode, $extension) = ('1', '');
293 if ( $value =~ s/^\s*\+\s*(\d+)// ) {
299 if ( $value =~ s/\s*(ext|x)\s*(\d+)\s*$//i ) {
303 ( 'countrycode' => $countrycode,
304 'phonenum' => $value,
305 'extension' => $extension,
311 Checks all fields to make sure this is a valid example. If there is
312 an error, returns the error, otherwise returns false. Called by the insert
317 # the check method should currently be supplied - FS::Record contains some
318 # data checking routines
324 $self->ut_numbern('contactnum')
325 || $self->ut_foreign_keyn('prospectnum', 'prospect_main', 'prospectnum')
326 || $self->ut_foreign_keyn('custnum', 'cust_main', 'custnum')
327 || $self->ut_foreign_keyn('locationnum', 'cust_location', 'locationnum')
328 || $self->ut_foreign_keyn('classnum', 'contact_class', 'classnum')
329 || $self->ut_textn('last')
330 || $self->ut_textn('first')
331 || $self->ut_textn('title')
332 || $self->ut_textn('comment')
333 || $self->ut_enum('disabled', [ '', 'Y' ])
335 return $error if $error;
337 return "No prospect or customer!" unless $self->prospectnum || $self->custnum;
338 return "Prospect and customer!" if $self->prospectnum && $self->custnum;
340 return "One of first name, last name, or title must have a value"
341 if ! grep $self->$_(), qw( first last title);
348 my $data = $self->first. ' '. $self->last;
349 $data .= ', '. $self->title
351 $data .= ' ('. $self->comment. ')'
358 return '' unless $self->locationnum;
359 qsearchs('cust_location', { 'locationnum' => $self->locationnum } );
364 return '' unless $self->classnum;
365 qsearchs('contact_class', { 'classnum' => $self->classnum } );
368 sub contact_classname {
370 my $contact_class = $self->contact_class or return '';
371 $contact_class->classname;
376 qsearch('contact_phone', { 'contactnum' => $self->contactnum } );
381 qsearch('contact_email', { 'contactnum' => $self->contactnum } );
390 L<FS::Record>, schema.html from the base documentation.