3 # Copyright 2020 Aleisha Amohia <aleisha@catalyst.net.nz>
5 # This file is part of Koha.
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.
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.
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>.
24 use Koha::DateUtils qw( dt_from_string );
26 use C4::Stats qw( UpdateStats );
28 use base qw(Koha::Objects);
32 Koha::Recalls - Koha Recalls Object set class
38 =head3 filter_by_current
40 my $current_recalls = $recalls->filter_by_current;
42 Returns a new resultset, filtering out finished recalls.
46 sub filter_by_current {
61 =head3 filter_by_finished
63 my $finished_recalls = $recalls->filter_by_finished;
65 Returns a new resultset, filtering out current recalls.
69 sub filter_by_finished {
85 my ( $recall, $due_interval, $due_date ) = Koha::Recalls->add_recall({
86 patron => $patron_object,
87 biblio => $biblio_object,
88 branchcode => $branchcode,
90 expirationdate => $expirationdate,
94 Add a new requested recall. We assume at this point that a recall is allowed to be placed on this item or biblio. We are past the checks and are now doing the recall.
95 Interface param is either OPAC or INTRANET
96 Send a RETURN_RECALLED_ITEM notice.
97 Add statistics and logs.
98 #FIXME: Add recallnotes and priority when staff-side recalls is added
103 my ( $self, $params ) = @_;
105 my $patron = $params->{patron};
106 my $biblio = $params->{biblio};
107 return if ( !defined($patron) or !defined($biblio) );
108 my $branchcode = $params->{branchcode};
109 $branchcode ||= $patron->branchcode;
110 my $item = $params->{item};
111 my $itemnumber = $item ? $item->itemnumber : undef;
112 my $expirationdate = $params->{expirationdate};
113 my $interface = $params->{interface};
115 if ( $expirationdate ){
116 my $now = dt_from_string;
117 $expirationdate = dt_from_string($expirationdate)->set({ hour => $now->hour, minute => $now->minute, second => $now->second });
120 my $recall_request = Koha::Recall->new({
121 patron_id => $patron->borrowernumber,
122 created_date => dt_from_string(),
123 biblio_id => $biblio->biblionumber,
124 pickup_library_id => $branchcode,
125 status => 'requested',
126 item_id => defined $itemnumber ? $itemnumber : undef,
127 expiration_date => $expirationdate,
128 item_level => defined $itemnumber ? 1 : 0,
131 if (defined $recall_request->id){ # successful recall
132 my $recall = Koha::Recalls->find( $recall_request->id );
134 # get checkout and adjust due date based on circulation rules
135 my $checkout = $recall->checkout;
136 my $recall_due_date_interval = Koha::CirculationRules->get_effective_rule({
137 categorycode => $checkout->patron->categorycode,
138 itemtype => $checkout->item->effective_itemtype,
139 branchcode => $branchcode,
140 rule_name => 'recall_due_date_interval',
142 my $due_interval = defined $recall_due_date_interval ? $recall_due_date_interval->rule_value : 5;
143 my $timestamp = dt_from_string( $recall->timestamp );
144 my $due_date = $timestamp->add( days => $due_interval );
145 $checkout->update({ date_due => $due_date });
147 # get itemnumber of most relevant checkout if a biblio-level recall
148 unless ( $recall->item_level ) { $itemnumber = $checkout->itemnumber; }
150 # send notice to user with recalled item checked out
151 my $letter = C4::Letters::GetPreparedLetter (
152 module => 'circulation',
153 letter_code => 'RETURN_RECALLED_ITEM',
154 branchcode => $recall->pickup_library_id,
156 biblio => $biblio->biblionumber,
157 borrowers => $checkout->borrowernumber,
158 items => $itemnumber,
159 issues => $itemnumber,
163 C4::Message->enqueue( $letter, $checkout->patron->unblessed, 'email' );
165 $item = Koha::Items->find( $itemnumber );
166 # add to statistics table
167 C4::Stats::UpdateStats({
168 branch => C4::Context->userenv->{'branch'},
170 itemnumber => $itemnumber,
171 borrowernumber => $recall->patron_id,
172 itemtype => $item->effective_itemtype,
173 ccode => $item->ccode,
177 C4::Log::logaction( 'RECALLS', 'CREATE', $recall->id, "Recall requested by borrower #" . $recall->patron_id, $interface ) if ( C4::Context->preference('RecallsLog') );
179 return ( $recall, $due_interval, $due_date );
182 # unable to add recall
188 my $message = Koha::Recalls->move_recall({
189 recall_id = $recall_id,
191 item => $item_object,
192 borrowernumber => $borrowernumber,
195 A patron is attempting to check out an item that has been recalled by another patron.
196 If the recall is requested/overdue, they have the option of cancelling the recall.
197 If the recall is waiting, they also have the option of reverting the waiting status.
199 We can also fulfill the recall here if the recall is placed by this borrower.
201 recall_id = ID of the recall to perform the action on
202 action = either cancel or revert
203 item = item object that the patron is attempting to check out
204 borrowernumber = borrowernumber of the patron that is attemptig to check out
209 my ( $self, $params ) = @_;
211 my $recall_id = $params->{recall_id};
212 my $action = $params->{action};
213 return 'no recall_id provided' if ( !defined $recall_id );
214 my $item = $params->{item};
215 my $borrowernumber = $params->{borrowernumber};
217 my $message = 'no action provided';
219 if ( $action and $action eq 'cancel' ) {
220 my $recall = Koha::Recalls->find( $recall_id );
221 $recall->set_cancelled;
222 $message = 'cancelled';
223 } elsif ( $action and $action eq 'revert' ) {
224 my $recall = Koha::Recalls->find( $recall_id );
225 $recall->revert_waiting;
226 $message = 'reverted';
229 if ( $message eq 'no action provided' and $item and $item->biblionumber and $borrowernumber ) {
230 # move_recall was not called to revert or cancel, but was called to fulfill
231 my $recall = Koha::Recalls->search(
233 patron_id => $borrowernumber,
234 biblio_id => $item->biblionumber,
235 item_id => [ $item->itemnumber, undef ],
238 { order_by => { -asc => 'created_date' } }
241 $recall->set_fulfilled;
242 $message = 'fulfilled';
249 =head2 Internal methods
264 return 'Koha::Recall';