From 47690dbcc440612a18ca2b870b3045e308915f5c Mon Sep 17 00:00:00 2001 From: Stephen Edwards Date: Thu, 23 Apr 2009 12:45:54 -0400 Subject: [PATCH] bug 3093: Enhance placing of holds in the staff interface. This patch allows staff users to request reserves on multiple items at one time. Added checkboxes, select-all, clear-all, and place-hold button to staff search results page. Place-hold button will only appear if the user has permission to place holds for others. Item-level Place-Hold button will not appear for multiple holds, nor will the vertical detail menu. Patron input page now shows multiple items, if applicable. Hold confirmation page shows results for multiple items, if applicable. Those which cannot be reserved are highlighted and are excluded from the reservation. The reservation is placed at the biblio number (i.e. next available) level. Fixed display of item type. Removed side menu for multiple items; removed item-oriented button for multiple items. Signed-off-by: Galen Charlton --- .../prog/en/modules/catalogue/results.tmpl | 89 ++- .../prog/en/modules/reserve/request.tmpl | 282 ++++++-- .../virtualshelves/addbybiblionumber.tmpl | 39 +- .../en/modules/virtualshelves/shelves.tmpl | 38 +- reserve/modrequest.pl | 10 +- reserve/placerequest.pl | 85 ++- reserve/request.pl | 627 ++++++++++-------- virtualshelves/addbybiblionumber.pl | 97 ++- 8 files changed, 843 insertions(+), 424 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tmpl index abaf52e775..5c4e4c5ff7 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tmpl +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tmpl @@ -1,8 +1,11 @@ Koha › Catalog › <!-- TMPL_IF NAME="searchdesc" -->Results of Search <!-- TMPL_IF NAME="query_desc" -->for '<!-- TMPL_VAR NAME="query_desc" -->'<!-- /TMPL_IF --><!-- TMPL_IF NAME="limit_desc" --> with limit(s): '<!-- TMPL_VAR NAME="limit_desc" -->'<!-- /TMPL_IF --><!-- TMPL_ELSE -->You did not specify any search criteria<!-- /TMPL_IF --> - + +$(document).ready(function() { + $("#selection_ops").show(); + $(".selection").show(); +}); +function selectAll () { + $(".selection").attr("checked", "checked"); +} +function clearAll () { + $(".selection").removeAttr("checked"); +} +function placeHold () { + var checkedItems = $(".selection:checked"); + if ($(checkedItems).size() == 0) { + alert(MSG_NO_ITEM_SELECTED); + return false; + } + var bibs = ""; + var badBibs = false; + $(checkedItems).each(function() { + var bib = $(this).val(); + if ($("#reserve_" + bib).size() == 0) { + alert(MSG_NON_RESERVES_SELECTED); + badBibs = true; + return false; + } + bibs += bib + "/"; + }); + if (badBibs) { + return false; + } + $("#hold_form_biblios").val(bibs); + $("#hold_form").submit(); + return false; +} +function addToList () { + var checkedItems = $(".selection:checked"); + if ($(checkedItems).size() == 0) { + alert(MSG_NO_ITEM_SELECTED); + return false; + } + var bibs = ""; + $(checkedItems).each(function() { + bibs += $(this).val() + "/"; + }); + + var url = "/cgi-bin/koha/virtualshelves/addbybiblionumber.pl?biblionumbers=" + bibs; + window.open(url, 'Add_to_virtualshelf', 'width=500, height=400, toolbar=false, scrollbars=yes'); + return false; +} +//]]> + @@ -79,6 +132,15 @@ $(window).load(function() {

result(s) found for '' with limit(s): '' in Catalog.
 

+

Ignored the following common words: ""

