C4::Reserves - Koha functions for dealing with reservation.


  use C4::Reserves;


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
            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
  The complete workflow is :
  ==== 1st use case ====
  patron request a document, 1st available :                      P >0, F=NULL, I=NULL
  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=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=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





    $res = GetReserve( $reserve_id );

    Return the current reserve.


  my $reserves = GetReservesFromBiblionumber({
    biblionumber => $biblionumber,
    [ itemnumber => $itemnumber, ]
    [ all_dates => 1|0 ]

This function gets the list of reservations for one $biblionumber, returning an arrayref pointing to the reserves for $biblionumber.

By default, only reserves whose start date falls before the current time are returned. To return all reserves, including future ones, the all_dates parameter can be included and set to a true value.

If the itemnumber parameter is supplied, reserves must be targeted to that item or not targeted to any item at all; otherwise, they are excluded from the list.


 ( $reservedate, $borrowernumber, $branchcode, $reserve_id, $waitingdate ) = GetReservesFromItemnumber($itemnumber);

Get the first reserve for a specific item number (based on priority). Returns the abovementioned values for that reserve.

The routine does not look at future reserves (read: item level holds), but DOES include future waits (a confirmed future hold).


    $borrowerreserv = GetReservesFromBorrowernumber($borrowernumber,$tatus);

TODO :: Descritpion


  $error = &CanBookBeReserved($borrowernumber, $biblionumber)


  $error = &CanItemBeReserved($borrowernumber, $itemnumber)

This function return 1 if an item can be issued by this borrower.


    $number = CanReserveBeCanceledFromOpac($reserve_id, $borrowernumber);

    returns 1 if reserve can be cancelled by user from OPAC.
    First check if reserve belongs to user, next checks if reserve is not in
    transfer or waiting status


  $number = &GetReserveCount($borrowernumber);

this function returns the number of reservation for a borrower given on input arg.



Check queued list of this document and check if this document must be transfered


  $fee = GetReserveFee($borrowernumber,$biblionumber,$constraint,$biblionumber);

Calculate the fee for a reserve


  @transreserv = GetReservesToBranch( $frombranch );

Get reserve list for a given branch


  @transreserv = GetReservesForBranch($frombranch);


  $reservestatus = GetReserveStatus($itemnumber, $biblionumber);

Take an itemnumber or a biblionumber and return the status of the reserve places on it. If several reserves exist, the reserve with the lower priority is given.


  ($status, $reserve, $all_reserves) = &CheckReserves($itemnumber);
  ($status, $reserve, $all_reserves) = &CheckReserves(undef, $barcode);
  ($status, $reserve, $all_reserves) = &CheckReserves($itemnumber,undef,$lookahead);

Find a book in the reserves.

$itemnumber is the book's item number. $lookahead is the number of days to look in advance for future reserves.

As I understand it, &CheckReserves looks for the given item in the reserves. If it is found, that's a match, and $status is set to Waiting.

Otherwise, it finds the most important item in the reserves with the same biblio number as this book (I'm not clear on this) and returns it with $status set to Reserved.

&CheckReserves returns a two-element list:

$status is either Waiting, Reserved (see above), or 0.

$reserve is the reserve item that matched. It is a reference-to-hash whose keys are mostly the fields of the reserves table in the Koha database.



Cancels all reserves with an expiration date from before today.



Unsuspends all suspended reserves with a suspend_until date from before today.


  CancelReserve({ reserve_id => $reserve_id, [ biblionumber => $biblionumber, borrowernumber => $borrrowernumber, itemnumber => $itemnumber ] });

Cancels a reserve.


  ModReserve({ rank => $rank,
               reserve_id => $reserve_id,
               branchcode => $branchcode
               [, itemnumber => $itemnumber ]
               [, biblionumber => $biblionumber, $borrowernumber => $borrowernumber ]

Change a hold request's priority or cancel it.

$rank specifies the effect of the change. If $rank is 'W' or 'n', nothing happens. This corresponds to leaving a request alone when changing its priority in the holds queue for a bib.

If $rank is 'del', the hold request is cancelled.

If $rank is an integer greater than zero, the priority of the request is set to that value. Since priority != 0 means that the item is not waiting on the hold shelf, setting the priority to a non-zero value also sets the request's found status and waiting date to NULL.

The optional $itemnumber parameter is used only when $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 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.



Fill a reserve. If I understand this correctly, this means that the reserved book has been found and given to the patron who reserved it.

$reserve specifies the reserve to fill. It is a reference-to-hash whose keys are fields from the reserves table in the Koha database.


  &ModReserveStatus($itemnumber, $newstatus);

Update the reserve status for the active (priority=0) reserve.

$itemnumber is the itemnumber the reserve is on

$newstatus is the new status.



This function affect an item and a status for a given reserve The itemnumber parameter is used to find the biblionumber. with the biblionumber & the borrowernumber, we can affect the itemnumber 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


  ($messages,$nextreservinfo) = &ModReserveCancelAll($itemnumber,$borrowernumber);

function to cancel reserv,check other reserves, and transfer document if it's necessary



Reduce the values of queued list



Get item and borrower details for a current hold. Current implementation this query should have a single result.


  my $is_available = IsAvailableForItemLevelRequest($itemnumber);

Checks whether a given item record is available for an item-level hold request. An item is available if

* it is not lost AND * it is not damaged AND * it is not withdrawn AND * does not have a not for loan value > 0

Whether or not the item is currently on loan is also checked - if the AllowOnShelfHolds system preference is ON, an item can be requested even if it is currently on loan to somebody else. If the system preference is OFF, an item that is currently checked out cannot be the target of an item-level hold request.

Note that IsAvailableForItemLevelRequest() does not check if the staff operator is authorized to place a request on the item - in particular, this routine does not check IndependentBranches and canreservefromotherbranches.


  AlterPriority( $where, $reserve_id );

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


  ToggleLowestPriority( $borrowernumber, $biblionumber );

This function sets the lowestPriority field to true if is false, and false if it is true.


  ToggleSuspend( $reserve_id );

This function sets the suspend field to true if is false, and false if it is true. If the reserve is currently suspended with a suspend_until date, that date will be cleared when it is unsuspended.


      borrowernumber   => $borrowernumber,
      [ biblionumber   => $biblionumber, ]
      [ suspend_until  => $suspend_until, ]
      [ suspend        => $suspend ]

  This function accepts a set of hash keys as its parameters.
  It requires either borrowernumber or biblionumber, or both.

  suspend_until is wholly optional.


    reserve_id => $reserve_id,
    [rank => $rank,]
    [ignoreSetLowestRank => $ignoreSetLowestRank]


  _FixPriority({ biblionumber => $biblionumber});

This routine adjusts the priority of a hold request and holds on the same bib.

In the first form, where a reserve_id is passed, the priority of the hold is set to supplied rank, and other holds for that bib are adjusted accordingly. If the rank is "del", the hold is cancelled. If no rank is supplied, all of the holds on that bib have their priority adjusted as if the second form had been used.

In the second form, where a biblionumber is passed, the holds on that bib (that are not captured) are sorted in order of increasing priority, then have reserves.priority set so that the first non-captured hold has its priority set to 1, the second non-captured hold has its priority set to 2, and so forth.

In both cases, holds that have the lowestPriority flag on are have their priority adjusted to ensure that they remain at the end of the line.

Note that the ignoreSetLowestRank parameter is meant to be used only when _FixPriority calls itself.


  @results = &_Findgroupreserve($biblioitemnumber, $biblionumber, $itemnumber, $lookahead);

Looks for an item-specific match first, then for a title-level match, returning the first match found. If neither, then we look for a 3rd kind of match based on reserve constraints. Lookahead is the number of days to look in advance.

TODO: add more explanation about reserve constraints

&_Findgroupreserve returns : @results is an array of references-to-hash whose keys are mostly fields from the reserves table of the Koha database, plus biblioitemnumber.


  _koha_notify_reserve( $itemnumber, $borrowernumber, $biblionumber );

Sends a notification to the patron that their hold has been filled (through ModReserveAffect, _not_ ModReserveFill)


  $new_priority = _ShiftPriorityByDateAndPriority( $biblionumber, $reservedate, $priority );

This increments the priority of all reserves after the one with either the lowest date after $reservedate or the lowest priority after $priority.

It effectively makes room for a new reserve to be inserted with a certain 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.


  MoveReserve( $itemnumber, $borrowernumber, $cancelreserve )

Use when checking out an item to handle reserves If $cancelreserve boolean is set to true, it will remove existing reserve


  MergeHolds($dbh,$to_biblio, $from_biblio);

This shifts the holds from $from_biblio to $to_biblio and reorders them by the date they were placed


  RevertWaitingStatus({ itemnumber => $itemnumber });

  Reverts a 'waiting' hold back to a regular hold with a priority of 1.

  Caveat: Any waiting hold fixed with RevertWaitingStatus will be an
          item level hold, even if it was only a bibliolevel hold to
          begin with. This is because we can no longer know if a hold
          was item-level or bib-level after a hold has been set to
          waiting status.


  $reserve_id = GetReserveId({ biblionumber => $biblionumber, borrowernumber => $borrowernumber [, itemnumber => $itemnumber ] });

  Returnes the first reserve id that matches the given criteria


  ReserveSlip($branchcode, $borrowernumber, $biblionumber)

  Returns letter hash ( see C4::Letters::GetPreparedLetter ) or undef


  my $reserves_control_branch = GetReservesControlBranch($item, $borrower);

  Return the branchcode to be used to determine which reserves
  policy applies to a transaction.

  C<$item> is a hashref for an item. Only 'homebranch' is used.

  C<$borrower> is a hashref to borrower. Only 'branchcode' is used.


    my $p = CalculatePriority($biblionumber, $resdate);

Calculate priority for a new reserve on biblionumber, placing it at the end of the line of all holds whose start date falls before the current system time and that are neither on the hold shelf or in transit.

The reserve date parameter is optional; if it is supplied, the priority is based on the set of holds whose start date falls before the parameter value.

After calculation of this priority, it is recommended to call _ShiftPriorityByDateAndPriority. Note that this is currently done in AddReserves.


Koha Development Team <http://koha-community.org/>