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

(-)a/C4/ILSDI/Services.pm (-2 / +8 lines)
Lines 786-792 sub HoldTitle { Link Here
786
    return { code => 'cannotBeTransferred' } unless $biblio->can_be_transferred({ to => $destination });
786
    return { code => 'cannotBeTransferred' } unless $biblio->can_be_transferred({ to => $destination });
787
787
788
    my $resdate = $cgi->param('start_date');
788
    my $resdate = $cgi->param('start_date');
789
    my $expdate = $cgi->param('expiry_date');
789
    my $expdate;
790
    if ( C4::Context->preference('ReserveExpiration') and $cgi->param('expiry_date') ) {
791
        $expdate = $cgi->param('expiry_date');
792
    }
790
793
791
    # Add the reserve
794
    # Add the reserve
792
    #    $branch,    $borrowernumber, $biblionumber,
795
    #    $branch,    $borrowernumber, $biblionumber,
Lines 881-887 sub HoldItem { Link Here
881
    return { code => $canitembereserved } unless $canitembereserved eq 'OK';
884
    return { code => $canitembereserved } unless $canitembereserved eq 'OK';
882
885
883
    my $resdate = $cgi->param('start_date');
886
    my $resdate = $cgi->param('start_date');
884
    my $expdate = $cgi->param('expiry_date');
887
    my $expdate;
888
    if ( C4::Context->preference('ReserveExpiration') and $cgi->param('expiry_date') ) {
889
        $expdate = $cgi->param('expiry_date');
890
    }
885
891
886
    # Add the reserve
892
    # Add the reserve
887
    my $priority = C4::Reserves::CalculatePriority($biblionumber);
893
    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 2132-2138 sub RevertWaitingStatus { Link Here
2132
            priority    => 1,
2132
            priority    => 1,
2133
            found       => undef,
2133
            found       => undef,
2134
            waitingdate => undef,
2134
            waitingdate => undef,
2135
            expirationdate => $hold->patron_expiration_date,
2135
            expirationdate => undef,
2136
            itemnumber  => $hold->item_level_hold ? $hold->itemnumber : undef,
2136
            itemnumber  => $hold->item_level_hold ? $hold->itemnumber : undef,
2137
        }
2137
        }
2138
    )->store();
2138
    )->store();
(-)a/Koha/Club/Hold.pm (-1 / +1 lines)
Lines 126-132 sub add { Link Here
126
                borrowernumber  => $patron_id,
126
                borrowernumber  => $patron_id,
127
                biblionumber    => $params->{biblio_id},
127
                biblionumber    => $params->{biblio_id},
128
                priority        => $priority,
128
                priority        => $priority,
129
                expiration_date => $params->{expiration_date},
129
                expiration_date => C4::Context->preference('ReserveExpiration') ? $params->{expiration_date} : undef,
130
                notes           => $params->{notes},
130
                notes           => $params->{notes},
131
                title           => $biblio->title,
131
                title           => $biblio->title,
132
                itemnumber      => $params->{item_id},
132
                itemnumber      => $params->{item_id},
(-)a/Koha/Hold.pm (-11 / +22 lines)
Lines 228-233 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
Lines 261-281 sub set_waiting { Link Here
261
        $new_expiration_date = $calendar->days_forward( dt_from_string($self->waitingdate), $max_pickup_delay );
265
        $new_expiration_date = $calendar->days_forward( dt_from_string($self->waitingdate), $max_pickup_delay );
262
    }
266
    }
263
267
264
    # If patron's requested expiration date is prior to the
268
    if ( C4::Context->preference('ExpireReservesMaxPickUpDelay') ) {
265
    # calculated one, we keep the patron's one.
269
        # If patron's requested expiration date is prior to the
266
    if ( $self->patron_expiration_date ) {
270
        # calculated one, we keep the patron's one.
267
        my $requested_expiration = dt_from_string( $self->patron_expiration_date );
271
        if ( $self->patron_expiration_date ) {
272
            my $requested_expiration = dt_from_string( $self->patron_expiration_date );
268
273
269
        my $cmp =
274
            my $cmp =
270
          $requested_expiration
275
              $requested_expiration
271
          ? DateTime->compare( $requested_expiration, $new_expiration_date )
276
              ? DateTime->compare( $requested_expiration, $new_expiration_date )
272
          : 0;
277
              : 0;
273
278
274
        $new_expiration_date =
279
            $new_expiration_date =
275
          $cmp == -1 ? $requested_expiration : $new_expiration_date;
280
              $cmp == -1 ? $requested_expiration : $new_expiration_date;
281
          }
282
    } else {
283
        # if holds don't need a waiting expiration date to be expired automatically, don't set one
284
        $new_expiration_date = undef;
276
    }
285
    }
