Bug 40769: Display hold fees in staff client when placing holds

This patch adds hold fee information display in the staff client's hold
request interface, bringing it to feature parity with the OPAC.

The OPAC already shows patrons the fee that will be charged for placing
a hold, but the staff client did not display this information when staff
place holds on behalf of patrons. This creates a transparency gap where
staff cannot inform patrons about potential charges.

Changes:
- Import GetReserveFee function in reserve/request.pl
- Calculate reserve charges for each biblio record
- Display fee information in both single and multi-hold interfaces
- Show appropriate messaging based on HoldFeeMode system preference
- Use consistent formatting with currency display

Test Plan:
1. Set up hold fees:
   - Go to Administration > Patron categories
   - Edit a patron category and set a "Hold fee" (e.g., 1.00)
   - Ensure HoldFeeMode system preference is set (default: "only if all
     items are checked out and the record has at least one")

2. Test single hold with fee display:
   - Go to a bibliographic record
   - Click "Place hold"
   - Find a patron from the category with hold fees configured
   - Verify fee information displays after the title:
     * Shows "Note: [Patron Name] will be charged a hold fee of $1.00
       for placing this hold" when the HoldFeeMode is set to "any time
       a hold is placed"
     * Or "...when they collect this item" if HoldFeeMode is set to "any
       time a hold is collected"

3. Test multi-hold with fee display:
   - Ensure 'DisplayMultiPlaceHold' preference is set to 'Enable'
   - Search the catalog
   - On the search results page, select multiple biblios and click
     'Place hold'
   - Search for the same patron
   - In the confirmation table, verify each record shows:
     * "Hold fee: $1.00 (charged when placed)" in the Information column
     * Or "(charged when collected)" based on HoldFeeMode

4. Test no fee display:
   - Repeat tests with a patron from a category with no hold fee
   - Verify no fee information is displayed

5. Test different HoldFeeMode settings:
   - Change HoldFeeMode system preference to 'any_time_is_collected'
   - Verify messaging changes to "when they collect this item"
   - Test with 'not_always' mode and verify fee only shows when appropriate

6. Verify existing functionality:
   - Ensure hold placement still works normally
   - Verify all other hold interface elements remain unchanged
   - Test that holds are properly placed with or without fees

Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This commit is contained in:
Martin Renvoize 2025-09-08 15:41:58 +01:00 committed by Lucas Gass
parent fd87ee6edf
commit b322e3e959
No known key found for this signature in database
GPG Key ID: 60B447398B0D36CA
2 changed files with 46 additions and 1 deletions

View File

@ -285,6 +285,17 @@
[% UNLESS ( multi_hold ) %]
<h2>Place hold on [% INCLUDE 'biblio-title.inc' link = 1 %] [% IF biblio.author %]by [% biblio.author | html %][% END %]</h2>
[% IF ( patron && reserve_charge ) %]
<div class="alert alert-warning" id="reserve_fee">
[% IF Koha.Preference('HoldFeeMode') == 'any_time_is_collected' %]
<strong>Note:</strong> [% INCLUDE 'patron-title.inc' patron = patron no_title = 1 no_cardnumber = 1 hide_patron_infos_if_needed = 1 %] will be charged a hold fee of [% reserve_charge | $Price %] when they collect this
item
[% ELSE %]
<strong>Note:</strong> [% INCLUDE 'patron-title.inc' patron = patron no_title = 1 no_cardnumber = 1 hide_patron_infos_if_needed = 1 %] will be charged a hold fee of [% reserve_charge | $Price %] for placing this hold
[% END %]
</div>
[% END %]
[% ELSE %]
<h2>
[% IF ( patron ) %]
@ -463,6 +474,18 @@
[% IF ( biblioloo.publicationyear ) %]
<li> <span class="label">Publication year:</span> [% biblioloo.publicationyear | html %] </li>
[% END %]
[% IF ( patron && biblioloo.reserve_charge ) %]
<li>
<span class="label">Hold fee:</span>
[% IF Koha.Preference('HoldFeeMode') == 'any_time_is_collected' %]
[% biblioloo.reserve_charge | $Price %]
(charged when collected)
[% ELSE %]
[% biblioloo.reserve_charge | $Price %]
(charged when placed)
[% END %]
</li>
[% END %]
</ul>
[% IF ( biblioloo.warn ) %]
<span class="not_holdable" title="[% biblioloo.biblionumber | html %]"></span>
@ -1211,6 +1234,18 @@
[% IF ( biblioloo.publicationyear ) %]
<li> <span class="label">Publication year:</span> [% biblioloo.publicationyear | html %] </li>
[% END %]
[% IF ( patron && biblioloo.reserve_charge ) %]
<li>
<span class="label">Hold fee:</span>
[% IF Koha.Preference('HoldFeeMode') == 'any_time_is_collected' %]
[% biblioloo.reserve_charge | $Price %]
(charged when collected)
[% ELSE %]
[% biblioloo.reserve_charge | $Price %]
(charged when placed)
[% END %]
</li>
[% END %]
</ul>
[% IF ( biblioloo.warn ) %]
<span class="not_holdable" title="[% biblioloo.biblionumber | html %]"></span>

View File

@ -33,7 +33,7 @@ use Date::Calc qw( Date_to_Days );
use C4::Output qw( output_html_with_http_headers );
use C4::Auth qw( get_template_and_user );
use C4::Reserves
qw( AlterPriority ToggleLowestPriority CanBookBeReserved GetMaxPatronHoldsForRecord CanItemBeReserved IsAvailableForItemLevelRequest );
qw( AlterPriority ToggleLowestPriority CanBookBeReserved GetMaxPatronHoldsForRecord CanItemBeReserved IsAvailableForItemLevelRequest GetReserveFee );
use C4::Items qw( get_hostitemnumbers_of );
use C4::Koha qw( getitemtypeimagelocation );
use C4::Serials qw( CountSubscriptionFromBiblionumber );
@ -769,6 +769,11 @@ if ( ( $findborrower && $borrowernumber_hold || $findclub && $club_hold )
$biblioloopiter{rank} = $fixedRank;
$biblioloopiter{reserveloop} = \@reserveloop;
# Pass through any reserve charge
if ($patron) {
$biblioloopiter{reserve_charge} = GetReserveFee( $patron->borrowernumber, $biblionumber );
}
if (@reserveloop) {
$template->param( reserveloop => \@reserveloop );
}
@ -798,6 +803,11 @@ if ( ( $findborrower && $borrowernumber_hold || $findclub && $club_hold )
unless ($multi_hold) {
my $biblio = Koha::Biblios->find( $biblionumbers[0] );
$template->param( biblio => $biblio );
# Pass through any reserve charge for single holds
if ($borrowernumber_hold) {
$template->param( reserve_charge => GetReserveFee( $borrowernumber_hold, $biblionumbers[0] ) );
}
}
$template->param( biblionumbers => \@biblionumbers );