2 use base qw( FS::cust_main_Mixin FS::Record );
5 use FS::Record qw( dbh );
10 FS::cust_msg - Object methods for cust_msg records
16 $record = new FS::cust_msg \%hash;
17 $record = new FS::cust_msg { 'column' => 'value' };
19 $error = $record->insert;
21 $error = $record->check;
25 An FS::cust_msg object represents an email message generated by Freeside.
26 FS::cust_msg inherits from FS::Record. The following fields are currently
31 =item custmsgnum - primary key
33 =item custnum - customer number
35 =item msgnum - template number
37 =item msgtype - the message type
39 =item _date - the time the message was sent
41 =item env_from - envelope From address
43 =item env_to - envelope To addresses, including Bcc, separated by newlines
45 =item header - message header
47 =item body - message body (as a complete MIME document)
49 =item preview - HTML fragment to show as a preview of the message
51 =item error - Email::Sender error message (or null for success)
53 =item status - "prepared", "sent", or "failed"
67 # the new method can be inherited from FS::Record, if a table method is defined
69 sub table { 'cust_msg'; }
71 sub nohistory_fields { ('header', 'body'); }
72 # history is kind of pointless on this table
74 our @statuses = qw( prepared sent failed );
78 Adds this record to the database. If there is an error, returns the error
79 and emits a warning; otherwise returns false.
84 # warn of all errors here; failing to insert/update one of these should
85 # cause a warning at worst
87 my $error = $self->SUPER::insert;
88 warn "[cust_msg] error logging message status: $error\n" if $error;
94 Delete this record from the database. There's no reason to do this.
100 warn "[cust_msg] log entry deleted\n";
101 return $self->SUPER::delete;
104 =item replace OLD_RECORD
106 Replaces the OLD_RECORD with this one in the database. If there is an error,
107 returns the error and emits a warning, otherwise returns false.
113 my $error = $self->SUPER::replace(@_);
114 warn "[cust_msg] error logging message status: $error\n" if $error;
120 Checks all fields to make sure this is a valid example. If there is
121 an error, returns the error, otherwise returns false. Called by the insert
126 # the check method should currently be supplied - FS::Record contains some
127 # data checking routines
133 $self->ut_numbern('custmsgnum')
134 || $self->ut_numbern('custnum')
135 || $self->ut_foreign_keyn('custnum', 'cust_main', 'custnum')
136 || $self->ut_numbern('msgnum')
137 || $self->ut_foreign_keyn('msgnum', 'msg_template', 'msgnum')
138 || $self->ut_numbern('_date')
139 || $self->ut_textn('env_from')
140 || $self->ut_textn('env_to')
141 || $self->ut_anything('header')
142 || $self->ut_anything('body')
143 || $self->ut_anything('preview')
144 || $self->ut_enum('status', \@statuses)
145 || $self->ut_textn('error')
146 || $self->ut_enum('msgtype', [ '',
153 return $error if $error;
160 Sends the message through its parent L<FS::msg_template>. Returns an error
161 message on error, or an empty string.
167 # it's still allowed to have cust_msgs without message templates, but only
169 my $msg_template = $self->msg_template || 'FS::msg_template::email';
170 $msg_template->send_prepared($self);
175 Returns the complete message as a L<MIME::Entity>.
177 XXX this only works if the message in fact contains a MIME entity. Messages
178 created by external APIs may not look like that.
182 Returns a list of the MIME parts contained in the message, as L<MIME::Entity>
189 if ( !exists($self->{entity}) ) {
190 my $parser = MIME::Parser->new;
191 my $output_dir = "$FS::UID::cache_dir/cache.$FS::UID::datasrc/mimeparts";
192 mkdir($output_dir) unless -d $output_dir;
193 $parser->output_under($output_dir);
195 $parser->parse_data( $self->header . "\n" . $self->body );
202 # return only the parts with bodies, not the multipart containers
203 grep { $_->bodyhandle } $self->entity->parts_DFS;
212 =item process_send CUSTMSGNUM
214 Given a C<cust_msg.custmsgnum> value, sends the message. It must already
215 have been prepared (via L<FS::msg_template/prepare>).
220 my $custmsgnum = shift;
221 my $cust_msg = FS::cust_msg->by_key($custmsgnum)
222 or die "cust_msg #$custmsgnum not found";
223 my $error = $cust_msg->send;
224 die $error if $error;
227 sub _upgrade_schema {
228 my ($class, %opts) = @_;
231 DELETE FROM cust_msg WHERE NOT EXISTS
232 ( SELECT 1 FROM cust_main WHERE cust_main.custnum = cust_msg.custnum )
235 my $sth = dbh->prepare($sql) or die dbh->errstr;
236 $sth->execute or die $sth->errstr;
245 L<FS::msg_template>, L<FS::cust_main>, L<FS::Record>.