X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fmsg_template.pm;h=c52b6336e3778792d67ccbc92d018c296d261504;hb=4f0250a76508176cdf5336c199c883a3912f5274;hp=011ce24d80a37ca9c7b5982792fbf96da8594f1b;hpb=c3a7e8855edbe4f836543184d5a7543e04255a43;p=freeside.git diff --git a/FS/FS/msg_template.pm b/FS/FS/msg_template.pm index 011ce24d8..c52b6336e 100644 --- a/FS/FS/msg_template.pm +++ b/FS/FS/msg_template.pm @@ -1,9 +1,20 @@ package FS::msg_template; +use base qw( FS::Record ); use strict; -use base qw( FS::Record ); +use vars qw( $DEBUG $conf ); + +use Date::Format qw( time2str ); +use File::Temp; +use IPC::Run qw(run); use Text::Template; -use FS::Misc qw( generate_email send_email ); + +use HTML::Entities qw( decode_entities encode_entities ) ; +use HTML::FormatText; +use HTML::TreeBuilder; +use Encode; + +use FS::Misc qw( generate_email send_email do_print ); use FS::Conf; use FS::Record qw( qsearch qsearchs ); use FS::UID qw( dbh ); @@ -12,15 +23,6 @@ use FS::cust_main; use FS::cust_msg; use FS::template_content; -use Date::Format qw( time2str ); -use HTML::Entities qw( decode_entities encode_entities ) ; -use HTML::FormatText; -use HTML::TreeBuilder; - -use File::Temp; -use IPC::Run qw(run); -use vars qw( $DEBUG $conf ); - FS::UID->install_callback( sub { $conf = new FS::Conf; } ); $DEBUG=0; @@ -276,16 +278,17 @@ A hash reference of additional substitutions sub prepare { my( $self, %opt ) = @_; - my $cust_main = $opt{'cust_main'} or die 'cust_main required'; + my $cust_main = $opt{'cust_main'}; # or die 'cust_main required'; my $object = $opt{'object'} or die 'object required'; # localization - my $locale = $cust_main->locale || ''; + my $locale = $cust_main && $cust_main->locale || ''; warn "no locale for cust#".$cust_main->custnum."; using default content\n" - if $DEBUG and !$locale; - my $content = $self->content($cust_main->locale); - warn "preparing template '".$self->msgname."' to cust#".$cust_main->custnum."\n" - if($DEBUG); + if $DEBUG and $cust_main && !$locale; + my $content = $self->content($locale); + + warn "preparing template '".$self->msgname."\n" + if $DEBUG; my $subs = $self->substitutions; @@ -293,7 +296,8 @@ sub prepare { # create substitution table ### my %hash; - my @objects = ($cust_main); + my @objects = (); + push @objects, $cust_main if $cust_main; my @prefixes = (''); my $svc; if( ref $object ) { @@ -383,21 +387,22 @@ sub prepare { my @to; if ( exists($opt{'to'}) ) { @to = split(/\s*,\s*/, $opt{'to'}); - } - else { + } elsif ( $cust_main ) { @to = $cust_main->invoicing_list_emailonly; + } else { + die 'no To: address or cust_main object specified'; } - # no warning when preparing with no destination my $from_addr = $self->from_addr; if ( !$from_addr ) { + + my $agentnum = $cust_main ? $cust_main->agentnum : ''; + if ( $opt{'from_config'} ) { - $from_addr = scalar( $conf->config($opt{'from_config'}, - $cust_main->agentnum) ); + $from_addr = $conf->config($opt{'from_config'}, $agentnum); } - $from_addr ||= scalar( $conf->config('invoice_from', - $cust_main->agentnum) ); + $from_addr ||= $conf->invoice_from_full($agentnum); } # my @cust_msg = (); # if ( $conf->exists('log_sent_mail') and !$opt{'preview'} ) { @@ -410,16 +415,19 @@ sub prepare { # @cust_msg = ('cust_msg' => $cust_msg); # } + my $text_body = encode('UTF-8', + HTML::FormatText->new(leftmargin => 0, rightmargin => 70) + ->format( HTML::TreeBuilder->new_from_content($body) ) + ); ( - 'custnum' => $cust_main->custnum, - 'msgnum' => $self->msgnum, - 'from' => $from_addr, - 'to' => \@to, - 'bcc' => $self->bcc_addr || undef, + 'custnum' => ( $cust_main ? $cust_main->custnum : ''), + 'msgnum' => $self->msgnum, + 'from' => $from_addr, + 'to' => \@to, + 'bcc' => $self->bcc_addr || undef, 'subject' => $subject, 'html_body' => $body, - 'text_body' => HTML::FormatText->new(leftmargin => 0, rightmargin => 70 - )->format( HTML::TreeBuilder->new_from_content($body) ), + 'text_body' => $text_body ); } @@ -457,24 +465,15 @@ sub render { my %hash = $self->prepare(%opt); my $html = $hash{'html_body'}; - my $tmp = 'msg'.$self->msgnum.'-'.time2str('%Y%m%d', time).'-XXXXXXXX'; - my $dir = "$FS::UID::cache_dir/cache.$FS::UID::datasrc"; - # Graphics/stylesheets should probably go in /var/www on the Freeside # machine. + my $script_path = `/usr/bin/which freeside-wkhtmltopdf`; + chomp $script_path; my $kit = PDF::WebKit->new(\$html); #%options # hack to use our wrapper script - $kit->configure(sub { shift->wkhtmltopdf('freeside-wkhtmltopdf') }); - my $fh = File::Temp->new( - TEMPLATE => $tmp, - DIR => $dir, - UNLINK => 0, - SUFFIX => '.pdf' - ); + $kit->configure(sub { shift->wkhtmltopdf($script_path) }); - print $fh $kit->to_pdf; - close $fh; - return $fh->filename; + $kit->to_pdf; } =item print OPTIONS @@ -485,12 +484,7 @@ Render a PDF and send it to the printer. OPTIONS are as for 'render'. sub print { my( $self, %opt ) = @_; - my $file = $self->render(%opt); - - my $lpr = $conf->config('lpr', $opt{'cust_main'}->agentnum ); - - run ( $lpr, '<', $file) - or die "lpr error:\n$?\n"; + do_print( [ $self->render(%opt) ], agentnum=>$opt{cust_main}->agentnum ); } # helper sub for package dates @@ -539,7 +533,7 @@ sub substitutions { balance credit_limit invoicing_list_emailonly - cust_status ucfirst_cust_status cust_statuscolor + cust_status ucfirst_cust_status cust_statuscolor cust_status_label signupdate dundate packages recurdates @@ -570,6 +564,9 @@ sub substitutions { [ company_phonenum => sub { $conf->config('company_phonenum', shift->agentnum) } ], + [ selfservice_server_base_url => sub { + $conf->config('selfservice_server-base_url') #, shift->agentnum) + } ], ], # next_bill_date 'cust_pkg' => [qw( @@ -604,7 +601,11 @@ sub substitutions { 'cust_bill' => [qw( invnum _date - )], + _date_pretty + due_date + ), + [ due_date2str => sub { shift->due_date2str('short') } ], + ], #XXX not really thinking about cust_bill substitutions quite yet # for welcome and limit warning messages @@ -705,13 +706,13 @@ Returns the L object for this template. =cut -sub agent { - qsearchs('agent', { 'agentnum' => $_[0]->agentnum }); -} - sub _upgrade_data { my ($self, %opts) = @_; + ### + # First move any historical templates in config to real message templates + ### + my @fixes = ( [ 'alerter_msgnum', 'alerter_template', '', '', '' ], [ 'cancel_msgnum', 'cancelmessage', 'cancelsubject', '', '' ], @@ -744,7 +745,70 @@ sub _upgrade_data { $conf->delete($subject, $agentnum) if $subject; } } + + if ( $conf->exists('alert_expiration', $agentnum) ) { + my $msgnum = $conf->exists('alerter_msgnum', $agentnum); + my $template = FS::msg_template->by_key($msgnum) if $msgnum; + if (!$template) { + warn "template for alerter_msgnum $msgnum not found\n"; + next; + } + # this is now a set of billing events + foreach my $days (30, 15, 5) { + my $event = FS::part_event->new({ + 'agentnum' => $agentnum, + 'event' => "Card expiration warning - $days days", + 'eventtable' => 'cust_main', + 'check_freq' => '1d', + 'action' => 'notice', + 'disabled' => 'Y', #initialize first + }); + my $error = $event->insert( 'msgnum' => $msgnum ); + if ($error) { + warn "error creating expiration alert event:\n$error\n\n"; + next; + } + # make it work like before: + # only send each warning once before the card expires, + # only warn active customers, + # only warn customers with CARD/DCRD, + # only warn customers who get email invoices + my %conds = ( + 'once_every' => { 'run_delay' => '30d' }, + 'cust_paydate_within' => { 'within' => $days.'d' }, + 'cust_status' => { 'status' => { 'active' => 1 } }, + 'payby' => { 'payby' => { 'CARD' => 1, + 'DCRD' => 1, } + }, + 'message_email' => {}, + ); + foreach (keys %conds) { + my $condition = FS::part_event_condition->new({ + 'conditionname' => $_, + 'eventpart' => $event->eventpart, + }); + $error = $condition->insert( %{ $conds{$_} }); + if ( $error ) { + warn "error creating expiration alert event:\n$error\n\n"; + next; + } + } + $error = $event->initialize; + if ( $error ) { + warn "expiration alert event was created, but not initialized:\n$error\n\n"; + } + } # foreach $days + $conf->delete('alerter_msgnum', $agentnum); + $conf->delete('alert_expiration', $agentnum); + + } # if alerter_msgnum + } + + ### + # Move subject and body from msg_template to template_content + ### + foreach my $msg_template ( qsearch('msg_template', {}) ) { if ( $msg_template->subject || $msg_template->body ) { # create new default content @@ -768,6 +832,35 @@ sub _upgrade_data { die $error if $error; } } + + ### + # Add new-style default templates if missing + ### + $self->_populate_initial_data; + +} + +sub _populate_initial_data { #class method + #my($class, %opts) = @_; + #my $class = shift; + + eval "use FS::msg_template::InitialData;"; + die $@ if $@; + + my $initial_data = FS::msg_template::InitialData->_initial_data; + + foreach my $hash ( @$initial_data ) { + + next if $hash->{_conf} && $conf->config( $hash->{_conf} ); + + 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}; + + } + } sub eviscerate {