add shipping distance from DB to copy hash and use it for sorting in hold targeter... user/lew/holdtargeter-geosort-wip
authorLlewellyn Marshall <llewellyn.marshall@ncdcr.gov>
Tue, 23 Aug 2022 21:06:30 +0000 (17:06 -0400)
committerLlewellyn Marshall <llewellyn.marshall@ncdcr.gov>
Tue, 23 Aug 2022 21:06:30 +0000 (17:06 -0400)
Open-ILS/src/perlmods/lib/OpenILS/Utils/HoldTargeter.pm

index 65215c8..5c4db61 100644 (file)
@@ -707,7 +707,7 @@ sub compile_weighted_proximity_map {
     # Collect copy proximity info (generated via DB trigger)
     # from our newly create copy maps.
     my $hold_copy_maps = $self->editor->json_query({
-        select => {ahcm => ['target_copy', 'proximity']},
+        select => {ahcm => ['target_copy', 'proximity','shipping_distance']},
         from => 'ahcm',
         where => {hold => $self->hold_id}
     });
@@ -1097,7 +1097,7 @@ sub attempt_prev_copy_retarget {
     return undef;
 }
 
-# Returns the closest copy by proximity and vicinity that is a confirmed valid
+# Returns the closest copy by proximity and shipping distance that is a confirmed valid
 # targetable copy.
 sub find_nearest_copy {
     my $self = shift;
@@ -1108,53 +1108,22 @@ sub find_nearest_copy {
     my %seen;
 
     for my $prox (sort {$a <=> $b} keys %prox_map) {
-        my %distance_matrix;
-        my %hub_by_target;
         my @copies = @{$prox_map{$prox}};
         next unless @copies;
-        # run vicinity calculator if proximity is greater than or equal to 3
-        unless($prox < 3){
-            unless($req_hub){  
-                # assigning the shipping hub for this hold
-                $req_hub = $vinc_calc->get_hub_from_ou($hold->pickup_lib);
-            }
-            my @copy_ids = map {$_->{id}} @copies;
-            # determine which shipping hub OU these copies would need to be sent to
-            %hub_by_target = $vinc_calc->get_target_hubs(\@copy_ids);
-            my @hubs = values(%hub_by_target);
-            %distance_matrix =  $vinc_calc->hub_matrix($req_hub,\@hubs);
-        }
-        # run this block only if target copies are within the same OU 
-        # or a distance matrix could not be retreived for a destination      
-        if($prox < 3 || !%distance_matrix){
-            # Pick a copy at random from each tier of the proximity map,
-            # starting at the lowest proximity and working up, until a
-            # copy is found that is suitable for targeting.
-            my $rand = int(rand(scalar(@copies)));
-            while (my ($c) = splice(@copies, $rand, 1)) {
-                $rand = int(rand(scalar(@copies)));
-                next if $seen{$c->{id}};
-
-                return $c if $self->copy_is_permitted($c);
-                $seen{$c->{id}} = 1;
-
-                last unless(@copies);
-            }
-        }
-        else{
-            # select the target copy from the closest OU
-            # TODO what happens if two hubs are the same distance away from home hub?
-            # TODO should we round distances so two hubs don't always choose from one another?
-            # TODO what if this was stored in the Action.hold_copy_map like the prox is? 
-            for my $c (sort { $distance_matrix{$hub_by_target{$a->{id}}} <=> $distance_matrix{$hub_by_target{$b->{id}}} } @copies){
-                $self->log_hold("VicinityCalculator - Copy: ".$c->{id}." Shipping Hub:".$hub_by_target{$c->{id}}. "Physical Distance: ".$distance_matrix{$hub_by_target{$c->{id}}});
-                next if $seen{$c->{id}};
-                return $c if $self->copy_is_permitted($c);
-                $seen{$c->{id}} = 1;
-                last unless(@copies);
-            }
-        }
-        
+               # Pick a copy at random from each tier of the proximity map,
+               # starting at the lowest proximity and working up, until a
+               # copy is found that is suitable for targeting.
+               # sort all of the copies by shipping hub distance.
+               # two copies with equal shipping distance are sorted at random.
+               for my $c (sort { $a->{shipping_distance} <=> $b->{shipping_distance} || (random(-2) + 1) } @copies){
+                       $rand = int(rand(scalar(@copies)));
+                       next if $seen{$c->{id}};
+
+                       return $c if $self->copy_is_permitted($c);
+                       $seen{$c->{id}} = 1;
+
+                       last unless(@copies);
+               }       
     }
 
     return undef;