# -- better up-front copy filtering when finding potential copies
sub new {
- my $class = shift;
+ my ($class, %args) = @_;
my $self = {
editor => new_editor(),
- ou_setting_cache => {}
+ ou_setting_cache => {},
+ %args,
};
return bless($self, $class);
}
return $c->{$org_id}->{$setting};
}
-# TODO: stream messages back to caller
sub exit_targeter {
my ($self, $msg) = @_;
+ $self->{exit} = 1;
+ $self->{exit_msg} = $msg;
$self->{editor}->rollback; # no-op if commit already occurred.
my $hold_id = $self->{hold_id};
$logger->info("targeter: exiting hold targeter for $hold_id : $msg");
return 0;
}
-# Cancel expired holds and kick off the A/T no-target event.
-# Returns true if the hold is expired or an error occured.
-# False otherwise.
+# Cancel expired holds and kick off the A/T no-target event. Returns
+# true (i.e. keep going) if the hold is not expired. Returns false if
+# the hold is canceled or a non-recoverable error occcurred.
sub handle_expired_hold {
my $self = shift;
my $hold = $self->{hold};
- return 0 unless $hold->expire_time;
+ return 1 unless $hold->expire_time;
my $ex_time =
$dt_parser->parse_datetime(cleanse_ISO8601($hold->expire_time));
- return 0 unless DateTime->compare($ex_time, DateTime->now) < 0;
+ return 1 unless DateTime->compare($ex_time, DateTime->now) < 0;
- # Hold is expired
+ # Hold is expired --
$hold->cancel_time('now');
$hold->cancel_cause(1); # == un-targeted expiration
if (!$self->{editor}->update_action_hold_request($hold)) {
- $self->exit_targeter("Error canceling hold");
- return 1; # Tell the caller to exit
+ my $evt = $self->{editor}->die_event;
+ return $self->exit_targeter("Error canceling hold: ".$evt->{textcode});
}
$self->{editor}->commit;
$hold, $hold->pickup_lib
);
- return 1;
+ return $self->exit_targeter("Hold is expired");
}
# Hold copy maps are only automatically deleted when the hold
# is fulfilled or canceled. Here, they have to be manually removed.
-# Returns event on error, undef on success.
+# Returns true on success, false on error.
sub remove_copy_maps {
my $self = shift;
my $e = $self->{editor};
my $prev_maps =
$e->search_action_hold_copy_map({hold => $self->{hold_id}});
+
for my $map (@$prev_maps) {
- $e->delete_action_hold_copy_map($map) or return $e->die_event;
+ if (!$e->delete_action_hold_copy_map($map)) {
+ my $evt = $e->die_event;
+ return $self->exit_targeter(
+ "Error deleting copy maps: ".$evt->{textcode});
+ }
}
- return undef;
+
+ return 1;
}
sub get_hold_copies {
return map {$_->{id}} @$res;
}
-sub handle_no_copies {
- my $self = shift;
+sub inspect_potential_copies {
+ my ($self, @copy_ids) = @_;
+
my $e = $self->{editor};
my $hold = $self->{hold};
+ my $hold_id = $self->{hold_id};
+
+ $logger->info("targeter: Hold $hold_id has ".
+ scalar(@copy_ids)." potential copies");
+
+ # Let the caller know we found the copy they were interested in.
+ $self->{found_copy} = 1 if $self->{find_copy}
+ && grep {$_ eq $self->{find_copy}} @copy_ids;
+
+ # We have copies. Nothing left to do here.
+ return 1 if @copy_ids;
$hold->prev_check_time('now');
$hold->clear_current_copy;
}
+sub build_copy_maps {
+ my ($self, @copy_ids) = @_;
+ my $e = $self->{editor};
+
+ for my $copy_id (@copy_ids) {
+ my $map = Fieldmapper::action::hold_copy_map->new;
+
+ $map->hold($self->{hold_id});
+ $map->target_copy($copy_id);
+
+ if (!$e->create_action_hold_copy_map($map)) {
+ my $evt = $e->die_event;
+ return $self->exit_targeter(
+ "Error creating hold copy map: ".$evt->{textcode});
+ }
+ }
+
+ # TODO: collect proximities
+
+ return 1;
+}
+
+
# Targets a single hold request
sub target_hold {
my ($self, $hold_id) = @_;
my $e = $self->{editor};
+
+ # reset hold-specific toggles
+ $self->{exit} = 0;
$self->{hold_id} = $hold_id;
+ $self->{found_copy} = 0;
$e->xact_begin;
return $self->exit_targeter("Hold is not eligible for targeting")
if $hold->capture_time || $hold->cancel_time;
- # Remove any existing hold copy maps so they can be replaced.
- my $evt = $self->remove_copy_maps;
- return $self->exit_targeter(
- "Error deleting copy maps: ".$evt->{textcode}) if $evt;
-
- return $self->exit_targeter("Hold is expired")
- if $self->handle_expired_hold;
+ return unless $self->remove_copy_maps;
+ return unless $self->handle_expired_hold;
my @copy_ids = $self->get_hold_copies;
+ return unless $self->inspect_potential_copies(@copy_ids);
- return $self->handle_no_copies unless @copy_ids;
+ return unless $self->build_copy_maps(@copy_ids);
- $logger->info("targeter: Hold $hold_id has ".
- scalar(@copy_ids)." potential copies");
+ $e->commit;
}