Lines 70-82
This modules provides somes functions to deal with reservations.
Link Here
|
70 |
The complete workflow is : |
70 |
The complete workflow is : |
71 |
==== 1st use case ==== |
71 |
==== 1st use case ==== |
72 |
patron request a document, 1st available : P >0, F=NULL, I=NULL |
72 |
patron request a document, 1st available : P >0, F=NULL, I=NULL |
73 |
a library having it run "transfertodo", and clic on the list |
73 |
a library having it run "transfertodo", and clic on the list |
74 |
if there is no transfer to do, the reserve waiting |
74 |
if there is no transfer to do, the reserve waiting |
75 |
patron can pick it up P =0, F=W, I=filled |
75 |
patron can pick it up P =0, F=W, I=filled |
76 |
if there is a transfer to do, write in branchtransfer P =0, F=T, I=filled |
76 |
if there is a transfer to do, write in branchtransfer P =0, F=T, I=filled |
77 |
The pickup library recieve the book, it check in P =0, F=W, I=filled |
77 |
The pickup library recieve the book, it check in P =0, F=W, I=filled |
78 |
The patron borrow the book P =0, F=F, I=filled |
78 |
The patron borrow the book P =0, F=F, I=filled |
79 |
|
79 |
|
80 |
==== 2nd use case ==== |
80 |
==== 2nd use case ==== |
81 |
patron requests a document, a given item, |
81 |
patron requests a document, a given item, |
82 |
If pickup is holding branch P =0, F=W, I=filled |
82 |
If pickup is holding branch P =0, F=W, I=filled |
Lines 106-114
BEGIN {
Link Here
|
106 |
&GetReserveFee |
106 |
&GetReserveFee |
107 |
&GetReserveInfo |
107 |
&GetReserveInfo |
108 |
&GetReserveStatus |
108 |
&GetReserveStatus |
109 |
|
109 |
|
110 |
&GetOtherReserves |
110 |
&GetOtherReserves |
111 |
|
111 |
|
112 |
&ModReserveFill |
112 |
&ModReserveFill |
113 |
&ModReserveAffect |
113 |
&ModReserveAffect |
114 |
&ModReserve |
114 |
&ModReserve |
Lines 116-122
BEGIN {
Link Here
|
116 |
&ModReserveCancelAll |
116 |
&ModReserveCancelAll |
117 |
&ModReserveMinusPriority |
117 |
&ModReserveMinusPriority |
118 |
&MoveReserve |
118 |
&MoveReserve |
119 |
|
119 |
|
120 |
&CheckReserves |
120 |
&CheckReserves |
121 |
&CanBookBeReserved |
121 |
&CanBookBeReserved |
122 |
&CanItemBeReserved |
122 |
&CanItemBeReserved |
Lines 127-133
BEGIN {
Link Here
|
127 |
&AutoUnsuspendReserves |
127 |
&AutoUnsuspendReserves |
128 |
|
128 |
|
129 |
&IsAvailableForItemLevelRequest |
129 |
&IsAvailableForItemLevelRequest |
130 |
|
130 |
|
|
|
131 |
&OPACItemHoldsAllowed |
132 |
|
131 |
&AlterPriority |
133 |
&AlterPriority |
132 |
&ToggleLowestPriority |
134 |
&ToggleLowestPriority |
133 |
|
135 |
|
Lines 140-146
BEGIN {
Link Here
|
140 |
IsItemOnHoldAndFound |
142 |
IsItemOnHoldAndFound |
141 |
); |
143 |
); |
142 |
@EXPORT_OK = qw( MergeHolds ); |
144 |
@EXPORT_OK = qw( MergeHolds ); |
143 |
} |
145 |
} |
144 |
|
146 |
|
145 |
=head2 AddReserve |
147 |
=head2 AddReserve |
146 |
|
148 |
|
Lines 351-357
sub GetReservesFromBiblionumber {
Link Here
|
351 |
push( @bibitemno, $bibitemnos ); # FIXME: inefficient: use fetchall_arrayref |
353 |
push( @bibitemno, $bibitemnos ); # FIXME: inefficient: use fetchall_arrayref |
352 |
} |
354 |
} |
353 |
my $count = scalar @bibitemno; |
355 |
my $count = scalar @bibitemno; |
354 |
|
356 |
|
355 |
# if we have two or more different specific itemtypes |
357 |
# if we have two or more different specific itemtypes |
356 |
# reserved by same person on same day |
358 |
# reserved by same person on same day |
357 |
my $bdata; |
359 |
my $bdata; |
Lines 491-497
sub CanBookBeReserved{
Link Here
|
491 |
|
493 |
|
492 |
sub CanItemBeReserved{ |
494 |
sub CanItemBeReserved{ |
493 |
my ($borrowernumber, $itemnumber) = @_; |
495 |
my ($borrowernumber, $itemnumber) = @_; |
494 |
|
496 |
|
495 |
my $dbh = C4::Context->dbh; |
497 |
my $dbh = C4::Context->dbh; |
496 |
my $ruleitemtype; # itemtype of the matching issuing rule |
498 |
my $ruleitemtype; # itemtype of the matching issuing rule |
497 |
my $allowedreserves = 0; |
499 |
my $allowedreserves = 0; |
Lines 513-530
sub CanItemBeReserved{
Link Here
|
513 |
my $itemtypefield = C4::Context->preference('item-level_itypes') ? "itype" : "itemtype"; |
515 |
my $itemtypefield = C4::Context->preference('item-level_itypes') ? "itype" : "itemtype"; |
514 |
|
516 |
|
515 |
# we retrieve user rights on this itemtype and branchcode |
517 |
# we retrieve user rights on this itemtype and branchcode |
516 |
my $sth = $dbh->prepare("SELECT categorycode, itemtype, branchcode, reservesallowed |
518 |
my $sth = $dbh->prepare("SELECT categorycode, itemtype, branchcode, reservesallowed |
517 |
FROM issuingrules |
519 |
FROM issuingrules |
518 |
WHERE (categorycode in (?,'*') ) |
520 |
WHERE (categorycode in (?,'*') ) |
519 |
AND (itemtype IN (?,'*')) |
521 |
AND (itemtype IN (?,'*')) |
520 |
AND (branchcode IN (?,'*')) |
522 |
AND (branchcode IN (?,'*')) |
521 |
ORDER BY |
523 |
ORDER BY |
522 |
categorycode DESC, |
524 |
categorycode DESC, |
523 |
itemtype DESC, |
525 |
itemtype DESC, |
524 |
branchcode DESC;" |
526 |
branchcode DESC;" |
525 |
); |
527 |
); |
526 |
|
528 |
|
527 |
my $querycount ="SELECT |
529 |
my $querycount ="SELECT |
528 |
count(*) as count |
530 |
count(*) as count |
529 |
FROM reserves |
531 |
FROM reserves |
530 |
LEFT JOIN items USING (itemnumber) |
532 |
LEFT JOIN items USING (itemnumber) |
Lines 536-542
sub CanItemBeReserved{
Link Here
|
536 |
|
538 |
|
537 |
my $branchcode = ""; |
539 |
my $branchcode = ""; |
538 |
my $branchfield = "reserves.branchcode"; |
540 |
my $branchfield = "reserves.branchcode"; |
539 |
|
541 |
|
540 |
if( $controlbranch eq "ItemHomeLibrary" ){ |
542 |
if( $controlbranch eq "ItemHomeLibrary" ){ |
541 |
$branchfield = "items.homebranch"; |
543 |
$branchfield = "items.homebranch"; |
542 |
$branchcode = $item->{homebranch}; |
544 |
$branchcode = $item->{homebranch}; |
Lines 553-561
sub CanItemBeReserved{
Link Here
|
553 |
}else{ |
555 |
}else{ |
554 |
$ruleitemtype = '*'; |
556 |
$ruleitemtype = '*'; |
555 |
} |
557 |
} |
556 |
|
558 |
|
557 |
# we retrieve count |
559 |
# we retrieve count |
558 |
|
560 |
|
559 |
$querycount .= "AND $branchfield = ?"; |
561 |
$querycount .= "AND $branchfield = ?"; |
560 |
|
562 |
|
561 |
$querycount .= " AND $itemtypefield = ?" if ($ruleitemtype ne "*"); |
563 |
$querycount .= " AND $itemtypefield = ?" if ($ruleitemtype ne "*"); |
Lines 566-577
sub CanItemBeReserved{
Link Here
|
566 |
}else{ |
568 |
}else{ |
567 |
$sthcount->execute($borrowernumber, $branchcode, $ruleitemtype); |
569 |
$sthcount->execute($borrowernumber, $branchcode, $ruleitemtype); |
568 |
} |
570 |
} |
569 |
|
571 |
|
570 |
my $reservecount = "0"; |
572 |
my $reservecount = "0"; |
571 |
if(my $rowcount = $sthcount->fetchrow_hashref()){ |
573 |
if(my $rowcount = $sthcount->fetchrow_hashref()){ |
572 |
$reservecount = $rowcount->{count}; |
574 |
$reservecount = $rowcount->{count}; |
573 |
} |
575 |
} |
574 |
|
|
|
575 |
# we check if it's ok or not |
576 |
# we check if it's ok or not |
576 |
if( $reservecount >= $allowedreserves ){ |
577 |
if( $reservecount >= $allowedreserves ){ |
577 |
return 'tooManyReserves'; |
578 |
return 'tooManyReserves'; |
Lines 949-955
sub CheckReserves {
Link Here
|
949 |
LEFT JOIN itemtypes ON biblioitems.itemtype = itemtypes.itemtype |
950 |
LEFT JOIN itemtypes ON biblioitems.itemtype = itemtypes.itemtype |
950 |
"; |
951 |
"; |
951 |
} |
952 |
} |
952 |
|
953 |
|
953 |
if ($item) { |
954 |
if ($item) { |
954 |
$sth = $dbh->prepare("$select WHERE itemnumber = ?"); |
955 |
$sth = $dbh->prepare("$select WHERE itemnumber = ?"); |
955 |
$sth->execute($item); |
956 |
$sth->execute($item); |
Lines 1047-1053
sub CancelExpiredReserves {
Link Here
|
1047 |
# Cancel reserves that have passed their expiration date. |
1048 |
# Cancel reserves that have passed their expiration date. |
1048 |
my $dbh = C4::Context->dbh; |
1049 |
my $dbh = C4::Context->dbh; |
1049 |
my $sth = $dbh->prepare( " |
1050 |
my $sth = $dbh->prepare( " |
1050 |
SELECT * FROM reserves WHERE DATE(expirationdate) < DATE( CURDATE() ) |
1051 |
SELECT * FROM reserves WHERE DATE(expirationdate) < DATE( CURDATE() ) |
1051 |
AND expirationdate IS NOT NULL |
1052 |
AND expirationdate IS NOT NULL |
1052 |
AND found IS NULL |
1053 |
AND found IS NULL |
1053 |
" ); |
1054 |
" ); |
Lines 1056-1062
sub CancelExpiredReserves {
Link Here
|
1056 |
while ( my $res = $sth->fetchrow_hashref() ) { |
1057 |
while ( my $res = $sth->fetchrow_hashref() ) { |
1057 |
CancelReserve({ reserve_id => $res->{'reserve_id'} }); |
1058 |
CancelReserve({ reserve_id => $res->{'reserve_id'} }); |
1058 |
} |
1059 |
} |
1059 |
|
1060 |
|
1060 |
# Cancel reserves that have been waiting too long |
1061 |
# Cancel reserves that have been waiting too long |
1061 |
if ( C4::Context->preference("ExpireReservesMaxPickUpDelay") ) { |
1062 |
if ( C4::Context->preference("ExpireReservesMaxPickUpDelay") ) { |
1062 |
my $max_pickup_delay = C4::Context->preference("ReservesMaxPickUpDelay"); |
1063 |
my $max_pickup_delay = C4::Context->preference("ReservesMaxPickUpDelay"); |
Lines 1182-1193
If C<$rank> is 'del', the hold request is cancelled.
Link Here
|
1182 |
|
1183 |
|
1183 |
If C<$rank> is an integer greater than zero, the priority of |
1184 |
If C<$rank> is an integer greater than zero, the priority of |
1184 |
the request is set to that value. Since priority != 0 means |
1185 |
the request is set to that value. Since priority != 0 means |
1185 |
that the item is not waiting on the hold shelf, setting the |
1186 |
that the item is not waiting on the hold shelf, setting the |
1186 |
priority to a non-zero value also sets the request's found |
1187 |
priority to a non-zero value also sets the request's found |
1187 |
status and waiting date to NULL. |
1188 |
status and waiting date to NULL. |
1188 |
|
1189 |
|
1189 |
The optional C<$itemnumber> parameter is used only when |
1190 |
The optional C<$itemnumber> parameter is used only when |
1190 |
C<$rank> is a non-zero integer; if supplied, the itemnumber |
1191 |
C<$rank> is a non-zero integer; if supplied, the itemnumber |
1191 |
of the hold request is set accordingly; if omitted, the itemnumber |
1192 |
of the hold request is set accordingly; if omitted, the itemnumber |
1192 |
is cleared. |
1193 |
is cleared. |
1193 |
|
1194 |
|
Lines 1299-1305
sub ModReserveFill {
Link Here
|
1299 |
"; |
1300 |
"; |
1300 |
$sth = $dbh->prepare($query); |
1301 |
$sth = $dbh->prepare($query); |
1301 |
$sth->execute( $biblionumber, $resdate, $borrowernumber ); |
1302 |
$sth->execute( $biblionumber, $resdate, $borrowernumber ); |
1302 |
|
1303 |
|
1303 |
# now fix the priority on the others (if the priority wasn't |
1304 |
# now fix the priority on the others (if the priority wasn't |
1304 |
# already sorted!).... |
1305 |
# already sorted!).... |
1305 |
unless ( $priority == 0 ) { |
1306 |
unless ( $priority == 0 ) { |
Lines 1344-1350
with the biblionumber & the borrowernumber, we can affect the itemnumber
Link Here
|
1344 |
to the correct reserve. |
1345 |
to the correct reserve. |
1345 |
|
1346 |
|
1346 |
if $transferToDo is not set, then the status is set to "Waiting" as well. |
1347 |
if $transferToDo is not set, then the status is set to "Waiting" as well. |
1347 |
otherwise, a transfer is on the way, and the end of the transfer will |
1348 |
otherwise, a transfer is on the way, and the end of the transfer will |
1348 |
take care of the waiting status |
1349 |
take care of the waiting status |
1349 |
|
1350 |
|
1350 |
=cut |
1351 |
=cut |
Lines 1505-1526
sub GetReserveInfo {
Link Here
|
1505 |
|
1506 |
|
1506 |
=head2 IsAvailableForItemLevelRequest |
1507 |
=head2 IsAvailableForItemLevelRequest |
1507 |
|
1508 |
|
1508 |
my $is_available = IsAvailableForItemLevelRequest($itemnumber); |
1509 |
my $is_available = IsAvailableForItemLevelRequest($item_record,$borrower_record); |
1509 |
|
1510 |
|
1510 |
Checks whether a given item record is available for an |
1511 |
Checks whether a given item record is available for an |
1511 |
item-level hold request. An item is available if |
1512 |
item-level hold request. An item is available if |
1512 |
|
1513 |
|
1513 |
* it is not lost AND |
1514 |
* it is not lost AND |
1514 |
* it is not damaged AND |
1515 |
* it is not damaged AND |
1515 |
* it is not withdrawn AND |
1516 |
* it is not withdrawn AND |
1516 |
* does not have a not for loan value > 0 |
1517 |
* does not have a not for loan value > 0 |
1517 |
|
1518 |
|
1518 |
Whether or not the item is currently on loan is |
1519 |
Need to check the issuingrules onshelfholds column, |
1519 |
also checked - if the AllowOnShelfHolds system preference |
1520 |
if this is set items on the shelf can be placed on hold |
1520 |
is ON, an item can be requested even if it is currently |
|
|
1521 |
on loan to somebody else. If the system preference |
1522 |
is OFF, an item that is currently checked out cannot |
1523 |
be the target of an item-level hold request. |
1524 |
|
1521 |
|
1525 |
Note that IsAvailableForItemLevelRequest() does not |
1522 |
Note that IsAvailableForItemLevelRequest() does not |
1526 |
check if the staff operator is authorized to place |
1523 |
check if the staff operator is authorized to place |
Lines 1531-1578
and canreservefromotherbranches.
Link Here
|
1531 |
=cut |
1528 |
=cut |
1532 |
|
1529 |
|
1533 |
sub IsAvailableForItemLevelRequest { |
1530 |
sub IsAvailableForItemLevelRequest { |
1534 |
my $itemnumber = shift; |
1531 |
my $item = shift; |
1535 |
|
1532 |
my $borrower = shift; |
1536 |
my $item = GetItem($itemnumber); |
|
|
1537 |
|
1533 |
|
|
|
1534 |
my $dbh = C4::Context->dbh; |
1538 |
# must check the notforloan setting of the itemtype |
1535 |
# must check the notforloan setting of the itemtype |
1539 |
# FIXME - a lot of places in the code do this |
1536 |
# FIXME - a lot of places in the code do this |
1540 |
# or something similar - need to be |
1537 |
# or something similar - need to be |
1541 |
# consolidated |
1538 |
# consolidated |
1542 |
my $dbh = C4::Context->dbh; |
1539 |
my $itype = _get_itype($item); |
1543 |
my $notforloan_query; |
1540 |
my $notforloan_per_itemtype |
|
|
1541 |
= $dbh->selectrow_array("SELECT notforloan FROM itemtypes WHERE itemtype = ?", |
1542 |
undef, $itype); |
1543 |
|
1544 |
return 0 if |
1545 |
$notforloan_per_itemtype || |
1546 |
$item->{itemlost} || |
1547 |
$item->{notforloan} > 0 || |
1548 |
$item->{wthdrawn} || |
1549 |
($item->{damaged} && !C4::Context->preference('AllowHoldsOnDamagedItems')); |
1550 |
|
1551 |
|
1552 |
return 1 if _OnShelfHoldsAllowed($itype,$borrower->{categorycode},$item->{holdingbranch}); |
1553 |
|
1554 |
return $item->{onloan} || GetReserveStatus($item->{itemnumber}) eq "Waiting"; |
1555 |
} |
1556 |
|
1557 |
=head2 OnShelfHoldsAllowed |
1558 |
|
1559 |
OnShelfHoldsAllowed($itemtype,$borrowercategory,$branchcode); |
1560 |
|
1561 |
Checks issuingrules, using the borrowers categorycode, the itemtype, and branchcode to see if onshelf |
1562 |
holds are allowed, returns true if so. |
1563 |
|
1564 |
=cut |
1565 |
|
1566 |
sub OnShelfHoldsAllowed { |
1567 |
my ($item, $borrower) = @_; |
1568 |
|
1569 |
my $itype = _get_itype($item); |
1570 |
return _OnShelfHoldsAllowed($itype,$borrower->{categorycode},$item->{holdingbranch}); |
1571 |
} |
1572 |
|
1573 |
sub _get_itype { |
1574 |
my $item = shift; |
1575 |
|
1576 |
my $itype; |
1544 |
if (C4::Context->preference('item-level_itypes')) { |
1577 |
if (C4::Context->preference('item-level_itypes')) { |
1545 |
$notforloan_query = "SELECT itemtypes.notforloan |
1578 |
# We cant trust GetItem to honour the syspref, so safest to do it ourselves |
1546 |
FROM items |
1579 |
# When GetItem is fixed, we can remove this |
1547 |
JOIN itemtypes ON (itemtypes.itemtype = items.itype) |
1580 |
$itype = $item->{itype}; |
1548 |
WHERE itemnumber = ?"; |
|
|
1549 |
} else { |
1550 |
$notforloan_query = "SELECT itemtypes.notforloan |
1551 |
FROM items |
1552 |
JOIN biblioitems USING (biblioitemnumber) |
1553 |
JOIN itemtypes USING (itemtype) |
1554 |
WHERE itemnumber = ?"; |
1555 |
} |
1581 |
} |
1556 |
my $sth = $dbh->prepare($notforloan_query); |
1582 |
else { |
1557 |
$sth->execute($itemnumber); |
1583 |
# XXX This is a bit dodgy. It relies on biblio itemtype column having different name. |
1558 |
my $notforloan_per_itemtype = 0; |
1584 |
# So if we already have a biblioitems join when calling this function, |
1559 |
if (my ($notforloan) = $sth->fetchrow_array) { |
1585 |
# we don't need to access the database again |
1560 |
$notforloan_per_itemtype = 1 if $notforloan; |
1586 |
$itype = $item->{itemtype}; |
|
|
1587 |
} |
1588 |
unless ($itype) { |
1589 |
my $dbh = C4::Context->dbh; |
1590 |
my $query = "SELECT itemtype FROM biblioitems WHERE biblioitemnumber = ? "; |
1591 |
my $sth = $dbh->prepare($query); |
1592 |
$sth->execute($item->{biblioitemnumber}); |
1593 |
if (my $data = $sth->fetchrow_hashref()){ |
1594 |
$itype = $data->{itemtype}; |
1595 |
} |
1561 |
} |
1596 |
} |
|
|
1597 |
return $itype; |
1598 |
} |
1562 |
|
1599 |
|
1563 |
my $available_per_item = 1; |
1600 |
sub _OnShelfHoldsAllowed { |
1564 |
$available_per_item = 0 if $item->{itemlost} or |
1601 |
my ($itype,$borrowercategory,$branchcode) = @_; |
1565 |
( $item->{notforloan} > 0 ) or |
|
|
1566 |
($item->{damaged} and not C4::Context->preference('AllowHoldsOnDamagedItems')) or |
1567 |
$item->{withdrawn} or |
1568 |
$notforloan_per_itemtype; |
1569 |
|
1570 |
|
1602 |
|
1571 |
if (C4::Context->preference('AllowOnShelfHolds')) { |
1603 |
my $rule = C4::Circulation::GetIssuingRule($borrowercategory, $itype, $branchcode); |
1572 |
return $available_per_item; |
1604 |
return $rule->{onshelfholds}; |
1573 |
} else { |
|
|
1574 |
return ($available_per_item and ($item->{onloan} or GetReserveStatus($itemnumber) eq "Waiting")); |
1575 |
} |
1576 |
} |
1605 |
} |
1577 |
|
1606 |
|
1578 |
=head2 AlterPriority |
1607 |
=head2 AlterPriority |
Lines 1840-1846
sub _FixPriority {
Link Here
|
1840 |
|
1869 |
|
1841 |
$sth = $dbh->prepare( "SELECT reserve_id FROM reserves WHERE lowestPriority = 1 ORDER BY priority" ); |
1870 |
$sth = $dbh->prepare( "SELECT reserve_id FROM reserves WHERE lowestPriority = 1 ORDER BY priority" ); |
1842 |
$sth->execute(); |
1871 |
$sth->execute(); |
1843 |
|
1872 |
|
1844 |
unless ( $ignoreSetLowestRank ) { |
1873 |
unless ( $ignoreSetLowestRank ) { |
1845 |
while ( my $res = $sth->fetchrow_hashref() ) { |
1874 |
while ( my $res = $sth->fetchrow_hashref() ) { |
1846 |
_FixPriority({ |
1875 |
_FixPriority({ |
Lines 1908-1914
sub _Findgroupreserve {
Link Here
|
1908 |
unless any{ $data->{borrowernumber} eq $_ } @$ignore_borrowers ; |
1937 |
unless any{ $data->{borrowernumber} eq $_ } @$ignore_borrowers ; |
1909 |
} |
1938 |
} |
1910 |
return @results if @results; |
1939 |
return @results if @results; |
1911 |
|
1940 |
|
1912 |
# check for title-level targetted match |
1941 |
# check for title-level targetted match |
1913 |
my $title_level_target_query = qq{ |
1942 |
my $title_level_target_query = qq{ |
1914 |
SELECT reserves.biblionumber AS biblionumber, |
1943 |
SELECT reserves.biblionumber AS biblionumber, |
Lines 1993-1999
sub _koha_notify_reserve {
Link Here
|
1993 |
|
2022 |
|
1994 |
my $dbh = C4::Context->dbh; |
2023 |
my $dbh = C4::Context->dbh; |
1995 |
my $borrower = C4::Members::GetMember(borrowernumber => $borrowernumber); |
2024 |
my $borrower = C4::Members::GetMember(borrowernumber => $borrowernumber); |
1996 |
|
2025 |
|
1997 |
# Try to get the borrower's email address |
2026 |
# Try to get the borrower's email address |
1998 |
my $to_address = C4::Members::GetNoticeEmailAddress($borrowernumber); |
2027 |
my $to_address = C4::Members::GetNoticeEmailAddress($borrowernumber); |
1999 |
|
2028 |
|
Lines 2113-2118
sub _ShiftPriorityByDateAndPriority {
Link Here
|
2113 |
return $new_priority; # so the caller knows what priority they wind up receiving |
2142 |
return $new_priority; # so the caller knows what priority they wind up receiving |
2114 |
} |
2143 |
} |
2115 |
|
2144 |
|
|
|
2145 |
=head2 OPACItemHoldsAllowed |
2146 |
|
2147 |
OPACItemHoldsAllowed($item_record,$borrower_record); |
2148 |
|
2149 |
Checks issuingrules, using the borrowers categorycode, the itemtype, and branchcode to see |
2150 |
if specific item holds are allowed, returns true if so. |
2151 |
|
2152 |
=cut |
2153 |
|
2154 |
sub OPACItemHoldsAllowed { |
2155 |
my ($item,$borrower) = @_; |
2156 |
|
2157 |
my $branchcode = $item->{homebranch} or die "No homebranch"; |
2158 |
my $itype; |
2159 |
my $dbh = C4::Context->dbh; |
2160 |
if (C4::Context->preference('item-level_itypes')) { |
2161 |
# We cant trust GetItem to honour the syspref, so safest to do it ourselves |
2162 |
# When GetItem is fixed, we can remove this |
2163 |
$itype = $item->{itype}; |
2164 |
} |
2165 |
else { |
2166 |
my $query = "SELECT itemtype FROM biblioitems WHERE biblioitemnumber = ? "; |
2167 |
my $sth = $dbh->prepare($query); |
2168 |
$sth->execute($item->{biblioitemnumber}); |
2169 |
if (my $data = $sth->fetchrow_hashref()){ |
2170 |
$itype = $data->{itemtype}; |
2171 |
} |
2172 |
} |
2173 |
|
2174 |
my $query = "SELECT opacitemholds,categorycode,itemtype,branchcode FROM issuingrules WHERE |
2175 |
(issuingrules.categorycode = ? OR issuingrules.categorycode = '*') |
2176 |
AND |
2177 |
(issuingrules.itemtype = ? OR issuingrules.itemtype = '*') |
2178 |
AND |
2179 |
(issuingrules.branchcode = ? OR issuingrules.branchcode = '*') |
2180 |
ORDER BY |
2181 |
issuingrules.categorycode desc, |
2182 |
issuingrules.itemtype desc, |
2183 |
issuingrules.branchcode desc |
2184 |
LIMIT 1"; |
2185 |
my $sth = $dbh->prepare($query); |
2186 |
$sth->execute($borrower->{categorycode},$itype,$branchcode); |
2187 |
my $data = $sth->fetchrow_hashref; |
2188 |
my $opacitemholds = uc substr ($data->{opacitemholds}, 0, 1); |
2189 |
return '' if $opacitemholds eq 'N'; |
2190 |
return $opacitemholds; |
2191 |
} |
2192 |
|
2116 |
=head2 MoveReserve |
2193 |
=head2 MoveReserve |
2117 |
|
2194 |
|
2118 |
MoveReserve( $itemnumber, $borrowernumber, $cancelreserve ) |
2195 |
MoveReserve( $itemnumber, $borrowernumber, $cancelreserve ) |