summaryrefslogtreecommitdiff
path: root/FS
diff options
context:
space:
mode:
authorMark Wells <mark@freeside.biz>2012-10-10 12:24:09 -0700
committerMark Wells <mark@freeside.biz>2012-10-10 12:24:09 -0700
commit963b977d201a71e85781bcbf6732795728e9fc0f (patch)
tree19a45ce6aa3c93e848511d15972f1ef81f65d99b /FS
parent64c605834e8674c6ae5a3c7e235e37364826c870 (diff)
HTML templates for printable form letters, #17349
Diffstat (limited to 'FS')
-rw-r--r--FS/FS/Misc.pm2
-rw-r--r--FS/FS/Schema.pm1
-rw-r--r--FS/FS/msg_template.pm73
-rw-r--r--FS/FS/part_event/Action/letter.pm47
-rw-r--r--FS/FS/part_tag.pm33
-rwxr-xr-xFS/bin/freeside-wkhtmltopdf7
6 files changed, 149 insertions, 14 deletions
diff --git a/FS/FS/Misc.pm b/FS/FS/Misc.pm
index 297e39f..a1c15fd 100644
--- a/FS/FS/Misc.pm
+++ b/FS/FS/Misc.pm
@@ -799,7 +799,7 @@ sub _pslatex {
}
-=item print ARRAYREF
+=item do_print ARRAYREF
Sends the lines in ARRAYREF to the printer.
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index 6ad4b74..fb1f1d6 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -1349,6 +1349,7 @@ sub tables_hashref {
'tagname', 'varchar', '', $char_d, '', '',
'tagdesc', 'varchar', 'NULL', $char_d, '', '',
'tagcolor', 'varchar', 'NULL', 6, '', '',
+ 'by_default', 'char', 'NULL', 1, '', '',
'disabled', 'char', 'NULL', 1, '', '',
],
'primary_key' => 'tagnum',
diff --git a/FS/FS/msg_template.pm b/FS/FS/msg_template.pm
index cac7fe5..e38346a 100644
--- a/FS/FS/msg_template.pm
+++ b/FS/FS/msg_template.pm
@@ -16,6 +16,9 @@ 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; } );
@@ -273,8 +276,8 @@ A hash reference of additional substitutions
sub prepare {
my( $self, %opt ) = @_;
- my $cust_main = $opt{'cust_main'};
- my $object = $opt{'object'};
+ 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 || '';
@@ -435,9 +438,65 @@ sub send {
send_email(generate_email($self->prepare(@_)));
}
+=item render OPTION => VALUE ...
+
+Fills in the template and renders it to a PDF document. Returns the
+name of the PDF file.
+
+Options are as for 'prepare', but 'from' and 'to' are meaningless.
+
+=cut
+
+# will also have options to set paper size, margins, etc.
+
+sub render {
+ my $self = shift;
+ eval "use PDF::WebKit";
+ die $@ if $@;
+ my %opt = @_;
+ 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 $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'
+ );
+
+ print $fh $kit->to_pdf;
+ close $fh;
+ return $fh->filename;
+}
+
+=item print OPTIONS
+
+Render a PDF and send it to the printer. OPTIONS are as for 'render'.
+
+=cut
+
+sub print {
+ my $file = render(@_);
+ my @lpr = $conf->config('lpr');
+ run ([@lpr, '-r'], '<', $file)
+ or die "lpr error:\n$?\n";
+}
+
+
# helper sub for package dates
my $ymd = sub { $_[0] ? time2str('%Y-%m-%d', $_[0]) : '' };
+# helper sub for money amounts
+my $money = sub { ($conf->money_char || '$') . sprintf('%.2f', $_[0] || 0) };
+
# helper sub for usage-related messages
my $usage_warning = sub {
my $svc = shift;
@@ -483,6 +542,7 @@ sub substitutions {
signupdate dundate
packages recurdates
),
+ [ invoicing_email => sub { shift->invoicing_list_emailonly_scalar } ],
#compatibility: obsolete ship_ fields - use the non-ship versions
map (
{ my $field = $_;
@@ -520,6 +580,8 @@ sub substitutions {
labels_short
),
[ pkg => sub { shift->part_pkg->pkg } ],
+ [ pkg_category => sub { shift->part_pkg->categoryname } ],
+ [ pkg_class => sub { shift->part_pkg->classname } ],
[ cancel => sub { shift->getfield('cancel') } ], # grrr...
[ start_ymd => sub { $ymd->(shift->getfield('start_date')) } ],
[ setup_ymd => sub { $ymd->(shift->getfield('setup')) } ],
@@ -529,6 +591,13 @@ sub substitutions {
[ susp_ymd => sub { $ymd->(shift->getfield('susp')) } ],
[ expire_ymd => sub { $ymd->(shift->getfield('expire')) } ],
[ cancel_ymd => sub { $ymd->(shift->getfield('cancel')) } ],
+
+ # not necessarily correct for non-flat packages
+ [ setup_fee => sub { shift->part_pkg->option('setup_fee') } ],
+ [ recur_fee => sub { shift->part_pkg->option('recur_fee') } ],
+
+ [ freq_pretty => sub { shift->part_pkg->freq_pretty } ],
+
],
'cust_bill' => [qw(
invnum
diff --git a/FS/FS/part_event/Action/letter.pm b/FS/FS/part_event/Action/letter.pm
new file mode 100644
index 0000000..57b7b77
--- /dev/null
+++ b/FS/FS/part_event/Action/letter.pm
@@ -0,0 +1,47 @@
+package FS::part_event::Action::letter;
+
+use strict;
+use base qw( FS::part_event::Action );
+use FS::Record qw( qsearchs );
+use FS::msg_template;
+
+sub description { 'Print a form letter to the customer' }
+
+#sub eventtable_hashref {
+# { 'cust_main' => 1,
+# 'cust_bill' => 1,
+# 'cust_pkg' => 1,
+# };
+#}
+
+sub option_fields {
+ (
+ 'msgnum' => { 'label' => 'Template',
+ 'type' => 'select-table',
+ 'table' => 'msg_template',
+ 'name_col' => 'msgname',
+ 'disable_empty' => 1,
+ },
+ );
+}
+
+sub default_weight { 56; } #?
+
+sub do_action {
+ my( $self, $object ) = @_;
+
+ my $cust_main = $self->cust_main($object);
+
+ my $msgnum = $self->option('msgnum');
+
+ my $msg_template = qsearchs('msg_template', { 'msgnum' => $msgnum } )
+ or die "Template $msgnum not found";
+
+ $msg_template->print(
+ 'cust_main' => $cust_main,
+ 'object' => $object,
+ );
+
+}
+
+1;
diff --git a/FS/FS/part_tag.pm b/FS/FS/part_tag.pm
index 0229e3a..ed31929 100644
--- a/FS/FS/part_tag.pm
+++ b/FS/FS/part_tag.pm
@@ -30,22 +30,17 @@ FS::Record. The following fields are currently supported:
=over 4
-=item tagnum
+=item tagnum - primary key
-primary key
+=item tagname - tag name
-=item tagname
+=item tagdesc - description (can be longer than name)
-tagname
+=item tagcolor - HTML-style color to display this tag
-=item tagdesc
-
-tagdesc
-
-=item tagcolor
-
-tagcolor
+=item by_default - 'Y' to enable this tag on new customers
+=item disabled
=back
@@ -111,6 +106,7 @@ sub check {
|| $self->ut_text('tagname')
|| $self->ut_textn('tagdesc')
|| $self->ut_textn('tagcolor')
+ || $self->ut_enum('by_default', [ '', 'Y' ] )
|| $self->ut_enum('disabled', [ '', 'Y' ] )
;
return $error if $error;
@@ -120,6 +116,21 @@ sub check {
=back
+=head1 CLASS METHODS
+
+=over 4
+
+=item default_tags
+
+Returns the tagnums of all tags that have 'by_default' enabled.
+
+=cut
+
+sub default_tags {
+ my $class = shift;
+ map { $_->tagnum } qsearch('part_tag', { disabled => '', by_default => 'Y' });
+}
+
=head1 BUGS
=head1 SEE ALSO
diff --git a/FS/bin/freeside-wkhtmltopdf b/FS/bin/freeside-wkhtmltopdf
new file mode 100755
index 0000000..c6c5531
--- /dev/null
+++ b/FS/bin/freeside-wkhtmltopdf
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+if [ $DISPLAY ] ; then
+ wkhtmltopdf $@
+else
+ xvfb-run -- wkhtmltopdf $@
+fi