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

(-)a/C4/Circulation.pm (-1 / +24 lines)
Lines 1273-1278 sub CanBookBeIssued { Link Here
1273
                }
1273
                }
1274
            }
1274
            }
1275
        }
1275
        }
1276
1277
        if ( C4::Context->preference("PreventCheckoutOnSameReservePeriod") ) {
1278
            my $now                     = dt_from_string();
1279
            my $reserves_on_same_period = C4::Reserves::ReservesOnSamePeriod(
1280
                $item_object->biblionumber, $item_object->itemnumber, $now->ymd,
1281
                $duedate->ymd
1282
            );
1283
            if ($reserves_on_same_period) {
1284
                my $reserve = $reserves_on_same_period->[0];
1285
                if ( $reserve->{borrowernumber} ne $patron->borrowernumber ) {
1286
                    my $patron = Koha::Patrons->find( $reserve->{borrowernumber} );
1287
                    $needsconfirmation{RESERVED}          = 1;
1288
                    $needsconfirmation{resfirstname}      = $patron->firstname;
1289
                    $needsconfirmation{ressurname}        = $patron->surname;
1290
                    $needsconfirmation{rescardnumber}     = $patron->cardnumber;
1291
                    $needsconfirmation{resborrowernumber} = $patron->borrowernumber;
1292
                    $needsconfirmation{resbranchcode}     = $patron->branchcode;
1293
                    $needsconfirmation{resreservedate}    = $reserve->{reservedate};
1294
                    $needsconfirmation{reserve_id}        = $reserve->{reserve_id};
1295
                }
1296
            }
1297
        }
1298
1276
    }
1299
    }
1277
1300
1278
    ## CHECK FOR BOOKINGS
1301
    ## CHECK FOR BOOKINGS
