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

(-)a/C4/ILSDI/Services.pm (-2 / +8 lines)
Lines 814-820 sub HoldTitle { Link Here
814
    return { code => 'cannotBeTransferred' }      unless $biblio->can_be_transferred( { to => $destination } );
814
    return { code => 'cannotBeTransferred' }      unless $biblio->can_be_transferred( { to => $destination } );
815
815
816
    my $resdate = $cgi->param('start_date');
816
    my $resdate = $cgi->param('start_date');
817
    my $expdate = $cgi->param('expiry_date');
817
    my $expdate;
818
    if ( C4::Context->preference('ReserveExpiration') and $cgi->param('expiry_date') ) {
819
        $expdate = $cgi->param('expiry_date');
820
    }
818
821
819
    # Add the reserve
822
    # Add the reserve
820
    #    $branch,    $borrowernumber, $biblionumber,
823
    #    $branch,    $borrowernumber, $biblionumber,
Lines 910-916 sub HoldItem { Link Here
910
    return { code => $canitembereserved } unless $canitembereserved eq 'OK';
913
    return { code => $canitembereserved } unless $canitembereserved eq 'OK';
911
914
912
    my $resdate = $cgi->param('start_date');
915
    my $resdate = $cgi->param('start_date');
913
    my $expdate = $cgi->param('expiry_date');
916
    my $expdate;
917
    if ( C4::Context->preference('ReserveExpiration') and $cgi->param('expiry_date') ) {
918
        $expdate = $cgi->param('expiry_date');
919
    }
914
920
915
    # Add the reserve
921
    # Add the reserve
916
    my $priority = C4::Reserves::CalculatePriority($biblionumber);
922
    my $priority = C4::Reserves::CalculatePriority($biblionumber);
(-)a/C4/Reserves.pm (-1 / +1 lines)
Lines 184-190 sub AddReserve { Link Here
184
    my $biblionumber           = $params->{biblionumber};
184
    my $biblionumber           = $params->{biblionumber};
185
    my $priority               = $params->{priority};
185
    my $priority               = $params->{priority};
186
    my $resdate                = $params->{reservation_date};
186
    my $resdate                = $params->{reservation_date};
187
    my $patron_expiration_date = $params->{expiration_date};
187
    my $patron_expiration_date = C4::Context->preference('ReserveExpiration') ? $params->{expiration_date} : undef;
188
    my $notes                  = $params->{notes};
188
    my $notes                  = $params->{notes};
189
    my $title                  = $params->{title};
189
    my $title                  = $params->{title};
190
    my $checkitem              = $params->{itemnumber};
190
    my $checkitem              = $params->{itemnumber};
(-)a/Koha/Club/Hold.pm (-1 / +1 lines)
Lines 131-137 sub add { Link Here
131
                borrowernumber  => $patron_id,
131
                borrowernumber  => $patron_id,
132
                biblionumber    => $params->{biblio_id},
132
                biblionumber    => $params->{biblio_id},
133
                priority        => $priority,
133
                priority        => $priority,
134
                expiration_date => $params->{expiration_date},
134
                expiration_date => C4::Context->preference('ReserveExpiration') ? $params->{expiration_date} : undef,
135
                notes           => $params->{notes},
135
                notes           => $params->{notes},
136
                title           => $biblio->title,
136
                title           => $biblio->title,
137
                itemnumber      => $params->{item_id},
137
                itemnumber      => $params->{item_id},
(-)a/Koha/Hold.pm (-35 / +41 lines)
Lines 289-341 sub set_waiting { Link Here
289
        desk_id => $desk_id,
289
        desk_id => $desk_id,
290
    };
290
    };
291
291
292
    my $max_pickup_delay   = C4::Context->preference("ReservesMaxPickUpDelay");
292
    my $new_expiration_date;
293
    my $cancel_on_holidays = C4::Context->preference('ExpireReservesOnHolidays');
294
293
295
    my $rule = Koha::CirculationRules->get_effective_rule(
294
    if ( C4::Context->preference('ReserveExpiration') ) {
296
        {
297
            categorycode => $self->borrower->categorycode,
298
            itemtype     => $self->item->effective_itemtype,
299
            branchcode   => $self->branchcode,
300
            rule_name    => 'holds_pickup_period',
301
        }
302
    );
303
    if ( defined($rule) and $rule->rule_value ne '' ) {
304
305
        # circulation rule overrides ReservesMaxPickUpDelay
306
        $max_pickup_delay = $rule->rule_value;
307
    }
308
295
309
    my $new_expiration_date = dt_from_string( $self->waitingdate )->clone->add( days => $max_pickup_delay );
296
        my $max_pickup_delay   = C4::Context->preference("ReservesMaxPickUpDelay");
297
        my $cancel_on_holidays = C4::Context->preference('ExpireReservesOnHolidays');
310
298
311
    if ( C4::Context->preference("ExcludeHolidaysFromMaxPickUpDelay") ) {
299
        my $rule = Koha::CirculationRules->get_effective_rule(
312
        my $itemtype = $self->item ? $self->item->effective_itemtype : $self->biblio->itemtype;
313
        my $daysmode = Koha::CirculationRules->get_effective_daysmode(
314
            {
300
            {
315
                categorycode => $self->borrower->categorycode,
301
                categorycode => $self->borrower->categorycode,
316
                itemtype     => $itemtype,
302
                itemtype     => $self->item->effective_itemtype,
317
                branchcode   => $self->branchcode,
303
                branchcode   => $self->branchcode,
304
                rule_name    => 'holds_pickup_period',
318
            }
305
            }
319
        );
306
        );
320
        my $calendar = Koha::Calendar->new( branchcode => $self->branchcode, days_mode => $daysmode );
307
        if ( defined($rule) and $rule->rule_value ne '' ) {
321
308
322
        $new_expiration_date = $calendar->days_forward( dt_from_string( $self->waitingdate ), $max_pickup_delay );
309
            # circulation rule overrides ReservesMaxPickUpDelay
323
    }
310
            $max_pickup_delay = $rule->rule_value;
311
        }
324
312
325
    # If patron's requested expiration date is prior to the
313
        $new_expiration_date = dt_from_string( $self->waitingdate )->clone->add( days => $max_pickup_delay );
326
    # calculated one, we keep the patron's one.
327
    if ( $self->patron_expiration_date ) {
328
        my $requested_expiration = dt_from_string( $self->patron_expiration_date );
329
314
330
        my $cmp =
315
        if ( C4::Context->preference("ExcludeHolidaysFromMaxPickUpDelay") ) {
331
            $requested_expiration
316
            my $itemtype = $self->item ? $self->item->effective_itemtype : $self->biblio->itemtype;
332
            ? DateTime->compare( $requested_expiration, $new_expiration_date )
317
            my $daysmode = Koha::CirculationRules->get_effective_daysmode(
333
            : 0;
318
                {
319
                    categorycode => $self->borrower->categorycode,
320
                    itemtype     => $itemtype,
321
                    branchcode   => $self->branchcode,
322
                }
323
            );
324
            my $calendar = Koha::Calendar->new( branchcode => $self->branchcode, days_mode => $daysmode );
334
325
335
        $new_expiration_date = $cmp == -1 ? $requested_expiration : $new_expiration_date;
326
            $new_expiration_date = $calendar->days_forward( dt_from_string( $self->waitingdate ), $max_pickup_delay );
336
    }
327
        }
328
329
        # If patron's requested expiration date is prior to the
330
        # calculated one, we keep the patron's one.
331
        if ( $self->patron_expiration_date ) {
332
            my $requested_expiration = dt_from_string( $self->patron_expiration_date );
333
334
            my $cmp =
335
                $requested_expiration
336
                ? DateTime->compare( $requested_expiration, $new_expiration_date )
337
                : 0;
338
339
            $new_expiration_date = $cmp == -1 ? $requested_expiration : $new_expiration_date;
340
        }
341
342
    }    # ReserveExpiration
337
343
338
    $values->{expirationdate} = $new_expiration_date->ymd;
344
    $values->{expirationdate} = $new_expiration_date ? $new_expiration_date->ymd : undef;
339
345
340
    $self->set($values)->store();
346
    $self->set($values)->store();
341
347
Lines 1010-1016 sub revert_found { Link Here
1010
                    priority       => 1,
1016
                    priority       => 1,
1011
                    found          => undef,
1017
                    found          => undef,
1012
                    waitingdate    => undef,
1018
                    waitingdate    => undef,
1013
                    expirationdate => $self->patron_expiration_date,
1019
                    expirationdate => undef,
1014
                    itemnumber     => $self->item_level_hold ? $self->itemnumber : undef,
1020
                    itemnumber     => $self->item_level_hold ? $self->itemnumber : undef,
1015
                    ( $self->is_waiting ? ( desk_id => undef ) : () ),
1021
                    ( $self->is_waiting ? ( desk_id => undef ) : () ),
1016
                }
1022
                }
(-)a/Koha/REST/V1/Clubs/Holds.pm (-1 / +1 lines)
Lines 53-59 sub add { Link Here
53
        my $pickup_library_id   = $body->{pickup_library_id};
53
        my $pickup_library_id   = $body->{pickup_library_id};
54
        my $item_id             = $body->{item_id};
54
        my $item_id             = $body->{item_id};
55
        my $item_type           = $body->{item_type};
55
        my $item_type           = $body->{item_type};
56
        my $expiration_date     = $body->{expiration_date};
56
        my $expiration_date   = C4::Context->preference('ReserveExpiration') ? $body->{expiration_date} : undef;
57
        my $notes               = $body->{notes};
57
        my $notes               = $body->{notes};
58
        my $default_patron_home = $body->{default_patron_home};
58
        my $default_patron_home = $body->{default_patron_home};
59
59
(-)a/Koha/REST/V1/Holds.pm (-1 / +1 lines)
Lines 82-88 sub add { Link Here
82
        my $item_id           = $body->{item_id};
82
        my $item_id           = $body->{item_id};
83
        my $patron_id         = $body->{patron_id};
83
        my $patron_id         = $body->{patron_id};
84
        my $item_type         = $body->{item_type};
84
        my $item_type         = $body->{item_type};
85
        my $expiration_date   = $body->{expiration_date};
85
        my $expiration_date   = C4::Context->preference('ReserveExpiration') ? $body->{expiration_date} : undef;
86
        my $notes             = $body->{notes};
86
        my $notes             = $body->{notes};
87
        my $hold_date         = $body->{hold_date};
87
        my $hold_date         = $body->{hold_date};
88
        my $non_priority      = $body->{non_priority};
88
        my $non_priority      = $body->{non_priority};
(-)a/circ/waitingreserves.pl (-3 / +3 lines)
Lines 104-113 my $today = Date_to_Days(&Today); Link Here
104
while ( my $hold = $holds->next ) {
104
while ( my $hold = $holds->next ) {
105
    next unless $hold->waitingdate;
105
    next unless $hold->waitingdate;
106
106
107
    my ( $expire_year, $expire_month, $expire_day ) = split( /-/, $hold->expirationdate );
107
    my ( $expire_year, $expire_month, $expire_day ) = split (/-/, $hold->expirationdate);
108
    my $calcDate = Date_to_Days( $expire_year, $expire_month, $expire_day );
108
    my $calcDate = Date_to_Days( $expire_year, $expire_month, $expire_day ) if $hold->expirationdate;
109
109
110
    if ( $today > $calcDate ) {
110
    if ($calcDate and $today > $calcDate) {
111
        if ( $op eq 'cud-cancelall' ) {
111
        if ( $op eq 'cud-cancelall' ) {
112
            my $res = cancel(
112
            my $res = cancel(
113
                $hold->item->itemnumber, $hold->borrowernumber, $hold->item->holdingbranch,
113
                $hold->item->itemnumber, $hold->borrowernumber, $hold->item->holdingbranch,
(-)a/installer/data/mysql/atomicupdate/bug24194-add-ReserveExpiration-syspref.pl (+12 lines)
Line 0 Link Here
1
use Modern::Perl;
2
3
return {
4
    bug_number => "24194",
5
    description => "Add new system preference ReserveExpiration",
6
    up => sub {
7
        my ($args) = @_;
8
        my ($dbh, $out) = @$args{qw(dbh out)};
9
10
        $dbh->do(q{INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) VALUES ("ReserveExpiration", 1, NULL, "Enable the use of expiration date in holds module.", "YesNo") });
11
    },
12
};
(-)a/installer/data/mysql/mandatory/sysprefs.sql (+1 lines)
Lines 691-696 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
691
('RequireChoosingExistingAuthority','0',NULL,'Require existing authority selection in controlled fields during cataloging.','YesNo'),
691
('RequireChoosingExistingAuthority','0',NULL,'Require existing authority selection in controlled fields during cataloging.','YesNo'),
692
('RequirePaymentType','0','','Require staff to select a payment type when a payment is made','YesNo'),
692
('RequirePaymentType','0','','Require staff to select a payment type when a payment is made','YesNo'),
693
('RequireStrongPassword','1','','Require a strong login password for staff and patrons','YesNo'),
693
('RequireStrongPassword','1','','Require a strong login password for staff and patrons','YesNo'),
694
('ReserveExpiration', 1, NULL, 'Enable the use of expiration date in holds module.', 'YesNo'),
694
('ReservesControlBranch','PatronLibrary','ItemHomeLibrary|PatronLibrary','Branch checked for members reservations rights','Choice'),
695
('ReservesControlBranch','PatronLibrary','ItemHomeLibrary|PatronLibrary','Branch checked for members reservations rights','Choice'),
695
('ReservesMaxPickUpDelay','7','','Define the Maximum delay to pick up an item on hold','Integer'),
696
('ReservesMaxPickUpDelay','7','','Define the Maximum delay to pick up an item on hold','Integer'),
696
('ReservesNeedReturns','1','','If ON, a hold placed on an item available in this library must be checked-in, otherwise, a hold on a specific item, that is in the library & available is considered available','YesNo'),
697
('ReservesNeedReturns','1','','If ON, a hold placed on an item available in this library must be checked-in, otherwise, a hold on a specific item, that is in the library & available is considered available','YesNo'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc (-4 / +8 lines)
Lines 13-19 Link Here
13
            <th id="patron" data-colname="patron">Patron</th>
13
            <th id="patron" data-colname="patron">Patron</th>
14
            <th id="notes" data-colname="notes">Notes</th>
14
            <th id="notes" data-colname="notes">Notes</th>
15
            <th id="date" data-colname="date">Date</th>
15
            <th id="date" data-colname="date">Date</th>
16
            <th id="expiration" data-colname="expiration">Expiration</th>
16
            [% IF Koha.Preference('ReserveExpiration') %]
17
                <th id="expiration" data-colname="expiration">Expiration</th>
18
            [% END %]
17
            <th id="pickup_library" data-colname="pickup_library">Pickup library</th>
19
            <th id="pickup_library" data-colname="pickup_library">Pickup library</th>
18
            <th id="details" data-colname="details">Details</th>
20
            <th id="details" data-colname="details">Details</th>
19
            [% IF ( CAN_user_reserveforothers_modify_holds_priority ) %]
21
            [% IF ( CAN_user_reserveforothers_modify_holds_priority ) %]
Lines 190-198 Link Here
190
                        [% hold.date | $KohaDates %]
192
                        [% hold.date | $KohaDates %]
191
                    [% END %]
193
                    [% END %]
192
                </td>
194
                </td>
193
                <td>
195
                [% IF Koha.Preference('ReserveExpiration') %]
194
                    <input type="text" class="flatpickr" data-flatpickr-futuredate="true" value="[% hold.expirationdate | html %]" size="10" name="expirationdate" />
196
                    <td>
195
                </td>
197
                        <input type="text" class="flatpickr" data-flatpickr-futuredate="true" value="[% hold.expirationdate | html %]" size="10" name="expirationdate" />
198
                    </td>
199
                [% END %]
196
                <td>
200
                <td>
197
                    [%- IF ( hold.found ) -%]
201
                    [%- IF ( hold.found ) -%]
198
                        <input type="hidden" name="pickup" value="[% hold.wbrcode | html %]" />
202
                        <input type="hidden" name="pickup" value="[% hold.wbrcode | html %]" />
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/patron-detail-tabs.inc (-1 / +3 lines)
Lines 155-161 Link Here
155
                                <th>Item type</th>
155
                                <th>Item type</th>
156
                                <th>Barcode</th>
156
                                <th>Barcode</th>
157
                                <th>Pickup at</th>
157
                                <th>Pickup at</th>
158
                                <th>Expiration</th>
158
                                [% IF Koha.Preference('ReserveExpiration') %]
159
                                    <th>Expiration</th>
160
                                [% END %]
159
                                <th>Priority</th>
161
                                <th>Priority</th>
160
                                <th>Notes</th>
162
                                <th>Notes</th>
161
                                <th>Delete?</th>
163
                                <th>Delete?</th>
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/waiting_holds.inc (-2 / +6 lines)
Lines 10-16 Link Here
10
            [% IF table_name == 'holdscr' %]
10
            [% IF table_name == 'holdscr' %]
11
                <th>Date cancellation requested</th>
11
                <th>Date cancellation requested</th>
12
            [% END %]
12
            [% END %]
13
            <th>Expiration date</th>
13
            [% IF Koha.Preference('ReserveExpiration') %]
14
                <th>Expiration date</th>
15
            [% END %]
14
            <th class="anti-the">Title</th>
16
            <th class="anti-the">Title</th>
15
            <th>Patron</th>
17
            <th>Patron</th>
16
            <th>Home library</th>
18
            <th>Home library</th>
Lines 39-45 Link Here
39
                        <td></td>
41
                        <td></td>
40
                    [% END %]
42
                    [% END %]
41
                [% END %]
43
                [% END %]
42
                <td data-order="[% reserveloo.expirationdate | html %]"><span>[% reserveloo.expirationdate | $KohaDates %]</span></td>
44
                [% IF Koha.Preference('ReserveExpiration') %]
45
                    <td data-order="[% reserveloo.expirationdate | html %]"><span>[% reserveloo.expirationdate | $KohaDates %]</span></td>
46
                [% END %]
43
                <td>
47
                <td>
44
                    [% INCLUDE 'biblio-title.inc' biblio=reserveloo.biblio link = 1 %]
48
                    [% INCLUDE 'biblio-title.inc' biblio=reserveloo.biblio link = 1 %]
45
                    [% UNLESS ( item_level_itypes ) %]
49
                    [% UNLESS ( item_level_itypes ) %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (-4 / +10 lines)
Lines 860-872 Circulation: Link Here
860
            - Mark a hold as problematic if it has been waiting for more than
860
            - Mark a hold as problematic if it has been waiting for more than
861
            - pref: ReservesMaxPickUpDelay
861
            - pref: ReservesMaxPickUpDelay
862
              class: integer
862
              class: integer
863
            - days.
863
            - 'days.<br><strong>NOTE:</strong> If <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=ReserveExpiration">ReserveExpiration</a> is disabled, holds marked as problematic must be dealt with manually as they will never automatically expire.'
864
        -
864
        -
865
            - pref: ExpireReservesMaxPickUpDelay
865
            - pref: ExpireReservesMaxPickUpDelay
866
              choices:
866
              choices:
867
                  1: Allow
867
                  1: Allow
868
                  0: "Don't allow"
868
                  0: "Don't allow"
869
            - 'holds to expire automatically if they have not been picked by within the time period specified in the <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=ReservesMaxPickUpDelay">ReservesMaxPickUpDelay</a> system preference.</br>'
869
            - 'holds to expire automatically if they have not been picked by within the time period specified in the <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=ReservesMaxPickUpDelay">ReservesMaxPickUpDelay</a> system preference.<br><strong>NOTE:</strong> This system preference requires the <code>misc/cronjobs/holds/cancel_expired_holds.pl</code> cronjob. Ask your system administrator to schedule it.<br><strong>NOTE:</strong> This will not apply if <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=ReserveExpiration">ReserveExpiration</a> is disabled.<br>'
870
            - pref: ExpireReservesAutoFill
870
            - pref: ExpireReservesAutoFill
871
              choices:
871
              choices:
872
                  1: "Do"
872
                  1: "Do"
Lines 881-887 Circulation: Link Here
881
            - If using <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=ExpireReservesMaxPickUpDelay">ExpireReservesMaxPickUpDelay</a>, charge a patron who allows their waiting hold to expire a fee of
881
            - If using <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=ExpireReservesMaxPickUpDelay">ExpireReservesMaxPickUpDelay</a>, charge a patron who allows their waiting hold to expire a fee of
882
            - pref: ExpireReservesMaxPickUpDelayCharge
882
            - pref: ExpireReservesMaxPickUpDelayCharge
883
              class: currency
883
              class: currency
884
            - .
884
            - '.<br><strong>NOTE:</strong> This will not apply if <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=ReserveExpiration">ReserveExpiration</a> is disabled.'
885
        -
885
        -
886
            - The holds queue should prioritize filling a hold by matching the patron's home library with an item having a matching
886
            - The holds queue should prioritize filling a hold by matching the patron's home library with an item having a matching
887
            - pref: HoldsQueuePrioritizeBranch
887
            - pref: HoldsQueuePrioritizeBranch
Lines 997-1003 Circulation: Link Here
997
              choices:
997
              choices:
998
                  1: allow
998
                  1: allow
999
                  0: "don't allow"
999
                  0: "don't allow"
1000
            - expired holds to be canceled on days the library is closed per the calendar.
1000
            - 'expired holds to be canceled on days the library is closed per the calendar.<br><strong>NOTE:</strong> This will not apply if <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=ReserveExpiration">ReserveExpiration</a> is disabled.'
1001
        -
1001
        -
1002
            - pref: ExcludeHolidaysFromMaxPickUpDelay
1002
            - pref: ExcludeHolidaysFromMaxPickUpDelay
1003
              choices:
1003
              choices:
Lines 1152-1157 Circulation: Link Here
1152
                  1: block
1152
                  1: block
1153
                  0: allow
1153
                  0: allow
1154
            - renewing of items from the staff interface and via the <code>misc/cronjobs/automatic_renewals.pl</code> cronjob.
1154
            - renewing of items from the staff interface and via the <code>misc/cronjobs/automatic_renewals.pl</code> cronjob.
1155
        -
1156
            - pref: ReserveExpiration
1157
              choices:
1158
                  1: Enable
1159
                  0: "Disable"
1160
            - the use of expiration dates in holds. When enabled, patrons can specify a date when their hold is not needed, any hold awaiting pickup will automatically expire after it has been waiting for a problematic number of days, and expiration dates will show on both the OPAC and staff interface.
1155
    Fines policy:
1161
    Fines policy:
1156
        -
1162
        -
1157
            - pref: finesCalendar
1163
            - pref: finesCalendar
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (+1 lines)
Lines 1109-1114 Link Here
1109
            relatives_borrowernumbers.push("[% b | html %]");
1109
            relatives_borrowernumbers.push("[% b | html %]");
1110
        [% END %]
1110
        [% END %]
1111
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
1111
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
1112
        var ReserveExpiration = [% ( Koha.Preference('ReserveExpiration') ) ? 1 : 0 | html %];
1112
    </script>
1113
    </script>
1113
    [% Asset.js("js/pages/circulation.js") | $raw %]
1114
    [% Asset.js("js/pages/circulation.js") | $raw %]
1114
    [% IF Koha.Preference('ClaimReturnedLostValue') || Koha.Preference('BundleLostValue') %]
1115
    [% IF Koha.Preference('ClaimReturnedLostValue') || Koha.Preference('BundleLostValue') %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/holdshistory.tt (-2 / +14 lines)
Lines 50-55 Link Here
50
    [% ELSE %]
50
    [% ELSE %]
51
51
52
        [% SET show_itemtype_column = Koha.Preference('AllowHoldItemTypeSelection') %]
52
        [% SET show_itemtype_column = Koha.Preference('AllowHoldItemTypeSelection') %]
53
        [% SET ReserveExpiration = Koha.Preference('ReserveExpiration') ? 1 : 0 %]
53
54
54
        <div id="holdshistory" class="page-section">
55
        <div id="holdshistory" class="page-section">
55
            <h2 id="current_holds_heading">Current holds</h2>
56
            <h2 id="current_holds_heading">Current holds</h2>
Lines 90-96 Link Here
90
                            <th>Call number</th>
91
                            <th>Call number</th>
91
                            <th>Library</th>
92
                            <th>Library</th>
92
                            <th>Hold date</th>
93
                            <th>Hold date</th>
93
                            <th>Expiration date</th>
94
                            [% IF ReserveExpiration == 1 %]
95
                                <th>Expiration date</th>
96
                            [% END %]
94
                            <th>Waiting date</th>
97
                            <th>Waiting date</th>
95
                            <th>Cancellation date</th>
98
                            <th>Cancellation date</th>
96
                            [% IF show_itemtype_column %]
99
                            [% IF show_itemtype_column %]
Lines 135-141 Link Here
135
                            <th>Call number</th>
138
                            <th>Call number</th>
136
                            <th>Library</th>
139
                            <th>Library</th>
137
                            <th>Hold date</th>
140
                            <th>Hold date</th>
138
                            <th>Expiration date</th>
141
                            [% IF ReserveExpiration == 1 %]
142
                                <th>Expiration date</th>
143
                            [% END %]
139
                            <th>Waiting date</th>
144
                            <th>Waiting date</th>
140
                            <th>Cancellation date</th>
145
                            <th>Cancellation date</th>
141
                            [% IF show_itemtype_column %]
146
                            [% IF show_itemtype_column %]
Lines 159-170 Link Here
159
    [% Asset.js("js/members-menu.js") | $raw %]
164
    [% Asset.js("js/members-menu.js") | $raw %]
160
    [% INCLUDE 'js-biblio-format.inc' %]
165
    [% INCLUDE 'js-biblio-format.inc' %]
161
    <script>
166
    <script>
167
        var ReserveExpiration = [% ( Koha.Preference('ReserveExpiration') ) ? 1 : 0 | html %];
162
        $(document).ready(function() {
168
        $(document).ready(function() {
163
            var table_settings = [% TablesSettings.GetTableSettings('members', 'holdshistory', 'holdshistory-table', 'json') | $raw %];
169
            var table_settings = [% TablesSettings.GetTableSettings('members', 'holdshistory', 'holdshistory-table', 'json') | $raw %];
164
            [% UNLESS show_itemtype_column %]
170
            [% UNLESS show_itemtype_column %]
165
              //Remove item type column settings
171
              //Remove item type column settings
166
              table_settings['columns'] = table_settings['columns'].filter(function(c){return c['columnname'] != 'itemtype';});
172
              table_settings['columns'] = table_settings['columns'].filter(function(c){return c['columnname'] != 'itemtype';});
167
            [% END %]
173
            [% END %]
174
            [% UNLESS ReserveExpiration %]
175
                //Remove Expiration date column settings
176
                table_settings['columns'] = table_settings['columns'].filter(function(c){return c['columnname'] != 'expirationdate';});
177
            [% END %]
168
            let current_holds_table = build_holds_table("#table_holdshistory");
178
            let current_holds_table = build_holds_table("#table_holdshistory");
169
            let old_holds_table = build_holds_table("#table_oldholdshistory", 1);
179
            let old_holds_table = build_holds_table("#table_oldholdshistory", 1);
170
            function build_holds_table(table_id, old){
180
            function build_holds_table(table_id, old){
Lines 269-274 Link Here
269
                                return $date(row.hold_date);
279
                                return $date(row.hold_date);
270
                            }
280
                            }
271
                        },
281
                        },
282
                        [% IF ReserveExpiration == 1 %]
272
                        {
283
                        {
273
                            data: "expiration_date",
284
                            data: "expiration_date",
274
                            type: "date",
285
                            type: "date",
Lines 278-283 Link Here
278
                                return $date(row.expiration_date)
289
                                return $date(row.expiration_date)
279
                            }
290
                            }
280
                        },
291
                        },
292
                        [% END %]
281
                        {
293
                        {
282
                            data: "waiting_date",
294
                            data: "waiting_date",
283
                            type: "date",
295
                            type: "date",
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-print.tt (-2 / +6 lines)
Lines 101-107 Link Here
101
                    <th class="anti-the">Title</th>
101
                    <th class="anti-the">Title</th>
102
                    <th>Author</th>
102
                    <th>Author</th>
103
                    <th>Placed on</th>
103
                    <th>Placed on</th>
104
                    <th>Expires on</th>
104
                    [% IF Koha.Preference('ReserveExpiration') %]
105
                        <th>Expires on</th>
106
                    [% END %]
105
                    <th>Pick up location</th>
107
                    <th>Pick up location</th>
106
                    <th>Hold priority</th>
108
                    <th>Hold priority</th>
107
                </tr>
109
                </tr>
Lines 112-118 Link Here
112
                        <td>[% reserve.title | html %]</td>
114
                        <td>[% reserve.title | html %]</td>
113
                        <td>[% reserve.author | html %]</td>
115
                        <td>[% reserve.author | html %]</td>
114
                        <td data-sort="[% reserve.reservedate | html %]">[% reserve.reservedate | $KohaDates %]</td>
116
                        <td data-sort="[% reserve.reservedate | html %]">[% reserve.reservedate | $KohaDates %]</td>
115
                        <td data-sort="[% reserve.expirationdate | html %]">[% reserve.expirationdate | $KohaDates %]</td>
117
                        [% IF Koha.Preference('ReserveExpiration') %]
118
                            <td data-sort="[% reserve.expirationdate | html %]">[% reserve.expirationdate | $KohaDates %]</td>
119
                        [% END %]
116
                        <td>[% reserve.waiting_at | html %]</td>
120
                        <td>[% reserve.waiting_at | html %]</td>
117
                        <td>[% reserve.priority | html %]</td>
121
                        <td>[% reserve.priority | html %]</td>
118
                    </tr>
122
                    </tr>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt (+1 lines)
Lines 786-791 Link Here
786
            relatives_borrowernumbers.push("[% b | html %]");
786
            relatives_borrowernumbers.push("[% b | html %]");
787
        [% END %]
787
        [% END %]
788
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
788
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
789
        var ReserveExpiration = [% ( Koha.Preference('ReserveExpiration') ) ? 1 : 0 | html %];
789
    </script>
790
    </script>
790
    [% Asset.js("js/pages/circulation.js") | $raw %]
791
    [% Asset.js("js/pages/circulation.js") | $raw %]
791
    [% IF Koha.Preference('ClaimReturnedLostValue') || Koha.Preference('BundleLostValue') %]
792
    [% IF Koha.Preference('ClaimReturnedLostValue') || Koha.Preference('BundleLostValue') %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (-4 / +6 lines)
Lines 665-674 Link Here
665
                            </li>
665
                            </li>
666
                        [% END %]
666
                        [% END %]
667
667
668
                        <li>
668
                        [% IF Koha.Preference('ReserveExpiration') %]
669
                            <label for="to">Hold expires on date:</label>
669
                            <li>
670
                            <input id="expiration_date" name="expiration_date" id="to" size="10" type="text" class="flatpickr" data-flatpickr-futuredate="true" />
670
                                <label for="to">Hold expires on date:</label>
671
                        </li>
671
                                <input id="expiration_date" name="expiration_date" id="to" size="10" type="text" class="flatpickr" data-flatpickr-futuredate="true" />
672
                            </li>
673
                        [% END %]
672
674
673
                        <li id="non_priority_list_item">
675
                        <li id="non_priority_list_item">
674
                            <label for="non_priority">Non priority hold:</label>
676
                            <label for="non_priority">Non priority hold:</label>
(-)a/koha-tmpl/intranet-tmpl/prog/js/holds.js (-4 / +2 lines)
Lines 339-348 $(document).ready(function () { Link Here
339
                            },
339
                            },
340
                        },
340
                        },
341
                        {
341
                        {
342
                            data: {
342
                            "visible": ReserveExpiration,
343
                                _: "expirationdate_formatted",
343
                            "data": { _: "expirationdate_formatted", "sort": "expirationdate" }
344
                                sort: "expirationdate",
345
                            },
346
                        },
344
                        },
347
                        {
345
                        {
348
                            data: function (oObj) {
346
                            data: function (oObj) {
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/includes/holds-table.inc (-8 / +13 lines)
Lines 15-21 Link Here
15
            [% ELSE %]
15
            [% ELSE %]
16
                <th class="psort">Placed on</th>
16
                <th class="psort">Placed on</th>
17
            [% END %]
17
            [% END %]
18
            <th>Expires on</th>
18
            [% IF Koha.Preference('ReserveExpiration') %]
19
                <th>Expires on</th>
20
            [% END %]
19
            [% UNLESS( singleBranchMode) %]
21
            [% UNLESS( singleBranchMode) %]
20
                <th>Pickup location</th>
22
                <th>Pickup location</th>
21
            [% END %]
23
            [% END %]
Lines 83-98 Link Here
83
                    [% END %]
85
                    [% END %]
84
                </td>
86
                </td>
85
                <td class="reservedate" data-order="[% HOLD.reservedate | html %]"> [% HOLD.reservedate | $KohaDates %] </td>
87
                <td class="reservedate" data-order="[% HOLD.reservedate | html %]"> [% HOLD.reservedate | $KohaDates %] </td>
86
                <td class="expirationdate" data-order="[% !HOLD.found ? HOLD.expirationdate : '0000-00-00' | html %]">
88
                [% IF Koha.Preference('ReserveExpiration') %]
87
                    [% IF ! HOLD.found %]
89
                    [% IF ! HOLD.found %]
88
                        [% IF ( HOLD.expirationdate ) %]
90
                        <td class="expirationdate" data-order="[% HOLD.expirationdate | html %]">
89
                            [% HOLD.expirationdate | $KohaDates %]
91
                            [% IF ( HOLD.expirationdate ) %]
90
                        [% ELSE %]
92
                                [% HOLD.expirationdate | $KohaDates %]
91
                            Never expires
93
                            [% ELSE %]
92
                        [% END %]
94
                                Never expires
95
                            [% END %]
93
                    [% ELSE %]
96
                    [% ELSE %]
94
                        -
97
                        <td class="expirationdate" data-order="0000-00-00">
98
                            -
95
                    [% END %]
99
                    [% END %]
100
                [% END %]
96
                </td>
101
                </td>
97
                [% UNLESS( singleBranchMode) %]
102
                [% UNLESS( singleBranchMode) %]
98
                    <td class="branch">
103
                    <td class="branch">
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-holdshistory.tt (-6 / +10 lines)
Lines 102-108 Link Here
102
                                            <th>Barcode</th>
102
                                            <th>Barcode</th>
103
                                            <th>Library</th>
103
                                            <th>Library</th>
104
                                            <th>Hold date</th>
104
                                            <th>Hold date</th>
105
                                            <th>Expiration date</th>
105
                                            [% IF Koha.Preference('ReserveExpiration') %]
106
                                                <th>Expiration date</th>
107
                                            [% END %]
106
                                            <th>Waiting date</th>
108
                                            <th>Waiting date</th>
107
                                            <th>Cancellation date</th>
109
                                            <th>Cancellation date</th>
108
                                            [% IF show_itemtype_column %]
110
                                            [% IF show_itemtype_column %]
Lines 124-134 Link Here
124
                                                <td>[% hold.item.barcode | html %]</td>
126
                                                <td>[% hold.item.barcode | html %]</td>
125
                                                <td>[% Branches.GetName( hold.branchcode ) | html %]</td>
127
                                                <td>[% Branches.GetName( hold.branchcode ) | html %]</td>
126
                                                <td data-order="[% hold.reservedate | html %]">[% hold.reservedate | $KohaDates %]</td>
128
                                                <td data-order="[% hold.reservedate | html %]">[% hold.reservedate | $KohaDates %]</td>
127
                                                <td data-order="[% hold.expirationdate | html %]">
129
                                                [% IF Koha.Preference('ReserveExpiration') %]
128
                                                    [% IF hold.expirationdate %]
130
                                                    <td data-order="[% hold.expirationdate | html %]">
129
                                                        [% hold.expirationdate | $KohaDates %]
131
                                                        [% IF hold.expirationdate %]
130
                                                    [% END %]
132
                                                            [% hold.expirationdate | $KohaDates %]
131
                                                </td>
133
                                                        [% END %]
134
                                                    </td>
135
                                                [% END %]
132
                                                <td data-order="[% hold.waitingdate | html %]">
136
                                                <td data-order="[% hold.waitingdate | html %]">
133
                                                    [% IF hold.waitingdate %]
137
                                                    [% IF hold.waitingdate %]
134
                                                        [% hold.waitingdate | $KohaDates %]
138
                                                        [% hold.waitingdate | $KohaDates %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt (+2 lines)
Lines 290-295 Link Here
290
                                                    </li>
290
                                                    </li>
291
                                                [% END %]
291
                                                [% END %]
292
292
293
                                                [% IF Koha.Preference('ReserveExpiration') %]
293
                                                <li>
294
                                                <li>
294
                                                    <label for="to[% bibitemloo.biblionumber | html %]">Hold not needed after:</label>
295
                                                    <label for="to[% bibitemloo.biblionumber | html %]">Hold not needed after:</label>
295
                                                    <input
296
                                                    <input
Lines 303-308 Link Here
303
                                                    <span class="date-format to" data-biblionumber="[% bibitemloo.biblionumber | html %]">[% INCLUDE 'date-format.inc' %]</span>
304
                                                    <span class="date-format to" data-biblionumber="[% bibitemloo.biblionumber | html %]">[% INCLUDE 'date-format.inc' %]</span>
304
                                                    <div class="required_label" style="display:none;">Required</div>
305
                                                    <div class="required_label" style="display:none;">Required</div>
305
                                                </li>
306
                                                </li>
307
                                                [% END %]
306
308
307
                                                [% IF Koha.Preference('AllowHoldItemTypeSelection') %]
309
                                                [% IF Koha.Preference('AllowHoldItemTypeSelection') %]
308
                                                    <li>
310
                                                    <li>
(-)a/misc/cronjobs/holds/cancel_expired_holds.pl (-1 / +3 lines)
Lines 74-79 GetOptions( Link Here
74
) or pod2usage(1);
74
) or pod2usage(1);
75
pod2usage(1) if $help;
75
pod2usage(1) if $help;
76
76
77
C4::Reserves::CancelExpiredReserves($reason);
77
if( C4::Context->preference('ReserveExpiration') ) {
78
    C4::Reserves::CancelExpiredReserves($reason);
79
}
78
80
79
cronlogaction( { action => 'End', info => "COMPLETED" } );
81
cronlogaction( { action => 'End', info => "COMPLETED" } );
(-)a/t/db_dependent/Hold.t (-1 / +38 lines)
Lines 30-36 use Koha::DateUtils qw( dt_from_string ); Link Here
30
use t::lib::TestBuilder;
30
use t::lib::TestBuilder;
31
31
32
use Test::NoWarnings;
32
use Test::NoWarnings;
33
use Test::More tests => 36;
33
use Test::More tests => 37;
34
use Test::Exception;
34
use Test::Exception;
35
use Test::Warn;
35
use Test::Warn;
36
36
Lines 488-490 subtest 'suspend() tests' => sub { Link Here
488
488
489
    $schema->storage->txn_rollback;
489
    $schema->storage->txn_rollback;
490
};
490
};
491
492
subtest 'ReserveExpiration syspref tests' => sub {
493
494
    plan tests => 2;
495
496
    $schema->storage->txn_begin;
497
    t::lib::Mocks::mock_preference( 'ExpireReservesMaxPickUpDelay', 1 );
498
499
    # Disable expiration date for reserves
500
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 0 );
501
502
    my $expirationdate = dt_from_string->add( days => 1 );
503
    my $hold           = $builder->build_object(
504
        {
505
            class => 'Koha::Holds',
506
            value => { patron_expiration_date => $expirationdate }
507
        }
508
    );
509
    $hold->set_waiting;
510
511
    is( $hold->expirationdate, undef, "No expiration date should be set with reserve expiration disabled" );
512
513
    # Re-enable expiration date for reserves
514
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 1 );
515
516
    $hold = $builder->build_object(
517
        {
518
            class => 'Koha::Holds',
519
            value => { patron_expiration_date => $expirationdate }
520
        }
521
    );
522
    $hold->set_waiting();
523
524
    is( $hold->expirationdate, $expirationdate->ymd, "Expiration date is set as expected" );
525
526
    $schema->storage->txn_rollback;
527
};
(-)a/t/db_dependent/Reserves.t (-2 / +47 lines)
Lines 17-23 Link Here
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Test::More tests => 70;
20
use Test::More tests => 71;
21
use Test::NoWarnings;
21
use Test::NoWarnings;
22
use Test::MockModule;
22
use Test::MockModule;
23
use Test::Warn;
23
use Test::Warn;
Lines 1420-1425 subtest 'ModReserveAffect logging' => sub { Link Here
1420
    like( $log->info, qr{$expected}, 'Timestamp logged is the current one' );
1420
    like( $log->info, qr{$expected}, 'Timestamp logged is the current one' );
1421
};
1421
};
1422
1422
1423
subtest 'ReserveExpiration syspref tests' => sub {
1424
1425
    plan tests => 2;
1426
1427
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 1 );
1428
1429
    my $expirationdate = dt_from_string->add( days => 1 );
1430
    my $hold           = $builder->build_object(
1431
        {
1432
            class => 'Koha::Holds',
1433
            value => {
1434
                found          => 'W',
1435
                expirationdate => $expirationdate
1436
            }
1437
        }
1438
    );
1439
1440
    # Disable expiration date for reserves
1441
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 0 );
1442
1443
    $hold->revert_found();
1444
1445
    is( $hold->expirationdate, undef, "Expiration date should be removed with reserve expiration disabled" );
1446
1447
    # Re-enable expiration date for reserves
1448
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 1 );
1449
1450
    $hold = $builder->build_object(
1451
        {
1452
            class => 'Koha::Holds',
1453
            value => {
1454
                found          => 'W',
1455
                expirationdate => $expirationdate
1456
            }
1457
        }
1458
    );
1459
1460
    $hold->set_waiting();
1461
    $hold->revert_found();
1462
1463
    is(
1464
        $hold->expirationdate, undef,
1465
        "Expiration date is still removed because we can't reset to the original expiration date"
1466
    );
1467
};
1468
1423
sub count_hold_print_messages {
1469
sub count_hold_print_messages {
1424
    my $message_count = $dbh->selectall_arrayref(
1470
    my $message_count = $dbh->selectall_arrayref(
1425
        q{
1471
        q{
1426
- 

Return to bug 24194