From 8cbb3e0b15cd99baa4f71e69c5ec3e4a256b8505 Mon Sep 17 00:00:00 2001 From: Alex Buckley Date: Sun, 8 Jul 2018 00:00:17 +0000 Subject: [PATCH] Bug 19532: Fixes and enhancements to recalls This implements the following fixes and enhancements: * Stopping a waiting recall from being able to be checked out to patrons other than the patron who placed the recall * Make the Recall confirmation popup appear everytime a recalled item is put through returns until it is checked out to recall requester * Introduce a new notice RECALL_REQUESTER_DET which outlines borrower and item information so the item can be put aside * Stop recalled items from being renewed * Stop display of 'Available' for waiting recalls * Check if recalls exist on an item before checking for reserves * Added ability to set Recall due date interval, and Recall pickup period in hours * Fix the 'Template process error Koha::Item->avail_for_recall' thrown on course page where a course reserve is currently issued Test plan: 1. Repeat major test plan - verify all points 2. Place another recall and check it in 3. Try checking the recall out to a different patron and confirm you are not able to check out a waiting recall to a different patron 4. Check the same item in again and observe that the recall modal is displayed again and is displayed every time the item is checked in until the item is checked out to the patron who placed the recall 5. Check the item in again and select the 'Print slip and confirm' and confirm the RECALL_REQUESTER_DET notice can be printed 6. Place a recall on an item and try to renew the item and confirm you are unable to renew recalled items 7. Return the same item and confirm in the OPAC and staff client that the item is not shown as available 8. Place a recall to one borrower then reserve the same item to a different borrower. Check the item in and confirm the recall modal is displayed not the reserve modal as recalls take precedence 9. In circ and fine rules set a rules 'Fine charge interval period'=1 10. Set the 'Unit' of the circ rule to 'hours', 'Recall due date interval' = 1, 'Recall overdue fine amount'=1, 'Recall pickup period'=1 11. Check out an item to borrower A and recall it in the OPAC by borrower B 12. In the database manually change the issues.date_due to 1 hour before the current time 13. From the Koha shell run './misc/cronjobs/fines.pl' 14. Notice the fine of 1 has been applied to the borrower for being 1 hour late in returning the recall 15. Return the item and confirm the recall. Manually change the waiting date to more than 1 hour before the current time and run ./misc/cronjobs/overdue_notices.pl 16. Notice the recall is overdue now - Steps 9-16 test point #7 above 17. Enable 'UseCourseReserves' syspref 18. Check out a course reserve item to a borrower 19. In the OPAC navigate to the course page containing the issued course reserve and confirm the page loads successfully 20. Recall a course reserve and confirm recalls works for course reserves Sponsored-By: Toi Ohomai Institute of Technology, New Zealand --- C4/Circulation.pm | 115 +++++++++++------- C4/Letters.pm | 1 + C4/Overdues.pm | 11 +- C4/Search.pm | 12 +- C4/XSLT.pm | 5 +- catalogue/detail.pl | 7 +- circ/recall-pickup-slip.pl | 88 ++++++++++++++ circ/returns.pl | 22 +++- ...2_-_alter_recalls_table_date_datatypes.sql | 2 + ..._19532_recall_requester_details_notice.sql | 1 + .../prog/en/includes/recalls-reports.inc | 10 +- .../prog/en/modules/admin/smart-rules.tt | 5 +- .../prog/en/modules/circ/circulation-home.tt | 8 ++ .../prog/en/modules/circ/circulation.tt | 8 ++ .../en/modules/circ/recall-pickup-slip.tt | 26 ++++ .../prog/en/modules/circ/recalls_overdue.tt | 3 +- .../prog/en/modules/circ/recalls_queue.tt | 3 +- .../prog/en/modules/circ/recalls_waiting.tt | 3 +- .../prog/en/modules/circ/renew.tt | 2 + .../prog/en/modules/circ/returns.tt | 11 +- .../prog/en/modules/members/moremember.tt | 4 +- .../prog/en/modules/members/recallshistory.tt | 3 +- .../en/modules/opac-course-details.tt | 4 +- opac/opac-course-details.pl | 8 ++ opac/opac-detail.pl | 3 +- opac/opac-recall.pl | 11 +- t/db_dependent/Koha/Recalls.t | 3 +- 27 files changed, 308 insertions(+), 71 deletions(-) create mode 100755 circ/recall-pickup-slip.pl create mode 100644 installer/data/mysql/atomicupdate/bug_19532_-_alter_recalls_table_date_datatypes.sql create mode 100644 installer/data/mysql/atomicupdate/bug_19532_recall_requester_details_notice.sql create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/circ/recall-pickup-slip.tt diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 078211880b..c544cbd491 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -353,16 +353,17 @@ sub transferbook { $dotransfer = 0; $messages->{'RecallPlacedAtHoldingBranch'} = 1; } else { - $dotransfer = 1; + $dotransfer = 0; } } else { #recalls take priority over holds, only check holds if no recalls # find reserves..... - my ( $resfound, $resrec, undef ) = CheckReserves( $itemnumber ); - if ( $resfound and not $ignoreRs ) { - $resrec->{'ResFound'} = $resfound; - # $messages->{'ResFound'} = $resrec; - $dotransfer = 1; - } +# my ( $resfound, $resrec, undef ) = +# CheckReserves( $itemnumber ); +# if ( $resfound and not $ignoreRs ) { +# $resrec->{'ResFound'} = $resfound; +# $messages->{'ResFound'} = $resrec; +# $dotransfer = 1; +# } } #actually do the transfer.... @@ -665,6 +666,10 @@ sticky due date is invalid or due date in the past if the borrower borrows to much things +=head3 WAITING_RECALL_FOR_A_DIFFERENT_PATRON + +if the item has been recalled by a different patron and the recall status is waiting 'W' + =cut sub CanBookBeIssued { @@ -989,36 +994,48 @@ sub CanBookBeIssued { } } - unless ( $ignore_reserves ) { - # See if the item is on reserve. - my ( $restype, $res ) = C4::Reserves::CheckReserves( $item->{'itemnumber'} ); - if ($restype) { - my $resbor = $res->{'borrowernumber'}; - if ( $resbor ne $patron->borrowernumber ) { - my $patron = Koha::Patrons->find( $resbor ); - if ( $restype eq "Waiting" ) - { - # The item is on reserve and waiting, but has been - # reserved by some other patron. - $needsconfirmation{RESERVE_WAITING} = 1; - $needsconfirmation{'resfirstname'} = $patron->firstname; - $needsconfirmation{'ressurname'} = $patron->surname; - $needsconfirmation{'rescardnumber'} = $patron->cardnumber; - $needsconfirmation{'resborrowernumber'} = $patron->borrowernumber; - $needsconfirmation{'resbranchcode'} = $res->{branchcode}; - $needsconfirmation{'reswaitingdate'} = $res->{'waitingdate'}; - } - elsif ( $restype eq "Reserved" ) { - # The item is on reserve for someone else. - $needsconfirmation{RESERVED} = 1; - $needsconfirmation{'resfirstname'} = $patron->firstname; - $needsconfirmation{'ressurname'} = $patron->surname; - $needsconfirmation{'rescardnumber'} = $patron->cardnumber; - $needsconfirmation{'resborrowernumber'} = $patron->borrowernumber; - $needsconfirmation{'resbranchcode'} = $patron->branchcode; - $needsconfirmation{'resreservedate'} = $res->{reservedate}; - } - } + my $recall; + #CHECK IF ITEM HAS WAITING RECALL FOR ANOTHER PATRON + if ( C4::Context->preference('UseRecalls') ) { + $recall = Koha::Recalls->find({ itemnumber => $item->{'itemnumber'}, status => 'W' }); + if ((defined $recall) && ($recall->patron->borrowernumber != $patron->borrowernumber) && $recall->status eq 'W') { + #Item has been recalled by a different patron and is waiting for them + $issuingimpossible{WAITING_RECALL_FOR_A_DIFFERENT_PATRON} = 1; + } + } + + if (!((defined $recall) && $recall->patron->borrowernumber == $patron->borrowernumber && $recall->status eq 'W')) { + unless ( $ignore_reserves ) { + # See if the item is on reserve. + my ( $restype, $res ) = C4::Reserves::CheckReserves( $item->{'itemnumber'} ); + if ($restype) { + my $resbor = $res->{'borrowernumber'}; + if ( $resbor ne $patron->borrowernumber ) { + my $patron = Koha::Patrons->find( $resbor ); + if ( $restype eq "Waiting" ) + { + # The item is on reserve and waiting, but has been + # reserved by some other patron. + $needsconfirmation{RESERVE_WAITING} = 1; + $needsconfirmation{'resfirstname'} = $patron->firstname; + $needsconfirmation{'ressurname'} = $patron->surname; + $needsconfirmation{'rescardnumber'} = $patron->cardnumber; + $needsconfirmation{'resborrowernumber'} = $patron->borrowernumber; + $needsconfirmation{'resbranchcode'} = $res->{branchcode}; + $needsconfirmation{'reswaitingdate'} = $res->{'waitingdate'}; + } + elsif ( $restype eq "Reserved" ) { + # The item is on reserve for someone else. + $needsconfirmation{RESERVED} = 1; + $needsconfirmation{'resfirstname'} = $patron->firstname; + $needsconfirmation{'ressurname'} = $patron->surname; + $needsconfirmation{'rescardnumber'} = $patron->cardnumber; + $needsconfirmation{'resborrowernumber'} = $patron->borrowernumber; + $needsconfirmation{'resbranchcode'} = $patron->branchcode; + $needsconfirmation{'resreservedate'} = $res->{reservedate}; + } + } + } } } @@ -1377,10 +1394,10 @@ sub AddIssue { # Check if a recall if ( C4::Context->preference('UseRecalls') ) { - my $recall = Koha::Recalls->find({ itemnumber => $item->{'itemnumber'}, borrowernumber => $borrower->{'borrowernumber'}, old => undef }); - if (defined $recall) { - $recall->update({ status => "F", old => 1 }); - } + my $recall = Koha::Recalls->find({ itemnumber => $item->{'itemnumber'}, borrowernumber => $borrower->{'borrowernumber'}, status => 'W' }); + if (defined $recall) { + $recall->update({ status => 'F', old => 1 }); + } } if ( C4::Context->preference('ReturnToShelvingCart') ) { @@ -2034,15 +2051,21 @@ sub AddReturn { my ($resfound, $resrec); # find recalls..... - my $recall = Koha::Recalls->find({ itemnumber => $item->{'itemnumber'}, old => undef }); + my $recall = Koha::Recalls->find({ itemnumber => $item->{'itemnumber'}, status => 'R' }); + my $waiting_recall = Koha::Recalls->find({ itemnumber => $item->{'itemnumber'}, status => 'W' }); if (defined $recall){ $messages->{'RecallFound'} = 1; $messages->{'Recall'} = $recall; + } elsif (defined $waiting_recall){ + $messages->{'RecallFound'} = 1; + $messages->{'Recall'} = $waiting_recall; } else { # find reserves..... # if we don't have a reserve with the status W, we launch the Checkreserves routine my $lookahead= C4::Context->preference('ConfirmFutureHolds'); #number of days to look for future holds ($resfound, $resrec, undef) = C4::Reserves::CheckReserves( $item->{'itemnumber'}, undef, $lookahead ) unless ( $item->{'withdrawn'} ); + warn $issue; + warn $resrec; if ($resfound) { $resrec->{'ResFound'} = $resfound; $messages->{'ResFound'} = $resrec; @@ -2692,6 +2715,14 @@ sub CanBookBeRenewed { } return ( 0, "on_reserve" ) if $resfound; # '' when no hold was found + # check if item has been recalled. do a transfer if the recall branch is different to the item holding branch, otherwise don't do a transfer + my $recall = Koha::Recalls->find({ itemnumber => $itemnumber, status => 'R' }); + my $recallfound; + if (defined $recall){ + $recallfound = 1; + } + return ( 0, "recalled" ) if $recallfound; + return ( 1, undef ) if $override_limit; my $branchcode = _GetCircControlBranch( $item, $patron->unblessed ); diff --git a/C4/Letters.pm b/C4/Letters.pm index f12a0141c1..65915af95b 100644 --- a/C4/Letters.pm +++ b/C4/Letters.pm @@ -40,6 +40,7 @@ use Koha::Notice::Messages; use Koha::DateUtils qw( format_sqldatetime dt_from_string ); use Koha::Patrons; use Koha::Subscriptions; +use Data::Dumper; use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); diff --git a/C4/Overdues.pm b/C4/Overdues.pm index 1e67b7f437..973a280a72 100644 --- a/C4/Overdues.pm +++ b/C4/Overdues.pm @@ -38,6 +38,7 @@ use Koha::Account::Lines; use Koha::Account::Offsets; use Koha::IssuingRules; use Koha::Libraries; +use Koha::Recalls; use vars qw(@ISA @EXPORT); @@ -255,7 +256,15 @@ sub CalcFine { # If chargeperiod_charge_at = 1, we charge a fine at the start of each charge period # if chargeperiod_charge_at = 0, we charge at the end of each charge period $charge_periods = $issuing_rule->chargeperiod_charge_at == 1 ? ceil($charge_periods) : floor($charge_periods); - $amount = $charge_periods * $issuing_rule->fine; + + # check if item has been recalled. + my $currentrecall = Koha::Recalls->find({ itemnumber => $item->{itemnumber}, status => 'R' }); + if (defined $currentrecall) { + $amount = $charge_periods * $issuing_rule->recall_overdue_fine; + } else { + $amount = $charge_periods * $issuing_rule->fine; + } + } # else { # a zero (or null) chargeperiod or negative units_minus_grace value means no charge. } $amount = $issuing_rule->overduefinescap if $issuing_rule->overduefinescap && $amount > $issuing_rule->overduefinescap; diff --git a/C4/Search.pm b/C4/Search.pm index 46fafcda9d..c8e9baa15b 100644 --- a/C4/Search.pm +++ b/C4/Search.pm @@ -2146,6 +2146,9 @@ sub searchResults { # is item on the reserve shelf? my $reservestatus = ''; + # is item a waiting recall? + my $recallstatus = ''; + unless ($item->{withdrawn} || $item->{itemlost} || $item->{damaged} @@ -2167,6 +2170,7 @@ sub searchResults { # ($transfertwhen, $transfertfrom, $transfertto) = C4::Circulation::GetTransfers($item->{itemnumber}); $reservestatus = C4::Reserves::GetReserveStatus( $item->{itemnumber} ); + $recallstatus = Koha::Recalls->find({ itemnumber => $item->{itemnumber}, status => 'W' }); } # item is withdrawn, lost, damaged, not for loan, reserved or in transit @@ -2175,13 +2179,14 @@ sub searchResults { || $item->{damaged} || $item->{notforloan} || $reservestatus eq 'Waiting' + || (defined $recallstatus) || ($transfertwhen ne '')) { $withdrawn_count++ if $item->{withdrawn}; $itemlost_count++ if $item->{itemlost}; $itemdamaged_count++ if $item->{damaged}; $item_in_transit_count++ if $transfertwhen ne ''; - $item_onhold_count++ if $reservestatus eq 'Waiting'; + $item_onhold_count++ if (($reservestatus eq 'Waiting') || (defined $recallstatus)); $item->{status} = $item->{withdrawn} . "-" . $item->{itemlost} . "-" . $item->{damaged} . "-" . $item->{notforloan}; # can place a hold on a item if @@ -2204,6 +2209,11 @@ sub searchResults { } $other_items->{$key}->{intransit} = ( $transfertwhen ne '' ) ? 1 : 0; $other_items->{$key}->{onhold} = ($reservestatus) ? 1 : 0; + if (defined $recallstatus) { + $recallstatus = 'W'; + } + $other_items->{$key}->{onhold} = ($recallstatus) ? 1 : 0; + $other_items->{$key}->{notforloan} = GetAuthorisedValueDesc('','',$item->{notforloan},'','',$notforloan_authorised_value) if $notforloan_authorised_value and $item->{notforloan}; $other_items->{$key}->{count}++ if $item->{$hbranch}; $other_items->{$key}->{location} = $shelflocations->{ $item->{location} }; diff --git a/C4/XSLT.pm b/C4/XSLT.pm index bf2647ab74..d040c5c034 100644 --- a/C4/XSLT.pm +++ b/C4/XSLT.pm @@ -291,9 +291,10 @@ sub buildKohaItemsNamespace { my ( $transfertwhen, $transfertfrom, $transfertto ) = C4::Circulation::GetTransfers($item->{itemnumber}); my $reservestatus = C4::Reserves::GetReserveStatus( $item->{itemnumber} ); + my $recallstatus = Koha::Recalls->find({ itemnumber => $item->{itemnumber}, status => 'W'}); if ( ( $item->{itype} && $itemtypes->{ $item->{itype} }->{notforloan} ) || $item->{notforloan} || $item->{onloan} || $item->{withdrawn} || $item->{itemlost} || $item->{damaged} || - (defined $transfertwhen && $transfertwhen ne '') || $item->{itemnotforloan} || (defined $reservestatus && $reservestatus eq "Waiting") ){ + (defined $transfertwhen && $transfertwhen ne '') || $item->{itemnotforloan} || (defined $reservestatus && $reservestatus eq "Waiting") || (defined $recallstatus)){ if ( $item->{notforloan} < 0) { $status = "On order"; } @@ -315,7 +316,7 @@ sub buildKohaItemsNamespace { if (defined $transfertwhen && $transfertwhen ne '') { $status = 'In transit'; } - if (defined $reservestatus && $reservestatus eq "Waiting") { + if ((defined $reservestatus && $reservestatus eq "Waiting") || (defined $recallstatus)) { $status = 'Waiting'; } } else { diff --git a/catalogue/detail.pl b/catalogue/detail.pl index deae6b47a4..4c47005b2a 100755 --- a/catalogue/detail.pl +++ b/catalogue/detail.pl @@ -46,6 +46,7 @@ use Koha::ItemTypes; use Koha::Patrons; use Koha::Virtualshelves; use Koha::Recalls; +use Data::Dumper; my $query = CGI->new(); @@ -334,10 +335,14 @@ foreach my $item (@items) { } } - my $recall = Koha::Recalls->find({ itemnumber => $item->{itemnumber}, old => undef }); + my $recall = Koha::Recalls->find({ itemnumber => $item->{itemnumber}, status => 'R' }); + my $waiting_recall = Koha::Recalls->find({ itemnumber => $item->{'itemnumber'}, status => 'W' }); if (defined $recall){ $item->{recalled} = 1; $item->{recall} = $recall; + } elsif (defined $waiting_recall) { + $item->{recalled} = 1; + $item->{recall} = $waiting_recall; } if ($currentbranch and $currentbranch ne "NO_LIBRARY_SET" diff --git a/circ/recall-pickup-slip.pl b/circ/recall-pickup-slip.pl new file mode 100755 index 0000000000..daf6c88112 --- /dev/null +++ b/circ/recall-pickup-slip.pl @@ -0,0 +1,88 @@ +#!/usr/bin/perl + + +# Copyright 2018 Catalyst IT +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; +use C4::Context; +use C4::Output; +use CGI qw ( -utf8 ); +use C4::Auth qw/:DEFAULT get_session/; +use Koha::Recall; +use Koha::Recalls; +use C4::Letters; +use C4::Message; +use Data::Dumper; +use Koha::Patrons; +use Koha::Items; +use Koha::Biblios; +use Koha::Libraries; +use vars qw($debug); + +BEGIN { + $debug = $ENV{DEBUG} || 0; +} + +my $input = new CGI; +my $sessionID = $input->cookie("CGISESSID"); +my $session = get_session($sessionID); + +my $borrowernumber = $input->param('borrowernumber'); +my $biblionumber = $input->param('biblionumber'); +my $itemnumber = $input->param('itemnumber'); +my $recallid = $input->param('recall_id'); +my ( $template, $loggedinuser, $cookie ) = get_template_and_user( + { + template_name => "circ/recall-pickup-slip.tt", + query => $input, + type => "intranet", + authnotrequired => 0, + flagsrequired => { circulate => "circulate_remaining_permissions" }, + debug => $debug, + } +); + +my $recall = Koha::Recalls->find($recallid); +my $patron = Koha::Patrons->find($borrowernumber); +my $item = Koha::Items->find($recall->itemnumber); +my $biblio = Koha::Biblios->find($item->biblionumber); +my $library = Koha::Libraries->find($recall->branchcode); + +#Print slip to inform library staff of details of recall requester, so the item can be put aside for requester +my ($slip, $is_html); +my $letter = C4::Letters::GetPreparedLetter ( + module => 'circulation', + letter_code => 'RECALL_REQUESTER_DET', + tables => { + 'branches' => $library->branchcode, + 'borrowers' => $patron->borrowernumber, + 'biblio' => $biblio->biblionumber, + 'items' => $item->itemnumber, + 'recalls' => $recall->recall_id + } +); + +if ($letter) { + $slip = $letter->{content}; + $is_html = $letter->{is_html}; +} + +$template->param( slip => $slip ) if ($slip); +$template->param( plain => !$is_html ); + +output_html_with_http_headers $input, $cookie, $template->output; diff --git a/circ/returns.pl b/circ/returns.pl index 11894f9d1b..cc13b9a575 100755 --- a/circ/returns.pl +++ b/circ/returns.pl @@ -89,6 +89,16 @@ if ( $query->param('print_slip') ) { ); } +if ( $query->param('print_recall_slip') ) { + $template->param( + print_recall_slip => 1, + borrowernumber => scalar $query->param('borrowernumber'), + biblionumber => scalar $query->param('biblionumber'), + itemnumber => scalar $query->param('itemnumber'), + recall_id => scalar $query->param('recall_id') + ); +} + ##################### #Global vars my $printers = GetPrinters(); @@ -513,14 +523,22 @@ if ( $messages->{'ResFound'}) { if ( $messages->{'RecallFound'} ){ my $recall = $messages->{'Recall'}; + warn $userenv_branch; + warn $recall->branchcode; + my $transfer_recall; + if ($userenv_branch eq $recall->branchcode) { + $transfer_recall = 0; + } else { + $transfer_recall = 1; + } my $patron = Koha::Patrons->find( $recall->borrowernumber ); $template->param( patron => $patron, found => 1, recalled => 1, recall => $recall, - transfer_recall => ($userenv_branch eq $recall->branchcode ? 1 : 0 ) -# address => $patron->address, + transfer_recall => $transfer_recall, + address => $patron->address, # address2 => $patron->address2, # streetnumber => $patron->streetnumber, # city => $patron->city, diff --git a/installer/data/mysql/atomicupdate/bug_19532_-_alter_recalls_table_date_datatypes.sql b/installer/data/mysql/atomicupdate/bug_19532_-_alter_recalls_table_date_datatypes.sql new file mode 100644 index 0000000000..486a077d3c --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_19532_-_alter_recalls_table_date_datatypes.sql @@ -0,0 +1,2 @@ +ALTER TABLE recalls MODIFY column waitingdate datetime; +ALTER TABLE recalls MODIFY column expirationdate datetime; diff --git a/installer/data/mysql/atomicupdate/bug_19532_recall_requester_details_notice.sql b/installer/data/mysql/atomicupdate/bug_19532_recall_requester_details_notice.sql new file mode 100644 index 0000000000..8c841d5aab --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_19532_recall_requester_details_notice.sql @@ -0,0 +1 @@ +insert into letter (module, code, name, is_html, title, content, message_transport_type, lang) values ('circulation', 'RECALL_REQUESTER_DET', 'Details of patron who recalled item', 0, 'Details of patorn who recalled item', '
Date: <>

