Browse Source

Bug 5786 - Move AllowOnShelfHolds and OPACItemHolds system prefs to the Circulation Matrix

C4::Reserves:
* Added OnShelfHoldsAllowed() to check issuingrules
* Added OPACItemHoldsAllowed() to check issuingrules
* IsAvailableForItemLevelRequest() changed interface, now takes
  $item_record,$borrower_record; calls OnShelfHoldsAllowed()

opac/opac-reserve.pl and opac/opac-search.pl:
* rewrote hold allowed rule to use OPACItemHoldsAllowed()
* also use OnShelfHoldsAllowed() through
* IsAvailableForItemLevelRequest()

templates:
* Removed AllowOnShelfHolds and OPACItemHolds global flags, they now
  only have meaning per item type

Signed-off-by: Nicole C. Engard <nengard@bywatersolutions.com>

I have tested this patch left, right and upside down for the last
several months. All tests have passed.

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@gmail.com>
3.20.x
Srdjan 11 years ago
committed by Tomas Cohen Arazi
parent
commit
1802aa9153
  1. 1
      C4/Auth.pm
  2. 6
      C4/Circulation.pm
  3. 2
      C4/ILSDI/Services.pm
  4. 2
      C4/Items.pm
  5. 157
      C4/Reserves.pm
  6. 2
      C4/UsageStats.pm
  7. 5
      C4/VirtualShelves/Page.pm
  8. 18
      admin/smart-rules.pl
  9. 1
      installer/data/mysql/it-IT/necessari/system_preferences.sql
  10. 2
      installer/data/mysql/kohastructure.sql
  11. 2
      installer/data/mysql/sysprefs.sql
  12. 35
      installer/data/mysql/updatedatabase.pl
  13. 2
      installer/html-template-to-template-toolkit.pl
  14. 6
      koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref
  15. 7
      koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref
  16. 17
      koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt
  17. 6
      koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-detail-sidebar.inc
  18. 36
      koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt
  19. 8
      koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results-grouped.tt
  20. 8
      koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt
  21. 2
      koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-shelves.tt
  22. 27
      opac/opac-ISBDdetail.pl
  23. 18
      opac/opac-MARCdetail.pl
  24. 22
      opac/opac-detail.pl
  25. 37
      opac/opac-reserve.pl
  26. 19
      opac/opac-search.pl
  27. 9
      reserve/request.pl
  28. 2
      t/db_dependent/Circulation.t
  29. 6
      t/db_dependent/Circulation_Issuingrule.t
  30. 24
      t/db_dependent/Reserves.t

1
C4/Auth.pm