Lines 3177-3183 already renewed the loan. Link Here
3177
=cut
3200
=cut
3178
3201
3179
sub CanBookBeRenewed {
3202
sub CanBookBeRenewed {
3180
    my ( $patron, $issue, $override_limit, $cron ) = @_;
3203
    my ( $patron, $issue, $override_limit, $cron, $date_due ) = @_;
3181
3204
3182
    my $auto_renew = "no";
3205
    my $auto_renew = "no";
3183
    my $soonest;
3206
    my $soonest;
(-)a/C4/ILSDI/Services.pm (-1 / +14 lines)
Lines 24-30 use C4::Members; Link Here
24
use C4::Items       qw( get_hostitemnumbers_of );
24
use C4::Items       qw( get_hostitemnumbers_of );
25
use C4::Circulation qw( CanBookBeRenewed barcodedecode CanBookBeIssued AddRenewal );
25
use C4::Circulation qw( CanBookBeRenewed barcodedecode CanBookBeIssued AddRenewal );
26
use C4::Accounts;
26
use C4::Accounts;
27
use C4::Reserves qw( CanBookBeReserved IsAvailableForItemLevelRequest CalculatePriority AddReserve CanItemBeReserved );
27
use C4::Reserves
28
    qw( CanBookBeReserved IsAvailableForItemLevelRequest CalculatePriority AddReserve CanItemBeReserved ReservesOnSamePeriod);
28
use C4::Context;
29
use C4::Context;
29
use C4::Auth;
30
use C4::Auth;
30
use CGI qw ( -utf8 );
31
use CGI qw ( -utf8 );
Lines 816-821 sub HoldTitle { Link Here
816
    my $resdate = $cgi->param('start_date');
817
    my $resdate = $cgi->param('start_date');
817
    my $expdate = $cgi->param('expiry_date');
818
    my $expdate = $cgi->param('expiry_date');
818
819
820
    if ( C4::Context->preference('PreventReservesOnSamePeriod')
821
        && ReservesOnSamePeriod( $biblionumber, undef, $resdate, $expdate ) )
822
    {
823
        return { code => 'overlap' };
824
    }
825
819
    # Add the reserve
826
    # Add the reserve
820
    #    $branch,    $borrowernumber, $biblionumber,
827
    #    $branch,    $borrowernumber, $biblionumber,
821
    #    $constraint, $bibitems,  $priority, $resdate, $expdate, $notes,
828
    #    $constraint, $bibitems,  $priority, $resdate, $expdate, $notes,
Lines 912-917 sub HoldItem { Link Here
912
    my $resdate = $cgi->param('start_date');
919
    my $resdate = $cgi->param('start_date');
913
    my $expdate = $cgi->param('expiry_date');
920
    my $expdate = $cgi->param('expiry_date');
914
921
922
    if ( C4::Context->preference('PreventReservesOnSamePeriod')
923
        && ReservesOnSamePeriod( $biblionumber, $itemnumber, $resdate, $expdate ) )
924
    {
925
        return { code => 'overlap' };
926
    }
927
915
    # Add the reserve
928
    # Add the reserve
916
    my $priority = C4::Reserves::CalculatePriority($biblionumber);
929
    my $priority = C4::Reserves::CalculatePriority($biblionumber);
917
    AddReserve(
930
    AddReserve(
(-)a/C4/Reserves.pm (-1 / +57 lines)
Lines 40-46 use Koha::Calendar; Link Here
40
use Koha::Cache::Memory::Lite;
40
use Koha::Cache::Memory::Lite;
41
use Koha::CirculationRules;
41
use Koha::CirculationRules;
42
use Koha::Database;
42
use Koha::Database;
43
use Koha::DateUtils qw( dt_from_string output_pref );
43
use Koha::DateUtils qw( dt_from_string output_pref date_ranges_overlap );
44
use Koha::Holds;
44
use Koha::Holds;
45
use Koha::ItemTypes;
45
use Koha::ItemTypes;
46
use Koha::Items;
46
use Koha::Items;
Lines 139-144 BEGIN { Link Here
139
        GetMaxPatronHoldsForRecord
139
        GetMaxPatronHoldsForRecord
140
140
141
        MergeHolds
141
        MergeHolds
142
143
        RevertWaitingStatus
144
145
        ReservesOnSamePeriod
142
    );
146
    );
143
}
147
}
144
148
Lines 2424-2429 sub GetMaxPatronHoldsForRecord { Link Here
2424
    return $max;
2428
    return $max;
2425
}
2429
}
2426
2430
2431
=head2 ReservesOnSamePeriod
2432
2433
    my $reserve = ReservesOnSamePeriod( $biblionumber, $itemnumber, $resdate, $expdate);
2434
2435
    Return the reserve that match the period ($resdate => $expdate),
2436
    undef if no reserve match.
2437
2438
=cut
2439
2440
sub ReservesOnSamePeriod {
2441
    my ( $biblionumber, $itemnumber, $resdate, $expdate ) = @_;
2442
2443
    unless ( $resdate && $expdate ) {
2444
        return;
2445
    }
2446
2447
    my @reserves = Koha::Holds->search( { biblionumber => $biblionumber } )->as_list;
2448
2449
    $resdate = output_pref( { str => $resdate, dateonly => 1, dateformat => 'iso' } );
2450
    $expdate = output_pref( { str => $expdate, dateonly => 1, dateformat => 'iso' } );
2451
2452
    my @reserves_overlaps;
2453
    foreach my $reserve (@reserves) {
2454
2455
        unless ( $reserve->reservedate && $reserve->expirationdate ) {
2456
            next;
2457
        }
2458
2459
        if (
2460
            date_ranges_overlap(
2461
                $resdate, $expdate,
2462
                $reserve->reservedate,
2463
                $reserve->expirationdate
2464
            )
2465
            )
2466
        {
2467
2468
            # If reserve is item level and the requested periods overlap.
2469
            if ( $itemnumber && $reserve->itemnumber && $reserve->itemnumber == $itemnumber ) {
2470
                return [ $reserve->unblessed ];
2471
            }
2472
            push @reserves_overlaps, $reserve->unblessed;
2473
        }
2474
    }
2475
2476
    if ( @reserves_overlaps >= Koha::Items->search( { biblionumber => $biblionumber } )->count() ) {
2477
        return \@reserves_overlaps;
2478
    }
2479
2480
    return;
2481
}
2482
2427
=head1 AUTHOR
2483
=head1 AUTHOR
2428
2484
2429
Koha Development Team <https://koha-community.org/>
2485
Koha Development Team <https://koha-community.org/>
(-)a/Koha/DateUtils.pm (+37 lines)
Lines 33-38 BEGIN { Link Here
33
        output_pref
33
        output_pref
34
        format_sqldatetime
34
        format_sqldatetime
35
        flatpickr_date_format
35
        flatpickr_date_format
36
        date_ranges_overlap
36
    );
37
    );
37
}
38
}
38
39
Lines 393-396 sub flatpickr_date_format { Link Here
393
    }->{$arg};
