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

(-)a/C4/Circulation.pm (-1 / +1 lines)
Lines 774-780 sub CanBookBeIssued { Link Here
774
    my $onsite_checkout     = $params->{onsite_checkout}     || 0;
774
    my $onsite_checkout     = $params->{onsite_checkout}     || 0;
775
    my $override_high_holds = $params->{override_high_holds} || 0;
775
    my $override_high_holds = $params->{override_high_holds} || 0;
776
776
777
    my $item_object = Koha::Items->find({barcode => $barcode });
777
    my $item_object = $params->{item} // Koha::Items->find({barcode => $barcode });
778
778
779
    # MANDATORY CHECKS - unless item exists, nothing else matters
779
    # MANDATORY CHECKS - unless item exists, nothing else matters
780
    unless ( $item_object ) {
780
    unless ( $item_object ) {
(-)a/Koha/Item.pm (-1 lines)
Lines 337-343 sub move_to_deleted { Link Here
337
    return Koha::Database->new->schema->resultset('Deleteditem')->create($item_infos);
337
    return Koha::Database->new->schema->resultset('Deleteditem')->create($item_infos);
338
}
338
}
339
339
340
341
=head3 effective_itemtype
340
=head3 effective_itemtype
342
341
343
Returns the itemtype for the item based on whether item level itemtypes are set or not.
342
Returns the itemtype for the item based on whether item level itemtypes are set or not.
(-)a/Koha/REST/V1/Checkouts.pm (-1 / +151 lines)
Lines 19-28 use Modern::Perl; Link Here
19
19
20
use Mojo::Base 'Mojolicious::Controller';
20
use Mojo::Base 'Mojolicious::Controller';
21
use Mojo::JSON;
21
use Mojo::JSON;
22
use Mojo::JWT;
23
use Digest::MD5 qw( md5_base64 );
24
use Encode;
22
25
23
use C4::Auth qw( haspermission );
26
use C4::Auth qw( haspermission );
24
use C4::Context;
27
use C4::Context;
25
use C4::Circulation qw( AddRenewal );
28
use C4::Circulation qw( CanBookBeIssued AddIssue AddRenewal );
26
use Koha::Checkouts;
29
use Koha::Checkouts;
27
use Koha::Old::Checkouts;
30
use Koha::Old::Checkouts;
28
31
Lines 99-104 sub get { Link Here
99
    };
102
    };
100
}
103
}
101
104
105
=head3 get_availablity
106
107
Controller function that handles retrieval of Checkout availability
108
109
=cut
110
111
sub get_availability {
112
    my $c = shift->openapi->valid_input or return;
113
114
    my $patron = Koha::Patrons->find( $c->validation->param('patron_id') );
115
    my $inprocess = 0; # What does this do?
116
    my $ignore_reserves = 0; # Don't ignore reserves
117
    my $item   = Koha::Items->find( $c->validation->param('item_id') );
118
    my $params = {
119
        item => $item
120
    };
121
122
    my ( $impossible, $confirmation, $alerts, $messages ) =
123
      CanBookBeIssued( $patron, undef, undef, $inprocess, $ignore_reserves,
124
        $params );
125
126
    my $token;
127
    if (keys %{$confirmation}) {
128
        my $claims = { map { $_ => 1 } keys %{$confirmation} };
129
        my $secret =
130
          md5_base64( Encode::encode( 'UTF-8', C4::Context->config('pass') ) );
131
        $token = Mojo::JWT->new( claims => $claims, secret => $secret )->encode;
132
    }
133
134
    my $response = {
135
        blockers           => $impossible,
136
        confirms           => $confirmation,
137
        warnings           => { %{$alerts}, %{$messages} },
138
        confirmation_token => $token
139
    };
140
141
    return $c->render( status => 200, openapi => $response );
142
}
143
144
=head3 add
145
146
Add a new checkout
147
148
=cut
149
150
sub add {
151
    my $c = shift->openapi->valid_input or return;
152
153
    my $params = $c->validation->param('body');
154
    my $item_id = $params->{item_id};
155
    my $patron_id = $params->{patron_id};
156
    my $onsite = $params->{onsite_checkout};
157
158
    return try {
159
        my $item = Koha::Items->find( $item_id );
160
        unless ($item) {
161
            return $c->render(
162
                status  => 409,
163
                openapi => {
164
                    error      => 'Item not found',
165
                    error_code => 'ITEM_NOT_FOUND',
166
                }
167
            );
168
        }
169
170
        my $patron = Koha::Patrons->find( $patron_id );
171
        unless ($patron) {
172
            return $c->render(
173
                status  => 409,
174
                openapi => {
175
                    error      => 'Patron not found',
176
                    error_code => 'PATRON_NOT_FOUND',
177
                }
178
            );
179
        }
180
181
        my $inprocess = 0; # What does this do?
182
        my $ignore_reserves = 0; # Don't ignore reserves
183
        my $params = {
184
            item => $item
185
        };
186
187
        # Call 'CanBookBeIssued'
188
        my ( $impossible, $confirmation, $alerts, $messages ) =
189
          CanBookBeIssued( $patron, undef, undef, $inprocess, $ignore_reserves,
190
            $params );
191
192
        # * Fail for blockers - render 403
193
        if (keys %{$impossible}) {
194
            my @errors = keys %{$impossible};
195
            return $c->render(
196
                status => 403,
197
                openapi => { error => "Checkout not authorized (@errors)" }
198
            );
199
        }
200
201
        # * If confirmation required, check variable set above - render 412 if variable is false
202
        if (keys %{$confirmation}) {
203
            my $confirmed = 0;
204
205
            # Check for existance of confirmation token and if exists check validity
206
            if ( my $token = $c->validation->param('confirmation') ) {
207
                my $secret =
208
                  md5_base64(
209
                    Encode::encode( 'UTF-8', C4::Context->config('pass') ) );
210
                my $claims = try {
211
                    Mojo::JWT->new( secret => $secret )->decode($token);
212
                } catch {
213
                    return $c->render(
214
                        status  => 403,
215
                        openapi =>
216
                          { error => "Confirmation required" }
217
                    );
218
                };
219
220
                # check claims match
221
                my $token_claims = join( / /, sort keys %{$claims} );
222
                my $confirm_keys = join( / /, sort keys %{$confirmation} );
223
                $confirmed = 1 if ( $token_claims eq $confirm_keys );
224
            }
225
226
            unless ($confirmed) {
227
                return $c->render(
228
                    status  => 412,
229
                    openapi => { error => "Confirmation error" }
230
                );
231
            }
232
        }
233
234
        # Call 'AddIssue'
235
        my $checkout = AddIssue($patron->unblessed, $item->barcode);
236
237
        # Check return of AddIssue
238
        # Get checkout from AddIssue - render 201
239
        # Get error from AddIssue - render 400?
240
241
        $c->res->headers->location( $c->req->url->to_string . '/' . $checkout->id );
242
        return $c->render(
243
            status  => 201,
244
            openapi => $checkout->to_api
245
        );
246
    }
247
    catch {
248
        $c->unhandled_exception($_);
249
    };
250
}
251
102
=head3 get_renewals
252
=head3 get_renewals
103
253
104
List Koha::Checkout::Renewals
254
List Koha::Checkout::Renewals
(-)a/api/v1/swagger/paths/checkouts.yaml (+128 lines)
Lines 61-66 Link Here
61
    x-koha-authorization:
61
    x-koha-authorization:
62
      permissions:
62
      permissions:
63
        circulate: circulate_remaining_permissions
63
        circulate: circulate_remaining_permissions
64
  post:
65
    x-mojo-to: Checkouts#add
66
    operationId: addCheckout
67
    tags:
68
      - checkouts
69
    summary: Add a new checkout
70
    parameters:
71
      - name: body
72
        in: body
73
        description: A JSON object containing informations about the new checkout
74
        required: true
75
        schema:
76
          $ref: "../swagger.yaml#/definitions/checkout"
77
    produces:
78
      - application/json
79
    responses:
80
      "201":
81
        description: Created new checkout
82
        schema:
83
          $ref: "../swagger.yaml#/definitions/checkout"
84
      "403":
85
        description: Cannot create checkout
86
        schema:
87
          $ref: "../swagger.yaml#/definitions/error"
88
      "404":
89
        description: Checkout not found
90
        schema:
91
          $ref: "../swagger.yaml#/definitions/error"
92
      "409":
93
        description: Conflict in creating resource
94
        schema:
95
          $ref: "../swagger.yaml#/definitions/error"
96
      "412":
97
        description: Precondition failed
98
        schema:
99
          $ref: "../swagger.yaml#/definitions/error"
100
      "500":
101
        description: |
102
          Internal server error. Possible `error_code` attribute values:
103
104
          * `internal_server_error`
105
        schema:
106
          $ref: "../swagger.yaml#/definitions/error"
107
      "503":
108
        description: Under maintenance
109
        schema:
110
          $ref: "../swagger.yaml#/definitions/error"
