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 2171-2177 sub RevertWaitingStatus { Link Here
2171
            priority    => 1,
2171
            priority    => 1,
2172
            found       => undef,
2172
            found       => undef,
2173
            waitingdate => undef,
2173
            waitingdate => undef,
2174
            expirationdate => $hold->patron_expiration_date,
2174
            expirationdate => undef,
2175
            itemnumber  => $hold->item_level_hold ? $hold->itemnumber : undef,
2175
            itemnumber  => $hold->item_level_hold ? $hold->itemnumber : undef,
2176
        }
2176
        }
2177
    )->store();
2177
    )->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 607-612 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
607
('RequireChoosingExistingAuthority','0',NULL,'Require existing authority selection in controlled fields during cataloging.','YesNo'),
607
('RequireChoosingExistingAuthority','0',NULL,'Require existing authority selection in controlled fields during cataloging.','YesNo'),
608
('RequirePaymentType','0','','Require staff to select a payment type when a payment is made','YesNo'),
608
('RequirePaymentType','0','','Require staff to select a payment type when a payment is made','YesNo'),
609
('RequireStrongPassword','1','','Require a strong login password for staff and patrons','YesNo'),
609
('RequireStrongPassword','1','','Require a strong login password for staff and patrons','YesNo'),
610
('ReserveExpiration', 1, NULL, 'Enable the use of expiration date in holds module.', 'YesNo'),
610
('ReservesControlBranch','PatronLibrary','ItemHomeLibrary|PatronLibrary','Branch checked for members reservations rights','Choice'),
611
('ReservesControlBranch','PatronLibrary','ItemHomeLibrary|PatronLibrary','Branch checked for members reservations rights','Choice'),
611
('ReservesMaxPickUpDelay','7','','Define the Maximum delay to pick up an item on hold','Integer'),
612
('ReservesMaxPickUpDelay','7','','Define the Maximum delay to pick up an item on hold','Integer'),
612
('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'),
613
('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 124-132 Link Here
124
                    [% hold.date | $KohaDates %]
126
                    [% hold.date | $KohaDates %]
125
                [% END %]
127
                [% END %]
126
            </td>
128
            </td>
129
            [% IF Koha.Preference('ReserveExpiration') %]
127
            <td>
130
            <td>
128
                <input type="text" class="flatpickr" data-flatpickr-futuredate="true" value="[% hold.expirationdate | html %]" size="10" name="expirationdate" />
131
                <input type="text" class="flatpickr" data-flatpickr-futuredate="true" value="[% hold.expirationdate | html %]" size="10" name="expirationdate" />
129
            </td>
132
            </td>
133
            [% END %]
130
            <td>
134
            <td>
131
                [%- IF ( hold.found ) -%]
135
                [%- IF ( hold.found ) -%]
132
                    <input type="hidden" name="pickup" value="[% hold.wbrcode | html %]" />
136
                    <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 766-778 Circulation: Link Here
766
            - Mark a hold as problematic if it has been waiting for more than
766
            - Mark a hold as problematic if it has been waiting for more than
767
            - pref: ReservesMaxPickUpDelay
767
            - pref: ReservesMaxPickUpDelay
768
              class: integer
768
              class: integer
769
            - days.
769
            - '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.'
770
        -
770
        -
771
            - pref: ExpireReservesMaxPickUpDelay
771
            - pref: ExpireReservesMaxPickUpDelay
772
              choices:
772
              choices:
773
                  1: Allow
773
                  1: Allow
774
                  0: "Don't allow"
774
                  0: "Don't allow"
775
            - '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>'
775
            - '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>'
776
            - pref: ExpireReservesAutoFill
776
            - pref: ExpireReservesAutoFill
777
              choices:
777
              choices:
778
                  1: "Do"
778
                  1: "Do"
Lines 787-793 Circulation: Link Here
787
            - 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
787
            - 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
788
            - pref: ExpireReservesMaxPickUpDelayCharge
788
            - pref: ExpireReservesMaxPickUpDelayCharge
789
              class: currency
789
              class: currency
790
            - "."
790
            - '.<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.'
791
        -
791
        -
792
            - Satisfy holds using items from the libraries
792
            - Satisfy holds using items from the libraries
793
            - pref: StaticHoldsQueueWeight
793
            - pref: StaticHoldsQueueWeight
Lines 877-883 Circulation: Link Here
877
              choices:
877
              choices:
878
                  1: allow
878
                  1: allow
879
                  0: "don't allow"
879
                  0: "don't allow"
880
            - expired holds to be canceled on days the library is closed per the calendar.
880
            - '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.'
881
        -
881
        -
882
            - pref: ExcludeHolidaysFromMaxPickUpDelay
882
            - pref: ExcludeHolidaysFromMaxPickUpDelay
883
              choices:
883
              choices:
Lines 1006-1011 Circulation: Link Here
1006
                  1: block
1006
                  1: block
1007
                  0: allow
1007
                  0: allow
1008
            - renewing of items from the staff interface and via the <code>misc/cronjobs/automatic_renewals.pl</code> cronjob.
1008
            - renewing of items from the staff interface and via the <code>misc/cronjobs/automatic_renewals.pl</code> cronjob.
1009
        -
1010
            - pref: ReserveExpiration
1011
              choices:
1012
                  1: Enable
1013
                  0: "Disable"
1014
            - 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.
1009
    Fines Policy:
1015
    Fines Policy:
1010
        -
1016
        -
1011
            - pref: finesCalendar
1017
            - pref: finesCalendar
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (+1 lines)
Lines 1067-1072 Link Here
1067
            relatives_borrowernumbers.push("[% b | html %]");
1067
            relatives_borrowernumbers.push("[% b | html %]");
1068
        [% END %]
1068
        [% END %]
1069
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
1069
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
1070
        var ReserveExpiration = [% ( Koha.Preference('ReserveExpiration') ) ? 1 : 0 | html %];
1070
    </script>
1071
    </script>
1071
    [% Asset.js("js/pages/circulation.js") | $raw %]
1072
    [% Asset.js("js/pages/circulation.js") | $raw %]
1072
    [% Asset.js("js/checkouts.js") | $raw %]
1073
    [% Asset.js("js/checkouts.js") | $raw %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/holdshistory.tt (-5 / +16 lines)
Lines 139-150 Link Here
139
    [% INCLUDE 'str/members-menu.inc' %]
139
    [% INCLUDE 'str/members-menu.inc' %]
140
    [% Asset.js("js/members-menu.js") | $raw %]
140
    [% Asset.js("js/members-menu.js") | $raw %]
141
    <script>
141
    <script>
142
        var ReserveExpiration = [% ( Koha.Preference('ReserveExpiration') ) ? 1 : 0 | html %];
143
        var show_itemtype_column = [% ( show_itemtype_column ) ? 1 : 0 | html %];
144
        var table_settings = [% TablesSettings.GetTableSettings('members', 'holdshistory', 'holdshistory-table', 'json') | $raw %];
142
        $(document).ready(function() {
145
        $(document).ready(function() {
143
            var table_settings = [% TablesSettings.GetTableSettings('members', 'holdshistory', 'holdshistory-table', 'json') | $raw %];
146
            table_settings['columns'].forEach(function(thisCol) {
144
            [% UNLESS show_itemtype_column %]
147
                if( show_itemtype_column == 0 && thisCol.columnname == "itemtype" ){
145
              //Remove item type column settings
148
                    thisCol.cannot_be_modified = 1;
146
              table_settings['columns'] = table_settings['columns'].filter(function(c){return c['columnname'] != 'itemtype';});
149
                    thisCol.cannot_be_toggled = 1;
147
            [% END %]
150
                    thisCol.is_hidden = 1;
151
                }
152
                if( ReserveExpiration == 0 && thisCol.columnname == "expirationdate" ){
153
                    thisCol.cannot_be_modified = 1;
154
                    thisCol.cannot_be_toggled = 1;
155
                    thisCol.is_hidden = 1;
156
                }
157
            });
158
148
            var table = KohaTable("table_holdshistory", {
159
            var table = KohaTable("table_holdshistory", {
149
                "sPaginationType": "full",
160
                "sPaginationType": "full",
150
                "aaSorting": [[4, 'desc']]
161
                "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 877-882 Link Here
877
            relatives_borrowernumbers.push("[% b | html %]");
877
            relatives_borrowernumbers.push("[% b | html %]");
878
        [% END %]
878
        [% END %]
879
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
879
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
880
        var ReserveExpiration = [% ( Koha.Preference('ReserveExpiration') ) ? 1 : 0 | html %];
880
    </script>
881
    </script>
881
    [% Asset.js("js/pages/circulation.js") | $raw %]
882
    [% Asset.js("js/pages/circulation.js") | $raw %]
882
    [% Asset.js("js/checkouts.js") | $raw %]
883
    [% Asset.js("js/checkouts.js") | $raw %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (-4 / +6 lines)
Lines 591-600 Link Here
591
                                </li>
591
                                </li>
592
                            [% END %]
592
                            [% END %]
593
593
594
                            <li>
594
                            [% IF Koha.Preference('ReserveExpiration') %]
595
                                <label for="to">Hold expires on date:</label>
595
                                <li>
596
                                <input id="expiration_date" name="expiration_date" id="to" size="10" type="text" class="flatpickr" data-flatpickr-futuredate="true" />
596
                                    <label for="to">Hold expires on date:</label>
597
                            </li>
597
                                    <input id="expiration_date" name="expiration_date" id="to" size="10" type="text" class="flatpickr" data-flatpickr-futuredate="true" />
598
                                </li>
599
                            [% END %]
598
600
599
                            [% UNLESS ( multi_hold ) %]
601
                            [% UNLESS ( multi_hold ) %]
600
                                <li>
602
                                <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