394
    }->{$arg};
394
}
395
}
395
396
397
=head2 date_ranges_overlap
398
399
    $bool = date_ranges_overlap($start1, $end1, $start2, $end2);
400
401
    Tells if first range ($start1 => $end1) overlaps
402
    the second one ($start2 => $end2)
403
404
=cut
405
406
sub date_ranges_overlap {
407
    my ( $start1, $end1, $start2, $end2 ) = @_;
408
409
    $start1 = dt_from_string( $start1, 'iso' );
410
    $end1   = dt_from_string( $end1,   'iso' );
411
    $start2 = dt_from_string( $start2, 'iso' );
412
    $end2   = dt_from_string( $end2,   'iso' );
413
414
    if (
415
        # Start of range 2 is in the range 1.
416
        ( DateTime->compare( $start2, $start1 ) >= 0 && DateTime->compare( $start2, $end1 ) <= 0 )
417
        ||
418
419
        # End of range 2 is in the range 1.
420
        ( DateTime->compare( $end2, $start1 ) >= 0 && DateTime->compare( $end2, $end1 ) <= 0 )
421
        ||
422
423
        # Range 2 start before and end after range 1.
424
        ( DateTime->compare( $start2, $start1 ) < 0 && DateTime->compare( $end2, $end1 ) > 0 )
425
        )
426
    {
427
        return 1;
428
    }
429
430
    return;
431
}
432
396
1;
433
1;
(-)a/installer/data/mysql/atomicupdate/bug-15261.pl (+18 lines)
Line 0 Link Here
1
use Modern::Perl;
2
3
return {
4
    bug_number  => '15261',
5
    description => 'Add sysprefs PreventCheckoutOnSameReservePeriod and PreventReservesOnSamePeriod',
6
    up          => sub {
7
        my ($args) = @_;
8
        my ( $dbh, $out ) = @$args{qw(dbh out)};
9
10
        $dbh->do(
11
            q{
12
            INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES
13
            ('PreventReservesOnSamePeriod', '0', 'Prevent to hold a document if a reserve on same period exists', NULL, 'YesNo'),
14
            ('PreventCheckoutOnSameReservePeriod', '0', 'Prevent to checkout a document if a reserve on same period exists', NULL, 'YesNo')
15
        }
16
        );
17
    },
18
};
(-)a/installer/data/mysql/mandatory/sysprefs.sql (+2 lines)
Lines 648-654 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
648
('PreservationNotForLoanDefaultTrainIn', '', '', 'Not for loan to apply to items removed from the preservation waiting list', 'TextArea'),
648
('PreservationNotForLoanDefaultTrainIn', '', '', 'Not for loan to apply to items removed from the preservation waiting list', 'TextArea'),
649
('PreservationNotForLoanWaitingListIn', '', '', 'Not for loan to apply to items added to the preservation waiting list', 'TextArea'),
649
('PreservationNotForLoanWaitingListIn', '', '', 'Not for loan to apply to items added to the preservation waiting list', 'TextArea'),
650
('PreserveSerialNotes','1','','When a new "Expected" issue is generated, should it be prefilled with last created issue notes?','YesNo'),
650
('PreserveSerialNotes','1','','When a new "Expected" issue is generated, should it be prefilled with last created issue notes?','YesNo'),
651
('PreventCheckoutOnSameReservePeriod','0','','Prevent to checkout a document if a reserve on same period exists','YesNo'),
651
('PreventWithdrawingItemsStatus', '', '', 'Prevent the withdrawing of items based on certain statuses' , 'multiple'),
652
('PreventWithdrawingItemsStatus', '', '', 'Prevent the withdrawing of items based on certain statuses' , 'multiple'),
653
('PreventReservesOnSamePeriod','0','','Prevent to hold a document if a reserve on same period exists','YesNo'),
652
('previousIssuesDefaultSortOrder','asc','asc|desc','Specify the sort order of Previous Issues on the circulation page','Choice'),
654
('previousIssuesDefaultSortOrder','asc','asc|desc','Specify the sort order of Previous Issues on the circulation page','Choice'),
653
('PrintNoticesMaxLines','0','','If greater than 0, sets the maximum number of lines an overdue notice will print. If the number of items is greater than this number, the notice will end with a warning asking the borrower to check their online account for a full list of overdue items.','Integer'),
655
('PrintNoticesMaxLines','0','','If greater than 0, sets the maximum number of lines an overdue notice will print. If the number of items is greater than this number, the notice will end with a warning asking the borrower to check their online account for a full list of overdue items.','Integer'),
654
('PrivacyPolicyConsent','','Enforced|Permissive|Disabled','Data privacy policy consent in the OPAC', 'Choice'),
656
('PrivacyPolicyConsent','','Enforced|Permissive|Disabled','Data privacy policy consent in the OPAC', 'Choice'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (+12 lines)
Lines 653-658 Circulation: Link Here
653
              class: integer
653
              class: integer
654
            - to fill holds.
654
            - to fill holds.
655
            - "(list of <a href='/cgi-bin/koha/admin/authorised_values.pl?searchfield=NOT_LOAN'>not for loan</a> authorized values separated with a pipe '|')"
655
            - "(list of <a href='/cgi-bin/koha/admin/authorised_values.pl?searchfield=NOT_LOAN'>not for loan</a> authorized values separated with a pipe '|')"
656
        -
657
            - pref: PreventCheckoutOnSameReservePeriod
658
              choices:
659
                  1: Do
660
                  0: "Don't"
661
            - If yes, checkouts periods can't overlap with a reserve period.
656
        -
662
        -
657
            - pref: HoldsAutoFill
663
            - pref: HoldsAutoFill
658
              choices:
664
              choices:
Lines 1123-1128 Circulation: Link Here
1123
                  1: "Do"
1129
                  1: "Do"
1124
                  0: "Don't"
1130
                  0: "Don't"
1125
            - set holds cancelled via SIP as cancellation requests.
1131
            - set holds cancelled via SIP as cancellation requests.
1132
        -
1133
            - pref: PreventReservesOnSamePeriod
1134
              choices:
1135
                  1: Do
1136
                  0: "Don't"
1137
            - If yes, Reserves periods for the same document can't overlap.
1126
    Patron restrictions:
1138
    Patron restrictions:
1127
        -
1139
        -
1128
            - pref: PatronRestrictionTypes
1140
            - pref: PatronRestrictionTypes
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (+2 lines)
Lines 346-351 Link Here
346
                        [% IF ( RESERVED ) %]
346
                        [% IF ( RESERVED ) %]
347
                            <p>
347
                            <p>
348
                                <input type="checkbox" id="cancelreserve" name="cancelreserve" value="cancel" />
348
                                <input type="checkbox" id="cancelreserve" name="cancelreserve" value="cancel" />
349
                                <input type="hidden" name="reserveid" value="[% resreserveid | html %]" />
349
                                <label for="cancelreserve">Cancel hold</label>
350
                                <label for="cancelreserve">Cancel hold</label>
350
                            </p>
351
                            </p>
351
                        [% END %]
352
                        [% END %]
Lines 354-359 Link Here
354
                            <p>
355
                            <p>
355
                                <label for="cancelreserve">Cancel hold</label>
356
                                <label for="cancelreserve">Cancel hold</label>
356
                                <input type="radio" value="cancel" name="cancelreserve" id="cancelreserve" /><br />
357
                                <input type="radio" value="cancel" name="cancelreserve" id="cancelreserve" /><br />
358
                                <input type="hidden" name="reserveid" value="[% resreserveid | html %]" />
357
                                <label for="revertreserve">Revert waiting status</label>
359
                                <label for="revertreserve">Revert waiting status</label>
358
                                <input type="radio" value="revert" name="cancelreserve" id="revertreserve" checked="checked" />
360
                                <input type="radio" value="revert" name="cancelreserve" id="revertreserve" checked="checked" />
359
                            </p>
361
                            </p>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/placerequest.tt (+75 lines)
Line 0 Link Here
1
[% USE JSON.Escape %]
2
[% USE raw %]
3
[% SET footerjs = 1 %]
4
[% INCLUDE 'doc-head-open.inc' %]
5
<title>Confirm holds &rsaquo; Holds &rsaquo; Circulation &rsaquo; Koha</title>
6
[% INCLUDE 'doc-head-close.inc' %]
7
</head>
8
<body id="circ_placerequest" class="catalog">
9
10
[% WRAPPER 'header.inc' %]
11
    [% INCLUDE 'circ-search.inc' %]
12
[% END %]
13
14
[% WRAPPER 'sub-header.inc' %]
15
    [% WRAPPER breadcrumbs %]
16
        [% WRAPPER breadcrumb_item %]
17
            <a href="/cgi-bin/koha/catalogue/search.pl">Catalog</a>
18
        [% END %]
19
        [% WRAPPER breadcrumb_item %]
20
            <span>Confirm holds</span>
21
        [% END %]
22
    [% END %]
23
[% END %]
24
25
<div class="main container-fluid">
26
    <div class="row">
27
        <div id="confirm-holds-modal" class="modal fade" tabindex="-1" role="dialog">
28
            <div class="modal-dialog" role="document">
29
                <div class="modal-content">
30
                    <div class="modal-header">
31
                        <h4 class="modal-title">Confirm holds</h4>
32
                    </div>
33
                    <div class="modal-body">
34
                        <p> Some of the reserves you are trying to do overlaps with existing reserves. Please tick the box confirming the reservation then click on Confirm if you want to proceed. </p>
35
36
                        <form method="post" id="confirm-holds">
37
                            [% FOREACH param IN params %]
38
                                <input type="hidden" name="[% param.name | html %]" value="[% param.value | html %]" />
39
                            [% END %]
40
                            [% INCLUDE 'csrf-token.inc' %]
41
42
                            [% FOREACH biblionumber IN overlap_reserves.keys %]
43
                                <div>
44
                                    <label>
45
                                        <input type="checkbox" name="confirm_biblionumbers" value="[% biblionumber | html %]" />
46
                                        Confirm hold for [% overlap_reserves.$biblionumber.title | html %]
47
                                    </label>
48
                                </div>
49
                            [% END %]
50
                        </form>
51
                    </div>
52
                    <div class="modal-footer">
53
                        <button type="button" class="btn btn-default deny" data-dismiss="modal"><i class="fa fa-times"></i> Cancel</button>
54
                        <button type="submit" class="btn btn-default approve" form="confirm-holds" name="confirm" value="1"><i class="fa fa-check"></i> Confirm</button>
55
                    </div> </div
56
                ><!-- /.modal-content --> </div
57
            ><!-- /.modal-dialog --> </div
58
        ><!-- /.modal -->
59
    </div>
60
</div>
61
62
[% MACRO jsinclude BLOCK %]
63
    <script>
64
        $(document).ready(function () {
65
            const confirmHoldsModal = document.getElementById('confirm-holds-modal');
66
            const modal = new bootstrap.Modal(confirmHoldsModal);
67
            modal.show();
68
            confirmHoldsModal.addEventListener('hide.bs.modal', function (e) {
69
                window.location = '/cgi-bin/koha/reserve/request.pl?biblionumber=' + [% biblionumber.json | $raw %] + '&borrowernumber=' + [% borrowernumber.json | $raw %]
70
            })
71
        });
72
    </script>
73
[% END %]
74
75
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt (+2 lines)
Lines 104-109 Link Here
104
                                            <span>There are items available in the library, please visit to check them out</span>
104
                                            <span>There are items available in the library, please visit to check them out</span>
105
                                        [% CASE 'not_placed' %]
105
                                        [% CASE 'not_placed' %]
106
                                            <span>Error when placing hold, please report this to the library</span>
106
                                            <span>Error when placing hold, please report this to the library</span>
107
                                        [% CASE 'overlaps' %]
108
                                            <span>Hold overlaps with existing holds</span>
107
                                        [% CASE %]
109
                                        [% CASE %]
108
                                            <span>Error: [% fail | html %]</span>
110
                                            <span>Error: [% fail | html %]</span>
109
                                        [% END %]
111
                                        [% END %]
(-)a/opac/opac-reserve.pl (-3 / +12 lines)
Lines 24-32 use CGI qw ( -utf8 ); Link Here
24
use C4::Auth        qw( get_template_and_user );
24
use C4::Auth        qw( get_template_and_user );
25
use C4::Koha        qw( getitemtypeimagelocation getitemtypeimagesrc );
25
use C4::Koha        qw( getitemtypeimagelocation getitemtypeimagesrc );
26
use C4::Circulation qw( GetBranchItemRule );
26
use C4::Circulation qw( GetBranchItemRule );
27
use C4::Reserves    qw( CanItemBeReserved CanBookBeReserved AddReserve IsAvailableForItemLevelRequest GetReserveFee );
27
use C4::Reserves
28
use C4::Biblio      qw( GetBiblioData GetFrameworkCode );
28
    qw( CanItemBeReserved CanBookBeReserved AddReserve IsAvailableForItemLevelRequest GetReserveFee ReservesOnSamePeriod );
29
use C4::Output      qw( output_html_with_http_headers );
29
use C4::Biblio qw( GetBiblioData GetFrameworkCode );
30
use C4::Output qw( output_html_with_http_headers );
30
use C4::Context;
31
use C4::Context;
31
use C4::Members;
32
use C4::Members;
32
use C4::Overdues;
33
use C4::Overdues;
Lines 267-272 if ( $op eq 'cud-place_reserve' ) { Link Here
267
            # Inserts a null into the 'itemnumber' field of 'reserves' table.
268
            # Inserts a null into the 'itemnumber' field of 'reserves' table.
268
            $itemNum = undef;
269
            $itemNum = undef;
269
        }
270
        }
