Bug 17561: ReserveSlip needs itemnumber for item level holds on same biblio
authorBenjamin Rokseth <benjamin.rokseth@deichman.no>
Thu, 15 Mar 2018 11:57:37 +0000 (12:57 +0100)
committerNick Clemens <nick@bywatersolutions.com>
Mon, 4 Jun 2018 17:40:36 +0000 (13:40 -0400)
This patch fixes a regression after bug 14695.
This patch adds itemnumber and barcode as optional params in ReserveSlip used
by hold-transfer-slip.pl to generate HOLD_SLIP. This is for ReserveSlip to be
able to generate correct slips when items in multi-item holds are checked in.

Test plan:

1) activate a circulation rule with multi-item holds
2) Place two holds on same biblio for patron
3) for debugging, either use browser console to observe POST request and responses
   or use info from reserves, e.g. reserve_id in the HOLD_SLIP
4) checkin two items from same biblio on pickup branch
5) note that both holds are effectuated, but reserve_id is the same on both slips
6) also note that there is no itemnumber or barcode in the requests from returns.pl
7) Apply this patch
8) repeat 2-4
9) note that reserve_id is now different on the two slips

and/or:
Run tests:
  t/db_dependent/Reserves/ReserveSlip.t

Signed-off-by: Brendan Gallagher <brendan@bywatersolutions.com>
Signed-off-by: Maksim Sen <maksim.sen@inlibro.com>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>

C4/Reserves.pm
circ/hold-transfer-slip.pl
koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt
t/db_dependent/Reserves/ReserveSlip.t [new file with mode: 0644]

