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

(-)a/Koha/Biblio.pm (+107 lines)
Lines 35-40 use Koha::ArticleRequest::Status; Link Here
35
use Koha::ArticleRequests;
35
use Koha::ArticleRequests;
36
use Koha::Biblio::Metadatas;
36
use Koha::Biblio::Metadatas;
37
use Koha::Biblioitems;
37
use Koha::Biblioitems;
38
use Koha::Bookings;
38
use Koha::CirculationRules;
39
use Koha::CirculationRules;
39
use Koha::Item::Transfer::Limits;
40
use Koha::Item::Transfer::Limits;
40
use Koha::Items;
41
use Koha::Items;
Lines 132-137 sub can_article_request { Link Here
132
    return q{};
133
    return q{};
133
}
134
}
134
135
136
=head3 can_by_booked
137
138
  my $bookable =
139
    $biblio->can_be_booked( { start_date => $datetime, end_date => $datetime, [ booking_id => $booking_id ] } );
140
141
Returns a boolean denoting whether the passed booking can be made without clashing.
142
143
Optionally, you may pass a booking id to exclude from the checks; This is helpful when you are updating an existing booking.
144
145
=cut
146
147
sub can_be_booked {
148
    my ( $self, $params ) = @_;
149
150
    my $start_date = dt_from_string( $params->{start_date} );
151
    my $end_date   = dt_from_string( $params->{end_date} );
152
    my $booking_id = $params->{booking_id};
153
154
    my $bookable_items = $self->items;
155
    my $total_bookable = $bookable_items->count;
156
157
    my $dtf = Koha::Database->new->schema->storage->datetime_parser;
158
    my $existing_bookings = $self->bookings(
159
        [
160
            start_date => {
161
                '-between' => [
162
                    $dtf->format_datetime($start_date),
163
                    $dtf->format_datetime($end_date)
164
                ]
165
            },
166
            end_date => {
167
                '-between' => [
168
                    $dtf->format_datetime($start_date),
169
                    $dtf->format_datetime($end_date)
170
                ]
171
            },
172
            {
173
                start_date => { '<' => $dtf->format_datetime($start_date) },
174
                end_date   => { '>' => $dtf->format_datetime($end_date) }
175
            }
176
        ]
177
    );
178
179
    my $booked_count =
180
      defined($booking_id)
181
      ? $existing_bookings->search( { booking_id => { '!=' => $booking_id } } )
182
      ->count
183
      : $existing_bookings->count;
184
    return ( ( $total_bookable - $booked_count ) > 0 ) ? 1 : 0;
185
}
186
187
=head3 place_booking
188
189
  my $booking = $biblio->place_booking(
190
    {
191
        patron     => $patron,
192
        start_date => $datetime,
193
        end_date   => $datetime
194
    }
195
  );
196
197
Add a booking for this item for the dates passed.
198
199
Returns the Koha::Booking object or throws an exception if the item cannot be booked for the given dates.
200
201
=cut
202
203
sub place_booking {
204
    my ( $self, $params ) = @_;
205
206
    # check for mandatory params
207
    my @mandatory = ( 'start_date', 'end_date', 'patron' );
208
    for my $param (@mandatory) {
209
        unless ( defined( $params->{$param} ) ) {
210
            Koha::Exceptions::MissingParameter->throw(
211
                error => "The $param parameter is mandatory" );
212
        }
213
    }
214
    my $patron = $params->{patron};
215
216
    # New booking object
217
    my $booking = Koha::Booking->new(
218
        {
219
            start_date     => $params->{start_date},
220
            end_date       => $params->{end_date},
221
            borrowernumber => $patron->borrowernumber,
222
            biblionumber   => $self->biblionumber
223
        }
224
    )->store();
225
    return $booking;
226
}
227
135
=head3 can_be_transferred
228
=head3 can_be_transferred
136
229
137
$biblio->can_be_transferred({ to => $to_library, from => $from_library })
230
$biblio->can_be_transferred({ to => $to_library, from => $from_library })
Lines 480-485 sub biblioitem { Link Here
480
    return $self->{_biblioitem};
573
    return $self->{_biblioitem};
481
}
574
}
482
575
576
=head3 bookings
577
578
  my $bookings = $item->bookings();
