ACL for hardware class config, RT#85057
[freeside.git] / FS / FS / cust_msg.pm
index 8d57a54..2f78f39 100644 (file)
@@ -1,9 +1,9 @@
 package FS::cust_msg;
+use base qw( FS::cust_main_Mixin FS::Record );
 
 use strict;
-use base qw( FS::cust_main_Mixin FS::Record );
-use FS::Record qw( qsearch qsearchs );
-use vars qw( @statuses );
+use FS::Record qw( dbh );
+use MIME::Parser;
 
 =head1 NAME
 
@@ -22,9 +22,9 @@ FS::cust_msg - Object methods for cust_msg records
 
 =head1 DESCRIPTION
 
-An FS::cust_msg object represents an email message generated by Freeside 
-and sent to a customer (see L<FS::msg_template>).  FS::cust_msg inherits 
-from FS::Record.  The following fields are currently supported:
+An FS::cust_msg object represents an email message generated by Freeside.
+FS::cust_msg inherits from FS::Record.  The following fields are currently
+supported:
 
 =over 4
 
@@ -44,10 +44,14 @@ from FS::Record.  The following fields are currently supported:
 
 =item header - message header
 
-=item body - message body
+=item body - message body (as a complete MIME document)
+
+=item preview - HTML fragment to show as a preview of the message
 
 =item error - Email::Sender error message (or null for success)
 
+=item status - "prepared", "sent", or "failed"
+
 =back
 
 =head1 METHODS
@@ -67,7 +71,7 @@ sub table { 'cust_msg'; }
 sub nohistory_fields { ('header', 'body'); } 
 # history is kind of pointless on this table
 
-@statuses = qw( prepared sent failed );
+our @statuses = qw( prepared sent failed );
 
 =item insert
 
@@ -136,12 +140,14 @@ sub check {
     || $self->ut_textn('env_to')
     || $self->ut_anything('header')
     || $self->ut_anything('body')
+    || $self->ut_anything('preview')
     || $self->ut_enum('status', \@statuses)
     || $self->ut_textn('error')
     || $self->ut_enum('msgtype', [  '',
                                     'invoice',
                                     'receipt',
                                     'admin',
+                                    'report',
                                  ])
   ;
   return $error if $error;
@@ -149,6 +155,89 @@ sub check {
   $self->SUPER::check;
 }
 
+=item send
+
+Sends the message through its parent L<FS::msg_template>. Returns an error
+message on error, or an empty string.
+
+=cut
+
+sub send {
+  my $self = shift;
+  # it's still allowed to have cust_msgs without message templates, but only 
+  # for email.
+  my $msg_template = $self->msg_template || 'FS::msg_template::email';
+  $msg_template->send_prepared($self);
+}
+
+=item entity
+
+Returns the complete message as a L<MIME::Entity>.
+
+XXX this only works if the message in fact contains a MIME entity. Messages
+created by external APIs may not look like that.
+
+=item parts
+
+Returns a list of the MIME parts contained in the message, as L<MIME::Entity>
+objects.
+
+=cut
+
+sub entity {
+  my $self = shift;
+  if ( !exists($self->{entity}) ) {
+    my $parser = MIME::Parser->new;
+    my $output_dir = "$FS::UID::cache_dir/cache.$FS::UID::datasrc/mimeparts";
+    mkdir($output_dir) unless -d $output_dir;
+    $parser->output_under($output_dir);
+    $self->{entity} =
+      $parser->parse_data( $self->header . "\n" . $self->body );
+  }
+  $self->{entity};
+}
+
+sub parts {
+  my $self = shift;
+  # return only the parts with bodies, not the multipart containers
+  grep { $_->bodyhandle } $self->entity->parts_DFS;
+}
+
+=back
+
+=head1 SUBROUTINES
+
+=over 4
+
+=item process_send CUSTMSGNUM
+
+Given a C<cust_msg.custmsgnum> value, sends the message. It must already
+have been prepared (via L<FS::msg_template/prepare>).
+
+=cut
+
+sub process_send {
+  my $custmsgnum = shift;
+  my $cust_msg = FS::cust_msg->by_key($custmsgnum)
+    or die "cust_msg #$custmsgnum not found";
+  my $error = $cust_msg->send;
+  die $error if $error;
+}
+
+sub _upgrade_schema {
+  my ($class, %opts) = @_;
+
+  my $sql = '
+    DELETE FROM cust_msg WHERE NOT EXISTS
+      ( SELECT 1 FROM cust_main WHERE cust_main.custnum = cust_msg.custnum )
+  ';
+
+  my $sth = dbh->prepare($sql) or die dbh->errstr;
+  $sth->execute or die $sth->errstr;
+  '';
+
+}
+
 =back
 
 =head1 SEE ALSO