X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=opac%2Fopac-reserve.pl;h=f1fe2ffbb68c709a517a32145ab9c36f213112e2;hb=7afddcb157a8d8e27cfdee3cdbeb0eae483aa24c;hp=6c381f36c9afe65e89dd0d60e78d19d78466a805;hpb=e20270fec4f6d34f01050bea4c5765d5b3c4ed33;p=koha.git diff --git a/opac/opac-reserve.pl b/opac/opac-reserve.pl index 6c381f36c9..f1fe2ffbb6 100755 --- a/opac/opac-reserve.pl +++ b/opac/opac-reserve.pl @@ -5,21 +5,21 @@ # # This file is part of Koha. # -# Koha is free software; you can redistribute it and/or modify it under the -# terms of the GNU General Public License as published by the Free Software -# Foundation; either version 2 of the License, or (at your option) any later -# version. +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. # -# Koha is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # -# You should have received a copy of the GNU General Public License along -# with Koha; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; -use strict; -use warnings; use CGI qw ( -utf8 ); use C4::Auth; # checkauth, getborrowernumber. use C4::Koha; @@ -28,27 +28,32 @@ use C4::Reserves; use C4::Biblio; use C4::Items; use C4::Output; -use C4::Dates qw/format_date/; use C4::Context; use C4::Members; -use C4::Branch; # GetBranches use C4::Overdues; use C4::Debug; use Koha::DateUtils; -use Koha::Borrower::Debarments qw(IsDebarred); +use Koha::Libraries; +use Koha::Patrons; use Date::Calc qw/Today Date_to_Days/; -# use Data::Dumper; +use List::MoreUtils qw/uniq/; my $maxreserves = C4::Context->preference("maxreserves"); my $query = new CGI; + +# if RequestOnOpac (for placing holds) is disabled, leave immediately +if ( ! C4::Context->preference('RequestOnOpac') ) { + print $query->redirect("/cgi-bin/koha/errors/404.pl"); + exit; +} + my ( $template, $borrowernumber, $cookie ) = get_template_and_user( { template_name => "opac-reserve.tt", query => $query, type => "opac", authnotrequired => 0, - flagsrequired => { borrow => 1 }, debug => 1, } ); @@ -65,12 +70,13 @@ sub get_out { } # get borrower information .... -my ( $borr ) = GetMemberDetails( $borrowernumber ); +my ( $borr ) = GetMember( borrowernumber => $borrowernumber ); +my $patron = Koha::Patrons->find( $borrowernumber ); # check if this user can place a reserve, -1 means use sys pref, 0 means dont block, 1 means block -if ( $borr->{'BlockExpiredPatronOpacActions'} ) { +if ( $patron->category->effective_BlockExpiredPatronOpacActions ) { - if ( $borr->{'is_expired'} ) { + if ( $patron->is_expired ) { # cannot reserve, their card has expired and the rules set mean this is not allowed $template->param( message => 1, expired_patron => 1 ); @@ -79,11 +85,11 @@ if ( $borr->{'BlockExpiredPatronOpacActions'} ) { } # Pass through any reserve charge -if ($borr->{reservefee} > 0){ - $template->param( RESERVE_CHARGE => sprintf("%.2f",$borr->{reservefee})); +my $reservefee = $patron->category->reservefee; +if ( $reservefee > 0){ + $template->param( RESERVE_CHARGE => sprintf("%.2f",$reservefee)); } -# get branches and itemtypes -my $branches = GetBranches(); + my $itemTypes = GetItemTypes(); # There are two ways of calling this script, with a single biblio num @@ -118,12 +124,8 @@ if (($#biblionumbers < 0) && (! $query->param('place_reserve'))) { # pass the pickup branch along.... my $branch = $query->param('branch') || $borr->{'branchcode'} || C4::Context->userenv->{branch} || '' ; -($branches->{$branch}) or $branch = ""; # Confirm branch is real $template->param( branch => $branch ); -# make branch selection options... -my $branchloop = GetBranchesLoop($branch); - # Is the person allowed to choose their branch my $OPACChooseBranch = (C4::Context->preference("OPACAllowUserToChooseBranch")) ? 1 : 0; @@ -215,6 +217,7 @@ if ( $query->param('place_reserve') ) { &get_out($query, $cookie, $template->output); } + my $failed_holds = 0; while (@selectedItems) { my $biblioNum = shift(@selectedItems); my $itemNum = shift(@selectedItems); @@ -222,7 +225,7 @@ if ( $query->param('place_reserve') ) { my $canreserve = 0; - my $singleBranchMode = C4::Context->preference("singleBranchMode"); + my $singleBranchMode = Koha::Libraries->search->count == 1; if ( $singleBranchMode || !$OPACChooseBranch ) { # single branch mode or disabled user choosing $branch = $borr->{'branchcode'}; @@ -275,21 +278,23 @@ if ( $query->param('place_reserve') ) { $canreserve = 0; } + my $itemtype = $query->param('itemtype') || undef; + $itemtype = undef if $itemNum; + # Here we actually do the reserveration. Stage 3. if ($canreserve) { - AddReserve( - $branch, $borrowernumber, - $biblioNum, 'a', - [$biblioNum], $rank, - $startdate, $expiration_date, - $notes, $biblioData->{title}, - $itemNum, $found + my $reserve_id = AddReserve( + $branch, $borrowernumber, $biblioNum, + [$biblioNum], $rank, $startdate, + $expiration_date, $notes, $biblioData->{title}, + $itemNum, $found, $itemtype, ); + $failed_holds++ unless $reserve_id; ++$reserve_cnt; } } - print $query->redirect("/cgi-bin/koha/opac-user.pl#opac-user-holds"); + print $query->redirect("/cgi-bin/koha/opac-user.pl?" . ( $failed_holds ? "failed_holds=$failed_holds" : q|| ) . "#opac-user-holds"); exit; } @@ -301,12 +306,14 @@ if ( $query->param('place_reserve') ) { my $noreserves = 0; my $maxoutstanding = C4::Context->preference("maxoutstanding"); $template->param( noreserve => 1 ) unless $maxoutstanding; -if ( $borr->{'amountoutstanding'} && ($borr->{'amountoutstanding'} > $maxoutstanding) ) { - my $amount = sprintf "%.02f", $borr->{'amountoutstanding'}; +my ( $amountoutstanding ) = GetMemberAccountRecords($borrowernumber); +if ( $amountoutstanding && ($amountoutstanding > $maxoutstanding) ) { + my $amount = sprintf "%.02f", $amountoutstanding; $template->param( message => 1 ); $noreserves = 1; $template->param( too_much_oweing => $amount ); } + if ( $borr->{gonenoaddress} && ($borr->{gonenoaddress} == 1) ) { $noreserves = 1; $template->param( @@ -314,6 +321,7 @@ if ( $borr->{gonenoaddress} && ($borr->{gonenoaddress} == 1) ) { GNA => 1 ); } + if ( $borr->{lost} && ($borr->{lost} == 1) ) { $noreserves = 1; $template->param( @@ -321,11 +329,14 @@ if ( $borr->{lost} && ($borr->{lost} == 1) ) { lost => 1 ); } -if ( IsDebarred($borrowernumber) ) { + +if ( Koha::Patrons->find( $borrowernumber )->is_debarred ) { $noreserves = 1; $template->param( - message => 1, - debarred => 1 + message => 1, + debarred => 1, + debarred_comment => $borr->{debarredcomment}, + debarred_date => $borr->{debarred}, ); } @@ -345,17 +356,6 @@ unless ( $noreserves ) { } } -foreach my $res (@reserves) { - foreach my $biblionumber (@biblionumbers) { - if ( $res->{'biblionumber'} == $biblionumber && $res->{'borrowernumber'} == $borrowernumber) { -# $template->param( message => 1 ); -# $noreserves = 1; -# $template->param( already_reserved => 1 ); - $biblioDataHash{$biblionumber}->{already_reserved} = 1; - } - } -} - unless ($noreserves) { $template->param( select_item_types => 1 ); } @@ -380,7 +380,7 @@ foreach my $biblioNum (@biblionumbers) { my $record = GetMarcBiblio($biblioNum); # Init the bib item with the choices for branch pickup - my %biblioLoopIter = ( branchloop => $branchloop ); + my %biblioLoopIter; # Get relevant biblio data. my $biblioData = $biblioDataHash{$biblioNum}; @@ -399,20 +399,13 @@ foreach my $biblioNum (@biblionumbers) { $biblioLoopIter{mandatorynotes}=0; #FIXME: For future use if (!$itemLevelTypes && $biblioData->{itemtype}) { - $biblioLoopIter{description} = $itemTypes->{$biblioData->{itemtype}}{description}; + $biblioLoopIter{translated_description} = $itemTypes->{$biblioData->{itemtype}}{translated_description}; $biblioLoopIter{imageurl} = getitemtypeimagesrc() . "/". $itemTypes->{$biblioData->{itemtype}}{imageurl}; } foreach my $itemInfo (@{$biblioData->{itemInfos}}) { - $debug and warn $itemInfo->{'notforloan'}; - - # Get reserve fee. - my $fee = GetReserveFee(undef, $borrowernumber, $itemInfo->{'biblionumber'}, 'a', - ( $itemInfo->{'biblioitemnumber'} ) ); - $itemInfo->{'reservefee'} = sprintf "%.02f", ($fee ? $fee : 0.0); - if ($itemLevelTypes && $itemInfo->{itype}) { - $itemInfo->{description} = $itemTypes->{$itemInfo->{itype}}{description}; + $itemInfo->{translated_description} = $itemTypes->{$itemInfo->{itype}}{translated_description}; $itemInfo->{imageurl} = getitemtypeimagesrc() . "/". $itemTypes->{$itemInfo->{itype}}{imageurl}; } @@ -423,26 +416,27 @@ foreach my $biblioNum (@biblionumbers) { $biblioLoopIter{itemLoop} = []; my $numCopiesAvailable = 0; + my $numCopiesOPACAvailable = 0; foreach my $itemInfo (@{$biblioData->{itemInfos}}) { my $itemNum = $itemInfo->{itemnumber}; my $itemLoopIter = {}; $itemLoopIter->{itemnumber} = $itemNum; $itemLoopIter->{barcode} = $itemInfo->{barcode}; - $itemLoopIter->{homeBranchName} = $branches->{$itemInfo->{homebranch}}{branchname}; + $itemLoopIter->{homeBranchName} = $itemInfo->{homebranch}; $itemLoopIter->{callNumber} = $itemInfo->{itemcallnumber}; $itemLoopIter->{enumchron} = $itemInfo->{enumchron}; $itemLoopIter->{copynumber} = $itemInfo->{copynumber}; if ($itemLevelTypes) { - $itemLoopIter->{description} = $itemInfo->{description}; + $itemLoopIter->{translated_description} = $itemInfo->{translated_description}; + $itemLoopIter->{itype} = $itemInfo->{itype}; $itemLoopIter->{imageurl} = $itemInfo->{imageurl}; } # If the holdingbranch is different than the homebranch, we show the # holdingbranch of the document too. if ( $itemInfo->{homebranch} ne $itemInfo->{holdingbranch} ) { - $itemLoopIter->{holdingBranchName} = - $branches->{ $itemInfo->{holdingbranch} }{branchname}; + $itemLoopIter->{holdingBranchName} = $itemInfo->{holdingbranch}; } # If the item is currently on loan, we display its return date and @@ -455,16 +449,14 @@ foreach my $biblioNum (@biblionumbers) { # checking reserve my ($reservedate,$reservedfor,$expectedAt,undef,$wait) = GetReservesFromItemnumber($itemNum); - my $ItemBorrowerReserveInfo = GetMemberDetails( $reservedfor, 0); + my $ItemBorrowerReserveInfo = GetMember( borrowernumber => $reservedfor ); # the item could be reserved for this borrower vi a host record, flag this - if ($reservedfor eq $borrowernumber){ - $itemLoopIter->{already_reserved} = 1; - } + $reservedfor //= ''; if ( defined $reservedate ) { $itemLoopIter->{backgroundcolor} = 'reserved'; - $itemLoopIter->{reservedate} = format_date($reservedate); + $itemLoopIter->{reservedate} = output_pref({ dt => dt_from_string($reservedate), dateonly => 1 }); $itemLoopIter->{ReservedForBorrowernumber} = $reservedfor; $itemLoopIter->{ReservedForSurname} = $ItemBorrowerReserveInfo->{'surname'}; $itemLoopIter->{ReservedForFirstname} = $ItemBorrowerReserveInfo->{'firstname'}; @@ -498,35 +490,35 @@ foreach my $biblioNum (@biblionumbers) { my ( $transfertwhen, $transfertfrom, $transfertto ) = GetTransfers($itemNum); if ( $transfertwhen && ($transfertwhen ne '') ) { - $itemLoopIter->{transfertwhen} = format_date($transfertwhen); - $itemLoopIter->{transfertfrom} = - $branches->{$transfertfrom}{branchname}; - $itemLoopIter->{transfertto} = $branches->{$transfertto}{branchname}; + $itemLoopIter->{transfertwhen} = output_pref({ dt => dt_from_string($transfertwhen), dateonly => 1 }); + $itemLoopIter->{transfertfrom} = $transfertfrom; + $itemLoopIter->{transfertto} = $transfertto; $itemLoopIter->{nocancel} = 1; } - # if the items belongs to a host record, show link to host record - if ($itemInfo->{biblionumber} ne $biblioNum){ - $biblioLoopIter{hostitemsflag} = 1; - $itemLoopIter->{hostbiblionumber} = $itemInfo->{biblionumber}; - $itemLoopIter->{hosttitle} = GetBiblioData($itemInfo->{biblionumber})->{title}; - } + # if the items belongs to a host record, show link to host record + if ( $itemInfo->{biblionumber} ne $biblioNum ) { + $biblioLoopIter{hostitemsflag} = 1; + $itemLoopIter->{hostbiblionumber} = $itemInfo->{biblionumber}; + $itemLoopIter->{hosttitle} = GetBiblioData( $itemInfo->{biblionumber} )->{title}; + } # If there is no loan, return and transfer, we show a checkbox. $itemLoopIter->{notforloan} = $itemLoopIter->{notforloan} || 0; 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}; + $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)) { - $itemLoopIter->{available} = 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,25 +537,43 @@ 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'; + + # For multiple holds per record, if a patron has previously placed a hold, + # the patron can only place more holds of the same type. That is, if the + # patron placed a record level hold, all the holds the patron places must + # be record level. If the patron placed an item level hold, all holds + # the patron places must be item level + my $forced_hold_level = Koha::Holds->search( + { + borrowernumber => $borrowernumber, + biblionumber => $biblioNum, + found => undef, + } + )->forced_hold_level(); + if ($forced_hold_level) { + $biblioLoopIter{force_hold} = 1 if $forced_hold_level eq 'item'; + $biblioLoopIter{itemholdable} = 0 if $forced_hold_level eq 'record'; + } + push @$biblioLoop, \%biblioLoopIter; + + $anyholdable = 1 if $biblioLoopIter{holdable}; } + if ( $numBibsAvailable == 0 || $anyholdable == 0) { $template->param( none_available => 1 ); } @@ -573,8 +583,6 @@ $template->param(OpacHoldNotes=>$show_notes); # display infos $template->param(bibitemloop => $biblioLoop); -$template->param( showholds=>$show_holds_count); -$template->param( showpriority=>$show_priority); # can set reserve date in future if ( C4::Context->preference( 'AllowHoldDateInFuture' ) && @@ -585,5 +593,4 @@ if ( ); } -output_html_with_http_headers $query, $cookie, $template->output; - +output_html_with_http_headers $query, $cookie, $template->output, undef, { force_no_caching => 1 };