From 5ff47a80a182a332f72e78cc5c718ab1f7d774c3 Mon Sep 17 00:00:00 2001 From: Nick Clemens Date: Fri, 21 Nov 2025 18:46:12 +0000 Subject: [PATCH] Bug 41282: Alert staff when patron's hold is filled at checkout When an item is checked out and the patron has a hold on the biblio we will fill thart hold with the item in hand Sometimes the hold this item fills has another copy that is already in transit or waiting on the shelf. We need to alert staff when this happens This patch adds a return of the hold from MoveReserve and adds an object message to the issue that is passed to the template If the hold was waiting or in transit we additionally pass a message in the hold that is returned To test: 1 - Place a biblio level hold for a patron 2 - Check an item from the biblio in and confirm the hold 3 - Check out a different item from the biblio to the patron 4 - Note the hold is filled, but there is no notice 5 - Apply the patch 6 - Repeat 1-3, note there is now a notice that a waiting hold was filled 7 - Place another hold for the patron for delivery at current branch 8 - Check the item in at a different branch and confirm transfer 9 - Switch back to first branch and check a different item from the biblio out to the patron 10 - Confirm the hold is filled and you are notified that a hold in transit was filled --- C4/Circulation.pm | 4 +++- C4/Reserves.pm | 11 +++++++++- .../prog/en/modules/circ/circulation.tt | 22 +++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 0a8df342638..433c8774d80 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -1608,6 +1608,7 @@ sub AddIssue { my $barcodecheck = CheckValidBarcode($barcode); my $issue; + my $filled_hold; if ( $datedue && ref $datedue ne 'DateTime' ) { $datedue = dt_from_string($datedue); @@ -1716,7 +1717,7 @@ sub AddIssue { ); } - C4::Reserves::MoveReserve( $item_object, $patron, $cancelreserve ); + $filled_hold = C4::Reserves::MoveReserve( $item_object, $patron, $cancelreserve ); # Starting process for transfer job (checking transfer and validate it if we have one) if ( my $transfer = $item_object->get_transfer ) { @@ -1989,6 +1990,7 @@ sub AddIssue { if C4::Context->preference('RealTimeHoldsQueue'); } } + $issue->add_message( { type => 'hold_filled', payload => $filled_hold, message => 'F' } ); return $issue; } diff --git a/C4/Reserves.pm b/C4/Reserves.pm index c4eb3b7ff69..7249e1a9fe7 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -2174,7 +2174,7 @@ sub _ShiftPriority { =head2 MoveReserve - MoveReserve( $item, $patron, $cancelreserve ) + my $filled_hold = MoveReserve( $item, $patron, $cancelreserve ) Use when checking out an item to handle reserves If $cancelreserve boolean is set to true, it will remove existing reserve @@ -2204,6 +2204,7 @@ sub MoveReserve { if ( $res && $res->{borrowernumber} == $patron->borrowernumber ) { my $hold = Koha::Holds->find( $res->{reserve_id} ); $hold->fill( { item_id => $item->id } ); + return $hold; } else { # The item is reserved by someone else. @@ -2227,7 +2228,14 @@ sub MoveReserve { if ($hold) { # The item is reserved by the current patron + # if we are filling a hold previously found we need to alert the staff + if ( $hold->found() eq 'W' ) { + $hold->add_message( { message => "W", type => 'filled_waiting' } ); + } elsif ( $hold->found() eq 'T' ) { + $hold->add_message( { message => "T", type => 'filled_transit' } ); + } $hold->fill( { item_id => $item->id } ); + return $hold; } $hold = Koha::Holds->find( $res->{reserve_id} ); @@ -2237,6 +2245,7 @@ sub MoveReserve { $hold->cancel; } } + return; } =head2 MergeHolds diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt index 672d27da176..9183d200ce6 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt @@ -963,6 +963,28 @@ [% END %] Due on [% issue.date_due | $KohaDates as_due_date => 1 %]

+ [%- SET issue_messages = issue.object_messages %] + [%- IF (issue_messages.size) %] +
+ [%- FOREACH message IN issue_messages %] + [%- IF (message.type == 'hold_filled') %] +

+ [%- SET hold = message.payload %] + [%- SET hold_messages = hold.object_messages -%] + [%- FOREACH message IN hold_messages %] + [%- IF (message.type == 'filled_transit') %] + This item filled a hold that had another item in-transit to this patron + [%- ELSIF (message.type == 'filled_waiting') %] + This item filled a hold that had another item waiting on the shelf for this patron, please check the holds shelf and check in any other copies. + [%- END %] + [%- END %] +

+ [%- ELSE %] +

Message type: ([% message.type | html %]) Message: [% message.message | html %]

+ [%- END %] + [%- END %] +
+ [%- END %] [% END %] -- 2.39.5