Bug 14251: Allow use of CSS in discharge letter
The discharge feature relies PDF::FromHTML which explicitly doesn't handle CSS [1]. This patch makes it use the `weasyprint` command-line tool to generate the PDF. This tool handles CSS correctly. To test: 1. Install weasyprint: $ apt install weasyprint 2. Add some style to your DISCHARGE letter. I used: <<today>> <h1>Discharge confirmation</h1> <p style="background-color: yellow;"><<branches.branchname>> certifies that the following borrower:<br> <<borrowers.firstname>> <<borrowers.surname>> (cardnumber: <<borrowers.cardnumber>>)<br> has returned all items.</p> 3. Have some non-latin chars on the patron name. I picked 'Henry Acevedo' and added 'Δοκιμή' as picked from bug 23589. Only to check no regressions. 4. Enable the 'UseDischarge' syspref 5. Go to Henry's detail page 6. Choose More > Discharge and Generate the discharge => SUCCESS: - Style is applied to the PDF - Greek characters are displayed correctly 7. Run the tests: $ kshell k$ prove -v t/db_dependent/Patron/Borrower_Discharge.t => SUCCESS: The rewritten tests pass! 8. Remove weasyprint: $ apt remove weasyprint 9. Repeat 7 => SUCCESS: Tests pass, relevant test is skipped because of missing weasyprint 10. Sign off :-D [1] https://metacpan.org/pod/PDF::FromHTML#CAVEATS Signed-off-by: David Nind <david@davidnind.com> Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com> Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
This commit is contained in:
parent
d22f885b06
commit
9d9ecdc49b
2 changed files with 52 additions and 41 deletions
|
@ -3,6 +3,7 @@ package Koha::Patron::Discharge;
|
|||
use Modern::Perl;
|
||||
use CGI;
|
||||
use File::Temp qw( tmpnam );
|
||||
use IPC::Cmd;
|
||||
use Carp qw( carp );
|
||||
|
||||
use C4::Templates qw ( gettemplate );
|
||||
|
@ -128,40 +129,27 @@ sub generate_as_pdf {
|
|||
my $html_path = tmpnam() . '.html';
|
||||
my $pdf_path = tmpnam() . '.pdf';
|
||||
my $html_content = $tmpl->output;
|
||||
|
||||
# export to HTML
|
||||
open my $html_fh, '>:encoding(utf8)', $html_path;
|
||||
say $html_fh $html_content;
|
||||
close $html_fh;
|
||||
my $output = eval { require PDF::FromHTML; return; } || $@;
|
||||
if ($output && $params->{testing}) {
|
||||
carp $output;
|
||||
$pdf_path = undef;
|
||||
}
|
||||
elsif ($output) {
|
||||
die $output;
|
||||
|
||||
if ( IPC::Cmd::can_run('weasyprint') ) {
|
||||
my( $success, $error_message, $full_buf, $stdout_buf, $stderr_buf ) =
|
||||
IPC::Cmd::run( command => "weasyprint $html_path $pdf_path", verbose => 0 );
|
||||
|
||||
map {warn $_} @$stderr_buf
|
||||
if $stderr_buf and scalar @$stderr_buf;
|
||||
|
||||
unless ( $success ) {
|
||||
warn $error_message;
|
||||
$pdf_path = undef;
|
||||
}
|
||||
}
|
||||
else {
|
||||
my $pdf = PDF::FromHTML->new( encoding => 'utf-8' );
|
||||
$pdf->load_file( $html_path );
|
||||
|
||||
my $ttf = C4::Context->config('ttf');
|
||||
if ( $ttf && exists $ttf->{font} ) {
|
||||
|
||||
my $type2path;
|
||||
foreach my $font ( @{ $ttf->{font} } ) {
|
||||
$type2path->{ $font->{type} } = $font->{content};
|
||||
}
|
||||
|
||||
$pdf->convert(
|
||||
FontBold => $type2path->{'HB'} || 'HelveticaBold',
|
||||
FontOblique => $type2path->{'HO'} || 'HelveticaOblique',
|
||||
FontBoldOblique => $type2path->{'HBO'}|| 'HelveticaBoldOblique',
|
||||
FontUnicode => $type2path->{'H'} || 'Helvetica',
|
||||
Font => $type2path->{'H'} || 'Helvetica',
|
||||
);
|
||||
} else {
|
||||
$pdf->convert();
|
||||
}
|
||||
$pdf->write_file( $pdf_path );
|
||||
warn "weasyprint not found!";
|
||||
$pdf_path = undef;
|
||||
}
|
||||
|
||||
return $pdf_path;
|
||||
|
|
|
@ -15,8 +15,13 @@
|
|||
# with Koha; if not, see <http://www.gnu.org/licenses>.
|
||||
|
||||
use Modern::Perl;
|
||||
use Test::More tests => 19;
|
||||
|
||||
use Test::More tests => 23;
|
||||
|
||||
use Test::MockModule;
|
||||
use Test::Warn;
|
||||
|
||||
use IPC::Cmd qw(can_run);
|
||||
use MARC::Record;
|
||||
|
||||
use C4::Circulation qw( AddIssue AddReturn );
|
||||
|
@ -114,18 +119,36 @@ is(scalar( Koha::Patron::Discharge::get_pendings ), 1, 'There is a pending disch
|
|||
Koha::Patron::Discharge::discharge( { borrowernumber => $patron->{borrowernumber} } );
|
||||
is_deeply( [ Koha::Patron::Discharge::get_pendings ], [], 'There is no pending discharge request (second time)');
|
||||
|
||||
# Check if PDF::FromHTML is installed.
|
||||
my $check = eval { require PDF::FromHTML; };
|
||||
SKIP: {
|
||||
skip "Skipping because weasyprint is not installed",
|
||||
5 unless can_run('weasyprint');
|
||||
|
||||
# Tests for if PDF::FromHTML is installed
|
||||
if ($check) {
|
||||
isnt( Koha::Patron::Discharge::generate_as_pdf({ borrowernumber => $patron->{borrowernumber} }), undef, "Temporary PDF generated." );
|
||||
}
|
||||
# Tests for if PDF::FromHTML is not installed
|
||||
else {
|
||||
warning_like { Koha::Patron::Discharge::generate_as_pdf({ borrowernumber => $patron->{borrowernumber}, testing => 1 }) }
|
||||
[ qr/Can't locate PDF\/FromHTML.pm in \@INC/ ],
|
||||
"Expected failure because of missing PDF::FromHTML.";
|
||||
isnt(
|
||||
Koha::Patron::Discharge::generate_as_pdf( { borrowernumber => $patron->{borrowernumber} } ),
|
||||
undef,
|
||||
"Temporary PDF generated."
|
||||
);
|
||||
|
||||
my $mocked_ipc = Test::MockModule->new('IPC::Cmd');
|
||||
|
||||
$mocked_ipc->mock( 'run', sub { return 0, 'Some error' } );
|
||||
|
||||
my $result;
|
||||
warning_is
|
||||
{ $result = Koha::Patron::Discharge::generate_as_pdf( { borrowernumber => $patron->{borrowernumber} } ); }
|
||||
'Some error',
|
||||
'Failed call to run() prints the generated error';
|
||||
|
||||
is( $result, undef, 'undef returned if failed run' );
|
||||
|
||||
$mocked_ipc->mock( 'can_run', undef );
|
||||
|
||||
warning_is
|
||||
{ $result = Koha::Patron::Discharge::generate_as_pdf( { borrowernumber => $patron->{borrowernumber} } ); }
|
||||
'weasyprint not found!',
|
||||
'Expected failure because of missing weasyprint';
|
||||
|
||||
is( $result, undef, 'undef returned if missing weasyprint' );
|
||||
}
|
||||
|
||||
# FIXME Should be a Koha::Object object
|
||||
|
|
Loading…
Reference in a new issue