From 9d9748b0149cd991fae7e548aab832e96829e503 Mon Sep 17 00:00:00 2001 From: Mike Rylander Date: Tue, 10 Nov 2020 13:14:14 -0500 Subject: [PATCH] LP#1903749: WIP - allow adjacent-copy capture during stalling Currently, setting a stalling interval disable all opportunistic capture except at the pickup library. It would be helpful to allow, optionally, a mode where holds that target a copy physically adjacent to the copy that staff pull from the shelf to fill the hold, all else being equal. This commit does that by: 1) confirming that hold stalling and the a new setting are both in use 2) gathering shelf-adjacent copies that are available 3) gathering holds that directly target those adjacent copies 4) filtering those hold to only those that the copy in hand could fill 5) adding that filtered list to the end of the $old_holds list for last-resort capture testing 6) avoiding retargetting of adjacent-copy-targetted holds, they can still capture TODO: be more flexible for criteria? Signed-off-by: Mike Rylander Signed-off-by: Michele Morgan --- .../perlmods/lib/OpenILS/Application/Circ/Holds.pm | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm index d0b5136640..39cfe80271 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm @@ -3409,6 +3409,42 @@ sub find_nearest_permitted_hold { "open-ils.storage.action.hold_request.nearest_hold.atomic", $user->ws_ou, $copy, 100, $hold_stall_interval, $fifo ); + if ($hold_stall_interval) { + my $adjacent_target_while_stalling = $U->ou_ancestor_setting_value( + $user->ws_ou, 'circ.holds.adjacent_target_while_stalling' + ); + + if ($adjacent_target_while_stalling) { + my $my_cns = $editor->search_asset_call_number({ + record => $copy->call_number->record, + deleted => 'f' + }); + + my $other_copies = $editor->search_asset_copy({ + call_number => [map {$_->id} @$my_cns], + circ_lib => $copy->circ_lib, + deleted => 'f', + status => 0, + id => { '<>' => $copy->id } + }); + + my $other_holds = $editor->search_action_hold_request({ + current_copy => [ map {$_->id} @$other_copies], + cancel_time => undef, + capture_time => undef + }); + + my $adjacent_hold_maps = $editor->search_action_hold_copy_map({ + hold => [map {$_->id} @$other_holds], + target_copy => $copy->id + }); + + for my $other_hold (@$other_holds) { + push(@$old_holds, $other_hold) if ( grep { $other_hold->id == $_->hold } @$adjacent_hold_maps ); + } + } + } + # Add any pre-targeted holds to the list too? Unless they are already there, anyway. if ($old_holds) { for my $holdid (@$old_holds) { @@ -3487,6 +3523,7 @@ sub find_nearest_permitted_hold { # re-target any other holds that already target this copy for my $old_hold (@$old_holds) { next if $old_hold->id eq $best_hold->id; # don't re-target the hold we want + next unless $old_hold->current_copy eq $copy->id; # don't re-target adjacent-copy holds $logger->info("circulator: clearing current_copy and prev_check_time on hold ". $old_hold->id." after a better hold [".$best_hold->id."] was found"); $old_hold->clear_current_copy; -- 2.11.0