1 package Koha::REST::V1::Checkouts;
3 # This file is part of Koha.
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
20 use Mojo::Base 'Mojolicious::Controller';
23 use C4::Auth qw( haspermission );
25 use C4::Circulation qw( AddIssue AddRenewal CanBookBeRenewed );
27 use Koha::Old::Checkouts;
30 use Try::Tiny qw( catch try );
34 Koha::REST::V1::Checkout
42 List Koha::Checkout objects
47 my $c = shift->openapi->valid_input or return;
49 my $checked_in = delete $c->validation->output->{checked_in};
55 $checkouts_set = Koha::Old::Checkouts->new;
57 $checkouts_set = Koha::Checkouts->new;
60 my $checkouts = $c->objects->search( $checkouts_set );
67 $c->unhandled_exception($_);
78 my $c = shift->openapi->valid_input or return;
80 my $checkout_id = $c->validation->param('checkout_id');
81 my $checkout = Koha::Checkouts->find( $checkout_id );
82 $checkout = Koha::Old::Checkouts->find( $checkout_id )
88 openapi => { error => "Checkout doesn't exist" }
95 openapi => $checkout->to_api
99 $c->unhandled_exception($_);
103 =head3 _check_availability
105 Internal function to call CanBookBeIssued and return an appropriately filtered
110 sub _check_availability {
111 my ( $c, $patron, $item ) = @_;
113 my $inprocess = 0; # What does this do?
114 my $ignore_reserves = 0; # Don't ignore reserves
115 my $params = { item => $item };
117 my ( $impossible, $confirmation, $alerts, $messages ) =
118 C4::Circulation::CanBookBeIssued( $patron, undef, undef, $inprocess,
119 $ignore_reserves, $params );
121 if ( $c->stash('is_public') ) {
123 # Upgrade some confirmations to blockers
125 qw/TOO_MANY ISSUED_TO_ANOTHER RESERVED RESERVED_WAITING TRANSFERRED PROCESSING AGE_RESTRICTION/;
126 for my $block (@should_block) {
127 if ( exists( $confirmation->{$block} ) ) {
128 $impossible->{$block} = $confirmation->{$block};
129 delete $confirmation->{$block};
133 # Remove any non-public info that's returned by CanBookBeIssued
134 my @restricted_keys =
135 qw/issued_borrowernumber issued_cardnumber issued_firstname issued_surname resborrowernumber resbranchcode rescardnumber reserve_id resfirstname resreservedate ressurname item_notforloan/;
136 for my $key (@restricted_keys) {
137 delete $confirmation->{$key};
138 delete $impossible->{$key};
139 delete $alerts->{$key};
140 delete $messages->{$key};
144 return ( $impossible, $confirmation, { %{$alerts}, %{$messages} } );
147 =head3 get_availability
149 Controller function that handles retrieval of Checkout availability
153 sub get_availability {
154 my $c = shift->openapi->valid_input or return;
155 my $user = $c->stash('koha.user');
157 my $patron = Koha::Patrons->find( $c->param('patron_id') );
158 my $item = Koha::Items->find( $c->param('item_id') );
160 my ( $impossible, $confirmation, $warnings ) =
161 $c->_check_availability( $patron, $item );
163 my $confirm_keys = join( ":", sort keys %{$confirmation} );
164 $confirm_keys = $user->id . ":" . $item->id . ":" . $confirm_keys;
165 my $token = Koha::Token->new->generate_jwt( { id => $confirm_keys } );
168 blockers => $impossible,
169 confirms => $confirmation,
170 warnings => $warnings,
171 confirmation_token => $token
174 return $c->render( status => 200, openapi => $response );
184 my $c = shift->openapi->valid_input or return;
185 my $user = $c->stash('koha.user');
187 my $body = $c->req->json;
188 my $item_id = $body->{item_id};
189 my $patron_id = $body->{patron_id};
190 my $onsite = $body->{onsite_checkout};
193 my $item = Koha::Items->find($item_id);
198 error => 'Item not found',
199 error_code => 'ITEM_NOT_FOUND',
204 my $patron = Koha::Patrons->find($patron_id);
209 error => 'Patron not found',
210 error_code => 'PATRON_NOT_FOUND',
215 my ( $impossible, $confirmation, $warnings ) =
216 $c->_check_availability( $patron, $item );
218 # * Fail for blockers - render 403
219 if ( keys %{$impossible} ) {
220 my @errors = keys %{$impossible};
223 openapi => { error => "Checkout not authorized (@errors)" }
227 # * If confirmation required, check variable set above
228 # and render 412 if variable is false
229 if ( keys %{$confirmation} ) {
232 # Check for existence of confirmation token
233 # and if exists check validity
234 if ( my $token = $c->param('confirmation') ) {
235 my $confirm_keys = join( ":", sort keys %{$confirmation} );
236 $confirm_keys = $user->id . ":" . $item->id . ":" . $confirm_keys;
237 $confirmed = Koha::Token->new->check_jwt(
238 { id => $confirm_keys, token => $token } );
241 unless ($confirmed) {
244 openapi => { error => "Confirmation error" }
250 my $checkout = AddIssue( $patron->unblessed, $item->barcode );
252 $c->res->headers->location(
253 $c->req->url->to_string . '/' . $checkout->id );
256 openapi => $checkout->to_api
262 openapi => { error => 'Unknown error during checkout' }
267 $c->unhandled_exception($_);
273 List Koha::Checkout::Renewals
278 my $c = shift->openapi->valid_input or return;
281 my $checkout_id = $c->validation->param('checkout_id');
282 my $checkout = Koha::Checkouts->find($checkout_id);
283 $checkout = Koha::Old::Checkouts->find($checkout_id)
289 openapi => { error => "Checkout doesn't exist" }
293 my $renewals_rs = $checkout->renewals;
294 my $renewals = $c->objects->search( $renewals_rs );
302 $c->unhandled_exception($_);
314 my $c = shift->openapi->valid_input or return;
316 my $checkout_id = $c->validation->param('checkout_id');
317 my $seen = $c->validation->param('seen') || 1;
318 my $checkout = Koha::Checkouts->find( $checkout_id );
323 openapi => { error => "Checkout doesn't exist" }
328 my ($can_renew, $error) = CanBookBeRenewed($checkout->patron, $checkout);
333 openapi => { error => "Renewal not authorized ($error)" }
338 $checkout->borrowernumber,
339 $checkout->itemnumber,
340 $checkout->branchcode,
345 $checkout = Koha::Checkouts->find($checkout_id);
347 $c->res->headers->location( $c->req->url->to_string );
350 openapi => $checkout->to_api
354 $c->unhandled_exception($_);
358 =head3 allows_renewal
360 Checks if the checkout could be renewed and return the related information.
365 my $c = shift->openapi->valid_input or return;
367 my $checkout_id = $c->validation->param('checkout_id');
368 my $checkout = Koha::Checkouts->find( $checkout_id );
373 openapi => { error => "Checkout doesn't exist" }
378 my ($can_renew, $error) = CanBookBeRenewed($checkout->patron, $checkout);
380 my $renewable = Mojo::JSON->false;
381 $renewable = Mojo::JSON->true if $can_renew;
383 my $rule = Koha::CirculationRules->get_effective_rule(
385 categorycode => $checkout->patron->categorycode,
386 itemtype => $checkout->item->effective_itemtype,
387 branchcode => $checkout->branchcode,
388 rule_name => 'renewalsallowed',
394 allows_renewal => $renewable,
395 max_renewals => $rule->rule_value,
396 current_renewals => $checkout->renewals_count,
397 unseen_renewals => $checkout->unseen_renewals,
403 $c->unhandled_exception($_);