579
580
Returns the bookings attached to this biblio.
581
582
=cut
583
584
sub bookings {
585
    my ( $self, $params ) = @_;
586
    my $bookings_rs = $self->_result->bookings->search($params);
587
    return Koha::Bookings->_new_from_dbic( $bookings_rs );
588
}
589
483
=head3 suggestions
590
=head3 suggestions
484
591
485
my $suggestions = $self->suggestions
592
my $suggestions = $self->suggestions
(-)a/Koha/Booking.pm (+220 lines)
Line 0 Link Here
1
package Koha::Booking;
2
3
# Copyright PTFS Europe 2021
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use Koha::Exceptions::Booking;
23
use Koha::DateUtils qw( dt_from_string );
24
25
use base qw(Koha::Object);
26
27
=head1 NAME
28
29
Koha::Booking - Koha Booking object class
30
31
=head1 API
32
33
=head2 Class methods
34
35
=head3 biblio
36
37
Returns the related Koha::Biblio object for this booking
38
39
=cut
40
41
sub biblio {
42
    my ($self) = @_;
43
44
    $self->{_biblio} ||= Koha::Biblios->find( $self->biblionumber() );
45
46
    return $self->{_biblio};
47
}
48
49
=head3 patron
50
51
Returns the related Koha::Patron object for this booking
52
53
=cut
54
55
sub patron {
56
    my ($self) = @_;
57
58
    my $patron_rs = $self->_result->patron;
59
    return Koha::Patron->_new_from_dbic($patron_rs);
60
}
61
62
=head3 item
63
64
Returns the related Koha::Item object for this Booking
65
66
=cut
67
68
sub item {
69
    my ($self) = @_;
70
71
    $self->{_item} ||= Koha::Items->find( $self->itemnumber() );
72
73
    return $self->{_item};
74
}
75
76
=head3 store
77
78
Booking specific store method to catch booking clashes
79
80
=cut
81
82
sub store {
83
    my ($self) = @_;
84
85
    $self->_result->result_source->schema->txn_do(
86
        sub {
87
            if ( $self->itemnumber ) {
88
                Koha::Exceptions::Object::FKConstraint->throw(
89
                    broken_fk => 'itemnumber',
90
                    value     => $self->itemnumber,
91
                ) unless ( $self->item );
92
93
                $self->biblionumber( $self->item->biblionumber )
94
                  unless $self->biblionumber;
95
96
                Koha::Exceptions::Object::FKConstraint->throw()
97
                  unless ( $self->biblionumber == $self->item->biblionumber );
98
            }
99
100
            Koha::Exceptions::Object::FKConstraint->throw(
101
                broken_fk => 'biblionumber',
102
                value     => $self->biblionumber,
103
            ) unless ( $self->biblio );
104
105
            # Throw exception for item level booking clash
106
            Koha::Exceptions::Booking::Clash->throw()
107
              if $self->itemnumber && !$self->item->can_be_booked(
108
                {
109
                    start_date => $self->start_date,
110
                    end_date   => $self->end_date,
111
                    booking_id => $self->in_storage ? $self->booking_id : undef
112
                }
113
              );
114
115
            # Throw exception for biblio level booking clash
116
            Koha::Exceptions::Booking::Clash->throw()
117
              if !$self->biblio->can_be_booked(
118
                {
119
                    start_date => $self->start_date,
120
                    end_date   => $self->end_date,
121
                    booking_id => $self->in_storage ? $self->booking_id : undef
122
                }
123
              );
124
125
            $self = $self->SUPER::store;
126
        }
127
    );
128
129
    return $self;
130
}
131
132
=head3 intersects
133
134
  my $intersects = $booking1->intersects($booking2);
135
136
Returns a boolean denoting whether booking1 interfers/overlaps/clashes with booking2.
137
138
=cut
139
140
sub intersects {
141
    my ( $self, $comp ) = @_;
142
143
    # Start date of comparison booking is after end date of this booking.
144
    return 0
145
      if (
146
        DateTime->compare(
147
            dt_from_string( $comp->start_date ),
148
            dt_from_string( $self->end_date )
149
        ) >= 0
150
      );
151
152
    # End date of comparison booking is before start date of this booking.
153
    return 0
154
      if (
155
        DateTime->compare(
156
            dt_from_string( $comp->end_date ),
157
            dt_from_string( $self->start_date )
158
        ) <= 0
159
      );
160
161
    # Bookings must overlap
162
    return 1;
163
}
164
165
=head3 get_items_that_can_fill
166
167
    my $items = $bookings->get_items_that_can_fill();
168
169
Return the list of items that can fulfill this booking.
170
171
Items that are not:
172
173
  in transit
174
  lost
175
  withdrawn
176
  not for loan
177
  not already booked
178
179
=cut
180
181
sub get_items_that_can_fill {
182
    my ($self) = @_;
183
    return;
184
}
185
186
=head3 to_api_mapping
187
188
This method returns the mapping for representing a Koha::Booking object
189
on the API.
190
191
=cut
192
193
sub to_api_mapping {
194
    return {
195
        booking_id     => 'booking_id',
196
        borrowernumber => 'patron_id',
197
        biblionumber   => 'biblio_id',
198
        itemnumber     => 'item_id',
199
        start_date     => 'start_date',
200
        end_date       => 'end_date'
201
    };
202
}
203
204
=head2 Internal methods
205
206
=head3 _type
207
208
=cut
209
210
sub _type {
211
    return 'Booking';
212
}
213
214
=head1 AUTHORS
215
216
Martin Renvoize <martin.renvoize@ptfs-europe.com>
217
218
=cut
219
220
1;
(-)a/Koha/Bookings.pm (+59 lines)
Line 0 Link Here
1
package Koha::Bookings;
2
3
# Copyright PTFS Europe 2021
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use Koha::Database;
23
use Koha::Booking;
24
25
use base qw(Koha::Objects);
26
27
=head1 NAME
28
29
Koha::Bookings - Koha Booking object set class
30
31
=head1 API
32
33
=head2 Class Methods
34
35
=cut
36
37
=head3 type
38
39
=cut
40
41
sub _type {
42
    return 'Booking';
43
}
44
45
=head3 object_class
46
47
=cut
48
49
sub object_class {
50
    return 'Koha::Booking';
51
}
52
53
=head1 AUTHOR
54
55
Martin Renvoize <martin.renvoize@ptfs-europe.com>
56
57
=cut
58
59
1;
(-)a/Koha/Exceptions/Booking.pm (+15 lines)
Line 0 Link Here
1
package Koha::Exceptions::Booking;
2
3
use Modern::Perl;
4
5
use Exception::Class (
6
    'Koha::Exceptions::Booking' => {
7
        description => "Something went wrong!"
8
    },
9
    'Koha::Exceptions::Booking::Clash' => {
10
        isa         => 'Koha::Exceptions::Booking',
11
        description => "Adding or updateing the booking would result in a clash"
12
    },
13
);
14
15
1;
(-)a/Koha/Item.pm (+105 lines)
Lines 410-415 sub holds { Link Here
410
    return Koha::Holds->_new_from_dbic( $holds_rs );
410
    return Koha::Holds->_new_from_dbic( $holds_rs );
411
}
411
}
412
412
413
=head3 bookings
414
415
  my $bookings = $item->bookings();