64
"/checkouts/{checkout_id}":
111
"/checkouts/{checkout_id}":
65
  get:
112
  get:
66
    x-mojo-to: Checkouts#get
113
    x-mojo-to: Checkouts#get
Lines 275-277 Link Here
275
    x-koha-authorization:
322
    x-koha-authorization:
276
      permissions:
323
      permissions:
277
        circulate: circulate_remaining_permissions
324
        circulate: circulate_remaining_permissions
325
"/public/checkouts":
326
  post:
327
    x-mojo-to: Checkouts#add
328
    operationId: addCheckoutPublic
329
    tags:
330
      - checkouts
331
    summary: Add a new checkout
332
    parameters:
333
      - name: body
334
        in: body
335
        description: A JSON object containing informations about the new checkout
336
        required: true
337
        schema:
338
          $ref: "../swagger.yaml#/definitions/checkout"
339
      - name: confirmation
340
        in: query
341
        description: A JWT confirmation token
342
        required: false
343
        type: string
344
    produces:
345
      - application/json
346
    responses:
347
      "201":
348
        description: Created new checkout
349
        schema:
350
          $ref: "../swagger.yaml#/definitions/checkout"
351
      "403":
352
        description: Cannot create checkout
353
        schema:
354
          $ref: "../swagger.yaml#/definitions/error"
355
      "404":
356
        description: Checkout not found
357
        schema:
358
          $ref: "../swagger.yaml#/definitions/error"
359
      "412":
360
        description: Confirmaion required
361
        schema:
362
          $ref: "../swagger.yaml#/definitions/error"
363
      "500":
364
        description: |
365
          Internal server error. Possible `error_code` attribute values:
366
367
          * `internal_server_error`
368
        schema:
369
          $ref: "../swagger.yaml#/definitions/error"
370
      "503":
371
        description: Under maintenance
372
        schema:
373
          $ref: "../swagger.yaml#/definitions/error"
374
"/public/checkouts/availability":
375
  get:
376
    x-mojo-to: Checkouts#get_availability
377
    operationId: availabilityCheckoutsPublic
378
    tags:
379
      - checkouts
380
    summary: Get checkout availability
381
    parameters:
382
      - $ref: "../swagger.yaml#/parameters/patron_id_qp"
383
      - $ref: "../swagger.yaml#/parameters/item_id_qp"
384
    produces:
385
      - application/json
386
    responses:
387
      "200":
388
        description: Availability
389
        schema:
390
          type: "object"
391
      "403":
392
        description: Access forbidden
393
        schema:
394
          $ref: "../swagger.yaml#/definitions/error"
395
      "500":
396
        description: |
397
          Internal server error. Possible `error_code` attribute values:
398
399
          * `internal_server_error`
400
        schema:
401
          $ref: "../swagger.yaml#/definitions/error"
402
      "503":
403
        description: Under maintenance
404
        schema:
405
          $ref: "../swagger.yaml#/definitions/error"
(-)a/api/v1/swagger/swagger.yaml (-1 / +9 lines)
Lines 211-216 paths: Link Here
211
    $ref: "./paths/patrons_password.yaml#/~1patrons~1{patron_id}~1password~1expiration_date"
211
    $ref: "./paths/patrons_password.yaml#/~1patrons~1{patron_id}~1password~1expiration_date"
212
  "/public/biblios/{biblio_id}":
212
  "/public/biblios/{biblio_id}":
213
    $ref: "./paths/biblios.yaml#/~1public~1biblios~1{biblio_id}"
213
    $ref: "./paths/biblios.yaml#/~1public~1biblios~1{biblio_id}"
214
  "/public/checkouts":
215
    $ref: ./paths/checkouts.yaml#/~1public~1checkouts
216
  "/public/checkouts/availability":
217
    $ref: ./paths/checkouts.yaml#/~1public~1checkouts~1availability
214
  "/public/items":
218
  "/public/items":
215
    $ref: "./paths/items.yaml#/~1public~1items"
219
    $ref: "./paths/items.yaml#/~1public~1items"
216
  "/public/biblios/{biblio_id}/items":
220
  "/public/biblios/{biblio_id}/items":
Lines 334-339 parameters: Link Here
334
    name: item_id
338
    name: item_id
335
    required: true
339
    required: true
336
    type: integer
340
    type: integer
341
  item_id_qp:
342
    description: Internal item identifier
343
    in: query
344
    name: item_id
345
    type: integer
337
  job_id_pp:
346
  job_id_pp:
338
    description: Job internal identifier
347
    description: Job internal identifier
339
    in: path
348
    in: path
340
- 

Return to bug 30979