From 65b44bbd0918f2ba02dfadf50e38d8a7b10006f7 Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Mon, 8 Jun 2015 08:14:20 -0400 Subject: [PATCH] Bug 14364 - Allow automatically canceled expired waiting holds to fill the next hold Right now, if a library automatically cancels expired waiting holds, a librarian must still re-checkin an item to trap the next available hold for that item. It would be better if the next hold was automatically trapped and the librarians receive an email notification so they can make any changes to the item if need be ( hold area, hold slip in item, etc ). Test Plan: 1) Apply this patch 2) Run updatedatabase.pl 3) Create a record with one item 4) Place two holds on that record 5) Check in the item and set it to waiting for the first patron 6) Set ReservesMaxPickUpDelay to 1 7) Enable ExpireReservesMaxPickUpDelay 8) Enable ExpireReservesAutoFill 9) Set an email address in ExpireReservesAutoFillEmail 10) Modify the holds waitingdate to be in the past 11) Run misc/cronjobs/holds/cancel_expired_holds.pl 12) Note the hold is now waiting for the next patron 12) Note a waiting hold notification email was sent to that patron 13) Note a hold changed notification email was sent to the library --- C4/Reserves.pm | 143 ++++++++++++++++---- C4/SIP/ILS/Transaction/Checkin.pm | 18 ++- circ/branchtransfers.pl | 2 +- circ/returns.pl | 2 +- installer/data/mysql/atomicupdate/bug_14364.sql | 13 ++ .../data/mysql/de-DE/mandatory/sample_notices.sql | 10 ++ .../data/mysql/en/mandatory/sample_notices.sql | 10 ++ .../data/mysql/es-ES/mandatory/sample_notices.sql | 10 ++ .../mysql/fr-FR/1-Obligatoire/sample_notices.sql | 10 ++ .../mysql/nb-NO/1-Obligatorisk/sample_notices.sql | 10 ++ .../data/mysql/pl-PL/mandatory/sample_notices.sql | 10 ++ .../data/mysql/ru-RU/mandatory/sample_notices.sql | 10 ++ installer/data/mysql/sysprefs.sql | 2 + .../data/mysql/uk-UA/mandatory/sample_notices.sql | 10 ++ .../en/modules/admin/preferences/circulation.pref | 10 ++ t/db_dependent/Holds/RevertWaitingStatus.t | 2 +- t/db_dependent/Reserves.t | 14 +- 17 files changed, 244 insertions(+), 42 deletions(-) create mode 100644 installer/data/mysql/atomicupdate/bug_14364.sql diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 9c760b6..c6739e3 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -252,7 +252,7 @@ sub AddReserve { foreach (@$bibitems) { $sth->execute($borrowernumber, $biblionumber, $resdate, $_); } - + return $reserve_id; } @@ -498,7 +498,7 @@ sub CanItemBeReserved{ my $dbh = C4::Context->dbh; my $ruleitemtype; # itemtype of the matching issuing rule my $allowedreserves = 0; - + # we retrieve borrowers and items informations # # item->{itype} will come for biblioitems if necessery my $item = GetItem($itemnumber); @@ -535,8 +535,8 @@ sub CanItemBeReserved{ LEFT JOIN borrowers USING (borrowernumber) WHERE borrowernumber = ? "; - - + + my $branchcode = ""; my $branchfield = "reserves.branchcode"; @@ -547,12 +547,12 @@ sub CanItemBeReserved{ $branchfield = "borrowers.branchcode"; $branchcode = $borrower->{branchcode}; } - - # we retrieve rights + + # we retrieve rights $sth->execute($borrower->{'categorycode'}, $item->{'itype'}, $branchcode); if(my $rights = $sth->fetchrow_hashref()){ $ruleitemtype = $rights->{itemtype}; - $allowedreserves = $rights->{reservesallowed}; + $allowedreserves = $rights->{reservesallowed}; }else{ $ruleitemtype = '*'; } @@ -560,10 +560,10 @@ sub CanItemBeReserved{ # we retrieve count $querycount .= "AND $branchfield = ?"; - + $querycount .= " AND $itemtypefield = ?" if ($ruleitemtype ne "*"); my $sthcount = $dbh->prepare($querycount); - + if($ruleitemtype eq "*"){ $sthcount->execute($borrowernumber, $branchcode); }else{ @@ -818,8 +818,8 @@ sub GetReservesToBranch { my $dbh = C4::Context->dbh; my $sth = $dbh->prepare( "SELECT reserve_id,borrowernumber,reservedate,itemnumber,timestamp - FROM reserves - WHERE priority='0' + FROM reserves + WHERE priority='0' AND branchcode=?" ); $sth->execute( $frombranch ); @@ -844,7 +844,7 @@ sub GetReservesForBranch { my $query = " SELECT reserve_id,borrowernumber,reservedate,itemnumber,waitingdate - FROM reserves + FROM reserves WHERE priority='0' AND found='W' "; @@ -1102,7 +1102,12 @@ sub CancelExpiredReserves { manualinvoice($res->{'borrowernumber'}, $res->{'itemnumber'}, 'Hold waiting too long', 'F', $charge); } - CancelReserve({ reserve_id => $res->{'reserve_id'} }); + CancelReserve( + { + reserve_id => $res->{'reserve_id'}, + autofill => C4::Context->preference('ExpireReservesAutoFill'), + } + ); } } } @@ -1129,7 +1134,7 @@ sub AutoUnsuspendReserves { =head2 CancelReserve - CancelReserve({ reserve_id => $reserve_id, [ biblionumber => $biblionumber, borrowernumber => $borrrowernumber, itemnumber => $itemnumber ] }); + CancelReserve({ reserve_id => $reserve_id, [ biblionumber => $biblionumber, borrowernumber => $borrrowernumber, itemnumber => $itemnumber, autofill => $autofill ] }); Cancels a reserve. @@ -1139,6 +1144,8 @@ sub CancelReserve { my ( $params ) = @_; my $reserve_id = $params->{'reserve_id'}; + my $autofill = $params->{autofill}; + $reserve_id = GetReserveId( $params ) unless ( $reserve_id ); return unless ( $reserve_id ); @@ -1174,6 +1181,26 @@ sub CancelReserve { # now fix the priority on the others.... _FixPriority({ biblionumber => $reserve->{biblionumber} }); + + # only attempt to autofill canceled holds that were found and waiting + if ( $autofill && $reserve->{itemnumber} && $reserve->{found} && $reserve->{found} eq 'W' ) { + my ( undef, $next_hold ) = CheckReserves( $reserve->{'itemnumber'} ); + if ($next_hold) { + my $is_transfer = $reserve->{branchcode} ne $next_hold->{branchcode}; + + ModReserveAffect( + { + itemnumber => $reserve->{itemnumber}, + borrowernumber => $next_hold->{borrowernumber}, + is_transfer => $is_transfer, + notify_library => 1, + } + ); + + ModItemTransfer( $reserve->{itemnumber}, $reserve->{branchcode}, $next_hold->{branchcode} ) + if $is_transfer; + } + } } return $reserve; @@ -1367,7 +1394,13 @@ take care of the waiting status =cut sub ModReserveAffect { - my ( $itemnumber, $borrowernumber,$transferToDo ) = @_; + my ( $params ) = @_; + + my $itemnumber = $params->{itemnumber}; + my $borrowernumber = $params->{borrowernumber}; + my $transferToDo = $params->{is_transfer}; + my $notify_library = $params->{notify_library}; + my $dbh = C4::Context->dbh; # we want to attach $itemnumber to $borrowernumber, find the biblionumber @@ -1412,8 +1445,18 @@ sub ModReserveAffect { } $sth = $dbh->prepare($query); $sth->execute( $itemnumber, $borrowernumber,$biblionumber); - _koha_notify_reserve( $itemnumber, $borrowernumber, $biblionumber ) if ( !$transferToDo && !$already_on_shelf ); + + _koha_notify_reserve( + { + itemnumber => $itemnumber, + borrowernumber => $borrowernumber, + biblionumber => $biblionumber, + notify_library => $notify_library, + } + ) if ( !$transferToDo && !$already_on_shelf ); + _FixPriority( { biblionumber => $biblionumber } ); + if ( C4::Context->preference("ReturnToShelvingCart") ) { CartToShelf( $itemnumber ); } @@ -1458,7 +1501,7 @@ sub ModReserveMinusPriority { my $dbh = C4::Context->dbh; my $query = " UPDATE reserves - SET priority = 0 , itemnumber = ? + SET priority = 0 , itemnumber = ? WHERE reserve_id = ? "; my $sth_upd = $dbh->prepare($query); @@ -1673,7 +1716,7 @@ sub ToggleLowestPriority { my $sth = $dbh->prepare( "UPDATE reserves SET lowestPriority = NOT lowestPriority WHERE reserve_id = ?"); $sth->execute( $reserve_id ); - + _FixPriority({ reserve_id => $reserve_id, rank => '999999' }); } @@ -1882,7 +1925,7 @@ sub _FixPriority { $priority[$j]->{'reserve_id'} ); } - + $sth = $dbh->prepare( "SELECT reserve_id FROM reserves WHERE lowestPriority = 1 ORDER BY priority" ); $sth->execute(); @@ -2026,7 +2069,14 @@ sub _Findgroupreserve { =head2 _koha_notify_reserve - _koha_notify_reserve( $itemnumber, $borrowernumber, $biblionumber ); +_koha_notify_reserve( + { + itemnumber => $itemnumber, + borrowernumber => $borrowernumber, + biblionumber => $biblionumber, + notify_library => $notify_library + } +); Sends a notification to the patron that their hold has been filled (through ModReserveAffect, _not_ ModReserveFill) @@ -2034,7 +2084,12 @@ ModReserveAffect, _not_ ModReserveFill) =cut sub _koha_notify_reserve { - my ($itemnumber, $borrowernumber, $biblionumber) = @_; + my ( $params ) = @_; + + my $itemnumber = $params->{itemnumber}; + my $borrowernumber = $params->{borrowernumber}; + my $biblionumber = $params->{biblionumber}; + my $notify_library = $params->{notify_library}; my $dbh = C4::Context->dbh; my $borrower = C4::Members::GetMember(borrowernumber => $borrowernumber); @@ -2084,12 +2139,14 @@ sub _koha_notify_reserve { return; } - C4::Letters::EnqueueLetter( { - letter => $letter, - borrowernumber => $borrowernumber, - from_address => $admin_email_address, - message_transport_type => $mtt, - } ); + C4::Letters::EnqueueLetter( + { + letter => $letter, + borrowernumber => $borrowernumber, + from_address => $admin_email_address, + message_transport_type => $mtt, + } + ); }; while ( my ( $mtt, $letter_code ) = each %{ $messagingprefs->{transports} } ) { @@ -2106,7 +2163,37 @@ sub _koha_notify_reserve { if (! $notification_sent) { &$send_notification('print', 'HOLD'); } - + + if ($notify_library) { + my $letter = C4::Letters::GetPreparedLetter( + module => 'reserves', + letter_code => 'HOLD_CHANGED', + branchcode => $reserve->{branchcode}, + substitute => { today => C4::Dates->new()->output() }, + tables => { + 'branches' => $branch_details, + 'borrowers' => $borrower, + 'biblio' => $biblionumber, + 'reserves' => $reserve, + 'items' => $reserve->{'itemnumber'}, + }, + ); + + my $email = + C4::Context->preference('ExpireReservesAutoFillEmail') + || $branch_details->{'branchemail'} + || C4::Context->preference('KohaAdminEmailAddress'); + + C4::Letters::EnqueueLetter( + { + letter => $letter, + borrowernumber => $borrowernumber, + message_transport_type => 'email', + from_address => $email, + to_address => $email, + } + ); + } } =head2 _ShiftPriorityByDateAndPriority diff --git a/C4/SIP/ILS/Transaction/Checkin.pm b/C4/SIP/ILS/Transaction/Checkin.pm index bc1c433..6cd860a 100644 --- a/C4/SIP/ILS/Transaction/Checkin.pm +++ b/C4/SIP/ILS/Transaction/Checkin.pm @@ -99,13 +99,23 @@ sub do_checkin { $self->hold($messages->{ResFound}); if ($branch eq $messages->{ResFound}->{branchcode}) { $self->alert_type('01'); - ModReserveAffect( $messages->{ResFound}->{itemnumber}, - $messages->{ResFound}->{borrowernumber}, 0); + ModReserveAffect( + { + itemnumber => $messages->{ResFound}->{itemnumber}, + borrowernumber => $messages->{ResFound}->{borrowernumber}, + is_transfer => 0, + } + ); } else { $self->alert_type('02'); - ModReserveAffect( $messages->{ResFound}->{itemnumber}, - $messages->{ResFound}->{borrowernumber}, 1); + ModReserveAffect( + { + itemnumber => $messages->{ResFound}->{itemnumber}, + borrowernumber => $messages->{ResFound}->{borrowernumber}, + is_transfer => 1, + } + ); ModItemTransfer( $messages->{ResFound}->{itemnumber}, $branch, $messages->{ResFound}->{branchcode} diff --git a/circ/branchtransfers.pl b/circ/branchtransfers.pl index 4caca05..94ff667 100755 --- a/circ/branchtransfers.pl +++ b/circ/branchtransfers.pl @@ -89,7 +89,7 @@ if ( $request eq "KillWaiting" ) { } elsif ( $request eq "SetWaiting" ) { my $item = $query->param('itemnumber'); - ModReserveAffect( $item, $borrowernumber ); + ModReserveAffect( { itemnumber => $item, borrowernumber => $borrowernumber } ); $ignoreRs = 1; $setwaiting = 1; $reqmessage = 1; diff --git a/circ/returns.pl b/circ/returns.pl index 8b70e1a..65ffd92 100755 --- a/circ/returns.pl +++ b/circ/returns.pl @@ -149,7 +149,7 @@ if ( $query->param('resbarcode') ) { my $diffBranchSend = ($userenv_branch ne $diffBranchReturned) ? $diffBranchReturned : undef; # diffBranchSend tells ModReserveAffect whether document is expected in this library or not, # i.e., whether to apply waiting status - ModReserveAffect( $item, $borrowernumber, $diffBranchSend); + ModReserveAffect( { itemnumber => $item, borrowernumber => $borrowernumber, is_transfer => $diffBranchSend } ); # check if we have other reserves for this document, if we have a return send the message of transfer my ( $messages, $nextreservinfo ) = GetOtherReserves($item); diff --git a/installer/data/mysql/atomicupdate/bug_14364.sql b/installer/data/mysql/atomicupdate/bug_14364.sql new file mode 100644 index 0000000..4f3e21e --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_14364.sql @@ -0,0 +1,13 @@ +INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES +('ExpireReservesAutoFill','0',NULL,'Automatically fill the next hold with a automatically canceled expired waiting hold.','YesNo'), +('ExpireReservesAutoFillEmail','', NULL,'If ExpireReservesAutoFill and an email is defined here, the email notification for the change in the hold will be sent to this address.','Free'); + +INSERT INTO letter(module,code,branchcode,name,is_html,title,content,message_transport_type) +VALUES ( 'reserves', 'HOLD_CHANGED', '', 'Canceled Hold Available for Different Patron', '0', 'Canceled Hold Available for Different Patron', 'The patron picking up <> (<>) has changed to <> <> (<>). + +Please update the hold information for this item. + +Title: <> +Author: <> +Copy: <> +Pickup location: <>', 'email'); diff --git a/installer/data/mysql/de-DE/mandatory/sample_notices.sql b/installer/data/mysql/de-DE/mandatory/sample_notices.sql index 88cf551..2ab409f 100644 --- a/installer/data/mysql/de-DE/mandatory/sample_notices.sql +++ b/installer/data/mysql/de-DE/mandatory/sample_notices.sql @@ -135,3 +135,13 @@ Ihr Biblioheksteam' INSERT INTO letter(module, code, branchcode, name, title, content, message_transport_type) VALUES ('acquisition', 'ACQ_NOTIF_ON_RECEIV', '', 'Benachrichtigung bei Zugang', 'Bestelltes Medium ist eingetroffen', 'Liebe/r <> <>,\n\nDie Bestellung <> (<>) ist eingetroffen und wird bearbeitet.\n\nIhr Bibliotheksteam', 'email') + +INSERT INTO letter(module,code,branchcode,name,is_html,title,content,message_transport_type) + VALUES ( 'reserves', 'HOLD_CHANGED', '', 'Canceled Hold Available for Different Patron', '0', 'Canceled Hold Available for Different Patron', 'The patron picking up <> (<>) has changed to <> <> (<>). + + Please update the hold information for this item. + + Title: <> + Author: <> + Copy: <> + Pickup location: <>', 'email'); diff --git a/installer/data/mysql/en/mandatory/sample_notices.sql b/installer/data/mysql/en/mandatory/sample_notices.sql index 8616dda..d207ee4 100644 --- a/installer/data/mysql/en/mandatory/sample_notices.sql +++ b/installer/data/mysql/en/mandatory/sample_notices.sql @@ -147,3 +147,13 @@ Your library.' INSERT INTO letter(module, code, branchcode, name, title, content, message_transport_type) VALUES ('acquisition', 'ACQ_NOTIF_ON_RECEIV', '', 'Notification on receiving', 'Order received', 'Dear <> <>,\n\n The order <> (<>) has been received.\n\nYour library.', 'email') + +INSERT INTO letter(module,code,branchcode,name,is_html,title,content,message_transport_type) + VALUES ( 'reserves', 'HOLD_CHANGED', '', 'Canceled Hold Available for Different Patron', '0', 'Canceled Hold Available for Different Patron', 'The patron picking up <> (<>) has changed to <> <> (<>). + + Please update the hold information for this item. + + Title: <> + Author: <> + Copy: <> + Pickup location: <>', 'email'); diff --git a/installer/data/mysql/es-ES/mandatory/sample_notices.sql b/installer/data/mysql/es-ES/mandatory/sample_notices.sql index 99494e2..9d0bf20 100644 --- a/installer/data/mysql/es-ES/mandatory/sample_notices.sql +++ b/installer/data/mysql/es-ES/mandatory/sample_notices.sql @@ -148,3 +148,13 @@ Your library.' INSERT INTO letter(module, code, branchcode, name, title, content, message_transport_type) VALUES ('acquisition', 'ACQ_NOTIF_ON_RECEIV', '', 'Notification on receiving', 'Order received', 'Dear <> <>,\n\n The order <> (<>) has been received.\n\nYour library.', 'email') + +INSERT INTO letter(module,code,branchcode,name,is_html,title,content,message_transport_type) + VALUES ( 'reserves', 'HOLD_CHANGED', '', 'Canceled Hold Available for Different Patron', '0', 'Canceled Hold Available for Different Patron', 'The patron picking up <> (<>) has changed to <> <> (<>). + +Please update the hold information for this item. + +Title: <> +Author: <> +Copy: <> +Pickup location: <>', 'email'); diff --git a/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql b/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql index 348597f..430363a 100644 --- a/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql +++ b/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql @@ -149,3 +149,13 @@ Your library.' INSERT INTO letter(module, code, branchcode, name, title, content, message_transport_type) VALUES ('acquisition', 'ACQ_NOTIF_ON_RECEIV', '', 'Notification on receiving', 'Order received', 'Dear <> <>,\n\n The order <> (<>) has been received.\n\nYour library.', 'email') + +INSERT INTO letter(module,code,branchcode,name,is_html,title,content,message_transport_type) + VALUES ( 'reserves', 'HOLD_CHANGED', '', 'Canceled Hold Available for Different Patron', '0', 'Canceled Hold Available for Different Patron', 'The patron picking up <> (<>) has changed to <> <> (<>). + +Please update the hold information for this item. + +Title: <> +Author: <> +Copy: <> +Pickup location: <>', 'email'); diff --git a/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql b/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql index 49826e8..93fc940 100644 --- a/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql +++ b/installer/data/mysql/nb-NO/1-Obligatorisk/sample_notices.sql @@ -169,3 +169,13 @@ Your library.' INSERT INTO letter(module, code, branchcode, name, title, content, message_transport_type) VALUES ('acquisition', 'ACQ_NOTIF_ON_RECEIV', '', 'Notification on receiving', 'Order received', 'Dear <> <>,\n\n The order <> (<>) has been received.\n\nYour library.', 'email') + +INSERT INTO letter(module,code,branchcode,name,is_html,title,content,message_transport_type) + VALUES ( 'reserves', 'HOLD_CHANGED', '', 'Canceled Hold Available for Different Patron', '0', 'Canceled Hold Available for Different Patron', 'The patron picking up <> (<>) has changed to <> <> (<>). + +Please update the hold information for this item. + +Title: <> +Author: <> +Copy: <> +Pickup location: <>', 'email'); diff --git a/installer/data/mysql/pl-PL/mandatory/sample_notices.sql b/installer/data/mysql/pl-PL/mandatory/sample_notices.sql index 1a419db..893c975 100644 --- a/installer/data/mysql/pl-PL/mandatory/sample_notices.sql +++ b/installer/data/mysql/pl-PL/mandatory/sample_notices.sql @@ -146,3 +146,13 @@ Your library.' INSERT INTO letter(module, code, branchcode, name, title, content, message_transport_type) VALUES ('acquisition', 'ACQ_NOTIF_ON_RECEIV', '', 'Notification on receiving', 'Order received', 'Dear <> <>,\n\n The order <> (<>) has been received.\n\nYour library.', 'email') + +INSERT INTO letter(module,code,branchcode,name,is_html,title,content,message_transport_type) +VALUES ( 'reserves', 'HOLD_CHANGED', '', 'Canceled Hold Available for Different Patron', '0', 'Canceled Hold Available for Different Patron', 'The patron picking up <> (<>) has changed to <> <> (<>). + +Please update the hold information for this item. + +Title: <> +Author: <> +Copy: <> +Pickup location: <>', 'email'); diff --git a/installer/data/mysql/ru-RU/mandatory/sample_notices.sql b/installer/data/mysql/ru-RU/mandatory/sample_notices.sql index ba2cf3d..e09609b 100644 --- a/installer/data/mysql/ru-RU/mandatory/sample_notices.sql +++ b/installer/data/mysql/ru-RU/mandatory/sample_notices.sql @@ -149,3 +149,13 @@ Your library.' INSERT INTO letter(module, code, branchcode, name, title, content, message_transport_type) VALUES ('acquisition', 'ACQ_NOTIF_ON_RECEIV', '', 'Notification on receiving', 'Order received', 'Dear <> <>,\n\n The order <> (<>) has been received.\n\nYour library.', 'email') + +INSERT INTO letter(module,code,branchcode,name,is_html,title,content,message_transport_type) +VALUES ( 'reserves', 'HOLD_CHANGED', '', 'Canceled Hold Available for Different Patron', '0', 'Canceled Hold Available for Different Patron', 'The patron picking up <> (<>) has changed to <> <> (<>). + +Please update the hold information for this item. + +Title: <> +Author: <> +Copy: <> +Pickup location: <>', 'email'); diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index a744cbf..5b0530c 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -122,6 +122,8 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('EnableSearchHistory','0','','Enable or disable search history','YesNo'), ('EnhancedMessagingPreferences','0','','If ON, allows patrons to select to receive additional messages about items due or nearly due.','YesNo'), ('expandedSearchOption','0',NULL,'If ON, set advanced search to be expanded by default','YesNo'), +('ExpireReservesAutoFill','0',NULL,'Automatically fill the next hold with a automatically canceled expired waiting hold.','YesNo'), +('ExpireReservesAutoFillEmail','', NULL,'If ExpireReservesAutoFill and an email is defined here, the email notification for the change in the hold will be sent to this address.','Free'), ('ExpireReservesMaxPickUpDelay','0','','Enabling this allows holds to expire automatically if they have not been picked by within the time period specified in ReservesMaxPickUpDelay','YesNo'), ('ExpireReservesMaxPickUpDelayCharge','0',NULL,'If ExpireReservesMaxPickUpDelay is enabled, and this field has a non-zero value, than a borrower whose waiting hold has expired will be charged this amount.','free'), ('ExpireReservesOnHolidays', '1', NULL, 'If false, reserves at a library will not be canceled on days the library is not open.', 'YesNo'), diff --git a/installer/data/mysql/uk-UA/mandatory/sample_notices.sql b/installer/data/mysql/uk-UA/mandatory/sample_notices.sql index 4aac574..94ed308 100644 --- a/installer/data/mysql/uk-UA/mandatory/sample_notices.sql +++ b/installer/data/mysql/uk-UA/mandatory/sample_notices.sql @@ -148,3 +148,13 @@ Your library.' INSERT INTO letter(module, code, branchcode, name, title, content, message_transport_type) VALUES ('acquisition', 'ACQ_NOTIF_ON_RECEIV', '', 'Notification on receiving', 'Order received', 'Dear <> <>,\n\n The order <> (<>) has been received.\n\nYour library.', 'email') + +INSERT INTO letter(module,code,branchcode,name,is_html,title,content,message_transport_type) +VALUES ( 'reserves', 'HOLD_CHANGED', '', 'Canceled Hold Available for Different Patron', '0', 'Canceled Hold Available for Different Patron', 'The patron picking up <> (<>) has changed to <> <> (<>). + +Please update the hold information for this item. + +Title: <> +Author: <> +Copy: <> +Pickup location: <>', 'email'); diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref index a16f231..12e324c 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -474,6 +474,16 @@ Circulation: no: "Don't allow" - "holds to expire automatically if they have not been picked by within the time period specified in ReservesMaxPickUpDelay" - + - pref: ExpireReservesAutoFill + choices: + yes: "Do" + no: "Don't" + - automatically fill the next hold using the item. If enabled, an email notification will be sent to either the email address defined in ExpireReservesAutoFillEmail, the item's holding library's email address, or the email address defined in KohaAdminEmailAddress in that order. + - + - Send email notification of the new hold filled with a canceled item to + - pref: ExpireReservesAutoFillEmail + - . If no address is defined here, the email will be sent to either the item's holding library or the email address defined in KohaAdminEmailAddress in that order. + - - If using ExpireReservesMaxPickUpDelay, charge a borrower who allows his or her waiting hold to expire a fee of - pref: ExpireReservesMaxPickUpDelayCharge class: currency diff --git a/t/db_dependent/Holds/RevertWaitingStatus.t b/t/db_dependent/Holds/RevertWaitingStatus.t index 7b43edd..97f9b99 100755 --- a/t/db_dependent/Holds/RevertWaitingStatus.t +++ b/t/db_dependent/Holds/RevertWaitingStatus.t @@ -79,7 +79,7 @@ foreach my $borrowernumber (@borrowernumbers) { ); } -ModReserveAffect( $itemnumber, $borrowernumbers[0] ); +ModReserveAffect( { itemnumber => $itemnumber, borrowernumber => $borrowernumbers[0] } ); C4::Circulation::AddIssue( GetMember( borrowernumber => $borrowernumbers[1] ), $item_barcode, my $datedue, my $cancelreserve = 'revert' ); diff --git a/t/db_dependent/Reserves.t b/t/db_dependent/Reserves.t index fa0cf94..77fae9e 100755 --- a/t/db_dependent/Reserves.t +++ b/t/db_dependent/Reserves.t @@ -231,7 +231,7 @@ AddReserve('FPL', $requesters{'FPL'}, $bibnum2, AddReserve('CPL', $requesters{'CPL'}, $bibnum2, $constraint, $bibitems, 3, $resdate, $expdate, $notes, $title, $checkitem, $found); -ModReserveAffect($itemnum_cpl, $requesters{'RPL'}, 0); +ModReserveAffect( { itemnumber => $itemnum_cpl, borrowernumber => $requesters{'RPL'}, is_transfer => 0 } ); # Now it should have different priorities. my $title_reserves = GetReservesFromBiblionumber({biblionumber => $bibnum2}); @@ -343,12 +343,12 @@ is(exists $messages->{ResFound}?1:0, 1, 'AddReturn considers future reserve with # test marking a hold as captured my $hold_notice_count = count_hold_print_messages(); -ModReserveAffect($itemnumber, $requesters{'CPL'}, 0); +ModReserveAffect( { itemnumber => $itemnumber, borrowernumber => $requesters{'CPL'}, is_transfer => 0 } ); my $new_count = count_hold_print_messages(); is($new_count, $hold_notice_count + 1, 'patron notified when item set to waiting'); # test that duplicate notices aren't generated -ModReserveAffect($itemnumber, $requesters{'CPL'}, 0); +ModReserveAffect( { itemnumber => $itemnumber, borrowernumber => $requesters{'CPL'}, is_transfer => 0 } ); $new_count = count_hold_print_messages(); is($new_count, $hold_notice_count + 1, 'patron not notified a second time (bug 11445)'); @@ -384,7 +384,7 @@ AddReserve('CPL', $requesters{'CPL'}, $bibnum, @results= GetReservesFromItemnumber($itemnumber); is(defined $results[3]?1:0, 0, 'GetReservesFromItemnumber does not return a future item level hold'); # 9788c: GetReservesFromItemnumber returns future wait (confirmed future hold) -ModReserveAffect( $itemnumber, $requesters{'CPL'} , 0); #confirm hold +ModReserveAffect( { itemnumber => $itemnumber, borrowernumber => $requesters{'CPL'}, is_transfer => 0 } ); #confirm hold @results= GetReservesFromItemnumber($itemnumber); is(defined $results[3]?1:0, 1, 'GetReservesFromItemnumber returns a future wait (confirmed future hold)'); # End of tests for bug 9788 @@ -408,7 +408,7 @@ AddReserve('CPL', $requesters{'CPL'}, $bibnum, $title, $itemnumber, $found); $p = C4::Reserves::CalculatePriority($bibnum); is($p, 2, 'CalculatePriority should now return priority 2'); -ModReserveAffect( $itemnumber, $requesters{'CPL'} , 0); +ModReserveAffect( { itemnumber => $itemnumber, borrowernumber => $requesters{'CPL'}, is_transfer => 0 } ); $p = C4::Reserves::CalculatePriority($bibnum); is($p, 1, 'CalculatePriority should now return priority 1'); #add another biblio hold, no resdate @@ -458,7 +458,7 @@ is($cancancel, 1, 'Can user cancel its own reserve'); $cancancel = CanReserveBeCanceledFromOpac($canres->{reserve_id}, $requesters{'FPL'}); is($cancancel, 0, 'Other user cant cancel reserve'); -ModReserveAffect($itemnumber, $requesters{'CPL'}, 1); +ModReserveAffect( { itemnumber => $itemnumber, borrowernumber => $requesters{'CPL'}, is_transfer => 1 } ); $cancancel = CanReserveBeCanceledFromOpac($canres->{reserve_id}, $requesters{'CPL'}); is($cancancel, 0, 'Reserve in transfer status cant be canceled'); @@ -468,7 +468,7 @@ AddReserve('CPL', $requesters{'CPL'}, $item_bibnum, $title, $checkitem, ''); (undef, $canres, undef) = CheckReserves($itemnumber); -ModReserveAffect($itemnumber, $requesters{'CPL'}, 0); +ModReserveAffect( { itemnumber => $itemnumber, borrowernumber => $requesters{'CPL'}, is_transfer => 0 } ); $cancancel = CanReserveBeCanceledFromOpac($canres->{reserve_id}, $requesters{'CPL'}); is($cancancel, 0, 'Reserve in waiting status cant be canceled'); -- 1.7.2.5