index c0a977f..e7fc3c1 100644 (file)
@@ -1868,7 +1868,13 @@ sub RevertWaitingStatus {
 
 =head2 ReserveSlip
 
-  ReserveSlip($branchcode, $borrowernumber, $biblionumber)
+  ReserveSlip($args => {
+      branchcode,
+      borrowernumber,
+      biblionumber,
+      [itemnumber],
+      [barcode],
+  })
 
 Returns letter hash ( see C4::Letters::GetPreparedLetter ) or undef
 
@@ -1885,19 +1891,28 @@ available within the slip:
 =cut
 
 sub ReserveSlip {
-    my ($branch, $borrowernumber, $biblionumber) = @_;
+    my ($args) = @_;
+    my $patron = Koha::Patrons->find( $args->{borrowernumber} );
 
-#   return unless ( C4::Context->boolean_preference('printreserveslips') );
-    my $patron = Koha::Patrons->find( $borrowernumber );
+    my $hold;
+    if ($args->{itemnumber}) {
+        $hold = Koha::Holds->search({biblionumber => $args->{biblionumber}, borrowernumber => $args->{borrowernumber}, itemnumber => $args->{itemnumber} })->next;
+    } elsif ($args->{barcode}) {
+        my $itemnumber = Koha::Items->find({ barcode => $args->{barcode} });
+        if ($args->{itemnumber}) {
+            $hold = Koha::Holds->search({biblionumber => $args->{biblionumber}, borrowernumber => $args->{borrowernumber}, itemnumber => $args->{itemnumber} })->next;
+        }
+    } else {
+        $hold = Koha::Holds->search({biblionumber => $args->{biblionumber}, borrowernumber => $args->{borrowernumber} })->next;
+    }
 
-    my $hold = Koha::Holds->search({biblionumber => $biblionumber, borrowernumber => $borrowernumber })->next;
     return unless $hold;
     my $reserve = $hold->unblessed;
 
     return  C4::Letters::GetPreparedLetter (
         module => 'circulation',
         letter_code => 'HOLD_SLIP',
-        branchcode => $branch,
+        branchcode => $args->{branchcode},
         lang => $patron->lang,
         tables => {
             'reserves'    => $reserve,
index 115a434..328f481 100755 (executable)
@@ -37,9 +37,11 @@ my $session = get_session($sessionID);
 
 my $biblionumber = $input->param('biblionumber');
 my $borrowernumber = $input->param('borrowernumber');
+my $itemnumber = $input->param('itemnumber');
+my $barcode = $input->param('barcode');
 
 my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
-    {   
+    {
         template_name   => "circ/printslip.tt",
         query           => $input,
         type            => "intranet",
@@ -51,7 +53,13 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
 
 my $userenv = C4::Context->userenv;
 my ($slip, $is_html);
-if ( my $letter = ReserveSlip ($session->param('branch') || $userenv->{branch}, $borrowernumber, $biblionumber) ) {
+if ( my $letter = ReserveSlip ({
+    branchcode     => $session->param('branch') || $userenv->{branch},
+    borrowernumber => $borrowernumber,
+    biblionumber   => $biblionumber,
+    itemnumber     => $itemnumber,
+    barcode        => $barcode,
+}) ) {
     $slip = $letter->{content};
     $is_html = $letter->{is_html};
 }
index b2c8834..d495539 100644 (file)
     <input type="hidden" name="borrowernumber" value="[% patron.borrowernumber %]" />
     <input type="hidden" name="duedatespec" value="[% duedatespec %]" />
     <input type="hidden" name="stickyduedate" value="[% stickyduedate %]" />
-    <button class="print" type="submit" onclick="Dopop('hold-transfer-slip.pl?borrowernumber=[% reserveborrowernumber %]&amp;biblionumber=[% itembiblionumber %]&amp;op=slip');this.form.submit();"><i class="fa fa-print"></i> Don't check out and print slip (P)</button>
+    <button class="print" type="submit" onclick="Dopop('hold-transfer-slip.pl?borrowernumber=[% reserveborrowernumber %]&amp;biblionumber=[% itembiblionumber %]&amp;itemnumber=[% itemnumber %]&amp;op=slip');this.form.submit();"><i class="fa fa-print"></i> Don't check out and print slip (P)</button>
 </form>
 [% END %]
 
     <input type="hidden" name="borrowernumber" value="[% patron.borrowernumber %]" />
     <input type="hidden" name="duedatespec" value="[% duedatespec %]" />
     <input type="hidden" name="stickyduedate" value="[% stickyduedate %]" />
-    <button class="print" type="submit" onclick="Dopop('hold-transfer-slip.pl?borrowernumber=[% reserveborrowernumber %]&amp;biblionumber=[% itembiblionumber %]&amp;op=slip');this.form.submit();"><i class="fa fa-print"></i> Don't check out and print slip (P)</button>
+    <button class="print" type="submit" onclick="Dopop('hold-transfer-slip.pl?borrowernumber=[% reserveborrowernumber %]&amp;biblionumber=[% itembiblionumber %]&amp;itemnumber=[% itemnumber %]&amp;op=slip');this.form.submit();"><i class="fa fa-print"></i> Don't check out and print slip (P)</button>
 </form>
 [% END %]
 
diff --git a/t/db_dependent/Reserves/ReserveSlip.t b/t/db_dependent/Reserves/ReserveSlip.t
new file mode 100644 (file)
index 0000000..9b28179
--- /dev/null
@@ -0,0 +1,165 @@
+#!/usr/bin/perl
+
+# Copyright 2016 Oslo Public Library
+#
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Koha is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
+
+use Modern::Perl;
+
+use Test::More tests => 5;
+use t::lib::TestBuilder;
+
+use C4::Reserves qw( ReserveSlip );
+use C4::Context;
+use Koha::Database;
+use Koha::Holds;
+my $schema = Koha::Database->new->schema;
+$schema->storage->txn_begin;
+
+my $dbh = C4::Context->dbh;
+$dbh->do(q|DELETE FROM letter|);
+$dbh->do(q|DELETE FROM reserves|);
+
+my $builder = t::lib::TestBuilder->new();
+my $library = $builder->build(
+    {
+        source => 'Branch',
+    }
+);
+
+my $patron = $builder->build(
+    {
+        source => 'Borrower',
+        value  => {
+            branchcode => $library->{branchcode},
+        },
+    }
+);
+
+
+my $biblio = $builder->build(
+    {
+        source => 'Biblio',
+        value  => {
+            title => 'Title 1',
+        },
+    }
+);
+
+my $item1 = $builder->build(
+    {
+        source => 'Item',
+        value  => {
+            biblionumber  => $biblio->{biblionumber},
+            homebranch    => $library->{branchcode},
+            holdingbranch => $library->{branchcode},
+        },
+    }
+);
+
+my $item2 = $builder->build(
+    {
+        source => 'Item',
+        value  => {
+            biblionumber  => $biblio->{biblionumber},
+            homebranch    => $library->{branchcode},
+            holdingbranch => $library->{branchcode},
+        },
+    }
+);
+
+my $hold1 = Koha::Hold->new(
+    {
+        biblionumber   => $biblio->{biblionumber},
+        itemnumber     => $item1->{itemnumber},
+        waitingdate    => '2000-01-01',
+        borrowernumber => $patron->{borrowernumber},
+        branchcode     => $library->{branchcode},
+    }
+)->store;
+
+my $hold2 = Koha::Hold->new(
+    {
+        biblionumber   => $biblio->{biblionumber},
+        itemnumber     => $item2->{itemnumber},
+        waitingdate    => '2000-01-01',
+        borrowernumber => $patron->{borrowernumber},
+        branchcode     => $library->{branchcode},
+    }
+)->store;
+
+my $letter = $builder->build(
+    {
+        source => 'Letter',
+        value  => {
+            module => 'circulation',
+            code   => 'HOLD_SLIP',
+            lang   => 'default',
+            branchcode => $library->{branchcode},
+            content => 'Hold found for <<borrowers.firstname>>: Please pick up <<biblio.title>> with barcode <<items.barcode>> at <<branches.branchcode>>.',
+            message_transport_type => 'email',
+        },
+    }
+);
+
+is ( ReserveSlip(), undef, "No hold slip returned if invalid or undef borrowernumber and/or biblionumber" );
+is ( ReserveSlip({
+        branchcode     => $library->{branchcode},
+        borrowernumber => $patron->{borrowernumber},
+        biblionumber   => $biblio->{biblionumber},
+    })->{code},
+    'HOLD_SLIP', "Get a hold slip from library, patron and biblio" );
+
+is (ReserveSlip({
+        branchcode     => $library->{branchcode},
+        borrowernumber => $patron->{borrowernumber},
+        biblionumber   => $biblio->{biblionumber},
+    })->{content},
+    "Hold found for $patron->{firstname}: Please pick up $biblio->{title} with barcode $item1->{barcode} at $library->{branchcode}.", "Hold slip contains correctly parsed content");
+
+is_deeply(
+    ReserveSlip({
+        branchcode     => $library->{branchcode},
+        borrowernumber => $patron->{borrowernumber},
+        biblionumber   => $biblio->{biblionumber},
+    }),
+    ReserveSlip({
+        branchcode     => $library->{branchcode},
+        borrowernumber => $patron->{borrowernumber},
+        biblionumber   => $biblio->{biblionumber},
+        itemnumber     => $item1->{itemnumber},
+        barcode        => $item1->{barcode},
+    }),
+    "No item as param generate hold slip from first item in reserves");
+
+isnt (
+    ReserveSlip({
+        branchcode     => $library->{branchcode},
+        borrowernumber => $patron->{borrowernumber},
+        biblionumber   => $biblio->{biblionumber},
+    })->{content},
+    ReserveSlip({
+        branchcode     => $library->{branchcode},
+        borrowernumber => $patron->{borrowernumber},
+        biblionumber   => $biblio->{biblionumber},
+        itemnumber     => $item2->{itemnumber},
+        barcode        => $item2->{barcode},
+    })->{content},
+    "Item and/or barcode as params return correct pickup item in hold slip");
+
+$schema->storage->txn_rollback;
+
+1;