@@ -, +, @@
interface
---
C4/Reserves.pm | 34 +++
Koha/Biblio.pm | 4 +-
Koha/Item.pm | 6 +-
.../intranet-tmpl/prog/en/includes/holds_table.inc | 6 +
.../prog/en/modules/recalls/request.tt | 263 +++++++++++++++++++--
.../prog/en/modules/reserve/request.tt | 8 +
.../intranet-tmpl/prog/js/patron-autocomplete.js | 4 +-
recalls/request.pl | 98 +++++++-
reserve/modrequest.pl | 14 +-
reserve/request.pl | 5 +
t/db_dependent/Holds.t | 83 ++++++-
11 files changed, 497 insertions(+), 28 deletions(-)
--- a/C4/Reserves.pm
+++ a/C4/Reserves.pm
@@ -1115,6 +1115,40 @@ sub ModReserve {
if ( $rank eq "del" ) {
$hold->cancel({ cancellation_reason => $cancellation_reason });
}
+ elsif ( $rank eq "recall" ) {
+ if ( !$biblionumber ) {
+ $biblionumber = $hold->biblionumber;
+ }
+ my $biblio = Koha::Biblios->find( $biblionumber );
+ if ( !$borrowernumber ) {
+ $borrowernumber = $hold->borrowernumber;
+ }
+ my $patron = Koha::Patrons->find( $borrowernumber );
+ if ( $hold->item_level_hold ) {
+ if ( $hold->item->can_be_recalled({ patron => $patron, hold_convert => 1 }) ) {
+ my ( $recall, $due_interval, $due_date ) = Koha::Recalls->add_recall({
+ patron => $patron,
+ biblio => $biblio,
+ branchcode => $branchcode,
+ expirationdate => $date,
+ interface => 'intranet',
+ item => $hold->item,
+ });
+ $hold->cancel({ cancellation_reason => 'RECALLED' });
+ }
+ } else {
+ if ( $biblio->can_be_recalled({ patron => $patron, hold_convert => 1 }) ) {
+ my ( $recall, $due_interval, $due_date ) = Koha::Recalls->add_recall({
+ patron => $patron,
+ biblio => $biblio,
+ branchcode => $branchcode,
+ expirationdate => $date,
+ interface => 'intranet',
+ });
+ $hold->cancel({ cancellation_reason => 'RECALLED' });
+ }
+ }
+ }
elsif ($hold->found && $hold->priority eq '0' && $date) {
logaction( 'HOLDS', 'MODIFY', $hold->reserve_id, $hold )
if C4::Context->preference('HoldsLog');
--- a/Koha/Biblio.pm
+++ a/Koha/Biblio.pm
@@ -1283,6 +1283,8 @@ sub recalls {
Does biblio-level checks and returns the items attached to this biblio that are available for recall
+if hold_convert $param is included, this is to say that this a check to convert a hold to a recall, so we should not check for an existing hold.
+
=cut
sub can_be_recalled {
@@ -1308,7 +1310,7 @@ sub can_be_recalled {
my @all_itemnumbers;
foreach my $item ( @all_items ) {
push( @all_itemnumbers, $item->itemnumber );
- if ( $item->can_be_recalled({ patron => $patron }) ) {
+ if ( $item->can_be_recalled({ patron => $patron, hold_convert => $params->{hold_convert} }) ) {
push( @itemtypes, $item->effective_itemtype );
push( @itemnumbers, $item->itemnumber );
push( @items, $item );
--- a/Koha/Item.pm
+++ a/Koha/Item.pm
@@ -1745,6 +1745,8 @@ sub recall {
Does item-level checks and returns if items can be recalled by this borrower
+if hold_convert $param is included, this is to say that this a check to convert a hold to a recall, so we should not check for an existing hold.
+
=cut
sub can_be_recalled {
@@ -1796,7 +1798,9 @@ sub can_be_recalled {
return 0 if ( Koha::Checkouts->search({ itemnumber => $self->itemnumber, borrowernumber => $patron->borrowernumber })->count > 0 );
# check if this patron has already reserved this item
- return 0 if ( Koha::Holds->search({ itemnumber => $self->itemnumber, borrowernumber => $patron->borrowernumber })->count > 0 );
+ unless ( $params->{hold_convert} ) {
+ return 0 if ( Koha::Holds->search({ itemnumber => $self->itemnumber, borrowernumber => $patron->borrowernumber })->count > 0 );
+ }
}
# check item availability
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc
+++ a/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc
@@ -64,6 +64,9 @@
[% END %]
+ [% IF Koha.Preference('UseRecalls') AND Koha.Preference('RecallsInterface') != 'opac' %]
+
+ [% END %]
[% ELSE %]
@@ -79,6 +82,9 @@
[% ELSE %]
[% END %]
+ [% IF Koha.Preference('UseRecalls') AND Koha.Preference('RecallsInterface') != 'opac' %]
+
+ [% END %]
[% END %]
[% ELSE %]
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/request.tt
+++ a/koha-tmpl/intranet-tmpl/prog/en/modules/recalls/request.tt
@@ -2,8 +2,17 @@
[% USE Asset %]
[% USE Koha %]
[% USE KohaDates %]
+[% USE TablesSettings %]
+[% USE Branches %]
+[% USE Categories %]
+[% USE AuthorisedValues %]
+[% USE ItemTypes %]
[% SET footerjs = 1 %]
[% INCLUDE 'doc-head-open.inc' %]
+[% SET libraries = Branches.all %]
+[% SET categories = Categories.all.unblessed %]
+[% SET columns = ['name', 'cardnumber', 'dateofbirth', 'category', 'branch', 'address', 'phone'] %]
+[% PROCESS "patron-search.inc" %]
Confirm recalls › Recalls › Koha
[% INCLUDE 'doc-head-close.inc' %]
@@ -11,36 +20,217 @@
[% INCLUDE 'header.inc' %]
[% INCLUDE 'circ-search.inc' %]
-
+
- Existing recalls
+ Recalls
- [% IF Koha.Preference('UseRecalls') %]
- [% IF recalls.count %]
-
+ [% ELSE %]
+ No recalls have been made.
+ [% END %]
+ [% ELSE %]
+ Recalls have not been enabled. Enable the
UseRecalls system preference to use recalls.
+ [% END %]
+
[% END %]
@@ -59,6 +249,45 @@
[% Asset.js("js/recalls.js") | $raw %]
[% INCLUDE 'datatables.inc' %]
[% INCLUDE 'columns_settings.inc' %]
+ [% INCLUDE 'calendar.inc' %]
+ [% SET url_biblio_params = "biblionumber=" _ biblio.biblionumber %]
+ [% PROCESS patron_search_js table_id => 'table_borrowers', categories => categories, libraries => libraries, extended_attribute_types => attribute_type_codes, columns => columns, open_on_row_click => 1, on_click_url => '/cgi-bin/koha/recalls/request.pl?' _ url_biblio_params, redirect_if_one_result => 1, redirect_url => '/cgi-bin/koha/recalls/request.pl?' _ url_biblio_params, redirect_if_attribute_equal => 'cardnumber' %]
+
[% END %]
[% INCLUDE 'intranet-bottom.inc' %]
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt
+++ a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt
@@ -216,6 +216,14 @@
No club with this name, please, try another
[% END %]
+
+ [% IF ( recallerror ) %]
+
+ [% END %]
+