From: erickson Date: Wed, 13 Dec 2006 16:02:10 +0000 (+0000) Subject: updated opportunistic hold-capture logic to find the best hold and not necessarily... X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=294bfcdf5ad24b96dbf2faa6fd8791a369017556;p=Evergreen.git updated opportunistic hold-capture logic to find the best hold and not necessarily the hold that already targets the copy in question git-svn-id: svn://svn.open-ils.org/ILS/branches/rel_1_0@6686 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm index 72e87a1850..828902bdc3 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm @@ -1529,9 +1529,8 @@ sub attempt_checkin_hold_capture { my $copy = $self->copy; # See if this copy can fulfill any holds - my ($hold) = $holdcode->find_nearest_permitted_hold( - OpenSRF::AppSession->create('open-ils.storage'), - $copy, $self->editor->requestor ); + my ($hold) = $holdcode->find_nearest_permitted_hold( + $self->editor, $copy, $self->editor->requestor ); if(!$hold) { $logger->debug("circulator: no potential permitted". diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm index 14198eb9b9..b3589ef9d7 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm @@ -562,12 +562,10 @@ sub _hold_status { } - - -sub find_local_hold { - my( $class, $session, $copy, $user ) = @_; - return $class->find_nearest_permitted_hold($session, $copy, $user); -} +#sub find_local_hold { +# my( $class, $session, $copy, $user ) = @_; +# return $class->find_nearest_permitted_hold($session, $copy, $user); +#} sub fetch_open_hold_by_current_copy { @@ -1069,58 +1067,103 @@ sub verify_copy_for_hold { sub find_nearest_permitted_hold { my $class = shift; - my $session = shift; - my $copy = shift; - my $user = shift; + my $editor = shift; # CStoreEditor object + my $copy = shift; # copy to target + my $user = shift; # hold recipient + my $check_only = shift; # do no updates, just see if the copy could fulfill a hold my $evt = OpenILS::Event->new('ACTION_HOLD_REQUEST_NOT_FOUND'); - # first see if this copy has already been selected to fulfill a hold - my $hold = $session->request( - "open-ils.storage.direct.action.hold_request.search_where", - { current_copy => $copy->id, cancel_time => undef, capture_time => undef } )->gather(1); - - if( $hold ) { - $logger->info("hold found which can be fulfilled by copy ".$copy->id); - return $hold; - } + my $bc = $copy->barcode; - # We know this hold is permitted, so just return it - return $hold if $hold; + # find any existing holds that already target this copy + my $old_holds = $editor->search_action_hold_request( + { current_copy => $copy->id, + cancel_time => undef, + capture_time => undef + } + ); - $logger->debug("searching for potential holds at org ". - $user->ws_ou." and copy ".$copy->id); + $logger->info("circulator: searching for best hold at org ".$user->ws_ou." and copy $bc"); - my $holds = $session->request( + # search for what should be the best holds for this copy to fulfill + my $best_holds = $U->storagereq( "open-ils.storage.action.hold_request.nearest_hold.atomic", - $user->ws_ou, $copy->id, 5 )->gather(1); + $user->ws_ou, $copy->id, 10 ); - return (undef, $evt) unless @$holds; + unless(@$best_holds) { + + if( my $hold = $$old_holds[0] ) { + $logger->info("circulator: using existing pre-targeted hold ".$hold->id." in hold search"); + return ($hold); + } + + $logger->info("circulator: no suitable holds found for copy $bc"); + return (undef, $evt); + } + + + my $best_hold; # for each potential hold, we have to run the permit script # to make sure the hold is actually permitted. - - for my $holdid (@$holds) { + for my $holdid (@$best_holds) { next unless $holdid; - $logger->info("Checking if hold $holdid is permitted for user ".$user->id); - - my ($hold) = $U->fetch_hold($holdid); - next unless $hold; - my ($reqr) = $U->fetch_user($hold->requestor); + $logger->info("circulator: checking if hold $holdid is permitted for copy $bc"); - my ($rlib) = $U->fetch_org_unit($hold->request_lib); + my $hold = $editor->retrieve_action_hold_request($holdid) or next; + my $reqr = $editor->retrieve_actor_user($hold->requestor) or next; + my $rlib = $editor->retrieve_actor_org_unit($hold->request_lib) or next; - return ($hold) if OpenILS::Utils::PermitHold::permit_copy_hold( - { - patron_id => $hold->usr, + # see if this hold is permitted + my $permitted = OpenILS::Utils::PermitHold::permit_copy_hold( + { patron_id => $hold->usr, requestor => $reqr->id, copy => $copy, pickup_lib => $hold->pickup_lib, request_lib => $rlib, } ); + + if( $permitted ) { + $best_hold = $hold; + last; + } + } + + + unless( $best_hold ) { # no "good" permitted holds were found + if( my $hold = $$old_holds[0] ) { # can we return a pre-targeted hold? + $logger->info("circulator: using existing pre-targeted hold ".$hold->id." in hold search"); + return ($hold); + } + + # we got nuthin + $logger->info("circulator: no suitable holds found for copy $bc"); + return (undef, $evt); + } + + $logger->info("circulator: best hold ".$best_hold->id." found for copy $bc"); + + # indicate a permitted hold was found + return $best_hold if $check_only; + + # we've found a permitted hold. we need to "grab" the copy + # to prevent re-targeted holds (next part) from re-grabbing the copy + $best_hold->current_copy($copy->id); + $editor->update_action_hold_request($best_hold) + or return (undef, $editor->event); + + + # 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 + $logger->info("circulator: re-targeting hold ".$old_hold->id. + " after a better hold [".$best_hold->id."] was found"); + $U->storagereq( + 'open-ils.storage.action.hold_request.copy_targeter', undef, $old_hold->id ); } - return (undef, $evt); + return ($best_hold); } diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/ScriptBuilder.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/ScriptBuilder.pm index 2f007146a3..6e48b35128 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ/ScriptBuilder.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/ScriptBuilder.pm @@ -369,8 +369,7 @@ sub insert_copy_methods { $runner->insert_method( 'environment.copy', '__OILS_FUNC_fetch_best_hold', sub { my $key = shift; $logger->debug("script_builder: searching for permitted hold for copy ".$copy->barcode); - my ($hold) = $holdcode->find_nearest_permitted_hold( - OpenSRF::AppSession->create('open-ils.storage'), $copy, $reqr ); + my ($hold) = $holdcode->find_nearest_permitted_hold( $e, $copy, $reqr, 1 ); $runner->insert( $key, $hold, 1 ); } );