[freeside-commits] freeside/FS/FS Conf.pm, 1.324.2.44, 1.324.2.45 msg_template.pm, 1.1.2.6, 1.1.2.7 cust_pay.pm, 1.74.2.2, 1.74.2.3
Mark Wells
mark at wavetail.420.am
Fri Jul 30 15:20:52 PDT 2010
Update of /home/cvs/cvsroot/freeside/FS/FS
In directory wavetail.420.am:/tmp/cvs-serv16052/FS/FS
Modified Files:
Tag: FREESIDE_1_9_BRANCH
Conf.pm msg_template.pm cust_pay.pm
Log Message:
payment receipts use msg_template, RT#9060
Index: msg_template.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/msg_template.pm,v
retrieving revision 1.1.2.6
retrieving revision 1.1.2.7
diff -u -w -d -r1.1.2.6 -r1.1.2.7
--- msg_template.pm 28 Jul 2010 23:20:58 -0000 1.1.2.6
+++ msg_template.pm 30 Jul 2010 22:20:49 -0000 1.1.2.7
@@ -8,10 +8,12 @@
use FS::Record qw( qsearch qsearchs );
use Date::Format qw( time2str );
-use HTML::Entities qw( encode_entities) ;
+use HTML::Entities qw( decode_entities encode_entities ) ;
+use HTML::FormatText;
+use HTML::TreeBuilder;
use vars '$DEBUG';
-$DEBUG=1;
+$DEBUG=0;
=head1 NAME
@@ -143,10 +145,6 @@
;
return $error if $error;
- my $body = $self->body;
- $body =~ s/ / /g; # just in case these somehow get in
- $self->body($body);
-
$self->mime_type('text/html') unless $self->mime_type;
$self->SUPER::check;
@@ -167,8 +165,8 @@
=item object
-Additional context object (currently, can be a cust_main object, cust_pkg
-object, or cust_bill object).
+Additional context object (currently, can be a cust_main, cust_pkg,
+cust_bill, svc_acct, or cust_pay object).
=back
@@ -204,30 +202,55 @@
}
}
}
- $_ = encode_entities($_) foreach values(%hash); # HTML escape
+ $_ = encode_entities($_) foreach values(%hash);
+
###
- # fill-in
+ # clean up template
###
-
my $subject_tmpl = new Text::Template (
TYPE => 'STRING',
SOURCE => $self->subject,
);
my $subject = $subject_tmpl->fill_in( HASH => \%hash );
+ my $body = $self->body;
+ my ($skin, $guts) = eviscerate($body);
+ @$guts = map {
+ $_ = decode_entities($_); # turn all punctuation back into itself
+ s/\r//gs; # remove \r's
+ s/<br[^>]*>/\n/gsi; # and <br /> tags
+ s/<p>/\n/gsi; # and <p>
+ s/<\/p>//gsi; # and </p>
+ s/\240/ /gs; # and
+ $_
+ } @$guts;
+
+ $body = '';
+ while(@$skin || @$guts) {
+ $body .= shift(@$skin) || '';
+ $body .= shift(@$guts) || '';
+ }
+
+ ###
+ # fill-in
+ ###
+
my $body_tmpl = new Text::Template (
TYPE => 'STRING',
- SOURCE => $self->body,
+ SOURCE => $body,
);
- my $body = $body_tmpl->fill_in( HASH => \%hash );
+
+ $body = $body_tmpl->fill_in( HASH => \%hash );
###
# and email
###
my @to = $cust_main->invoicing_list_emailonly;
- #unless (@to) { #XXX do something }
+ warn "prepared msg_template with no email destination (custnum ".
+ $cust_main->custnum.")\n"
+ if !@to;
my $conf = new FS::Conf;
@@ -237,8 +260,8 @@
'to' => \@to,
'subject' => $subject,
'html_body' => $body,
- #XXX auto-make a text copy w/HTML::FormatText?
- # alas, us luddite mutt/pine users just aren't that big a deal
+ 'text_body' => HTML::FormatText->new(leftmargin => 0, rightmargin => 70
+ )->format( HTML::TreeBuilder->new_from_content($body) ),
);
}
@@ -250,6 +273,8 @@
=cut
+# broken out from prepare() in case we want to queue the sending,
+# preview it, etc.
sub send {
my $self = shift;
send_email(generate_email($self->prepare(@_)));
@@ -258,6 +283,9 @@
# helper sub for package dates
my $ymd = sub { $_[0] ? time2str('%Y-%m-%d', $_[0]) : '' };
+# needed for some things
+my $conf = new FS::Conf;
+
#return contexts and fill-in values
# If you add anything, be sure to add a description in
# httemplate/edit/msg_template.html.
@@ -278,7 +306,7 @@
ship_country
ship_daytime ship_night ship_fax
- payby paymask payname paytype payip
+ paymask payname paytype payip
num_cancelled_pkgs num_ncancelled_pkgs num_pkgs
classname categoryname
balance
@@ -290,8 +318,10 @@
[ signupdate_ymd => sub { time2str('%Y-%m-%d', shift->signupdate) } ],
[ dundate_ymd => sub { time2str('%Y-%m-%d', shift->dundate) } ],
[ paydate_my => sub { sprintf('%02d/%04d', shift->paydate_monthyear) } ],
- [ otaker_first => sub { shift->access_user->first } ],
- [ otaker_last => sub { shift->access_user->last } ],
+ [ payby => sub { FS::payby->shortname(shift->payby) } ],
+ [ company_name => sub {
+ $conf->config('company_name', shift->agentnum)
+ } ],
],
# next_bill_date
'cust_pkg' => [qw(
@@ -315,6 +345,7 @@
],
'cust_bill' => [qw(
invnum
+ _date
)],
#XXX not really thinking about cust_bill substitutions quite yet
@@ -323,6 +354,20 @@
),
[ password => sub { shift->getfield('_password') } ],
], # for welcome messages
+ 'cust_pay' => [qw(
+ paynum
+ _date
+ ),
+ [ paid => sub { sprintf("%.2f", shift->paid) } ],
+ # 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)
+ } ],
+ ],
};
}
@@ -334,6 +379,7 @@
[ 'cancel_msgnum', 'cancelmessage', 'cancelsubject', '' ],
[ 'decline_msgnum', 'declinetemplate', '', '' ],
[ 'impending_recur_msgnum', 'impending_recur_template', '', '' ],
+ [ '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' ],
);
@@ -364,6 +410,56 @@
}
}
+sub eviscerate {
+ # Every bit as pleasant as it sounds.
+ #
+ # We do this because Text::Template::Preprocess doesn't
+ # actually work. It runs the entire template through
+ # the preprocessor, instead of the code segments. Which
+ # is a shame, because Text::Template already contains
+ # the code to do this operation.
+ my $body = shift;
+ my (@outside, @inside);
+ my $depth = 0;
+ my $chunk = '';
+ while($body || $chunk) {
+ my ($first, $delim, $rest);
+ # put all leading non-delimiters into $first
+ ($first, $rest) =
+ ($body =~ /^((?:\\[{}]|[^{}])*)(.*)$/s);
+ $chunk .= $first;
+ # put a leading delimiter into $delim if there is one
+ ($delim, $rest) =
+ ($rest =~ /^([{}]?)(.*)$/s);
+
+ if( $delim eq '{' ) {
+ $chunk .= '{';
+ if( $depth == 0 ) {
+ push @outside, $chunk;
+ $chunk = '';
+ }
+ $depth++;
+ }
+ elsif( $delim eq '}' ) {
+ $depth--;
+ if( $depth == 0 ) {
+ push @inside, $chunk;
+ $chunk = '';
+ }
+ $chunk .= '}';
+ }
+ else {
+ # no more delimiters
+ if( $depth == 0 ) {
+ push @outside, $chunk . $rest;
+ } # else ? something wrong
+ last;
+ }
+ $body = $rest;
+ }
+ (\@outside, \@inside);
+}
+
=back
=head1 BUGS
Index: cust_pay.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_pay.pm,v
retrieving revision 1.74.2.2
retrieving revision 1.74.2.3
diff -u -w -d -r1.74.2.2 -r1.74.2.3
--- cust_pay.pm 11 Jun 2010 21:18:11 -0000 1.74.2.2
+++ cust_pay.pm 30 Jul 2010 22:20:50 -0000 1.74.2.3
@@ -446,17 +446,24 @@
my $conf = new FS::Conf;
- return ''
- unless $conf->exists('payment_receipt_email')
- && grep { $_ !~ /^(POST|FAX)$/ } $cust_main->invoicing_list;
+ my @invoicing_list = $cust_main->invoicing_list_emailonly;
+ return '' unless @invoicing_list;
$cust_bill ||= ($cust_main->cust_bill)[-1]; #rather inefficient though?
if ( ( exists($opt->{'manual'}) && $opt->{'manual'} )
- || ! $conf->exists('invoice_html_statement')
+ || ! $conf->exists('invoice_html_statement') # XXX msg_template
|| ! $cust_bill
) {
+ my $error = '';
+
+ if( $conf->exists('payment_receipt_msgnum') ) {
+ my $msg_template =
+ FS::msg_template->by_key($conf->config('payment_receipt_msgnum'));
+ $error = $msg_template->send('cust_main'=> $cust_main, 'object'=> $self);
+ }
+ elsif ( $conf->exists('payment_receipt_email') ) {
my $receipt_template = new Text::Template (
TYPE => 'ARRAY',
SOURCE => [ map "$_\n", $conf->config('payment_receipt_email') ],
@@ -465,9 +472,6 @@
return '';
};
- my @invoicing_list = grep { $_ !~ /^(POST|FAX)$/ }
- $cust_main->invoicing_list;
-
my $payby = $self->payby;
my $payinfo = $self->payinfo;
$payby =~ s/^BILL$/Check/ if $payinfo;
@@ -494,7 +498,7 @@
#setup date, other things?
}
- send_email(
+ $error = send_email(
'from' => $conf->config('invoice_from', $cust_main->agentnum),
#invoice_from??? well as good as any
'to' => \@invoicing_list,
@@ -502,7 +506,8 @@
'body' => [ $receipt_template->fill_in( HASH => \%fill_in ) ],
);
- } else {
+ }
+ else { # no payment_receipt_msgnum or payment_receipt_email
my $queue = new FS::queue {
'paynum' => $self->paynum,
@@ -513,9 +518,10 @@
'invnum' => $cust_bill->invnum,
'template' => 'statement',
);
-
}
+ warn "send_receipt: $error\n" if $error;
+ } #$opt{manual} || no invoice_html_statement || customer has no invoices
}
=item cust_bill_pay
Index: Conf.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/Conf.pm,v
retrieving revision 1.324.2.44
retrieving revision 1.324.2.45
diff -u -w -d -r1.324.2.44 -r1.324.2.45
--- Conf.pm 30 Jul 2010 05:38:45 -0000 1.324.2.44
+++ Conf.pm 30 Jul 2010 22:20:49 -0000 1.324.2.45
@@ -1227,15 +1227,22 @@
},
{
+ 'key' => 'payment_receipt_msgnum',
+ 'section' => 'notification',
+ 'description' => 'Template to use for payment receipts',
+ %msg_template_options,
+ },
+
+ {
'key' => 'payment_receipt_email',
- 'section' => 'billing',
- 'description' => 'Template file for payment receipts. Payment receipts are sent to the customer email invoice destination(s) when a payment is received. See the <a href="http://search.cpan.org/dist/Text-Template/lib/Text/Template.pm">Text::Template</a> documentation for details on the template substitution language. The following variables are available: <ul><li><code>$date</code> <li><code>$name</code> <li><code>$paynum</code> - Freeside payment number <li><code>$paid</code> - Amount of payment <li><code>$payby</code> - Payment type (Card, Check, Electronic check, etc.) <li><code>$payinfo</code> - Masked credit card number or check number <li><code>$balance</code> - New balance<li><code>$pkg</code> - Package (requires payment_receipt-trigger set to "when payment is applied".)</ul>',
+ 'section' => 'deprecated',
+ 'description' => 'Template file for payment receipts. Payment receipts are sent to the customer email invoice destination(s) when a payment is received.',
'type' => [qw( checkbox textarea )],
},
{
'key' => 'payment_receipt-trigger',
- 'section' => 'billing',
+ 'section' => 'notification',
'description' => 'When payment receipts are triggered. Defaults to when payment is made.',
'type' => 'select',
'select_hash' => [
More information about the freeside-commits
mailing list