416
417
Returns the bookings attached to this item.
418
419
=cut
420
421
sub bookings {
422
    my ( $self, $params ) = @_;
423
    my $bookings_rs = $self->_result->bookings->search($params);
424
    return Koha::Bookings->_new_from_dbic( $bookings_rs );
425
}
426
427
=head3 can_be_booked
428
429
  my $bookable =
430
    $item->can_be_booked( { start_date => $datetime, end_date => $datetime, [ booking_id => $booking_id ] } );
431
432
Returns a boolean denoting whether the passed booking can be made without clashing.
433
434
Optionally, you may pass a booking id to exclude from the checks; This is helpful when you are updating an existing booking.
435
436
=cut
437
438
sub can_be_booked {
439
    my ($self, $params) = @_;
440
441
    my $start_date = dt_from_string( $params->{start_date} );
442
    my $end_date   = dt_from_string( $params->{end_date} );
443
    my $booking_id = $params->{booking_id};
444
445
    my $dtf = Koha::Database->new->schema->storage->datetime_parser;
446
    my $existing_bookings = $self->bookings(
447
        [
448
            start_date => {
449
                '-between' => [
450
                    $dtf->format_datetime($start_date),
451
                    $dtf->format_datetime($end_date)
452
                ]
453
            },
454
            end_date => {
455
                '-between' => [
456
                    $dtf->format_datetime($start_date),
457
                    $dtf->format_datetime($end_date)
458
                ]
459
            },
460
            {
461
                start_date => { '<' => $dtf->format_datetime($start_date) },
462
                end_date   => { '>' => $dtf->format_datetime($end_date) }
463
            }
464
        ]
465
    );
466
467
    my $bookings_count =
468
      defined($booking_id)
469
      ? $existing_bookings->search( { booking_id => { '!=' => $booking_id } } )
470
      ->count
471
      : $existing_bookings->count;
472
473
    return $bookings_count ? 0 : 1;
474
}
475
476
=head3 place_booking
477
478
  my $booking = $item->place_booking(
479
    {
480
        patron     => $patron,
481
        start_date => $datetime,
482
        end_date   => $datetime
483
    }
484
  );
