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 => 17;
20
use Test::More tests => 18;
21
use Test::NoWarnings;
21
use Test::NoWarnings;
22
use Test::MockModule;
22
use Test::MockModule;
23
use Test::Mojo;
23
use Test::Mojo;
Lines 523-528 subtest 'suspend and resume tests' => sub { Link Here
523
    $schema->storage->txn_rollback;
523
    $schema->storage->txn_rollback;
524
};
524
};
525
525
526
subtest 'suspend bulk tests' => sub {
527
528
    plan tests => 16;
529
530
    $schema->storage->txn_begin;
531
532
    my $password = 'AbcdEFG123';
533
534
    my $patron = $builder->build_object( { class => 'Koha::Patrons', value => { userid => 'tomasito', flags => 0 } } );
535
    $builder->build(
536
        {
537
            source => 'UserPermission',
538
            value  => {
539
                borrowernumber => $patron->borrowernumber,
540
                module_bit     => 6,
541
                code           => 'place_holds',
542
            },
543
        }
544
    );
545
546
    $patron->set_password( { password => $password, skip_validation => 1 } );
547
    my $userid = $patron->userid;
548
549
    # Disable logging
550
    t::lib::Mocks::mock_preference( 'HoldsLog',      0 );
551
    t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
552
553
    my $hold = $builder->build_object(
554
        {
555
            class => 'Koha::Holds',
556
            value => { suspend => 0, suspend_until => undef, waitingdate => undef, found => undef }
557
        }
558
    );
559
560
    my $hold_2 = $builder->build_object(
561
        {
562
            class => 'Koha::Holds',
563
            value => { suspend => 0, suspend_until => undef, waitingdate => undef, found => undef }
564
        }
565
    );
566
567
    ok( !$hold->is_suspended,   'Hold is not suspended' );
568
    ok( !$hold_2->is_suspended, 'Hold is not suspended' );
569
570
    $t->post_ok(
571
        "//$userid:$password@/api/v1/holds/suspension_bulk" => json => { hold_ids => [ $hold->id, $hold_2->id ] } )
572
        ->status_is( 201, 'Hold bulk suspension created' );
573
574
    $hold->discard_changes;
575
    $hold_2->discard_changes;
576
577
    ok( $hold->is_suspended,   'Hold is suspended' );
578
    ok( $hold_2->is_suspended, 'Hold is suspended' );
579
580
    $hold->resume;
581
    $hold_2->resume;
582
583
    ok( !$hold->is_suspended,   'Hold is not suspended' );
584
    ok( !$hold_2->is_suspended, 'Hold is not suspended' );
585
586
    $t->post_ok( "//$userid:$password@/api/v1/holds/suspension_bulk" => json =>
587
            { end_date => "2024-07-30", hold_ids => [ $hold->id, $hold_2->id ] } )
588
        ->status_is( 201, 'Hold bulk suspension created' )
589
        ->json_is( { end_date => "2024-07-30", hold_ids => [ $hold->id, $hold_2->id ] } );
590
591
    $hold->discard_changes;
592
    $hold_2->discard_changes;
593
594
    $hold_2->delete;
595
596
    $hold->resume;
597
    ok( !$hold->is_suspended, 'Hold is not suspended' );
598
599
    $t->post_ok( "//$userid:$password@/api/v1/holds/suspension_bulk" => json => { hold_ids => [ $hold_2->id ] } )
600
        ->status_is( 404, 'Hold bulk suspension failed. Hold not found' );
601
    ok( !$hold->is_suspended, 'Hold is not suspended. Bulk suspension failed' );
602
603
    $hold->discard_changes;
604
605
    ok( !$hold->is_suspended, 'Hold is not suspended. Bulk suspension failed' );
606
607
    $schema->storage->txn_rollback;
608
};
609
526
subtest 'PUT /holds/{hold_id}/priority tests' => sub {
610
subtest 'PUT /holds/{hold_id}/priority tests' => sub {
527
611
528
    plan tests => 14;
612
    plan tests => 14;
529
- 

Return to bug 40395