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

(-)a/C4/ILSDI/Services.pm (-2 / +8 lines)
Lines 792-798 sub HoldTitle { Link Here
792
    return { code => 'cannotBeTransferred' } unless $biblio->can_be_transferred({ to => $destination });
792
    return { code => 'cannotBeTransferred' } unless $biblio->can_be_transferred({ to => $destination });
793
793
794
    my $resdate = $cgi->param('start_date');
794
    my $resdate = $cgi->param('start_date');
795
    my $expdate = $cgi->param('expiry_date');
795
    my $expdate;
796
    if ( C4::Context->preference('ReserveExpiration') and $cgi->param('expiry_date') ) {
797
        $expdate = $cgi->param('expiry_date');
798
    }
796
799
797
    # Add the reserve
800
    # Add the reserve
798
    #    $branch,    $borrowernumber, $biblionumber,
801
    #    $branch,    $borrowernumber, $biblionumber,
Lines 888-894 sub HoldItem { Link Here
888
    return { code => $canitembereserved } unless $canitembereserved eq 'OK';
891
    return { code => $canitembereserved } unless $canitembereserved eq 'OK';
889
892
890
    my $resdate = $cgi->param('start_date');
893
    my $resdate = $cgi->param('start_date');
891
    my $expdate = $cgi->param('expiry_date');
894
    my $expdate;
895
    if ( C4::Context->preference('ReserveExpiration') and $cgi->param('expiry_date') ) {
896
        $expdate = $cgi->param('expiry_date');
897
    }
892
898
893
    # Add the reserve
899
    # Add the reserve
894
    my $priority = C4::Reserves::CalculatePriority($biblionumber);
900
    my $priority = C4::Reserves::CalculatePriority($biblionumber);
(-)a/C4/Reserves.pm (-5 / +5 lines)
Lines 190-196 sub AddReserve { Link Here
190
    my $biblionumber   = $params->{biblionumber};
190
    my $biblionumber   = $params->{biblionumber};
191
    my $priority       = $params->{priority};
191
    my $priority       = $params->{priority};
192
    my $resdate        = $params->{reservation_date};
192
    my $resdate        = $params->{reservation_date};
193
    my $patron_expiration_date = $params->{expiration_date};
193
    my $patron_expiration_date = C4::Context->preference('ReserveExpiration') ? $params->{expiration_date} : undef;
194
    my $notes          = $params->{notes};
194
    my $notes          = $params->{notes};
195
    my $title          = $params->{title};
195
    my $title          = $params->{title};
196
    my $checkitem      = $params->{itemnumber};
196
    my $checkitem      = $params->{itemnumber};
Lines 2126-2135 sub RevertWaitingStatus { Link Here
2126
    ## Fix up the currently waiting reserve
2126
    ## Fix up the currently waiting reserve
2127
    $hold->set(
2127
    $hold->set(
2128
        {
2128
        {
2129
            priority       => 1,
2129
            priority    => 1,
2130
            found          => undef,
2130
            found       => undef,
2131
            waitingdate    => undef,
2131
            waitingdate => undef,
2132
            expirationdate => $hold->patron_expiration_date,
2132
            expirationdate => undef,
2133
            itemnumber     => $hold->item_level_hold ? $hold->itemnumber : undef,
2133
            itemnumber     => $hold->item_level_hold ? $hold->itemnumber : undef,
2134
        }
2134
        }
2135
    )->store( { hold_reverted => 1 } );
2135
    )->store( { hold_reverted => 1 } );
(-)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 232-237 sub set_waiting { Link Here
232
        desk_id => $desk_id,
232
        desk_id => $desk_id,
233
    };
233
    };
234
234
235
    my $new_expiration_date;
236
237
    if ( C4::Context->preference('ReserveExpiration') ) {
238
235
    my $max_pickup_delay = C4::Context->preference("ReservesMaxPickUpDelay");
239
    my $max_pickup_delay = C4::Context->preference("ReservesMaxPickUpDelay");
236
    my $cancel_on_holidays = C4::Context->preference('ExpireReservesOnHolidays');
240
    my $cancel_on_holidays = C4::Context->preference('ExpireReservesOnHolidays');
237
241
Lines 265-285 sub set_waiting { Link Here
265
        $new_expiration_date = $calendar->days_forward( dt_from_string($self->waitingdate), $max_pickup_delay );
269
        $new_expiration_date = $calendar->days_forward( dt_from_string($self->waitingdate), $max_pickup_delay );
266
    }
270
    }
267
271
268
    # If patron's requested expiration date is prior to the
272
    if ( C4::Context->preference('ExpireReservesMaxPickUpDelay') ) {
269
    # calculated one, we keep the patron's one.
273
        # If patron's requested expiration date is prior to the
270
    if ( $self->patron_expiration_date ) {
274
        # calculated one, we keep the patron's one.
271
        my $requested_expiration = dt_from_string( $self->patron_expiration_date );
275
        if ( $self->patron_expiration_date ) {
276
            my $requested_expiration = dt_from_string( $self->patron_expiration_date );
272
277
273
        my $cmp =
278
            my $cmp =
274
          $requested_expiration
279
              $requested_expiration
275
          ? DateTime->compare( $requested_expiration, $new_expiration_date )
280
              ? DateTime->compare( $requested_expiration, $new_expiration_date )
276
          : 0;
281
              : 0;
277
282
278
        $new_expiration_date =
283
            $new_expiration_date =
279
          $cmp == -1 ? $requested_expiration : $new_expiration_date;
284
              $cmp == -1 ? $requested_expiration : $new_expiration_date;
285
          }
286
    } else {
287
        # if holds don't need a waiting expiration date to be expired automatically, don't set one
288
        $new_expiration_date = undef;
280
    }
289
    }
281
290
282
    $values->{expirationdate} = $new_expiration_date->ymd;
291
    } # ReserveExpiration
292
293
    $values->{expirationdate} = $new_expiration_date ? $new_expiration_date->ymd : undef;
283
294
284
    $self->set($values)->store();
295
    $self->set($values)->store();
285
296
(-)a/Koha/REST/V1/Clubs/Holds.pm (-1 / +1 lines)
Lines 53-59 sub add { Link Here
53
        my $pickup_library_id = $body->{pickup_library_id};
53
        my $pickup_library_id = $body->{pickup_library_id};
54
        my $item_id           = $body->{item_id};
54
        my $item_id           = $body->{item_id};
55
        my $item_type         = $body->{item_type};
55
        my $item_type         = $body->{item_type};
56
        my $expiration_date   = $body->{expiration_date};
56
        my $expiration_date   = C4::Context->preference('ReserveExpiration') ? $body->{expiration_date} : undef;
57
        my $notes             = $body->{notes};
57
        my $notes             = $body->{notes};
58
        my $default_patron_home = $body->{default_patron_home};
58
        my $default_patron_home = $body->{default_patron_home};
59
59
(-)a/Koha/REST/V1/Holds.pm (-1 / +1 lines)
Lines 82-88 sub add { Link Here
82
        my $item_id           = $body->{item_id};
82
        my $item_id           = $body->{item_id};
83
        my $patron_id         = $body->{patron_id};
83
        my $patron_id         = $body->{patron_id};
84
        my $item_type         = $body->{item_type};
84
        my $item_type         = $body->{item_type};
85
        my $expiration_date   = $body->{expiration_date};
85
        my $expiration_date   = C4::Context->preference('ReserveExpiration') ? $body->{expiration_date} : undef;
86
        my $notes             = $body->{notes};
86
        my $notes             = $body->{notes};
87
        my $hold_date         = $body->{hold_date};
87
        my $hold_date         = $body->{hold_date};
88
        my $non_priority      = $body->{non_priority};
88
        my $non_priority      = $body->{non_priority};
(-)a/circ/waitingreserves.pl (-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 ( $op eq 'cud-cancelall' ) {
106
        if ( $op eq 'cud-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 656-661 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
656
('RequireChoosingExistingAuthority','0',NULL,'Require existing authority selection in controlled fields during cataloging.','YesNo'),
656
('RequireChoosingExistingAuthority','0',NULL,'Require existing authority selection in controlled fields during cataloging.','YesNo'),
657
('RequirePaymentType','0','','Require staff to select a payment type when a payment is made','YesNo'),
657
('RequirePaymentType','0','','Require staff to select a payment type when a payment is made','YesNo'),
658
('RequireStrongPassword','1','','Require a strong login password for staff and patrons','YesNo'),
658
('RequireStrongPassword','1','','Require a strong login password for staff and patrons','YesNo'),
659
('ReserveExpiration', 1, NULL, 'Enable the use of expiration date in holds module.', 'YesNo'),
659
('ReservesControlBranch','PatronLibrary','ItemHomeLibrary|PatronLibrary','Branch checked for members reservations rights','Choice'),
660
('ReservesControlBranch','PatronLibrary','ItemHomeLibrary|PatronLibrary','Branch checked for members reservations rights','Choice'),
660
('ReservesMaxPickUpDelay','7','','Define the Maximum delay to pick up an item on hold','Integer'),
661
('ReservesMaxPickUpDelay','7','','Define the Maximum delay to pick up an item on hold','Integer'),
661
('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'),
662
('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 16-22 Link Here
16
            <th id="patron" data-colname="patron">Patron</th>
16
            <th id="patron" data-colname="patron">Patron</th>
17
            <th id="notes" data-colname="notes">Notes</th>
17
            <th id="notes" data-colname="notes">Notes</th>
18
            <th id="date" data-colname="date">Date</th>
18
            <th id="date" data-colname="date">Date</th>
19
            <th id="expiration" data-colname="expiration">Expiration</th>
19
            [% IF Koha.Preference('ReserveExpiration') %]
20
                <th id="expiration" data-colname="expiration">Expiration</th>
21
            [% END %]
20
            <th id="pickup_library" data-colname="pickup_library">Pickup library</th>
22
            <th id="pickup_library" data-colname="pickup_library">Pickup library</th>
21
            <th id="details" data-colname="details">Details</th>
23
            <th id="details" data-colname="details">Details</th>
22
            [% IF ( CAN_user_reserveforothers_modify_holds_priority ) %]
24
            [% IF ( CAN_user_reserveforothers_modify_holds_priority ) %]
Lines 130-138 Link Here
130
                        [% hold.date | $KohaDates %]
132
                        [% hold.date | $KohaDates %]
131
                    [% END %]
133
                    [% END %]
132
                </td>
134
                </td>
133
                <td>
135
                [% IF Koha.Preference('ReserveExpiration') %]
134
                    <input type="text" class="flatpickr" data-flatpickr-futuredate="true" value="[% hold.expirationdate | html %]" size="10" name="expirationdate" />
136
                    <td>
135
                </td>
137
                        <input type="text" class="flatpickr" data-flatpickr-futuredate="true" value="[% hold.expirationdate | html %]" size="10" name="expirationdate" />
138
                    </td>
139
                [% END %]
136
                <td>
140
                <td>
137
                    [%- IF ( hold.found ) -%]
141
                    [%- IF ( hold.found ) -%]
138
                        <input type="hidden" name="pickup" value="[% hold.wbrcode | html %]" />
142
                        <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 / +11 lines)
Lines 828-840 Circulation: Link Here
828
            - Mark a hold as problematic if it has been waiting for more than
828
            - Mark a hold as problematic if it has been waiting for more than
829
            - pref: ReservesMaxPickUpDelay
829
            - pref: ReservesMaxPickUpDelay
830
              class: integer
830
              class: integer
831
            - days.
831
            - '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.'
832
        -
832
        -
833
            - pref: ExpireReservesMaxPickUpDelay
833
            - pref: ExpireReservesMaxPickUpDelay
834
              choices:
834
              choices:
835
                  1: Allow
835
                  1: Allow
836
                  0: "Don't allow"
836
                  0: "Don't allow"
837
            - '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>'
837
            - '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>'
838
            - pref: ExpireReservesAutoFill
838
            - pref: ExpireReservesAutoFill
839
              choices:
839
              choices:
840
                  1: "Do"
840
                  1: "Do"
Lines 849-855 Circulation: Link Here
849
            - 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
849
            - 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
850
            - pref: ExpireReservesMaxPickUpDelayCharge
850
            - pref: ExpireReservesMaxPickUpDelayCharge
851
              class: currency
851
              class: currency
852
            - "."
852
            - '.<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.'
853
        -
853
        -
854
            - The holds queue should prioritize filling a hold by matching the patron's home library with an item having a matching
854
            - The holds queue should prioritize filling a hold by matching the patron's home library with an item having a matching
855
            - pref: HoldsQueuePrioritizeBranch
855
            - pref: HoldsQueuePrioritizeBranch
Lines 953-959 Circulation: Link Here
953
              choices:
953
              choices:
954
                  1: allow
954
                  1: allow
955
                  0: "don't allow"
955
                  0: "don't allow"
956
            - expired holds to be canceled on days the library is closed per the calendar.
956
            - '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.'
957
        -
957
        -
958
            - pref: ExcludeHolidaysFromMaxPickUpDelay
958
            - pref: ExcludeHolidaysFromMaxPickUpDelay
959
              choices:
959
              choices:
Lines 1104-1109 Circulation: Link Here
1104
                  1: Email
1104
                  1: Email
1105
                  0:  "Don't email"
1105
                  0:  "Don't email"
1106
            - a patron when they have placed a hold.
1106
            - a patron when they have placed a hold.
1107
        -
1108
            - pref: ReserveExpiration
1109
              choices:
1110
                  1: Enable
1111
                  0: "Disable"
1112
            - 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.
1113
1107
    Fines Policy:
1114
    Fines Policy:
1108
        -
1115
        -
1109
            - pref: finesCalendar
1116
            - pref: finesCalendar
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (+1 lines)
Lines 1018-1023 Link Here
1018
            relatives_borrowernumbers.push("[% b | html %]");
1018
            relatives_borrowernumbers.push("[% b | html %]");
1019
        [% END %]
1019
        [% END %]
1020
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
1020
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
1021
        var ReserveExpiration = [% ( Koha.Preference('ReserveExpiration') ) ? 1 : 0 | html %];
1021
    </script>
1022
    </script>
1022
    [% Asset.js("js/pages/circulation.js") | $raw %]
1023
    [% Asset.js("js/pages/circulation.js") | $raw %]
1023
    [% Asset.js("js/checkouts.js") | $raw %]
1024
    [% Asset.js("js/checkouts.js") | $raw %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/holdshistory.tt (-5 / +16 lines)
Lines 143-154 Link Here
143
    [% INCLUDE 'str/members-menu.inc' %]
143
    [% INCLUDE 'str/members-menu.inc' %]
144
    [% Asset.js("js/members-menu.js") | $raw %]
144
    [% Asset.js("js/members-menu.js") | $raw %]
145
    <script>
145
    <script>
146
        var ReserveExpiration = [% ( Koha.Preference('ReserveExpiration') ) ? 1 : 0 | html %];
147
        var show_itemtype_column = [% ( show_itemtype_column ) ? 1 : 0 | html %];
148
        var table_settings = [% TablesSettings.GetTableSettings('members', 'holdshistory', 'holdshistory-table', 'json') | $raw %];
146
        $(document).ready(function() {
149
        $(document).ready(function() {
147
            var table_settings = [% TablesSettings.GetTableSettings('members', 'holdshistory', 'holdshistory-table', 'json') | $raw %];
150
            table_settings['columns'].forEach(function(thisCol) {
148
            [% UNLESS show_itemtype_column %]
151
                if( show_itemtype_column == 0 && thisCol.columnname == "itemtype" ){
149
              //Remove item type column settings
152
                    thisCol.cannot_be_modified = 1;
150
              table_settings['columns'] = table_settings['columns'].filter(function(c){return c['columnname'] != 'itemtype';});
153
                    thisCol.cannot_be_toggled = 1;
151
            [% END %]
154
                    thisCol.is_hidden = 1;
155
                }
156
                if( ReserveExpiration == 0 && thisCol.columnname == "expirationdate" ){
157
                    thisCol.cannot_be_modified = 1;
158
                    thisCol.cannot_be_toggled = 1;
159
                    thisCol.is_hidden = 1;
160
                }
161
            });
162
152
            var table = KohaTable("table_holdshistory", {
163
            var table = KohaTable("table_holdshistory", {
153
                "pagingType": "full",
164
                "pagingType": "full",
154
                "order": [[4, 'desc']]
165
                "order": [[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 759-764 Link Here
759
            relatives_borrowernumbers.push("[% b | html %]");
759
            relatives_borrowernumbers.push("[% b | html %]");
760
        [% END %]
760
        [% END %]
761
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
761
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
762
        var ReserveExpiration = [% ( Koha.Preference('ReserveExpiration') ) ? 1 : 0 | html %];
762
    </script>
763
    </script>
763
    [% Asset.js("js/pages/circulation.js") | $raw %]
764
    [% Asset.js("js/pages/circulation.js") | $raw %]
764
    [% Asset.js("js/checkouts.js") | $raw %]
765
    [% Asset.js("js/checkouts.js") | $raw %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (-4 / +6 lines)
Lines 599-608 Link Here
599
                                </li>
599
                                </li>
600
                            [% END %]
600
                            [% END %]
601
601
602
                            <li>
602
                            [% IF Koha.Preference('ReserveExpiration') %]
603
                                <label for="to">Hold expires on date:</label>
603
                                <li>
604
                                <input id="expiration_date" name="expiration_date" id="to" size="10" type="text" class="flatpickr" data-flatpickr-futuredate="true" />
604
                                    <label for="to">Hold expires on date:</label>
605
                            </li>
605
                                    <input id="expiration_date" name="expiration_date" id="to" size="10" type="text" class="flatpickr" data-flatpickr-futuredate="true" />
606
                                </li>
607
                            [% END %]
606
608
607
                                <li id="non_priority_list_item">
609
                                <li id="non_priority_list_item">
608
                                    <label for="non_priority">Non priority hold:</label>
610
                                    <label for="non_priority">Non priority hold:</label>
(-)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
                        "data": function( oObj ) {
231
                        "data": 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 102-108 Link Here
102
                                        <th>Barcode</th>
102
                                        <th>Barcode</th>
103
                                        <th>Library</th>
103
                                        <th>Library</th>
104
                                        <th>Hold date</th>
104
                                        <th>Hold date</th>
105
                                        <th>Expiration date</th>
105
                                        [% IF Koha.Preference('ReserveExpiration') %]
106
                                            <th>Expiration date</th>
107
                                        [% END %]
106
                                        <th>Waiting date</th>
108
                                        <th>Waiting date</th>
107
                                        <th>Cancellation date</th>
109
                                        <th>Cancellation date</th>
108
                                        [% IF show_itemtype_column %]
110
                                        [% IF show_itemtype_column %]
Lines 119-129 Link Here
119
                                        <td>[% hold.item.barcode | html %]</td>
121
                                        <td>[% hold.item.barcode | html %]</td>
120
                                        <td>[% Branches.GetName( hold.branchcode ) | html %]</td>
122
                                        <td>[% Branches.GetName( hold.branchcode ) | html %]</td>
121
                                        <td data-order="[% hold.reservedate | html %]">[% hold.reservedate | $KohaDates %]</td>
123
                                        <td data-order="[% hold.reservedate | html %]">[% hold.reservedate | $KohaDates %]</td>
122
                                        <td data-order="[% hold.expirationdate | html %]">
124
                                        [% IF Koha.Preference('ReserveExpiration') %]
123
                                            [% IF hold.expirationdate %]
125
                                            <td data-order="[% hold.expirationdate | html %]">
124
                                                [% hold.expirationdate | $KohaDates %]
126
                                                [% IF hold.expirationdate %]
125
                                            [% END %]
127
                                                    [% hold.expirationdate | $KohaDates %]
126
                                        </td>
128
                                                [% END %]
129
                                            </td>
130
                                        [% END %]
127
                                        <td data-order="[% hold.waitingdate | html %]">
131
                                        <td data-order="[% hold.waitingdate | html %]">
128
                                            [% IF hold.waitingdate %]
132
                                            [% IF hold.waitingdate %]
129
                                                [% hold.waitingdate | $KohaDates %]
133
                                                [% hold.waitingdate | $KohaDates %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt (+2 lines)
Lines 310-321 Link Here
310
                                                    </li>
310
                                                    </li>
311
                                                [% END %]
311
                                                [% END %]
312
312
313
                                                [% IF Koha.Preference('ReserveExpiration') %]
313
                                                <li>
314
                                                <li>
314
                                                    <label for="to[% bibitemloo.biblionumber | html %]">Hold not needed after:</label>
315
                                                    <label for="to[% bibitemloo.biblionumber | html %]">Hold not needed after:</label>
315
                                                    <input type="text" name="expiration_date_[% bibitemloo.biblionumber | html %]" id="to[% bibitemloo.biblionumber | html %]" size="10" data-flatpickr-future="true" class="flatpickr futuredate" />
316
                                                    <input type="text" name="expiration_date_[% bibitemloo.biblionumber | html %]" id="to[% bibitemloo.biblionumber | html %]" size="10" data-flatpickr-future="true" class="flatpickr futuredate" />
316
                                                    <span class="date-format to" data-biblionumber="[% bibitemloo.biblionumber | html %]">[% INCLUDE 'date-format.inc' %]</span>
317
                                                    <span class="date-format to" data-biblionumber="[% bibitemloo.biblionumber | html %]">[% INCLUDE 'date-format.inc' %]</span>
317
                                                    <div class="required_label" style="display:none;">Required</div>
318
                                                    <div class="required_label" style="display:none;">Required</div>
318
                                                </li>
319
                                                </li>
320
                                                [% END %]
319
321
320
                                                [% IF Koha.Preference('AllowHoldItemTypeSelection') %]
322
                                                [% IF Koha.Preference('AllowHoldItemTypeSelection') %]
321
                                                    <li>
323
                                                    <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 431-433 subtest 'suspend() tests' => sub { Link Here
431
431
432
    $schema->storage->txn_rollback;
432
    $schema->storage->txn_rollback;
433
};
433
};
434
435
subtest 'ReserveExpiration syspref tests' => sub {
436
437
    plan tests => 2;
438
439
    $schema->storage->txn_begin;
440
    t::lib::Mocks::mock_preference( 'ExpireReservesMaxPickUpDelay', 1 );
441
442
    # Disable expiration date for reserves
443
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 0 );
444
445
    my $expirationdate = dt_from_string->add( days => 1 );
446
    my $hold = $builder->build_object(
447
        {   class => 'Koha::Holds',
448
            value => { patron_expiration_date => $expirationdate }
449
        }
450
    );
451
    $hold->set_waiting;
452
453
    is( $hold->expirationdate, undef, "No expiration date should be set with reserve expiration disabled" );
454
455
    # Re-enable expiration date for reserves
456
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 1 );
457
458
    $hold = $builder->build_object(
459
        {   class => 'Koha::Holds',
460
            value => { patron_expiration_date => $expirationdate }
461
        }
462
    );
463
    $hold->set_waiting();
464
465
    is( $hold->expirationdate, $expirationdate->ymd, "Expiration date is set as expected" );
466
467
    $schema->storage->txn_rollback;
468
};
(-)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 1419-1424 subtest 'ModReserveAffect logging' => sub { Link Here
1419
    like( $log->info, qr{$expected}, 'Timestamp logged is the current one' );
1419
    like( $log->info, qr{$expected}, 'Timestamp logged is the current one' );
1420
};
1420
};
1421
1421
1422
subtest 'ReserveExpiration syspref tests' => sub {
1423
1424
    plan tests => 2;
1425
1426
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 1 );
1427
1428
    my $expirationdate = dt_from_string->add( days => 1 );
1429
    my $hold = $builder->build_object(
1430
        {   class => 'Koha::Holds',
1431
            value => { expirationdate => $expirationdate }
1432
        }
1433
    );
1434
1435
    # Disable expiration date for reserves
1436
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 0 );
1437
1438
    my $reverted = C4::Reserves::RevertWaitingStatus({ itemnumber => $hold->itemnumber });
1439
1440
    is( $reverted->expirationdate, undef, "Expiration date should be removed with reserve expiration disabled" );
1441
1442
    # Re-enable expiration date for reserves
1443
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 1 );
1444
1445
    $hold = $builder->build_object(
1446
        {   class => 'Koha::Holds',
1447
            value => { expirationdate => $expirationdate }
1448
        }
1449
    );
1450
1451
    $reverted = C4::Reserves::RevertWaitingStatus({ itemnumber => $hold->itemnumber });
1452
1453
    is( $reverted->expirationdate, undef, "Expiration date is still removed because we can't reset to the original expiration date" );
1454
};
1455
1422
sub count_hold_print_messages {
1456
sub count_hold_print_messages {
1423
    my $message_count = $dbh->selectall_arrayref(q{
1457
    my $message_count = $dbh->selectall_arrayref(q{
1424
        SELECT COUNT(*)
1458
        SELECT COUNT(*)
1425
- 

Return to bug 24194