485
486
Add a booking for this item for the dates passed.
487
488
Returns the Koha::Booking object or throws an exception if the item cannot be booked for the given dates.
489
490
=cut
491
492
sub place_booking {
493
    my ( $self, $params ) = @_;
494
495
    # check for mandatory params
496
    my @mandatory = ( 'start_date', 'end_date', 'patron' );
497
    for my $param (@mandatory) {
498
        unless ( defined( $params->{$param} ) ) {
499
            Koha::Exceptions::MissingParameter->throw(
500
                error => "The $param parameter is mandatory" );
501
        }
502
    }
503
    my $patron = $params->{patron};
504
505
    # New booking object
506
    my $booking = Koha::Booking->new(
507
        {
508
            start_date     => $params->{start_date},
509
            end_date       => $params->{end_date},
510
            borrowernumber => $patron->borrowernumber,
511
            biblionumber   => $self->biblionumber,
512
            itemnumber     => $self->itemnumber,
513
        }
514
    )->store();
515
    return $booking;
516
}
517
413
=head3 request_transfer
518
=head3 request_transfer
414
519
415
  my $transfer = $item->request_transfer(
520
  my $transfer = $item->request_transfer(
(-)a/Koha/REST/V1/Biblios.pm (+34 lines)
Lines 235-240 sub get_public { Link Here
235
    };
235
    };
236
}
236
}
237
237
238
=head3 get_bookings
239
240
Controller function that handles retrieving biblio's bookings
241
242
=cut
243
244
sub get_bookings {
245
    my $c = shift->openapi->valid_input or return;
246
247
    my $biblio = Koha::Biblios->find( { biblionumber => $c->validation->param('biblio_id') }, { prefetch => ['bookings'] } );
248
249
    unless ( $biblio ) {
250
        return $c->render(
251
            status  => 404,
252
            openapi => {
253
                error => "Object not found."
254
            }
255
        );
256
    }
257
258
    return try {
259
260
        my $bookings_rs = $biblio->bookings;
261
        my $bookings    = $c->objects->search( $bookings_rs );
262
        return $c->render(
263
            status  => 200,
264
            openapi => $bookings
265
        );
266
    }
267
    catch {
268
        $c->unhandled_exception($_);
269
    };
270
}
271
238
=head3 get_items
272
=head3 get_items
239
273
240
Controller function that handles retrieving biblio's items
274
Controller function that handles retrieving biblio's items
(-)a/Koha/REST/V1/Bookings.pm (+165 lines)
Line 0 Link Here
1
package Koha::REST::V1::Bookings;
2
3
# This file is part of Koha.
4
#
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.
9
#
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.
14
#
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>.
17
18
use Modern::Perl;
19
20
use Mojo::Base 'Mojolicious::Controller';
21
22
use Koha::Bookings;
23
24
use Try::Tiny qw( catch try );
25
26
=head1 API
27
28
=head2 Methods
29
30
=head3 list
31
32
Controller function that handles retrieving a list of bookings
33
34
=cut
35
36
sub list {
37
    my $c = shift->openapi->valid_input or return;
38
39
    return try {
40
        my $bookings_set = Koha::Bookings->new;
41
        my $bookings     = $c->objects->search($bookings_set);
42
        return $c->render( status => 200, openapi => $bookings );
43
    }
44
    catch {
45
        $c->unhandled_exception($_);
46
    };
47
48
}
49
50
=head3 get
51
52
Controller function that handles retrieving a single booking
53
54
=cut
55
56
sub get {
57
    my $c = shift->openapi->valid_input or return;
58
59
    return try {
60
        my $booking =
61
          Koha::Bookings->find( $c->validation->param('booking_id') );
62
        unless ($booking) {
63
            return $c->render(
64
                status  => 404,
65
                openapi => { error => "Booking not found" }
66
            );
67
        }
68
69
        return $c->render( status => 200, openapi => $booking->to_api );
70
    }
71
    catch {
72
        $c->unhandled_exception($_);
73
    }
74
}
75
76
=head3 add
77
78
Controller function that handles adding a new booking
79
80
=cut
81
82
sub add {
83
    my $c = shift->openapi->valid_input or return;
84
85
    return try {
86
        my $booking =
87
          Koha::Booking->new_from_api( $c->validation->param('body') );
88
        $booking->store;
89
        $c->res->headers->location(
90
            $c->req->url->to_string . '/' . $booking->booking_id );
91
        return $c->render(
92
            status  => 201,
93
            openapi => $booking->to_api
94
        );
95
    }
96
    catch {
97
        if ( blessed $_ and $_->isa('Koha::Exceptions::Booking::Clash') ) {
98
            return $c->render(
99
                status  => 400,
100
                openapi => { error => "Booking would conflict" }
101
            );
102
        }
103
104
        return $c->unhandled_exception($_);
105
    };
106
}
107
108
=head3 update
109
110
Controller function that handles updating an existing booking
111
112
=cut
113
114
sub update {
115
    my $c = shift->openapi->valid_input or return;
116
117
    my $booking = Koha::Bookings->find( $c->validation->param('booking_id') );
118
119
    if ( not defined $booking ) {
120
        return $c->render(
121
            status  => 404,
122
            openapi => { error => "Object not found" }
123
        );
124
    }
125
126
    return try {
127
        $booking->set_from_api( $c->validation->param('body') );
128
        $booking->store();
129
        return $c->render( status => 200, openapi => $booking->to_api );
130
    }
131
    catch {
132
        $c->unhandled_exception($_);
133
    };
134
}
135
136
=head3 delete
137
138
Controller function that handles removing an existing booking
139
140
=cut
141
142
sub delete {
143
    my $c = shift->openapi->valid_input or return;
144
145
    my $booking = Koha::Bookings->find( $c->validation->param('booking_id') );
146
    if ( not defined $booking ) {
147
        return $c->render(
148
            status  => 404,
149
            openapi => { error => "Object not found" }
150
        );
151
    }
152
153
    return try {
154
        $booking->delete;
155
        return $c->render(
156
            status  => 204,
157
            openapi => q{}
158
        );
159
    }
160
    catch {
161
        $c->unhandled_exception($_);
162
    };
163
}
164
165
1;
(-)a/Koha/REST/V1/Items.pm (+34 lines)
Lines 81-86 sub get { Link Here
81
    };
81
    };
