From 34e9b9e3412ccad1850d909293e35a8462644a5c Mon Sep 17 00:00:00 2001 From: Jason Stephenson Date: Tue, 27 Oct 2015 13:13:42 -0400 Subject: [PATCH] Cancel requests via RequestId in NCIP::ILS::Evergreen. Add a routine to search for holds via the RequestIdentifierValue of the CancelRequestItem message's RequestId. This searches action:: hold_request_note by title and body for uncancelled, unfilled holds where request_lib is equal to our working org. unit. If found, the corresponding hold is returned to be canceled. The original logic of searching by ItemId remains as a fallback when the above fails and for those cases where holds were placed before this logic was added. Signed-off-by: Jason Stephenson --- lib/NCIP/ILS/Evergreen.pm | 126 +++++++++++++++++++++++--------------- 1 file changed, 75 insertions(+), 51 deletions(-) diff --git a/lib/NCIP/ILS/Evergreen.pm b/lib/NCIP/ILS/Evergreen.pm index 1ee1b58..db97d70 100644 --- a/lib/NCIP/ILS/Evergreen.pm +++ b/lib/NCIP/ILS/Evergreen.pm @@ -1084,60 +1084,40 @@ sub cancelrequestitem { return $response; } - # Auto-Graphics has agreed to return the ItemId that we sent them - # in the RequestItemResponse when they attempt CancelRequestItem - # for that same request. For the sake of time, we're only going - # to support that method of looking up the hold request in - # Evergreen. We leave it as future enhancement to make this - # "portable" to other vendors. (Frankly, that's a fool's errand. - # NCIP is one of those "standards" where you neeed a separate - # implementation for every vendor.) - my $item_id = $request->{$message}->{ItemId}; - unless ($item_id) { - # We'll throw a problem that we're missing needed information. - my $problem = NCIP::Problem->new(); - $problem->ProblemType('Needed Data Missing'); - $problem->ProblemDetail('Cannot find ItemId in message.'); - $problem->ProblemElement('ItemId'); - $problem->ProblemValue('NULL'); - $response->problem($problem); - return $response; - } - my $idvalue = $item_id->{ItemIdentifierValue}; - my $itemagy = $item_id->{AgencyId}; - my $selection_ou = $self->find_location_failover($itemagy, $request, $message); - unless ($selection_ou) { - my $problem = NCIP::Problem->new( - { - ProblemType => 'Unknown Agency', - ProblemDetail => 'Agency is not known', - ProblemElement => 'AgencyId', - ProblemValue => $item_id->{AgencyId} || $request->{$message}->{InitiationHeader}->{ToAgencyId}->{AgencyId} + # First, let's see if we can find the hold via the RequestId's + # RequestIdentifierValue. If not, we fall back on the ItemId. + my $hold = $self->find_hold_via_note('NCIP Remote Request ID', $request->{$message}->{RequestId}->{RequestIdentifierValue}); + + unless ($hold) { + my $item_id = $request->{$message}->{ItemId}; + if ($item_id) { + my $idvalue = $item_id->{ItemIdentifierValue}; + my $itemagy = $item_id->{AgencyId}; + my $selection_ou = $self->find_location_failover($itemagy, $request, $message); + unless ($selection_ou) { + my $problem = NCIP::Problem->new( + { + ProblemType => 'Unknown Agency', + ProblemDetail => 'Agency is not known', + ProblemElement => 'AgencyId', + ProblemValue => $item_id->{AgencyId} || $request->{$message}->{InitiationHeader}->{ToAgencyId}->{AgencyId} + } + ); + $response->problem($problem); + return $response; } - ); - $response->problem($problem); - return $response; - } - # We should support looking up holds by barcode, since we still - # support placing them by barcode, but that is not how it is going - # to work with Auto-Graphics, apparently. I'll leave the - # reimplementation of that for a future enhancement. + # We should support looking up holds by barcode, since we still + # support placing them by barcode, but that is not how it is going + # to work with Auto-Graphics, apparently. I'll leave the + # reimplementation of that for a future enhancement. - # See if we can find the hold: - my $hold = $self->_hold_search($user, $idvalue, $selection_ou); - if ($hold && $hold->transit()) { - $response->problem( - NCIP::Problem->new( - { - ProblemType => 'Request Already Processed', - ProblemDetail => 'Request has already been processed', - ProblemElement => 'RequestIdentifierValue', - ProblemValue => $request->{message}->{RequestId}->{RequestIdentifierValue} - } - ) - ); - } elsif ($hold) { + # See if we can find the hold: + my $hold = $self->_hold_search($user, $idvalue, $selection_ou); + } + } + + if ($hold) { my $result = $self->cancel_hold($hold); if (ref($result)) { $response->problem(_problem_from_event("Temporary Processing Failure", $result)); @@ -2411,6 +2391,50 @@ sub create_hold_note { return undef; } +=head2 find_hold_via_note + + $hold = $ils->find_hold_via_note($title, $body); + +Searches for a hold based on a note title and note body. Returns the +note if found, undef otherwise. The search is limited to unfulfilled, +uncanceled hold where the request_lib equals the NCIPServer working +org. unit. + +=cut + +sub find_hold_via_note { + my $self = shift; + my $title = shift; + my $body = shift; + + # Build the search clause up here, because it is a bit complex. + my $search = { + title => $title, + body => $body, + hold => { + in => { + select => { ahr => ['id']}, + from => 'ahr', + where => {cancel_time => undef, fulfillment_time => undef, + request_lib => $self->{session}->{work_ou}->id()} + } + } + }; + + my $note = $U->simplereq( + 'open-ils.pcrud', + 'open-ils.pcrud.search.ahrn', + $self->{session}->{authtoken}, + $search, + {flesh => 1, flesh_fields => {ahrn => ['hold']}} + ); + if (ref($note) eq 'Fieldmapper::action::hold_request_note') { + return $note->hold(); + } + + return undef; +} + =head2 delete_copy $ils->delete_copy($copy); -- 2.43.2