# Isolate the copy.
my $copy = $details->{copy};
- # Look for a circulation and examine its information:
- my $circ = $details->{circ};
+ # Look for a circulation or hold so we can retrieve the user.
+ my $circ = $details->{circ} || $details->{hold};
# Check the circ details to see if the copy is checked out and, if
# the patron was provided, that it is checked out to the patron in
copy_barcode => $copy->barcode(),
force => 1,
noop => 1,
- void_overdues => 1
+ void_overdues => 1,
+ clear_expired => 1
};
my $result = $U->simplereq(
'open-ils.circ',
# the patron was provided, that it is checked out to the patron in
# question. We also verify the copy ownership and circulation
# location.
- my $problem = $self->check_circ_details($details, $user);
+ my $problem = $self->check_circ_details($details, $user, 1);
if ($problem) {
# We need to fill in some information, however.
if (!$problem->ProblemValue() && !$problem->ProblemElement()) {
=head2 check_circ_details
- $problem = $ils->check_circ_details($details, $user);
+ $problem = $ils->check_circ_details($details, $user, $isrenewal);
Checks if we can checkin or renew a circulation. That is, the
circulation is still open (i.e. the copy is still checked out), if we
is required and comes from the retrieve_copy_details call. $user is
optional.
+The optional C<$isrenewal> argument must be true when checking for
+renewals. This argument set to true bypasses the hold check
+(described below) and requires a circulation.
+
+If we are not checking for renewals, this function will also check for
+a shelf-expired hold for the copy and patron. If that is found, it is
+considered success as well.
+
+Also, if we are not checking for renewals, it will also check for an
+open transit return the item to our working organizational unit.
+
Returns a problem if any of the above conditions fail. Returns undef
if they pass and we can proceed with the checkin or renewal.
=cut
sub check_circ_details {
- my ($self, $details, $user) = @_;
+ my ($self, $details, $user, $isrenewal) = @_;
my $copy = $details->{copy};
my $circ = $details->{circ};
my $transit = $details->{transit};
+ my $hold = $details->{hold};
+
+ # User from the hold or circulation.
+ my $circ_user;
# Shortcut for the next check.
my $ou_id = $self->{session}->{work_ou}->id();
# been checked out at the NCIP user's working_ou or it needs to be
# owned there. If the circulation was subsequently checked in,
# then we need an open transit to the NCIP user's working_ou.
- if (!$circ || ($circ->circ_lib() != $ou_id && $copy->circ_lib() != $ou_id)
- || ($circ->checkin_time() && (!$transit || $transit->dest() != $ou_id))) {
- # Item isn't checked out.
- return NCIP::Problem->new(
- {
- ProblemType => 'Item Not Checked Out',
- ProblemDetail => 'Item with barcode ' . $copy->barcode() . ' is not checked out.',
- ProblemValue => $copy->barcode()
- }
- );
- } else {
- # Get data on the patron who has it checked out.
- my $circ_user = $self->retrieve_user_by_id($circ->usr());
+ if ($circ) {
+ if (($circ->circ_lib() == $ou_id || $copy->circ_lib() == $ou_id)
+ || ($circ->checkin_time() && !$isrenewal && ($transit && $transit->dest() == $ou_id))) {
+ $circ_user = $self->retrieve_user_by_id($circ->usr());
+ }
+ } elsif ($hold && !$isrenewal) {
+ # If we don't have a circulation, we want to have a shelf-expired hold.
+ if ($hold->shelf_time() && _date_past($hold->shelf_expire_time())) {
+ $circ_user = $self->retrieve_user_by_id($hold->usr());
+ }
+ }
+
+ if ($circ_user) {
+ # Check if the $circ_user matches the passed in $user.
if ($user && $circ_user && $user->id() != $circ_user->id()) {
# The ProblemElement and ProblemValue field need to be
# filled in by the caller.
}
);
}
+ } else {
+ # We consider the item to be not checked out.
+ return NCIP::Problem->new(
+ {
+ ProblemType => 'Item Not Checked Out',
+ ProblemDetail => 'Item with barcode ' . $copy->barcode() . ' is not checked out.',
+ ProblemValue => $copy->barcode()
+ }
+ );
}
# If we get here, we're good to go.
return undef;
# Users might not expire. If so, they have no expire_date.
if ($user->expire_date()) {
- my $expires = DateTime::Format::ISO8601->parse_datetime(
- cleanse_ISO8601($user->expire_date())
- )->epoch();
- my $now = DateTime->now()->epoch();
- $expired = $now > $expires;
+ $expired = _date_past($user->expire_date());
}
return $expired;
}
+# Check if a date has been passed, i.e. is in the past.
+#
+# This subroutine was added to have the same functionality of _expired
+# without necessitating a change to the _expired subroutine interface
+# and the code that already uses it.
+sub _date_past {
+ my $date = shift;
+
+ my $date_clean = DateTime::Format::ISO8601->parse_datetime(
+ cleanse_ISO8601($date)
+ )->epoch();
+ my $now = DateTime->now()->epoch();
+ return $now > $date_clean;
+}
+
# Creates a NCIP Problem from an event. Takes a string for the problem
# type, the event hashref (or a string to use for the detail), and
# optional arguments for the ProblemElement and ProblemValue fields.