82
}
82
}
83
83
84
=head3 get_bookings
85
86
Controller function that handles retrieving item's bookings
87
88
=cut
89
90
sub get_bookings {
91
    my $c = shift->openapi->valid_input or return;
92
93
    my $item = Koha::Items->find( { itemnumber => $c->validation->param('item_id') }, { prefetch => ['bookings'] } );
94
95
    unless ( $item ) {
96
        return $c->render(
97
            status  => 404,
98
            openapi => {
99
                error => "Object not found."
100
            }
101
        );
102
    }
103
104
    return try {
105
106
        my $bookings_rs = $item->bookings;
107
        my $bookings    = $c->objects->search( $bookings_rs );
108
        return $c->render(
109
            status  => 200,
110
            openapi => $bookings
111
        );
112
    }
113
    catch {
114
        $c->unhandled_exception($_);
115
    };
116
}
117
84
=head3 pickup_locations
118
=head3 pickup_locations
85
119
86
Method that returns the possible pickup_locations for a given item
120
Method that returns the possible pickup_locations for a given item
(-)a/api/v1/swagger/definitions.json (+3 lines)
Lines 5-10 Link Here
5
  "basket": {
5
  "basket": {
6
    "$ref": "definitions/basket.json"
6
    "$ref": "definitions/basket.json"
7
  },
7
  },
8
  "booking": {
9
    "$ref": "definitions/booking.json"
10
  },
8
  "cashup": {
11
  "cashup": {
9
    "$ref": "definitions/cashup.json"
12
    "$ref": "definitions/cashup.json"
10
  },
13
  },
(-)a/api/v1/swagger/definitions/booking.json (+33 lines)
Line 0 Link Here
1
{
2
  "type": "object",
3
  "properties": {
4
    "booking_id": {
5
      "type": "integer",
6
      "description": "Internal booking identifier"
7
    },
8
    "biblio_id": {
9
      "type": "integer",
10
      "description": "Internal identifier for the parent bibliographic record"
11
    },
12
    "item_id": {
13
      "type": [ "integer", "null" ],
14
      "description": "Internal item identifier"
15
    },
16
    "patron_id": {
17
        "type": "integer",
18
        "description": "Internal patron identifier"
19
    },
20
    "start_date": {
21
      "type": "string",
22
      "format": "date-time",
23
      "description": "Start date and time of this booking"
24
    },
25
    "end_date": {
26
      "type": "string",
27
      "format": "date-time",
28
      "description": "Start date and time of this booking"
29
    }
30
  },
31
  "additionalProperties": false,
32
  "required": ["biblio_id", "item_id", "patron_id", "start_date", "end_date"]
33
}
(-)a/api/v1/swagger/parameters.json (+3 lines)
Lines 2-7 Link Here
2
  "biblio_id_pp": {
2
  "biblio_id_pp": {
3
    "$ref": "parameters/biblio.json#/biblio_id_pp"
3
    "$ref": "parameters/biblio.json#/biblio_id_pp"
4
  },
4
  },
5
  "booking_id_pp": {
6
    "$ref": "parameters/booking.json#/booking_id_pp"
7
  },
5
  "advancededitormacro_id_pp": {
8
  "advancededitormacro_id_pp": {
6
    "$ref": "parameters/advancededitormacro.json#/advancededitormacro_id_pp"
9
    "$ref": "parameters/advancededitormacro.json#/advancededitormacro_id_pp"
7
  },
10
  },
(-)a/api/v1/swagger/parameters/booking.json (+9 lines)
Line 0 Link Here
1
{
2
    "booking_id_pp": {
3
      "name": "booking_id",
4
      "in": "path",
5
      "description": "Booking internal identifier",
6
      "required": true,
7
      "type": "integer"
8
    }
9
}
(-)a/api/v1/swagger/paths.json (+12 lines)
Lines 20-31 Link Here
20
  "/biblios/{biblio_id}": {
20
  "/biblios/{biblio_id}": {
21
    "$ref": "paths/biblios.json#/~1biblios~1{biblio_id}"
21
    "$ref": "paths/biblios.json#/~1biblios~1{biblio_id}"
22
  },
22
  },
23
  "/biblios/{biblio_id}/bookings": {
24
    "$ref": "paths/biblios.json#/~1biblios~1{biblio_id}~1bookings"
25
  },
23
  "/biblios/{biblio_id}/items": {
26
  "/biblios/{biblio_id}/items": {
24
    "$ref": "paths/biblios.json#/~1biblios~1{biblio_id}~1items"
27
    "$ref": "paths/biblios.json#/~1biblios~1{biblio_id}~1items"
25
  },
28
  },
26
  "/biblios/{biblio_id}/pickup_locations": {
29
  "/biblios/{biblio_id}/pickup_locations": {
27
    "$ref": "paths/biblios.json#/~1biblios~1{biblio_id}~1pickup_locations"
30
    "$ref": "paths/biblios.json#/~1biblios~1{biblio_id}~1pickup_locations"
28
  },
31
  },
32
  "/bookings": {
33
    "$ref": "paths/bookings.json#/~1bookings"
34
  },
35
  "/bookings/{booking_id}": {
36
    "$ref": "paths/bookings.json#/~1bookings~1{booking_id}"
37
  },
29
  "/cash_registers/{cash_register_id}/cashups": {
38
  "/cash_registers/{cash_register_id}/cashups": {
30
    "$ref": "paths/cash_registers.json#/~1cash_registers~1{cash_register_id}~1cashups"
39
    "$ref": "paths/cash_registers.json#/~1cash_registers~1{cash_register_id}~1cashups"
31
  },
40
  },
