X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=FS%2FFS%2Fmsg_template.pm;h=33e150ae338dc7743f20b04b9eabbb806a5d029a;hp=4c2ac4bd46e868c8152ec53a54264cf4a091391c;hb=HEAD;hpb=9fd03716b831bd00a725a63edbe19cfe6b88aea0 diff --git a/FS/FS/msg_template.pm b/FS/FS/msg_template.pm index 4c2ac4bd4..33e150ae3 100644 --- a/FS/FS/msg_template.pm +++ b/FS/FS/msg_template.pm @@ -11,6 +11,7 @@ use FS::cust_msg; use FS::template_content; use Date::Format qw(time2str); +use PDF::WebKit; FS::UID->install_callback( sub { $conf = new FS::Conf; } ); @@ -66,7 +67,9 @@ global template. =item bcc_addr - Bcc all mail to this address. -=item disabled - disabled ('Y' or NULL). +=item disabled - disabled (NULL for not-disabled and selectable, 'D' for a +draft of a one-time message, 'C' for a completed one-time message, 'Y' for a +normal template disabled by user action). =back @@ -91,9 +94,11 @@ sub extension_table { ''; } # subclasses don't HAVE to have extensions sub _rebless { my $self = shift; + return '' unless $self->msgclass; my $class = 'FS::msg_template::' . $self->msgclass; eval "use $class;"; bless($self, $class) unless $@; + warn "Error loading msg_template msgclass: " . $@ if $@; #or die? # merge in the extension fields (but let fields in $self override them) # except don't ever override the extension's primary key, it's immutable @@ -246,7 +251,7 @@ sub check { || $self->ut_text('msgname') || $self->ut_foreign_keyn('agentnum', 'agent', 'agentnum') || $self->ut_textn('mime_type') - || $self->ut_enum('disabled', [ '', 'Y' ] ) + || $self->ut_enum('disabled', [ '', 'Y', 'D', 'S' ] ) || $self->ut_textn('from_addr') || $self->ut_textn('bcc_addr') # fine for now, but change this to some kind of dynamic check if we @@ -271,7 +276,7 @@ Options are passed as a list of name/value pairs: =item cust_main -Customer object (required). +Customer object =item object @@ -321,7 +326,7 @@ sub prepare_substitutions { my( $self, %opt ) = @_; my $cust_main = $opt{'cust_main'}; # or die 'cust_main required'; - my $object = $opt{'object'} or die 'object required'; + my $object = $opt{'object'}; # or die 'object required'; warn "preparing substitutions for '".$self->msgname."'\n" if $DEBUG; @@ -407,8 +412,6 @@ Options are as for 'prepare', but 'from' and 'to' are meaningless. sub render { my $self = shift; - eval "use PDF::WebKit"; - die $@ if $@; my %opt = @_; my %hash = $self->prepare(%opt); my $html = $hash{'html_body'}; @@ -459,6 +462,17 @@ my $usage_warning = sub { # If you add anything, be sure to add a description in # httemplate/edit/msg_template.html. sub substitutions { + my $payinfo_sub = sub { + my $obj = shift; + ($obj->payby eq 'CARD' || $obj->payby eq 'CHEK') + ? $obj->paymask + : $obj->decrypt($obj->payinfo) + }; + my $payinfo_end = sub { + my $obj = shift; + my $payinfo = &$payinfo_sub($obj); + substr($payinfo, -4); + }; { 'cust_main' => [qw( display_custnum agentnum agent_name @@ -605,11 +619,17 @@ sub substitutions { # overrides the one in cust_main in cases where a cust_pay is passed [ payby => sub { FS::payby->shortname(shift->payby) } ], [ date => sub { time2str("%a %B %o, %Y", shift->_date) } ], - [ payinfo => sub { - my $cust_pay = shift; - ($cust_pay->payby eq 'CARD' || $cust_pay->payby eq 'CHEK') ? - $cust_pay->paymask : $cust_pay->decrypt($cust_pay->payinfo) - } ], + [ 'payinfo' => $payinfo_sub ], + [ 'payinfo_end' => $payinfo_end ], + ], + # for refund receipts + 'cust_refund' => [ + 'refundnum', + [ refund => sub { sprintf("%.2f", shift->refund) } ], + [ payby => sub { FS::payby->shortname(shift->payby) } ], + [ date => sub { time2str("%a %B %o, %Y", shift->_date) } ], + [ 'payinfo' => $payinfo_sub ], + [ 'payinfo_end' => $payinfo_end ], ], # for payment decline messages # try to support all cust_pay fields @@ -621,11 +641,8 @@ sub substitutions { [ paid => sub { sprintf("%.2f", shift->paid) } ], [ payby => sub { FS::payby->shortname(shift->payby) } ], [ date => sub { time2str("%a %B %o, %Y", shift->_date) } ], - [ payinfo => sub { - my $pending = shift; - ($pending->payby eq 'CARD' || $pending->payby eq 'CHEK') ? - $pending->paymask : $pending->decrypt($pending->payinfo) - } ], + [ 'payinfo' => $payinfo_sub ], + [ 'payinfo_end' => $payinfo_end ], ], }; } @@ -657,20 +674,22 @@ sub _upgrade_data { [ 'decline_msgnum', 'declinetemplate', '', '', '' ], [ 'impending_recur_msgnum', 'impending_recur_template', '', '', 'impending_recur_bcc' ], [ 'payment_receipt_msgnum', 'payment_receipt_email', '', '', '' ], - [ 'welcome_msgnum', 'welcome_email', 'welcome_email-subject', 'welcome_email-from', '' ], - [ 'warning_msgnum', 'warning_email', 'warning_email-subject', 'warning_email-from', '' ], + [ 'welcome_msgnum', 'welcome_email', 'welcome_email-subject', 'welcome_email-from', '', 'welcome_email-mimetype' ], + [ 'threshold_warning_msgnum', 'warning_email', 'warning_email-subject', 'warning_email-from', 'warning_email-cc', 'warning_email-mimetype' ], ); my @agentnums = ('', map {$_->agentnum} qsearch('agent', {})); foreach my $agentnum (@agentnums) { foreach (@fixes) { - my ($newname, $oldname, $subject, $from, $bcc) = @$_; + my ($newname, $oldname, $subject, $from, $bcc, $mimetype) = @$_; + if ($conf->exists($oldname, $agentnum)) { my $new = new FS::msg_template({ + 'msgclass' => 'email', 'msgname' => $oldname, 'agentnum' => $agentnum, 'from_addr' => ($from && $conf->config($from, $agentnum)) || '', - 'bcc_addr' => ($bcc && $conf->config($from, $agentnum)) || '', + 'bcc_addr' => ($bcc && $conf->config($bcc, $agentnum)) || '', 'subject' => ($subject && $conf->config($subject, $agentnum)) || '', 'mime_type' => 'text/html', 'body' => join('
',$conf->config($oldname, $agentnum)), @@ -681,6 +700,8 @@ sub _upgrade_data { $conf->delete($oldname, $agentnum); $conf->delete($from, $agentnum) if $from; $conf->delete($subject, $agentnum) if $subject; + $conf->delete($bcc, $agentnum) if $bcc; + $conf->delete($mimetype, $agentnum) if $mimetype; } } @@ -782,6 +803,78 @@ sub _upgrade_data { ### $self->_populate_initial_data; + ### + # Move welcome_msgnum to an export + ### + + #upgrade_journal loaded by _populate_initial_data + unless (FS::upgrade_journal->is_done('msg_template__welcome_export')) { + if (my $msgnum = $conf->config('welcome_msgnum')) { + eval "use FS::part_export;"; + die $@ if $@; + eval "use FS::part_svc;"; + die $@ if $@; + eval "use FS::export_svc;"; + die $@ if $@; + #create the export + my $part_export = new FS::part_export { + 'exportname' => 'Welcome Email', + 'exporttype' => 'send_email' + }; + my $error = $part_export->insert({ + 'to_customer' => 1, + 'insert_template' => $msgnum, + # replicate blank options that would be generated by UI, + # to avoid unexpected results from not having them exist + 'to_address' => '', + 'replace_template' => 0, + 'suspend_template' => 0, + 'unsuspend_template' => 0, + 'delete_template' => 0, + }); + die $error if $error; + #attach it to part_svcs + my @welcome_exclude_svcparts = $conf->config('svc_acct_welcome_exclude'); + foreach my $part_svc ( + qsearch('part_svc',{ 'svcdb' => 'svc_acct', 'disabled' => '' }) + ) { + next if grep { $_ eq $part_svc->svcpart } @welcome_exclude_svcparts; + my $export_svc = new FS::export_svc { + 'exportnum' => $part_export->exportnum, + 'svcpart' => $part_svc->svcpart, + }; + $error = $export_svc->insert; + die $error if $error; + } + #remove the old confs + $error = $conf->delete('welcome_msgnum'); + die $error if $error; + $error = $conf->delete('svc_acct_welcome_exclude'); + die $error if $error; + } + FS::upgrade_journal->set_done('msg_template__welcome_export'); + } + + + ### Fix dump-email_to (needs to happen after _populate_initial_data) + if ($conf->config('dump-email_to')) { + # anyone who still uses dump-email_to should have just had this created + my ($msg_template) = qsearch('msg_template',{ msgname => 'System log' }); + if ($msg_template) { + eval "use FS::log_email;"; + die $@ if $@; + my $log_email = new FS::log_email { + 'context' => 'Cron::backup', + 'min_level' => 1, + 'msgnum' => $msg_template->msgnum, + 'to_addr' => $conf->config('dump-email_to'), + }; + my $error = $log_email->insert; + die $error if $error; + $conf->delete('dump-email_to'); + } + } + } sub _populate_initial_data { #class method @@ -790,18 +883,22 @@ sub _populate_initial_data { #class method eval "use FS::msg_template::InitialData;"; die $@ if $@; + eval "use FS::upgrade_journal;"; + die $@ if $@; my $initial_data = FS::msg_template::InitialData->_initial_data; foreach my $hash ( @$initial_data ) { next if $hash->{_conf} && $conf->config( $hash->{_conf} ); + next if $hash->{_upgrade_journal} && FS::upgrade_journal->is_done( $hash->{_upgrade_journal} ); my $msg_template = new FS::msg_template($hash); my $error = $msg_template->insert( @{ $hash->{_insert_args} || [] } ); die $error if $error; $conf->set( $hash->{_conf}, $msg_template->msgnum ) if $hash->{_conf}; + FS::upgrade_journal->set_done( $hash->{_upgrade_journal} ) if $hash->{_upgrade_journal}; }