@@ -205,7 +267,7 @@ $(window).load(function() { - + @@ -218,6 +280,9 @@ $(window).load(function() { http://images.amazon.com/images/P/.01.TZZZZZZZ.jpghttp://g-images.amazon.com/images/G/01/x-site/icons/no-img-sm.gif" alt="image" class="thumbnail" /> + @@ -377,6 +442,18 @@ $(window).load(function() { + + + + + + + + + + + +
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tmpl index be254eaeb0..ce8e5cb169 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tmpl +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tmpl @@ -1,5 +1,9 @@ -Koha › Circulation › Holds › Place a hold on <!-- TMPL_VAR NAME="title" escape="html" --> + + Koha › Circulation › Holds › Place a hold on <!-- TMPL_VAR NAME="title" escape="html" --> + + Koha › Circulation › Holds › Confirm Holds + @@ -107,7 +125,12 @@ $(document).ready(function(){
Contents of -

+ +

+ + +

+
 ResultsResults Location
+ " style="display:none" /> +

. @@ -287,7 +352,7 @@ $(window).load(function() { No holds allowed - ">Holds + " href="/cgi-bin/koha/reserve/request.pl?biblionumber=">Holds

@@ -128,9 +151,9 @@ $(document).ready(function(){ @@ -162,6 +185,7 @@ $(document).ready(function(){
+
@@ -379,6 +403,12 @@ $(document).ready(function(){ + + + + + + diff --git a/reserve/modrequest.pl b/reserve/modrequest.pl index a88b67c115..3b66623886 100755 --- a/reserve/modrequest.pl +++ b/reserve/modrequest.pl @@ -46,6 +46,8 @@ my @biblionumber=$query->param('biblionumber'); my @borrower=$query->param('borrowernumber'); my @branch=$query->param('pickup'); my @itemnumber=$query->param('itemnumber'); +my $multi_hold = $query->param('multi_hold'); +my $biblionumbers = $query->param('biblionumbers'); my $count=@rank; my $CancelBiblioNumber=$query->param('CancelBiblioNumber'); @@ -71,5 +73,11 @@ my $from=$query->param('from'); if ($from eq 'borrower'){ print $query->redirect("/cgi-bin/koha/members/moremember.pl?borrowernumber=$borrower[0]"); } else { - print $query->redirect("/cgi-bin/koha/reserve/request.pl?biblionumber=$biblionumber[0]"); + my $url = "/cgi-bin/koha/reserve/request.pl?"; + if ($multi_hold) { + $url .= "multi_hold=1&biblionumbers=$biblionumbers"; + } else { + $url .= "biblionumber=$biblionumber[0]"; + } + print $query->redirect($url); } diff --git a/reserve/placerequest.pl b/reserve/placerequest.pl index 96fdb7cf63..355b5b63ec 100755 --- a/reserve/placerequest.pl +++ b/reserve/placerequest.pl @@ -34,6 +34,7 @@ use C4::Members; my $input = new CGI; #print $input->header; + my @bibitems=$input->param('biblioitem'); # FIXME I think reqbib does not exist anymore, it's used in line 82, to AddReserve of contraint type 'o' # I bet it's a 2.x feature, reserving a given biblioitem, that is useless in Koha 3.0 @@ -49,9 +50,24 @@ my $type=$input->param('type'); my $title=$input->param('title'); my $borrowernumber=GetMember($borrower,'cardnumber'); my $checkitem=$input->param('checkitem'); + +my $multi_hold = $input->param('multi_hold'); +my $biblionumbers = $multi_hold ? $input->param('biblionumbers') : ($biblionumber . '/'); +my $bad_bibs = $input->param('bad_bibs'); + +my %bibinfos = (); +my @biblionumbers = split '/', $biblionumbers; +foreach my $bibnum (@biblionumbers) { + my %bibinfo = (); + $bibinfo{title} = $input->param("title_$bibnum"); + $bibinfo{rank} = $input->param("rank_$bibnum"); + $bibinfos{$bibnum} = \%bibinfo; +} + my $found; -#if we have an item selectionned, and the pickup branch is the same as the holdingbranch of the document, we force the value $rank and $found . +# if we have an item selectionned, and the pickup branch is the same as the holdingbranch +# of the document, we force the value $rank and $found . if ($checkitem ne ''){ $rank[0] = '0' unless C4::Context->preference('ReservesNeedReturns'); my $item = $checkitem; @@ -62,31 +78,48 @@ if ($checkitem ne ''){ } if ($type eq 'str8' && $borrowernumber ne ''){ - my $count=@bibitems; - @bibitems=sort @bibitems; - my $i2=1; - my @realbi; - $realbi[0]=$bibitems[0]; - for (my $i=1;$i<$count;$i++) { - my $i3=$i2-1; - if ($realbi[$i3] ne $bibitems[$i]) { - $realbi[$i2]=$bibitems[$i]; - $i2++; - } - } - my $const; - if ($input->param('request') eq 'any'){ - # place a request on 1st available - AddReserve($branch,$borrowernumber->{'borrowernumber'},$biblionumber,'a',\@realbi,$rank[0],$notes,$title,$checkitem,$found); - } elsif ($reqbib[0] ne ''){ - # FIXME : elsif probably never reached, (see top of the script) - # place a request on a given item - AddReserve($branch,$borrowernumber->{'borrowernumber'},$biblionumber,'o',\@reqbib,$rank[0],$notes,$title,$checkitem, $found); - } else { - AddReserve($branch,$borrowernumber->{'borrowernumber'},$biblionumber,'a',\@realbi,$rank[0],$notes,$title,$checkitem, $found); - } - -print $input->redirect("request.pl?biblionumber=$biblionumber"); + + foreach my $biblionumber (keys %bibinfos) { + my $count=@bibitems; + @bibitems=sort @bibitems; + my $i2=1; + my @realbi; + $realbi[0]=$bibitems[0]; + for (my $i=1;$i<$count;$i++) { + my $i3=$i2-1; + if ($realbi[$i3] ne $bibitems[$i]) { + $realbi[$i2]=$bibitems[$i]; + $i2++; + } + } + my $const; + + if ($multi_hold) { + my $bibinfo = $bibinfos{$biblionumber}; + AddReserve($branch,$borrowernumber->{'borrowernumber'},$biblionumber,'a',[$biblionumber], + $bibinfo->{rank},$notes,$bibinfo->{title},$checkitem,$found); + } else { + if ($input->param('request') eq 'any'){ + # place a request on 1st available + AddReserve($branch,$borrowernumber->{'borrowernumber'},$biblionumber,'a',\@realbi,$rank[0],$notes,$title,$checkitem,$found); + } elsif ($reqbib[0] ne ''){ + # FIXME : elsif probably never reached, (see top of the script) + # place a request on a given item + AddReserve($branch,$borrowernumber->{'borrowernumber'},$biblionumber,'o',\@reqbib,$rank[0],$notes,$title,$checkitem, $found); + } else { + AddReserve($branch,$borrowernumber->{'borrowernumber'},$biblionumber,'a',\@realbi,$rank[0],$notes,$title,$checkitem, $found); + } + } + } + + if ($multi_hold) { + if ($bad_bibs) { + $biblionumbers .= $bad_bibs; + } + print $input->redirect("request.pl?biblionumbers=$biblionumbers&multi_hold=1"); + } else { + print $input->redirect("request.pl?biblionumber=$biblionumber"); + } } elsif ($borrowernumber eq ''){ print $input->header(); print "Invalid card number please try again"; diff --git a/reserve/request.pl b/reserve/request.pl index fbe1a789f4..496962f5b4 100755 --- a/reserve/request.pl +++ b/reserve/request.pl @@ -54,13 +54,30 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user( } ); +my $multihold = $input->param('multi_hold'); +$template->param(multi_hold => $multihold); + # get Branches and Itemtypes my $branches = GetBranches(); my $itemtypes = GetItemTypes(); - -# get biblio information.... -my $biblionumber = $input->param('biblionumber'); -my $dat = GetBiblioData($biblionumber); + +my $default = C4::Context->userenv->{branch}; +my @values; +my %label_of; + +foreach my $branchcode (sort keys %{$branches} ) { + push @values, $branchcode; + $label_of{$branchcode} = $branches->{$branchcode}->{branchname}; +} +my $CGIbranch = CGI::scrolling_list( + -name => 'pickup', + -id => 'pickup', + -values => \@values, + -default => $default, + -labels => \%label_of, + -size => 1, + -multiple => 0, + ); # Select borrowers infos my $findborrower = $input->param('findborrower'); @@ -181,321 +198,355 @@ if ($borrowerslist) { ); } -# get existing reserves ..... -my ( $count, $reserves ) = GetReservesFromBiblionumber($biblionumber); -my $totalcount = $count; -my $alreadyreserved; - # FIXME launch another time GetMemberDetails perhaps until my $borrowerinfo = GetMemberDetails( 0, $cardnumber ); -foreach my $res (@$reserves) { - if ( ( $res->{found} eq 'W' ) ) { - $count--; - } - - if ( $borrowerinfo->{borrowernumber} eq $res->{borrowernumber} ) { - $warnings = 1; - $alreadyreserved = 1; - } -} - -$template->param( alreadyreserved => $alreadyreserved, - messages => $messages, - warnings => $warnings ); - -# FIXME think @optionloop, is maybe obsolete, or must be switchable by a systeme preference fixed rank or not -# make priorities options - -my @optionloop; -for ( 1 .. $count + 1 ) { - push( - @optionloop, - { - num => $_, - selected => ( $_ == $count + 1 ), - } - ); -} -# adding a fixed value for priority options -my $fixedRank = $count+1; - -my @branchcodes; -my %itemnumbers_of_biblioitem; -my @itemnumbers; - -if (my $items = get_itemnumbers_of($biblionumber)->{$biblionumber}){ - @itemnumbers = @$items; -} -else { - $template->param('noitems' => 1); -} - -my $iteminfos_of = GetItemInfosOf(@itemnumbers); - -foreach my $itemnumber (@itemnumbers) { - my $biblioitemnumber = $iteminfos_of->{$itemnumber}->{biblioitemnumber}; - push( @{ $itemnumbers_of_biblioitem{$biblioitemnumber} }, $itemnumber ); +my @biblionumbers = (); +my $biblionumbers = $input->param('biblionumbers'); +if ($multihold) { + @biblionumbers = split '/', $biblionumbers; +} else { + push @biblionumbers, $input->param('biblionumber'); } -my @biblioitemnumbers = keys %itemnumbers_of_biblioitem; - -my $notforloan_label_of = get_notforloan_label_of(); -my $biblioiteminfos_of = GetBiblioItemInfosOf(@biblioitemnumbers); - -my @bibitemloop; +my @biblioloop = (); +foreach my $biblionumber (@biblionumbers) { -foreach my $biblioitemnumber (@biblioitemnumbers) { - my $biblioitem = $biblioiteminfos_of->{$biblioitemnumber}; - my $num_available; - my $num_override; + my %biblioloopiter = (); - $biblioitem->{description} = - $itemtypes->{ $biblioitem->{itemtype} }{description}; + my $dat = GetBiblioData($biblionumber); - foreach my $itemnumber ( @{ $itemnumbers_of_biblioitem{$biblioitemnumber} } ) { - my $item = $iteminfos_of->{$itemnumber}; + # get existing reserves ..... + my ( $count, $reserves ) = GetReservesFromBiblionumber($biblionumber); + my $totalcount = $count; + my $alreadyreserved; - unless (C4::Context->preference('item-level_itypes')) { - $item->{itype} = $biblioitem->{itemtype}; + foreach my $res (@$reserves) { + if ( ( $res->{found} eq 'W' ) ) { + $count--; } - $item->{itypename} = $itemtypes->{ $item->{itype} }{description}; - $item->{imageurl} = getitemtypeimagelocation( 'intranet', $itemtypes->{ $item->{itype} }{imageurl} ); - $item->{homebranchname} = $branches->{ $item->{homebranch} }{branchname}; - - # if the holdingbranch is different than the homebranch, we show the - # holdingbranch of the document too - if ( $item->{homebranch} ne $item->{holdingbranch} ) { - $item->{holdingbranchname} = - $branches->{ $item->{holdingbranch} }{branchname}; + if ( $borrowerinfo->{borrowernumber} eq $res->{borrowernumber} ) { + $warnings = 1; + $alreadyreserved = 1; + $biblioloopiter{warn} = 1; + $biblioloopiter{alreadyres} = 1; } - - # 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); - if ( $issues->{'date_due'} ) { - $item->{date_due} = format_date($issues->{'date_due'}); - $item->{backgroundcolor} = 'onloan'; - } - - # checking reserve - my ($reservedate,$reservedfor,$expectedAt) = GetReservesFromItemnumber($itemnumber); - my $ItemBorrowerReserveInfo = GetMemberDetails( $reservedfor, 0); - - if ( defined $reservedate ) { - $item->{backgroundcolor} = 'reserved'; - $item->{reservedate} = format_date($reservedate); - $item->{ReservedForBorrowernumber} = $reservedfor; - $item->{ReservedForSurname} = $ItemBorrowerReserveInfo->{'surname'}; - $item->{ReservedForFirstname} = $ItemBorrowerReserveInfo->{'firstname'}; - $item->{ExpectedAtLibrary} = $branches->{$expectedAt}{branchname}; - - } - - # Management of the notforloan document - if ( $item->{notforloan} ) { - $item->{backgroundcolor} = 'other'; - $item->{notforloanvalue} = - $notforloan_label_of->{ $item->{notforloan} }; - } - - # Management of lost or long overdue items - if ( $item->{itemlost} ) { - - # FIXME localized strings should never be in Perl code - $item->{message} = - $item->{itemlost} == 1 ? "(lost)" - : $item->{itemlost} == 2 ? "(long overdue)" - : ""; - $item->{backgroundcolor} = 'other'; - } - - # Check the transit status - my ( $transfertwhen, $transfertfrom, $transfertto ) = - GetTransfers($itemnumber); + } - if ( $transfertwhen ne '' ) { - $item->{transfertwhen} = format_date($transfertwhen); - $item->{transfertfrom} = - $branches->{$transfertfrom}{branchname}; - $item->{transfertto} = $branches->{$transfertto}{branchname}; - $item->{nocancel} = 1; - } + $template->param( alreadyreserved => $alreadyreserved, + messages => $messages, + warnings => $warnings ); + + + # FIXME think @optionloop, is maybe obsolete, or must be switchable by a systeme preference fixed rank or not + # make priorities options + + my @optionloop; + for ( 1 .. $count + 1 ) { + push( + @optionloop, + { + num => $_, + selected => ( $_ == $count + 1 ), + } + ); + } + # adding a fixed value for priority options + my $fixedRank = $count+1; - # If there is no loan, return and transfer, we show a checkbox. - $item->{notforloan} = $item->{notforloan} || 0; + my @branchcodes; + my %itemnumbers_of_biblioitem; + my @itemnumbers; - # if independent branches is on we need to check if the person can reserve - # for branches they arent logged in to - if ( C4::Context->preference("IndependantBranches") ) { - if (! C4::Context->preference("canreservefromotherbranches")){ - # cant reserve items so need to check if item homebranch and userenv branch match if not we cant reserve - my $userenv = C4::Context->userenv; - if ( ($userenv) && ( $userenv->{flags} != 1 ) ) { - $item->{cantreserve} = 1 if ( $item->{homebranch} ne $userenv->{branch} ); + ## $items is array of 'item' table numbers + if (my $items = get_itemnumbers_of($biblionumber)->{$biblionumber}){ + @itemnumbers = @$items; + } + else { + $template->param('noitems' => 1); + $biblioloopiter{noitems} = 1; + } + + ## Hash of item number to 'item' table fields + my $iteminfos_of = GetItemInfosOf(@itemnumbers); + + ## Here we go backwards again to create hash of biblioitemnumber to itemnumbers, + ## when by definition all of the itemnumber have the same biblioitemnumber + foreach my $itemnumber (@itemnumbers) { + my $biblioitemnumber = $iteminfos_of->{$itemnumber}->{biblioitemnumber}; + push( @{ $itemnumbers_of_biblioitem{$biblioitemnumber} }, $itemnumber ); + } + + ## Should be same as biblionumber + my @biblioitemnumbers = keys %itemnumbers_of_biblioitem; + + my $notforloan_label_of = get_notforloan_label_of(); + + ## Hash of biblioitemnumber to 'biblioitem' table records + my $biblioiteminfos_of = GetBiblioItemInfosOf(@biblioitemnumbers); + + my @bibitemloop; + + foreach my $biblioitemnumber (@biblioitemnumbers) { + my $biblioitem = $biblioiteminfos_of->{$biblioitemnumber}; + my $num_available; + my $num_override; + + $biblioitem->{description} = + $itemtypes->{ $biblioitem->{itemtype} }{description}; + $biblioloopiter{description} = $biblioitem->{description}; + $biblioloopiter{itypename} = $biblioitem->{description}; + $biblioloopiter{imageurl} = + getitemtypeimagelocation('intranet', $itemtypes->{$biblioitem->{itemtype}}{imageurl}); + + foreach my $itemnumber ( @{ $itemnumbers_of_biblioitem{$biblioitemnumber} } ) { + my $item = $iteminfos_of->{$itemnumber}; + + unless (C4::Context->preference('item-level_itypes')) { + $item->{itype} = $biblioitem->{itemtype}; + } + + $item->{itypename} = $itemtypes->{ $item->{itype} }{description}; + $item->{imageurl} = getitemtypeimagelocation( 'intranet', $itemtypes->{ $item->{itype} }{imageurl} ); + $item->{homebranchname} = $branches->{ $item->{homebranch} }{branchname}; + + # if the holdingbranch is different than the homebranch, we show the + # holdingbranch of the document too + if ( $item->{homebranch} ne $item->{holdingbranch} ) { + $item->{holdingbranchname} = + $branches->{ $item->{holdingbranch} }{branchname}; + } + + # 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); + if ( $issues->{'date_due'} ) { + $item->{date_due} = format_date($issues->{'date_due'}); + $item->{backgroundcolor} = 'onloan'; + } + + # checking reserve + my ($reservedate,$reservedfor,$expectedAt) = GetReservesFromItemnumber($itemnumber); + my $ItemBorrowerReserveInfo = GetMemberDetails( $reservedfor, 0); + + if ( defined $reservedate ) { + $item->{backgroundcolor} = 'reserved'; + $item->{reservedate} = format_date($reservedate); + $item->{ReservedForBorrowernumber} = $reservedfor; + $item->{ReservedForSurname} = $ItemBorrowerReserveInfo->{'surname'}; + $item->{ReservedForFirstname} = $ItemBorrowerReserveInfo->{'firstname'}; + $item->{ExpectedAtLibrary} = $branches->{$expectedAt}{branchname}; + + } + + # Management of the notforloan document + if ( $item->{notforloan} ) { + $item->{backgroundcolor} = 'other'; + $item->{notforloanvalue} = + $notforloan_label_of->{ $item->{notforloan} }; + } + + # Management of lost or long overdue items + if ( $item->{itemlost} ) { + + # FIXME localized strings should never be in Perl code + $item->{message} = + $item->{itemlost} == 1 ? "(lost)" + : $item->{itemlost} == 2 ? "(long overdue)" + : ""; + $item->{backgroundcolor} = 'other'; + } + + # Check the transit status + my ( $transfertwhen, $transfertfrom, $transfertto ) = + GetTransfers($itemnumber); + + if ( $transfertwhen ne '' ) { + $item->{transfertwhen} = format_date($transfertwhen); + $item->{transfertfrom} = + $branches->{$transfertfrom}{branchname}; + $item->{transfertto} = $branches->{$transfertto}{branchname}; + $item->{nocancel} = 1; + } + + # If there is no loan, return and transfer, we show a checkbox. + $item->{notforloan} = $item->{notforloan} || 0; + + # if independent branches is on we need to check if the person can reserve + # for branches they arent logged in to + if ( C4::Context->preference("IndependantBranches") ) { + if (! C4::Context->preference("canreservefromotherbranches")){ + # cant reserve items so need to check if item homebranch and userenv branch match if not we cant reserve + my $userenv = C4::Context->userenv; + if ( ($userenv) && ( $userenv->{flags} != 1 ) ) { + $item->{cantreserve} = 1 if ( $item->{homebranch} ne $userenv->{branch} ); + } } } - } - - my $branchitemrule = GetBranchItemRule( $item->{'homebranch'}, $item->{'itype'} ); - my $policy_holdallowed = 1; - - $item->{'holdallowed'} = $branchitemrule->{'holdallowed'}; - - if ( $branchitemrule->{'holdallowed'} == 0 || - ( $branchitemrule->{'holdallowed'} == 1 && $borrowerinfo->{'branchcode'} ne $item->{'homebranch'} ) ) { - $policy_holdallowed = 0; - } - - if (IsAvailableForItemLevelRequest($itemnumber) and not $item->{cantreserve}) { - if ( not $policy_holdallowed and C4::Context->preference( 'AllowHoldPolicyOverride' ) ) { - $item->{override} = 1; - $num_override++; - } elsif ( $policy_holdallowed ) { - $item->{available} = 1; - $num_available++; + + my $branchitemrule = GetBranchItemRule( $item->{'homebranch'}, $item->{'itype'} ); + my $policy_holdallowed = 1; + + $item->{'holdallowed'} = $branchitemrule->{'holdallowed'}; + + if ( $branchitemrule->{'holdallowed'} == 0 || + ( $branchitemrule->{'holdallowed'} == 1 && $borrowerinfo->{'branchcode'} ne $item->{'homebranch'} ) ) { + $policy_holdallowed = 0; + } + + if (IsAvailableForItemLevelRequest($itemnumber) and not $item->{cantreserve}) { + if ( not $policy_holdallowed and C4::Context->preference( 'AllowHoldPolicyOverride' ) ) { + $item->{override} = 1; + $num_override++; + } elsif ( $policy_holdallowed ) { + $item->{available} = 1; + $num_available++; + } + } + # If none of the conditions hold true, then neither override nor available is set and the item cannot be checked + + # FIXME: move this to a pm + my $sth2 = $dbh->prepare("SELECT * FROM reserves WHERE borrowernumber=? AND itemnumber=? AND found='W'"); + $sth2->execute($item->{ReservedForBorrowernumber},$item->{itemnumber}); + while (my $wait_hashref = $sth2->fetchrow_hashref) { + $item->{waitingdate} = format_date($wait_hashref->{waitingdate}); } + push @{ $biblioitem->{itemloop} }, $item; } - # If none of the conditions hold true, then neither override nor available is set and the item cannot be checked - - # FIXME: move this to a pm - my $sth2 = $dbh->prepare("SELECT * FROM reserves WHERE borrowernumber=? AND itemnumber=? AND found='W'"); - $sth2->execute($item->{ReservedForBorrowernumber},$item->{itemnumber}); - while (my $wait_hashref = $sth2->fetchrow_hashref) { - $item->{waitingdate} = format_date($wait_hashref->{waitingdate}); + + if ( $num_override == scalar( @{ $biblioitem->{itemloop} } ) ) { # That is, if all items require an override + $template->param( override_required => 1 ); + } elsif ( $num_available == 0 ) { + $template->param( none_available => 1 ); + $template->param( warnings => 1 ); + $biblioloopiter{warn} = 1; + $biblioloopiter{none_avail} = 1; } - push @{ $biblioitem->{itemloop} }, $item; - } - - if ( $num_override == scalar( @{ $biblioitem->{itemloop} } ) ) { # That is, if all items require an override - $template->param( override_required => 1 ); - } elsif ( $num_available == 0 ) { - $template->param( none_available => 1 ); - $template->param( warnings => 1 ); - } - - push @bibitemloop, $biblioitem; -} - -# existingreserves building -my @reserveloop; -( $count, $reserves ) = GetReservesFromBiblionumber($biblionumber); -foreach my $res ( sort { $a->{found} cmp $b->{found} } @$reserves ) { - my %reserve; - my @optionloop; - for ( my $i = 1 ; $i <= $totalcount ; $i++ ) { - push( - @optionloop, - { - num => $i, - selected => ( $i == $res->{priority} ), - } - ); - } - my @branchloop; - foreach my $br ( keys %$branches ) { - my %abranch; - $abranch{'selected'} = ( $br eq $res->{'branchcode'} ); - $abranch{'branch'} = $br; - $abranch{'branchname'} = $branches->{$br}->{'branchname'}; - push( @branchloop, \%abranch ); + + push @bibitemloop, $biblioitem; } - if ( ( $res->{'found'} eq 'W' ) ) { - my $item = $res->{'itemnumber'}; - $item = GetBiblioFromItemNumber($item,undef); - $reserve{'wait'}= 1; - $reserve{'holdingbranch'}=$item->{'holdingbranch'}; - $reserve{'biblionumber'}=$item->{'biblionumber'}; - $reserve{'barcodenumber'} = $item->{'barcode'}; - $reserve{'wbrcode'} = $res->{'branchcode'}; - $reserve{'itemnumber'} = $res->{'itemnumber'}; - $reserve{'wbrname'} = $branches->{$res->{'branchcode'}}->{'branchname'}; - if($reserve{'holdingbranch'} eq $reserve{'wbrcode'}){ - $reserve{'atdestination'} = 1; + # existingreserves building + my @reserveloop; + ( $count, $reserves ) = GetReservesFromBiblionumber($biblionumber); + foreach my $res ( sort { $a->{found} cmp $b->{found} } @$reserves ) { + my %reserve; + my @optionloop; + for ( my $i = 1 ; $i <= $totalcount ; $i++ ) { + push( + @optionloop, + { + num => $i, + selected => ( $i == $res->{priority} ), + } + ); } - # set found to 1 if reserve is waiting for patron pickup - $reserve{'found'} = 1 if $res->{'found'} eq 'W'; - } elsif ($res->{priority} > 0) { - if (defined($res->{itemnumber})) { - my $item = GetItem($res->{itemnumber}); - $reserve{'itemnumber'} = $res->{'itemnumber'}; + my @branchloop; + foreach my $br ( keys %$branches ) { + my %abranch; + $abranch{'selected'} = ( $br eq $res->{'branchcode'} ); + $abranch{'branch'} = $br; + $abranch{'branchname'} = $branches->{$br}->{'branchname'}; + push( @branchloop, \%abranch ); + } + + if ( ( $res->{'found'} eq 'W' ) ) { + my $item = $res->{'itemnumber'}; + $item = GetBiblioFromItemNumber($item,undef); + $reserve{'wait'}= 1; + $reserve{'holdingbranch'}=$item->{'holdingbranch'}; + $reserve{'biblionumber'}=$item->{'biblionumber'}; $reserve{'barcodenumber'} = $item->{'barcode'}; - $reserve{'item_level_hold'} = 1; + $reserve{'wbrcode'} = $res->{'branchcode'}; + $reserve{'itemnumber'} = $res->{'itemnumber'}; + $reserve{'wbrname'} = $branches->{$res->{'branchcode'}}->{'branchname'}; + if($reserve{'holdingbranch'} eq $reserve{'wbrcode'}){ + $reserve{'atdestination'} = 1; + } + # set found to 1 if reserve is waiting for patron pickup + $reserve{'found'} = 1 if $res->{'found'} eq 'W'; + } elsif ($res->{priority} > 0) { + if (defined($res->{itemnumber})) { + my $item = GetItem($res->{itemnumber}); + $reserve{'itemnumber'} = $res->{'itemnumber'}; + $reserve{'barcodenumber'} = $item->{'barcode'}; + $reserve{'item_level_hold'} = 1; + } } + + # get borrowers reserve info + my $reserveborrowerinfo = GetMemberDetails( $res->{'borrowernumber'}, 0); + + $reserve{'date'} = format_date( $res->{'reservedate'} ); + $reserve{'borrowernumber'} = $res->{'borrowernumber'}; + $reserve{'biblionumber'} = $res->{'biblionumber'}; + $reserve{'borrowernumber'} = $res->{'borrowernumber'}; + $reserve{'firstname'} = $reserveborrowerinfo->{'firstname'}; + $reserve{'surname'} = $reserveborrowerinfo->{'surname'}; + $reserve{'notes'} = $res->{'reservenotes'}; + $reserve{'wait'} = + ( ( $res->{'found'} eq 'W' ) or ( $res->{'priority'} eq '0' ) ); + $reserve{'constrainttypea'} = ( $res->{'constrainttype'} eq 'a' ); + $reserve{'constrainttypeo'} = ( $res->{'constrainttype'} eq 'o' ); + $reserve{'voldesc'} = $res->{'volumeddesc'}; + $reserve{'ccode'} = $res->{'ccode'}; + $reserve{'barcode'} = $res->{'barcode'}; + $reserve{'priority'} = $res->{'priority'}; + $reserve{'branchloop'} = \@branchloop; + $reserve{'optionloop'} = \@optionloop; + + push( @reserveloop, \%reserve ); } -# get borrowers reserve info -my $reserveborrowerinfo = GetMemberDetails( $res->{'borrowernumber'}, 0); - - $reserve{'date'} = format_date( $res->{'reservedate'} ); - $reserve{'borrowernumber'} = $res->{'borrowernumber'}; - $reserve{'biblionumber'} = $res->{'biblionumber'}; - $reserve{'borrowernumber'} = $res->{'borrowernumber'}; - $reserve{'firstname'} = $reserveborrowerinfo->{'firstname'}; - $reserve{'surname'} = $reserveborrowerinfo->{'surname'}; - $reserve{'notes'} = $res->{'reservenotes'}; - $reserve{'wait'} = - ( ( $res->{'found'} eq 'W' ) or ( $res->{'priority'} eq '0' ) ); - $reserve{'constrainttypea'} = ( $res->{'constrainttype'} eq 'a' ); - $reserve{'constrainttypeo'} = ( $res->{'constrainttype'} eq 'o' ); - $reserve{'voldesc'} = $res->{'volumeddesc'}; - $reserve{'ccode'} = $res->{'ccode'}; - $reserve{'barcode'} = $res->{'barcode'}; - $reserve{'priority'} = $res->{'priority'}; - $reserve{'branchloop'} = \@branchloop; - $reserve{'optionloop'} = \@optionloop; - - push( @reserveloop, \%reserve ); -} + # get the time for the form name... + my $time = time(); + + $template->param( + CGIbranch => $CGIbranch, -my $default = C4::Context->userenv->{branch}; -my @values; -my %label_of; + time => $time, + fixedRank => $fixedRank, + ); + + # display infos + $template->param( + optionloop => \@optionloop, + bibitemloop => \@bibitemloop, + date => $date, + biblionumber => $biblionumber, + findborrower => $findborrower, + cardnumber => $cardnumber, + CGIselectborrower => $CGIselectborrower, + title => $dat->{title}, + author => $dat->{author}, + holdsview => 1, + borrower_branchname => $branches->{$borrowerinfo->{'branchcode'}}->{'branchname'}, + borrower_branchcode => $borrowerinfo->{'branchcode'}, + ); + + $biblioloopiter{biblionumber} = $biblionumber; + $biblioloopiter{title} = $dat->{title}; + $biblioloopiter{rank} = $fixedRank; + $biblioloopiter{reserveloop} = \@reserveloop; + + if (@reserveloop) { + $template->param( reserveloop => \@reserveloop ); + } + -foreach my $branchcode (sort keys %{$branches} ) { - push @values, $branchcode; - $label_of{$branchcode} = $branches->{$branchcode}->{branchname}; + push @biblioloop, \%biblioloopiter; } -my $CGIbranch = CGI::scrolling_list( - -name => 'pickup', - -id => 'pickup', - -values => \@values, - -default => $default, - -labels => \%label_of, - -size => 1, - -multiple => 0, -); - -# get the time for the form name... -my $time = time(); - -$template->param( - CGIbranch => $CGIbranch, - reserveloop => \@reserveloop, - time => $time, - fixedRank => $fixedRank, -); -# display infos -$template->param( - optionloop => \@optionloop, - bibitemloop => \@bibitemloop, - date => $date, - biblionumber => $biblionumber, - findborrower => $findborrower, - cardnumber => $cardnumber, - CGIselectborrower => $CGIselectborrower, - title => $dat->{title}, - author => $dat->{author}, - holdsview => 1, - borrower_branchname => $branches->{$borrowerinfo->{'branchcode'}}->{'branchname'}, - borrower_branchcode => $borrowerinfo->{'branchcode'}, -); +$template->param( biblioloop => \@biblioloop ); +$template->param( biblionumbers => $biblionumbers ); +if ($multihold) { + $template->param( multi_hold => 1 ); +} + # printout the page output_html_with_http_headers $input, $cookie, $template->output; diff --git a/virtualshelves/addbybiblionumber.pl b/virtualshelves/addbybiblionumber.pl index b19e7da4f8..d565493d62 100755 --- a/virtualshelves/addbybiblionumber.pl +++ b/virtualshelves/addbybiblionumber.pl @@ -67,7 +67,13 @@ use CGI::Carp qw/fatalsToBrowser/; use warnings; my $query = new CGI; + +# If set, then single item case. my $biblionumber = $query->param('biblionumber'); + +# If set, then multiple item case. +my $biblionumbers = $query->param('biblionumbers'); + my $shelfnumber = $query->param('shelfnumber'); my $newvirtualshelf = $query->param('newvirtualshelf'); my $category = $query->param('category'); @@ -83,50 +89,79 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( } ); +my @biblionumbers; +if ($biblionumbers) { + @biblionumbers = split '/', $biblionumbers; +} else { + @biblionumbers = ($biblionumber); +} + $shelfnumber = AddShelf( $newvirtualshelf, $loggedinuser, $category, $sortfield ) if $newvirtualshelf; if ( $shelfnumber || ( $shelfnumber == -1 ) ) { # the shelf already exist. - AddToShelfFromBiblio( $biblionumber, $shelfnumber ); + foreach my $biblionumber (@biblionumbers) { + AddToShelfFromBiblio( $biblionumber, $shelfnumber ); + } print "Content-Type: text/html\n\n"; exit; } else { # this shelf doesn't already exist. - my ( $bibliocount, @biblios ) = GetBiblio($biblionumber); - - my $limit = 10; - my ($shelflist) = GetRecentShelves(1, $limit, $loggedinuser); + my $limit = 10; + my ($shelflist) = GetRecentShelves(1, $limit, $loggedinuser); my @shelvesloop; my %shelvesloop; for my $shelf ( @{ $shelflist->[0] } ) { push( @shelvesloop, $shelf->{shelfnumber} ); - $shelvesloop{$shelf->{shelfnumber}} = $shelf->{shelfname}; - } - # then open shelves... - my ($shelflist) = GetRecentShelves(3, $limit, undef); + $shelvesloop{$shelf->{shelfnumber}} = $shelf->{shelfname}; + } + # then open shelves... + my ($shelflist) = GetRecentShelves(3, $limit, undef); for my $shelf ( @{ $shelflist->[0] } ) { push( @shelvesloop, $shelf->{shelfnumber} ); - $shelvesloop{$shelf->{shelfnumber}} = $shelf->{shelfname}; - } - if(@shelvesloop gt 0){ - my $CGIvirtualshelves = CGI::scrolling_list( - -name => 'shelfnumber', - -values => \@shelvesloop, - -labels => \%shelvesloop, - -size => 1, - -tabindex => '', - -multiple => 0 - ); - $template->param( - CGIvirtualshelves => $CGIvirtualshelves, - ); - } - - $template->param( - biblionumber => $biblionumber, - title => $biblios[0]->{'title'}, - author => $biblios[0]->{'author'}, - ); - + $shelvesloop{$shelf->{shelfnumber}} = $shelf->{shelfname}; + } + if(@shelvesloop gt 0){ + my $CGIvirtualshelves = CGI::scrolling_list + ( + -name => 'shelfnumber', + -values => \@shelvesloop, + -labels => \%shelvesloop, + -size => 1, + -tabindex => '', + -multiple => 0 + ); + $template->param + ( + CGIvirtualshelves => $CGIvirtualshelves, + ); + } + + unless ($biblionumbers) { + my ( $bibliocount, @biblios ) = GetBiblio($biblionumber); + + $template->param + ( + biblionumber => $biblionumber, + title => $biblios[0]->{'title'}, + author => $biblios[0]->{'author'}, + ); + } else { + my @biblioloop = (); + foreach my $biblionumber (@biblionumbers) { + my ( $bibliocount, @biblios ) = GetBiblio($biblionumber); + my %biblioiter = ( + title=>$biblios[0]->{'title'}, + author=>$biblios[0]->{'author'} + ); + push @biblioloop, \%biblioiter; + } + $template->param + ( + biblioloop => \@biblioloop, + biblionumbers => $biblionumbers + ); + } + output_html_with_http_headers $query, $cookie, $template->output; } -- 2.39.5
" /> - " checked /> + " name="REM-" checked /> - " /> + " name="REM-" />