Bug 35961: Add missing includes
[koha.git] / Koha / Checkout.pm
1 package Koha::Checkout;
2
3 # Copyright ByWater Solutions 2015
4 # Copyright 2016 Koha Development Team
5 #
6 # This file is part of Koha.
7 #
8 # Koha is free software; you can redistribute it and/or modify it
9 # under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # Koha is distributed in the hope that it will be useful, but
14 # WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with Koha; if not, see <http://www.gnu.org/licenses>.
20
21 use Modern::Perl;
22
23 use DateTime;
24 use Try::Tiny qw( catch try );
25
26 use C4::Circulation qw( AddRenewal CanBookBeRenewed LostItem MarkIssueReturned );
27 use Koha::Checkouts::Renewals;
28 use Koha::Checkouts::ReturnClaims;
29 use Koha::Database;
30 use Koha::DateUtils qw( dt_from_string );
31 use Koha::Items;
32 use Koha::Libraries;
33
34 use base qw(Koha::Object);
35
36 =head1 NAME
37
38 Koha::Checkout - Koha Checkout object class
39
40 =head1 API
41
42 =head2 Class methods
43
44 =cut
45
46 =head3 is_overdue
47
48 my  $is_overdue = $checkout->is_overdue( [ $reference_dt ] );
49
50 Return 1 if the checkout is overdue.
51
52 A reference date can be passed, in this case it will be used, otherwise today
53 will be the reference date.
54
55 =cut
56
57 sub is_overdue {
58     my ( $self, $dt ) = @_;
59     $dt ||= dt_from_string();
60
61     my $is_overdue =
62       DateTime->compare( dt_from_string( $self->date_due, 'sql' ), $dt ) == -1
63       ? 1
64       : 0;
65     return $is_overdue;
66 }
67
68 =head3 item
69
70 my $item = $checkout->item;
71
72 Return the checked out item
73
74 =cut
75
76 sub item {
77     my ( $self ) = @_;
78     my $item_rs = $self->_result->item;
79     return Koha::Item->_new_from_dbic( $item_rs );
80 }
81
82 =head3 account_lines
83
84 my $account_lines = $checkout->account_lines;
85
86 Return the checked out account_lines
87
88 =cut
89
90 sub account_lines {
91     my ( $self ) = @_;
92     my $account_lines_rs = $self->_result->account_lines;
93     return Koha::Account::Lines->_new_from_dbic( $account_lines_rs );
94 }
95
96 =head3 library
97
98 my $library = $checkout->library;
99
100 Return the library in which the transaction took place
101
102 =cut
103
104 sub library {
105     my ( $self ) = @_;
106     my $library_rs = $self->_result->library;
107     return Koha::Library->_new_from_dbic( $library_rs );
108 }
109
110 =head3 patron
111
112 my $patron = $checkout->patron
113
114 Return the patron for who the checkout has been done
115
116 =cut
117
118 sub patron {
119     my ( $self ) = @_;
120     my $patron_rs = $self->_result->patron;
121     return Koha::Patron->_new_from_dbic( $patron_rs );
122 }
123
124 =head3 issuer
125
126 my $issuer = $checkout->issuer
127
128 Return the patron by whom the checkout was done
129
130 =cut
131
132 sub issuer {
133     my ( $self ) = @_;
134     my $issuer_rs = $self->_result->issuer;
135     return unless $issuer_rs;
136     return Koha::Patron->_new_from_dbic( $issuer_rs );
137 }
138
139 =head3 renewals
140
141   my $renewals = $checkout->renewals;
142
143 Return a Koha::Checkouts::Renewals set attached to this checkout
144
145 =cut
146
147 sub renewals {
148     my ( $self ) = @_;
149     my $renewals_rs = $self->_result->renewals;
150     return unless $renewals_rs;
151     return Koha::Checkouts::Renewals->_new_from_dbic( $renewals_rs );
152 }
153
154 =head3 attempt_auto_renew
155
156   my ($success, $error, $updated) = $checkout->auto_renew({ confirm => 1 });
157
158 Attempt to automatically renew a book. Return error reason if it cannot be renewed.
159 Also return whether a change has been made to avoid notifying on more than one attempt.
160
161 If not passed confirm, we will only report and no changes will be made.
162
163 =cut
164
165 sub attempt_auto_renew {
166     my ( $self, $params ) = @_;
167     my $confirm = $params->{confirm} // 0;
168
169     # CanBookBeRenewed returns 'auto_renew' when the renewal should be done by this script
170     my ( $ok, $error ) = C4::Circulation::CanBookBeRenewed( $self->patron, $self, undef, 1 );
171     my $store_error;
172     if ( $error eq 'auto_renew' || $error eq 'auto_renew_final' || $error eq 'auto_unseen_final' ) {
173         if ($confirm) {
174             my $date_due = C4::Circulation::AddRenewal(
175                 {
176                     borrowernumber => $self->borrowernumber,
177                     itemnumber     => $self->itemnumber,
178                     branch         => $self->branchcode,
179                     seen           => 0,
180                     automatic      => 1,
181                 }
182             );
183             $store_error = $error eq 'auto_renew' ? undef : $error;
184             $self->auto_renew_error($store_error)->store;
185         }
186         return ( 1, $store_error, 1 );
187     } else {
188         my $updated = 0;
189         if ( !$self->auto_renew_error || $error ne $self->auto_renew_error ) {
190             $updated = 1
191                 unless (
192                 $self->auto_renew_error
193                 && (   $self->auto_renew_error eq 'auto_renew_final' && $error eq 'too_many'
194                     || $self->auto_renew_error eq 'auto_unseen_final' && $error eq 'too_unseen' )
195                 );
196             $self->auto_renew_error($error)->store if $confirm;
197         }
198         return ( 0, $error, $updated );
199     }
200
201 }
202
203 =head3 to_api_mapping
204
205 This method returns the mapping for representing a Koha::Checkout object
206 on the API.
207
208 =cut
209
210 sub to_api_mapping {
211     return {
212         issue_id        => 'checkout_id',
213         borrowernumber  => 'patron_id',
214         itemnumber      => 'item_id',
215         date_due        => 'due_date',
216         branchcode      => 'library_id',
217         returndate      => 'checkin_date',
218         lastreneweddate => 'last_renewed_date',
219         issuedate       => 'checkout_date',
220         notedate        => 'note_date',
221         noteseen        => 'note_seen',
222     };
223 }
224
225 =head3 claim_returned
226
227   my $return_claim = $checkout->claim_returned();
228
229 This method sets the checkout as claimed return.  It will:
230
231 1.  Add a new row to the `return_claims` table
232 2.  Set the item as lost using the 'ClaimReturnedLostValue'
233 3.  Charge a fee depending on the value of ClaimReturnedChargeFee
234 3a. If set to charge, then accruing overdues will be halted
235 3b. If set to charge, then any existing transfers will be cancelled
236     and the holding branch will be set back to 'frombranch'.
237 4.  The issue will be marked as returned as per the 'MarkLostItemsAsReturned' preference
238
239 =cut
240
241 sub claim_returned {
242     my ( $self, $params ) = @_;
243
244     my $charge_lost_fee = $params->{charge_lost_fee};
245
246     try {
247         $self->_result->result_source->schema->txn_do(
248             sub {
249                 my $claim = Koha::Checkouts::ReturnClaim->new(
250                     {
251                         issue_id       => $self->id,
252                         itemnumber     => $self->itemnumber,
253                         borrowernumber => $self->borrowernumber,
254                         notes          => $params->{notes},
255                         created_by     => $params->{created_by},
256                         created_on     => dt_from_string,
257                     }
258                 )->store();
259
260                 my $ClaimReturnedLostValue = C4::Context->preference('ClaimReturnedLostValue');
261                 $self->item->itemlost($ClaimReturnedLostValue)->store;
262
263                 my $ClaimReturnedChargeFee = C4::Context->preference('ClaimReturnedChargeFee');
264                 $charge_lost_fee =
265                     $ClaimReturnedChargeFee eq 'charge'    ? 1
266                 : $ClaimReturnedChargeFee eq 'no_charge' ? 0
267                 :   $charge_lost_fee;    # $ClaimReturnedChargeFee eq 'ask'
268
269                 if ( $charge_lost_fee ) {
270                     C4::Circulation::LostItem( $self->itemnumber, 'claim_returned' );
271                 }
272                 elsif ( C4::Context->preference( 'MarkLostItemsAsReturned' ) =~ m/claim_returned/ ) {
273                     C4::Circulation::MarkIssueReturned( $self->borrowernumber, $self->itemnumber, undef, $self->patron->privacy );
274                 }
275
276                 return $claim;
277             }
278         );
279     }
280     catch {
281         if ( $_->isa('Koha::Exception') ) {
282             $_->rethrow();
283         }
284         else {
285             # ?
286             Koha::Exception->throw( "Unhandled exception" );
287         }
288     };
289 }
290
291 =head2 Internal methods
292
293 =head3 _type
294
295 =cut
296
297 sub _type {
298     return 'Issue';
299 }
300
301 =head1 AUTHOR
302
303 Kyle M Hall <kyle@bywatersolutions.com>
304
305 Jonathan Druart <jonathan.druart@bugs.koha-community.org>
306
307 =cut
308
309 1;