View | Details | Raw Unified | Return to bug 40395
Collapse All | Expand All

(-)a/Koha/REST/V1/Holds.pm (+47 lines)
Lines 378-383 sub suspend { Link Here
378
    };
378
    };
379
}
379
}
380
380
381
=head3 suspend_bulk
382
383
Method that handles suspending multiple holds
384
385
=cut
386
387
sub suspend_bulk {
388
    my $c = shift->openapi->valid_input or return;
389
390
    my $body     = $c->req->json;
391
    my $end_date = ($body) ? $body->{end_date} : undef;
392
    my $hold_ids = ($body) ? $body->{hold_ids} : undef;
393
394
    return $c->render_resource_not_found("Hold")
395
        unless $hold_ids;
396
397
    return try {
398
        Koha::Database->new->schema->txn_do(
399
            sub {
400
                foreach my $hold_id (@$hold_ids) {
401
                    my $hold = Koha::Holds->find($hold_id);
402
403
                    return $c->render_resource_not_found( "Hold", "id", $hold_id )
404
                        unless $hold;
405
406
                    $hold->suspend_hold($end_date);
407
                    $hold->discard_changes;
408
                }
409
                $c->res->headers->location( $c->req->url->to_string );
410
                return $c->render(
411
                    status  => 201,
412
                    openapi => {
413
                        hold_ids => $hold_ids,
414
                        end_date => $end_date,
415
                    }
416
                );
417
            }
418
        );
419
    } catch {
420
        if ( blessed $_ and $_->isa('Koha::Exceptions::Hold::CannotSuspendFound') ) {
421
            return $c->render( status => 400, openapi => { error => "$_" } );
422
        }
423
424
        $c->unhandled_exception($_);
425
    };
426
}
427
381
=head3 resume
428
=head3 resume
382
429
383
Method that handles resuming a hold
430
Method that handles resuming a hold
(-)a/api/v1/swagger/paths/holds.yaml (+61 lines)
Lines 279-284 Link Here
279
    x-koha-authorization:
279
    x-koha-authorization:
280
      permissions:
280
      permissions:
281
        reserveforothers: "1"
281
        reserveforothers: "1"
282
"/holds/suspension_bulk":
283
  post:
284
    x-mojo-to: Holds#suspend_bulk
285
    operationId: suspendHoldBulk
286
    tags:
287
      - holds
288
    summary: Suspend the holds
289
    parameters:
290
      - name: body
291
        in: body
292
        description: Hold ids
293
        required: true
294
        schema:
295
          type: object
296
          properties:
297
            end_date:
298
              description: Date the hold suspension expires
299
              type: string
300
              format: date
301
            hold_ids:
302
              type: array
303
              items:
304
                type: integer
305
          additionalProperties: false
306
    consumes:
307
      - application/json
308
    produces:
309
      - application/json
310
    responses:
311
      "201":
312
        description: Holds suspended
313
      "400":
314
        description: Bad request
315
        schema:
316
          $ref: "../swagger.yaml#/definitions/error"
317
      "401":
318
        description: Authentication required
319
        schema:
320
          $ref: "../swagger.yaml#/definitions/error"
321
      "403":
322
        description: Hold not allowed
323
        schema:
324
          $ref: "../swagger.yaml#/definitions/error"
325
      "404":
326
        description: Hold not found
327
        schema:
328
          $ref: "../swagger.yaml#/definitions/error"
329
      "500":
330
        description: |
331
          Internal server error. Possible `error_code` attribute values:
332
333
          * `internal_server_error`
334
        schema:
335
          $ref: "../swagger.yaml#/definitions/error"
336
      "503":
337
        description: Under maintenance
338
        schema:
339
          $ref: "../swagger.yaml#/definitions/error"
340
    x-koha-authorization:
341
      permissions:
342
        reserveforothers: place_holds
282
"/holds/{hold_id}":
343
"/holds/{hold_id}":
283
  patch:
344
  patch:
284
    x-mojo-to: Holds#edit
345
    x-mojo-to: Holds#edit
(-)a/api/v1/swagger/swagger.yaml (+2 lines)
Lines 399-404 paths: Link Here
399
    $ref: ./paths/extended_attribute_types.yaml#/~1extended_attribute_types
399
    $ref: ./paths/extended_attribute_types.yaml#/~1extended_attribute_types
400
  /holds:
400
  /holds:
401
    $ref: ./paths/holds.yaml#/~1holds
401
    $ref: ./paths/holds.yaml#/~1holds
402
  "/holds/suspension_bulk":
403
    $ref: "./paths/holds.yaml#/~1holds~1suspension_bulk"
