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

(-)a/C4/ILSDI/Services.pm (-2 / +8 lines)
Lines 777-783 sub HoldTitle { Link Here
777
    return { code => 'cannotBeTransferred' } unless $biblio->can_be_transferred({ to => $destination });
777
    return { code => 'cannotBeTransferred' } unless $biblio->can_be_transferred({ to => $destination });
778
778
779
    my $resdate = $cgi->param('start_date');
779
    my $resdate = $cgi->param('start_date');
780
    my $expdate = $cgi->param('expiry_date');
780
    my $expdate;
781
    if ( C4::Context->preference('ReserveExpiration') and $cgi->param('expiry_date') ) {
782
        $expdate = $cgi->param('expiry_date');
783
    }
781
784
782
    # Add the reserve
785
    # Add the reserve
783
    #    $branch,    $borrowernumber, $biblionumber,
786
    #    $branch,    $borrowernumber, $biblionumber,
Lines 872-878 sub HoldItem { Link Here
872
    return { code => $canitembereserved } unless $canitembereserved eq 'OK';
875
    return { code => $canitembereserved } unless $canitembereserved eq 'OK';
873
876
874
    my $resdate = $cgi->param('start_date');
877
    my $resdate = $cgi->param('start_date');
875
    my $expdate = $cgi->param('expiry_date');
878
    my $expdate;
879
    if ( C4::Context->preference('ReserveExpiration') and $cgi->param('expiry_date') ) {
880
        $expdate = $cgi->param('expiry_date');
881
    }
876
882
877
    # Add the reserve
883
    # Add the reserve
878
    my $priority = C4::Reserves::CalculatePriority($biblionumber);
884
    my $priority = C4::Reserves::CalculatePriority($biblionumber);
(-)a/C4/Reserves.pm (-2 / +2 lines)
Lines 186-192 sub AddReserve { Link Here
186
    my $biblionumber   = $params->{biblionumber};
186
    my $biblionumber   = $params->{biblionumber};
187
    my $priority       = $params->{priority};
187
    my $priority       = $params->{priority};
188
    my $resdate        = $params->{reservation_date};
188
    my $resdate        = $params->{reservation_date};
189
    my $patron_expiration_date = $params->{expiration_date};
189
    my $patron_expiration_date = C4::Context->preference('ReserveExpiration') ? $params->{expiration_date} : undef;
190
    my $notes          = $params->{notes};
190
    my $notes          = $params->{notes};
191
    my $title          = $params->{title};
191
    my $title          = $params->{title};
192
    my $checkitem      = $params->{itemnumber};
192
    my $checkitem      = $params->{itemnumber};
Lines 2172-2178 sub RevertWaitingStatus { Link Here
2172
            priority    => 1,
2172
            priority    => 1,
2173
            found       => undef,
2173
            found       => undef,
2174
            waitingdate => undef,
2174
            waitingdate => undef,
2175
            expirationdate => $hold->patron_expiration_date,
2175
            expirationdate => undef,
2176
            itemnumber  => $hold->item_level_hold ? $hold->itemnumber : undef,
2176
            itemnumber  => $hold->item_level_hold ? $hold->itemnumber : undef,
2177
        }
2177
        }
2178
    )->store();
2178
    )->store();
(-)a/Koha/Club/Hold.pm (-1 / +1 lines)
Lines 125-131 sub add { Link Here
125
                borrowernumber  => $patron_id,
125
                borrowernumber  => $patron_id,
126
                biblionumber    => $params->{biblio_id},
126
                biblionumber    => $params->{biblio_id},
127
                priority        => $priority,
127
                priority        => $priority,
128
                expiration_date => $params->{expiration_date},
128
                expiration_date => C4::Context->preference('ReserveExpiration') ? $params->{expiration_date} : undef,
129
                notes           => $params->{notes},
129
                notes           => $params->{notes},
130
                title           => $biblio->title,
130
                title           => $biblio->title,
131
                itemnumber      => $params->{item_id},
131
                itemnumber      => $params->{item_id},
(-)a/Koha/Hold.pm (-15 / +25 lines)
Lines 228-237 sub set_waiting { Link Here
228
        desk_id => $desk_id,
228
        desk_id => $desk_id,
229
    };
229
    };
230
230
231
    my $new_expiration_date;
