diff --git a/Koha/Exceptions/Item/Bundle.pm b/Koha/Exceptions/Item/Bundle.pm index 8c42fd2cb2..fb8c46d22f 100644 --- a/Koha/Exceptions/Item/Bundle.pm +++ b/Koha/Exceptions/Item/Bundle.pm @@ -31,6 +31,10 @@ use Exception::Class ( isa => 'Koha::Exceptions::Item::Bundle', description => 'Someone tried to add a checked out item to a bundle', }, + 'Koha::Exceptions::Item::Bundle::ItemHasHolds' => { + isa => 'Koha::Exceptions::Item::Bundle', + description => 'Someone tried to add a reserved item to a bundle', + }, ); =head1 NAME diff --git a/Koha/Item.pm b/Koha/Item.pm index 7e1890878d..0d29655938 100644 --- a/Koha/Item.pm +++ b/Koha/Item.pm @@ -1730,6 +1730,13 @@ sub add_to_bundle { } } + my $holds = $bundle_item->current_holds; + if ($holds->count) { + unless ($options->{ignore_holds}) { + Koha::Exceptions::Item::Bundle::ItemHasHolds->throw(); + } + } + $self->_result->add_to_item_bundles_hosts( { item => $bundle_item->itemnumber } ); diff --git a/Koha/REST/V1/Items.pm b/Koha/REST/V1/Items.pm index 087deb3fab..3f20e3a577 100644 --- a/Koha/REST/V1/Items.pm +++ b/Koha/REST/V1/Items.pm @@ -278,8 +278,13 @@ sub add_to_bundle { } return try { - my $force_checkin = $c->validation->param('body')->{'force_checkin'}; - my $link = $item->add_to_bundle($bundle_item, { force_checkin => $force_checkin }); + my $body = $c->validation->param('body'); + my $options = { + force_checkin => $body->{force_checkin}, + ignore_holds => $body->{ignore_holds}, + }; + + my $link = $item->add_to_bundle($bundle_item, $options); return $c->render( status => 201, openapi => $bundle_item @@ -315,6 +320,15 @@ sub add_to_bundle { } ); } + elsif ( ref($_) eq 'Koha::Exceptions::Item::Bundle::ItemHasHolds' ) { + return $c->render( + status => 409, + openapi => { + error => 'Item is reserved', + error_code => 'reserved' + } + ); + } elsif ( ref($_) eq 'Koha::Exceptions::Item::Bundle::IsBundle' ) { return $c->render( status => 400, diff --git a/api/v1/swagger/definitions/bundle_link.yaml b/api/v1/swagger/definitions/bundle_link.yaml index 382ad67516..b564d039ee 100644 --- a/api/v1/swagger/definitions/bundle_link.yaml +++ b/api/v1/swagger/definitions/bundle_link.yaml @@ -15,4 +15,8 @@ properties: type: - boolean - "null" + ignore_holds: + type: + - boolean + - "null" additionalProperties: false diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt index aeda09d0e7..4be5eefad8 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt @@ -1976,6 +1976,18 @@ Note that permanent location is a code, and location may be an authval. .empty() .attr('class', 'alert alert-danger') .append(__x('Failure: Item {barcode} cannot be checked in', { barcode })) + } else if (response.error_code === 'reserved') { + const button = $('