From d53a943f79a3b698ea6ce0a56449f0d4a907bb7a Mon Sep 17 00:00:00 2001 From: David Cook Date: Mon, 12 Feb 2024 23:17:05 +0000 Subject: [PATCH] Bug 15565: Place multiple holds on one record on staff interface Signed-off-by: Lisette Scheer --- .../prog/en/modules/reserve/request.tt | 70 ++++++++++++++--- reserve/placerequest.pl | 78 +++++++++++-------- reserve/request.pl | 3 + 3 files changed, 108 insertions(+), 43 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt index c6a8bba700..8653094915 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt @@ -168,6 +168,56 @@ [% END %] + [% IF ( failed_holds ) %] +
+ One or more holds were not placed due to following errors: +
    + [% FOREACH fail IN failed_holds %] +
  • + [% SWITCH fail %] + [% CASE 'damaged' %] + Item is damaged + [% CASE 'ageRestricted' %] + The record and its items are age restricted + [% CASE 'tooManyHoldsForThisRecord' %] + Patron exceeded the number of concurrent holds for this record + [% CASE 'tooManyReservesToday' %] + Patron reached daily holds limit + [% CASE 'tooManyReserves' %] + Too many holds already + [% CASE 'notReservable' %] + Not holdable + [% CASE 'cannotReserveFromOtherBranches' %] + Patron from a different library + [% CASE 'branchNotInHoldGroup' %] + Holds are not allowed from patron's library + [% CASE 'itemAlreadyOnHold' %] + Patron already has a hold for failed item(s) + [% CASE 'cannotBeTransferred' %] + Cannot be transferred to pickup library + [% CASE 'pickupNotInHoldGroup' %] + The chosen pickup location is not allowed + [% CASE 'noReservesAllowed' %] + No holds are allowed on failed item(s) + [% CASE 'libraryNotPickupLocation' %] + Library is not a valid pickup location + [% CASE 'no_valid_pickup_location' %] + No valid pickup location + [% CASE 'notforloan' %] + Not for loan + [% CASE 'items_available' %] + There are items available in the library + [% CASE 'not_placed' %] + Error when placing hold + [% CASE %] + Error: [% fail | html %] + [% END %] +
  • + [% END %] +
+
+ [% END %] + [% UNLESS ( multi_hold ) %]

Place a hold on [% INCLUDE 'biblio-title.inc' link = 1 %] [% IF biblio.author %] by [% biblio.author | html %][% END %]

