View | Details | Raw Unified | Return to bug 11634
Collapse All | Expand All

(-)a/C4/Circulation.pm (+54 lines)
Lines 48-54 use Data::Dumper; Link Here
48
use Koha::DateUtils;
48
use Koha::DateUtils;
49
use Koha::Calendar;
49
use Koha::Calendar;
50
use Koha::Borrower::Debarments;
50
use Koha::Borrower::Debarments;
51
use Koha::Database;
51
use Carp;
52
use Carp;
53
use List::MoreUtils qw( uniq );
52
use Date::Calc qw(
54
use Date::Calc qw(
53
  Today
55
  Today
54
  Today_and_Now
56
  Today_and_Now
Lines 2637-2642 sub CanBookBeRenewed { Link Here
2637
2639
2638
    my ( $resfound, $resrec, undef ) = C4::Reserves::CheckReserves($itemnumber);
2640
    my ( $resfound, $resrec, undef ) = C4::Reserves::CheckReserves($itemnumber);
2639
2641
2642
    # This item can fill one or more unfilled reserve, can those unfilled reserves
2643
    # all be filled by other available items?
2644
    if ( $resfound
2645
        && C4::Context->preference('AllowRenewalIfOtherItemsAvailable') )
2646
    {
2647
        my $schema = Koha::Database->new()->schema();
2648
2649
        # Get all other items that could possibly fill reserves
2650
        my @itemnumbers = $schema->resultset('Item')->search(
2651
            {
2652
                biblionumber => $resrec->{biblionumber},
2653
                onloan       => undef,
2654
                -not         => { itemnumber => $itemnumber }
2655
            },
2656
            { columns => 'itemnumber' }
2657
        )->get_column('itemnumber')->all();
2658
2659
        # Get all other reserves that could have been filled by this item
2660
        my @borrowernumbers;
2661
        while (1) {
2662
            my ( $reserve_found, $reserve, undef ) =
2663
              C4::Reserves::CheckReserves( $itemnumber, undef, undef,
2664
                \@borrowernumbers );
2665
2666
            if ($reserve_found) {
2667
                push( @borrowernumbers, $reserve->{borrowernumber} );
2668
            }
2669
            else {
2670
                last;
2671
            }
2672
        }
2673
2674
        # If the count of the union of the lists of reservable items for each borrower
2675
        # is equal or greater than the number of borrowers, we know that all reserves
2676
        # can be filled with available items. We can get the union of the sets simply
2677
        # by pushing all the elements onto an array and removing the duplicates.
2678
        my @reservable;
2679
        foreach my $b (@borrowernumbers) {
2680
            foreach my $i (@itemnumbers) {
2681
                if ( CanItemBeReserved( $b, $i ) ) {
2682
                    push( @reservable, $i );
2683
                }
2684
            }
2685
        }
2686
2687
        @reservable = uniq(@reservable);
2688
2689
        if ( @reservable >= @borrowernumbers ) {
2690
            $resfound = 0;
2691
        }
2692
    }
2693
2640
    return ( 0, "on_reserve" ) if $resfound;    # '' when no hold was found
2694
    return ( 0, "on_reserve" ) if $resfound;    # '' when no hold was found
2641
2695
2642
    return ( 1, undef ) if $override_limit;
2696
    return ( 1, undef ) if $override_limit;
(-)a/C4/Reserves.pm (-8 / +11 lines)
Lines 41-47 use Koha::DateUtils; Link Here
41
use Koha::Calendar;
41
use Koha::Calendar;
42
use Koha::Database;
42
use Koha::Database;
43
43
44
use List::MoreUtils qw( firstidx );
44
use List::MoreUtils qw( firstidx any );
45
45
46
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
46
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
47
47
Lines 904-910 table in the Koha database. Link Here
904
=cut
904
=cut
905
905
906
sub CheckReserves {
906
sub CheckReserves {
907
    my ( $item, $barcode, $lookahead_days) = @_;
907
    my ( $item, $barcode, $lookahead_days, $ignore_borrowers) = @_;
908
    my $dbh = C4::Context->dbh;
908
    my $dbh = C4::Context->dbh;
909
    my $sth;
909
    my $sth;
910
    my $select;
910
    my $select;
Lines 955-961 sub CheckReserves { Link Here
955
    return if  ( $notforloan_per_item > 0 ) or $notforloan_per_itemtype;
955
    return if  ( $notforloan_per_item > 0 ) or $notforloan_per_itemtype;
956
956
957
    # Find this item in the reserves
957
    # Find this item in the reserves
958
    my @reserves = _Findgroupreserve( $bibitem, $biblio, $itemnumber, $lookahead_days);
958
    my @reserves = _Findgroupreserve( $bibitem, $biblio, $itemnumber, $lookahead_days, $ignore_borrowers);
959
959
960
    # $priority and $highest are used to find the most important item
960
    # $priority and $highest are used to find the most important item
961
    # in the list returned by &_Findgroupreserve. (The lower $priority,
961
    # in the list returned by &_Findgroupreserve. (The lower $priority,
Lines 1813-1819 sub _FixPriority { Link Here
1813
1813
1814
=head2 _Findgroupreserve
1814
=head2 _Findgroupreserve
1815
1815
1816
  @results = &_Findgroupreserve($biblioitemnumber, $biblionumber, $itemnumber, $lookahead);
1816
  @results = &_Findgroupreserve($biblioitemnumber, $biblionumber, $itemnumber, $lookahead, $ignore_borrowers);
1817
1817
1818
Looks for an item-specific match first, then for a title-level match, returning the
1818
Looks for an item-specific match first, then for a title-level match, returning the
1819
first match found.  If neither, then we look for a 3rd kind of match based on
1819
first match found.  If neither, then we look for a 3rd kind of match based on
Lines 1830-1836 C<biblioitemnumber>. Link Here
1830
=cut
1830
=cut
1831
1831
1832
sub _Findgroupreserve {
1832
sub _Findgroupreserve {
1833
    my ( $bibitem, $biblio, $itemnumber, $lookahead) = @_;
1833
    my ( $bibitem, $biblio, $itemnumber, $lookahead, $ignore_borrowers) = @_;
1834
    my $dbh   = C4::Context->dbh;
1834
    my $dbh   = C4::Context->dbh;
1835
1835
1836
    # TODO: consolidate at least the SELECT portion of the first 2 queries to a common $select var.
1836
    # TODO: consolidate at least the SELECT portion of the first 2 queries to a common $select var.
Lines 1862-1868 sub _Findgroupreserve { Link Here
1862
    $sth->execute($itemnumber, $lookahead||0);
1862
    $sth->execute($itemnumber, $lookahead||0);
1863
    my @results;
1863
    my @results;
1864
    if ( my $data = $sth->fetchrow_hashref ) {
1864
    if ( my $data = $sth->fetchrow_hashref ) {
1865
        push( @results, $data );
1865
        push( @results, $data )
1866
          unless any{ $data->{borrowernumber} eq $_ } @$ignore_borrowers ;
1866
    }
1867
    }
1867
    return @results if @results;
1868
    return @results if @results;
1868
    
1869
    
Lines 1894-1900 sub _Findgroupreserve { Link Here
1894
    $sth->execute($itemnumber, $lookahead||0);
1895
    $sth->execute($itemnumber, $lookahead||0);
1895
    @results = ();
1896
    @results = ();
1896
    if ( my $data = $sth->fetchrow_hashref ) {
1897
    if ( my $data = $sth->fetchrow_hashref ) {
1897
        push( @results, $data );
1898
        push( @results, $data )
1899
          unless any{ $data->{borrowernumber} eq $_ } @$ignore_borrowers ;
1898
    }
1900
    }
1899
    return @results if @results;
1901
    return @results if @results;
1900
1902
Lines 1927-1933 sub _Findgroupreserve { Link Here
1927
    $sth->execute( $biblio, $bibitem, $itemnumber, $lookahead||0);
1929
    $sth->execute( $biblio, $bibitem, $itemnumber, $lookahead||0);
1928
    @results = ();
1930
    @results = ();
1929
    while ( my $data = $sth->fetchrow_hashref ) {
1931
    while ( my $data = $sth->fetchrow_hashref ) {
1930
        push( @results, $data );
1932
        push( @results, $data )
1933
          unless any{ $data->{borrowernumber} eq $_ } @$ignore_borrowers ;
1931
    }
1934
    }
1932
    return @results;
1935
    return @results;
1933
}
1936
}
(-)a/installer/data/mysql/sysprefs.sql (+1 lines)
Lines 28-33 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
28
('AllowOnShelfHolds','0','','Allow hold requests to be placed on items that are not on loan','YesNo'),
28
('AllowOnShelfHolds','0','','Allow hold requests to be placed on items that are not on loan','YesNo'),
29
('AllowPKIAuth','None','None|Common Name|emailAddress','Use the field from a client-side SSL certificate to look a user in the Koha database','Choice'),
29
('AllowPKIAuth','None','None|Common Name|emailAddress','Use the field from a client-side SSL certificate to look a user in the Koha database','Choice'),
30
('AllowPurchaseSuggestionBranchChoice','0','1','Allow user to choose branch when making a purchase suggestion','YesNo'),
30
('AllowPurchaseSuggestionBranchChoice','0','1','Allow user to choose branch when making a purchase suggestion','YesNo'),
31
('AllowRenewalIfOtherItemsAvailable','0',NULL,'If enabled, allow a patron to renew an item with unfilled holds if other available items can fill that hold.','YesNo'),
31
('AllowRenewalLimitOverride','0',NULL,'if ON, allows renewal limits to be overridden on the circulation screen','YesNo'),
32
('AllowRenewalLimitOverride','0',NULL,'if ON, allows renewal limits to be overridden on the circulation screen','YesNo'),
32
('AllowReturnToBranch','anywhere','anywhere|homebranch|holdingbranch|homeorholdingbranch','Where an item may be returned','Choice'),
33
('AllowReturnToBranch','anywhere','anywhere|homebranch|holdingbranch|homeorholdingbranch','Where an item may be returned','Choice'),
33
('AllowSelfCheckReturns','0','','If enabled, patrons may return items through the Web-based Self Checkout','YesNo'),
34
('AllowSelfCheckReturns','0','','If enabled, patrons may return items through the Web-based Self Checkout','YesNo'),
(-)a/installer/data/mysql/updatedatabase.pl (+10 lines)
Lines 8891-8896 if ( CheckVersion($DBversion) ) { Link Here
8891
    SetVersion($DBversion);
8891
    SetVersion($DBversion);
8892
}
8892
}
8893
8893
8894
$DBversion = "3.17.00.XXX";
8895
if (CheckVersion($DBversion)) {
8896
    $dbh->do(q{
8897
        INSERT INTO systempreferences ( variable, value, options, explanation, type ) VALUES
8898
        ('AllowRenewalIfOtherItemsAvailable','0',NULL,'If enabled, allow a patron to renew an item with unfilled holds if other available items can fill that hold.','YesNo')
8899
    });
8900
    print "Upgrade to $DBversion done (Bug 11634 - Allow renewal of item with unfilled holds if other available items can fill those holds)\n";
8901
    SetVersion($DBversion);
8902
}
8903
8894
=head1 FUNCTIONS
8904
=head1 FUNCTIONS
8895
8905
8896
=head2 TableExists($table)
8906
=head2 TableExists($table)
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (-1 / +6 lines)
Lines 385-390 Circulation: Link Here
385
            - Each pair of values should be on a separate line.
385
            - Each pair of values should be on a separate line.
386
    Holds Policy:
386
    Holds Policy:
387
        -
387
        -
388
            - pref: AllowRenewalIfOtherItemsAvailable
389
              choices:
390
                  yes: Allow
391
                  no: "Don't allow"
392
            - a patron to renew an item with unfilled holds if other available items can fill that hold.
393
        -
388
            - pref: AllowHoldPolicyOverride
394
            - pref: AllowHoldPolicyOverride
389
              choices:
395
              choices:
390
                  yes: Allow
396
                  yes: Allow
391
- 

Return to bug 11634