Bug 40395: Preparation: suspension_bulk REST API endpoint
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit ad66f7d7d3)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
This commit is contained in:
parent
52465feb11
commit
2124549447
|
|
@ -378,6 +378,53 @@ sub suspend {
|
|||
};
|
||||
}
|
||||
|
||||
=head3 suspend_bulk
|
||||
|
||||
Method that handles suspending multiple holds
|
||||
|
||||
=cut
|
||||
|
||||
sub suspend_bulk {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
my $body = $c->req->json;
|
||||
my $end_date = ($body) ? $body->{end_date} : undef;
|
||||
my $hold_ids = ($body) ? $body->{hold_ids} : undef;
|
||||
|
||||
return $c->render_resource_not_found("Hold")
|
||||
unless $hold_ids;
|
||||
|
||||
return try {
|
||||
Koha::Database->new->schema->txn_do(
|
||||
sub {
|
||||
foreach my $hold_id (@$hold_ids) {
|
||||
my $hold = Koha::Holds->find($hold_id);
|
||||
|
||||
return $c->render_resource_not_found( "Hold", "id", $hold_id )
|
||||
unless $hold;
|
||||
|
||||
$hold->suspend_hold($end_date);
|
||||
$hold->discard_changes;
|
||||
}
|
||||
$c->res->headers->location( $c->req->url->to_string );
|
||||
return $c->render(
|
||||
status => 201,
|
||||
openapi => {
|
||||
hold_ids => $hold_ids,
|
||||
end_date => $end_date,
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
} catch {
|
||||
if ( blessed $_ and $_->isa('Koha::Exceptions::Hold::CannotSuspendFound') ) {
|
||||
return $c->render( status => 400, openapi => { error => "$_" } );
|
||||
}
|
||||
|
||||
$c->unhandled_exception($_);
|
||||
};
|
||||
}
|
||||
|
||||
=head3 resume
|
||||
|
||||
Method that handles resuming a hold
|
||||
|
|
|
|||
|
|
@ -280,6 +280,67 @@
|
|||
x-koha-authorization:
|
||||
permissions:
|
||||
reserveforothers: "1"
|
||||
"/holds/suspension_bulk":
|
||||
post:
|
||||
x-mojo-to: Holds#suspend_bulk
|
||||
operationId: suspendHoldBulk
|
||||
tags:
|
||||
- holds
|
||||
summary: Suspend the holds
|
||||
parameters:
|
||||
- name: body
|
||||
in: body
|
||||
description: Hold ids
|
||||
required: true
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
end_date:
|
||||
description: Date the hold suspension expires
|
||||
type: string
|
||||
format: date
|
||||
hold_ids:
|
||||
type: array
|
||||
items:
|
||||
type: integer
|
||||
additionalProperties: false
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"201":
|
||||
description: Holds suspended
|
||||
"400":
|
||||
description: Bad request
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"401":
|
||||
description: Authentication required
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"403":
|
||||
description: Hold not allowed
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"404":
|
||||
description: Hold not found
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"500":
|
||||
description: |
|
||||
Internal server error. Possible `error_code` attribute values:
|
||||
|
||||
* `internal_server_error`
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"503":
|
||||
description: Under maintenance
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
x-koha-authorization:
|
||||
permissions:
|
||||
reserveforothers: place_holds
|
||||
"/holds/{hold_id}":
|
||||
patch:
|
||||
x-mojo-to: Holds#edit
|
||||
|
|
|
|||
|
|
@ -403,6 +403,8 @@ paths:
|
|||
$ref: ./paths/extended_attribute_types.yaml#/~1extended_attribute_types
|
||||
/holds:
|
||||
$ref: ./paths/holds.yaml#/~1holds
|
||||
"/holds/suspension_bulk":
|
||||
$ref: "./paths/holds.yaml#/~1holds~1suspension_bulk"
|
||||
"/holds/{hold_id}":
|
||||
$ref: "./paths/holds.yaml#/~1holds~1{hold_id}"
|
||||
"/holds/{hold_id}/pickup_location":
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
use Modern::Perl;
|
||||
|
||||
use Test::More tests => 17;
|
||||
use Test::More tests => 18;
|
||||
use Test::NoWarnings;
|
||||
use Test::MockModule;
|
||||
use Test::Mojo;
|
||||
|
|
@ -523,6 +523,90 @@ subtest 'suspend and resume tests' => sub {
|
|||
$schema->storage->txn_rollback;
|
||||
};
|
||||
|
||||
subtest 'suspend bulk tests' => sub {
|
||||
|
||||
plan tests => 16;
|
||||
|
||||
$schema->storage->txn_begin;
|
||||
|
||||
my $password = 'AbcdEFG123';
|
||||
|
||||
my $patron = $builder->build_object( { class => 'Koha::Patrons', value => { userid => 'tomasito', flags => 0 } } );
|
||||
$builder->build(
|
||||
{
|
||||
source => 'UserPermission',
|
||||
value => {
|
||||
borrowernumber => $patron->borrowernumber,
|
||||
module_bit => 6,
|
||||
code => 'place_holds',
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
$patron->set_password( { password => $password, skip_validation => 1 } );
|
||||
my $userid = $patron->userid;
|
||||
|
||||
# Disable logging
|
||||
t::lib::Mocks::mock_preference( 'HoldsLog', 0 );
|
||||
t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
|
||||
|
||||
my $hold = $builder->build_object(
|
||||
{
|
||||
class => 'Koha::Holds',
|
||||
value => { suspend => 0, suspend_until => undef, waitingdate => undef, found => undef }
|
||||
}
|
||||
);
|
||||
|
||||
my $hold_2 = $builder->build_object(
|
||||
{
|
||||
class => 'Koha::Holds',
|
||||
value => { suspend => 0, suspend_until => undef, waitingdate => undef, found => undef }
|
||||
}
|
||||
);
|
||||
|
||||
ok( !$hold->is_suspended, 'Hold is not suspended' );
|
||||
ok( !$hold_2->is_suspended, 'Hold is not suspended' );
|
||||
|
||||
$t->post_ok(
|
||||
"//$userid:$password@/api/v1/holds/suspension_bulk" => json => { hold_ids => [ $hold->id, $hold_2->id ] } )
|
||||
->status_is( 201, 'Hold bulk suspension created' );
|
||||
|
||||
$hold->discard_changes;
|
||||
$hold_2->discard_changes;
|
||||
|
||||
ok( $hold->is_suspended, 'Hold is suspended' );
|
||||
ok( $hold_2->is_suspended, 'Hold is suspended' );
|
||||
|
||||
$hold->resume;
|
||||
$hold_2->resume;
|
||||
|
||||
ok( !$hold->is_suspended, 'Hold is not suspended' );
|
||||
ok( !$hold_2->is_suspended, 'Hold is not suspended' );
|
||||
|
||||
$t->post_ok( "//$userid:$password@/api/v1/holds/suspension_bulk" => json =>
|
||||
{ end_date => "2024-07-30", hold_ids => [ $hold->id, $hold_2->id ] } )
|
||||
->status_is( 201, 'Hold bulk suspension created' )
|
||||
->json_is( { end_date => "2024-07-30", hold_ids => [ $hold->id, $hold_2->id ] } );
|
||||
|
||||
$hold->discard_changes;
|
||||
$hold_2->discard_changes;
|
||||
|
||||
$hold_2->delete;
|
||||
|
||||
$hold->resume;
|
||||
ok( !$hold->is_suspended, 'Hold is not suspended' );
|
||||
|
||||
$t->post_ok( "//$userid:$password@/api/v1/holds/suspension_bulk" => json => { hold_ids => [ $hold_2->id ] } )
|
||||
->status_is( 404, 'Hold bulk suspension failed. Hold not found' );
|
||||
ok( !$hold->is_suspended, 'Hold is not suspended. Bulk suspension failed' );
|
||||
|
||||
$hold->discard_changes;
|
||||
|
||||
ok( !$hold->is_suspended, 'Hold is not suspended. Bulk suspension failed' );
|
||||
|
||||
$schema->storage->txn_rollback;
|
||||
};
|
||||
|
||||
subtest 'PUT /holds/{hold_id}/priority tests' => sub {
|
||||
|
||||
plan tests => 14;
|
||||
|
|
|
|||
Loading…
Reference in New Issue