From 7798a579b515b928eddec922cbac0f05c5aa6d58 Mon Sep 17 00:00:00 2001 From: Lyon3 Team Date: Mon, 11 Nov 2013 08:05:45 -0500 Subject: [PATCH 2/2] Bug 11482 PickupHoldOnlyFromItemBranches new syspref This syspref sets the following behavior about reserves : Pickup location can be choosen only among the branches of a record items. Within this limit, you can choose the next available copy at whatever location or at a specific location. It's compatible with multi-holds functionnality from opac but not on staff interface. It is disabled by default. --- C4/Branch.pm | 22 ++++++++++++++++ C4/Reserves.pm | 18 ++++++++++++- catalogue/search.pl | 2 + circ/returns.pl | 7 ++++- installer/data/mysql/sysprefs.sql | 3 +- installer/data/mysql/updatedatabase.pl | 7 +++++ .../en/modules/admin/preferences/circulation.pref | 8 ++++++ .../prog/en/modules/catalogue/results.tt | 2 +- .../intranet-tmpl/prog/en/modules/circ/returns.tt | 4 +++ .../prog/en/modules/reserve/request.tt | 22 ++++++++++------ .../opac-tmpl/prog/en/modules/opac-reserve.tt | 13 ++++++--- koha-tmpl/opac-tmpl/prog/en/modules/opac-user.tt | 14 +++------- opac/opac-reserve.pl | 10 +++++++ reserve/modrequest.pl | 1 + reserve/placerequest.pl | 1 + reserve/request.pl | 27 ++++++++++++++++++- 16 files changed, 133 insertions(+), 28 deletions(-) diff --git a/C4/Branch.pm b/C4/Branch.pm index 83d2010..5411541 100644 --- a/C4/Branch.pm +++ b/C4/Branch.pm @@ -33,6 +33,7 @@ BEGIN { &GetBranch &GetBranches &GetBranchesLoop + &GetBranchesPartLoop &GetBranchDetail &get_branchinfos_of &ModBranch @@ -168,6 +169,27 @@ sub GetBranchesLoop { # since this is what most pages want anyway return \@loop; } +=head2 GetBranchesPartLoop + + &GetBranchesPartLoop($branches;$branch) + +=cut + +sub GetBranchesPartLoop { + my $branches = shift; + my $branch = shift; + my @loop; + while ( my ($branchcode, $branchname) = each %$branches) { + push @loop, { + value => $branchcode, + branchcode => $branchcode, + selected => ($branchcode eq $branch) ? 1 : 0, + branchname => $branchname, + }; + } + return \@loop; +} + =head2 GetBranchName =cut diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 5759919..907bd98 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -118,6 +118,7 @@ BEGIN { &CheckReserves &CanBookBeReserved &CanItemBeReserved + &SetFirstReturnedItem &CancelReserve &CancelExpiredReserves @@ -578,7 +579,22 @@ sub CanItemBeReserved{ } } - } +} +# +=head2 SetFirstReturnedItem + + &SetFirstReturnedItem( $branchcode, $itemnumber, $borrowernumber, $biblionumber ); + +=cut + +sub SetFirstReturnedItem { + my ( $branchcode, $itemnumber, $borrowernumber, $biblionumber ) = @_; + my $dbh = C4::Context->dbh; + my $query = "UPDATE reserves SET branchcode = ?, itemnumber = ? WHERE borrowernumber = ? AND biblionumber = ?"; + my $sth_upd = $dbh->prepare($query); + $sth_upd->execute($branchcode,$itemnumber,$borrowernumber,$biblionumber); +} + #-------------------------------------------------------------------------------- =head2 GetReserveCount diff --git a/catalogue/search.pl b/catalogue/search.pl index a391dfe..a359c68 100755 --- a/catalogue/search.pl +++ b/catalogue/search.pl @@ -154,6 +154,7 @@ use String::Random; use C4::Branch; # GetBranches my $DisplayMultiPlaceHold = C4::Context->preference("DisplayMultiPlaceHold"); +my $PickupHoldOnlyFromItemBranches = C4::Context->preference("PickupHoldOnlyFromItemBranches"); # create a new CGI object # FIXME: no_undef_params needs to be tested use CGI qw('-no_undef_params'); @@ -578,6 +579,7 @@ for (my $i=0;$i<@servers;$i++) { $template->param(limit_desc => $limit_desc); $template->param(offset => $offset); $template->param(DisplayMultiPlaceHold => $DisplayMultiPlaceHold); + $template->param(PickupHoldOnlyFromItemBranches => $PickupHoldOnlyFromItemBranches); if ($query_desc || $limit_desc) { $template->param(searchdesc => 1); } diff --git a/circ/returns.pl b/circ/returns.pl index 93f36f2..06b21b4 100755 --- a/circ/returns.pl +++ b/circ/returns.pl @@ -58,7 +58,6 @@ if (!C4::Context->userenv){ exit; } } - #getting the template my ( $template, $librarian, $cookie ) = get_template_and_user( { @@ -140,6 +139,7 @@ if ( $query->param('resbarcode') ) { # fix up item type for display $iteminfo->{'itemtype'} = C4::Context->preference('item-level_itypes') ? $iteminfo->{'itype'} : $iteminfo->{'itemtype'}; my $diffBranchSend = ($userenv_branch ne $diffBranchReturned) ? $diffBranchReturned : undef; + SetFirstReturnedItem($iteminfo->{'homebranch'}, $item, $borrowernumber, $iteminfo->{'biblionumber'}) if $query->param('nextavailable'); # diffBranchSend tells ModReserveAffect whether document is expected in this library or not, # i.e., whether to apply waiting status ModReserveAffect( $item, $borrowernumber, $diffBranchSend); @@ -365,6 +365,11 @@ if ( $messages->{'WrongTransfer'} and not $messages->{'WasTransfered'}) { # if ( $messages->{'ResFound'}) { my $reserve = $messages->{'ResFound'}; + # If PickupHoldOnlyFromItemBranches syspref activated and next available copy had been asked + unless ( $reserve->{'branchcode'} ){ + $reserve->{'branchcode'} = GetItem($itemnumber)->{'homebranch'}; + $template->param( nextavailable => 1 ); + } my $branchname = $branches->{ $reserve->{'branchcode'} }->{'branchname'}; my ($borr) = GetMemberDetails( $reserve->{'borrowernumber'}, 0 ); diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 2e13e23..88bab9c 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -429,4 +429,5 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('yuipath','local','local|http://yui.yahooapis.com/2.5.1/build','Insert the path to YUI libraries, choose local if you use koha offline','Choice'), ('z3950AuthorAuthFields','701,702,700',NULL,'Define the MARC biblio fields for Personal Name Authorities to fill biblio.author','free'), ('z3950NormalizeAuthor','0','','If ON, Personal Name Authorities will replace authors in biblio.author','YesNo'), -('HoldOnlyWhenAllItemsOnLoan','0', 'Placing hold on a document is possible only when all items that can be reserved according to the issuing rules are on loan', NULL, 'YesNo') +('HoldOnlyWhenAllItemsOnLoan','0', 'Placing hold on a document is possible only when all items that can be reserved according to the issuing rules are on loan', NULL, 'YesNo'), +('PickupHoldOnlyFromItemBranches','0', 'Pickup location can be choosen only among the branches of the items that can be reserved', NULL, 'YesNo') diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 20a06c2..9c1f350 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -8044,6 +8044,13 @@ if (CheckVersion($DBversion) ) { SetVersion($DBversion); } +$DBversion = "3.13.00.XXX"; +if (CheckVersion($DBversion) ) { + $dbh->do("INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('PickupHoldOnlyFromItemBranches','0', 'Pickup location can be choosen only among the branches of the items that can be reserved', NULL, 'YesNo')"); + print "Upgrade to $DBversion done (Add system preference PickupHoldOnlyFromItemBranches)\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 6e265a9..5d990a0 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 @@ -440,6 +440,14 @@ Circulation: no: "Don't allow" - a user to choose the library to pick up a hold from. - + - Pickup location can be choosen + - pref: PickupHoldOnlyFromItemBranches + default: 0 + choices: + yes: "only among the branches of the items that can be reserved" + no: "unrestrictedly" + - ( works with OPACAllowUserToChooseBranch on ) + - - pref: ReservesNeedReturns choices: yes: "Don't automatically" diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt index 7bb75f8..721f23e 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt @@ -311,7 +311,7 @@ var holdForPatron = function () { Highlight | - [% IF ( CAN_user_reserveforothers && DisplayMultiPlaceHold ) %] + [% IF ( CAN_user_reserveforothers && DisplayMultiPlaceHold && !PickupHoldOnlyFromItemBranches ) %] [% IF ( holdfor ) %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt index aee0a5e..f3f7fcb 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt @@ -107,6 +107,7 @@ $(document).ready(function () { + [% IF ( nextavailable ) %][% END %] @@ -156,6 +157,7 @@ $(document).ready(function () { + [% IF ( nextavailable ) %][% END %]
[% END %] @@ -196,6 +198,7 @@ $(document).ready(function () { + [% IF ( nextavailable ) %][% END %] [% END %] @@ -310,6 +313,7 @@ $(document).ready(function () { + [% IF ( nextavailable ) %][% END %] [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt index b09ba03..8c3fdd7 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt @@ -92,6 +92,10 @@ function checkMultiHold() { } $(document).ready(function() { + [% IF ( PickupHoldOnlyFromItemBranches and !none_available) %] + $("#hold-request-form fieldset.action").nextAll().hide(); + $("#requestany").attr('disabled','disabled'); + [% END %] $("input.needsoverride").click(function() { // This must be before the radio button/checkbox switch logic var itemnumber = this.value; var msg = ''; @@ -323,13 +327,15 @@ function checkMultiHold() {
  • @@ -678,7 +684,7 @@ function checkMultiHold() { [% ELSE %] [% END %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt index 4f1882d..6b9b80a 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt @@ -378,12 +378,17 @@ + [% IF ( PickupHoldOnlyFromItemBranches ) %](Next available copy at the selected place)[% END %] [% END %] [% END %] @@ -422,7 +427,7 @@ [% IF ( bibitemloo.holdable ) %] - [% IF ( OPACItemHolds ) %] + [% IF ( OPACItemHolds and !PickupHoldOnlyFromItemBranches ) %]
  • @@ -463,7 +468,7 @@ [% END %] [% END %] - [% IF ( OPACItemHolds ) %] + [% IF ( OPACItemHolds and !PickupHoldOnlyFromItemBranches ) %] [% IF ( bibitemloo.holdable ) %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-user.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-user.tt index 62a852b..2bfc72a 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-user.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-user.tt @@ -390,16 +390,10 @@ var MSG_CONFIRM_RESUME_HOLDS = _("Are you sure you want to resume all suspended - - [% IF OpacHoldNotes %][% END %] - - + + [% IF OpacShowHoldNotes %][% END %] + + [% IF ( showpriority ) %] [% END %] diff --git a/opac/opac-reserve.pl b/opac/opac-reserve.pl index 6d5d46f..00b21d2 100755 --- a/opac/opac-reserve.pl +++ b/opac/opac-reserve.pl @@ -206,6 +206,8 @@ if ( $query->param('place_reserve') ) { my $itemNum = shift(@selectedItems); my $branch = shift(@selectedItems); # i.e., branch code, not name + # if no hold pickup location had been selected (syspref PickupHoldAtItemLocation on), $branch must be undef (to be recorded as NULL in branchcode field) + undef($branch) if $branch eq 'any'; my $canreserve = 0; my $singleBranchMode = C4::Context->preference("singleBranchMode"); @@ -400,6 +402,7 @@ foreach my $biblioNum (@biblionumbers) { $biblioLoopIter{itemLoop} = []; my $numCopiesAvailable = 0; + my %pickplaces; foreach my $itemInfo (@{$biblioData->{itemInfos}}) { my $itemNum = $itemInfo->{itemnumber}; my $itemLoopIter = {}; @@ -504,6 +507,7 @@ foreach my $biblioNum (@biblionumbers) { if (IsAvailableForItemLevelRequest($itemNum) and $policy_holdallowed and CanItemBeReserved($borrowernumber,$itemNum) and ($itemLoopIter->{already_reserved} ne 1)) { $itemLoopIter->{available} = 1; + $pickplaces{$itemInfo->{homebranch}}=$itemLoopIter->{homeBranchName}; $numCopiesAvailable++; } @@ -536,6 +540,12 @@ foreach my $biblioNum (@biblionumbers) { if( $biblioLoopIter{holdable} ){ $anyholdable++; } + if ( C4::Context->preference('PickupHoldOnlyFromItemBranches') ){ + my $branch; + ($pickplaces{'any'}='' and $branch eq 'any') if scalar( keys %pickplaces ) > 1; + $biblioLoopIter{branchloop} = GetBranchesPartLoop (\%pickplaces, $branch); + $template->param(PickupHoldOnlyFromItemBranches => 1); + } push @$biblioLoop, \%biblioLoopIter; } diff --git a/reserve/modrequest.pl b/reserve/modrequest.pl index 2f0b8d3..78533b5 100755 --- a/reserve/modrequest.pl +++ b/reserve/modrequest.pl @@ -46,6 +46,7 @@ my @rank = $query->param('rank-request'); my @biblionumber = $query->param('biblionumber'); my @borrower = $query->param('borrowernumber'); my @branch = $query->param('pickup'); +map { undef($_) if $_ eq 'any' } @branch; my @itemnumber = $query->param('itemnumber'); my @suspend_until=$query->param('suspend_until'); my $multi_hold = $query->param('multi_hold'); diff --git a/reserve/placerequest.pl b/reserve/placerequest.pl index 3fe459c..b0669b7 100755 --- a/reserve/placerequest.pl +++ b/reserve/placerequest.pl @@ -47,6 +47,7 @@ my $biblionumber=$input->param('biblionumber'); my $borrowernumber=$input->param('borrowernumber'); my $notes=$input->param('notes'); my $branch=$input->param('pickup'); +undef($branch) if $branch eq 'any'; my $startdate=$input->param('reserve_date') || ''; my @rank=$input->param('rank-request'); my $type=$input->param('type'); diff --git a/reserve/request.pl b/reserve/request.pl index 461af6c..75ec9fb 100755 --- a/reserve/request.pl +++ b/reserve/request.pl @@ -181,6 +181,9 @@ if ($multihold) { my $itemdata_enumchron = 0; my @biblioloop = (); my $not_all_holdable_onloan; +my %pickplaces; +my @itembrlist; +my $itembranchesloop; foreach my $biblionumber (@biblionumbers) { my %biblioloopiter = (); @@ -307,6 +310,9 @@ foreach my $biblionumber (@biblionumbers) { $item->{imageurl} = getitemtypeimagelocation( 'intranet', $itemtypes->{ $item->{itype} }{imageurl} ); $item->{homebranchname} = $branches->{ $item->{homebranch} }{branchname}; + if( !$item->{notforloan} and !$item->{lost} and !$item->{withdrawn} and !$item->{damaged} ) { + push @itembrlist, {'itemnumber' => $itemnumber,'brcode' => $item->{homebranch},'brname' => $item->{homebranchname}}; + } # if the holdingbranch is different than the homebranch, we show the # holdingbranch of the document too if ( $item->{homebranch} ne $item->{holdingbranch} ) { @@ -416,6 +422,7 @@ foreach my $biblionumber (@biblionumbers) { ) { $item->{available} = 1; + $pickplaces{$item->{'homebranch'}}=$item->{'homebranchname'}; $num_available++ unless $not_all_holdable_onloan; } elsif ( C4::Context->preference('AllowHoldPolicyOverride') ) { @@ -448,6 +455,12 @@ foreach my $biblionumber (@biblionumbers) { push @bibitemloop, $biblioitem; } + if ( C4::Context->preference('PickupHoldOnlyFromItemBranches') ){ + $template->param( PickupHoldOnlyFromItemBranches => 1 ); + $pickplaces{'any'}='' if scalar(keys %pickplaces) > 1; + %pickplaces = {} if $not_all_holdable_onloan; + $itembranchesloop = GetBranchesPartLoop(\%pickplaces); + } # existingreserves building my @reserveloop; $reserves = GetReservesFromBiblionumber({ biblionumber => $biblionumber, all_dates => 1 }); @@ -524,6 +537,17 @@ foreach my $biblionumber (@biblionumbers) { if ( C4::Context->preference('IndependentBranches') && $flags->{'superlibrarian'} != 1 ) { $reserve{'branchloop'} = [ GetBranchDetail($res->{'branchcode'}) ]; + } elsif (C4::Context->preference('PickupHoldOnlyFromItemBranches') ) { + $res->{'branchcode'}||='any'; + my %brlist; + foreach ( @itembrlist ) { + my $canreserve = CanItemBeReserved( $reserve{'borrowernumber'},$_->{'itemnumber'} ); + if ( !defined($canreserve) or $canreserve > 0 ){ # this to get the itembranch on location list even if the item is not any more on loan (return=undef) + $brlist{$_->{'brcode'}} = $_->{'brname'}; + } + } + $brlist{'any'} = '' if scalar(keys %brlist) > 1; + $reserve{'branchloop'}=GetBranchesPartLoop(\%brlist,$res->{'branchcode'}); } else { $reserve{'branchloop'} = GetBranchesLoop($res->{'branchcode'}); } @@ -535,11 +559,10 @@ foreach my $biblionumber (@biblionumbers) { my $time = time(); $template->param( - branchloop => GetBranchesLoop($userbranch), + branchloop => $itembranchesloop ? $itembranchesloop : GetBranchesLoop($userbranch), time => $time, fixedRank => $fixedRank, ); - # display infos $template->param( optionloop => \@optionloop, -- 1.7.2.5
    [% RESERVE.reserves_title %][% FOREACH subtitl IN RESERVE.subtitle %] [% subtitl.subfield %][% END %] [% RESERVE.author %] [% RESERVE.reservedate | $KohaDates %][% RESERVE.reservenotes %] - [% IF ( RESERVE.expirationdate ) %] - [% RESERVE.expirationdate | $KohaDates %] - [% ELSE %] - Never expires - [% END %] - [% RESERVE.branch %][% RESERVE.reservedate | $KohaDates %]][% RESERVE.reservenotes %][% IF ( RESERVE.expirationdate ) %][% RESERVE.expirationdate | $KohaDates %][% ELSE %]Never expires[% END %][% IF ( RESERVE.branch ) %][% RESERVE.branch %][% ELSE %]Location of next available copy[% END %][% RESERVE.priority %]