[open-ils-commits] r8139 -
trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ
svn at svn.open-ils.org
svn at svn.open-ils.org
Wed Dec 5 12:21:17 EST 2007
Author: miker
Date: 2007-12-05 12:01:38 -0500 (Wed, 05 Dec 2007)
New Revision: 8139
Modified:
trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm
Log:
speedy json_query version of metarecord hold permit
Modified: trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm 2007-12-04 16:56:30 UTC (rev 8138)
+++ trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm 2007-12-05 17:01:38 UTC (rev 8139)
@@ -1092,6 +1092,119 @@
my %prox_cache;
+sub _check_metarecord_hold_is_possible {
+ my( $mrid, $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 metarecord
+ my $copies = $e->json_query(
+ {
+ select => { acp => ['id', 'circ_lib'] },
+ from => {
+ acp => {
+ acn => {
+ field => 'id',
+ fkey => 'call_number',
+ 'join' => {
+ bre => {
+ field => 'id',
+ fkey => 'record',
+ 'join' => {
+ mmrsm => {
+ filter => { metarecord => $mrid },
+ field => 'source',
+ fkey => 'id'
+ }
+ }
+ }
+ }
+ },
+ 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("metarecord 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 %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);
+
+ my $vol = $e->retrieve_asset_call_number(
+ [ $copy->call_number, { flesh => 1, flesh_fields => { acn => ['record'] } } ] );
+
+ return 1 if verify_copy_for_hold(
+ $patron, $requestor, $vol->record, $copy, $pickup_lib, $request_lib );
+
+ }
+ }
+
+ return 0;
+}
+
sub _check_title_hold_is_possible {
my( $titleid, $rangelib, $depth, $request_lib, $patron, $requestor, $pickup_lib ) = @_;
More information about the open-ils-commits
mailing list