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