Lines 404-411
sub CanBookBeReserved{
Link Here
|
404 |
current params are: |
404 |
current params are: |
405 |
'ignore_hold_counts' - we use this routine to check if an item can fill a hold - on this case we |
405 |
'ignore_hold_counts' - we use this routine to check if an item can fill a hold - on this case we |
406 |
should not check if there are too many holds as we only care about reservability |
406 |
should not check if there are too many holds as we only care about reservability |
|
|
407 |
'ignore_onshelfholds_policy' - if set to a true value, do not check if the |
408 |
"on shelf holds" policy is satisfied; useful to avoid infinite recursion with |
409 |
IsOnShelfHoldsPolicySatisfied and ItemsAnyAvailableAndNotRestricted |
407 |
|
410 |
|
408 |
@RETURNS { status => OK }, if the Item can be reserved. |
411 |
@RETURNS { status => OK }, if the Item can be reserved. |
|
|
412 |
{ status => onShelfHoldsNotAllowed }, if onShelfHoldsAllowed parameter and item availability combination doesn't allow holds. |
409 |
{ status => ageRestricted }, if the Item is age restricted for this borrower. |
413 |
{ status => ageRestricted }, if the Item is age restricted for this borrower. |
410 |
{ status => damaged }, if the Item is damaged. |
414 |
{ status => damaged }, if the Item is damaged. |
411 |
{ status => cannotReserveFromOtherBranches }, if syspref 'canreservefromotherbranches' is OK. |
415 |
{ status => cannotReserveFromOtherBranches }, if syspref 'canreservefromotherbranches' is OK. |
Lines 657-662
sub CanItemBeReserved {
Link Here
|
657 |
} |
661 |
} |
658 |
} |
662 |
} |
659 |
|
663 |
|
|
|
664 |
unless ( $params->{ignore_onshelfholds_policy} ) { |
665 |
unless ( IsOnShelfHoldsPolicySatisfied( { item => $item, patron => $patron } ) ) { |
666 |
return _cache { status => 'onShelfHoldsNotAllowed' }; |
667 |
} |
668 |
} |
669 |
|
660 |
return _cache { status => 'OK' }; |
670 |
return _cache { status => 'OK' }; |
661 |
} |
671 |
} |
662 |
|
672 |
|
Lines 1367-1395
sub IsAvailableForItemLevelRequest {
Link Here
|
1367 |
return 0 unless $branchitemrule->{hold_fulfillment_policy} ne 'holdgroup' || $home_library->validate_hold_sibling( {branchcode => $pickup_branchcode} ); |
1377 |
return 0 unless $branchitemrule->{hold_fulfillment_policy} ne 'holdgroup' || $home_library->validate_hold_sibling( {branchcode => $pickup_branchcode} ); |
1368 |
} |
1378 |
} |
1369 |
|
1379 |
|
1370 |
my $on_shelf_holds = Koha::CirculationRules->get_onshelfholds_policy( { item => $item, patron => $patron } ); |
1380 |
return IsOnShelfHoldsPolicySatisfied({ item => $item, patron => $patron }); |
1371 |
|
|
|
1372 |
if ( $on_shelf_holds == 1 ) { |
1373 |
return 1; |
1374 |
} elsif ( $on_shelf_holds == 2 ) { |
1375 |
|
1376 |
# These calculations work at the biblio level, and can be expensive |
1377 |
# we use the in-memory cache to avoid calling once per item when looping items on a biblio |
1378 |
|
1379 |
my $memory_cache = Koha::Cache::Memory::Lite->get_instance(); |
1380 |
my $cache_key = sprintf "ItemsAnyAvailableAndNotRestricted:%s:%s", $patron->id, $item->biblionumber; |
1381 |
|
1382 |
my $any_available = $memory_cache->get_from_cache($cache_key); |
1383 |
return $any_available ? 0 : 1 if defined($any_available); |
1384 |
|
1385 |
$any_available = |
1386 |
ItemsAnyAvailableAndNotRestricted( { biblionumber => $item->biblionumber, patron => $patron } ); |
1387 |
$memory_cache->set_in_cache( $cache_key, $any_available ); |
1388 |
return $any_available ? 0 : 1; |
1389 |
|
1390 |
} else { # on_shelf_holds == 0 "If any unavailable" (the description is rather cryptic and could still be improved) |
1391 |
return $item->notforloan < 0 || $item->onloan || IsItemOnHoldAndFound( $item->itemnumber ); |
1392 |
} |
1393 |
} |
1381 |
} |
1394 |
|
1382 |
|
1395 |
=head2 ItemsAnyAvailableAndNotRestricted |
1383 |
=head2 ItemsAnyAvailableAndNotRestricted |
Lines 1427-1438
sub ItemsAnyAvailableAndNotRestricted {
Link Here
|
1427 |
|| Koha::ItemTypes->find( $i->effective_itemtype() )->notforloan |
1415 |
|| Koha::ItemTypes->find( $i->effective_itemtype() )->notforloan |
1428 |
|| $branchitemrule->{holdallowed} eq 'from_home_library' && $param->{patron}->branchcode ne $i->homebranch |
1416 |
|| $branchitemrule->{holdallowed} eq 'from_home_library' && $param->{patron}->branchcode ne $i->homebranch |
1429 |
|| $branchitemrule->{holdallowed} eq 'from_local_hold_group' && ! $item_library->validate_hold_sibling( { branchcode => $param->{patron}->branchcode } ) |
1417 |
|| $branchitemrule->{holdallowed} eq 'from_local_hold_group' && ! $item_library->validate_hold_sibling( { branchcode => $param->{patron}->branchcode } ) |
1430 |
|| CanItemBeReserved( $param->{patron}, $i )->{status} ne 'OK'; |
1418 |
|| CanItemBeReserved( $param->{patron}, $i, undef, { ignore_onshelfholds_policy => 1 } )->{status} ne 'OK'; |
1431 |
} |
1419 |
} |
1432 |
|
1420 |
|
1433 |
return 0; |
1421 |
return 0; |
1434 |
} |
1422 |
} |
1435 |
|
1423 |
|
|
|
1424 |
=head2 IsOnShelfHoldsPolicySatisfied |
1425 |
|
1426 |
Verifies if a patron can place a hold on an item according to the "on shelf |
1427 |
holds" policy. |
1428 |
|
1429 |
Uses in-memory cache. |
1430 |
|
1431 |
$policy_ok = IsOnShelfHoldsPolicySatisfied({ item => $item, patron => $patron }) |
1432 |
|
1433 |
=head3 Parameters |
1434 |
|
1435 |
=over |
1436 |
|
1437 |
=item C<$item> - a Koha::Item object |
1438 |
|
1439 |
=item C<$patron> - a Koha::Patron object |
1440 |
|
1441 |
=back |
1442 |
|
1443 |
=head3 Return value |
1444 |
|
1445 |
a true value if the hold is possible, a false value otherwise |
1446 |
|
1447 |
=cut |
1448 |
|
1449 |
sub IsOnShelfHoldsPolicySatisfied { |
1450 |
my ($args) = @_; |
1451 |
my ( $item, $patron ) = @$args{qw(item patron)}; |
1452 |
|
1453 |
my $on_shelf_holds = Koha::CirculationRules->get_onshelfholds_policy( { item => $item, patron => $patron } ); |
1454 |
|
1455 |
if ( $on_shelf_holds == 1 ) { |
1456 |
return 1; |
1457 |
} |
1458 |
|
1459 |
if ( $on_shelf_holds == 2 ) { |
1460 |
|
1461 |
# These calculations work at the biblio level, and can be expensive |
1462 |
# we use the in-memory cache to avoid calling once per item when looping items on a biblio |
1463 |
|
1464 |
my $memory_cache = Koha::Cache::Memory::Lite->get_instance(); |
1465 |
my $cache_key = sprintf "ItemsAnyAvailableAndNotRestricted:%s:%s", $patron->id, $item->biblionumber; |
1466 |
|
1467 |
my $any_available = $memory_cache->get_from_cache($cache_key); |
1468 |
unless ( defined $any_available ) { |
1469 |
$any_available = |
1470 |
ItemsAnyAvailableAndNotRestricted( { biblionumber => $item->biblionumber, patron => $patron } ); |
1471 |
$memory_cache->set_in_cache( $cache_key, $any_available ); |
1472 |
} |
1473 |
|
1474 |
return $any_available ? 0 : 1; |
1475 |
} |
1476 |
|
1477 |
# on_shelf_holds == 0 "If any unavailable" (the description is rather cryptic and could still be improved) |
1478 |
return $item->notforloan < 0 || $item->onloan || IsItemOnHoldAndFound( $item->itemnumber ); |
1479 |
} |
1480 |
|
1436 |
=head2 AlterPriority |
1481 |
=head2 AlterPriority |
1437 |
|
1482 |
|
1438 |
AlterPriority( $where, $reserve_id, $prev_priority, $next_priority, $first_priority, $last_priority ); |
1483 |
AlterPriority( $where, $reserve_id, $prev_priority, $next_priority, $first_priority, $last_priority ); |