From: erickson Date: Mon, 5 Feb 2007 19:14:23 +0000 (+0000) Subject: for title hold possibility check, we now sort copies into buckets based X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=c2b0a00e09c91f03f9eb4d314550ddb72ad6beab;p=Evergreen.git for title hold possibility check, we now sort copies into buckets based on the copy circ lib. then we check "closest" copies first since they are the more likely to be allowed, and therefore allow the possibility check to succeed. git-svn-id: svn://svn.open-ils.org/ILS/branches/rel_1_0@6879 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm index ef708c0b24..9d37096ec7 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm @@ -1046,7 +1046,7 @@ sub check_title_hold { -sub _check_title_hold_is_possible { +sub ___check_title_hold_is_possible { my( $titleid, $rangelib, $depth, $request_lib, $patron, $requestor, $pickup_lib ) = @_; my $limit = 10; @@ -1081,6 +1081,120 @@ sub _check_title_hold_is_possible { return 0; } +my %prox_cache; + +sub _check_title_hold_is_possible { + my( $titleid, $rangelib, $depth, $request_lib, $patron, $requestor, $pickup_lib ) = @_; + + my $e = new_editor(); + + # this monster will grab the id and circ_lib of all of the "holdable" copies for the given record + my $copies = $e->json_query( + { + select => { acp => ['id', 'circ_lib'] }, + from => { + acp => { + acn => { + field => 'id', + fkey => 'call_number', + 'join' => { + bre => { + field => 'id', + filter => { id => $titleid }, + fkey => 'record' + } + } + }, + acpl => { field => 'id', filter => { holdable => 't'}, fkey => 'location' }, + ccs => { field => 'id', filter => { holdable => 't'}, fkey => 'status' } + } + }, + where => { + '+acp' => { circulate => 't', deleted => 'f', holdable => 't' } + } + } + ); + + return $e->event unless defined $copies; + $logger->info("title possible found ".scalar(@$copies)." potential copies"); + return 0 unless @$copies; + + # ----------------------------------------------------------------------- + # sort the copies into buckets based on their circ_lib proximity to + # the patron's home_ou. + # ----------------------------------------------------------------------- + + my $home_org = $patron->home_ou; + my $req_org = $request_lib->id; + + my $home_prox = + ($prox_cache{$home_org}) ? + $prox_cache{$home_org} : + $prox_cache{$home_org} = $e->search_actor_org_unit_proximity({from_org => $home_org}); + + my %buckets; + my %hash = map { ($_->to_org => $_->prox) } @$home_prox; + push( @{$buckets{ $hash{$_->{circ_lib}} } }, $_->{id} ) for @$copies; + + my @keys = sort { $a <=> $b } keys %buckets; + + + if( $home_org ne $req_org ) { + # ----------------------------------------------------------------------- + # shove the copies close to the request_lib into the primary buckets + # directly before the farthest away copies. That way, they are not + # given priority, but they are checked before the farthest copies. + # ----------------------------------------------------------------------- + my $req_prox = + ($prox_cache{$req_org}) ? + $prox_cache{$req_org} : + $prox_cache{$req_org} = $e->search_actor_org_unit_proximity({from_org => $req_org}); + + my %buckets2; + my %hash2 = map { ($_->to_org => $_->prox) } @$req_prox; + push( @{$buckets2{ $hash2{$_->{circ_lib}} } }, $_->{id} ) for @$copies; + + my $highest_key = $keys[@keys - 1]; # the farthest prox in the exising buckets + my $new_key = $highest_key - 0.5; # right before the farthest prox + my @keys2 = sort { $a <=> $b } keys %buckets2; + for my $key (@keys2) { + last if $key >= $highest_key; + push( @{$buckets{$new_key}}, $_ ) for @{$buckets2{$key}}; + } + } + + @keys = sort { $a <=> $b } keys %buckets; + + my $title; + my %seen; + for my $key (@keys) { + my @cps = @{$buckets{$key}}; + + $logger->info("looking at " . scalar(@{$buckets{$key}}). " copies in proximity bucket $key"); + + for my $copyid (@cps) { + + next if $seen{$copyid}; + $seen{$copyid} = 1; # there could be dupes given the merged buckets + my $copy = $e->retrieve_asset_copy($copyid) or return $e->event; + $logger->debug("looking at bucket_key=$key, copy $copyid : circ_lib = " . $copy->circ_lib); + + unless($title) { # grab the title if we don't already have it + my $vol = $e->retrieve_asset_call_number( + [ $copy->call_number, { flesh => 1, flesh_fields => { acn => ['record'] } } ] ); + $title = $vol->record; + } + + return 1 if verify_copy_for_hold( + $patron, $requestor, $title, $copy, $pickup_lib, $request_lib ); + + } + } + + return 0; +} + + sub _check_volume_hold_is_possible { my( $vol, $title, $rangelib, $depth, $request_lib, $patron, $requestor, $pickup_lib ) = @_; my $copies = new_editor->search_asset_copy({call_number => $vol->id});