+
+ if ( !$msg_template or $msg_template->disabled eq 'D' ) {
+ # then this is a one-off template; edit it in place
+ my $subject = $cgi->param('subject') || '';
+ my $body = $cgi->param('body') || '';
+
+ # create a draft template
+ $msg_template ||= FS::msg_template->new({
+ msgclass => 'email',
+ disabled => 'D',
+ });
+ # anyone have a better idea for msgname?
+ $msg_template->set('msgname' => "Notice " . DateTime->now->iso8601);
+ $msg_template->set('from_addr' => $from);
+ my %content = (
+ subject => $subject,
+ body => $body,
+ );
+ my $error;
+ if ( $msg_template->msgnum ) {
+ $error = $msg_template->replace(%content);
+ } else {
+ $error = $msg_template->insert(%content);
+ }
+
+ if ( $error ) {
+ $cgi->param('error', $error);
+ $cgi->delete('preview'); # don't go on to preview stage yet
+ undef $msg_template;
+ }
+ }
+ # unless creating the msg_template failed, we now have one, so construct a
+ # preview message from the first customer/whatever in the search results
+
+ my $cust;
+
+ if ( $msg_template ) {
+ $sql_query->{'extra_sql'} .= ' LIMIT 1';
+ $sql_query->{'select'} = "$table.*";
+ $sql_query->{'order_by'} = '';
+ my $object = qsearchs($sql_query);
+ # Could use better error handling here...
+ die "No customers match the search criteria" unless ref $object;
+ $cust = $object->cust_main;
+ my %msgopts = (
+ 'cust_main' => $cust,
+ 'object' => $object,
+ );
+
+ my $cust_msg = $msg_template->prepare(%msgopts);
+ $from = $cust_msg->env_from;
+ $html_body = $cust_msg->preview;
+#hmm. this came in with the #37098 rewrite, but isn't on v3 :/
+# causing problems with mangling subject of unrelated things
+# should probably decode instead of ignore the UTF-8 thing, but
+# this at least masks the ugliness for now :/
+ if ( $cust_msg->header =~ /^subject: (.*)/mi && $1 !~ /^\=\?UTF-8/ ) {
+ $subject = $1;
+ }
+ }
+
+ # contact_class_X params
+ #we can't switch to multi_param until we're done supporting deb 7
+ local($CGI::LIST_CONTEXT_WARN) = 0;
+
+ if ($cgi->param('emailtovoice_contact')) {
+ $email_to = $cgi->param('emailtovoice_contact') . '@' . $send_to_domain;
+ push @contact_classnum, 'emailtovoice';
+ push @contact_classname, $email_to;
+ }
+ else {
+ foreach my $param ( $cgi->param ) {
+ if ( $param =~ /^contact_class_(\w+)$/ ) {
+ push @contact_classnum, $1;
+ if ( $1 eq 'invoice' ) {
+ push @contact_classname, 'Invoice recipients';
+ } elsif ( $1 eq 'message' ) {
+ push @contact_classname, 'Message recipients';
+ } else {
+ my $contact_class = FS::contact_class->by_key($1);
+ push @contact_classname, encode_entities(
+ $contact_class ? $contact_class->classname : '(none)'
+ );
+ }
+ }
+ }
+ }
+}
+
+# Build data structures for "Opt In" and "Contact Type" checkboxes
+#
+# By default, message recipients will be selected, this is a message.
+# By default, all Contact Types will be selected, but this may be
+# overridden by passing 'classnums' get/post values. If no contact
+# types have been defined, the option will not be presented.
+
+my @active_classes = qsearch(contact_class => {disabled => ''} );
+
+my %classnum_ischecked;
+my %dest_ischecked;
+
+$CGI::LIST_CONTEXT_WARN = 0;
+if ( my @in_classnums = $cgi->param('classnums') ) {
+ # Set checked boxes from form input
+ for my $v (@in_classnums) {
+
+ if ( $v =~ /^\d+$/ ) {
+ $classnum_ischecked{$v} = 1
+ } elsif ( $v =~ /^(invoice|message)$/ ) {
+ $dest_ischecked{$v} = 1;
+ }
+
+ }
+} else {
+ # Checked boxes default values
+ $classnum_ischecked{$_->classnum} = 1 for @active_classes;
+ $classnum_ischecked{0} = 1;