@ -471,7 +471,6 @@ sub get_template_and_user {
OPACAmazonCoverImages => C4::Context->preference("OPACAmazonCoverImages"),
OPACFRBRizeEditions => C4::Context->preference("OPACFRBRizeEditions"),
OpacHighlightedWords => C4::Context->preference("OpacHighlightedWords"),
OPACItemHolds => C4::Context->preference("OPACItemHolds"),
OPACShelfBrowser => "" . C4::Context->preference("OPACShelfBrowser"),
OPACURLOpenInNewWindow => "" . C4::Context->preference("OPACURLOpenInNewWindow"),
OPACUserCSS => "" . C4::Context->preference("OPACUserCSS"),

6
C4/Circulation.pm

@ -1468,7 +1468,7 @@ Returns a hashref from the issuingrules table.
sub GetIssuingRule {
my ( $borrowertype, $itemtype, $branchcode ) = @_;
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare( "select * from issuingrules where categorycode=? and itemtype=? and branchcode=? and issuelength is not null" );
my $sth = $dbh->prepare( "select * from issuingrules where categorycode=? and itemtype=? and branchcode=?" );
my $irule;
$sth->execute( $borrowertype, $itemtype, $branchcode );
@ -2699,8 +2699,10 @@ sub CanBookBeRenewed {
# by pushing all the elements onto an array and removing the duplicates.
my @reservable;
foreach my $b (@borrowernumbers) {
my ( $borr ) = C4::Members::GetMemberDetails( $b );
foreach my $i (@itemnumbers) {
if ( IsAvailableForItemLevelRequest($i)
my $item = GetItem($i);
if ( IsAvailableForItemLevelRequest($item, $borr)
&& CanItemBeReserved( $b, $i )
&& !IsItemOnHoldAndFound($i) )
{

2
C4/ILSDI/Services.pm

@ -491,7 +491,7 @@ sub GetServices {
my $canbookbereserved = CanBookBeReserved( $borrower, $biblionumber );
if ($canbookbereserved eq 'OK') {
push @availablefor, 'title level hold';
my $canitembereserved = IsAvailableForItemLevelRequest($itemnumber);
my $canitembereserved = IsAvailableForItemLevelRequest($item, $borrower);
if ($canitembereserved) {
push @availablefor, 'item level hold';
}

2
C4/Items.pm

@ -174,6 +174,8 @@ sub GetItem {
($data->{'serialseq'} , $data->{'publisheddate'}) = $ssth->fetchrow_array();
}
#if we don't have an items.itype, use biblioitems.itemtype.
# FIXME this should respect the itypes systempreference
# if (C4::Context->preference('item-level_itypes')) {
if( ! $data->{'itype'} ) {
my $sth = $dbh->prepare("SELECT itemtype FROM biblioitems WHERE biblionumber = ?");
$sth->execute($data->{'biblionumber'});

157
C4/Reserves.pm

@ -128,6 +128,8 @@ BEGIN {
&IsAvailableForItemLevelRequest
&OPACItemHoldsAllowed
&AlterPriority
&ToggleLowestPriority
@ -571,7 +573,6 @@ sub CanItemBeReserved{
if(my $rowcount = $sthcount->fetchrow_hashref()){
$reservecount = $rowcount->{count};
}
# we check if it's ok or not
if( $reservecount >= $allowedreserves ){
return 'tooManyReserves';
@ -1505,7 +1506,7 @@ sub GetReserveInfo {
=head2 IsAvailableForItemLevelRequest
my $is_available = IsAvailableForItemLevelRequest($itemnumber);
my $is_available = IsAvailableForItemLevelRequest($item_record,$borrower_record);
Checks whether a given item record is available for an
item-level hold request. An item is available if
@ -1515,12 +1516,8 @@ item-level hold request. An item is available if
* it is not withdrawn AND
* does not have a not for loan value > 0
Whether or not the item is currently on loan is
also checked - if the AllowOnShelfHolds system preference
is ON, an item can be requested even if it is currently
on loan to somebody else. If the system preference
is OFF, an item that is currently checked out cannot
be the target of an item-level hold request.
Need to check the issuingrules onshelfholds column,
if this is set items on the shelf can be placed on hold
Note that IsAvailableForItemLevelRequest() does not
check if the staff operator is authorized to place
@ -1531,48 +1528,80 @@ and canreservefromotherbranches.
=cut
sub IsAvailableForItemLevelRequest {
my $itemnumber = shift;
my $item = GetItem($itemnumber);
my $item = shift;
my $borrower = shift;
my $dbh = C4::Context->dbh;
# must check the notforloan setting of the itemtype
# FIXME - a lot of places in the code do this
# or something similar - need to be
# consolidated
my $dbh = C4::Context->dbh;
my $notforloan_query;
my $itype = _get_itype($item);
my $notforloan_per_itemtype
= $dbh->selectrow_array("SELECT notforloan FROM itemtypes WHERE itemtype = ?",
undef, $itype);
return 0 if
$notforloan_per_itemtype ||
$item->{itemlost} ||
$item->{notforloan} > 0 ||
$item->{wthdrawn} ||
($item->{damaged} && !C4::Context->preference('AllowHoldsOnDamagedItems'));
return 1 if _OnShelfHoldsAllowed($itype,$borrower->{categorycode},$item->{holdingbranch});
return $item->{onloan} || GetReserveStatus($item->{itemnumber}) eq "Waiting";
}
=head2 OnShelfHoldsAllowed
OnShelfHoldsAllowed($itemtype,$borrowercategory,$branchcode);
Checks issuingrules, using the borrowers categorycode, the itemtype, and branchcode to see if onshelf
holds are allowed, returns true if so.
=cut
sub OnShelfHoldsAllowed {
my ($item, $borrower) = @_;
my $itype = _get_itype($item);
return _OnShelfHoldsAllowed($itype,$borrower->{categorycode},$item->{holdingbranch});
}
sub _get_itype {
my $item = shift;
my $itype;
if (C4::Context->preference('item-level_itypes')) {
$notforloan_query = "SELECT itemtypes.notforloan
FROM items
JOIN itemtypes ON (itemtypes.itemtype = items.itype)
WHERE itemnumber = ?";
} else {
$notforloan_query = "SELECT itemtypes.notforloan
FROM items
JOIN biblioitems USING (biblioitemnumber)
JOIN itemtypes USING (itemtype)
WHERE itemnumber = ?";
# We cant trust GetItem to honour the syspref, so safest to do it ourselves
# When GetItem is fixed, we can remove this
$itype = $item->{itype};
}
my $sth = $dbh->prepare($notforloan_query);
$sth->execute($itemnumber);
my $notforloan_per_itemtype = 0;
if (my ($notforloan) = $sth->fetchrow_array) {
$notforloan_per_itemtype = 1 if $notforloan;
else {
# XXX This is a bit dodgy. It relies on biblio itemtype column having different name.
# So if we already have a biblioitems join when calling this function,
# we don't need to access the database again
$itype = $item->{itemtype};
}
unless ($itype) {
my $dbh = C4::Context->dbh;
my $query = "SELECT itemtype FROM biblioitems WHERE biblioitemnumber = ? ";
my $sth = $dbh->prepare($query);
$sth->execute($item->{biblioitemnumber});
if (my $data = $sth->fetchrow_hashref()){
$itype = $data->{itemtype};
}
}
return $itype;
}
my $available_per_item = 1;
$available_per_item = 0 if $item->{itemlost} or
( $item->{notforloan} > 0 ) or
($item->{damaged} and not C4::Context->preference('AllowHoldsOnDamagedItems')) or
$item->{withdrawn} or
$notforloan_per_itemtype;
sub _OnShelfHoldsAllowed {
my ($itype,$borrowercategory,$branchcode) = @_;
if (C4::Context->preference('AllowOnShelfHolds')) {
return $available_per_item;
} else {
return ($available_per_item and ($item->{onloan} or GetReserveStatus($itemnumber) eq "Waiting"));
}
my $rule = C4::Circulation::GetIssuingRule($borrowercategory, $itype, $branchcode);
return $rule->{onshelfholds};
}
=head2 AlterPriority
@ -2113,6 +2142,54 @@ sub _ShiftPriorityByDateAndPriority {
return $new_priority; # so the caller knows what priority they wind up receiving
}
=head2 OPACItemHoldsAllowed
OPACItemHoldsAllowed($item_record,$borrower_record);
Checks issuingrules, using the borrowers categorycode, the itemtype, and branchcode to see
if specific item holds are allowed, returns true if so.
=cut
sub OPACItemHoldsAllowed {
my ($item,$borrower) = @_;
my $branchcode = $item->{homebranch} or die "No homebranch";
my $itype;
my $dbh = C4::Context->dbh;
if (C4::Context->preference('item-level_itypes')) {
# We cant trust GetItem to honour the syspref, so safest to do it ourselves
# When GetItem is fixed, we can remove this
$itype = $item->{itype};
}
else {
my $query = "SELECT itemtype FROM biblioitems WHERE biblioitemnumber = ? ";
my $sth = $dbh->prepare($query);
$sth->execute($item->{biblioitemnumber});
if (my $data = $sth->fetchrow_hashref()){
$itype = $data->{itemtype};
}
}
my $query = "SELECT opacitemholds,categorycode,itemtype,branchcode FROM issuingrules WHERE
(issuingrules.categorycode = ? OR issuingrules.categorycode = '*')
AND
(issuingrules.itemtype = ? OR issuingrules.itemtype = '*')
AND
(issuingrules.branchcode = ? OR issuingrules.branchcode = '*')
ORDER BY
issuingrules.categorycode desc,
issuingrules.itemtype desc,
issuingrules.branchcode desc
LIMIT 1";
my $sth = $dbh->prepare($query);
$sth->execute($borrower->{categorycode},$itype,$branchcode);
my $data = $sth->fetchrow_hashref;
my $opacitemholds = uc substr ($data->{opacitemholds}, 0, 1);
return '' if $opacitemholds eq 'N';
return $opacitemholds;
}
=head2 MoveReserve
MoveReserve( $itemnumber, $borrowernumber, $cancelreserve )

2
C4/UsageStats.pm

@ -155,7 +155,6 @@ sub BuildReport {
AllowHoldPolicyOverride
AllowHoldsOnDamagedItems
AllowHoldsOnPatronsPossessions
AllowOnShelfHolds
AutoResumeSuspendedHolds
canreservefromotherbranches
decreaseLoanHighHolds
@ -265,7 +264,6 @@ sub BuildReport {
AllowPurchaseSuggestionBranchChoice
OpacAllowPublicListCreation
OpacAllowSharingPrivateLists
OPACItemHolds
OpacRenewalAllowed
OpacRenewalBranch
OPACViewOthersSuggestions

5
C4/VirtualShelves/Page.pm

@ -30,6 +30,7 @@ use Data::Dumper;
use C4::VirtualShelves qw/:DEFAULT ShelvesMax/;
use C4::Biblio;
use C4::Items;
use C4::Reserves;
use C4::Koha;
use C4::Auth qw/get_session/;
use C4::Members;
@ -226,7 +227,6 @@ sub shelfpage {
my ($shelfnumber2,$shelfname,$owner,$category,$sorton) = GetShelf($shelfnumber);
$template->param(
'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds'),
'DisplayMultiPlaceHold' => C4::Context->preference('DisplayMultiPlaceHold'),
);
if (C4::Context->preference('TagsEnabled')) {
@ -257,6 +257,8 @@ sub shelfpage {
@cart_list = split(/\//, $cart_list);
}
my $borrower = GetMember( 'borrowernumber' => $loggedinuser );
for my $this_item (@$items) {
my $biblionumber = $this_item->{'biblionumber'};
my $record = GetMarcBiblio($biblionumber);
@ -294,6 +296,7 @@ sub shelfpage {
});
}
$this_item->{'allow_onshelf_holds'} = C4::Reserves::OnShelfHoldsAllowed($this_item, $borrower);
}
if($type eq 'intranet'){
# Build drop-down list for 'Add To:' menu...

18
admin/smart-rules.pl

@ -101,12 +101,12 @@ elsif ($op eq 'delete-branch-item') {
# save the values entered
elsif ($op eq 'add') {
my $sth_search = $dbh->prepare('SELECT COUNT(*) AS total FROM issuingrules WHERE branchcode=? AND categorycode=? AND itemtype=?');
my $sth_insert = $dbh->prepare('INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, renewalperiod, norenewalbefore, auto_renew, reservesallowed, issuelength, lengthunit, hardduedate, hardduedatecompare, fine, finedays, maxsuspensiondays, firstremind, chargeperiod,rentaldiscount, overduefinescap) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)');
my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, maxsuspensiondays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, renewalperiod=?, norenewalbefore=?, auto_renew=?, reservesallowed=?, issuelength=?, lengthunit = ?, hardduedate=?, hardduedatecompare=?, rentaldiscount=?, overduefinescap=? WHERE branchcode=? AND categorycode=? AND itemtype=?");
my $sth_insert = $dbh->prepare('INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, reservesallowed, norenewalbefore, auto_renew, reservesallowed, issuelength, lengthunit, hardduedate, hardduedatecompare, fine, finedays, maxsuspensiondays, firstremind, chargeperiod,rentaldiscount, onshelfholds, opacitemholds, overduefinescap) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)');
my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, maxsuspensiondays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, renewalperiod=?, norenewalbefore=?, auto_renew=?, reservesallowed=?, issuelength=?, lengthunit=?, hardduedate=?, hardduedatecompare=?, rentaldiscount=?, onshelfholds=?, opacitemholds=?, overduefinescap=? WHERE branchcode=? AND categorycode=? AND itemtype=?");
my $br = $branch; # branch
my $bor = $input->param('categorycode'); # borrower category
my $cat = $input->param('itemtype'); # item type
my $itemtype = $input->param('itemtype'); # item type
my $fine = $input->param('fine');
my $finedays = $input->param('finedays');
my $maxsuspensiondays = $input->param('maxsuspensiondays');
@ -120,6 +120,7 @@ elsif ($op eq 'add') {
$norenewalbefore = undef if $norenewalbefore eq '0' or $norenewalbefore =~ /^\s*$/;
my $auto_renew = $input->param('auto_renew') eq 'yes' ? 1 : 0;
my $reservesallowed = $input->param('reservesallowed');
my $onshelfholds = $input->param('onshelfholds') || 0;
$maxissueqty =~ s/\s//g;
$maxissueqty = undef if $maxissueqty !~ /^\d+/;
my $issuelength = $input->param('issuelength');
@ -128,15 +129,16 @@ elsif ($op eq 'add') {
$hardduedate = format_date_in_iso($hardduedate);
my $hardduedatecompare = $input->param('hardduedatecompare');
my $rentaldiscount = $input->param('rentaldiscount');
my $opacitemholds = $input->param('opacitemholds') || 0;
my $overduefinescap = $input->param('overduefinescap') || undef;
$debug and warn "Adding $br, $bor, $cat, $fine, $maxissueqty";
$debug and warn "Adding $br, $bor, $itemtype, $fine, $maxissueqty";
$sth_search->execute($br,$bor,$cat);
$sth_search->execute($br,$bor,$itemtype);
my $res = $sth_search->fetchrow_hashref();
if ($res->{total}) {
$sth_update->execute($fine, $finedays, $maxsuspensiondays, $firstremind, $chargeperiod, $maxissueqty, $renewalsallowed, $renewalperiod, $norenewalbefore, $auto_renew, $reservesallowed, $issuelength,$lengthunit, $hardduedate,$hardduedatecompare,$rentaldiscount,$overduefinescap, $br,$bor,$cat);
$sth_update->execute($fine, $finedays, $maxsuspensiondays, $firstremind, $chargeperiod, $maxissueqty, $renewalsallowed, $renewalperiod, $norenewalbefore, $auto_renew, $reservesallowed, $issuelength,$lengthunit, $hardduedate,$hardduedatecompare,$rentaldiscount, $onshelfholds, $opacitemholds, $overduefinescap, $br,$bor,$itemtype);
} else {
$sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed, $renewalperiod, $norenewalbefore, $auto_renew, $reservesallowed,$issuelength,$lengthunit,$hardduedate,$hardduedatecompare,$fine,$finedays, $maxsuspensiondays, $firstremind,$chargeperiod,$rentaldiscount,$overduefinescap);
$sth_insert->execute($br,$bor,$itemtype,$maxissueqty,$renewalsallowed, $renewalperiod, $norenewalbefore, $auto_renew, $reservesallowed,$issuelength,$lengthunit,$hardduedate,$hardduedatecompare,$fine,$finedays, $maxsuspensiondays, $firstremind,$chargeperiod,$rentaldiscount,$onshelfholds,$opacitemholds,$overduefinescap);
}
}
elsif ($op eq "set-branch-defaults") {
@ -391,7 +393,7 @@ while (my $row = $sth2->fetchrow_hashref) {
$row->{'humancategorycode'} ||= $row->{'categorycode'};
$row->{'default_humancategorycode'} = 1 if $row->{'humancategorycode'} eq '*';
$row->{'fine'} = sprintf('%.2f', $row->{'fine'});
if ($row->{'hardduedate'} ne '0000-00-00') {
if ($row->{'hardduedate'} && $row->{'hardduedate'} ne '0000-00-00') {
$row->{'hardduedate'} = format_date( $row->{'hardduedate'});
$row->{'hardduedatebefore'} = 1 if ($row->{'hardduedatecompare'} == -1);
$row->{'hardduedateexact'} = 1 if ($row->{'hardduedatecompare'} == 0);

1
installer/data/mysql/it-IT/necessari/system_preferences.sql

@ -17,7 +17,6 @@
-- 51 Franklin Street' WHERE variable = ' Fifth Floor' WHERE variable = ' Boston' WHERE variable = ' MA 02110-1301 USA.
UPDATE systempreferences SET value = 'cataloguing' WHERE variable = 'AcqCreateItem';
UPDATE systempreferences SET value = '1' WHERE variable = 'AllowOnShelfHolds';
UPDATE systempreferences SET value = '1' WHERE variable = 'AllowRenewalLimitOverride';
UPDATE systempreferences SET value = 'annual' WHERE variable = 'autoBarcode';
UPDATE systempreferences SET value = 'email' WHERE variable = 'AutoEmailPrimaryAddress';

2
installer/data/mysql/kohastructure.sql

@ -1192,6 +1192,8 @@ CREATE TABLE `issuingrules` ( -- circulation and fine rules
`reservesallowed` smallint(6) NOT NULL default "0", -- how many holds are allowed
`branchcode` varchar(10) NOT NULL default '', -- the branch this rule is for (branches.branchcode)
overduefinescap decimal(28,6) default NULL, -- the maximum amount of an overdue fine
onshelfholds tinyint(1) NOT NULL default 0, -- allow holds for items that are on shelf
opacitemholds char(1) NOT NULL default 'N', -- allow opac users to place specific items on hold
PRIMARY KEY (`branchcode`,`categorycode`,`itemtype`),
KEY `categorycode` (`categorycode`),
KEY `itemtype` (`itemtype`)

2
installer/data/mysql/sysprefs.sql

@ -25,7 +25,6 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `
('AllowMultipleIssuesOnABiblio',1,'Allow/Don\'t allow patrons to check out multiple items from one biblio','','YesNo'),
('AllowNotForLoanOverride','0','','If ON, Koha will allow the librarian to loan a not for loan item.','YesNo'),
('AllowOfflineCirculation','0','','If on, enables HTML5 offline circulation functionality.','YesNo'),
('AllowOnShelfHolds','0','','Allow hold requests to be placed on items that are not on loan','YesNo'),
('AllowPKIAuth','None','None|Common Name|emailAddress','Use the field from a client-side SSL certificate to look a user in the Koha database','Choice'),
('AllowPurchaseSuggestionBranchChoice','0','1','Allow user to choose branch when making a purchase suggestion','YesNo'),
('AllowRenewalIfOtherItemsAvailable','0',NULL,'If enabled, allow a patron to renew an item with unfilled holds if other available items can fill that hold.','YesNo'),
@ -262,7 +261,6 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `
('OpacHiddenItems','','','This syspref allows to define custom rules for hiding specific items at opac. See docs/opac/OpacHiddenItems.txt for more informations.','Textarea'),
('OpacHighlightedWords','1','','If Set, then queried words are higlighted in OPAC','YesNo'),
('OpacHoldNotes','0','','Show hold notes on OPAC','YesNo'),
('OPACItemHolds','1','0|1|force','Allow OPAC users to place hold on specific items. If No, users can only request next available copy. If Yes, users can choose between next available and specific copy. If Force, users *must* choose a specific copy.','Choice'),
('OpacItemLocation','callnum','callnum|ccode|location','Show the shelving location of items in the opac','Choice'),
('OPACItemsResultsDisplay','0','','If OFF : show only the status of items in result list.If ON : show full location of items (branch+location+callnumber) as in staff interface','YesNo'),
('OpacKohaUrl','1',NULL,'Show \'Powered by Koha\' text on OPAC footer.',NULL),

35
installer/data/mysql/updatedatabase.pl

@ -9672,6 +9672,41 @@ if ( CheckVersion($DBversion) ) {
$dbh->do(q|SET foreign_key_checks = 1|);;
print "Upgrade to $DBversion done (Bug 11944 - Convert DB tables to utf8_unicode_ci)\n";
SetVersion($DBversion);
}
$DBversion = '3.19.00.XXX';
if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
# First create the column
$dbh->do("ALTER TABLE issuingrules ADD onshelfholds tinyint(1) default 0 NOT NULL");
# Now update the column
if (C4::Context->preference("AllowOnShelfHolds")){
# Pref is on, set allow for all rules
$dbh->do("UPDATE issuingrules SET onshelfholds=1");
} else {
# If the preference is not set, leave off
$dbh->do("UPDATE issuingrules SET onshelfholds=0");
}
# Remove from the systempreferences table
$dbh->do("DELETE FROM systempreferences WHERE variable = 'AllowOnShelfHolds'");
# First create the column
$dbh->do("ALTER TABLE issuingrules ADD opacitemholds char(1) DEFAULT 'N' NOT NULL");
# Now update the column
my $opacitemholds = C4::Context->preference("OPACItemHolds") || '';
if (lc ($opacitemholds) eq 'force') {
$opacitemholds = 'F';
}
else {
$opacitemholds = $opacitemholds ? 'Y' : 'N';
}
# Set allow for all rules
$dbh->do("UPDATE issuingrules SET opacitemholds='$opacitemholds'");
# Remove from the systempreferences table
$dbh->do("DELETE FROM systempreferences WHERE variable = 'OPACItemHolds'");
print "Upgrade to $DBversion done (Bug 5786 - Move AllowOnShelfHolds to circulation matrix; Move OPACItemHolds system preference to circulation matrix)\n";
SetVersion ($DBversion);
}

2
installer/html-template-to-template-toolkit.pl

@ -32,7 +32,7 @@ my @globals = ("themelang","JacketImages","OPACAmazonCoverImages","GoogleJackets
"SyndeticsEnabled", "OpacRenewalAllowed", "item_level_itypes","noItemTypeImages",
"virtualshelves", "RequestOnOpac", "COinSinOPACResults", "OPACXSLTResultsDisplay",
"OPACItemsResultsDisplay", "LibraryThingForLibrariesID", "opacuserlogin", "TagsEnabled",
"TagsShowOnList", "TagsInputOnList","loggedinusername","AllowOnShelfHolds","opacbookbag",
"TagsShowOnList", "TagsInputOnList","loggedinusername","opacbookbag",
"OPACAmazonEnabled", "SyndeticsCoverImages","using_https");
# Arguments:

6
koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref

@ -438,12 +438,6 @@ Circulation:
yes: Allow
no: "Don't allow"
- hold requests to be placed on and filled by damaged items.
-
- pref: AllowOnShelfHolds
choices:
yes: Allow
no: "Don't allow"
- hold requests to be placed on items that are not checked out.
-
- pref: AllowHoldDateInFuture
choices:

7
koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref

@ -493,13 +493,6 @@ OPAC:
# - pref: OpacCloud
# choices:
# - If ON, enables subject cloud on OPAC
-
- pref: OPACItemHolds
choices:
no: "Don't allow"
yes: Allow
force: Force
- patrons to place holds on specific items in the OPAC. If this is disabled, users can only put a hold on the next available item. If this is forced, users must put a hold on a specific item.
-
- pref: OpacRenewalAllowed
choices:

17
koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt

@ -156,6 +156,8 @@ for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde
<th>No renewal before</th>
<th>Automatic renewal</th>
<th>Holds allowed (count)</th>
<th>On shelf holds allowed</th>
<th>Item level holds</th>
<th>Rental discount (%)</th>
<th colspan="2">&nbsp;</th>
</tr>
@ -218,6 +220,8 @@ for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde
[% END %]
</td>
<td>[% rule.reservesallowed %]</td>
<td>[% IF rule.onshelfholds %]Yes[% ELSE %]No[% END %]</td>
<td>[% IF rule.opacitemholds == 'F'%]Enforce[% ELSIF rule.opacitemholds == 'Y'%]Allow[% ELSE %]Don't allow[% END %]</td>
<td>[% rule.rentaldiscount %]</td>
<td><a href="#" class="editrule">Edit</a></td>
<td>
@ -275,6 +279,19 @@ for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde
</select>
</td>
<td><input type="text" name="reservesallowed" id="reservesallowed" size="2" /></td>
<td>
<select name="onshelfholds" id="onshelfholds">
<option value="0" selected>No</option>
<option value="1">Yes</option>
</select>
</td>
<td>
<select id="opacitemholds" name="opacitemholds">
<option value="N">Don't allow</option>
<option value="Y">Allow</option>
<option value="F">Enforce</option>
</select>
</td>
<td><input type="text" name="rentaldiscount" id="rentaldiscount" size="2" /></td>
<td colspan="2">
<input type="hidden" name="branch" value="[% current_branch %]"/>

6
koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-detail-sidebar.inc

@ -2,12 +2,8 @@
[% UNLESS ( norequests ) %]
[% IF Koha.Preference( 'opacuserlogin' ) == 1 %]
[% IF Koha.Preference( 'RequestOnOpac' ) == 1 %]
[% IF ( AllowOnShelfHolds ) %]
[% IF ( AllowOnShelfHolds OR ItemsIssued ) %]
<li><a class="reserve" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% biblionumber %]">Place hold</a></li>
[% ELSE %]
[% IF ( ItemsIssued ) %]
<li><a class="reserve" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% biblionumber %]">Place hold</a></li>
[% END %]
[% END %]
[% END %]
[% END %]

36
koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt

@ -249,44 +249,31 @@
</li>
[% END # / IF OpacHoldNotes %]
[% IF OPACItemHolds == '1' or OPACItemHolds == 'force' %]
<li>
</li>
[% IF bibitemloo.itemholdable %]
<!-- ITEM HOLDS -->
<li class="lradio place_on_type" style="display:none;">
[% IF NOT bibitemloo.force_hold %]
<label class="radio inline" for="reqany_[% bibitemloo.biblionumber %]">Next available item</label>
[% IF OPACItemHolds == "1" %]
<input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
id="reqany_[% bibitemloo.biblionumber %]"
class="selectany"
value="Any"
checked="checked"
/>
[% ELSE %]
<input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
id="reqany_[% bibitemloo.biblionumber %]"
class="selectany"
value="Any"
/>
[% END %]
<label class="radio inline" for="reqspecific_[% bibitemloo.biblionumber %]">A specific item</label>
[% IF OPACItemHolds == "force" %]
<input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
id="reqspecific_[% bibitemloo.biblionumber %]"
class="selectspecific"
value="Specific"
checked="checked"
/>
[% ELSE %]
<input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
id="reqspecific_[% bibitemloo.biblionumber %]"
class="selectspecific"
value="Specific"
/>
[% END %]
</li>
[% END # / IF OPACItemHolds %]
[% END # / IF bibitemloo.itemholdable %]
</ul>
[% IF OPACItemHolds == '1' || OPACItemHolds == 'force' %]
[% IF bibitemloo.itemholdable %]
<table class="copiesrow table table-bordered table-striped" id="copiesrow_[% bibitemloo.biblionumber %]">
<caption>Select a specific item:</caption>
<tr>
@ -386,7 +373,7 @@
</tr>
[% END # / FOREACH itemLoo IN bibitemloo.itemLoop%]
</table> <!-- / #copiesrow_[% bibitemloo.biblionumber %] -->
[% END # / IF ( OPACItemHolds )%]
[% END # / IF ( bibitemloo.itemholdable )%]
</div> <!-- / #hold-options-[% bibitemloo.biblionumber %] -->
</fieldset>
[% END # / IF ( bibitemloo.holdable ) %]
@ -466,14 +453,13 @@
// Hides all 'specific copy' table rows on load.
$(".copiesrow").hide();
[% IF OPACItemHolds == 'force' %]
[% FOREACH bibitemloo IN bibitemloop %]
[% IF bibitemloo.holdable %]
[% IF bibitemloo.force_hold %]
$("#toggle-hold-options-[% bibitemloo.biblionumber %]").click();
$("#reqspecific_[% bibitemloo.biblionumber %]").click();
$("#copiesrow_[% bibitemloo.biblionumber %]").show();
[% END %]
[% END %]
[% END %]
// Insert reasons for forced hold notes
$(".forcenotesreason").each(function(){
@ -529,20 +515,16 @@
$("#place_on_hdr").show();
[% IF OPACItemHolds == '1' %]
$(".place_on_type").show();
// onload, selectany is checked
$(".selectany").attr("checked", "checked");
[% END %]
// If the user is *allowed* to choose a specific item
// The first one is preselected
[% IF OPACItemHolds =="1" %]
$("table.copiesrow").each(function(){
var id = suffixOf($(this).attr("id"), "_");
select_first_available(id);
});
[% END %]
// On confirmsjs change
$(".confirmjs").change(function(){

8
koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results-grouped.tt

@ -227,14 +227,8 @@ href="/cgi-bin/koha/opac-rss.pl?[% query_cgi %][% limit_cgi |html %]" />
<p>
[% IF Koha.Preference( 'RequestOnOpac' ) == 1 %]
[% UNLESS ( GROUP_RESULT.norequests ) %]
[% IF Koha.Preference( 'opacuserlogin' ) == 1 %]
[% IF ( AllowOnShelfHolds ) %]
[% IF Koha.Preference( 'opacuserlogin' ) == 1 && GROUP_RESULT.holdable %]
<a class="hold" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% GROUP_RESULT.biblionumber %]">Place hold</a><!-- add back when available 0 holds in queue-->
[% ELSE %]
[% IF ( GROUP_RESULT.itemsissued ) %]
<a class="hold" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% GROUP_RESULT.biblionumber %]">Place hold</a><!-- add back when available 0 holds in queue-->
[% END %]
[% END %]
[% END %]
[% END %]
[% END %]

8
koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt

@ -471,13 +471,9 @@
<div class="actions-menu noprint">
[% IF Koha.Preference( 'RequestOnOpac' ) == 1 %]
[% UNLESS ( SEARCH_RESULT.norequests ) %]
[% IF ( ( Koha.Preference( 'opacuserlogin' ) == 1 ) && AllowOnShelfHolds ) %]
[% IF ( Koha.Preference( 'opacuserlogin' ) == 1 ) && SEARCH_RESULT.holdable %]
<span class="actions"><a class="hold" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% SEARCH_RESULT.biblionumber %]">Place hold</a></span><!-- add back when available 0 holds in queue-->
[% ELSE %]
[% IF ( SEARCH_RESULT.itemsissued ) %]
<a class="hold" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% SEARCH_RESULT.biblionumber %]">Place hold</a><!-- add back when available 0 holds in queue-->
[% END %]
[% END # / IF opacuserlogin && AllowOnShelfHolds %]
[% END # / IF opacuserlogin && holdable %]
[% END # UNLESS SEARCH_RESULT.norequests %]
[% END # IF RequestOnOpac %]

2
koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-shelves.tt

@ -418,7 +418,7 @@
[% IF Koha.Preference( 'RequestOnOpac' ) == 1 %]
[% UNLESS ( itemsloo.norequests ) %]
[% IF Koha.Preference( 'opacuserlogin' ) == 1 %]
[% IF ( AllowOnShelfHolds ) %]
[% IF ( itemsloo.allow_onshelf_holds ) %]
<span class="actions"><a class="hold" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% itemsloo.biblionumber %]">Place hold</a><!-- add back when available 0 holds in queue--></span>
[% ELSE %]
[% IF ( itemsloo.itemsissued ) %]

27
opac/opac-ISBDdetail.pl

@ -49,6 +49,7 @@ use CGI qw ( -utf8 );
use MARC::Record;
use C4::Biblio;
use C4::Items;
use C4::Reserves;
use C4::Acquisition;
use C4::Review;
use C4::Serials; # uses getsubscriptionfrom biblionumber
@ -70,17 +71,13 @@ my $biblionumber = $query->param('biblionumber');
$biblionumber = int($biblionumber);
# get biblionumbers stored in the cart
my @cart_list;
if($query->cookie("bib_list")){
my $cart_list = $query->cookie("bib_list");
@cart_list = split(/\//, $cart_list);
if(my $cart_list = $query->cookie("bib_list")){
my @cart_list = split(/\//, $cart_list);
if ( grep {$_ eq $biblionumber} @cart_list) {
$template->param( incart => 1 );
}
}
$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') );
$template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) );
my $marcflavour = C4::Context->preference("marcflavour");
@ -148,16 +145,22 @@ $template->param(
);
my $norequests = 1;
my $allow_onshelf_holds;
my $res = GetISBDView($biblionumber, "opac");
my $itemtypes = GetItemTypes();
my $borrower = GetMember( 'borrowernumber' => $loggedinuser );
for my $itm (@items) {
$norequests = 0
if ( (not $itm->{'withdrawn'} )
&& (not $itm->{'itemlost'} )
&& ($itm->{'itemnotforloan'}<0 || not $itm->{'itemnotforloan'} )
&& (not $itemtypes->{$itm->{'itype'}}->{notforloan} )
&& ($itm->{'itemnumber'} ) );
if $norequests
&& !$itm->{'withdrawn'}
&& !$itm->{'itemlost'}
&& ($itm->{'itemnotforloan'}<0 || not $itm->{'itemnotforloan'})
&& !$itemtypes->{$itm->{'itype'}}->{notforloan}
&& $itm->{'itemnumber'};
$allow_onshelf_holds = C4::Reserves::OnShelfHoldsAllowed($itm, $borrower)
unless $allow_onshelf_holds;
}
my $reviews = getreviews( $biblionumber, 1 );
@ -173,7 +176,7 @@ foreach ( @$reviews ) {
$template->param(
RequestOnOpac => C4::Context->preference("RequestOnOpac"),
AllowOnShelfHolds => C4::Context->preference('AllowOnShelfHolds'),
AllowOnShelfHolds => $allow_onshelf_holds,
norequests => $norequests,
ISBD => $res,
biblionumber => $biblionumber,

18
opac/opac-MARCdetail.pl

@ -52,6 +52,8 @@ use CGI qw ( -utf8 );
use MARC::Record;
use C4::Biblio;
use C4::Items;
use C4::Reserves;
use C4::Members;
use C4::Acquisition;
use C4::Koha;
use List::MoreUtils qw/any/;
@ -103,17 +105,21 @@ $template->param(
);
# get biblionumbers stored in the cart
my @cart_list;
if($query->cookie("bib_list")){
my $cart_list = $query->cookie("bib_list");
@cart_list = split(/\//, $cart_list);
if(my $cart_list = $query->cookie("bib_list")){
my @cart_list = split(/\//, $cart_list);
if ( grep {$_ eq $biblionumber} @cart_list) {
$template->param( incart => 1 );
}
}
$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') );
my $allow_onshelf_holds;
my $borrower = GetMember( 'borrowernumber' => $loggedinuser );
for my $itm (@all_items) {
$allow_onshelf_holds = C4::Reserves::OnShelfHoldsAllowed($itm, $borrower);
last if $allow_onshelf_holds;
}
$template->param( 'AllowOnShelfHolds' => $allow_onshelf_holds );
$template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) );
# adding the $RequestOnOpac param

22
opac/opac-detail.pl

@ -437,12 +437,7 @@ if ($session->param('busc')) {
}
$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') );
$template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) );
$template->param('OPACShowCheckoutName' => C4::Context->preference("OPACShowCheckoutName") );
$template->param('OPACShowBarcode' => C4::Context->preference("OPACShowBarcode") );
@ -627,15 +622,21 @@ if ( not $viewallitems and @items > $max_items_to_display ) {
items_count => scalar( @items ),
);
} else {
my $allow_onshelf_holds;
my $borrower = GetMember( 'borrowernumber' => $borrowernumber );
for my $itm (@items) {
$itm->{holds_count} = $item_reserves{ $itm->{itemnumber} };
$itm->{priority} = $priority{ $itm->{itemnumber} };
$norequests = 0
if ( (not $itm->{'withdrawn'} )
&& (not $itm->{'itemlost'} )
&& ($itm->{'itemnotforloan'}<0 || not $itm->{'itemnotforloan'} )
&& (not $itemtypes->{$itm->{'itype'}}->{notforloan} )
&& ($itm->{'itemnumber'} ) );
if $norequests
&& !$itm->{'withdrawn'}
&& !$itm->{'itemlost'}
&& ($itm->{'itemnotforloan'}<0 || not $itm->{'itemnotforloan'})
&& !$itemtypes->{$itm->{'itype'}}->{notforloan}
&& $itm->{'itemnumber'};
$allow_onshelf_holds = C4::Reserves::OnShelfHoldsAllowed($itm, $borrower)
unless $allow_onshelf_holds;
# get collection code description, too
my $ccode = $itm->{'ccode'};
@ -691,6 +692,7 @@ if ( not $viewallitems and @items > $max_items_to_display ) {
push @itemloop, $itm;
}
}
$template->param( 'AllowOnShelfHolds' => $allow_onshelf_holds );
}
# Display only one tab if one items list is empty

37
opac/opac-reserve.pl

@ -423,6 +423,7 @@ foreach my $biblioNum (@biblionumbers) {
$biblioLoopIter{itemLoop} = [];
my $numCopiesAvailable = 0;
my $numCopiesOPACAvailable = 0;
foreach my $itemInfo (@{$biblioData->{itemInfos}}) {
my $itemNum = $itemInfo->{itemnumber};
my $itemLoopIter = {};
@ -517,16 +518,27 @@ foreach my $biblioNum (@biblionumbers) {
my $branch = GetReservesControlBranch( $itemInfo, $borr );
my $branchitemrule = GetBranchItemRule( $branch, $itemInfo->{'itype'} );
my $policy_holdallowed = 1;
if ( $branchitemrule->{'holdallowed'} == 0 ||
( $branchitemrule->{'holdallowed'} == 1 && $borr->{'branchcode'} ne $itemInfo->{'homebranch'} ) ) {
$policy_holdallowed = 0;
my $policy_holdallowed = !$itemLoopIter->{already_reserved};
if ($policy_holdallowed) {
if (my $branchitemrule = GetBranchItemRule( $branch, $itemInfo->{'itype'} )) {
$policy_holdallowed =
($branchitemrule->{'holdallowed'} == 2) ||
($branchitemrule->{'holdallowed'} == 1
&& $borr->{'branchcode'} eq $itemInfo->{'homebranch'});
} else {
$policy_holdallowed = 0; # No rule - not allowed
}
}
$policy_holdallowed &&=
IsAvailableForItemLevelRequest($itemInfo,$borr) &&
CanItemBeReserved($borrowernumber,$itemNum) eq 'OK';
if (IsAvailableForItemLevelRequest($itemNum) and $policy_holdallowed and CanItemBeReserved($borrowernumber,$itemNum) eq 'OK' and ($itemLoopIter->{already_reserved} ne 1)) {
if ($policy_holdallowed) {
if ( my $hold_allowed = OPACItemHoldsAllowed( $itemInfo, $borr ) ) {
$itemLoopIter->{available} = 1;
$numCopiesOPACAvailable++;
$biblioLoopIter{force_hold} = 1 if $hold_allowed eq 'F';
}
$numCopiesAvailable++;
}
@ -545,23 +557,22 @@ foreach my $biblioNum (@biblionumbers) {
$numBibsAvailable++;
$biblioLoopIter{bib_available} = 1;
$biblioLoopIter{holdable} = 1;
$biblioLoopIter{itemholdable} = 1 if $numCopiesOPACAvailable;
}
if ($biblioLoopIter{already_reserved}) {
$biblioLoopIter{holdable} = undef;
}
my $canReserve = CanBookBeReserved($borrowernumber,$biblioNum);
unless ($canReserve eq 'OK') {
$biblioLoopIter{holdable} = undef;
$biblioLoopIter{ $canReserve } = 1;
$biblioLoopIter{itemholdable} = undef;
}
if(not C4::Context->preference('AllowHoldsOnPatronsPossessions') and CheckIfIssuedToPatron($borrowernumber,$biblioNum)) {
$biblioLoopIter{holdable} = undef;
$biblioLoopIter{already_patron_possession} = 1;
}
if( $biblioLoopIter{holdable} ){ $anyholdable++; }
$biblioLoopIter{holdable} &&= CanBookBeReserved($borrowernumber,$biblioNum) eq 'OK';
push @$biblioLoop, \%biblioLoopIter;
$anyholdable = 1 if $biblioLoopIter{holdable};
}
if ( $numBibsAvailable == 0 || $anyholdable == 0) {

19
opac/opac-search.pl

@ -42,6 +42,8 @@ use C4::Branch; # GetBranches
use C4::SocialData;
use C4::Ratings;
use C4::External::OverDrive;
use C4::Members;
use C4::Reserves;
use POSIX qw(ceil floor strftime);
use URI::Escape;
@ -136,7 +138,7 @@ if (C4::Context->preference("marcflavour") eq "UNIMARC" ) {
elsif (C4::Context->preference("marcflavour") eq "MARC21" ) {
$template->param('usmarc' => 1);
}
$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') );
$template->param( 'OPACNoResultsFound' => C4::Context->preference('OPACNoResultsFound') );
$template->param(
@ -567,8 +569,11 @@ if ($@ || $error) {
exit;
}
my $borrower = $borrowernumber ? GetMember( borrowernumber => $borrowernumber ) : undef;
# At this point, each server has given us a result set
# now we build that set for template display
my %allow_onshelf_holds;
my @sup_results_array;
for (my $i=0;$i<@servers;$i++) {
my $server = $servers[$i];
@ -583,11 +588,23 @@ for (my $i=0;$i<@servers;$i++) {
# we need to set the offset parameter of searchResults to 0
my @group_results = searchResults( 'opac', $query_desc, $group->{'group_count'},$results_per_page, 0, $scan,
$group->{"RECORDS"});
if ($borrower) {
$_->{holdable} =
IsAvailableForItemLevelRequest($_, $borrower) &&
OPACItemHoldsAllowed($_, $borrower)
foreach @group_results;
}
push @newresults, { group_label => $group->{'group_label'}, GROUP_RESULTS => \@group_results };
}
} else {
@newresults = searchResults('opac', $query_desc, $hits, $results_per_page, $offset, $scan,
$results_hashref->{$server}->{"RECORDS"});
if ($borrower) {
$_->{holdable} =
IsAvailableForItemLevelRequest($_, $borrower) &&
OPACItemHoldsAllowed($_, $borrower)
foreach @newresults;
}
}
$hits = 0 unless @newresults;

9
reserve/request.pl

@ -334,9 +334,6 @@ foreach my $biblionumber (@biblionumbers) {
$item->{hosttitle} = GetBiblioData($item->{biblionumber})->{title};
}
# add information
$item->{itemcallnumber} = $item->{itemcallnumber};
# if the item is currently on loan, we display its return date and
# change the background color
my $issues= GetItemIssue($itemnumber);
@ -347,9 +344,9 @@ foreach my $biblionumber (@biblionumbers) {
# checking reserve
my ($reservedate,$reservedfor,$expectedAt,$reserve_id,$wait) = GetReservesFromItemnumber($itemnumber);
if ( defined $reservedate ) {
my $ItemBorrowerReserveInfo = GetMember( borrowernumber => $reservedfor );
if ( defined $reservedate ) {
$item->{backgroundcolor} = 'reserved';
$item->{reservedate} = format_date($reservedate);
$item->{ReservedForBorrowernumber} = $reservedfor;
@ -394,7 +391,7 @@ foreach my $biblionumber (@biblionumbers) {
}
# If there is no loan, return and transfer, we show a checkbox.
$item->{notforloan} = $item->{notforloan} || 0;
$item->{notforloan} ||= 0;
# if independent branches is on we need to check if the person can reserve
# for branches they arent logged in to
@ -424,7 +421,7 @@ foreach my $biblionumber (@biblionumbers) {
if (
$policy_holdallowed
&& !$item->{cantreserve}
&& IsAvailableForItemLevelRequest($itemnumber)
&& IsAvailableForItemLevelRequest($item, $borrowerinfo)
&& CanItemBeReserved(
$borrowerinfo->{borrowernumber}, $itemnumber
) eq 'OK'

2
t/db_dependent/Circulation.t

@ -291,7 +291,7 @@ C4::Context->dbh->do("DELETE FROM accountlines");
);
# Testing of feature to allow the renewal of reserved items if other items on the record can fill all needed holds
C4::Context->set_preference('AllowOnShelfHolds', 1 );
C4::Context->dbh->do("UPDATE issuingrules SET onshelfholds = 1");
C4::Context->set_preference('AllowRenewalIfOtherItemsAvailable', 1 );
( $renewokay, $error ) = CanBookBeRenewed($renewing_borrowernumber, $itemnumber);
is( $renewokay, 1, 'Bug 11634 - Allow renewal of item with unfilled holds if other available items can fill those holds');

6
t/db_dependent/Circulation_Issuingrule.t

@ -132,6 +132,8 @@ my $sampleissuingrule1 = {
itemtype => 'BOOK',
categorycode => $samplecat->{categorycode},
maxsuspensiondays => 0,
onshelfholds => 0,
opacitemholds => 'N',
};
my $sampleissuingrule2 = {
branchcode => $samplebranch2->{branchcode},
@ -158,6 +160,8 @@ my $sampleissuingrule2 = {
chargename => 'Null',
restrictedtype => 'Null',
maxsuspensiondays => 0,
onshelfholds => 1,
opacitemholds => 'Y',
};
my $sampleissuingrule3 = {
branchcode => $samplebranch1->{branchcode},
@ -184,6 +188,8 @@ my $sampleissuingrule3 = {
chargename => 'Null',
restrictedtype => 'Null',
maxsuspensiondays => 0,
onshelfholds => 1,
opacitemholds => 'F',
};
$query = 'INSERT INTO issuingrules (
branchcode,

24
t/db_dependent/Reserves.t

@ -17,7 +17,7 @@
use Modern::Perl;
use Test::More tests => 53;
use Test::More tests => 56;
use MARC::Record;
use DateTime::Duration;
@ -506,6 +506,28 @@ is( C4::Reserves::CanBookBeReserved($borrowernumber, $biblionumber) , 'OK', "Res
####### EO Bug 13113 <<<
####
my $item = GetItem($itemnumber);
ok( C4::Reserves::IsAvailableForItemLevelRequest($item, $borrower), "Reserving a book on item level" );
my $itype = C4::Reserves::_get_itype($item);
my $categorycode = $borrower->{categorycode};
my $holdingbranch = $item->{holdingbranch};
my $rule = C4::Circulation::GetIssuingRule($categorycode, $itype, $holdingbranch);
$dbh->do(
"UPDATE issuingrules SET onshelfholds = 1 WHERE categorycode = ? AND itemtype= ? and branchcode = ?",
undef,
$rule->{categorycode}, $rule->{itemtype}, $rule->{branchcode}
);
ok( C4::Reserves::OnShelfHoldsAllowed($item, $borrower), "OnShelfHoldsAllowed() allowed" );
$dbh->do(
"UPDATE issuingrules SET onshelfholds = 0 WHERE categorycode = ? AND itemtype= ? and branchcode = ?",
undef,
$rule->{categorycode}, $rule->{itemtype}, $rule->{branchcode}
);
ok( !C4::Reserves::OnShelfHoldsAllowed($item, $borrower), "OnShelfHoldsAllowed() disallowed" );
$dbh->rollback;
sub count_hold_print_messages {

Loading…
Cancel
Save