Bug 35174: Add misc/translator/po to .gitignore
[koha.git] / Koha / ArticleRequest.pm
1 package Koha::ArticleRequest;
2
3 # Copyright ByWater Solutions 2015
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::Account::Lines;
23 use Koha::Database;
24 use Koha::Patrons;
25 use Koha::Biblios;
26 use Koha::Items;
27 use Koha::Libraries;
28 use Koha::DateUtils qw( dt_from_string );
29 use Koha::ArticleRequest::Status;
30 use Koha::Exceptions::ArticleRequest;
31
32 use base qw(Koha::Object);
33
34 =head1 NAME
35
36 Koha::ArticleRequest - Koha Article Request Object class
37
38 =head1 API
39
40 =head2 Class methods
41
42 =cut
43
44 =head3 request
45
46     $article_request->request;
47
48 Marks the article as requested. Send a notification if appropriate.
49
50 =cut
51
52 sub request {
53     my ($self) = @_;
54
55     Koha::Exceptions::ArticleRequest::LimitReached->throw(
56         error => 'Patron cannot request more articles for today'
57     ) unless $self->borrower->can_request_article;
58
59     $self->status(Koha::ArticleRequest::Status::Requested);
60
61     # Handle possible fees
62     my $debit = $self->borrower->add_article_request_fee_if_needed({ item_id => $self->itemnumber });
63     $self->debit_id( $debit->id )
64         if $debit;
65
66     $self->store();
67     $self->notify();
68     return $self;
69 }
70
71 =head3 set_pending
72
73     $article_request->set_pending;
74
75 Marks the article as pending. Send a notification if appropriate.
76
77 =cut
78
79 sub set_pending {
80     my ($self) = @_;
81
82     $self->status(Koha::ArticleRequest::Status::Pending);
83     $self->store();
84     $self->notify();
85     return $self;
86 }
87
88 =head3 process
89
90     $article_request->process;
91
92 Marks the article as in process. Send a notification if appropriate.
93
94 =cut
95
96 sub process {
97     my ($self) = @_;
98
99     $self->status(Koha::ArticleRequest::Status::Processing);
100     $self->store();
101     $self->notify();
102     return $self;
103 }
104
105 =head3 complete
106
107     $article_request->complete;
108
109 Marks the article as completed. Send a notification if appropriate.
110
111 =cut
112
113 sub complete {
114     my ($self) = @_;
115
116     $self->status(Koha::ArticleRequest::Status::Completed);
117     $self->store();
118     $self->notify();
119     return $self;
120 }
121
122 =head3 cancel
123
124     $article_request->cancel;
125
126 Marks the article as cancelled. Send a notification if appropriate.
127
128 =cut
129
130 sub cancel {
131     my ( $self, $params ) = @_;
132
133     my $cancellation_reason = $params->{cancellation_reason};
134     my $notes = $params->{notes};
135
136     $self->status(Koha::ArticleRequest::Status::Canceled);
137     $self->cancellation_reason($cancellation_reason) if $cancellation_reason;
138     $self->notes($notes) if $notes;
139     $self->store();
140     $self->notify();
141
142     my $debit = $self->debit;
143
144     if ( $debit ) {
145         # fees found, refund
146         my $account = $self->borrower->account;
147
148         my $total_reversible = $debit->debit_offsets->filter_by_reversible->total;
149         if ( $total_reversible ) {
150
151             $account->add_credit(
152                 {
153                     amount       => abs $total_reversible,
154                     interface    => C4::Context->interface,
155                     type         => 'REFUND',
156                 }
157             );
158         }
159
160         if ( $debit->amountoutstanding ) {
161             $debit->reduce({
162                 reduction_type => 'REFUND',
163                 amount         => $debit->amountoutstanding,
164                 interface      => C4::Context->interface,
165             })->discard_changes;
166         }
167     }
168
169     return $self;
170 }
171
172 =head3 biblio
173
174 Returns the Koha::Biblio object for this article request
175
176 =cut
177
178 sub biblio {
179     my ($self) = @_;
180
181     my $rs = $self->_result->biblionumber;
182     return unless $rs;
183     return Koha::Biblio->_new_from_dbic($rs);
184 }
185
186 =head3 debit
187
188     my $debit = $article_request->debit;
189
190 Returns the related Koha::Account::Line object for this article request
191
192 =cut
193
194 sub debit {
195     my ($self) = @_;
196
197     my $debit_rs = $self->_result->debit;
198     return unless $debit_rs;
199
200     return Koha::Account::Line->_new_from_dbic( $debit_rs );
201 }
202
203 =head3 item
204
205 Returns the Koha::Item object for this article request
206
207 =cut
208
209 sub item {
210     my ($self) = @_;
211     my $rs = $self->_result->itemnumber;
212     return unless $rs;
213     return Koha::Item->_new_from_dbic($rs);
214 }
215
216 =head3 borrower
217
218 Returns the Koha::Patron object for this article request
219
220 =cut
221
222 sub borrower {
223     my ($self) = @_;
224     my $rs = $self->_result->borrowernumber;
225     return unless $rs;
226     return Koha::Patron->_new_from_dbic($rs);
227 }
228
229 =head3 branch
230
231 Returns the Koha::Library object for this article request
232
233 =cut
234
235 sub branch {
236     my ($self) = @_;
237     my $rs = $self->_result->branchcode;
238     return unless $rs;
239     return Koha::Library->_new_from_dbic($rs);
240 }
241
242 =head3 store
243
244 Override the default store behavior so that new opac requests
245 will have notifications sent.
246
247 =cut
248
249 sub store {
250     my ($self) = @_;
251
252     if ( !$self->in_storage ) {
253         $self->created_on( dt_from_string() );
254     }
255
256     return $self->SUPER::store;
257 }
258
259 =head2 Internal methods
260
261 =head3 notify
262
263     $self->notify();
264
265 internal method to be called when changing an article request status.
266 If a letter exists for the new status, it enqueues it.
267
268 =cut
269
270 sub notify {
271     my ($self) = @_;
272
273     my $status = $self->status;
274     my $reason = $self->notes;
275     if ( !defined $reason && $self->cancellation_reason ) {
276         my $av = Koha::AuthorisedValues->search(
277             {
278                 category            => 'AR_CANCELLATION',
279                 authorised_value    => $self->cancellation_reason
280             }
281         )->next;
282         $reason = $av->lib_opac ? $av->lib_opac : $av->lib if $av;
283     }
284
285     require C4::Letters;
286     if (
287         my $letter = C4::Letters::GetPreparedLetter(
288             module                 => 'circulation',
289             letter_code            => "AR_$status", # AR_REQUESTED, AR_PENDING, AR_PROCESSING, AR_COMPLETED, AR_CANCELED
290             message_transport_type => 'email',
291             lang                   => $self->borrower->lang,
292             tables                 => {
293                 article_requests => $self->id,
294                 borrowers        => $self->borrowernumber,
295                 biblio           => $self->biblionumber,
296                 biblioitems      => $self->biblionumber,
297                 items            => $self->itemnumber,
298                 branches         => $self->branchcode,
299             },
300             substitute => {
301                 reason => $reason,
302             },
303         )
304       )
305     {
306         C4::Letters::EnqueueLetter(
307             {
308                 letter                 => $letter,
309                 borrowernumber         => $self->borrowernumber,
310                 message_transport_type => 'email',
311             }
312         ) or warn "can't enqueue letter " . $letter->{code};
313     }
314 }
315
316 =head3 _type
317
318 =cut
319
320 sub _type {
321     return 'ArticleRequest';
322 }
323
324 =head1 AUTHOR
325
326 Kyle M Hall <kyle@bywatersolutions.com>
327
328 =cut
329
330 1;