From 34673b1151848a746c7be3bcfab399b9c2a84a01 Mon Sep 17 00:00:00 2001 From: Jason Stephenson Date: Thu, 14 Jan 2016 11:40:59 -0500 Subject: [PATCH 1/1] Handle shelf-expired holds in NCIP::ILS::Evergreen->checkinitem. We modify the check_circ_details method to look for shelf-expired holds in addition to circulations and transits. It is also modified to better handle being used from the renewitem handler. We add the clear_expired flag when actually doing the checkin. Finally, a new helper _date_past is added to check if a date is in the past, and the _expired helper is modified to use the _date_past subroutine. Signed-off-by: Jason Stephenson --- lib/NCIP/ILS/Evergreen.pm | 85 ++++++++++++++++++++++++++++----------- 1 file changed, 61 insertions(+), 24 deletions(-) diff --git a/lib/NCIP/ILS/Evergreen.pm b/lib/NCIP/ILS/Evergreen.pm index b19ceee..2e2bbd5 100644 --- a/lib/NCIP/ILS/Evergreen.pm +++ b/lib/NCIP/ILS/Evergreen.pm @@ -430,8 +430,8 @@ sub checkinitem { # 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 @@ -457,7 +457,8 @@ sub checkinitem { copy_barcode => $copy->barcode(), force => 1, noop => 1, - void_overdues => 1 + void_overdues => 1, + clear_expired => 1 }; my $result = $U->simplereq( 'open-ils.circ', @@ -590,7 +591,7 @@ sub renewitem { # 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()) { @@ -1752,7 +1753,7 @@ sub check_user_for_problems { =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 @@ -1761,6 +1762,17 @@ circulation is for the optional $user argument. The $details argument 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. @@ -1773,11 +1785,15 @@ fields will be empty and need to be filled in by the caller. =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(); @@ -1786,19 +1802,20 @@ sub check_circ_details { # 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. @@ -1809,6 +1826,15 @@ sub check_circ_details { } ); } + } 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; @@ -2976,16 +3002,27 @@ sub _expired { # 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. -- 2.43.2