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 2494-2499 sub CanBookBeRenewed { Link Here
2494
2496
2495
    my ( $resfound, $resrec, undef ) = C4::Reserves::CheckReserves( $itemnumber );
2497
    my ( $resfound, $resrec, undef ) = C4::Reserves::CheckReserves( $itemnumber );
2496
2498
2499
    # This item can fill one or more unfilled reserve, can those unfilled reserves
2500
    # all be filled by other available items?
2501
    if ( $resfound
2502
        && C4::Context->preference('AllowRenewalIfOtherItemsAvailable') )
2503
    {
2504
        my $schema = Koha::Database->new()->schema();
2505
2506
        # Get all other items that could possibly fill reserves
2507
        my @itemnumbers = $schema->resultset('Item')->search(
2508
            {
2509
                biblionumber => $resrec->{biblionumber},
2510
                onloan       => undef,
2511
                -not         => { itemnumber => $itemnumber }
2512
            },
2513
            { columns => 'itemnumber' }
2514
        )->get_column('itemnumber')->all();
2515
2516
        # Get all other reserves that could have been filled by this item
2517
        my @borrowernumbers;
2518
        while (1) {
2519
            my ( $reserve_found, $reserve, undef ) =
2520
              C4::Reserves::CheckReserves( $itemnumber, undef, undef,
2521
                \@borrowernumbers );
2522
2523
            if ($reserve_found) {
2524
                push( @borrowernumbers, $reserve->{borrowernumber} );
2525
            }
2526
            else {
2527
                last;
2528
            }
2529
        }
2530
2531
        # If the count of the union of the lists of reservable items for each borrower
2532
        # is equal or greater than the number of borrowers, we know that all reserves
2533
        # can be filled with available items. We can get the union of the sets simply
2534
        # by pushing all the elements onto an array and removing the duplicates.
2535
        my @reservable;
2536
        foreach my $b (@borrowernumbers) {
2537
            foreach my $i (@itemnumbers) {
2538
                if ( CanItemBeReserved( $b, $i ) ) {
2539
                    push( @reservable, $i );
2540
                }
2541
            }
2542
        }
2543
2544
        @reservable = uniq(@reservable);
2545
2546
        if ( @reservable >= @borrowernumbers ) {
2547
            $resfound = 0;
2548
        }
2549
    }
2550
2497
    if ( $resfound ) { # '' when no hold was found
2551
    if ( $resfound ) { # '' when no hold was found
2498
        $renewokay = 0;
2552
        $renewokay = 0;
2499
        $error = "on_reserve";
2553
        $error = "on_reserve";
(-)a/C4/Reserves.pm (-8 / +11 lines)
Lines 39-45 use C4::Dates qw( format_date_in_iso ); Link Here
39
39
40
use Koha::DateUtils;
40
use Koha::DateUtils;
41
41
42
use List::MoreUtils qw( firstidx );
42
use List::MoreUtils qw( firstidx any );
43
43
44
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
44
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
45
45
Lines 846-852 table in the Koha database. Link Here
846
=cut
846
=cut
847
847
848
sub CheckReserves {
848
sub CheckReserves {
849
    my ( $item, $barcode, $lookahead_days) = @_;
849
    my ( $item, $barcode, $lookahead_days, $ignore_borrowers) = @_;
850
    my $dbh = C4::Context->dbh;
850
    my $dbh = C4::Context->dbh;
851
    my $sth;
851
    my $sth;
852
    my $select;
852
    my $select;
Lines 893-899 sub CheckReserves { Link Here
893
    return ( '' ) if  ( $notforloan_per_item > 0 ) or $notforloan_per_itemtype;
893
    return ( '' ) if  ( $notforloan_per_item > 0 ) or $notforloan_per_itemtype;
894
894
895
    # Find this item in the reserves
895
    # Find this item in the reserves
896
    my @reserves = _Findgroupreserve( $bibitem, $biblio, $itemnumber, $lookahead_days);
896
    my @reserves = _Findgroupreserve( $bibitem, $biblio, $itemnumber, $lookahead_days, $ignore_borrowers);
897
897
898
    # $priority and $highest are used to find the most important item
898
    # $priority and $highest are used to find the most important item
899
    # in the list returned by &_Findgroupreserve. (The lower $priority,
899
    # in the list returned by &_Findgroupreserve. (The lower $priority,
Lines 1727-1733 sub _FixPriority { Link Here
1727
1727
1728
=head2 _Findgroupreserve
1728
=head2 _Findgroupreserve
1729
1729
1730
  @results = &_Findgroupreserve($biblioitemnumber, $biblionumber, $itemnumber, $lookahead);
1730
  @results = &_Findgroupreserve($biblioitemnumber, $biblionumber, $itemnumber, $lookahead, $ignore_borrowers);
1731
1731
1732
Looks for an item-specific match first, then for a title-level match, returning the
1732
Looks for an item-specific match first, then for a title-level match, returning the
1733
first match found.  If neither, then we look for a 3rd kind of match based on
1733
first match found.  If neither, then we look for a 3rd kind of match based on
Lines 1744-1750 C<biblioitemnumber>. Link Here
1744
=cut
1744
=cut
1745
1745
1746
sub _Findgroupreserve {
1746
sub _Findgroupreserve {
1747
    my ( $bibitem, $biblio, $itemnumber, $lookahead) = @_;
1747
    my ( $bibitem, $biblio, $itemnumber, $lookahead, $ignore_borrowers) = @_;
1748
    my $dbh   = C4::Context->dbh;
1748
    my $dbh   = C4::Context->dbh;
1749
1749
1750
    # TODO: consolidate at least the SELECT portion of the first 2 queries to a common $select var.
1750
    # TODO: consolidate at least the SELECT portion of the first 2 queries to a common $select var.
Lines 1776-1782 sub _Findgroupreserve { Link Here
1776
    $sth->execute($itemnumber, $lookahead||0);
1776
    $sth->execute($itemnumber, $lookahead||0);
1777
    my @results;
1777
    my @results;
1778
    if ( my $data = $sth->fetchrow_hashref ) {
1778
    if ( my $data = $sth->fetchrow_hashref ) {
1779
        push( @results, $data );
1779
        push( @results, $data )
1780
          unless any{ $data->{borrowernumber} eq $_ } @$ignore_borrowers ;
1780
    }
1781
    }
1781
    return @results if @results;
1782
    return @results if @results;
1782
    
1783
    
Lines 1807-1813 sub _Findgroupreserve { Link Here
1807
    $sth->execute($itemnumber, $lookahead||0);
1808
    $sth->execute($itemnumber, $lookahead||0);
1808
    @results = ();
1809
    @results = ();
1809
    if ( my $data = $sth->fetchrow_hashref ) {
1810
    if ( my $data = $sth->fetchrow_hashref ) {
1810
        push( @results, $data );
1811
        push( @results, $data )
1812
          unless any{ $data->{borrowernumber} eq $_ } @$ignore_borrowers ;
1811
    }
1813
    }
1812
    return @results if @results;
1814
    return @results if @results;
1813
1815
Lines 1839-1845 sub _Findgroupreserve { Link Here
1839
    $sth->execute( $biblio, $bibitem, $itemnumber, $lookahead||0);
1841
    $sth->execute( $biblio, $bibitem, $itemnumber, $lookahead||0);
1840
    @results = ();
1842
    @results = ();
1841
    while ( my $data = $sth->fetchrow_hashref ) {
1843
    while ( my $data = $sth->fetchrow_hashref ) {
1842
        push( @results, $data );
1844
        push( @results, $data )
1845
          unless any{ $data->{borrowernumber} eq $_ } @$ignore_borrowers ;
1843
    }
1846
    }
1844
    return @results;
1847
    return @results;
1845
}
1848
}
(-)a/installer/data/mysql/sysprefs.sql (+1 lines)
Lines 23-28 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
23
('AllowOnShelfHolds','0','','Allow hold requests to be placed on items that are not on loan','YesNo'),
23
('AllowOnShelfHolds','0','','Allow hold requests to be placed on items that are not on loan','YesNo'),
24
('AllowPKIAuth','None','None|Common Name|emailAddress','Use the field from a client-side SSL certificate to look a user in the Koha database','Choice'),
24
('AllowPKIAuth','None','None|Common Name|emailAddress','Use the field from a client-side SSL certificate to look a user in the Koha database','Choice'),
25
('AllowPurchaseSuggestionBranchChoice','0','1','Allow user to choose branch when making a purchase suggestion','YesNo'),
25
('AllowPurchaseSuggestionBranchChoice','0','1','Allow user to choose branch when making a purchase suggestion','YesNo'),
26
('AllowRenewalIfOtherItemsAvailable','0',NULL,'If enabled, allow a patron to renew an item with unfilled holds if other available items can fill that hold.','YesNo'),
26
('AllowRenewalLimitOverride','0',NULL,'if ON, allows renewal limits to be overridden on the circulation screen','YesNo'),
27
('AllowRenewalLimitOverride','0',NULL,'if ON, allows renewal limits to be overridden on the circulation screen','YesNo'),
27
('AllowReturnToBranch','anywhere','anywhere|homebranch|holdingbranch|homeorholdingbranch','Where an item may be returned','Choice'),
28
('AllowReturnToBranch','anywhere','anywhere|homebranch|holdingbranch|homeorholdingbranch','Where an item may be returned','Choice'),
28
('AllowSelfCheckReturns','0','','If enabled, patrons may return items through the Web-based Self Checkout','YesNo'),
29
('AllowSelfCheckReturns','0','','If enabled, patrons may return items through the Web-based Self Checkout','YesNo'),
(-)a/installer/data/mysql/updatedatabase.pl (+10 lines)
Lines 7945-7950 if (CheckVersion($DBversion)) { Link Here
7945
    SetVersion($DBversion);
7945
    SetVersion($DBversion);
7946
}
7946
}
7947
7947
7948
$DBversion = "3.15.00.XXX";
7949
if (CheckVersion($DBversion)) {
7950
    $dbh->do(q{
7951
        INSERT INTO systempreferences ( variable, value, options, explanation, type ) VALUES
7952
        ('AllowRenewalIfOtherItemsAvailable','0',NULL,'If enabled, allow a patron to renew an item with unfilled holds if other available items can fill that hold.','YesNo')
7953
    });
7954
    print "Upgrade to $DBversion done (Bug 11634 - Allow renewal of item with unfilled holds if other available items can fill those holds)\n";
7955
    SetVersion($DBversion);
7956
}
7957
7948
=head1 FUNCTIONS
7958
=head1 FUNCTIONS
7949
7959
7950
=head2 TableExists($table)
7960
=head2 TableExists($table)
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (-1 / +6 lines)
Lines 353-358 Circulation: Link Here
353
            - <br /><b>NOTE If you are doing hourly loans then you should have this on.</b>
353
            - <br /><b>NOTE If you are doing hourly loans then you should have this on.</b>
354
    Holds Policy:
354
    Holds Policy:
355
        -
355
        -
356
            - pref: AllowRenewalIfOtherItemsAvailable
357
              choices:
358
                  yes: Allow
359
                  no: "Don't allow"
360
            - a patron to renew an item with unfilled holds if other available items can fill that hold.
361
        -
356
            - pref: AllowHoldPolicyOverride
362
            - pref: AllowHoldPolicyOverride
357
              choices:
363
              choices:
358
                  yes: Allow
364
                  yes: Allow
359
- 

Return to bug 11634