Bug 34587: DBIC schema
[koha.git] / Koha / Booking.pm
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     my $biblio_rs = $self->_result->biblio;
45     return Koha::Biblio->_new_from_dbic($biblio_rs);
46 }
47
48 =head3 patron
49
50 Returns the related Koha::Patron object for this booking
51
52 =cut
53
54 sub patron {
55     my ($self) = @_;
56
57     my $patron_rs = $self->_result->patron;
58     return Koha::Patron->_new_from_dbic($patron_rs);
59 }
60
61 =head3 item
62
63 Returns the related Koha::Item object for this Booking
64
65 =cut
66
67 sub item {
68     my ($self) = @_;
69
70     my $item_rs = $self->_result->item;
71     return unless $item_rs;
72     return Koha::Item->_new_from_dbic($item_rs);
73 }
74
75 =head3 store
76
77 Booking specific store method to catch booking clashes
78
79 =cut
80
81 sub store {
82     my ($self) = @_;
83
84     $self->_result->result_source->schema->txn_do(
85         sub {
86             if ( $self->item_id ) {
87                 Koha::Exceptions::Object::FKConstraint->throw(
88                     broken_fk => 'item_id',
89                     value     => $self->item_id,
90                 ) unless ( $self->item );
91
92                 $self->biblio_id( $self->item->biblionumber )
93                     unless $self->biblio_id;
94
95                 Koha::Exceptions::Object::FKConstraint->throw()
96                     unless ( $self->biblio_id == $self->item->biblionumber );
97             }
98
99             Koha::Exceptions::Object::FKConstraint->throw(
100                 broken_fk => 'biblio_id',
101                 value     => $self->biblio_id,
102             ) unless ( $self->biblio );
103
104             # Throw exception for item level booking clash
105             Koha::Exceptions::Booking::Clash->throw()
106                 if $self->item_id && !$self->item->check_booking(
107                 {
108                     start_date => $self->start_date,
109                     end_date   => $self->end_date,
110                     booking_id => $self->in_storage ? $self->booking_id : undef
111                 }
112                 );
113
114             # Throw exception for biblio level booking clash
115             Koha::Exceptions::Booking::Clash->throw()
116                 if !$self->biblio->check_booking(
117                 {
118                     start_date => $self->start_date,
119                     end_date   => $self->end_date,
120                     booking_id => $self->in_storage ? $self->booking_id : undef
121                 }
122                 );
123
124             # Assign item at booking time
125             if ( !$self->item_id ) {
126                 $self->item_id(
127                     $self->biblio->assign_item_for_booking(
128                         {
129                             start_date => $self->start_date,
130                             end_date   => $self->end_date
131                         }
132                     )
133                 );
134             }
135
136             # FIXME: We should be able to combine the above two functions into one
137
138             $self = $self->SUPER::store;
139         }
140     );
141
142     return $self;
143 }
144
145 =head3 intersects
146
147   my $intersects = $booking1->intersects($booking2);
148
149 Returns a boolean denoting whether booking1 interfers/overlaps/clashes with booking2.
150
151 =cut
152
153 sub intersects {
154     my ( $self, $comp ) = @_;
155
156     # Start date of comparison booking is after end date of this booking.
157     return 0
158         if (
159         DateTime->compare(
160             dt_from_string( $comp->start_date ),
161             dt_from_string( $self->end_date )
162         ) >= 0
163         );
164
165     # End date of comparison booking is before start date of this booking.
166     return 0
167         if (
168         DateTime->compare(
169             dt_from_string( $comp->end_date ),
170             dt_from_string( $self->start_date )
171         ) <= 0
172         );
173
174     # Bookings must overlap
175     return 1;
176 }
177
178 =head3 get_items_that_can_fill
179
180     my $items = $bookings->get_items_that_can_fill();
181
182 Return the list of items that can fulfill this booking.
183
184 Items that are not:
185
186   in transit
187   lost
188   withdrawn
189   not for loan
190   not already booked
191
192 =cut
193
194 sub get_items_that_can_fill {
195     my ($self) = @_;
196     return;
197 }
198
199 =head3 to_api_mapping
200
201 This method returns the mapping for representing a Koha::Booking object
202 on the API.
203
204 =cut
205
206 sub to_api_mapping {
207     return {};
208 }
209
210 =head2 Internal methods
211
212 =head3 _type
213
214 =cut
215
216 sub _type {
217     return 'Booking';
218 }
219
220 =head1 AUTHORS
221
222 Martin Renvoize <martin.renvoize@ptfs-europe.com>
223
224 =cut
225
226 1;