Lines 83-88 Link Here
83
  "/items/{item_id}": {
92
  "/items/{item_id}": {
84
    "$ref": "paths/items.json#/~1items~1{item_id}"
93
    "$ref": "paths/items.json#/~1items~1{item_id}"
85
  },
94
  },
95
  "/items/{item_id}/bookings": {
96
    "$ref": "paths/items.json#/~1items~1{item_id}~1bookings"
97
  },
86
  "/items/{item_id}/pickup_locations": {
98
  "/items/{item_id}/pickup_locations": {
87
    "$ref": "paths/items.json#/~1items~1{item_id}~1pickup_locations"
99
    "$ref": "paths/items.json#/~1items~1{item_id}~1pickup_locations"
88
  },
100
  },
(-)a/api/v1/swagger/paths/biblios.json (+98 lines)
Lines 132-137 Link Here
132
      }
132
      }
133
    }
133
    }
134
  },
134
  },
135
  "/biblios/{biblio_id}/bookings": {
136
    "get": {
137
      "x-mojo-to": "Biblios#get_bookings",
138
      "operationId": "getBiblioBookings",
139
      "tags": [
140
        "bookings"
141
      ],
142
      "summary": "Get bookings for a biblio",
143
      "parameters": [
144
        {
145
          "$ref": "../parameters.json#/biblio_id_pp"
146
        },
147
        {
148
          "$ref": "../parameters.json#/match"
149
        },
150
        {
151
          "$ref": "../parameters.json#/order_by"
152
        },
153
        {
154
          "$ref": "../parameters.json#/page"
155
        },
156
        {
157
          "$ref": "../parameters.json#/per_page"
158
        },
159
        {
160
          "$ref": "../parameters.json#/q_param"
161
        },
162
        {
163
          "$ref": "../parameters.json#/q_body"
164
        },
165
        {
166
          "$ref": "../parameters.json#/q_header"
167
        }
168
      ],
169
      "consumes": [
170
        "application/json"
171
      ],
172
      "produces": [
173
        "application/json"
174
      ],
175
      "responses": {
176
        "200": {
177
          "description": "A list of the bookings attached to the record",
178
          "schema": {
179
            "type": "array",
180
            "items": {
181
              "$ref": "../definitions.json#/booking"
182
            }
183
          }
184
        },
185
        "401": {
186
          "description": "Authentication required",
187
          "schema": {
188
            "$ref": "../definitions.json#/error"
189
          }
190
        },
191
        "403": {
192
          "description": "Access forbidden",
193
          "schema": {
194
            "$ref": "../definitions.json#/error"
195
          }
196
        },
197
        "404": {
198
          "description": "Biblio not found",
199
          "schema": {
200
            "$ref": "../definitions.json#/error"
201
          }
202
        },
203
        "406": {
204
          "description": "Not acceptable",
205
          "schema": {
206
            "type": "array",
207
            "description": "Accepted content-types",
208
            "items": {
209
                "type": "string"
210
            }
211
          }
212
        },
213
        "500": {
214
          "description": "Internal server error",
215
          "schema": {
216
            "$ref": "../definitions.json#/error"
217
          }
218
        },
219
        "503": {
220
          "description": "Under maintenance",
221
          "schema": {
222
            "$ref": "../definitions.json#/error"
223
          }
224
        }
225
      },
226
      "x-koha-authorization": {
227
        "permissions": {
228
            "circulation": "1"
229
        }
230
      }
231
    }
232
  },