277
286
278
    $values->{expirationdate} = $new_expiration_date->ymd;
287
    } # ReserveExpiration
288
289
    $values->{expirationdate} = $new_expiration_date ? $new_expiration_date->ymd : undef;
279
290
280
    $self->set($values)->store();
291
    $self->set($values)->store();
281
292
(-)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 74-80 sub add { Link Here
74
        my $item_id           = $body->{item_id};
74
        my $item_id           = $body->{item_id};
75
        my $patron_id         = $body->{patron_id};
75
        my $patron_id         = $body->{patron_id};
76
        my $item_type         = $body->{item_type};
76
        my $item_type         = $body->{item_type};
77
        my $expiration_date   = $body->{expiration_date};
77
        my $expiration_date   = C4::Context->preference('ReserveExpiration') ? $body->{expiration_date} : undef;
78
        my $notes             = $body->{notes};
78
        my $notes             = $body->{notes};
79
        my $hold_date         = $body->{hold_date};
79
        my $hold_date         = $body->{hold_date};
80
        my $non_priority      = $body->{non_priority};
80
        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 626-631 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
626
('RequireChoosingExistingAuthority','0',NULL,'Require existing authority selection in controlled fields during cataloging.','YesNo'),
626
('RequireChoosingExistingAuthority','0',NULL,'Require existing authority selection in controlled fields during cataloging.','YesNo'),
627
('RequirePaymentType','0','','Require staff to select a payment type when a payment is made','YesNo'),
627
('RequirePaymentType','0','','Require staff to select a payment type when a payment is made','YesNo'),
628
('RequireStrongPassword','1','','Require a strong login password for staff and patrons','YesNo'),
628
('RequireStrongPassword','1','','Require a strong login password for staff and patrons','YesNo'),
629
('ReserveExpiration', 1, NULL, 'Enable the use of expiration date in holds module.', 'YesNo'),
629
('ReservesControlBranch','PatronLibrary','ItemHomeLibrary|PatronLibrary','Branch checked for members reservations rights','Choice'),
630
('ReservesControlBranch','PatronLibrary','ItemHomeLibrary|PatronLibrary','Branch checked for members reservations rights','Choice'),
630
('ReservesMaxPickUpDelay','7','','Define the Maximum delay to pick up an item on hold','Integer'),
631
('ReservesMaxPickUpDelay','7','','Define the Maximum delay to pick up an item on hold','Integer'),
631
('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'),
632
('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 12-18 Link Here
12
            <th id="patron" data-colname="patron">Patron</th>
12
            <th id="patron" data-colname="patron">Patron</th>
13
            <th id="notes" data-colname="notes">Notes</th>
13
            <th id="notes" data-colname="notes">Notes</th>
14
            <th id="date" data-colname="date">Date</th>
14
            <th id="date" data-colname="date">Date</th>
15
            <th id="expiration" data-colname="expiration">Expiration</th>
15
            [% IF Koha.Preference('ReserveExpiration') %]
16
                <th id="expiration" data-colname="expiration">Expiration</th>
17
            [% END %]
16
            <th id="pickup_library" data-colname="pickup_library">Pickup library</th>
18
            <th id="pickup_library" data-colname="pickup_library">Pickup library</th>
17
            <th id="details" data-colname="details">Details</th>
19
            <th id="details" data-colname="details">Details</th>
18
            [% IF ( CAN_user_reserveforothers_modify_holds_priority ) %]
20
            [% IF ( CAN_user_reserveforothers_modify_holds_priority ) %]
Lines 126-134 Link Here
126
                        [% hold.date | $KohaDates %]
128
                        [% hold.date | $KohaDates %]
127
                    [% END %]
129
                    [% END %]
128
                </td>
130
                </td>
129
                <td>
131
                [% IF Koha.Preference('ReserveExpiration') %]
130
                    <input type="text" class="flatpickr" data-flatpickr-futuredate="true" value="[% hold.expirationdate | html %]" size="10" name="expirationdate" />
132
                    <td>
131
                </td>
133
                        <input type="text" class="flatpickr" data-flatpickr-futuredate="true" value="[% hold.expirationdate | html %]" size="10" name="expirationdate" />
134
                    </td>
135
                [% END %]
132
                <td>
136
                <td>
133
                    [%- IF ( hold.found ) -%]
137
                    [%- IF ( hold.found ) -%]
134
                        <input type="hidden" name="pickup" value="[% hold.wbrcode | html %]" />
138
                        <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 773-785 Circulation: Link Here
773
            - Mark a hold as problematic if it has been waiting for more than
773
            - Mark a hold as problematic if it has been waiting for more than
774
            - pref: ReservesMaxPickUpDelay
774
            - pref: ReservesMaxPickUpDelay
775
              class: integer
775
              class: integer
776
            - days.
776
            - '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.'
777
        -
777
        -
778
            - pref: ExpireReservesMaxPickUpDelay
778
            - pref: ExpireReservesMaxPickUpDelay
779
              choices:
779
              choices:
780
                  1: Allow
780
                  1: Allow
781
                  0: "Don't allow"
781
                  0: "Don't allow"
782
            - '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>'
782
            - '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>'
783
            - pref: ExpireReservesAutoFill
783
            - pref: ExpireReservesAutoFill
784
              choices:
784
              choices:
785
                  1: "Do"
785
                  1: "Do"
Lines 794-800 Circulation: Link Here
794
            - 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
794
            - 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
            - pref: ExpireReservesMaxPickUpDelayCharge
795
            - pref: ExpireReservesMaxPickUpDelayCharge
796
              class: currency
796
              class: currency
797
            - "."
797
            - '.<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.'
798
        -
798
        -
799
            - The holds queue should prioritize filling a hold by matching the patron's home library with an item having a matching
799
            - The holds queue should prioritize filling a hold by matching the patron's home library with an item having a matching
800
            - pref: HoldsQueuePrioritizeBranch
800
            - pref: HoldsQueuePrioritizeBranch
Lines 891-897 Circulation: Link Here
891
              choices:
891
              choices:
892
                  1: allow
892
                  1: allow
893
                  0: "don't allow"
893
                  0: "don't allow"
894
            - expired holds to be canceled on days the library is closed per the calendar.
894
            - '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.'
895
        -
895
        -
896
            - pref: ExcludeHolidaysFromMaxPickUpDelay
896
            - pref: ExcludeHolidaysFromMaxPickUpDelay
897
              choices:
897
              choices:
Lines 1030-1035 Circulation: Link Here
1030
                  1: block
1030
                  1: block
1031
                  0: allow
1031
                  0: allow
1032
            - renewing of items from the staff interface and via the <code>misc/cronjobs/automatic_renewals.pl</code> cronjob.
1032
            - renewing of items from the staff interface and via the <code>misc/cronjobs/automatic_renewals.pl</code> cronjob.
1033
        -
1034
            - pref: ReserveExpiration
1035
              choices:
1036
                  1: Enable
1037
                  0: "Disable"
1038
            - 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.
1033
    Fines Policy:
1039
    Fines Policy:
1034
        -
1040
        -
1035
            - pref: finesCalendar
1041
            - pref: finesCalendar
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (+1 lines)
Lines 967-972 Link Here
967
            relatives_borrowernumbers.push("[% b | html %]");
967
            relatives_borrowernumbers.push("[% b | html %]");
968
        [% END %]
968
        [% END %]
969
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
969
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
970
        var ReserveExpiration = [% ( Koha.Preference('ReserveExpiration') ) ? 1 : 0 | html %];
970
    </script>
971
    </script>
971
    [% Asset.js("js/pages/circulation.js") | $raw %]
972
    [% Asset.js("js/pages/circulation.js") | $raw %]
972
    [% Asset.js("js/checkouts.js") | $raw %]
973
    [% Asset.js("js/checkouts.js") | $raw %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/holdshistory.tt (-5 / +16 lines)
Lines 140-151 Link Here
140
    [% INCLUDE 'str/members-menu.inc' %]
140
    [% INCLUDE 'str/members-menu.inc' %]
141
    [% Asset.js("js/members-menu.js") | $raw %]
141
    [% Asset.js("js/members-menu.js") | $raw %]
142
    <script>
142
    <script>
143
        var ReserveExpiration = [% ( Koha.Preference('ReserveExpiration') ) ? 1 : 0 | html %];
144
        var show_itemtype_column = [% ( show_itemtype_column ) ? 1 : 0 | html %];
145
        var table_settings = [% TablesSettings.GetTableSettings('members', 'holdshistory', 'holdshistory-table', 'json') | $raw %];
143
        $(document).ready(function() {
146
        $(document).ready(function() {
144
            var table_settings = [% TablesSettings.GetTableSettings('members', 'holdshistory', 'holdshistory-table', 'json') | $raw %];
147
            table_settings['columns'].forEach(function(thisCol) {
145
            [% UNLESS show_itemtype_column %]
148
                if( show_itemtype_column == 0 && thisCol.columnname == "itemtype" ){
146
              //Remove item type column settings
149
                    thisCol.cannot_be_modified = 1;
147
              table_settings['columns'] = table_settings['columns'].filter(function(c){return c['columnname'] != 'itemtype';});
150
                    thisCol.cannot_be_toggled = 1;
148
            [% END %]
151
                    thisCol.is_hidden = 1;
152
                }
153
                if( ReserveExpiration == 0 && thisCol.columnname == "expirationdate" ){
154
                    thisCol.cannot_be_modified = 1;
155
                    thisCol.cannot_be_toggled = 1;
156
                    thisCol.is_hidden = 1;
157
                }
158
            });
159
149
            var table = KohaTable("table_holdshistory", {
160
            var table = KohaTable("table_holdshistory", {
150
                "sPaginationType": "full",
161
                "sPaginationType": "full",
151
                "aaSorting": [[4, 'desc']]
162
                "aaSorting": [[4, 'desc']]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-print.tt (-2 / +6 lines)
Lines 119-125 Link Here
119
                    <th>Title</th>
119
                    <th>Title</th>
120
                    <th>Author</th>
120
                    <th>Author</th>
121
                    <th>Placed on</th>
121
                    <th>Placed on</th>
122
                    <th>Expires on</th>
122
                    [% IF Koha.Preference('ReserveExpiration') %]
123
                        <th>Expires on</th>
124
                    [% END %]
123
                    <th>Pick up location</th>
125
                    <th>Pick up location</th>
124
                </tr>
126
                </tr>
125
            </thead>
127
            </thead>
Lines 129-135 Link Here
129
                        <td>[% reserve.title | html %]</td>
131
                        <td>[% reserve.title | html %]</td>
130
                        <td>[% reserve.author | html %]</td>
132
                        <td>[% reserve.author | html %]</td>
131
                        <td>[% reserve.reservedate | $KohaDates %]</td>
133
                        <td>[% reserve.reservedate | $KohaDates %]</td>
132
                        <td>[% reserve.expirationdate | $KohaDates %]</td>
134
                        [% IF Koha.Preference('ReserveExpiration') %]
135
                            <td>[% reserve.expirationdate | $KohaDates %]</td>
136
                        [% END %]
133
                        <td>[% reserve.waiting_at | html %]</td>
137
                        <td>[% reserve.waiting_at | html %]</td>
134
                    </tr>
138
                    </tr>
135
                [% END %]
139
                [% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt (+1 lines)
Lines 709-714 Link Here
709
            relatives_borrowernumbers.push("[% b | html %]");
709
            relatives_borrowernumbers.push("[% b | html %]");
710
        [% END %]
710
        [% END %]
711
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
711
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
712
        var ReserveExpiration = [% ( Koha.Preference('ReserveExpiration') ) ? 1 : 0 | html %];
712
    </script>
713
    </script>
713
    [% Asset.js("js/pages/circulation.js") | $raw %]
714
    [% Asset.js("js/pages/circulation.js") | $raw %]
714
    [% Asset.js("js/checkouts.js") | $raw %]
715
    [% Asset.js("js/checkouts.js") | $raw %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (-4 / +6 lines)
Lines 582-591 Link Here
582
                                </li>
582
                                </li>
583
                            [% END %]
583
                            [% END %]
584
584
585
                            <li>
585
                            [% IF Koha.Preference('ReserveExpiration') %]
586
                                <label for="to">Hold expires on date:</label>
586
                                <li>
587
                                <input id="expiration_date" name="expiration_date" id="to" size="10" type="text" class="flatpickr" data-flatpickr-futuredate="true" />
587
                                    <label for="to">Hold expires on date:</label>
588
                            </li>
588
                                    <input id="expiration_date" name="expiration_date" id="to" size="10" type="text" class="flatpickr" data-flatpickr-futuredate="true" />
589
                                </li>
590
                            [% END %]
589
591
590
                            [% UNLESS ( multi_hold ) %]
592
                            [% UNLESS ( multi_hold ) %]
591
                                <li>
593
                                <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 (-11 / +15 lines)
Lines 14-20 Link Here
14
            [% ELSE %]
14
            [% ELSE %]
15
                <th class="psort">Placed on</th>
15
                <th class="psort">Placed on</th>
16
            [% END %]
16
            [% END %]
17
            <th>Expires on</th>
17
            [% IF Koha.Preference('ReserveExpiration') %]
18
                <th>Expires on</th>
19
            [% END %]
18
            [% UNLESS( singleBranchMode) %]
20
            [% UNLESS( singleBranchMode) %]
19
                <th>Pickup location</th>
21
                <th>Pickup location</th>
20
            [% END %]
22
            [% END %]
Lines 68-83 Link Here
68
                <td class="reservedate" data-order="[% HOLD.reservedate | html %]">
70
                <td class="reservedate" data-order="[% HOLD.reservedate | html %]">
69
                    [% HOLD.reservedate | $KohaDates %]
71
                    [% HOLD.reservedate | $KohaDates %]
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
                            [% HOLD.expirationdate | $KohaDates %]
76
                            [% IF ( HOLD.expirationdate ) %]
75
                        [% ELSE %]
77
                                [% HOLD.expirationdate | $KohaDates %]
76
                            Never expires
78
                            [% ELSE %]
77
                        [% END %]
79
                                Never expires
78
                [% ELSE %]
80
                            [% END %]
79
                    <td class="expirationdate" data-order="0000-00-00">
81
                    [% ELSE %]
80
                        -
82
                        <td class="expirationdate" data-order="0000-00-00">
83
                            -
84
                    [% END %]
81
                [% END %]
85
                [% END %]
82
                </td>
86
                </td>
83
                [% UNLESS( singleBranchMode) %]
87
                [% UNLESS( singleBranchMode) %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-holdshistory.tt (-6 / +10 lines)
Lines 101-107 Link Here
101
                                        <th>Barcode</th>
101
                                        <th>Barcode</th>
102
                                        <th>Library</th>
102
                                        <th>Library</th>
103
                                        <th>Hold date</th>
103
                                        <th>Hold date</th>
104
                                        <th>Expiration date</th>
104
                                        [% IF Koha.Preference('ReserveExpiration') %]
105
                                            <th>Expiration date</th>
106
                                        [% END %]
105
                                        <th>Waiting date</th>
107
                                        <th>Waiting date</th>
106
                                        <th>Cancellation date</th>
108
                                        <th>Cancellation date</th>
107
                                        [% IF show_itemtype_column %]
109
                                        [% IF show_itemtype_column %]
Lines 118-128 Link Here
118
                                        <td>[% hold.item.barcode | html %]</td>
120
                                        <td>[% hold.item.barcode | html %]</td>
119
                                        <td>[% Branches.GetName( hold.branchcode ) | html %]</td>
121
                                        <td>[% Branches.GetName( hold.branchcode ) | html %]</td>
120
                                        <td data-order="[% hold.reservedate | html %]">[% hold.reservedate | $KohaDates %]</td>
122
                                        <td data-order="[% hold.reservedate | html %]">[% hold.reservedate | $KohaDates %]</td>
121
                                        <td data-order="[% hold.expirationdate | html %]">
123
                                        [% IF Koha.Preference('ReserveExpiration') %]
122
                                            [% IF hold.expirationdate %]
124
                                            <td data-order="[% hold.expirationdate | html %]">
123
                                                [% hold.expirationdate | $KohaDates %]
125
                                                [% IF hold.expirationdate %]
124
                                            [% END %]
126
                                                    [% hold.expirationdate | $KohaDates %]
125
                                        </td>
127
                                                [% END %]
128
                                            </td>
129
                                        [% END %]
126
                                        <td data-order="[% hold.waitingdate | html %]">
130
                                        <td data-order="[% hold.waitingdate | html %]">
127
                                            [% IF hold.waitingdate %]
131
                                            [% IF hold.waitingdate %]
128
                                                [% hold.waitingdate | $KohaDates %]
132
                                                [% hold.waitingdate | $KohaDates %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt (+2 lines)
Lines 293-304 Link Here
293
                                                    </li>
293
                                                    </li>
294
                                                [% END %]
294
                                                [% END %]
295
295
296
                                                [% IF Koha.Preference('ReserveExpiration') %]
296
                                                <li>
297
                                                <li>
297
                                                    <label for="to[% bibitemloo.biblionumber | html %]">Hold not needed after:</label>
298
                                                    <label for="to[% bibitemloo.biblionumber | html %]">Hold not needed after:</label>
298
                                                    <input type="text" name="expiration_date_[% bibitemloo.biblionumber | html %]" id="to[% bibitemloo.biblionumber | html %]" size="10" class="flatpickr futuredate" />
299
                                                    <input type="text" name="expiration_date_[% bibitemloo.biblionumber | html %]" id="to[% bibitemloo.biblionumber | html %]" size="10" class="flatpickr futuredate" />
299
                                                    <span class="date-format to" data-biblionumber="[% bibitemloo.biblionumber | html %]">[% INCLUDE 'date-format.inc' %]</span>
300
                                                    <span class="date-format to" data-biblionumber="[% bibitemloo.biblionumber | html %]">[% INCLUDE 'date-format.inc' %]</span>
300
                                                    <div class="required_label" style="display:none;">Required</div>
301
                                                    <div class="required_label" style="display:none;">Required</div>
301
                                                </li>
302
                                                </li>
303
                                                [% END %]
302
304
303
                                                [% IF Koha.Preference('AllowHoldItemTypeSelection') %]
305
                                                [% IF Koha.Preference('AllowHoldItemTypeSelection') %]
304
                                                    <li>
306
                                                    <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 1405-1410 subtest 'ModReserveAffect logging' => sub { Link Here
1405
    like( $log->info, qr{$expected}, 'Timestamp logged is the current one' );
1405
    like( $log->info, qr{$expected}, 'Timestamp logged is the current one' );
1406
};
1406
};
1407
1407
1408
subtest 'ReserveExpiration syspref tests' => sub {
1409
1410
    plan tests => 2;
1411
1412
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 1 );
1413
1414
    my $expirationdate = dt_from_string->add( days => 1 );
1415
    my $hold = $builder->build_object(
1416
        {   class => 'Koha::Holds',
1417
            value => { expirationdate => $expirationdate }
1418
        }
1419
    );
1420
1421
    # Disable expiration date for reserves
1422
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 0 );
1423
1424
    my $reverted = C4::Reserves::RevertWaitingStatus({ itemnumber => $hold->itemnumber });
1425
1426
    is( $reverted->expirationdate, undef, "Expiration date should be removed with reserve expiration disabled" );
1427
1428
    # Re-enable expiration date for reserves
1429
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 1 );
1430
1431
    $hold = $builder->build_object(
1432
        {   class => 'Koha::Holds',
1433
            value => { expirationdate => $expirationdate }
1434
        }
1435
    );
1436
1437
    $reverted = C4::Reserves::RevertWaitingStatus({ itemnumber => $hold->itemnumber });
1438
1439
    is( $reverted->expirationdate, undef, "Expiration date is still removed because we can't reset to the original expiration date" );
1440
};
1441
1408
sub count_hold_print_messages {
1442
sub count_hold_print_messages {
1409
    my $message_count = $dbh->selectall_arrayref(q{
1443
    my $message_count = $dbh->selectall_arrayref(q{
1410
        SELECT COUNT(*)
1444
        SELECT COUNT(*)
1411
- 

Return to bug 24194