X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=C4%2FReserves.pm;h=4af8a8584c8481bbb711e9b5b9700bc3fe471f8c;hb=f21577986f8ff5da5fde88deaae2302a8b40dbe7;hp=65b97dd3e6f5f4070b061129960452fd89550a16;hpb=6241d54c52b9ad1e8f1117b260cbbc86c4d37faa;p=koha_fer diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 65b97dd3e6..4af8a8584c 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -2,7 +2,8 @@ package C4::Reserves; # Copyright 2000-2002 Katipo Communications # 2006 SAN Ouest Provence -# 2007 BibLibre Paul POULAIN +# 2007-2010 BibLibre Paul POULAIN +# 2011 Catalyst IT # # This file is part of Koha. # @@ -26,7 +27,6 @@ use C4::Context; use C4::Biblio; use C4::Members; use C4::Items; -use C4::Search; use C4::Circulation; use C4::Accounts; @@ -50,14 +50,15 @@ C4::Reserves - Koha functions for dealing with reservation. =head1 DESCRIPTION - this modules provides somes functions to deal with reservations. - +This modules provides somes functions to deal with reservations. + Reserves are stored in reserves table. The following columns contains important values : - priority >0 : then the reserve is at 1st stage, and not yet affected to any item. =0 : then the reserve is being dealed - found : NULL : means the patron requested the 1st available, and we haven't choosen the item - W(aiting) : the reserve has an itemnumber affected, and is on the way + T(ransit) : the reserve is linked to an item but is in transit to the pickup branch + W(aiting) : the reserve is linked to an item, is at the pickup branch, and is waiting on the hold shelf F(inished) : the reserve has been completed, and is done - itemnumber : empty : the reserve is still unaffected to an item filled: the reserve is attached to an item @@ -67,27 +68,25 @@ C4::Reserves - Koha functions for dealing with reservation. a library having it run "transfertodo", and clic on the list if there is no transfer to do, the reserve waiting patron can pick it up P =0, F=W, I=filled - if there is a transfer to do, write in branchtransfer P =0, F=NULL, I=filled + if there is a transfer to do, write in branchtransfer P =0, F=T, I=filled The pickup library recieve the book, it check in P =0, F=W, I=filled The patron borrow the book P =0, F=F, I=filled ==== 2nd use case ==== patron requests a document, a given item, If pickup is holding branch P =0, F=W, I=filled - If transfer needed, write in branchtransfer P =0, F=NULL, I=filled - The pickup library recieve the book, it checks it in P =0, F=W, I=filled + If transfer needed, write in branchtransfer P =0, F=T, I=filled + The pickup library receive the book, it checks it in P =0, F=W, I=filled The patron borrow the book P =0, F=F, I=filled - -=head1 FUNCTIONS -=over 2 +=head1 FUNCTIONS =cut BEGIN { # set the version for version checking $VERSION = 3.01; - require Exporter; + require Exporter; @ISA = qw(Exporter); @EXPORT = qw( &AddReserve @@ -122,9 +121,10 @@ BEGIN { &AlterPriority &ToggleLowestPriority ); + @EXPORT_OK = qw( MergeHolds ); } -=item AddReserve +=head2 AddReserve AddReserve($branch,$borrowernumber,$biblionumber,$constraint,$bibitems,$priority,$resdate,$expdate,$notes,$title,$checkitem,$found) @@ -195,7 +195,9 @@ sub AddReserve { my $borrower = C4::Members::GetMember(borrowernumber => $borrowernumber); my $biblio = GetBiblioData($biblionumber); my $letter = C4::Letters::getletter( 'reserves', 'HOLDPLACED'); - my $admin_email_address = C4::Context->preference('KohaAdminEmailAddress'); + my $branchcode = $borrower->{branchcode}; + my $branch_details = C4::Branch::GetBranchDetail($branchcode); + my $admin_email_address =$branch_details->{'branchemail'} || C4::Context->preference('KohaAdminEmailAddress'); my %keys = (%$borrower, %$biblio); foreach my $key (keys %keys) { @@ -233,9 +235,9 @@ sub AddReserve { return; # FIXME: why not have a useful return value? } -=item GetReservesFromBiblionumber +=head2 GetReservesFromBiblionumber -($count, $title_reserves) = &GetReserves($biblionumber); + ($count, $title_reserves) = &GetReserves($biblionumber); This function gets the list of reservations for one C<$biblionumber>, returning a count of the reserves and an arrayref pointing to the reserves for C<$biblionumber>. @@ -313,11 +315,11 @@ sub GetReservesFromBiblionumber { return ( $#results + 1, \@results ); } -=item GetReservesFromItemnumber +=head2 GetReservesFromItemnumber ( $reservedate, $borrowernumber, $branchcode ) = GetReservesFromItemnumber($itemnumber); - TODO :: Description here +TODO :: Description here =cut @@ -338,12 +340,12 @@ sub GetReservesFromItemnumber { return ( $reservedate, $borrowernumber, $branchcode ); } -=item GetReservesFromBorrowernumber +=head2 GetReservesFromBorrowernumber $borrowerreserv = GetReservesFromBorrowernumber($borrowernumber,$tatus); - - TODO :: Descritpion - + +TODO :: Descritpion + =cut sub GetReservesFromBorrowernumber { @@ -372,92 +374,33 @@ sub GetReservesFromBorrowernumber { return @$data; } #------------------------------------------------------------------------------------- -=item CanBookBeReserved +=head2 CanBookBeReserved -$error = &CanBookBeReserved($borrowernumber, $biblionumber) + $error = &CanBookBeReserved($borrowernumber, $biblionumber) =cut sub CanBookBeReserved{ my ($borrowernumber, $biblionumber) = @_; - my $dbh = C4::Context->dbh; - my $biblio = GetBiblioData($biblionumber); - my $borrower = C4::Members::GetMember(borrowernumber=>$borrowernumber); - my $controlbranch = C4::Context->preference('ReservesControlBranch'); - my $itype = C4::Context->preference('item-level_itypes'); - my $reservesrights= 0; - my $reservescount = 0; - - # we retrieve the user rights - my @args; - my $rightsquery = "SELECT categorycode, itemtype, branchcode, reservesallowed - FROM issuingrules - WHERE categorycode IN (?, '*')"; - push @args,$borrower->{categorycode}; - - if($controlbranch eq "ItemHomeLibrary"){ - $rightsquery .= " AND branchcode = '*'"; - }elsif($controlbranch eq "PatronLibrary"){ - $rightsquery .= " AND branchcode IN (?,'*')"; - push @args, $borrower->{branchcode}; + my @items = get_itemnumbers_of($biblionumber); + #get items linked via host records + my @hostitems = get_hostitemnumbers_of($biblionumber); + if (@hostitems){ + push (@items,@hostitems); } - - if(not $itype){ - $rightsquery .= " AND itemtype IN (?,'*')"; - push @args, $biblio->{itemtype}; - }else{ - $rightsquery .= " AND itemtype = '*'"; - } - - $rightsquery .= " ORDER BY categorycode DESC, itemtype DESC, branchcode DESC"; - my $sthrights = $dbh->prepare($rightsquery); - $sthrights->execute(@args); - - if(my $row = $sthrights->fetchrow_hashref()){ - $reservesrights = $row->{reservesallowed}; - } - - @args = (); - # we count how many reserves the borrower have - my $countquery = "SELECT count(*) as count - FROM reserves - LEFT JOIN items USING (itemnumber) - LEFT JOIN biblioitems ON (reserves.biblionumber=biblioitems.biblionumber) - LEFT JOIN borrowers USING (borrowernumber) - WHERE borrowernumber = ? - "; - push @args, $borrowernumber; - - if(not $itype){ - $countquery .= "AND itemtype = ?"; - push @args, $biblio->{itemtype}; - } - - if($controlbranch eq "PatronLibrary"){ - $countquery .= " AND borrowers.branchcode = ? "; - push @args, $borrower->{branchcode}; - } - - my $sthcount = $dbh->prepare($countquery); - $sthcount->execute(@args); - - if(my $row = $sthcount->fetchrow_hashref()){ - $reservescount = $row->{count}; - } - if($reservescount < $reservesrights){ - return 1; - }else{ - return 0; + + foreach my $item (@items){ + return 1 if CanItemBeReserved($borrowernumber, $item); } - + return 0; } -=item CanItemBeReserved +=head2 CanItemBeReserved -$error = &CanItemBeReserved($borrowernumber, $itemnumber) + $error = &CanItemBeReserved($borrowernumber, $itemnumber) -this function return 1 if an item can be issued by this borrower. +This function return 1 if an item can be issued by this borrower. =cut @@ -544,9 +487,9 @@ sub CanItemBeReserved{ } } #-------------------------------------------------------------------------------- -=item GetReserveCount +=head2 GetReserveCount -$number = &GetReserveCount($borrowernumber); + $number = &GetReserveCount($borrowernumber); this function returns the number of reservation for a borrower given on input arg. @@ -568,9 +511,9 @@ sub GetReserveCount { return $row->{counter}; } -=item GetOtherReserves +=head2 GetOtherReserves -($messages,$nextreservinfo)=$GetOtherReserves(itemnumber); + ($messages,$nextreservinfo)=$GetOtherReserves(itemnumber); Check queued list of this document and check if this document must be transfered @@ -618,9 +561,9 @@ sub GetOtherReserves { return ( $messages, $nextreservinfo ); } -=item GetReserveFee +=head2 GetReserveFee -$fee = GetReserveFee($borrowernumber,$biblionumber,$constraint,$biblionumber); + $fee = GetReserveFee($borrowernumber,$biblionumber,$constraint,$biblionumber); Calculate the fee for a reserve @@ -721,9 +664,9 @@ sub GetReserveFee { return $fee; } -=item GetReservesToBranch +=head2 GetReservesToBranch -@transreserv = GetReservesToBranch( $frombranch ); + @transreserv = GetReservesToBranch( $frombranch ); Get reserve list for a given branch @@ -748,9 +691,9 @@ sub GetReservesToBranch { return (@transreserv); } -=item GetReservesForBranch +=head2 GetReservesForBranch -@transreserv = GetReservesForBranch($frombranch); + @transreserv = GetReservesForBranch($frombranch); =cut @@ -793,7 +736,7 @@ sub GetReserveStatus { return $found; } -=item CheckReserves +=head2 CheckReserves ($status, $reserve) = &CheckReserves($itemnumber); ($status, $reserve) = &CheckReserves(undef, $barcode); @@ -824,17 +767,32 @@ sub CheckReserves { my ( $item, $barcode ) = @_; my $dbh = C4::Context->dbh; my $sth; - my $select = " - SELECT items.biblionumber, + my $select; + if (C4::Context->preference('item-level_itypes')){ + $select = " + SELECT items.biblionumber, items.biblioitemnumber, itemtypes.notforloan, items.notforloan AS itemnotforloan, items.itemnumber - FROM items - LEFT JOIN biblioitems ON items.biblioitemnumber = biblioitems.biblioitemnumber - LEFT JOIN itemtypes ON biblioitems.itemtype = itemtypes.itemtype - "; - + FROM items + LEFT JOIN biblioitems ON items.biblioitemnumber = biblioitems.biblioitemnumber + LEFT JOIN itemtypes ON items.itype = itemtypes.itemtype + "; + } + else { + $select = " + SELECT items.biblionumber, + items.biblioitemnumber, + itemtypes.notforloan, + items.notforloan AS itemnotforloan, + items.itemnumber + FROM items + LEFT JOIN biblioitems ON items.biblioitemnumber = biblioitems.biblioitemnumber + LEFT JOIN itemtypes ON biblioitems.itemtype = itemtypes.itemtype + "; + } + if ($item) { $sth = $dbh->prepare("$select WHERE itemnumber = ?"); $sth->execute($item); @@ -868,6 +826,12 @@ sub CheckReserves { } else { # See if this item is more important than what we've got so far if ( $res->{'priority'} && $res->{'priority'} < $priority ) { + my $borrowerinfo=C4::Members::GetMember(borrowernumber => $res->{'borrowernumber'}); + my $iteminfo=C4::Items::GetItem($itemnumber); + my $branch=C4::Circulation::_GetCircControlBranch($iteminfo,$borrowerinfo); + my $branchitemrule = C4::Circulation::GetBranchItemRule($branch,$iteminfo->{'itype'}); + next if ($branchitemrule->{'holdallowed'} == 0); + next if (($branchitemrule->{'holdallowed'} == 1) && ($branch ne $borrowerinfo->{'branchcode'})); $priority = $res->{'priority'}; $highest = $res; } @@ -886,12 +850,12 @@ sub CheckReserves { } } -=item CancelExpiredReserves +=head2 CancelExpiredReserves CancelExpiredReserves(); - - Cancels all reserves with an expiration date from before today. - + +Cancels all reserves with an expiration date from before today. + =cut sub CancelExpiredReserves { @@ -909,7 +873,7 @@ sub CancelExpiredReserves { } -=item CancelReserve +=head2 CancelReserve &CancelReserve($biblionumber, $itemnumber, $borrowernumber); @@ -1007,17 +971,13 @@ sub CancelReserve { $sth->execute( $biblio, $borr ); # now fix the priority on the others.... - _FixPriority( $priority, $biblio ); + _FixPriority( $biblio, $borr ); } } -=item ModReserve +=head2 ModReserve -=over 4 - -ModReserve($rank, $biblio, $borrower, $branch[, $itemnumber]) - -=back + ModReserve($rank, $biblio, $borrower, $branch[, $itemnumber]) Change a hold request's priority or cancel it. @@ -1039,7 +999,7 @@ C<$rank> is a non-zero integer; if supplied, the itemnumber of the hold request is set accordingly; if omitted, the itemnumber is cleared. -FIXME: Note that the forgoing can have the effect of causing +B Note that the forgoing can have the effect of causing item-level hold requests to turn into title-level requests. This will be fixed once reserves has separate columns for requested itemnumber and supplying itemnumber. @@ -1093,7 +1053,7 @@ sub ModReserve { } } -=item ModReserveFill +=head2 ModReserveFill &ModReserveFill($reserve); @@ -1157,13 +1117,13 @@ sub ModReserveFill { # now fix the priority on the others (if the priority wasn't # already sorted!).... unless ( $priority == 0 ) { - _FixPriority( $priority, $biblionumber ); + _FixPriority( $biblionumber, $borrowernumber ); } } -=item ModReserveStatus +=head2 ModReserveStatus -&ModReserveStatus($itemnumber, $newstatus); + &ModReserveStatus($itemnumber, $newstatus); Update the reserve status for the active (priority=0) reserve. @@ -1192,9 +1152,9 @@ sub ModReserveStatus { } } -=item ModReserveAffect +=head2 ModReserveAffect -&ModReserveAffect($itemnumber,$borrowernumber,$diffBranchSend); + &ModReserveAffect($itemnumber,$borrowernumber,$diffBranchSend); This function affect an item and a status for a given reserve The itemnumber parameter is used to find the biblionumber. @@ -1204,6 +1164,7 @@ to the correct reserve. if $transferToDo is not set, then the status is set to "Waiting" as well. otherwise, a transfer is on the way, and the end of the transfer will take care of the waiting status + =cut sub ModReserveAffect { @@ -1227,7 +1188,8 @@ sub ModReserveAffect { $query = " UPDATE reserves SET priority = 0, - itemnumber = ? + itemnumber = ?, + found = 'T' WHERE borrowernumber = ? AND biblionumber = ? "; @@ -1255,11 +1217,11 @@ sub ModReserveAffect { return; } -=item ModReserveCancelAll +=head2 ModReserveCancelAll -($messages,$nextreservinfo) = &ModReserveCancelAll($itemnumber,$borrowernumber); + ($messages,$nextreservinfo) = &ModReserveCancelAll($itemnumber,$borrowernumber); - function to cancel reserv,check other reserves, and transfer document if it's necessary +function to cancel reserv,check other reserves, and transfer document if it's necessary =cut @@ -1277,9 +1239,9 @@ sub ModReserveCancelAll { return ( $messages, $nextreservinfo ); } -=item ModReserveMinusPriority +=head2 ModReserveMinusPriority -&ModReserveMinusPriority($itemnumber,$borrowernumber,$biblionumber) + &ModReserveMinusPriority($itemnumber,$borrowernumber,$biblionumber) Reduce the values of queuded list @@ -1302,12 +1264,13 @@ sub ModReserveMinusPriority { _FixPriority($biblionumber, $borrowernumber, '0'); } -=item GetReserveInfo +=head2 GetReserveInfo -&GetReserveInfo($borrowernumber,$biblionumber); + &GetReserveInfo($borrowernumber,$biblionumber); + +Get item and borrower details for a current hold. +Current implementation this query should have a single result. - Get item and borrower details for a current hold. - Current implementation this query should have a single result. =cut sub GetReserveInfo { @@ -1356,13 +1319,9 @@ sub GetReserveInfo { } -=item IsAvailableForItemLevelRequest - -=over 4 +=head2 IsAvailableForItemLevelRequest -my $is_available = IsAvailableForItemLevelRequest($itemnumber); - -=back + my $is_available = IsAvailableForItemLevelRequest($itemnumber); Checks whether a given item record is available for an item-level hold request. An item is available if @@ -1432,13 +1391,15 @@ sub IsAvailableForItemLevelRequest { } } -=item AlterPriority -AlterPriority( $where, $borrowernumber, $biblionumber, $reservedate ); +=head2 AlterPriority + + AlterPriority( $where, $borrowernumber, $biblionumber, $reservedate ); This function changes a reserve's priority up, down, to the top, or to the bottom. Input: $where is 'up', 'down', 'top' or 'bottom'. Biblionumber, Date reserve was placed =cut + sub AlterPriority { my ( $where, $borrowernumber, $biblionumber ) = @_; @@ -1467,10 +1428,12 @@ sub AlterPriority { } } -=item ToggleLowestPriority -ToggleLowestPriority( $borrowernumber, $biblionumber ); +=head2 ToggleLowestPriority + + ToggleLowestPriority( $borrowernumber, $biblionumber ); This function sets the lowestPriority field to true if is false, and false if it is true. + =cut sub ToggleLowestPriority { @@ -1492,16 +1455,16 @@ sub ToggleLowestPriority { _FixPriority( $biblionumber, $borrowernumber, '999999' ); } -=item _FixPriority +=head2 _FixPriority -&_FixPriority($biblio,$borrowernumber,$rank,$ignoreSetLowestRank); + &_FixPriority($biblio,$borrowernumber,$rank,$ignoreSetLowestRank); - Only used internally (so don't export it) - Changed how this functions works # - Now just gets an array of reserves in the rank order and updates them with - the array index (+1 as array starts from 0) - and if $rank is supplied will splice item from the array and splice it back in again - in new priority rank +Only used internally (so don't export it) +Changed how this functions works # +Now just gets an array of reserves in the rank order and updates them with +the array index (+1 as array starts from 0) +and if $rank is supplied will splice item from the array and splice it back in again +in new priority rank =cut @@ -1513,13 +1476,13 @@ sub _FixPriority { } if ( $rank eq "W" || $rank eq "0" ) { - # make sure priority for waiting items is 0 + # make sure priority for waiting or in-transit items is 0 my $query = qq/ UPDATE reserves SET priority = 0 WHERE biblionumber = ? AND borrowernumber = ? - AND found ='W' + AND found IN ('W', 'T') /; my $sth = $dbh->prepare($query); $sth->execute( $biblio, $borrowernumber ); @@ -1536,7 +1499,7 @@ sub _FixPriority { SELECT borrowernumber, reservedate, constrainttype FROM reserves WHERE biblionumber = ? - AND ((found <> 'W') or found is NULL) + AND ((found <> 'W' AND found <> 'T') or found is NULL) ORDER BY priority ASC /; my $sth = $dbh->prepare($query); @@ -1593,7 +1556,7 @@ sub _FixPriority { } } -=item _Findgroupreserve +=head2 _Findgroupreserve @results = &_Findgroupreserve($biblioitemnumber, $biblionumber, $itemnumber); @@ -1679,6 +1642,7 @@ sub _Findgroupreserve { SELECT reserves.biblionumber AS biblionumber, reserves.borrowernumber AS borrowernumber, reserves.reservedate AS reservedate, + reserves.waitingdate AS waitingdate, reserves.branchcode AS branchcode, reserves.cancellationdate AS cancellationdate, reserves.found AS found, @@ -1706,13 +1670,9 @@ sub _Findgroupreserve { return @results; } -=item _koha_notify_reserve +=head2 _koha_notify_reserve -=over 4 - -_koha_notify_reserve( $itemnumber, $borrowernumber, $biblionumber ); - -=back + _koha_notify_reserve( $itemnumber, $borrowernumber, $biblionumber ); Sends a notification to the patron that their hold has been filled (through ModReserveAffect, _not_ ModReserveFill) @@ -1724,11 +1684,22 @@ sub _koha_notify_reserve { my $dbh = C4::Context->dbh; my $borrower = C4::Members::GetMember(borrowernumber => $borrowernumber); + + # Try to get the borrower's email address + my $to_address; + my $which_address = C4::Context->preference('AutoEmailPrimaryAddress'); + # If the system preference is set to 'first valid' (value == OFF), look up email address + if ($which_address eq 'OFF') { + $to_address = C4::Members::GetFirstValidEmailAddress( $borrowernumber ); + } else { + $to_address = $borrower->{$which_address}; + } + my $letter_code; my $print_mode = 0; my $messagingprefs; - if ( $borrower->{'email'} || $borrower->{'smsalertnumber'} ) { - $messagingprefs = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $borrowernumber, message_name => 'Hold Filled' } ); + if ( $to_address || $borrower->{'smsalertnumber'} ) { + $messagingprefs = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $borrowernumber, message_name => 'Hold_Filled' } ); return if ( !defined( $messagingprefs->{'letter_code'} ) ); $letter_code = $messagingprefs->{'letter_code'}; @@ -1796,25 +1767,21 @@ sub _koha_notify_reserve { } } -=item _ShiftPriorityByDateAndPriority - -=over 4 - -$new_priority = _ShiftPriorityByDateAndPriority( $biblionumber, $reservedate, $priority ); +=head2 _ShiftPriorityByDateAndPriority -=back + $new_priority = _ShiftPriorityByDateAndPriority( $biblionumber, $reservedate, $priority ); This increments the priority of all reserves after the one - with either the lowest date after C<$reservedate> - or the lowest priority after C<$priority>. +with either the lowest date after C<$reservedate> +or the lowest priority after C<$priority>. It effectively makes room for a new reserve to be inserted with a certain - priority, which is returned. +priority, which is returned. This is most useful when the reservedate can be set by the user. It allows - the new reserve to be placed before other reserves that have a later - reservedate. Since priority also is set by the form in reserves/request.pl - the sub accounts for that too. +the new reserve to be placed before other reserves that have a later +reservedate. Since priority also is set by the form in reserves/request.pl +the sub accounts for that too. =cut @@ -1849,11 +1816,54 @@ sub _ShiftPriorityByDateAndPriority { return $new_priority; # so the caller knows what priority they wind up receiving } -=back +=head2 MergeHolds + + MergeHolds($dbh,$to_biblio, $from_biblio); + +This shifts the holds from C<$from_biblio> to C<$to_biblio> and reorders them by the date they were placed + +=cut + +sub MergeHolds { + my ( $dbh, $to_biblio, $from_biblio ) = @_; + my $sth = $dbh->prepare( + "SELECT count(*) as reservenumber FROM reserves WHERE biblionumber = ?" + ); + $sth->execute($from_biblio); + if ( my $data = $sth->fetchrow_hashref() ) { + + # holds exist on old record, if not we don't need to do anything + $sth = $dbh->prepare( + "UPDATE reserves SET biblionumber = ? WHERE biblionumber = ?"); + $sth->execute( $to_biblio, $from_biblio ); + + # Reorder by date + # don't reorder those already waiting + + $sth = $dbh->prepare( +"SELECT * FROM reserves WHERE biblionumber = ? AND (found <> ? AND found <> ? OR found is NULL) ORDER BY reservedate ASC" + ); + my $upd_sth = $dbh->prepare( +"UPDATE reserves SET priority = ? WHERE biblionumber = ? AND borrowernumber = ? + AND reservedate = ? AND constrainttype = ? AND (itemnumber = ? or itemnumber is NULL) " + ); + $sth->execute( $to_biblio, 'W', 'T' ); + my $priority = 1; + while ( my $reserve = $sth->fetchrow_hashref() ) { + $upd_sth->execute( + $priority, $to_biblio, + $reserve->{'borrowernumber'}, $reserve->{'reservedate'}, + $reserve->{'constrainttype'}, $reserve->{'itemnumber'} + ); + $priority++; + } + } +} + =head1 AUTHOR -Koha Development Team +Koha Development Team =cut