[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