|
Lines 370-388
sub CanBookBeReserved{
Link Here
|
| 370 |
return { status =>'alreadypossession' }; |
370 |
return { status =>'alreadypossession' }; |
| 371 |
} |
371 |
} |
| 372 |
|
372 |
|
|
|
373 |
my @circulation_rules; |
| 374 |
|
| 373 |
if ( $params->{itemtype} ) { |
375 |
if ( $params->{itemtype} ) { |
| 374 |
|
376 |
|
| 375 |
# biblio-level, item type-contrained |
377 |
# biblio-level, item type-contrained |
| 376 |
my $patron = Koha::Patrons->find($borrowernumber); |
378 |
my $patron = Koha::Patrons->find($borrowernumber); |
| 377 |
my $reservesallowed = Koha::CirculationRules->get_effective_rule( |
379 |
my $reservesallowed_rule = Koha::CirculationRules->get_effective_rule( |
| 378 |
{ |
380 |
{ |
| 379 |
itemtype => $params->{itemtype}, |
381 |
itemtype => $params->{itemtype}, |
| 380 |
categorycode => $patron->categorycode, |
382 |
categorycode => $patron->categorycode, |
| 381 |
branchcode => $pickup_branchcode, |
383 |
branchcode => $pickup_branchcode, |
| 382 |
rule_name => 'reservesallowed', |
384 |
rule_name => 'reservesallowed', |
| 383 |
} |
385 |
} |
| 384 |
)->rule_value; |
386 |
); |
|
|
387 |
push @circulation_rules, $reservesallowed_rule if $reservesallowed_rule; |
| 385 |
|
388 |
|
|
|
389 |
my $reservesallowed = $reservesallowed_rule ? $reservesallowed_rule->rule_value : undef; |
| 386 |
$reservesallowed = ( $reservesallowed eq '' ) ? undef : $reservesallowed; |
390 |
$reservesallowed = ( $reservesallowed eq '' ) ? undef : $reservesallowed; |
| 387 |
|
391 |
|
| 388 |
my $count = $patron->holds->search( |
392 |
my $count = $patron->holds->search( |
|
Lines 397-403
sub CanBookBeReserved{
Link Here
|
| 397 |
} |
401 |
} |
| 398 |
)->count; |
402 |
)->count; |
| 399 |
|
403 |
|
| 400 |
return { status => '' } |
404 |
return { status => '', circulation_rules => \@circulation_rules } |
| 401 |
if defined $reservesallowed and $reservesallowed < $count + 1; |
405 |
if defined $reservesallowed and $reservesallowed < $count + 1; |
| 402 |
} |
406 |
} |
| 403 |
|
407 |
|
|
Lines 415-450
sub CanBookBeReserved{
Link Here
|
| 415 |
$items = Koha::Items->search({ biblionumber => $biblionumber}); |
419 |
$items = Koha::Items->search({ biblionumber => $biblionumber}); |
| 416 |
} |
420 |
} |
| 417 |
|
421 |
|
| 418 |
my $canReserve = { status => '' }; |
422 |
my $response = { status => '', item_responses => [] }; |
| 419 |
my $patron = Koha::Patrons->find( $borrowernumber ); |
423 |
my $patron = Koha::Patrons->find( $borrowernumber ); |
| 420 |
while ( my $item = $items->next ) { |
424 |
while ( my $item = $items->next ) { |
| 421 |
$canReserve = CanItemBeReserved( $patron, $item, $pickup_branchcode, $params ); |
425 |
my $itemResponse = CanItemBeReserved( $patron, $item, $pickup_branchcode, $params ); |
| 422 |
return { status => 'OK' } if $canReserve->{status} eq 'OK'; |
426 |
push @{ $response->{item_responses} }, { %$itemResponse, item => $item }; |
|
|
427 |
|
| 428 |
if ($itemResponse->{status} eq 'OK') { |
| 429 |
$response->{status} = 'OK'; |
| 430 |
|
| 431 |
return $response; |
| 432 |
} |
| 423 |
} |
433 |
} |
| 424 |
return $canReserve; |
434 |
|
|
|
435 |
return $response; |
| 425 |
} |
436 |
} |
| 426 |
|
437 |
|
| 427 |
=head2 CanItemBeReserved |
438 |
=head2 CanItemBeReserved |
| 428 |
|
439 |
|
| 429 |
$canReserve = &CanItemBeReserved($patron, $item, $branchcode, $params) |
440 |
$canReserve = CanItemBeReserved($patron, $item, $branchcode, $params) |
| 430 |
if ($canReserve->{status} eq 'OK') { #We can reserve this Item! } |
441 |
if ($canReserve->{status} eq 'OK') { #We can reserve this Item! } |
| 431 |
|
442 |
|
| 432 |
current params are: |
443 |
Current params are: |
| 433 |
'ignore_hold_counts' - we use this routine to check if an item can fill a hold - on this case we |
444 |
|
| 434 |
should not check if there are too many holds as we only care about reservability |
445 |
=over |
| 435 |
|
446 |
|
| 436 |
@RETURNS { status => OK }, if the Item can be reserved. |
447 |
=item * C<ignore_hold_counts> |
| 437 |
{ status => ageRestricted }, if the Item is age restricted for this borrower. |
448 |
|
| 438 |
{ status => damaged }, if the Item is damaged. |
449 |
we use this routine to check if an item can |
| 439 |
{ status => cannotReserveFromOtherBranches }, if syspref 'canreservefromotherbranches' is OK. |
450 |
fill a hold - on this case we should not check if there are too many holds as |
| 440 |
{ status => branchNotInHoldGroup }, if borrower home library is not in hold group, and holds are only allowed from hold groups. |
451 |
we only care about reservability |
| 441 |
{ status => tooManyReserves, limit => $limit }, if the borrower has exceeded their maximum reserve amount. |
452 |
|
| 442 |
{ status => notReservable }, if holds on this item are not allowed |
453 |
=back |
| 443 |
{ status => libraryNotFound }, if given branchcode is not an existing library |
454 |
|
| 444 |
{ status => libraryNotPickupLocation }, if given branchcode is not configured to be a pickup location |
455 |
Returns a hashref with the following keys: |
| 445 |
{ status => cannotBeTransferred }, if branch transfer limit applies on given item and branchcode |
456 |
|
| 446 |
{ status => pickupNotInHoldGroup }, pickup location is not in hold group, and pickup locations are only allowed from hold groups. |
457 |
=over |
| 447 |
{ status => recall }, if the borrower has already placed a recall on this item |
458 |
|
|
|
459 |
=item * C<status> |
| 460 |
|
| 461 |
A string that can have the following values: |
| 462 |
|
| 463 |
=over |
| 464 |
|
| 465 |
=item * C<OK> if the item can be reserved |
| 466 |
|
| 467 |
=item * C<ageRestricted> if the item is aged restricted for this borrower |
| 468 |
|
| 469 |
=item * C<damaged> if the item is damaged |
| 470 |
|
| 471 |
=item * C<cannotReserveFromOtherBranches> if syspref |
| 472 |
'canreservefromotherbranches' is OK |
| 473 |
|
| 474 |
=item * C<branchNotInHoldGroup> if borrower home library is not in hold group, |
| 475 |
and holds are only allowed from hold groups. |
| 476 |
|
| 477 |
=item * C<tooManyReserves> if the borrower has exceeded their maximum reserve |
| 478 |
amount. |
| 479 |
|
| 480 |
=item * C<tooManyHoldsForThisRecord> if the borrower has exceeded their maximum |
| 481 |
reserve amount for this biblio record |
| 482 |
|
| 483 |
=item * C<tooManyReservesToday> if the borrower has exceeded their maximum |
| 484 |
reserve amount for today |
| 485 |
|
| 486 |
=item * C<notReservable> if holds on this item are not allowed |
| 487 |
|
| 488 |
=item * C<libraryNotFound> if given branchcode is not an existing library |
| 489 |
|
| 490 |
=item * C<libraryNotPickupLocation> if given branchcode is not configured to be |
| 491 |
a pickup location |
| 492 |
|
| 493 |
=item * C<cannotBeTransferred> if branch transfer limit applies on given item |
| 494 |
and branchcode |
| 495 |
|
| 496 |
=item * C<pickupNotInHoldGroup> if pickup location is not in hold group, and |
| 497 |
pickup locations are only allowed from hold groups. |
| 498 |
|
| 499 |
=item * C<recall> if the borrower has already placed a recall on this item |
| 500 |
|
| 501 |
=back |
| 502 |
|
| 503 |
=item * C<limit> |
| 504 |
|
| 505 |
Only if C<status> is equal to C<tooManyReserves>, C<tooManyHoldsForThisRecord>, |
| 506 |
or C<tooManyReservesToday>. |
| 507 |
|
| 508 |
It contains the number of reserves allowed. |
| 509 |
|
| 510 |
=item * C<circulation_rules> |
| 511 |
|
| 512 |
An arrayref containing all circulations rules (L<Koha::CirculationRule>) that |
| 513 |
have been checked |
| 514 |
|
| 515 |
=back |
| 448 |
|
516 |
|
| 449 |
=cut |
517 |
=cut |
| 450 |
|
518 |
|
|
Lines 467-474
sub CanItemBeReserved {
Link Here
|
| 467 |
} |
535 |
} |
| 468 |
|
536 |
|
| 469 |
my $dbh = C4::Context->dbh; |
537 |
my $dbh = C4::Context->dbh; |
| 470 |
my $ruleitemtype; # itemtype of the matching issuing rule |
|
|
| 471 |
my $allowedreserves = 0; # Total number of holds allowed across all records, default to none |
| 472 |
|
538 |
|
| 473 |
# We check item branch if IndependentBranches is ON |
539 |
# We check item branch if IndependentBranches is ON |
| 474 |
# and canreservefromotherbranches is OFF |
540 |
# and canreservefromotherbranches is OFF |
|
Lines 520-553
sub CanItemBeReserved {
Link Here
|
| 520 |
$reserves_control_branch = $patron->branchcode; |
586 |
$reserves_control_branch = $patron->branchcode; |
| 521 |
} |
587 |
} |
| 522 |
|
588 |
|
| 523 |
# we retrieve rights |
589 |
my @circulation_rules; |
| 524 |
if ( |
|
|
| 525 |
my $reservesallowed = Koha::CirculationRules->get_effective_rule({ |
| 526 |
itemtype => $item->effective_itemtype, |
| 527 |
categorycode => $patron->categorycode, |
| 528 |
branchcode => $reserves_control_branch, |
| 529 |
rule_name => 'reservesallowed', |
| 530 |
}) |
| 531 |
) { |
| 532 |
$ruleitemtype = $reservesallowed->itemtype; |
| 533 |
$allowedreserves = $reservesallowed->rule_value // 0; #undefined is 0, blank is unlimited |
| 534 |
} |
| 535 |
else { |
| 536 |
$ruleitemtype = undef; |
| 537 |
} |
| 538 |
|
590 |
|
| 539 |
my $rights = Koha::CirculationRules->get_effective_rules({ |
591 |
my $holds_per_record_rule = Koha::CirculationRules->get_effective_rule({ |
| 540 |
categorycode => $patron->categorycode, |
592 |
categorycode => $patron->categorycode, |
| 541 |
itemtype => $item->effective_itemtype, |
593 |
itemtype => $item->effective_itemtype, |
| 542 |
branchcode => $reserves_control_branch, |
594 |
branchcode => $reserves_control_branch, |
| 543 |
rules => ['holds_per_record','holds_per_day'] |
595 |
rule_name => 'holds_per_record', |
| 544 |
}); |
596 |
}); |
| 545 |
my $holds_per_record = $rights->{holds_per_record} // 1; |
597 |
push @circulation_rules, $holds_per_record_rule if $holds_per_record_rule; |
| 546 |
my $holds_per_day = $rights->{holds_per_day}; |
598 |
|
|
|
599 |
my $holds_per_record = $holds_per_record_rule ? $holds_per_record_rule->rule_value : 1; |
| 547 |
|
600 |
|
| 548 |
if ( defined $holds_per_record && $holds_per_record ne '' ){ |
601 |
if ( defined $holds_per_record && $holds_per_record ne '' ){ |
| 549 |
if ( $holds_per_record == 0 ) { |
602 |
if ( $holds_per_record == 0 ) { |
| 550 |
return _cache { status => "noReservesAllowed" }; |
603 |
return _cache { status => "noReservesAllowed", circulation_rules => \@circulation_rules }; |
| 551 |
} |
604 |
} |
| 552 |
if ( !$params->{ignore_hold_counts} ) { |
605 |
if ( !$params->{ignore_hold_counts} ) { |
| 553 |
my $search_params = { |
606 |
my $search_params = { |
|
Lines 555-578
sub CanItemBeReserved {
Link Here
|
| 555 |
biblionumber => $item->biblionumber, |
608 |
biblionumber => $item->biblionumber, |
| 556 |
}; |
609 |
}; |
| 557 |
my $holds = Koha::Holds->search($search_params); |
610 |
my $holds = Koha::Holds->search($search_params); |
| 558 |
return _cache { status => "tooManyHoldsForThisRecord", limit => $holds_per_record } if $holds->count() >= $holds_per_record; |
611 |
|
|
|
612 |
if ($holds->count() >= $holds_per_record) { |
| 613 |
return _cache { |
| 614 |
status => "tooManyHoldsForThisRecord", |
| 615 |
limit => $holds_per_record, |
| 616 |
circulation_rules => \@circulation_rules, |
| 617 |
}; |
| 618 |
} |
| 559 |
} |
619 |
} |
| 560 |
} |
620 |
} |
| 561 |
|
621 |
|
|
|
622 |
my $holds_per_day_rule = Koha::CirculationRules->get_effective_rule({ |
| 623 |
categorycode => $patron->categorycode, |
| 624 |
itemtype => $item->effective_itemtype, |
| 625 |
branchcode => $reserves_control_branch, |
| 626 |
rule_name => 'holds_per_day', |
| 627 |
}); |
| 628 |
push @circulation_rules, $holds_per_day_rule if $holds_per_day_rule; |
| 629 |
|
| 630 |
my $holds_per_day = $holds_per_day_rule ? $holds_per_day_rule->rule_value : undef; |
| 562 |
if (!$params->{ignore_hold_counts} && defined $holds_per_day && $holds_per_day ne '') |
631 |
if (!$params->{ignore_hold_counts} && defined $holds_per_day && $holds_per_day ne '') |
| 563 |
{ |
632 |
{ |
| 564 |
my $today_holds = Koha::Holds->search({ |
633 |
my $today_holds = Koha::Holds->search({ |
| 565 |
borrowernumber => $patron->borrowernumber, |
634 |
borrowernumber => $patron->borrowernumber, |
| 566 |
reservedate => dt_from_string->date |
635 |
reservedate => dt_from_string->date |
| 567 |
}); |
636 |
}); |
| 568 |
return _cache { status => 'tooManyReservesToday', limit => $holds_per_day } if $today_holds->count() >= $holds_per_day; |
637 |
|
|
|
638 |
if ($today_holds->count() >= $holds_per_day) { |
| 639 |
return _cache { |
| 640 |
status => 'tooManyReservesToday', |
| 641 |
limit => $holds_per_day, |
| 642 |
circulation_rules => \@circulation_rules, |
| 643 |
}; |
| 644 |
} |
| 645 |
} |
| 646 |
|
| 647 |
my $reservesallowed_rule = Koha::CirculationRules->get_effective_rule({ |
| 648 |
itemtype => $item->effective_itemtype, |
| 649 |
categorycode => $patron->categorycode, |
| 650 |
branchcode => $reserves_control_branch, |
| 651 |
rule_name => 'reservesallowed', |
| 652 |
}); |
| 653 |
push @circulation_rules, $reservesallowed_rule if $reservesallowed_rule; |
| 654 |
|
| 655 |
my $ruleitemtype; # itemtype of the matching issuing rule |
| 656 |
my $allowedreserves = 0; # Total number of holds allowed across all records, default to none |
| 657 |
if ($reservesallowed_rule) { |
| 658 |
$ruleitemtype = $reservesallowed_rule->itemtype; |
| 659 |
$allowedreserves = $reservesallowed_rule->rule_value // 0; #undefined is 0, blank is unlimited |
| 569 |
} |
660 |
} |
| 570 |
|
661 |
|
| 571 |
# we check if it's ok or not |
662 |
# we check if it's ok or not |
| 572 |
if ( defined $allowedreserves && $allowedreserves ne '' ){ |
663 |
if ( defined $allowedreserves && $allowedreserves ne '' ){ |
| 573 |
if( $allowedreserves == 0 ){ |
664 |
if ( $allowedreserves == 0 ) { |
| 574 |
return _cache { status => 'noReservesAllowed' }; |
665 |
return _cache { |
|
|
666 |
status => 'noReservesAllowed', |
| 667 |
circulation_rules => \@circulation_rules, |
| 668 |
}; |
| 575 |
} |
669 |
} |
|
|
670 |
|
| 576 |
if ( !$params->{ignore_hold_counts} ) { |
671 |
if ( !$params->{ignore_hold_counts} ) { |
| 577 |
# we retrieve count |
672 |
# we retrieve count |
| 578 |
my $querycount = q{ |
673 |
my $querycount = q{ |
|
Lines 616-660
sub CanItemBeReserved {
Link Here
|
| 616 |
$reservecount = $rowcount->{count}; |
711 |
$reservecount = $rowcount->{count}; |
| 617 |
} |
712 |
} |
| 618 |
|
713 |
|
| 619 |
return _cache { status => 'tooManyReserves', limit => $allowedreserves } if $reservecount >= $allowedreserves; |
714 |
if ($reservecount >= $allowedreserves) { |
|
|
715 |
return _cache { |
| 716 |
status => 'tooManyReserves', |
| 717 |
limit => $allowedreserves, |
| 718 |
circulation_rules => \@circulation_rules, |
| 719 |
}; |
| 720 |
} |
| 620 |
} |
721 |
} |
| 621 |
} |
722 |
} |
| 622 |
|
723 |
|
| 623 |
# Now we need to check hold limits by patron category |
724 |
# Now we need to check hold limits by patron category |
| 624 |
my $rule = Koha::CirculationRules->get_effective_rule( |
725 |
my $max_holds_rule = Koha::CirculationRules->get_effective_rule( |
| 625 |
{ |
726 |
{ |
| 626 |
categorycode => $patron->categorycode, |
727 |
categorycode => $patron->categorycode, |
| 627 |
branchcode => $reserves_control_branch, |
728 |
branchcode => $reserves_control_branch, |
| 628 |
rule_name => 'max_holds', |
729 |
rule_name => 'max_holds', |
| 629 |
} |
730 |
} |
| 630 |
); |
731 |
); |
| 631 |
if (!$params->{ignore_hold_counts} && $rule && defined( $rule->rule_value ) && $rule->rule_value ne '' ) { |
732 |
push @circulation_rules, $max_holds_rule if $max_holds_rule; |
|
|
733 |
|
| 734 |
if (!$params->{ignore_hold_counts} && $max_holds_rule && defined( $max_holds_rule->rule_value ) && $max_holds_rule->rule_value ne '' ) { |
| 632 |
my $total_holds_count = Koha::Holds->search( |
735 |
my $total_holds_count = Koha::Holds->search( |
| 633 |
{ |
736 |
{ |
| 634 |
borrowernumber => $patron->borrowernumber |
737 |
borrowernumber => $patron->borrowernumber |
| 635 |
} |
738 |
} |
| 636 |
)->count(); |
739 |
)->count(); |
| 637 |
|
740 |
|
| 638 |
return _cache { status => 'tooManyReserves', limit => $rule->rule_value} if $total_holds_count >= $rule->rule_value; |
741 |
if ($total_holds_count >= $max_holds_rule->rule_value) { |
|
|
742 |
return _cache { |
| 743 |
status => 'tooManyReserves', |
| 744 |
limit => $max_holds_rule->rule_value, |
| 745 |
circulation_rules => \@circulation_rules, |
| 746 |
}; |
| 747 |
} |
| 639 |
} |
748 |
} |
| 640 |
|
749 |
|
|
|
750 |
my $holdallowed_rule = Koha::CirculationRules->get_effective_rule({ |
| 751 |
branchcode => $reserves_control_branch, |
| 752 |
itemtype => $item->effective_itemtype, |
| 753 |
rule_name => 'holdallowed', |
| 754 |
}); |
| 755 |
push @circulation_rules, $holdallowed_rule if $holdallowed_rule; |
| 756 |
|
| 641 |
my $branchitemrule = |
757 |
my $branchitemrule = |
| 642 |
C4::Circulation::GetBranchItemRule( $reserves_control_branch, $item->effective_itemtype ); |
758 |
C4::Circulation::GetBranchItemRule( $reserves_control_branch, $item->effective_itemtype ); |
| 643 |
|
759 |
|
| 644 |
if ( $branchitemrule->{holdallowed} eq 'not_allowed' ) { |
760 |
if ( $branchitemrule->{holdallowed} eq 'not_allowed' ) { |
| 645 |
return _cache { status => 'notReservable' }; |
761 |
return _cache { status => 'notReservable', circulation_rules => \@circulation_rules }; |
| 646 |
} |
762 |
} |
| 647 |
|
763 |
|
| 648 |
if ( $branchitemrule->{holdallowed} eq 'from_home_library' |
764 |
if ( $branchitemrule->{holdallowed} eq 'from_home_library' |
| 649 |
&& $patron->branchcode ne $item->homebranch ) |
765 |
&& $patron->branchcode ne $item->homebranch ) |
| 650 |
{ |
766 |
{ |
| 651 |
return _cache { status => 'cannotReserveFromOtherBranches' }; |
767 |
return _cache { status => 'cannotReserveFromOtherBranches', circulation_rules => \@circulation_rules }; |
| 652 |
} |
768 |
} |
| 653 |
|
769 |
|
| 654 |
my $item_library = Koha::Libraries->find( {branchcode => $item->homebranch} ); |
770 |
my $item_library = Koha::Libraries->find( {branchcode => $item->homebranch} ); |
| 655 |
if ( $branchitemrule->{holdallowed} eq 'from_local_hold_group') { |
771 |
if ( $branchitemrule->{holdallowed} eq 'from_local_hold_group') { |
| 656 |
if($patron->branchcode ne $item->homebranch && !$item_library->validate_hold_sibling( {branchcode => $patron->branchcode} )) { |
772 |
if($patron->branchcode ne $item->homebranch && !$item_library->validate_hold_sibling( {branchcode => $patron->branchcode} )) { |
| 657 |
return _cache { status => 'branchNotInHoldGroup' }; |
773 |
return _cache { status => 'branchNotInHoldGroup', circulation_rules => \@circulation_rules }; |
| 658 |
} |
774 |
} |
| 659 |
} |
775 |
} |
| 660 |
|
776 |
|
|
Lines 672-686
sub CanItemBeReserved {
Link Here
|
| 672 |
unless ($item->can_be_transferred({ to => $destination })) { |
788 |
unless ($item->can_be_transferred({ to => $destination })) { |
| 673 |
return _cache { status => 'cannotBeTransferred' }; |
789 |
return _cache { status => 'cannotBeTransferred' }; |
| 674 |
} |
790 |
} |
|
|
791 |
|
| 792 |
my $hold_fulfillment_policy_rule = Koha::CirculationRules->get_effective_rule({ |
| 793 |
branchcode => $reserves_control_branch, |
| 794 |
itemtype => $item->effective_itemtype, |
| 795 |
rule_name => 'hold_fulfillment_policy', |
| 796 |
}); |
| 797 |
push @circulation_rules, $hold_fulfillment_policy_rule if $hold_fulfillment_policy_rule; |
| 798 |
|
| 675 |
if ($branchitemrule->{hold_fulfillment_policy} eq 'holdgroup' && !$item_library->validate_hold_sibling( {branchcode => $pickup_branchcode} )) { |
799 |
if ($branchitemrule->{hold_fulfillment_policy} eq 'holdgroup' && !$item_library->validate_hold_sibling( {branchcode => $pickup_branchcode} )) { |
| 676 |
return _cache { status => 'pickupNotInHoldGroup' }; |
800 |
return _cache { status => 'pickupNotInHoldGroup', circulation_rules => \@circulation_rules }; |
| 677 |
} |
801 |
} |
| 678 |
if ($branchitemrule->{hold_fulfillment_policy} eq 'patrongroup' && !Koha::Libraries->find({branchcode => $patron->branchcode})->validate_hold_sibling({branchcode => $pickup_branchcode})) { |
802 |
if ($branchitemrule->{hold_fulfillment_policy} eq 'patrongroup' && !Koha::Libraries->find({branchcode => $patron->branchcode})->validate_hold_sibling({branchcode => $pickup_branchcode})) { |
| 679 |
return _cache { status => 'pickupNotInHoldGroup' }; |
803 |
return _cache { status => 'pickupNotInHoldGroup', circulation_rules => \@circulation_rules }; |
| 680 |
} |
804 |
} |
| 681 |
} |
805 |
} |
| 682 |
|
806 |
|
| 683 |
return _cache { status => 'OK' }; |
807 |
return _cache { status => 'OK', circulation_rules => \@circulation_rules }; |
| 684 |
} |
808 |
} |
| 685 |
|
809 |
|
| 686 |
=head2 ChargeReserveFee |
810 |
=head2 ChargeReserveFee |