135
  "/biblios/{biblio_id}/items": {
233
  "/biblios/{biblio_id}/items": {
136
    "get": {
234
    "get": {
137
      "x-mojo-to": "Biblios#get_items",
235
      "x-mojo-to": "Biblios#get_items",
(-)a/api/v1/swagger/paths/bookings.json (+352 lines)
Line 0 Link Here
1
{
2
  "/bookings": {
3
    "get": {
4
      "x-mojo-to": "Bookings#list",
5
      "operationId": "listBookings",
6
      "tags": [
7
        "bookings"
8
      ],
9
      "summary": "List bookings",
10
      "produces": [
11
        "application/json"
12
      ],
13
      "parameters": [
14
        {
15
          "name": "biblio_id",
16
          "in": "query",
17
          "description": "Case insensative search on booking biblio_id",
18
          "required": false,
19
          "type": "string"
20
        },
21
        {
22
          "name": "item_id",
23
          "in": "query",
24
          "description": "Case insensative search on booking item_id",
25
          "required": false,
26
          "type": "string"
27
        },
28
        {
29
          "name": "patron_id",
30
          "in": "query",
31
          "description": "Case insensative search on booking patron_id",
32
          "required": false,
33
          "type": "string"
34
        },
35
        {
36
          "name": "start_date",
37
          "in": "query",
38
          "description": "Case Insensative search on booking start_date",
39
          "required": false,
40
          "type": "string"
41
        },
42
        {
43
          "name": "end_date",
44
          "in": "query",
45
          "description": "Case Insensative search on booking end_date",
46
          "required": false,
47
          "type": "string"
48
        },
49
50
        {
51
          "$ref": "../parameters.json#/match"
52
        },
53
        {
54
          "$ref": "../parameters.json#/order_by"
55
        },
56
        {
57
          "$ref": "../parameters.json#/page"
58
        },
59
        {
60
          "$ref": "../parameters.json#/per_page"
61
        },
62
        {
63
          "$ref": "../parameters.json#/q_param"
64
        },
65
        {
66
          "$ref": "../parameters.json#/q_body"
67
        },
68
        {
69
          "$ref": "../parameters.json#/q_header"
70
        }
71
      ],
72
      "responses": {
73
        "200": {
74
          "description": "A list of bookings",
75
          "schema": {
76
            "type": "array",
77
            "items": {
78
              "$ref": "../definitions.json#/booking"
79
            }
80
          }
81
        },
82
        "403": {
83
          "description": "Access forbidden",
84
          "schema": {
85
            "$ref": "../definitions.json#/error"
86
          }
87
        },
88
        "500": {
89
          "description": "Internal error",
90
          "schema": {
91
            "$ref": "../definitions.json#/error"
92
          }
93
        },
94
        "503": {
95
          "description": "Under maintenance",
96
          "schema": {
97
            "$ref": "../definitions.json#/error"
98
          }
99
        }
100
      },
101
      "x-koha-authorization": {
102
        "permissions": {
103
          "catalogue": "1"
104
        }
105
      }
106
    },
107
    "post": {
108
      "x-mojo-to": "Bookings#add",
109
      "operationId": "addBooking",
110
      "tags": [
111
        "bookings"
112
      ],
113
      "summary": "Add booking",
114
      "parameters": [
115
        {
116
          "name": "body",
117
          "in": "body",
118
          "description": "A JSON object containing informations about the new booking",
119
          "required": true,
120
          "schema": {
121
            "$ref": "../definitions.json#/booking"
122
          }
123
        }
124
      ],
125
      "produces": [
126
        "application/json"
127
      ],
128
      "responses": {
129
        "201": {
130
          "description": "Booking added",
131
          "schema": {
132
            "$ref": "../definitions.json#/booking"
133
          }
134
        },
135
        "400": {
136
          "description": "Client error",
137
          "schema": {
138
            "$ref": "../definitions.json#/error"
139
          }
140
        },
141
        "401": {
142
          "description": "Authentication required",
143
          "schema": {
144
            "$ref": "../definitions.json#/error"
145
          }
146
        },
147
        "403": {
148
          "description": "Access forbidden",
149
          "schema": {
150
            "$ref": "../definitions.json#/error"
151
          }
152
        },
153
        "500": {
154
          "description": "Internal error",
155
          "schema": {
156
            "$ref": "../definitions.json#/error"
157
          }
158
        },
159
        "503": {
160
          "description": "Under maintenance",
161
          "schema": {
162
            "$ref": "../definitions.json#/error"
163
          }
164
        }
165
      },
166
      "x-koha-authorization": {
167
        "permissions": {
168
          "parameters": "manage_bookings"
169
        }
170
      }
171
    }
172
  },
173
  "/bookings/{booking_id}": {
174
    "get": {
175
      "x-mojo-to": "Bookings#get",
176
      "operationId": "getBooking",
177
      "tags": [
178
        "bookings"
179
      ],
180
      "summary": "Get booking",
181
      "parameters": [
182
        {
183
          "$ref": "../parameters.json#/booking_id_pp"
184
        }
185
      ],
186
      "produces": [
187
        "application/json"
188
      ],
189
      "responses": {
190
        "200": {
191
          "description": "A booking",
192
          "schema": {
193
            "$ref": "../definitions.json#/booking"
194
          }
195
        },
196
        "404": {
197
          "description": "Booking not found",
198
          "schema": {
199
            "$ref": "../definitions.json#/error"
200
          }
201
        },
202
        "500": {
203
          "description": "Internal error",
204
          "schema": {
205
            "$ref": "../definitions.json#/error"
206
          }
207
        },
208
        "503": {
209
          "description": "Under maintenance",
210
          "schema": {
211
            "$ref": "../definitions.json#/error"
212
          }
213
        }
214
      },
215
      "x-koha-authorization": {
216
        "permissions": {
217
          "catalogue": "1"
218
        }
219
      }
220
    },
221
    "put": {
222
      "x-mojo-to": "Bookings#update",
223
      "operationId": "updateBooking",
224
      "tags": [
225
        "bookings"
226
      ],
227
      "summary": "Update booking",
228
      "parameters": [
229
        {
230
          "$ref": "../parameters.json#/booking_id_pp"
231
        },
232
        {
233
          "name": "body",
234
          "in": "body",
235
          "description": "A booking object",
236
          "required": true,
237
          "schema": {
238
            "$ref": "../definitions.json#/booking"
239
          }
240
        }
241
      ],
242
      "produces": [
243
        "application/json"
244
      ],
245
      "responses": {
246
        "200": {
247
          "description": "A booking",
248
          "schema": {
249
            "$ref": "../definitions.json#/booking"
250
          }
251
        },
252
        "400": {
253
          "description": "Client error",
254
          "schema": {
255
            "$ref": "../definitions.json#/error"
256
          }
257
        },
258
        "401": {
259
          "description": "Authentication required",
260
          "schema": {
261
            "$ref": "../definitions.json#/error"
262
          }
263
        },
264
        "403": {
265
          "description": "Access forbidden",
266
          "schema": {
267
            "$ref": "../definitions.json#/error"
268
          }
269
        },
270
        "404": {
271
          "description": "Booking not found",
272
          "schema": {
273
            "$ref": "../definitions.json#/error"
274
          }
275
        },
276
        "500": {
277
          "description": "Internal error",
278
          "schema": {
279
            "$ref": "../definitions.json#/error"
280
          }
281
        },
282
        "503": {
283
          "description": "Under maintenance",
284
          "schema": {
285
            "$ref": "../definitions.json#/error"
286
          }
287
        }
288
      },
289
      "x-koha-authorization": {
290
        "permissions": {
291
          "parameters": "manage_bookings"
292
        }
293
      }
294
    },
295
    "delete": {
296
      "x-mojo-to": "Bookings#delete",
297
      "operationId": "deleteBooking",
298
      "tags": [
299
        "bookings"
300
      ],
301
      "summary": "Delete booking",
302
      "parameters": [
303
        {
304
          "$ref": "../parameters.json#/booking_id_pp"
305
        }
306
      ],
307
      "produces": [
308
        "application/json"
309
      ],
310
      "responses": {
311
        "204": {
312
          "description": "Booking deleted"
313
        },
314
        "401": {
315
          "description": "Authentication required",
316
          "schema": {
317
            "$ref": "../definitions.json#/error"
318
          }
319
        },
320
        "403": {
321
          "description": "Access forbidden",
322
          "schema": {
323
            "$ref": "../definitions.json#/error"
324
          }
325
        },
326
        "404": {
327
          "description": "Booking not found",
328
          "schema": {
329
            "$ref": "../definitions.json#/error"
330
          }
331
        },
332
        "500": {
333
          "description": "Internal error",
334
          "schema": {
335
            "$ref": "../definitions.json#/error"
336
          }
337
        },
338
        "503": {
339
          "description": "Under maintenance",
340
          "schema": {
341
            "$ref": "../definitions.json#/error"
342
          }
343
        }
344
      },
345
      "x-koha-authorization": {
346
        "permissions": {
347
          "parameters": "manage_bookings"
348
        }
349
      }
350
    }
351
  }
352
}
(-)a/api/v1/swagger/paths/items.json (-1 / +92 lines)
Lines 127-132 Link Here
127
      }
127
      }
128
    }
128
    }