Recall for pickup at <>

<>, <>


ITEM RECALLED

<>

<>

Notes:

<>

', 'email', default); diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/recalls-reports.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/recalls-reports.inc index fd683d042d..7ba692dd51 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/recalls-reports.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/recalls-reports.inc @@ -58,18 +58,18 @@ - [% IF recall.waitingdate %][% recall.waitingdate | $KohaDates %][% ELSE %]Not waiting[% END %] + [% IF recall.waitingdate %][% recall.waitingdate %][% ELSE %]Not waiting[% END %] [% IF ( recall.is_waiting ) %] [% IF ( recall.expirationdate ) %] - [% recall.expirationdate | $KohaDates %] + [% recall.expirationdate %] [% ELSE %] Never expires [% END %] [% ELSIF ( recall.has_expired && recall.expirationdate ) %] - [% recall.expirationdate | $KohaDates %] + [% recall.expirationdate %] [% ELSE %] - [% END %] @@ -97,9 +97,9 @@ [% IF ( recall.is_requested ) %] - Due to be returned by [% recall.checkout.date_due | $KohaDates %] + Due to be returned by [% recall.checkout.date_due %] [% ELSIF ( recall.is_waiting && recall.expirationdate ) %] - Pick up by [% recall.expirationdate | $KohaDates %] + Pick up by [% recall.expirationdate %] [% ELSE %] - [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt index 1426474f1d..04343dc255 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt @@ -95,9 +95,9 @@ Holds per record (count) On shelf holds allowed Item level holds - Recall due date interval (days) + Recall due date interval Recall overdue fine amount - Recall pickup period (days) + Recall pickup period Article requests Rental discount (%) Actions @@ -214,7 +214,6 @@ Don't allow [% END %] - [% IF rule.opacitemholds == 'F'%]Force[% ELSIF rule.opacitemholds == 'Y'%]Allow[% ELSE %]Don't allow[% END %] [% rule.recall_due_date_interval %] [% rule.recall_overdue_fine FILTER format("%.2f") %] [% rule.recall_shelf_time %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt index f59fcaa6fa..ef3bc02d3e 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt @@ -70,6 +70,14 @@ Hold ratios + [% IF Koha.Preference('UseRecalls') %] +