[% ELSE %] @@ -736,9 +786,9 @@ Hold must be item group level [% ELSIF ( itemloo.available ) %] - + [% ELSIF ( itemloo.override ) %] - + [% ELSE %] @@ -1507,11 +1557,11 @@ if ( ! $("#requestany").is(":checked") ) { // requestany not selected, go through the item-specific cases - if ( $('input[type="radio"]:checked').length > 0 ) { + if ( $('input[name="checkitem"]:checked').length > 0 ) { // got item-specific hold requests in the form! // verify they have a pickup location selected - if (table.find('input[type="radio"]:checked') + if (table.find('input[name="checkitem"]:checked') .closest('tr') .find(".pickup_locations").val() === null) { @@ -1602,15 +1652,17 @@ } }); $("input[name=checkitem]").click(function() { - onechecked = 0; + let onechecked = 0; $("input[name=checkitem]").each(function() { if(this.checked){ - onechecked = 1; + onechecked++; } }); - if(onechecked == 1){ + if(onechecked > 0){ $("#requestany").prop("checked", false); $("#holds_to_place_count").prop('disabled', true); + + $("#holds_to_place_count").val(onechecked); } else { $("#requestany").prop("checked",true); $("#holds_to_place_count").prop('disabled', false); @@ -1676,10 +1728,10 @@ [% IF Koha.Preference('EnableItemGroupHolds') %] $(':radio[name="item_group_id"]').change(function(){ - $(':radio[name="checkitem"]').prop('checked', false); + $('input[name="checkitem"]').prop('checked', false); }); - $(':radio[name="checkitem"]').change(function(){ + $('input[name="checkitem"]').change(function(){ $(':radio[name="item_group_id"]').prop('checked', false); }); [% END %] diff --git a/reserve/placerequest.pl b/reserve/placerequest.pl index d2fec975dd..48dd0636c5 100755 --- a/reserve/placerequest.pl +++ b/reserve/placerequest.pl @@ -44,7 +44,7 @@ my $branch = $input->param('pickup'); my $startdate = $input->param('reserve_date') || ''; my @rank = $input->multi_param('rank-request'); my $title = $input->param('title'); -my $checkitem = $input->param('checkitem'); +my @checkitems = $input->multi_param('checkitem'); my $item_group_id = $input->param('item_group_id'); my $expirationdate = $input->param('expiration_date'); my $itemtype = $input->param('itemtype') || undef; @@ -64,43 +64,48 @@ foreach my $bibnum ( @holdable_bibs ) { $bibinfos{$bibnum} = \%bibinfo; } -my $found; -if ( $op eq 'cud-placerequest' && $patron ) { +if ( $op eq 'cud-placerequest' && $patron ) { + my %failed_holds; foreach my $biblionumber ( keys %bibinfos ) { my $can_override = C4::Context->preference('AllowHoldPolicyOverride'); - if ( defined $checkitem && $checkitem ne '' ) { - - if ( my $item_pickup_location = $input->param("item_pickup_$checkitem") ) { + if ( @checkitems ) { + for ( my $i = 0; $i < scalar @checkitems; $i++ ){ + my $checkitem = $checkitems[$i]; + if ( my $item_pickup_location = $input->param("item_pickup_$checkitem") ) { - my $item = Koha::Items->find($checkitem); + my $item = Koha::Items->find($checkitem); - if ( $item->biblionumber ne $biblionumber ) { - $biblionumber = $item->biblionumber; - } - - my $can_item_be_reserved = CanItemBeReserved($patron, $item, $item_pickup_location)->{status}; + if ( $item->biblionumber ne $biblionumber ) { + $biblionumber = $item->biblionumber; + } - if ( $can_item_be_reserved eq 'OK' || ( $can_item_be_reserved ne 'itemAlreadyOnHold' && $can_override ) ) { - AddReserve( - { - branchcode => $item_pickup_location, - borrowernumber => $patron->borrowernumber, - biblionumber => $biblionumber, - priority => $rank[0], - reservation_date => $startdate, - expiration_date => $expirationdate, - notes => $notes, - title => $title, - itemnumber => $checkitem, - found => $found, - itemtype => $itemtype, - non_priority => $non_priority, - } - ); + my $can_item_be_reserved = CanItemBeReserved($patron, $item, $item_pickup_location)->{status}; + + if ( $can_item_be_reserved eq 'OK' || ( $can_item_be_reserved ne 'itemAlreadyOnHold' && $can_override ) ) { + AddReserve( + { + branchcode => $item_pickup_location, + borrowernumber => $patron->borrowernumber, + biblionumber => $biblionumber, + priority => $rank[$i], + reservation_date => $startdate, + expiration_date => $expirationdate, + notes => $notes, + title => $title, + itemnumber => $checkitem, + found => undef, + itemtype => $itemtype, + non_priority => $non_priority, + } + ); + } + else { + $failed_holds{$can_item_be_reserved} = 1; + } } } @@ -117,8 +122,8 @@ if ( $op eq 'cud-placerequest' && $patron ) { expiration_date => $expirationdate, notes => $notes, title => $bibinfo->{title}, - itemnumber => $checkitem, - found => $found, + itemnumber => undef, + found => undef, itemtype => $itemtype, non_priority => $non_priority, } @@ -138,8 +143,8 @@ if ( $op eq 'cud-placerequest' && $patron ) { expiration_date => $expirationdate, notes => $notes, title => $title, - itemnumber => $checkitem, - found => $found, + itemnumber => undef, + found => undef, itemtype => $itemtype, non_priority => $non_priority, item_group_id => $item_group_id, @@ -151,7 +156,12 @@ if ( $op eq 'cud-placerequest' && $patron ) { } my $redirect_url = URI->new("request.pl"); - $redirect_url->query_form( biblionumber => [@biblionumbers]); + my @failed_hold_msgs = (); + #NOTE: Deduplicate failed hold reason statuses/codes + foreach my $msg (keys %failed_holds){ + push(@failed_hold_msgs,$msg); + } + $redirect_url->query_form( biblionumber => [@biblionumbers], failed_holds => \@failed_hold_msgs); print $input->redirect($redirect_url); } elsif ( $borrowernumber eq '' ) { diff --git a/reserve/request.pl b/reserve/request.pl index 36e8eb2aad..023d7de424 100755 --- a/reserve/request.pl +++ b/reserve/request.pl @@ -88,6 +88,7 @@ my $warnings; my $messages; my $exceeded_maxreserves; my $exceeded_holds_per_record; +my @failed_holds = $input->multi_param('failed_holds'); my $op = $input->param('op') || q{}; @@ -709,6 +710,8 @@ $template->param( pickup => $pickup || C4::Context->userenv->{branch} ); $template->param(borrowernumber => $borrowernumber_hold); +$template->param( failed_holds => \@failed_holds ); + # printout the page output_html_with_http_headers $input, $cookie, $template->output; -- 2.30.2