402
  "/holds/{hold_id}":
404
  "/holds/{hold_id}":
403
    $ref: "./paths/holds.yaml#/~1holds~1{hold_id}"
405
    $ref: "./paths/holds.yaml#/~1holds~1{hold_id}"
404
  "/holds/{hold_id}/pickup_location":
406
  "/holds/{hold_id}/pickup_location":
(-)a/t/db_dependent/api/v1/holds.t (-2 / +85 lines)
Lines 17-23 Link Here
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Test::More tests => 16;
20
use Test::More tests => 17;
21
use Test::MockModule;
21
use Test::MockModule;
22
use Test::Mojo;
22
use Test::Mojo;
23
use t::lib::TestBuilder;
23
use t::lib::TestBuilder;
Lines 518-523 subtest 'suspend and resume tests' => sub { Link Here
518
    $schema->storage->txn_rollback;
518
    $schema->storage->txn_rollback;
519
};
519
};
520
520
521
subtest 'suspend bulk tests' => sub {
522
523
    plan tests => 16;
524
525
    $schema->storage->txn_begin;
526
527
    my $password = 'AbcdEFG123';
528
529
    my $patron = $builder->build_object( { class => 'Koha::Patrons', value => { userid => 'tomasito', flags => 0 } } );
530
    $builder->build(
531
        {
532
            source => 'UserPermission',
533
            value  => {
534
                borrowernumber => $patron->borrowernumber,
535
                module_bit     => 6,
536
                code           => 'place_holds',
537
            },
538
        }
539
    );
540
541
    $patron->set_password( { password => $password, skip_validation => 1 } );
542
    my $userid = $patron->userid;
543
544
    # Disable logging
545
    t::lib::Mocks::mock_preference( 'HoldsLog',      0 );
546
    t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
547
548
    my $hold = $builder->build_object(
549
        {
550
            class => 'Koha::Holds',
551
            value => { suspend => 0, suspend_until => undef, waitingdate => undef, found => undef }
552
        }
553
    );
554
555
    my $hold_2 = $builder->build_object(
556
        {
557
            class => 'Koha::Holds',
558
            value => { suspend => 0, suspend_until => undef, waitingdate => undef, found => undef }
559
        }
560
    );
561
562
    ok( !$hold->is_suspended,   'Hold is not suspended' );
563
    ok( !$hold_2->is_suspended, 'Hold is not suspended' );
564
565
    $t->post_ok(
566
        "//$userid:$password@/api/v1/holds/suspension_bulk" => json => { hold_ids => [ $hold->id, $hold_2->id ] } )
567
        ->status_is( 201, 'Hold bulk suspension created' );
568
569
    $hold->discard_changes;
570
    $hold_2->discard_changes;
571
572
    ok( $hold->is_suspended,   'Hold is suspended' );
573
    ok( $hold_2->is_suspended, 'Hold is suspended' );
574
575
    $hold->resume;
576
    $hold_2->resume;
577
578
    ok( !$hold->is_suspended,   'Hold is not suspended' );
579
    ok( !$hold_2->is_suspended, 'Hold is not suspended' );
580
581
    $t->post_ok( "//$userid:$password@/api/v1/holds/suspension_bulk" => json =>
582
            { end_date => "2024-07-30", hold_ids => [ $hold->id, $hold_2->id ] } )
583
        ->status_is( 201, 'Hold bulk suspension created' )
584
        ->json_is( { end_date => "2024-07-30", hold_ids => [ $hold->id, $hold_2->id ] } );
585
586
    $hold->discard_changes;
587
    $hold_2->discard_changes;
588
589
    $hold_2->delete;
590
591
    $hold->resume;
592
    ok( !$hold->is_suspended, 'Hold is not suspended' );
593
594
    $t->post_ok( "//$userid:$password@/api/v1/holds/suspension_bulk" => json => { hold_ids => [ $hold_2->id ] } )
595
        ->status_is( 404, 'Hold bulk suspension failed. Hold not found' );
596
    ok( !$hold->is_suspended, 'Hold is not suspended. Bulk suspension failed' );
597
598
    $hold->discard_changes;
599
600
    ok( !$hold->is_suspended, 'Hold is not suspended. Bulk suspension failed' );
601
602
    $schema->storage->txn_rollback;
603
};
604
521
subtest 'PUT /holds/{hold_id}/priority tests' => sub {
605
subtest 'PUT /holds/{hold_id}/priority tests' => sub {
522
606
523
    plan tests => 14;
607
    plan tests => 14;
524
- 

Return to bug 40395