Bug 15565: Place multiple holds on one record on staff interface

Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de>
This commit is contained in:
David Cook 2024-02-12 23:17:05 +00:00 committed by Katrin Fischer
parent 1ff3d65c70
commit 1fc3bf1e34
No known key found for this signature in database
GPG Key ID: 0EF6E2C03357A834
3 changed files with 107 additions and 42 deletions

View File

@ -168,6 +168,56 @@
</div>
[% END %]
[% IF ( failed_holds ) %]
<div class="dialog alert">
<strong>One or more holds were not placed due to following errors:</strong>
<ul>
[% FOREACH fail IN failed_holds %]
<li>
[% SWITCH fail %]
[% CASE 'damaged' %]
<span>Item is damaged</span>
[% CASE 'ageRestricted' %]
<span>The record and its items are age restricted</span>
[% CASE 'tooManyHoldsForThisRecord' %]
<span>Patron exceeded the number of concurrent holds for this record</span>
[% CASE 'tooManyReservesToday' %]
<span>Patron reached daily holds limit</span>
[% CASE 'tooManyReserves' %]
<span>Too many holds already</span>
[% CASE 'notReservable' %]
<span>Not holdable</span>
[% CASE 'cannotReserveFromOtherBranches' %]
<span>Patron from a different library</span>
[% CASE 'branchNotInHoldGroup' %]
<span>Holds are not allowed from patron's library</span>
[% CASE 'itemAlreadyOnHold' %]
<span>Patron already has a hold for failed item(s)</span>
[% CASE 'cannotBeTransferred' %]
<span>Cannot be transferred to pickup library</span>
[% CASE 'pickupNotInHoldGroup' %]
<span>The chosen pickup location is not allowed</span>
[% CASE 'noReservesAllowed' %]
<span>No holds are allowed on failed item(s)</span>
[% CASE 'libraryNotPickupLocation' %]
<span>Library is not a valid pickup location</span>
[% CASE 'no_valid_pickup_location' %]
<span>No valid pickup location</span>
[% CASE 'notforloan' %]
<span>Not for loan</span>
[% CASE 'items_available' %]
<span>There are items available in the library</span>
[% CASE 'not_placed' %]
<span>Error when placing hold</span>
[% CASE %]
<span>Error: [% fail | html %]</span>
[% END %]
</li>
[% END %]
</ul>
</div>
[% END %]
[% UNLESS ( multi_hold ) %]
<h2>Place a hold on [% INCLUDE 'biblio-title.inc' link = 1 %] [% IF biblio.author %] by [% biblio.author | html %][% END %]</h2>
[% ELSE %]
@ -754,9 +804,9 @@
Hold must be item group level
</span>
[% ELSIF ( itemloo.available ) %]
<input type="radio" name="checkitem" value="[% itemloo.itemnumber | html %]" />
<input type="checkbox" name="checkitem" value="[% itemloo.itemnumber | html %]" />
[% ELSIF ( itemloo.override ) %]
<input type="radio" name="checkitem" class="needsoverride" value="[% itemloo.itemnumber | html %]" />
<input type="checkbox" name="checkitem" class="needsoverride" value="[% itemloo.itemnumber | html %]" />
<i class="fa fa-exclamation-triangle fa-lg" style="color:gold" title="Requires override of hold policy"/></i>
[% ELSE %]
<span class="error">
@ -1526,11 +1576,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) {
@ -1621,15 +1671,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);
@ -1695,10 +1747,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 %]

View File

@ -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 ) {
my %failed_holds;
foreach my $biblionumber ( keys %bibinfos ) {
my $can_override = C4::Context->preference('AllowHoldPolicyOverride');
if ( defined $checkitem && $checkitem ne '' ) {
if ( @checkitems ) {
for ( my $i = 0; $i < scalar @checkitems; $i++ ){
my $checkitem = $checkitems[$i];
if ( my $item_pickup_location = $input->param("item_pickup_$checkitem") ) {
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;
}
if ( $item->biblionumber ne $biblionumber ) {
$biblionumber = $item->biblionumber;
}
my $can_item_be_reserved = CanItemBeReserved($patron, $item, $item_pickup_location)->{status};
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[0],
reservation_date => $startdate,
expiration_date => $expirationdate,
notes => $notes,
title => $title,
itemnumber => $checkitem,
found => $found,
itemtype => $itemtype,
non_priority => $non_priority,
}
);
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 '' ) {

View File

@ -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{};
@ -724,6 +725,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;