return $self->{hold};
}
+sub inside_hard_stall_interval {
+ my ($self) = @_;
+ if (defined $self->{inside_hard_stall_interval}) {
+ return $self->{inside_hard_stall_interval};
+ }
+
+ my $hard_stall_interval =
+ $self->parent->get_ou_setting(
+ $self->hold->pickup_lib, 'circ.pickup_hold_stalling.hard', $self->editor) || '0 seconds';
+
+ my $hold_request_time = $dt_parser->parse_datetime(clean_ISO8601($self->hold->request_time));
+ my $hard_stall_time = $hold_request_time->clone->add(
+ seconds => OpenILS::Utils::DateTime->interval_to_seconds($hard_stall_interval)
+ );
+
+ if (DateTime->compare($hold_request_time, $hard_stall_time) < 0) {
+ $self->{inside_hard_stall_interval} = 1
+ } else {
+ $self->{inside_hard_stall_interval} = 0
+ }
+
+ return $self->{inside_hard_stall_interval};
+}
+
# Debug message
sub message {
my ($self, $message) = @_;
return $self->{recall_copies};
}
+sub in_use_copies {
+ my ($self, $in_use_copies) = @_;
+ $self->{in_use_copies} = $in_use_copies if $in_use_copies;
+ return $self->{in_use_copies};
+}
+
# Maps copy ID's to their hold proximity
sub copy_prox_map {
my ($self, $copy_prox_map) = @_;
my %prox_map;
for my $copy_hash (@{$self->copies}) {
my $prox = $copy_prox_map{$copy_hash->{id}};
+ $copy_hash->{proximity} = $prox;
$prox_map{$prox} ||= [];
my $weight = $self->parent->get_ou_setting(
sub filter_copies_in_use {
my $self = shift;
+ # Copies that are targeted, but could contribute to pickup lib
+ # hard (foreign) stalling. These are Available-status copies.
+ $self->in_use_copies([grep {$_->{current_copy}} @{$self->copies}]);
+
# A copy with a 'current_copy' value means it's in use by another hold.
$self->copies([
grep {!$_->{current_copy}} @{$self->copies}
my $hold = $self->hold;
my %seen;
+ # See if there are in-use (targeted) copies "here".
+ my $have_local_copies = 0;
+ if ($self->inside_hard_stall_interval) { # But only if we're inside the hard age.
+ if (grep { $_->{proximity} <= 0 } @{$self->in_use_copies}) {
+ $have_local_copies = 1;
+ }
+ }
+
# 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 @copies = @{$prox_map{$prox}};
next unless @copies;
+ $have_local_copies = 1 if ($prox <= 0);
+
+ if ($prox > 0 and $have_local_copies and $self->inside_hard_stall_interval) {
+ # Unset valid_previous_copy if it's not local and we have local copies now
+ $self->{valid_previous_copy} = undef if (
+ $self->{valid_previous_copy}
+ and $self->{valid_previous_copy}->{proximity} > 0
+ );
+ last; # No point in looking further "out".
+ }
+
my $rand = int(rand(scalar(@copies)));
while (my ($c) = splice(@copies, $rand, 1)) {
'coust', 'description'),
'interval', null)
+,( 'circ.pickup_hold_stalling.hard', 'holds',
+ oils_i18n_gettext('circ.pickup_hold_stalling.hard',
+ 'Pickup Library Hard stalling interval',
+ 'coust','label'),
+ oils_i18n_gettext('circ.pickup_hold_stalling.hard',
+ 'When set for the pickup library, this specifies that no items with a calculated proximity greater than 0 from the pickup library can be directly targeted for this time period if there are local available copies. Example "3 days".',
+ 'coust','description'),
+ 'interval', null)
+
,( 'circ.hold_stalling_hard', 'holds',
oils_i18n_gettext('circ.hold_stalling_hard',
'Hard stalling interval',