From: Llewellyn Marshall Date: Fri, 24 Mar 2023 16:07:31 +0000 (-0400) Subject: incorporate reset entries into the retargeter so that manually retargeted copies... X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=refs%2Fheads%2Fuser%2Flew%2Fretargeter_reset_entry_adjustments;p=working%2FEvergreen.git incorporate reset entries into the retargeter so that manually retargeted copies from the hold copy map get max_prox+1 proximity adjustments and timed out copies get +1 proximity adjustments --- diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Utils/HoldTargeter.pm b/Open-ILS/src/perlmods/lib/OpenILS/Utils/HoldTargeter.pm index 31b8852cb0..c3a185cd5b 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Utils/HoldTargeter.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Utils/HoldTargeter.pm @@ -265,6 +265,7 @@ use DateTime; use OpenSRF::AppSession; use OpenILS::Utils::DateTime qw/:datetime/; use OpenSRF::Utils::Logger qw(:logger); +use OpenILS::Const qw/:const/; use OpenILS::Application::AppUtils; use OpenILS::Utils::CStoreEditor qw/:funcs/; @@ -367,6 +368,20 @@ sub result { }; } +sub retarget_previous_targets_interval { + my ($self) = @_; + if (!defined($self->{retarget_previous_targets_interval}) || !$self->{retarget_previous_targets_interval}) { + # See if we have a global flag value for the interval + my $rri = $self->editor->search_config_global_flag({ + name => 'circ.holds.retarget_previous_targets_interval', + enabled => 't' + })->[0]; + # If no flag is present, default to 0 so feature is disabled + $self->{retarget_previous_targets_interval} = $rri ? $rri->value : 0; + } + return $self->{retarget_previous_targets_interval}; +} + # List of potential copies in the form of slim hashes. This list # evolves as copies are filtered as they are deemed non-targetable. sub copies { @@ -735,6 +750,42 @@ sub get_copy_circ_libs { sub compile_weighted_proximity_map { my $self = shift; + my %copy_reset_map = {}; + my %copy_timeout_map = {}; + eval{ + my $pt_interval = $self->retarget_previous_targets_interval(); + if($pt_interval){ + my $reset_cutoff_time = DateTime->now(time_zone => 'local') + ->subtract(days => $pt_interval); + + # Collect reset reason info and previous copies. + # for this hold within the last time interval + my $reset_entries = $self->editor->json_query({ + select => {ahrrre => ['reset_reason','reset_time','previous_copy']}, + from => 'ahrrre', + where => { + hold => $self->hold_id, + previous_copy => {'!=' => undef}, + reset_time => {'>=' => $reset_cutoff_time->strftime('%F %T%z')}, + reset_reason => [OILS_HOLD_TIMED_OUT, OILS_HOLD_MANUAL_RESET] + } + }); + + # count how many times each copy + # was reset or timed out + for(@$reset_entries){ + my $pc = $_->{previous_copy}; + my $rr = $_->{reset_reason}; + if($rr == OILS_HOLD_MANUAL_RESET){ + $copy_reset_map{$pc} += 1; + } + elsif($rr == OILS_HOLD_TIMED_OUT){ + $copy_timeout_map{$pc} += 1; + } + } + } + }; + # Collect copy proximity info (generated via DB trigger) # from our newly create copy maps. my $hold_copy_maps = $self->editor->json_query({ @@ -745,7 +796,14 @@ sub compile_weighted_proximity_map { my %copy_prox_map = map {$_->{target_copy} => $_->{proximity}} @$hold_copy_maps; - + + # calculate the maximum proximity to make adjustments + my $max_prox = 0; + foreach(@$hold_copy_maps){ + my $mp = $_->{proximity} + 1; + $max_prox = $mp unless $max_prox >= $mp; + } + # Pre-fetch the org setting value for all circ libs so that # later calls can reference the cached value. $self->parent->precache_batch_ou_settings($self->get_copy_circ_libs, @@ -753,7 +811,18 @@ sub compile_weighted_proximity_map { my %prox_map; for my $copy_hash (@{$self->copies}) { - my $prox = $copy_prox_map{$copy_hash->{id}}; + my $copy_id = $copy_hash->{id}; + my $prox = $copy_prox_map{$copy_id}; + my $reset_count = $copy_reset_map{$copy_id}; + my $timeout_count = $copy_timeout_map{$copy_id}; + + # make adjustments to proximity based on reset reason. + # manual resets get +max_prox each time + # this moves them to the end of the hold copy map. + # timeout resets only add one level of proximity + # so that copies can be inspected again later. + $prox += (($reset_count || 0) * $max_prox) + (($timeout_count || 0)); + $copy_hash->{proximity} = $prox; $prox_map{$prox} ||= []; diff --git a/Open-ILS/src/sql/Pg/upgrade/xxxx.hold_reset_reasons.sql b/Open-ILS/src/sql/Pg/upgrade/xxxx.hold_reset_reasons.sql index 39ab13a34f..15e2f3b662 100644 --- a/Open-ILS/src/sql/Pg/upgrade/xxxx.hold_reset_reasons.sql +++ b/Open-ILS/src/sql/Pg/upgrade/xxxx.hold_reset_reasons.sql @@ -66,3 +66,15 @@ INSERT INTO config.global_flag (name, label, enabled) ), TRUE ); + +INSERT INTO config.global_flag (name, label, enabled) + VALUES ( + 'circ.holds.retarget_previous_targets_interval', + oils_i18n_gettext( + 'circ.holds.retarget_previous_targets_interval', + 'Hold targeter will create proximity adjustments for previously targeted copies within this time interval (in days).', + 'cgf', + 'label' + ), + TRUE + );