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

(-)a/Koha/REST/V1/Items.pm (+60 lines)
Lines 148-151 sub pickup_locations { Link Here
148
    };
148
    };
149
}
149
}
150
150
151
=head3 checkout
152
153
Check out an item
154
155
=cut
156
157
sub checkout {
158
    my $c = shift->openapi->valid_input or return;
159
160
    my $item_id = $c->validation->param('item_id');
161
    my $item = Koha::Items->find( $item_id );
162
163
    unless ( $item ) {
164
        return $c->render(
165
            status  => 404,
166
            openapi => { error => "Item not found" }
167
        );
168
    }
169
170
    my $patron_id = $c->validation->param('patron_id');
171
    my $patron    = Koha::Patrons->find( $patron_id );
172
173
    unless ( $patron ) {
174
        return $c->render(
175
            status  => 400,
176
            openapi => { error => "Patron not found" }
177
        );
178
    }
179
180
    try {
181
        my $barcode = $item->barcode;
182
        my ( $issuing_impossible, $needs_confirmation ) = C4::Circulation::CanBookBeIssued(
183
            $patron, $barcode );
184
185
        if ( keys %$issuing_impossible or keys %$needs_confirmation ) {
186
            return $c->render(
187
                status => 403,
188
                openapi => { error => "Checkout not allowed" }
189
            );
190
        }
191
192
        my $borrower = $patron->unblessed;
193
194
        my $checkout = C4::Circulation::AddIssue(
195
            $borrower,
196
            $barcode
197
        );
198
199
        $c->res->headers->location( $c->req->url->to_string );
200
        return $c->render(
201
            status  => 201,
202
            openapi => $checkout->to_api
203
        );
204
    }
205
    catch {
206
        $c->unhandled_exception($_);
207
    };
208
}
209
210
151
1;
211
1;
(-)a/api/v1/swagger/paths/items.yaml (+35 lines)
Lines 156-158 Link Here
156
    x-koha-authorization:
156
    x-koha-authorization:
157
      permissions:
157
      permissions:
158
        reserveforothers: place_holds
158
        reserveforothers: place_holds
159
"/items/{item_id}/checkout/{patron_id}":
160
  post:
161
    x-mojo-to: Items#checkout
162
    operationId: addCheckout
163
    tags:
164
      - items
165
      - checkouts
166
    summary: Add a checkout
167
    parameters:
168
      - $ref: "../swagger.yaml#/parameters/item_id_pp"
169
      - $ref: "../swagger.yaml#/parameters/patron_id_pp"
170
    consumes:
171
      - application/json
172
    produces:
173
      - application/json
174
    responses:
175
      "201":
176
        description: Added checkout
177
        schema:
178
          $ref: "../swagger.yaml#/definitions/checkout"
179
      "400":
180
        description: Patron not found
181
        schema:
182
          $ref: "../swagger.yaml#/definitions/error"
183
      "403":
184
        description: Cannot add checkout
185
        schema:
186
          $ref: "../swagger.yaml#/definitions/error"
187
      "404":
188
        description: Item not found
189
        schema:
190
          $ref: "../swagger.yaml#/definitions/error"
191
    x-koha-authorization:
192
      permissions:
193
        circulate: circulate_remaining_permissions
(-)a/api/v1/swagger/swagger.yaml (+2 lines)
Lines 157-162 paths: Link Here
157
    $ref: "./paths/items.yaml#/~1items~1{item_id}"
157
    $ref: "./paths/items.yaml#/~1items~1{item_id}"
158
  "/items/{item_id}/pickup_locations":
158
  "/items/{item_id}/pickup_locations":
159
    $ref: "./paths/items.yaml#/~1items~1{item_id}~1pickup_locations"
159
    $ref: "./paths/items.yaml#/~1items~1{item_id}~1pickup_locations"
160
  "/items/{item_id}/checkout/{patron_id}":
161
    $ref: "./paths/items.yaml#/~1items~1{item_id}~1checkout~1{patron_id}"
160
  /jobs:
162
  /jobs:
161
    $ref: ./paths/jobs.yaml#/~1jobs
163
    $ref: ./paths/jobs.yaml#/~1jobs
162
  "/jobs/{job_id}":
164
  "/jobs/{job_id}":
(-)a/t/db_dependent/api/v1/items.t (-2 / +69 lines)
Lines 19-25 Link Here
19
19
20
use Modern::Perl;
20
use Modern::Perl;
21
21
22
use Test::More tests => 3;
22
use Test::More tests => 4;
23
use Test::Mojo;
23
use Test::Mojo;
24
use Test::Warn;
24
use Test::Warn;
25
25
Lines 321-323 subtest 'pickup_locations() tests' => sub { Link Here
321
321
322
    $schema->storage->txn_rollback;
322
    $schema->storage->txn_rollback;
323
};
323
};
324
- 
324
325
subtest 'checkout() tests' => sub {
326
327
    plan tests => 12;
328
329
    $schema->storage->txn_begin;
330
331
    my $item   = $builder->build_sample_item;
332
    my $patron = $builder->build_object(
333
        {
334
            class => 'Koha::Patrons',
335
            value => { flags => 4 }
336
        }
337
    );
338
339
    # Make sure we have at least 10 items
340
    for ( 1..10 ) {
341
        $builder->build_sample_item;
342
    }
343
344
    my $nonprivilegedpatron = $builder->build_object(
345
        {
346
            class => 'Koha::Patrons',
347
            value => { flags => 0 }
348
        }
349
    );
350
351
    my $password = 'thePassword123';
352
353
    $nonprivilegedpatron->set_password(
354
        { password => $password, skip_validation => 1 } );
355
356
    my $userid = $nonprivilegedpatron->userid;
357
    my $itemid = $item->id;
358
    my $patronid = $patron->id;
359
360
    $t->get_ok( "//$userid:$password@/api/v1/items/$itemid/checkout/$patronid" )
361
      ->status_is(403)
362
      ->json_is(
363
        '/error' => 'Authorization failure. Missing required permission(s).' );
364
    
365
    $t->get_ok( "//$userid:$password@/api/v1/items/" . $non_existent_code )
366
      ->status_is(404)
367
      ->json_is( 
368
        '/error' => 'Item not found' );
369
370
    $userid = $patron->userid;
371
372
    $t->get_ok( "//$userid:$password@/api/v1/items?_per_page=10" )
373
      ->status_is( 200, 'SWAGGER3.2.2' );
374
375
    my $response_count = scalar @{ $t->tx->res->json };
376
377
    is( $response_count, 10, 'The API returns 10 items' );
378
379
    $t->get_ok( "//$userid:$password@/api/v1/items?external_id=" . $item->barcode )
380
      ->status_is(200)
381
      ->json_is( '' => [ $item->to_api ], 'SWAGGER3.3.2');
382
383
    my $barcode = $item->barcode;
384
    $item->delete;
385
386
    $t->get_ok( "//$userid:$password@/api/v1/items?external_id=" . $item->barcode )
387
      ->status_is(200)
388
      ->json_is( '' => [] );
389
390
    $schema->storage->txn_rollback;
391
};

Return to bug 24400