232
233
    if ( C4::Context->preference('ReserveExpiration') ) {
234
231
    my $max_pickup_delay = C4::Context->preference("ReservesMaxPickUpDelay");
235
    my $max_pickup_delay = C4::Context->preference("ReservesMaxPickUpDelay");
232
    my $cancel_on_holidays = C4::Context->preference('ExpireReservesOnHolidays');
236
    my $cancel_on_holidays = C4::Context->preference('ExpireReservesOnHolidays');
233
237
234
    my $new_expiration_date = $today->clone->add(days => $max_pickup_delay);
238
    $new_expiration_date = $today->clone->add(days => $max_pickup_delay);
235
239
236
    if ( C4::Context->preference("ExcludeHolidaysFromMaxPickUpDelay") ) {
240
    if ( C4::Context->preference("ExcludeHolidaysFromMaxPickUpDelay") ) {
237
        my $itemtype = $self->item ? $self->item->effective_itemtype : $self->biblio->itemtype;
241
        my $itemtype = $self->item ? $self->item->effective_itemtype : $self->biblio->itemtype;
Lines 243-267 sub set_waiting { Link Here
243
            }
247
            }
244
        );
248
        );
245
        my $calendar = Koha::Calendar->new( branchcode => $self->branchcode, days_mode => $daysmode );
249
        my $calendar = Koha::Calendar->new( branchcode => $self->branchcode, days_mode => $daysmode );
246
247
        $new_expiration_date = $calendar->days_forward( dt_from_string(), $max_pickup_delay );
250
        $new_expiration_date = $calendar->days_forward( dt_from_string(), $max_pickup_delay );
248
    }
251
    }
249
252
250
    # If patron's requested expiration date is prior to the
253
    if ( C4::Context->preference('ExpireReservesMaxPickUpDelay') ) {
251
    # calculated one, we keep the patron's one.
254
        # If patron's requested expiration date is prior to the
252
    if ( $self->patron_expiration_date ) {
255
        # calculated one, we keep the patron's one.
253
        my $requested_expiration = dt_from_string( $self->patron_expiration_date );
256
        if ( $self->patron_expiration_date ) {
254
257
            my $requested_expiration = dt_from_string( $self->patron_expiration_date );
255
        my $cmp =
258
256
          $requested_expiration
259
            my $cmp =
257
          ? DateTime->compare( $requested_expiration, $new_expiration_date )
260
              $requested_expiration
258
          : 0;
261
              ? DateTime->compare( $requested_expiration, $new_expiration_date )
259
262
              : 0;
260
        $new_expiration_date =
263
261
          $cmp == -1 ? $requested_expiration : $new_expiration_date;
264
            $new_expiration_date =
265
              $cmp == -1 ? $requested_expiration : $new_expiration_date;
266
          }
267
    } else {
268
        # if holds don't need a waiting expiration date to be expired automatically, don't set one
269
        $new_expiration_date = undef;
262
    }
270
    }
263
271
264
    $values->{expirationdate} = $new_expiration_date->ymd;
272
    } # ReserveExpiration
273
274
    $values->{expirationdate} = $new_expiration_date ? $new_expiration_date->ymd : undef;
265
275
266
    $self->set($values)->store();
276
    $self->set($values)->store();
