From: Jason Stephenson Date: Sun, 15 Jul 2018 21:11:46 +0000 (-0400) Subject: More back end work for marking items. X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=6e1180f441e5ce62a1392954b743407ba8863baf;p=working%2FEvergreen.git More back end work for marking items. This work unifies the back end behavior more for the different statuses. The tests will have to be reworked. --- diff --git a/Open-ILS/src/extras/ils_events.xml b/Open-ILS/src/extras/ils_events.xml index 9f92944cc5..362fff563d 100644 --- a/Open-ILS/src/extras/ils_events.xml +++ b/Open-ILS/src/extras/ils_events.xml @@ -1060,6 +1060,18 @@ The prediction pattern still has dependent objects + + + + + The item to be marked is checked out to a patron. + + + The item to be marked is in transit. + + + The item to be marked is the last possible target for a hold. + diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ.pm index c4be222b2e..bbeeae5d76 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ.pm @@ -1307,31 +1307,24 @@ sub mark_item { my( $self, $conn, $auth, $copy_id, $args ) = @_; $args ||= {}; - # Items must be checked in before any attempt is made to mark damaged or discard - my $evt = try_checkin($auth, $copy_id) if - ($self->api_name=~ /(?:damaged|discard)/ && $args->{handle_checkin}); - return $evt if $evt; - my $e = new_editor(authtoken=>$auth, xact =>1); return $e->die_event unless $e->checkauth; my $copy = $e->retrieve_asset_copy([ $copy_id, - {flesh => 1, flesh_fields => {'acp' => ['call_number']}}]) + {flesh => 1, flesh_fields => {'acp' => ['call_number','status']}}]) or return $e->die_event; - my $owning_lib = + my $owning_lib = ($copy->call_number->id == OILS_PRECAT_CALL_NUMBER) ? $copy->circ_lib : $copy->call_number->owning_lib; + my $evt; # For later. my $perm = 'MARK_ITEM_MISSING'; my $stat = OILS_COPY_STATUS_MISSING; if( $self->api_name =~ /damaged/ ) { $perm = 'MARK_ITEM_DAMAGED'; $stat = OILS_COPY_STATUS_DAMAGED; - my $evt = handle_mark_damaged($e, $copy, $owning_lib, $args); - return $evt if $evt; - } elsif ( $self->api_name =~ /bindery/ ) { $perm = 'MARK_ITEM_BINDERY'; $stat = OILS_COPY_STATUS_BINDERY; @@ -1355,20 +1348,85 @@ sub mark_item { # caller may proceed if either perm is allowed return $e->die_event unless $e->allowed([$perm, 'UPDATE_COPY'], $owning_lib); - $copy->status($stat); - $copy->edit_date('now'); - $copy->editor($e->requestor->id); - - $e->update_asset_copy($copy) or return $e->die_event; + # Copy status checks. + if ($copy->status->id() == OILS_COPY_STATUS_CHECKED_OUT) { + # Items must be checked in before any attempt is made to change its status. + if ($args->{handle_checkin}) { + $evt = try_checkin($auth, $copy_id); + } else { + $evt = OpenILS::Event->new('ITEM_TO_MARK_CHECKED_OUT'); + } + } elsif ($copy->status->id() == OILS_COPY_STATUS_IN_TRANSIT) { + # Items in transit need to have the transit aborted before being marked. + if ($args->{handle_transit}) { + if ($e->allowed('ABORT_TRANSIT')) { + my $transit = $e->search_action_transit_copy( + { + target_copy => $copy->id, + dest_recv_time => undef, + cancel_time => undef + } + ); + if ($transit && @{$transit}) { + # Abort the transit and do not retarget holds nor commit the transaction. + # NOTE: __abort_transit should probably be moved/renamed since we're reaching in to use it. + my $r = OpenILS::Application::Circ::Transit::__abort_transit($e, $transit->[0], $copy, 1, 1); + $evt = $r if (ref $r); #__abort_transit returns 1 or an event. + } + } else { + $evt = $e->event; + } + } else { + $evt = OpenILS::Event->new('ITEM_TO_MARK_IN_TRANSIT'); + } + } elsif ($copy->status->restrict_copy_delete() && $self->api_name =~ /discard/) { + # Items with restrict_copy_delete status require the + # COPY_DELETE_WARNING.override permission to be marked for + # discard. + if ($args->{handle_copy_delete_warning}) { + $evt = $e->event unless $e->allowed(['COPY_DELETE_WARNING.override'], $owning_lib); + } else { + $evt = OpenILS::Event->new('COPY_DELETE_WARNING'); + } + } + return $evt if $evt; + # Retrieving holds for later use. my $holds = $e->search_action_hold_request( - { + { current_copy => $copy->id, fulfillment_time => undef, cancel_time => undef, - } + }, + {flesh=>1, flesh_fields=>{ahr=>['eligible_copies']}} ); + # Handle extra mark damaged charges, etc. + if ($self->api_name =~ /damaged/) { + $evt = handle_mark_damaged($e, $copy, $owning_lib, $args); + return $evt if $evt; + } + + # Throw event if attempting to mark discard the only copy to fill a hold. + if ($self->api_name =~ /discard/) { + if (!$args->{handle_last_hold_copy}) { + for my $hold (@$holds) { + my $eligible = $hold->eligible_copies(); + if (scalar(@{$eligible}) < 2) { + $evt = OpenILS::Event->new('ITEM_TO_MARK_LAST_HOLD_COPY'); + last; + } + } + } + return $evt if $evt; + } + + $copy->status($stat); + $copy->edit_date('now'); + $copy->editor($e->requestor->id); + + $e->update_asset_copy($copy) or return $e->die_event; + $e->commit; if( $self->api_name =~ /damaged/ ) {