|
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 ); |