267
277
(-)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 75-81 sub add { Link Here
75
        my $item_id           = $body->{item_id};
75
        my $item_id           = $body->{item_id};
76
        my $patron_id         = $body->{patron_id};
76
        my $patron_id         = $body->{patron_id};
77
        my $item_type         = $body->{item_type};
77
        my $item_type         = $body->{item_type};
78
        my $expiration_date   = $body->{expiration_date};
78
        my $expiration_date   = C4::Context->preference('ReserveExpiration') ? $body->{expiration_date} : undef;
79
        my $notes             = $body->{notes};
79
        my $notes             = $body->{notes};
80
        my $hold_date         = $body->{hold_date};
80
        my $hold_date         = $body->{hold_date};
81
        my $non_priority      = $body->{non_priority};
81
        my $non_priority      = $body->{non_priority};
(-)a/circ/waitingreserves.pl (-2 / +2 lines)
Lines 100-108 while ( my $hold = $holds->next ) { Link Here
100
    next unless $hold->waitingdate;
100
    next unless $hold->waitingdate;
101
101
102
    my ( $expire_year, $expire_month, $expire_day ) = split (/-/, $hold->expirationdate);
102
    my ( $expire_year, $expire_month, $expire_day ) = split (/-/, $hold->expirationdate);
103
    my $calcDate = Date_to_Days( $expire_year, $expire_month, $expire_day );
103
    my $calcDate = Date_to_Days( $expire_year, $expire_month, $expire_day ) if $hold->expirationdate;
104
104
105
    if ($today > $calcDate) {
105
    if ($calcDate and $today > $calcDate) {
106
        if ($cancelall) {
106
        if ($cancelall) {
107
            my $res = cancel( $hold->item->itemnumber, $hold->borrowernumber, $hold->item->holdingbranch, $hold->item->homebranch, !$transfer_when_cancel_all );
107
            my $res = cancel( $hold->item->itemnumber, $hold->borrowernumber, $hold->item->holdingbranch, $hold->item->homebranch, !$transfer_when_cancel_all );
108
            push @cancel_result, $res if $res;
108
            push @cancel_result, $res if $res;
(-)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 612-617 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
612
('RequireChoosingExistingAuthority','0',NULL,'Require existing authority selection in controlled fields during cataloging.','YesNo'),
612
('RequireChoosingExistingAuthority','0',NULL,'Require existing authority selection in controlled fields during cataloging.','YesNo'),
613
('RequirePaymentType','0','','Require staff to select a payment type when a payment is made','YesNo'),
613
('RequirePaymentType','0','','Require staff to select a payment type when a payment is made','YesNo'),
614
('RequireStrongPassword','1','','Require a strong login password for staff and patrons','YesNo'),
614
('RequireStrongPassword','1','','Require a strong login password for staff and patrons','YesNo'),
615
('ReserveExpiration', 1, NULL, 'Enable the use of expiration date in holds module.', 'YesNo'),
615
('ReservesControlBranch','PatronLibrary','ItemHomeLibrary|PatronLibrary','Branch checked for members reservations rights','Choice'),
616
('ReservesControlBranch','PatronLibrary','ItemHomeLibrary|PatronLibrary','Branch checked for members reservations rights','Choice'),
616
('ReservesMaxPickUpDelay','7','','Define the Maximum delay to pick up an item on hold','Integer'),
617
('ReservesMaxPickUpDelay','7','','Define the Maximum delay to pick up an item on hold','Integer'),
617
('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'),
618
('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 (-1 / +5 lines)
Lines 12-18 Link Here
12
            <th>Patron</th>
12
            <th>Patron</th>
13
            <th>Notes</th>
13
            <th>Notes</th>
14
            <th>Date</th>
14
            <th>Date</th>
15
            <th>Expiration</th>
15
            [% IF Koha.Preference('ReserveExpiration') %]
16
                <th>Expiration</th>
17
            [% END %]
16
            <th>Pickup library</th>
18
            <th>Pickup library</th>
17
            <th>Details</th>
19
            <th>Details</th>
18
            [% IF ( CAN_user_reserveforothers_modify_holds_priority ) %]
20
            [% IF ( CAN_user_reserveforothers_modify_holds_priority ) %]
Lines 128-136 Link Here
128
                    [% hold.date | $KohaDates %]
130
                    [% hold.date | $KohaDates %]
129
                [% END %]
131
                [% END %]
130
            </td>
132
            </td>
133
            [% IF Koha.Preference('ReserveExpiration') %]
131
            <td>
134
            <td>
132
                <input type="text" class="flatpickr" data-flatpickr-futuredate="true" value="[% hold.expirationdate | html %]" size="10" name="expirationdate" />
135
                <input type="text" class="flatpickr" data-flatpickr-futuredate="true" value="[% hold.expirationdate | html %]" size="10" name="expirationdate" />
133
            </td>
136
            </td>
137
            [% END %]
134
            <td>
138
            <td>
135
                [%- IF ( hold.found ) -%]
139
                [%- IF ( hold.found ) -%]
136
                    <input type="hidden" name="pickup" value="[% hold.wbrcode | html %]" />
140
                    <input type="hidden" name="pickup" value="[% hold.wbrcode | html %]" />
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/waiting_holds.inc (+4 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
          [% IF Koha.Preference('ReserveExpiration') %]
13
            <th>Expiration date</th>
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 43-49 Link Here
43
                  <td></td>
45
                  <td></td>
44
                [% END %]
46
                [% END %]
45
              [% END %]
47
              [% END %]
48
              [% IF Koha.Preference('ReserveExpiration') %]
46
                <td data-order="[% reserveloo.expirationdate | html %]"><span>[% reserveloo.expirationdate | $KohaDates %]</span></td>
49
                <td data-order="[% reserveloo.expirationdate | html %]"><span>[% reserveloo.expirationdate | $KohaDates %]</span></td>
50
              [% END %]
47
                <td>
51
                <td>
48
                    [% INCLUDE 'biblio-title.inc' biblio=reserveloo.biblio link = 1 %]
52
                    [% INCLUDE 'biblio-title.inc' biblio=reserveloo.biblio link = 1 %]
49
                        [% UNLESS ( item_level_itypes ) %]
53
                        [% UNLESS ( item_level_itypes ) %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (-4 / +10 lines)
Lines 774-786 Circulation: Link Here
774
            - Mark a hold as problematic if it has been waiting for more than
774
            - Mark a hold as problematic if it has been waiting for more than
775
            - pref: ReservesMaxPickUpDelay
775
            - pref: ReservesMaxPickUpDelay
776
              class: integer
776
              class: integer
777
            - days.
777
            - '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.'
778
        -
778
        -
779
            - pref: ExpireReservesMaxPickUpDelay
779
            - pref: ExpireReservesMaxPickUpDelay
780
              choices:
780
              choices:
781
                  1: Allow
781
                  1: Allow
782
                  0: "Don't allow"
782
                  0: "Don't allow"
783
            - '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>'
783
            - '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>'
784
            - pref: ExpireReservesAutoFill
784
            - pref: ExpireReservesAutoFill
785
              choices:
785
              choices:
786
                  1: "Do"
786
                  1: "Do"
Lines 795-801 Circulation: Link Here
795
            - 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
795
            - 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
796
            - pref: ExpireReservesMaxPickUpDelayCharge
796
            - pref: ExpireReservesMaxPickUpDelayCharge
797
              class: currency
797
              class: currency
798
            - "."
798
            - '.<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.'
799
        -
799
        -
800
            - Satisfy holds using items from the libraries
800
            - Satisfy holds using items from the libraries
801
            - pref: StaticHoldsQueueWeight
801
            - pref: StaticHoldsQueueWeight
Lines 885-891 Circulation: Link Here
885
              choices:
885
              choices:
886
                  1: allow
886
                  1: allow
887
                  0: "don't allow"
887
                  0: "don't allow"
888
            - expired holds to be canceled on days the library is closed per the calendar.
888
            - '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.'
889
        -
889
        -
890
            - pref: ExcludeHolidaysFromMaxPickUpDelay
890
            - pref: ExcludeHolidaysFromMaxPickUpDelay
891
              choices:
891
              choices:
Lines 1014-1019 Circulation: Link Here
1014
                  1: block
1014
                  1: block
1015
                  0: allow
1015
                  0: allow
1016
            - renewing of items from the staff interface and via the <code>misc/cronjobs/automatic_renewals.pl</code> cronjob.
1016
            - renewing of items from the staff interface and via the <code>misc/cronjobs/automatic_renewals.pl</code> cronjob.
1017
        -
1018
            - pref: ReserveExpiration
1019
              choices:
1020
                  1: Enable
1021
                  0: "Disable"
1022
            - 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.
1017
    Fines Policy:
1023
    Fines Policy:
1018
        -
1024
        -
1019
            - pref: finesCalendar
1025
            - pref: finesCalendar
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (+1 lines)
Lines 1057-1062 Link Here
1057
            relatives_borrowernumbers.push("[% b | html %]");
1057
            relatives_borrowernumbers.push("[% b | html %]");
1058
        [% END %]
1058
        [% END %]
1059
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
1059
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
1060
        var ReserveExpiration = [% ( Koha.Preference('ReserveExpiration') ) ? 1 : 0 | html %];
1060
    </script>
1061
    </script>
1061
    [% Asset.js("js/pages/circulation.js") | $raw %]
1062
    [% Asset.js("js/pages/circulation.js") | $raw %]
1062
    [% Asset.js("js/checkouts.js") | $raw %]
1063
    [% Asset.js("js/checkouts.js") | $raw %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/holdshistory.tt (-5 / +16 lines)
Lines 135-146 Link Here
135
    [% INCLUDE 'str/members-menu.inc' %]
135
    [% INCLUDE 'str/members-menu.inc' %]
136
    [% Asset.js("js/members-menu.js") | $raw %]
136
    [% Asset.js("js/members-menu.js") | $raw %]
137
    <script>
137
    <script>
138
        var ReserveExpiration = [% ( Koha.Preference('ReserveExpiration') ) ? 1 : 0 | html %];
139
        var show_itemtype_column = [% ( show_itemtype_column ) ? 1 : 0 | html %];
140
        var table_settings = [% TablesSettings.GetTableSettings('members', 'holdshistory', 'holdshistory-table', 'json') | $raw %];
138
        $(document).ready(function() {
141
        $(document).ready(function() {
139
            var table_settings = [% TablesSettings.GetTableSettings('members', 'holdshistory', 'holdshistory-table', 'json') | $raw %];
142
            table_settings['columns'].forEach(function(thisCol) {
140
            [% UNLESS show_itemtype_column %]
143
                if( show_itemtype_column == 0 && thisCol.columnname == "itemtype" ){
141
              //Remove item type column settings
144
                    thisCol.cannot_be_modified = 1;
142
              table_settings['columns'] = table_settings['columns'].filter(function(c){return c['columnname'] != 'itemtype';});
145
                    thisCol.cannot_be_toggled = 1;
143
            [% END %]
146
                    thisCol.is_hidden = 1;
147
                }
148
                if( ReserveExpiration == 0 && thisCol.columnname == "expirationdate" ){
149
                    thisCol.cannot_be_modified = 1;
150
                    thisCol.cannot_be_toggled = 1;
151
                    thisCol.is_hidden = 1;
152
                }
153
            });
154
144
            var table = KohaTable("table_holdshistory", {
155
            var table = KohaTable("table_holdshistory", {
145
                "sPaginationType": "full",
156
                "sPaginationType": "full",
146
                "aaSorting": [[4, 'desc']]
157
                "aaSorting": [[4, 'desc']]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-print.tt (-2 / +6 lines)
Lines 115-121 Link Here
115
                    <th>Title</th>
115
                    <th>Title</th>
116
                    <th>Author</th>
116
                    <th>Author</th>
117
                    <th>Placed on</th>
117
                    <th>Placed on</th>
118
                    <th>Expires on</th>
118
                    [% IF Koha.Preference('ReserveExpiration') %]
119
                        <th>Expires on</th>
120
                    [% END %]
119
                    <th>Pick up location</th>
121
                    <th>Pick up location</th>
120
                </tr>
122
                </tr>
121
            </thead>
123
            </thead>
Lines 125-131 Link Here
125
                        <td>[% reserve.title | html %]</td>
127
                        <td>[% reserve.title | html %]</td>
126
                        <td>[% reserve.author | html %]</td>
128
                        <td>[% reserve.author | html %]</td>
127
                        <td>[% reserve.reservedate | $KohaDates %]</td>
129
                        <td>[% reserve.reservedate | $KohaDates %]</td>
128
                        <td>[% reserve.expirationdate | $KohaDates %]</td>
130
                        [% IF Koha.Preference('ReserveExpiration') %]
131
                            <td>[% reserve.expirationdate | $KohaDates %]</td>
132
                        [% END %]
129
                        <td>[% reserve.waiting_at | html %]</td>
133
                        <td>[% reserve.waiting_at | html %]</td>
130
                    </tr>
134
                    </tr>
131
                [% END %]
135
                [% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt (+1 lines)
Lines 907-912 Link Here
907
            relatives_borrowernumbers.push("[% b | html %]");
907
            relatives_borrowernumbers.push("[% b | html %]");
908
        [% END %]
908
        [% END %]
909
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
909
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
910
        var ReserveExpiration = [% ( Koha.Preference('ReserveExpiration') ) ? 1 : 0 | html %];
910
    </script>
911
    </script>
911
    [% Asset.js("js/pages/circulation.js") | $raw %]
912
    [% Asset.js("js/pages/circulation.js") | $raw %]
912
    [% Asset.js("js/checkouts.js") | $raw %]
913
    [% Asset.js("js/checkouts.js") | $raw %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (-4 / +6 lines)
Lines 593-602 Link Here
593
                                </li>
593
                                </li>
594
                            [% END %]
594
                            [% END %]
595
595
596
                            <li>
596
                            [% IF Koha.Preference('ReserveExpiration') %]
597
                                <label for="to">Hold expires on date:</label>
597
                                <li>
598
                                <input id="expiration_date" name="expiration_date" id="to" size="10" type="text" class="flatpickr" data-flatpickr-futuredate="true" />
598
                                    <label for="to">Hold expires on date:</label>
599
                            </li>
599
                                    <input id="expiration_date" name="expiration_date" id="to" size="10" type="text" class="flatpickr" data-flatpickr-futuredate="true" />
600
                                </li>
601
                            [% END %]
600
602
601
                            [% UNLESS ( multi_hold ) %]
603
                            [% UNLESS ( multi_hold ) %]
602
                                <li>
604
                                <li>
(-)a/koha-tmpl/intranet-tmpl/prog/js/holds.js (-1 / +4 lines)
Lines 223-229 $(document).ready(function() { Link Here
223
                            else { return oObj.branchcode.escapeHtml() || ""; }
223
                            else { return oObj.branchcode.escapeHtml() || ""; }
224
                        }
224
                        }
225
                    },
225
                    },
226
                    { "data": { _: "expirationdate_formatted", "sort": "expirationdate" } },
226
                    {
227
                        "visible": ReserveExpiration,
228
                        "data": { _: "expirationdate_formatted", "sort": "expirationdate" }
229
                    },
227
                    {
230
                    {
228
                        "mDataProp": function( oObj ) {
231
                        "mDataProp": function( oObj ) {
229
                            if ( oObj.priority && parseInt( oObj.priority ) && parseInt( oObj.priority ) > 0 ) {
232
                            if ( oObj.priority && parseInt( oObj.priority ) && parseInt( oObj.priority ) > 0 ) {
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/includes/holds-table.inc (-14 / +18 lines)
Lines 16-22 Link Here
16
                    [% ELSE %]
16
                    [% ELSE %]
17
                        <th class="psort">Placed on</th>
17
                        <th class="psort">Placed on</th>
18
                    [% END %]
18
                    [% END %]
19
                    <th>Expires on</th>
19
                    [% IF Koha.Preference('ReserveExpiration') %]
20
                        <th>Expires on</th>
21
                    [% END %]
20
                    [% UNLESS( singleBranchMode) %]
22
                    [% UNLESS( singleBranchMode) %]
21
                        <th>Pickup location</th>
23
                        <th>Pickup location</th>
22
                    [% END %]
24
                    [% END %]
Lines 68-87 Link Here
68
                                [% HOLD.reservedate | $KohaDates %]
70
                                [% HOLD.reservedate | $KohaDates %]
69
                            </span>
71
                            </span>
70
                        </td>
72
                        </td>
71
                        [% IF ! HOLD.found %]
73
                        [% IF Koha.Preference('ReserveExpiration') %]
72
                            <td class="expirationdate" data-order="[% HOLD.expirationdate | html %]">
74
                            [% IF ! HOLD.found %]
73
                                [% IF ( HOLD.expirationdate ) %]
75
                                <td class="expirationdate" data-order="[% HOLD.expirationdate | html %]">
74
                                    <span class="tdlabel">Expiration:</span>
76
                                    [% IF ( HOLD.expirationdate ) %]
75
                                    [% HOLD.expirationdate | $KohaDates %]
77
                                        <span class="tdlabel">Expiration:</span>
76
                                [% ELSE %]
78
                                        [% HOLD.expirationdate | $KohaDates %]
77
                                    <span class="tdlabel">Expiration:</span>
79
                                    [% ELSE %]
78
                                    Never expires
80
                                        <span class="tdlabel">Expiration:</span>
79
                                [% END %]
81
                                        Never expires
80
                        [% ELSE %]
82
                                    [% END %]
81
                            <td class="expirationdate" data-order="0000-00-00">
83
                            [% ELSE %]
82
                                -
84
                                <td class="expirationdate" data-order="0000-00-00">
85
                                    -
86
                            [% END %]
87
                            </td>
83
                        [% END %]
88
                        [% END %]
84
                        </td>
85
                        [% UNLESS( singleBranchMode) %]
89
                        [% UNLESS( singleBranchMode) %]
86
                            <td class="branch">
90
                            <td class="branch">
87
                                <span class="tdlabel">Pickup location:</span>
91
                                <span class="tdlabel">Pickup location:</span>
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-holdshistory.tt (-6 / +10 lines)
Lines 106-112 Link Here
106
                                        <th>Barcode</th>
106
                                        <th>Barcode</th>
107
                                        <th>Library</th>
107
                                        <th>Library</th>
108
                                        <th>Hold date</th>
108
                                        <th>Hold date</th>
109
                                        <th>Expiration date</th>
109
                                        [% IF Koha.Preference('ReserveExpiration') %]
110
                                            <th>Expiration date</th>
111
                                        [% END %]
110
                                        <th>Waiting date</th>
112
                                        <th>Waiting date</th>
111
                                        <th>Cancellation date</th>
113
                                        <th>Cancellation date</th>
112
                                        [% IF show_itemtype_column %]
114
                                        [% IF show_itemtype_column %]
Lines 123-133 Link Here
123
                                        <td>[% hold.item.barcode | html %]</td>
125
                                        <td>[% hold.item.barcode | html %]</td>
124
                                        <td>[% Branches.GetName( hold.branchcode ) | html %]</td>
126
                                        <td>[% Branches.GetName( hold.branchcode ) | html %]</td>
125
                                        <td data-order="[% hold.reservedate | html %]">[% hold.reservedate | $KohaDates %]</td>
127
                                        <td data-order="[% hold.reservedate | html %]">[% hold.reservedate | $KohaDates %]</td>
126
                                        <td data-order="[% hold.expirationdate | html %]">
128
                                        [% IF Koha.Preference('ReserveExpiration') %]
127
                                            [% IF hold.expirationdate %]
129
                                            <td data-order="[% hold.expirationdate | html %]">
128
                                                [% hold.expirationdate | $KohaDates %]
130
                                                [% IF hold.expirationdate %]
129
                                            [% END %]
131
                                                    [% hold.expirationdate | $KohaDates %]
130
                                        </td>
132
                                                [% END %]
133
                                            </td>
134
                                        [% END %]
131
                                        <td data-order="[% hold.waitingdate | html %]">
135
                                        <td data-order="[% hold.waitingdate | html %]">
132
                                            [% IF hold.waitingdate %]
136
                                            [% IF hold.waitingdate %]
133
                                                [% hold.waitingdate | $KohaDates %]
137
                                                [% hold.waitingdate | $KohaDates %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt (+2 lines)
Lines 296-306 Link Here
296
                                                    </li>
296
                                                    </li>
297
                                                [% END %]
297
                                                [% END %]
298
298
299
                                                [% IF Koha.Preference('ReserveExpiration') %]
299
                                                <li>
300
                                                <li>
300
                                                    <label for="to[% bibitemloo.biblionumber | html %]">Hold not needed after:</label>
301
                                                    <label for="to[% bibitemloo.biblionumber | html %]">Hold not needed after:</label>
301
                                                    <input type="text" name="expiration_date_[% bibitemloo.biblionumber | html %]" id="to[% bibitemloo.biblionumber | html %]" size="10" class="flatpickr futuredate" />
302
                                                    <input type="text" name="expiration_date_[% bibitemloo.biblionumber | html %]" id="to[% bibitemloo.biblionumber | html %]" size="10" class="flatpickr futuredate" />
302
                                                    <span class="date-format to" data-biblionumber="[% bibitemloo.biblionumber | html %]">[% INCLUDE 'date-format.inc' %]</span>
303
                                                    <span class="date-format to" data-biblionumber="[% bibitemloo.biblionumber | html %]">[% INCLUDE 'date-format.inc' %]</span>
303
                                                </li>
304
                                                </li>
305
                                                [% END %]
304
306
305
                                                [% IF Koha.Preference('AllowHoldItemTypeSelection') %]
307
                                                [% IF Koha.Preference('AllowHoldItemTypeSelection') %]
306
                                                    <li>
308
                                                    <li>
(-)a/misc/cronjobs/holds/cancel_expired_holds.pl (-1 / +3 lines)
Lines 75-80 pod2usage(1) if $help; Link Here
75
75
76
cronlogaction({ info => $command_line_options });
76
cronlogaction({ info => $command_line_options });
77
77
78
C4::Reserves::CancelExpiredReserves($reason);
78
if( C4::Context->preference('ReserveExpiration') ) {
79
    C4::Reserves::CancelExpiredReserves($reason);
80
}
79
81
80
cronlogaction({ action => 'End', info => "COMPLETED" });
82
cronlogaction({ action => 'End', info => "COMPLETED" });
(-)a/t/db_dependent/Hold.t (-1 / +36 lines)
Lines 29-35 use Koha::Item; Link Here
29
use Koha::DateUtils qw( dt_from_string );
29
use Koha::DateUtils qw( dt_from_string );
30
use t::lib::TestBuilder;
30
use t::lib::TestBuilder;
31
31
32
use Test::More tests => 35;
32
use Test::More tests => 36;
33
use Test::Exception;
33
use Test::Exception;
34
use Test::Warn;
34
use Test::Warn;
35
35
Lines 386-388 subtest 'suspend() tests' => sub { Link Here
386
386
387
    $schema->storage->txn_rollback;
387
    $schema->storage->txn_rollback;
388
};
388
};
389
390
subtest 'ReserveExpiration syspref tests' => sub {
391
392
    plan tests => 2;
393
394
    $schema->storage->txn_begin;
395
    t::lib::Mocks::mock_preference( 'ExpireReservesMaxPickUpDelay', 1 );
396
397
    # Disable expiration date for reserves
398
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 0 );
399
400
    my $expirationdate = dt_from_string->add( days => 1 );
401
    my $hold = $builder->build_object(
402
        {   class => 'Koha::Holds',
403
            value => { patron_expiration_date => $expirationdate }
404
        }
405
    );
406
    $hold->set_waiting;
407
408
    is( $hold->expirationdate, undef, "No expiration date should be set with reserve expiration disabled" );
409
410
    # Re-enable expiration date for reserves
411
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 1 );
412
413
    $hold = $builder->build_object(
414
        {   class => 'Koha::Holds',
415
            value => { patron_expiration_date => $expirationdate }
416
        }
417
    );
418
    $hold->set_waiting();
419
420
    is( $hold->expirationdate, $expirationdate->ymd, "Expiration date is set as expected" );
421
422
    $schema->storage->txn_rollback;
423
};
(-)a/t/db_dependent/Reserves.t (-2 / +35 lines)
Lines 17-23 Link Here
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Test::More tests => 77;
20
use Test::More tests => 78;
21
use Test::MockModule;
21
use Test::MockModule;
22
use Test::Warn;
22
use Test::Warn;
23
23
Lines 1422-1427 subtest 'ModReserveAffect logging' => sub { Link Here
1422
    like( $log->info, qr{$expected}, 'Timestamp logged is the current one' );
1422
    like( $log->info, qr{$expected}, 'Timestamp logged is the current one' );
1423
};
1423
};
1424
1424
1425
subtest 'ReserveExpiration syspref tests' => sub {
1426
1427
    plan tests => 2;
1428
1429
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 1 );
1430
1431
    my $expirationdate = dt_from_string->add( days => 1 );
1432
    my $hold = $builder->build_object(
1433
        {   class => 'Koha::Holds',
1434
            value => { expirationdate => $expirationdate }
1435
        }
1436
    );
1437
1438
    # Disable expiration date for reserves
1439
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 0 );
1440
1441
    my $reverted = C4::Reserves::RevertWaitingStatus({ itemnumber => $hold->itemnumber });
1442
1443
    is( $reverted->expirationdate, undef, "Expiration date should be removed with reserve expiration disabled" );
1444
1445
    # Re-enable expiration date for reserves
1446
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 1 );
1447
1448
    $hold = $builder->build_object(
1449
        {   class => 'Koha::Holds',
1450
            value => { expirationdate => $expirationdate }
1451
        }
1452
    );
1453
1454
    $reverted = C4::Reserves::RevertWaitingStatus({ itemnumber => $hold->itemnumber });
1455
1456
    is( $reverted->expirationdate, undef, "Expiration date is still removed because we can't reset to the original expiration date" );
1457
};
1458
1425
sub count_hold_print_messages {
1459
sub count_hold_print_messages {
1426
    my $message_count = $dbh->selectall_arrayref(q{
1460
    my $message_count = $dbh->selectall_arrayref(q{
1427
        SELECT COUNT(*)
1461
        SELECT COUNT(*)
1428
- 

Return to bug 24194