271
272
        if ( $canreserve && C4::Context->preference("PreventReservesOnSamePeriod") ) {
273
            if ( C4::Reserves::ReservesOnSamePeriod( $biblioNum, $itemNum, $startdate, $patron_expiration_date ) ) {
274
                $canreserve = 0;
275
                push @failed_holds, 'overlaps';
276
            }
277
        }
278
270
        my $notes         = $query->param( 'notes_' . $biblioNum )    || '';
279
        my $notes         = $query->param( 'notes_' . $biblioNum )    || '';
271
        my $item_group_id = $query->param("item_group_id_$biblioNum") || undef;
280
        my $item_group_id = $query->param("item_group_id_$biblioNum") || undef;
272
281
(-)a/reserve/placerequest.pl (-3 / +70 lines)
Lines 22-31 Link Here
22
22
23
use Modern::Perl;
23
use Modern::Perl;
24
24
25
use List::MoreUtils qw( none );
26
25
use CGI qw ( -utf8 );
27
use CGI qw ( -utf8 );
26
use URI;
28
use URI;
27
use C4::Reserves qw( CanItemBeReserved AddReserve CanBookBeReserved );
29
use C4::Reserves qw( CanItemBeReserved AddReserve CanBookBeReserved );
28
use C4::Auth     qw( checkauth );
30
use C4::Auth     qw( get_template_and_user );
31
use C4::Output   qw( output_html_with_http_headers );
29
32
30
use Koha::Items;
33
use Koha::Items;
31
use Koha::Patrons;
34
use Koha::Patrons;
Lines 33-39 use Koha::HoldGroup; Link Here
33
36
34
my $input = CGI->new();
37
my $input = CGI->new();
35
38
36
checkauth( $input, 0, { reserveforothers => 'place_holds' }, 'intranet' );
39
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
40
    {
41
        template_name => 'reserve/placerequest.tt',
42
        query         => $input,
43
        type          => 'intranet',
44
        flagsrequired => { reserveforothers => 'place_holds' },
45
    }
