Bug 38412: Display warning on biblio level

When no item is available, with AllowHoldPolicyOverride, a triangle appears on
    each item to be forced, but if you choose “next item available” without
    having  any item available, you won't see anything. Additionally, the top
    warning message about "No items are available" does not show when
    'AllowHoldPolicyOverride' is set to allow and no items are available
    (e.g. withdrawn, lost, damanged, depending on settings)

This patch corrects an error in request.pl where no incrementation of
    $num_override happens when an item is forced. This causes the warning
    triangle to appear on the 'Place hold' button on the bib level. The top
    warning message is restored as well.

 Finally, this patch changes the display of the fa-warning-triangle icon on the
    'Place hold' buttons to increase contrast with the button color, making it
    easier to see and increasing accessibility.

Test plan:
1) Set circulations rules for specific category and/or itemtype (for example 1
    hold allowed for staff on books). Set AllowHoldPolicyOverride on "Allow".
2) Search for a book biblio with multiple items, and set each item to a
    non-circulating status (withdrawn, lost, etc.)
3) Place a hold for a staff category patron for this bib record.
4) Normally you will see triangles on each item on specific section but you can
    force it. When you just select the next item available none triangle and
    none alert showing.
5) Apply this patch and restart_all.
6) Refresh your browser page.
7) Normally now there is a triangle into 'Place hold' submit button and an
    alert message appears on the top of the page. The triangle is also more
    visible.
8) Test other hold limits, such as max holds per record, to ensure the
    appropriate top alert message appears and the triangle alert appears on
    the 'Place hold' button.

Co-authored-by: Thibaud Guillot <thibaud.guillot@biblibre.com>
Sponsored-by: BibLibre
Sponsored-by: Westlake Porter Public Library <https://westlakelibrary.org>
Signed-off-by: Emily Lamancusa <emily.lamancusa@montgomerycountymd.gov>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 1900effc9b)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
(cherry picked from commit 9827914216)
Signed-off-by: Fridolin Somers <fridolin.somers@biblibre.com>
This commit is contained in:
CJ Lynce 2025-07-11 17:02:17 +00:00 committed by Fridolin Somers
parent 3de53001d4
commit 56f439ea9f
No known key found for this signature in database
GPG Key ID: 9A8E73E2A8B96537
2 changed files with 16 additions and 6 deletions

View File

@ -471,7 +471,7 @@
</div>
[% END %]
[% IF ( no_reserves_allowed || exceeded_maxreserves || exceeded_holds_per_record || alreadyreserved || none_available || alreadypossession || ageRestricted || recall ) %]
[% IF ( no_reserves_allowed || exceeded_maxreserves || exceeded_holds_per_record || alreadyreserved || none_available || none_available_override || alreadypossession || ageRestricted || recall ) %]
<div class="alert alert-warning">
[% UNLESS ( multi_hold ) %]
@ -489,7 +489,7 @@
<li>[% INCLUDE 'patron-title.inc' patron => patron no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 %] <strong>already has a hold</strong> on this item.</li>
[% ELSIF ( ageRestricted ) %]
<li><strong>Age restricted</strong></li>
[% ELSIF ( none_available ) %]
[% ELSIF ( none_available || none_available_override ) %]
<li> <strong>No items are available</strong> to be placed on hold.</li>
[% ELSIF ( maxreserves ) %]
<li><strong>Too many holds:</strong> [% INCLUDE 'patron-title.inc' patron => patron no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 %] has too many holds.</li>
@ -680,7 +680,7 @@
<fieldset class="action">
[% IF ( patron.borrowernumber ) %]
[% IF ( override_required ) %]
<button type="submit" id="hold_grp_btn" class="btn btn-primary warning"><i class="fa fa-exclamation-triangle "></i> Place hold</button>
<button type="submit" id="hold_grp_btn" class="btn btn-primary"><i class="fa fa-exclamation-triangle "></i> Place hold</button>
[% ELSIF ( none_available ) %]
<button type="submit" id="hold_grp_btn" disabled="disabled" class="btn btn-primary btn-disabled">Place hold</button>
[% ELSE %]
@ -780,7 +780,7 @@
<fieldset class="action">
[% IF ( patron.borrowernumber ) %]
[% IF ( override_required ) %]
<button type="submit" id="hold_any_btn" class="btn btn-primary warning"><i class="fa fa-exclamation-triangle "></i> Place hold</button>
<button type="submit" id="hold_any_btn" class="btn btn-primary"><i class="fa fa-exclamation-triangle "></i> Place hold</button>
[% ELSIF ( none_available ) %]
<button type="submit" id="hold_any_btn" disabled="disabled" class="btn btn-primary btn-disabled">Place hold</button>
[% ELSE %]
@ -1039,7 +1039,7 @@
<fieldset class="action">
[% IF ( patron.borrowernumber ) %]
[% IF ( override_required ) %]
<button type="submit" id="hold_item_btn" class="btn btn-primary warning"><i class="fa fa-exclamation-triangle "></i> Place hold</button>
<button type="submit" id="hold_item_btn" class="btn btn-primary"><i class="fa fa-exclamation-triangle "></i> Place hold</button>
[% ELSIF ( none_available ) %]
<button type="submit" id="hold_item_btn" disabled="disabled" class="btn btn-primary btn-disabled">Place hold</button>
[% ELSE %]
@ -1197,7 +1197,7 @@
<fieldset class="action">
[% IF ( patron AND patron.borrowernumber ) %]
[% IF ( override_required ) %]
<button type="submit" id="hold_multi_btn" class="btn btn-primary warning"><i class="fa fa-exclamation-triangle "></i> Place holds</button>
<button type="submit" id="hold_multi_btn" class="btn btn-primary "><i class="fa fa-exclamation-triangle "></i> Place holds</button>
[% ELSIF ( no_bibs_available ) %]
<button type="submit" id="hold_multi_btn" class="btn btn-primary btn-disabled" disabled="disabled">Place holds</button>
[% ELSIF ( none_available ) %]

View File

@ -401,6 +401,7 @@ if ( ( $findborrower && $borrowernumber_hold || $findclub && $club_hold )
my $num_override = 0;
my $hiddencount = 0;
my $num_alreadyheld = 0;
my $valid_items = 0;
# iterating through all items first to check if any of them available
# to pass this value further inside down to IsAvailableForItemLevelRequest to
@ -522,6 +523,11 @@ if ( ( $findborrower && $borrowernumber_hold || $findclub && $club_hold )
&& IsAvailableForItemLevelRequest($item_object, $patron, undef)
)
{
$valid_items = 1;
}
if ($valid_items) {
# Send the pickup locations count to the UI, the pickup locations will be pulled using the API
my $pickup_locations = $item_object->pickup_locations({ patron => $patron });
$item->{pickup_locations_count} = $pickup_locations->count;
@ -550,6 +556,7 @@ if ( ( $findborrower && $borrowernumber_hold || $findclub && $club_hold )
if ( @pickup_locations || C4::Context->preference('AllowHoldPolicyOverride') ) {
$num_items_available++;
$item->{override} = 1;
$num_override++;
my $default_pickup_location;
@ -590,6 +597,9 @@ if ( ( $findborrower && $borrowernumber_hold || $findclub && $club_hold )
if ( $num_override > 0 && ($num_override + $num_alreadyheld) == scalar( @{ $biblioloopiter{itemloop} } ) ) {
# That is, if all items require an override
$template->param( override_required => 1 );
if ( $valid_items == 0 ) {
$template->param( none_available_override => 1 );
}
} elsif ( $num_items_available == 0 ) {
$template->param( none_available => 1 );
$biblioloopiter{warn} = 1;