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;
# 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/ ) {