From d0e9db0847d6050439ef578dc13dd38c87b42c56 Mon Sep 17 00:00:00 2001 From: Julian Maurice Date: Tue, 13 Jun 2017 16:00:09 +0200 Subject: [PATCH] Bug 18796: Allow to print notice while claiming serials MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It can be useful to have a printable version of a claim notice, for testing purposes or for when supplier has no email address for example Test plan: 1. Go to Serials > Claims and select a vendor 2. Select some serials by clicking on checkboxes 3. Click to the little arrow next to 'Send notification' button and click on 'Print notification' 4. Verify that the downloaded PDF contains the content of the selected notice 5. Verify that the 'Send notification' button still works as before 6. Run `prove t/db_dependent/Letters.t` Followed test plan, works as expected. Signed-off-by: Marc VĂ©ron --- C4/Letters.pm | 79 +++++++++++++++++++ cpanfile | 1 + .../prog/en/modules/serials/claims.tt | 25 +++++- serials/claims.pl | 47 +++++++---- t/db_dependent/Letters.t | 42 +++++++++- 5 files changed, 175 insertions(+), 19 deletions(-) diff --git a/C4/Letters.pm b/C4/Letters.pm index 87b82624c6..2f920c4be4 100644 --- a/C4/Letters.pm +++ b/C4/Letters.pm @@ -23,6 +23,7 @@ use MIME::Lite; use Carp qw( carp croak ); use Template; use Module::Load::Conditional qw( can_load ); +use PDF::FromHTML; use Try::Tiny qw( catch try ); @@ -40,6 +41,7 @@ use Koha::DateUtils qw( dt_from_string output_pref ); use Koha::Patrons; use Koha::SMTP::Servers; use Koha::Subscriptions; +use Koha::Acquisition::Booksellers; our (@ISA, @EXPORT_OK); BEGIN { @@ -583,6 +585,83 @@ sub SendAlerts { return 1; } +=head2 PrintClaimIssueNotice + +Returns a 'claimissues' notice for given serial ids and letter code as PDF + + my $pdf = PrintClaimIssueNotice(\@serialids, $letter_code); + + print $cgi->header('application/pdf'); + print $pdf; + + +Returns undef if: + +=over + +=item * a parameter is missing + +=item * C<@serialids> is empty + +=item * C<@serialids> does not contain any existing serial id + +=item * C<$letter_code> does not exist + +=back + +=cut + +sub PrintClaimIssueNotice { + my ($serialids, $letter_code) = @_; + + return unless ref $serialids eq 'ARRAY'; + return unless @$serialids > 0; + return unless $letter_code; + + my $dbh = C4::Context->dbh; + + my $serialids_str = join(',', ('?') x @$serialids); + my $serials = $dbh->selectall_arrayref(qq{ + SELECT subscription.*, biblio.*, serial.* + FROM serial + LEFT JOIN subscription ON serial.subscriptionid = subscription.subscriptionid + LEFT JOIN biblio ON serial.biblionumber = biblio.biblionumber + WHERE serial.serialid IN ($serialids_str) + }, {Slice => {}}, @$serialids); + + return unless @$serials; + + my $booksellerid = $serials->[0]->{aqbooksellerid}; + my $bookseller = Koha::Acquisition::Booksellers->find($booksellerid); + + my $userenv = C4::Context->userenv; + my $letter = GetPreparedLetter( + module => 'claimissues', + letter_code => $letter_code, + branchcode => $userenv->{branch}, + message_transport_type => 'print', + tables => { + 'branches' => $userenv->{branch}, + 'aqbooksellers' => $bookseller->unblessed, + }, + repeat => $serials, + want_librarian => 1, + ) or return; + + my $content = $letter->{content}; + if ($letter->{is_html}) { + $content = _wrap_html($content, $letter->{title}); + } + + my $output = ''; + my $pdf = PDF::FromHTML->new(encoding => 'utf-8'); + $pdf->load_file(\$content); + $pdf->convert(); + $pdf->write_file(\$output); + + return $output; +} + =head2 GetPreparedLetter( %params ) %params hash: diff --git a/cpanfile b/cpanfile index 6e13f04932..a1fc4eb219 100644 --- a/cpanfile +++ b/cpanfile @@ -133,6 +133,7 @@ recommends 'AnyEvent', '5.0'; recommends 'AnyEvent::HTTP', '2.13'; recommends 'Archive::Extract', '0.60'; recommends 'Archive::Zip', '1.30'; +recommends 'CAM::PDF', '1.60'; recommends 'CGI::Session::Driver::memcached', '0.04'; recommends 'DBD::SQLite2', '0.33'; recommends 'Devel::Cover', '0.89'; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/claims.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/claims.tt index 2ab6873e28..d1fad20a65 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/claims.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/claims.tt @@ -206,7 +206,16 @@ - +
+ + + +
[% END %] @@ -337,6 +346,20 @@ }); } + + [% END %] [% INCLUDE 'intranet-bottom.inc' %] diff --git a/serials/claims.pl b/serials/claims.pl index f988a6cc4f..aaa6e4e3e1 100755 --- a/serials/claims.pl +++ b/serials/claims.pl @@ -55,25 +55,38 @@ for my $s (@{$supplierlist} ) { my $additional_fields = Koha::AdditionalFields->search( { tablename => 'subscription', searchable => 1 } ); -my @serialnums=$input->multi_param('serialid'); +my @serialnums = $input->multi_param('serialid'); if (@serialnums) { # i.e. they have been flagged to generate claims - my $err; - eval { - $err = SendAlerts('claimissues',\@serialnums,$input->param("letter_code")); - if ( not ref $err or not exists $err->{error} ) { - C4::Serials::updateClaim( \@serialnums ); - } - }; - if ( $@ ) { - $template->param(error_claim => $@); - } elsif ( ref $err and exists $err->{error} ) { - if ( $err->{error} eq "no_email" ) { - $template->param( error_claim => 'no_vendor_email' ); - } elsif ( $err->{error} =~ m|Bad or missing From address| ) { - $template->param( error_claim => 'bad_or_missing_sender' ); - } + my $op = $input->param('op'); + my $letter_code = $input->param('letter_code'); + + if ($op eq 'print_alert') { + my $pdf = C4::Letters::PrintClaimIssueNotice(\@serialnums, $letter_code); + print $input->header( + -type => 'application/pdf', + -attachment => 'claims.pdf', + ); + print $pdf; + exit; } else { - $template->param( info_claim => 1 ); + my $err; + eval { + $err = SendAlerts('claimissues',\@serialnums, $letter_code); + if ( not ref $err or not exists $err->{error} ) { + C4::Serials::updateClaim( \@serialnums ); + } + }; + if ( $@ ) { + $template->param(error_claim => $@); + } elsif ( ref $err and exists $err->{error} ) { + if ( $err->{error} eq "no_email" ) { + $template->param( error_claim => 'no_vendor_email' ); + } elsif ( $err->{error} =~ m|Bad or missing From address| ) { + $template->param( error_claim => 'bad_or_missing_sender' ); + } + } else { + $template->param( info_claim => 1 ); + } } } diff --git a/t/db_dependent/Letters.t b/t/db_dependent/Letters.t index 4ba2105560..3a8d38e322 100755 --- a/t/db_dependent/Letters.t +++ b/t/db_dependent/Letters.t @@ -18,7 +18,7 @@ # along with Koha; if not, see . use Modern::Perl; -use Test::More tests => 83; +use Test::More tests => 84; use Test::MockModule; use Test::Warn; use Test::Exception; @@ -52,6 +52,7 @@ use t::lib::TestBuilder; use Koha::Database; use Koha::DateUtils qw( dt_from_string output_pref ); use Koha::Acquisition::Booksellers; +use Koha::Acquisition::Bookseller; use Koha::Acquisition::Bookseller::Contacts; use Koha::Acquisition::Orders; use Koha::Libraries; @@ -970,3 +971,42 @@ subtest 'Test message_id parameter for SendQueuedMessages' => sub { is( $message_1->{status}, 'pending', 'Message 1 status is unchanged' ); # Must be 'failed' is( $message_2->{status}, 'sent', 'Valid KohaAdminEmailAddress => status sent' ); }; + +subtest 'PrintClaimIssueNotice' => sub { + plan tests => 6; + + my $bookseller = Koha::Acquisition::Bookseller->new({ name => 'Bookie' })->store(); + my $subscriptionid = NewSubscription(undef, "", $bookseller->id, 0, undef, + $biblionumber, '2013-01-01', 1, undef, undef, undef, undef, undef, + undef, undef, undef, undef, 1, undef, undef, '2013-01-01', undef, 1, + undef, undef, 0, undef, 0, undef, undef, 0, undef, '2013-12-31', 0); + my ($serials_count, @serials) = GetSerials($subscriptionid); + + my $letter = 'CLAIMSERIAL'; + my $content = 'Date:<>'; + $dbh->do(qq{ + INSERT INTO letter + (module, code, name, is_html, title, content, message_transport_type) + VALUES + ('claimissues', '$letter', 'Claim', 1, 'Claim', '$content', 'print') + }); + + my @serialids = map { $_->{serialid} } @serials; + is(C4::Letters::PrintClaimIssueNotice(), undef, 'returns undef with no args'); + is(C4::Letters::PrintClaimIssueNotice(\@serialids), undef, 'returns undef with no letter code'); + is(C4::Letters::PrintClaimIssueNotice(undef, $letter), undef, 'returns undef with no serial ids'); + is(C4::Letters::PrintClaimIssueNotice([], $letter), undef, 'returns undef with no serial ids'); + + my $pdf = C4::Letters::PrintClaimIssueNotice(\@serialids, $letter); + is(substr($pdf, 0, 4), '%PDF', 'output is a PDF'); + + SKIP: { + eval { require CAM::PDF }; + + skip "CAM::PDF is not installed", 1 if $@; + + my $cam = CAM::PDF->new($pdf); + my $text = $cam->getPageContent(1); + like($text, qr/Date:2013-01-01/, 'PDF contains Date:2013-01-01'); + } +}; -- 2.20.1