Recalls

+ + [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt index 7ef3ab5d7d..96af5172e5 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt @@ -79,6 +79,7 @@
Staff members are not allowed to discharge borrowers, nor borrowers to request a discharge.
[% END %] + [% IF ( NEEDSCONFIRMATION ) %]
@@ -313,6 +314,13 @@ [% IF ( INVALID_DATE ) %]
  • The due date "[% INVALID_DATE | html %]" is invalid
  • [% END %] + [% IF ( WAITING_RECALL_FOR_A_DIFFERENT_PATRON ) %] +
  • This item is awaiting pickup by another patron who recalled it.
  • + [% END %] + + [% IF ( WAITING_RECALL_FOR_A_DIFFERENT_PATRON ) %] +
  • This item is awaiting pickup by another patron who recalled it.
  • + [% END %] [% IF ( UNKNOWN_BARCODE ) %]
  • The barcode was not found: [% barcode | html %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/recall-pickup-slip.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/recall-pickup-slip.tt new file mode 100644 index 0000000000..a2ba1e7e53 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/recall-pickup-slip.tt @@ -0,0 +1,26 @@ +[% USE Asset %] +[% USE Koha %] +[% INCLUDE 'doc-head-open.inc' %] +Koha › Circulation › Recall print receipt +[% INCLUDE 'doc-head-close.inc' %] + + +[% Asset.css("css/print.css") %] +[% IF ( Koha.Preference('SlipCSS') ) %] + +[% END %] + +[% INCLUDE 'slip-print.inc' #printThenClose %] + + +
    + +[% IF plain %] +
    +[% IF ( slip ) %][% slip %][% ELSE %]No slip template found[% END %]
    +
    +[% ELSE %] +[% IF ( slip ) %][% slip %][% ELSE %]No slip template found[% END %] +[% END %] + +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/recalls_overdue.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/recalls_overdue.tt index 4137632a45..787018a07c 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/recalls_overdue.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/recalls_overdue.tt @@ -1,3 +1,4 @@ +[% USE Asset %] [% USE Koha %] [% USE KohaDates %] [% INCLUDE 'doc-head-open.inc' %] @@ -5,7 +6,7 @@ [% INCLUDE 'doc-head-close.inc' %] - +[% Asset.js("js/recalls.js") %] [% INCLUDE 'datatables.inc' %] [% INCLUDE 'columns_settings.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/recalls_queue.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/recalls_queue.tt index c3d6b377cd..3efe280aa2 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/recalls_queue.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/recalls_queue.tt @@ -1,3 +1,4 @@ +[% USE Asset %] [% USE Koha %] [% USE KohaDates %] [% SET footerjs = 1 %] @@ -58,7 +59,7 @@ [% MACRO jsinclude BLOCK %] [% INCLUDE 'datatables.inc' %] [% INCLUDE 'columns_settings.inc' %] - + [% Asset.js("js/recalls.js") %] +[% Asset.js("js/recalls.js") %] [% INCLUDE 'datatables.inc' %] +[% Asset.js("js/recalls.js") %] [% INCLUDE 'header.inc' %] diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-course-details.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-course-details.tt index e2d8a8703e..25a6e3b30e 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-course-details.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-course-details.tt @@ -75,10 +75,10 @@ [% AuthorisedValues.GetByCode( 'CCODE', cr.item.ccode ) | html %] [% cr.item.itemcallnumber | html %] [% cr.item.copynumber | html %] - [% INCLUDE 'item-status.inc' item=cr.item issue=cr.issue %] + [% INCLUDE 'item-status.inc' item=cr.course_item issue=cr.issue %] [% cr.issue.date_due | $KohaDates as_due_date => 1 | html %] [% IF ( cr.public_note ) %] - [% cr.public_note | html %] + [% cr.public_note | html %] [% ELSIF ( cr.item.itemnotes ) %] [% cr.item.itemnotes | html %] [% END %] diff --git a/opac/opac-course-details.pl b/opac/opac-course-details.pl index 3afa8a921a..57d15a114e 100755 --- a/opac/opac-course-details.pl +++ b/opac/opac-course-details.pl @@ -46,6 +46,14 @@ die("No course_id given") unless ($course_id); my $course = GetCourse($course_id); my $course_reserves = GetCourseReserves( course_id => $course_id, include_items => 1, include_count => 1 ); +foreach my $cr (@$course_reserves) { + if ($cr->{'issue'}->{date_due} && $cr->{'issue'}->{borrowernumber} && $borrowernumber != $cr->{'issue'}->{borrowernumber} && C4::Context->preference('UseRecalls')) { + $cr->{'course_item'}->{avail_for_recall} = 1; + } else { + $cr->{'course_item'}->{avail_for_recall} = 0; + } +} + $template->param( course => $course, course_reserves => $course_reserves, diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl index 3d300b4898..082f5d4cfb 100755 --- a/opac/opac-detail.pl +++ b/opac/opac-detail.pl @@ -694,7 +694,8 @@ if ( not $viewallitems and @items > $max_items_to_display ) { } my $reserve_status = C4::Reserves::GetReserveStatus($itm->{itemnumber}); - if( $reserve_status eq "Waiting"){ $itm->{'waiting'} = 1; } + my $waiting_recall_status = Koha::Recalls->find({ itemnumber => $itm->{itemnumber}, status => 'W' }); + if( $reserve_status eq "Waiting" || defined($waiting_recall_status) ){ $itm->{'waiting'} = 1; } if( $reserve_status eq "Reserved"){ $itm->{'onhold'} = 1; } my ( $transfertwhen, $transfertfrom, $transfertto ) = GetTransfers($itm->{itemnumber}); diff --git a/opac/opac-recall.pl b/opac/opac-recall.pl index 0f8e39e34a..e5c1016e66 100755 --- a/opac/opac-recall.pl +++ b/opac/opac-recall.pl @@ -87,9 +87,14 @@ if ($op eq 'request'){ my $recall = Koha::Recalls->find($recall_request->recall_id); # updating due date on checkout my $timestamp = dt_from_string($recall->timestamp); - my $due_date = $timestamp->add( $issuing_rule->lengthunit => $issuing_rule->recall_due_date_interval ); - $checkout->update({ date_due => $due_date }); - my $checkout_borrower = $checkout->patron; + my $due_date; + if ( $issuing_rule->recall_due_date_interval eq '' ) { + $due_date = $timestamp->add( $issuing_rule->lengthunit => 0 ); + } else { + $due_date = $timestamp->add( $issuing_rule->lengthunit => $issuing_rule->recall_due_date_interval ); + } + my $checkout = Koha::Checkouts->find({ itemnumber => $itemnumber })->update({ date_due => $due_date }); + my $checkout_borrower = Koha::Patrons->find($checkout->borrowernumber->borrowernumber); # send notice to user with recalled item checked out my $letter = C4::Letters::GetPreparedLetter ( diff --git a/t/db_dependent/Koha/Recalls.t b/t/db_dependent/Koha/Recalls.t index 1b421ff50b..375371db83 100644 --- a/t/db_dependent/Koha/Recalls.t +++ b/t/db_dependent/Koha/Recalls.t @@ -38,6 +38,7 @@ my $biblio = $builder->build( { source => 'Biblio' } ); my $itemtype = $builder->build( { source => 'Itemtype' } ); my $item = $builder->build( { source => 'Item', value => { biblionumber => $biblio->{biblionumber}, itype => $itemtype->{itemtype}, holdingbranch => $library->{branchcode} } } ); my $checkout = $builder->build( { source => 'Issue', value => { borrowernumber => 5, itemnumber => $item->{itemnumber} } } ); +my $nb_of_recalls = Koha::Recalls->search->count; # recall requested by second patron my $recall = Koha::Recall->new({ @@ -50,7 +51,7 @@ my $recall = Koha::Recall->new({ itemtype => $item->{itype}, })->store; -is( Koha::Recalls->search->count, 1, 'The one recall should be added' ); +is( Koha::Recalls->search->count, $nb_of_recalls + 1, 'The one recall should have be added' ); is( $recall->is_requested, 1, 'Recall status is set to R, requested' ); $recall->update({ status => 'O' }); -- 2.19.1