46
);
37
47
38
my @reqbib           = $input->multi_param('reqbib');
48
my @reqbib           = $input->multi_param('reqbib');
39
my @biblionumbers    = $input->multi_param('biblionumber');
49
my @biblionumbers    = $input->multi_param('biblionumber');
Lines 54-64 my $multi_holds = $input->param('multi_holds'); Link Here
54
my $hold_group_param = $input->param('hold_group') || undef;
64
my $hold_group_param = $input->param('hold_group') || undef;
55
my $hold_group;
65
my $hold_group;
56
66
67
my $confirm               = $input->param('confirm');
68
my @confirm_biblionumbers = $input->multi_param('confirm_biblionumbers');
69
57
my $patron = Koha::Patrons->find($borrowernumber);
70
my $patron = Koha::Patrons->find($borrowernumber);
58
71
59
my $holds_to_place_count = $input->param('holds_to_place_count') || 1;
72
my $holds_to_place_count = $input->param('holds_to_place_count') || 1;
60
73
61
my %bibinfos = ();
74
my %bibinfos   = ();
75
my $multi_hold = @holdable_bibs > 1;
62
foreach my $bibnum (@holdable_bibs) {
76
foreach my $bibnum (@holdable_bibs) {
63
    my %bibinfo = ();
77
    my %bibinfo = ();
64
    $bibinfo{title}    = $input->param("title_$bibnum");
78
    $bibinfo{title}    = $input->param("title_$bibnum");
Lines 73-79 if ( $op eq 'cud-placerequest' && $patron ) { Link Here
73
        $hold_group = Koha::HoldGroup->new->store;
87
        $hold_group = Koha::HoldGroup->new->store;
74
    }
88
    }
75
89
90
    if ( C4::Context->preference('PreventReservesOnSamePeriod') && !$confirm ) {
91
        my %overlap_reserves;
92
        foreach my $biblionumber ( keys %bibinfos ) {
93
            next if exists $overlap_reserves{$biblionumber};
94
95
            if (@checkitems) {
96
                for my $checkitem (@checkitems) {
97
                    my $item = Koha::Items->find($checkitem);
98
                    next if $biblionumber ne $item->biblionumber;
99
100
                    my $overlapping_reserves =
101
                        C4::Reserves::ReservesOnSamePeriod( $biblionumber, $checkitem, $startdate, $expirationdate );
102
                    if ( $overlapping_reserves && 0 < scalar @$overlapping_reserves ) {
103
                        $overlap_reserves{$biblionumber} = {
104
                            title => $multi_hold ? $bibinfos{$biblionumber}->{title} : $title,
105
                        };
106
                    }
107
                }
108
            } else {
109
                my $overlapping_reserves =
110
                    C4::Reserves::ReservesOnSamePeriod( $biblionumber, undef, $startdate, $expirationdate );
111
                if ( $overlapping_reserves && 0 < scalar @$overlapping_reserves ) {
112
                    $overlap_reserves{$biblionumber} = {
113
                        title => $multi_hold ? $bibinfos{$biblionumber}->{title} : $title,
114
                    };
115
                }
116
            }
117
        }
118
119
        if ( scalar keys %overlap_reserves ) {
120
            my %params = $input->Vars;
121
            delete $params{csrf_token};
122
            my @params;
123
            foreach my $name ( sort keys %params ) {
124
                my @values = split( "\0", $params{$name} );
125
                foreach my $value (@values) {
126
                    push @params, { name => $name, value => $value };
127
                }
128
            }
129
            $template->param( params => \@params );
130
131
            $template->param(
132
                borrowernumber   => $borrowernumber,
133
                biblionumbers    => \@biblionumbers,
134
                overlap_reserves => \%overlap_reserves,
135
            );
136
137
            output_html_with_http_headers $input, $cookie, $template->output;
138
            exit;
139
        }
140
    }
141
76
    foreach my $biblionumber ( keys %bibinfos ) {
142
    foreach my $biblionumber ( keys %bibinfos ) {
143
        next if ( $confirm && none { $_ eq $biblionumber } @confirm_biblionumbers );
77
144
78
        my $can_override = C4::Context->preference('AllowHoldPolicyOverride');
145
        my $can_override = C4::Context->preference('AllowHoldPolicyOverride');
79
        if (@checkitems) {
146
        if (@checkitems) {
(-)a/svc/renew (-2 / +1 lines)
Lines 64-70 my $item = Koha::Items->find($itemnumber); Link Here
64
64
65
my $confirmations;
65
my $confirmations;
66
( $data->{renew_okay}, $data->{error} ) =
66
( $data->{renew_okay}, $data->{error} ) =
67
    CanBookBeRenewed( $patron, $item->checkout, $override_limit );
67
    CanBookBeRenewed( $patron, $item->checkout, $override_limit, 0, $date_due );
68
68
69
# If we're allowing reserved items to be renewed...
69
# If we're allowing reserved items to be renewed...
70
if ( $data->{error} && $data->{error} eq 'on_reserve' && C4::Context->preference('AllowRenewalOnHoldOverride') ) {
70
if ( $data->{error} && $data->{error} eq 'on_reserve' && C4::Context->preference('AllowRenewalOnHoldOverride') ) {
71
- 

Return to bug 15261