From 5d8b950f5e6da977b81d17acdc4d4edfcf2059f7 Mon Sep 17 00:00:00 2001 From: Barry Cannon Date: Fri, 8 Nov 2013 18:46:32 +0000 Subject: [PATCH] Bug 6837 When AllowOnShelfHolds is OFF then holds on records with available items should not be possible Although AllowOnShelfHolds does, under certain cirmcumstances restrict items from having holds placed on them there are certain conditions that cause OPAC to still display an available Hold when it shouldn't. Eg. It there are two items, one is on the self and one is Checked Out. This patch adds a new SystemPreference 'PreventOPACHoldsAnyAvailableItem' which will enforce the restriction of placing a hold when any item is on the shelf. --- C4/Reserves.pm | 66 ++++++++++++++++++++ installer/data/mysql/sysprefs.sql | 1 + installer/data/mysql/updatedatabase.pl | 6 ++ .../en/modules/admin/preferences/circulation.pref | 7 +++ .../prog/en/includes/opac-detail-sidebar.inc | 12 ++-- .../opac-tmpl/prog/en/modules/opac-results.tt | 10 +-- opac/opac-detail.pl | 9 ++- opac/opac-search.pl | 9 ++- 8 files changed, 109 insertions(+), 11 deletions(-) diff --git a/C4/Reserves.pm b/C4/Reserves.pm index d1bca25..46bc6e0 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -133,6 +133,7 @@ BEGIN { &SuspendAll &GetReservesControlBranch + &PreventOPACHoldsAnyAvailableItem ); @EXPORT_OK = qw( MergeHolds ); } @@ -2214,6 +2215,71 @@ sub GetReservesControlBranch { return $branchcode; } + +=head2 PreventOPACHoldsAnyAvailableItem +Checks if an item is available to have a hold placed on it from the OPAC only. +Specifically relates to items currently on the shelf (without a datedue). +If 'AllowOnShelfHolds' syspref is allowed then this will always return false i.e +PreventOPACHoldsAnyAvailableItem will not prevent OPAC holds. + +Is controlled by the 'PreventOPACHoldsAnyAvailableItem' system preference. + +The system preference has 2 states: + +* off: Not in effect. Allowing of hold will be determined elsewhere in the system. +* on: Each bibnumber will be checked for attached items. Each item is checked for +its availability. The only status that prevents a hold is when an item is on the +shelf and available. All other status should be ignored. + +Returns true when any item attached to the bib is on the shelf and available + +=cut + +sub PreventOPACHoldsAnyAvailableItem { + my $biblionumber = shift; + + if ( C4::Context->preference('AllowOnShelfHolds') or not C4::Context->preference('PreventOPACHoldsAnyAvailableItem') ) { + return 0; # we shouldn't be in here + } + + my @items = GetItemsInfo( $biblionumber ); + my $prevent_hold = 0; + my $dbh = C4::Context->dbh; + my $notforloan_query; + 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 = ?"; + } + my $sth = $dbh->prepare($notforloan_query); + foreach my $item (@items) { + $sth->execute( $item->{itemnumber} ); + my $notforloan_itemtype = 0; + if (my ($notforloan) = $sth->fetchrow_array) { + $notforloan_itemtype = 1 if $notforloan; + } + + if ( not $item->{datedue} ) { + if ($item->{itemlost} + or ( $item->{notforloan} > 0 ) + or ( $item->{damaged} and not C4::Context->preference('AllowHoldsOnDamagedItems') ) + or $item->{wthdrawn} + or $notforloan_itemtype) { + next; + } + else {$prevent_hold++} + } + } + return $prevent_hold; +} + =head1 AUTHOR Koha Development Team diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 72eead2..0fda5d5 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -301,6 +301,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('Persona','0','','Use Mozilla Persona for login','YesNo'), ('PrefillItem','0','','When a new item is added, should it be prefilled with last created item values?','YesNo'), ('previousIssuesDefaultSortOrder','asc','asc|desc','Specify the sort order of Previous Issues on the circulation page','Choice'), +('PreventOPACHoldsAnyAvailableItem,'0',NULL,'Define how OPAC users can place holds on items that are checked in (on the self),'Choice'), ('printcirculationslips','1','','If ON, enable printing circulation receipts','YesNo'), ('PrintNoticesMaxLines','0','','If greater than 0, sets the maximum number of lines an overdue notice will print. If the number of items is greater than this number, the notice will end with a warning asking the borrower to check their online account for a full list of overdue items.','Integer'), ('QueryAutoTruncate','1',NULL,'If ON, query truncation is enabled by default','YesNo'), diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 6162bc5..3ed8a5f 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -7743,6 +7743,12 @@ if(CheckVersion($DBversion)) { SetVersion($DBversion); } +$DBversion = "3.13.00.XXX"; + if ( CheckVersion($DBversion) ) { + $dbh->do("INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('PreventOPACHoldsAnyAvailableItem', '0', 'Define how OPAC users can place holds on items that are checked in (on the self)', NULL ,'Choice')"); + print "Upgrade to $DBversion done (Bug 6837: Enchances AllowOnShelfHolds SystemPref, give more granular control over OPAC holds )\n"; + SetVersion($DBversion); + } =head1 FUNCTIONS =head2 TableExists($table) 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 9ae9c44..2827f93 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 @@ -370,6 +370,13 @@ Circulation: no: "Don't allow" - hold requests to be placed on items that are not checked out. - + - pref: PreventOPACHoldsAnyAvailableItem + type: choice + choices: + yes: Prevent + no: Do not explicitly prevent + - holds to be placed when ANY item is on the shelf. (Preference is ignored if AllowOnShelfHolds is ON) + - - pref: AllowHoldDateInFuture choices: yes: Allow diff --git a/koha-tmpl/opac-tmpl/prog/en/includes/opac-detail-sidebar.inc b/koha-tmpl/opac-tmpl/prog/en/includes/opac-detail-sidebar.inc index 0f16f3a..4a6a573 100644 --- a/koha-tmpl/opac-tmpl/prog/en/includes/opac-detail-sidebar.inc +++ b/koha-tmpl/opac-tmpl/prog/en/includes/opac-detail-sidebar.inc @@ -2,12 +2,14 @@ [% UNLESS ( norequests ) %] [% IF ( opacuserlogin ) %] [% IF ( RequestOnOpac ) %] - [% IF ( AllowOnShelfHolds ) %] -
  • Place hold
  • - [% ELSE %] - [% IF ( ItemsIssued ) %] + [% UNLESS (PreventOPACHoldsAnyAvailableItem) %] + [% IF ( AllowOnShelfHolds ) %]
  • Place hold
  • - [% END %] + [% ELSE %] + [% IF ( ItemsIssued ) %] +
  • Place hold
  • + [% END %] + [% END %] [% END %] [% END %] [% END %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt index 9235b2b..3b0d3db 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt @@ -667,11 +667,13 @@ $(document).ready(function(){ [% IF ( RequestOnOpac ) %] [% UNLESS ( SEARCH_RESULT.norequests ) %] [% IF ( opacuserlogin ) %] - [% IF ( AllowOnShelfHolds ) %] - Place hold - [% ELSE %] - [% IF ( SEARCH_RESULT.itemsissued ) %] + [% UNLESS SEARCH_RESULT.prevent_holds %] + [% IF ( AllowOnShelfHolds ) %] Place hold + [% ELSE %] + [% IF ( SEARCH_RESULT.itemsissued ) %] + Place hold + [% END %] [% END %] [% END %] [% END %] diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl index 41de4fd..8829400 100755 --- a/opac/opac-detail.pl +++ b/opac/opac-detail.pl @@ -401,9 +401,16 @@ if ($session->param('busc')) { } +# Check if we can place a hold on this bib where there is an item out but others available +my $prevent_holds = 0; +if ( C4::Context->preference('PreventOPACHoldsAnyAvailableItem') && not C4::Context->preference('AllowOnShelfHolds') ) { + $prevent_holds = PreventOPACHoldsAnyAvailableItem( $biblionumber ); + print "HOLDS: $prevent_holds
    "; +} +$template->param( 'PreventOPACHoldsAnyAvailableItem' => $prevent_holds ); $template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') ); -$template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) ); +$template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) ) if not $prevent_holds; diff --git a/opac/opac-search.pl b/opac/opac-search.pl index 2854da6..1fffbdb 100755 --- a/opac/opac-search.pl +++ b/opac/opac-search.pl @@ -52,7 +52,7 @@ use C4::Branch; # GetBranches use C4::SocialData; use C4::Ratings; use C4::External::OverDrive; - +use C4::Reserves; use POSIX qw(ceil floor strftime); use URI::Escape; use JSON qw/decode_json encode_json/; @@ -675,6 +675,13 @@ for (my $i=0;$i<@servers;$i++) { my $j = 0; foreach (@newresults) { my $bibnum = ($_->{biblionumber})?$_->{biblionumber}:0; + my $prevent_holds = 0; + if ( C4::Context->preference('PreventOPACHoldsAnyAvailableItem') && not C4::Context->preference('AllowOnShelfHolds') ) { + $prevent_holds = PreventOPACHoldsAnyAvailableItem($bibnum) if $bibnum; + } + if ( $prevent_holds ) { + $_->{prevent_holds} =1; + } $pasarParams .= $bibnum . ','; $j++; last if ($j == $results_per_page); -- 1.7.10.4