129
  },
129
  },
130
  "/items/{item_id}/bookings": {
131
    "get": {
132
      "x-mojo-to": "Items#bookings",
133
      "operationId": "getItemBookings",
134
      "summary": "Get existing bookings for an item",
135
      "tags": ["items"],
136
      "parameters": [
137
        {
138
          "$ref": "../parameters.json#/item_id_pp"
139
        },
140
        {
141
          "$ref": "../parameters.json#/match"
142
        },
143
        {
144
          "$ref": "../parameters.json#/order_by"
145
        },
146
        {
147
          "$ref": "../parameters.json#/page"
148
        },
149
        {
150
          "$ref": "../parameters.json#/per_page"
151
        },
152
        {
153
          "$ref": "../parameters.json#/q_param"
154
        },
155
        {
156
          "$ref": "../parameters.json#/q_body"
157
        },
158
        {
159
          "$ref": "../parameters.json#/q_header"
160
        }
161
      ],
162
      "consumes": [
163
        "application/json"
164
      ],
165
      "produces": [
166
        "application/json"
167
      ],
168
      "responses": {
169
        "200": {
170
          "description": "Item bookings",
171
          "schema": {
172
            "type": "array",
173
            "items": {
174
              "$ref": "../definitions.json#/booking"
175
            }
176
          }
177
        },
178
        "400": {
179
          "description": "Missing or wrong parameters",
180
          "schema": {
181
            "$ref": "../definitions.json#/error"
182
          }
183
        },
184
        "401": {
185
          "description": "Authentication required",
186
          "schema": {
187
            "$ref": "../definitions.json#/error"
188
          }
189
        },
190
        "403": {
191
          "description": "Access forbidden",
192
          "schema": {
193
            "$ref": "../definitions.json#/error"
194
          }
195
        },
196
        "404": {
197
          "description": "Item not found",
198
          "schema": {
199
            "$ref": "../definitions.json#/error"
200
          }
201
        },
202
        "500": {
203
          "description": "Internal server error",
204
          "schema": {
205
            "$ref": "../definitions.json#/error"
206
          }
207
        },
208
        "503": {
209
          "description": "Under maintenance",
210
          "schema": {
211
            "$ref": "../definitions.json#/error"
212
          }
213
        }
214
      },
215
      "x-koha-authorization": {
216
        "permissions": {
217
          "circulation": 1
218
        }
219
      }
220
    }
221
  },
130
  "/items/{item_id}/pickup_locations": {
222
  "/items/{item_id}/pickup_locations": {
131
    "get": {
223
    "get": {
132
      "x-mojo-to": "Items#pickup_locations",
224
      "x-mojo-to": "Items#pickup_locations",
133
- 

Return to bug 29002