@@ -, +, @@ you should not be able to ( default is 1 per record ) you should be able to place 3 holds for one patron on a given record. A 4th hold should result in a message stating the patron has placed the max number of holds allowed on this record. --- C4/Reserves.pm | 59 ++++++++++++-------- installer/data/mysql/sysprefs.sql | 1 + installer/data/mysql/updatedatabase.pl | 6 ++ .../en/modules/admin/preferences/circulation.pref | 7 ++- .../prog/en/modules/reserve/request.tt | 25 ++++---- .../opac-tmpl/prog/en/modules/opac-reserve.tt | 6 ++- opac/opac-reserve.pl | 29 ++++++---- reserve/request.pl | 9 +++- 8 files changed, 92 insertions(+), 50 deletions(-) --- a/C4/Reserves.pm +++ a/C4/Reserves.pm @@ -373,36 +373,47 @@ sub GetReservesFromItemnumber { =head2 GetReservesFromBorrowernumber - $borrowerreserv = GetReservesFromBorrowernumber($borrowernumber,$tatus); - -TODO :: Descritpion + $borrowerreserv = GetReservesFromBorrowernumber($borrowernumber[,$status][,$biblionumber][,$itemnumber]); =cut sub GetReservesFromBorrowernumber { - my ( $borrowernumber, $status ) = @_; - my $dbh = C4::Context->dbh; - my $sth; - if ($status) { - $sth = $dbh->prepare(" - SELECT * - FROM reserves - WHERE borrowernumber=? - AND found =? - ORDER BY reservedate - "); - $sth->execute($borrowernumber,$status); - } else { - $sth = $dbh->prepare(" - SELECT * - FROM reserves - WHERE borrowernumber=? - ORDER BY reservedate - "); - $sth->execute($borrowernumber); + my ( $borrowernumber, $found, $biblionumber, $itemnumber ) = @_; + + my @params; + + my $sql = "SELECT * FROM reserves WHERE borrowernumber = ?"; + push( @params, $borrowernumber ); + + if ( $biblionumber ) { + $sql .= " AND biblionumber = ? "; + push( @params, $biblionumber ); + } + + if ( $itemnumber ) { + $sql .= " AND itemnumber = ? "; + push( @params, $itemnumber ); + } + + if ( $found ) { + $sql .= " AND found = ? "; + push( @params, $found ); } + + $sql .= " ORDER BY reservedate "; + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare( $sql ); + + $sth->execute( @params ); + my $data = $sth->fetchall_arrayref({}); - return @$data; + + if ( scalar @$data ) { + return @$data; + } else { + return (); + } } #------------------------------------------------------------------------------------- =head2 CanBookBeReserved --- a/installer/data/mysql/sysprefs.sql +++ a/installer/data/mysql/sysprefs.sql @@ -423,3 +423,4 @@ INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ( INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES('DisplayIconsXSLT', '1', '', 'If ON, displays the format, audience, and material type icons in XSLT MARC21 results and detail pages.', 'YesNo'); INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('HighlightOwnItemsOnOPAC','0','','If on, and a patron is logged into the OPAC, items from his or her home library will be emphasized and shown first in search results and item details.','YesNo'); INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('HighlightOwnItemsOnOPACWhich','PatronBranch','PatronBranch|OpacURLBranch','Decides which branch''s items to emphasize. If PatronBranch, emphasize the logged in user''s library''s items. If OpacURLBranch, highlight the items of the Apache var BRANCHCODE defined in Koha''s Apache configuration file.','Choice') +INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('MaxHoldsPerRecord', '1', 'The maximum number of holds allowed per bibliographic record per borrower', NULL, NULL); --- a/installer/data/mysql/updatedatabase.pl +++ a/installer/data/mysql/updatedatabase.pl @@ -6771,6 +6771,12 @@ if ( CheckVersion($DBversion) ) { SetVersion ($DBversion); } +$DBversion = "3.11.00.XXX"; +if (C4::Context->preference("Version") < TransformToNum($DBversion)) { + $dbh->do("INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES ('MaxHoldsPerRecord', '1', 'The maximum number of holds allowed per bibliographic record per borrower', NULL, NULL)"); + print "Upgrade to $DBversion done (Add syspref MaxHoldsPerRecord)\n"; + SetVersion ($DBversion); +} =head1 FUNCTIONS --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -404,7 +404,12 @@ Circulation: - Patrons can only have - pref: maxreserves class: integer - - holds at once. + - total holds at a time. + - + - Patrons can only place + - pref: MaxHoldsPerRecord + class: integer + - holds on a single record at a time. - - pref: emailLibrarianWhenHoldIsPlaced choices: --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt @@ -55,7 +55,7 @@ function check() { } if (alreadyreserved > "0"){ - msg += (_("- This patron had already placed a hold on this item") + "\n" + _("Please cancel the previous hold first") + "\n"); + msg += (_("This patron has already placed the maximum number of holds for this record.") + "\n\n" + _("Please cancel a previous hold first.") + "\n"); } if (msg == "") return(true); @@ -208,7 +208,7 @@ function checkMultiHold() {
  • Too Many Holds: [% borrowerfirstname %] [% borrowersurname %] has too many holds.
  • [% END %] [% IF ( alreadyreserved ) %] -
  • [% borrowerfirstname %] [% borrowersurname %] already has a hold on this item
  • +
  • [% borrowerfirstname %] [% borrowersurname %] has already placed the maximum allowed number of holds on this record
  • [% END %] [% IF ( none_available ) %]
  • No copies are available to be placed on hold
  • @@ -564,6 +564,7 @@ function checkMultiHold() { [% FOREACH reserveloo IN biblioloo.reserveloop %] [% UNLESS ( loop.odd ) %][% ELSE %][% END %] + + [% IF AutoResumeSuspendedHolds %] - - - Clear Date + + + Clear Date [% END %] [% ELSE %] --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt +++ a/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt @@ -296,7 +296,11 @@ [% IF ( bibitemloo.already_patron_possession ) %]
    This title cannot be requested because it's already in your possession.
    [% ELSE %] -
    This title cannot be requested.
    + [% IF bibitemloo.max_holds %] +
    This title cannot be requested. You have already placed the maximum number of requests allowed for this title.
    + [% ELSE %] +
    This title cannot be requested.
    + [% END %] [% END %] [% END %] [% END %] --- a/opac/opac-reserve.pl +++ a/opac/opac-reserve.pl @@ -37,7 +37,8 @@ use C4::Debug; use Koha::DateUtils; # use Data::Dumper; -my $MAXIMUM_NUMBER_OF_RESERVES = C4::Context->preference("maxreserves"); +my $maxreserves = C4::Context->preference("maxreserves"); +my $max_holds_per_record = C4::Context->preference('MaxHoldsPerRecord'); my $query = new CGI; my ( $template, $borrowernumber, $cookie ) = get_template_and_user( @@ -172,7 +173,7 @@ foreach my $biblioNumber (@biblionumbers) { if ( $query->param('place_reserve') ) { my $notes = $query->param('notes'); my $reserve_cnt = 0; - if ($MAXIMUM_NUMBER_OF_RESERVES) { + if ($maxreserves) { $reserve_cnt = GetReservesFromBorrowernumber( $borrowernumber ); } @@ -255,8 +256,8 @@ if ( $query->param('place_reserve') ) { $itemNum = undef; } - if ( $MAXIMUM_NUMBER_OF_RESERVES - && $reserve_cnt >= $MAXIMUM_NUMBER_OF_RESERVES ) + if ( $maxreserves + && $reserve_cnt >= $maxreserves ) { $canreserve = 0; } @@ -317,7 +318,7 @@ if ( CheckBorrowerDebarred($borrowernumber) ) { my @reserves = GetReservesFromBorrowernumber( $borrowernumber ); $template->param( RESERVES => \@reserves ); -if ( $MAXIMUM_NUMBER_OF_RESERVES && (scalar(@reserves) >= $MAXIMUM_NUMBER_OF_RESERVES) ) { +if ( $maxreserves && (scalar(@reserves) >= $maxreserves) ) { $template->param( message => 1 ); $noreserves = 1; $template->param( too_many_reserves => scalar(@reserves)); @@ -325,12 +326,10 @@ if ( $MAXIMUM_NUMBER_OF_RESERVES && (scalar(@reserves) >= $MAXIMUM_NUMBER_OF_RES 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; + $biblioDataHash{$biblionumber}->{holds_count}++; } } + } unless ($noreserves) { @@ -372,7 +371,7 @@ foreach my $biblioNum (@biblionumbers) { $biblioLoopIter{author} = $biblioData->{author}; $biblioLoopIter{rank} = $biblioData->{rank}; $biblioLoopIter{reservecount} = $biblioData->{reservecount}; - $biblioLoopIter{already_reserved} = $biblioData->{already_reserved}; + $biblioLoopIter{holds_count} = $biblioData->{holds_count}; if (!$itemLevelTypes && $biblioData->{itemtype}) { $biblioLoopIter{description} = $itemTypes->{$biblioData->{itemtype}}{description}; @@ -499,11 +498,14 @@ foreach my $biblioNum (@biblionumbers) { $policy_holdallowed = 0; } - if (IsAvailableForItemLevelRequest($itemNum) and $policy_holdallowed and CanItemBeReserved($borrowernumber,$itemNum) and ($itemLoopIter->{already_reserved} ne 1)) { + if (IsAvailableForItemLevelRequest($itemNum) and $policy_holdallowed and CanItemBeReserved($borrowernumber,$itemNum) and ($itemLoopIter->{holds_count} < $max_holds_per_record )) { $itemLoopIter->{available} = 1; $numCopiesAvailable++; } + # Don't allow multiple item level holds on the same item if borrowers can place multiple holds on one bib + $itemLoopIter->{available} = 0 if ( GetReservesFromBorrowernumber( $borrowernumber, undef, undef, $itemNum ) ); + # FIXME: move this to a pm my $dbh = C4::Context->dbh; my $sth2 = $dbh->prepare("SELECT * FROM reserves WHERE borrowernumber=? AND itemnumber=? AND found='W'"); @@ -532,6 +534,11 @@ foreach my $biblioNum (@biblionumbers) { $biblioLoopIter{holdable} = undef; $anyholdable = undef; } + if ($biblioLoopIter{holds_count} >= $max_holds_per_record) { + $biblioLoopIter{holdable} = undef; + $anyholdable = undef; + $biblioLoopIter{max_holds} = 1; + } if(not CanBookBeReserved($borrowernumber,$biblioNum)){ $biblioLoopIter{holdable} = undef; $anyholdable = undef; --- a/reserve/request.pl +++ a/reserve/request.pl @@ -209,6 +209,7 @@ if ($borrowerslist) { # FIXME launch another time GetMember perhaps until my $borrowerinfo = GetMember( borrowernumber => $borrowernumber_hold ); +my $max_holds_per_record = C4::Context->preference('MaxHoldsPerRecord'); my @biblionumbers = (); my $biblionumbers = $input->param('biblionumbers'); @@ -254,7 +255,7 @@ foreach my $biblionumber (@biblionumbers) { } } - if ( $holds_count ) { + if ( $holds_count >= $max_holds_per_record ) { $alreadyreserved = 1; $warnings = 1; $biblioloopiter{warn} = 1; @@ -482,6 +483,12 @@ foreach my $biblionumber (@biblionumbers) { $itemdata_enumchron = 1; } + # Don't allow multiple item level holds on the same item if borrowers can place multiple holds on one bib + if ( GetReservesFromBorrowernumber( $borrowerinfo->{borrowernumber}, undef, undef, $itemnumber) ) { + $item->{available} = 0; + $item->{override} = 0; + } + push @{ $biblioitem->{itemloop} }, $item; } --