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 185-191 sub AddReserve { Link Here
185
    my $biblionumber   = $params->{biblionumber};
185
    my $biblionumber   = $params->{biblionumber};
186
    my $priority       = $params->{priority};
186
    my $priority       = $params->{priority};
187
    my $resdate        = $params->{reservation_date};
187
    my $resdate        = $params->{reservation_date};
188
    my $patron_expiration_date = $params->{expiration_date};
188
    my $patron_expiration_date = C4::Context->preference('ReserveExpiration') ? $params->{expiration_date} : undef;
189
    my $notes          = $params->{notes};
189
    my $notes          = $params->{notes};
190
    my $title          = $params->{title};
190
    my $title          = $params->{title};
191
    my $checkitem      = $params->{itemnumber};
191
    my $checkitem      = $params->{itemnumber};
Lines 2075-2084 sub RevertWaitingStatus { Link Here
2075
    ## Fix up the currently waiting reserve
2075
    ## Fix up the currently waiting reserve
2076
    $hold->set(
2076
    $hold->set(
2077
        {
2077
        {
2078
            priority       => 1,
2078
            priority    => 1,
2079
            found          => undef,
2079
            found       => undef,
2080
            waitingdate    => undef,
2080
            waitingdate => undef,
2081
            expirationdate => $hold->patron_expiration_date,
2081
            expirationdate => undef,
2082
            itemnumber     => $hold->item_level_hold ? $hold->itemnumber : undef,
2082
            itemnumber     => $hold->item_level_hold ? $hold->itemnumber : undef,
2083
        }
2083
        }
2084
    )->store( { hold_reverted => 1 } );
2084
    )->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 231-236 sub set_waiting { Link Here
231
        desk_id => $desk_id,
231
        desk_id => $desk_id,
232
    };
232
    };
233
233
234
    my $new_expiration_date;
235
236
    if ( C4::Context->preference('ReserveExpiration') ) {
237
234
    my $max_pickup_delay = C4::Context->preference("ReservesMaxPickUpDelay");
238
    my $max_pickup_delay = C4::Context->preference("ReservesMaxPickUpDelay");
235
    my $cancel_on_holidays = C4::Context->preference('ExpireReservesOnHolidays');
239
    my $cancel_on_holidays = C4::Context->preference('ExpireReservesOnHolidays');
236
240
Lines 264-284 sub set_waiting { Link Here
264
        $new_expiration_date = $calendar->days_forward( dt_from_string($self->waitingdate), $max_pickup_delay );
268
        $new_expiration_date = $calendar->days_forward( dt_from_string($self->waitingdate), $max_pickup_delay );
265
    }
269
    }
266
270
267
    # If patron's requested expiration date is prior to the
271
    if ( C4::Context->preference('ExpireReservesMaxPickUpDelay') ) {
268
    # calculated one, we keep the patron's one.
272
        # If patron's requested expiration date is prior to the
269
    if ( $self->patron_expiration_date ) {
273
        # calculated one, we keep the patron's one.
270
        my $requested_expiration = dt_from_string( $self->patron_expiration_date );
274
        if ( $self->patron_expiration_date ) {
275
            my $requested_expiration = dt_from_string( $self->patron_expiration_date );
271
276
272
        my $cmp =
277
            my $cmp =
273
          $requested_expiration
278
              $requested_expiration
274
          ? DateTime->compare( $requested_expiration, $new_expiration_date )
279
              ? DateTime->compare( $requested_expiration, $new_expiration_date )
275
          : 0;
280
              : 0;
276
281
277
        $new_expiration_date =
282
            $new_expiration_date =
278
          $cmp == -1 ? $requested_expiration : $new_expiration_date;
283
              $cmp == -1 ? $requested_expiration : $new_expiration_date;
284
          }
285
    } else {
286
        # if holds don't need a waiting expiration date to be expired automatically, don't set one
287
        $new_expiration_date = undef;
279
    }
288
    }
280
289
281
    $values->{expirationdate} = $new_expiration_date->ymd;
290
    } # ReserveExpiration
291
292
    $values->{expirationdate} = $new_expiration_date ? $new_expiration_date->ymd : undef;
282
293
283
    $self->set($values)->store();
294
    $self->set($values)->store();
284
295
(-)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 672-677 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
672
('RequireChoosingExistingAuthority','0',NULL,'Require existing authority selection in controlled fields during cataloging.','YesNo'),
672
('RequireChoosingExistingAuthority','0',NULL,'Require existing authority selection in controlled fields during cataloging.','YesNo'),
673
('RequirePaymentType','0','','Require staff to select a payment type when a payment is made','YesNo'),
673
('RequirePaymentType','0','','Require staff to select a payment type when a payment is made','YesNo'),
674
('RequireStrongPassword','1','','Require a strong login password for staff and patrons','YesNo'),
674
('RequireStrongPassword','1','','Require a strong login password for staff and patrons','YesNo'),
675
('ReserveExpiration', 1, NULL, 'Enable the use of expiration date in holds module.', 'YesNo'),
675
('ReservesControlBranch','PatronLibrary','ItemHomeLibrary|PatronLibrary','Branch checked for members reservations rights','Choice'),
676
('ReservesControlBranch','PatronLibrary','ItemHomeLibrary|PatronLibrary','Branch checked for members reservations rights','Choice'),
676
('ReservesMaxPickUpDelay','7','','Define the Maximum delay to pick up an item on hold','Integer'),
677
('ReservesMaxPickUpDelay','7','','Define the Maximum delay to pick up an item on hold','Integer'),
677
('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'),
678
('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 / +10 lines)
Lines 848-860 Circulation: Link Here
848
            - Mark a hold as problematic if it has been waiting for more than
848
            - Mark a hold as problematic if it has been waiting for more than
849
            - pref: ReservesMaxPickUpDelay
849
            - pref: ReservesMaxPickUpDelay
850
              class: integer
850
              class: integer
851
            - days.
851
            - '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.'
852
        -
852
        -
853
            - pref: ExpireReservesMaxPickUpDelay
853
            - pref: ExpireReservesMaxPickUpDelay
854
              choices:
854
              choices:
855
                  1: Allow
855
                  1: Allow
856
                  0: "Don't allow"
856
                  0: "Don't allow"
857
            - '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>'
857
            - '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>'
858
            - pref: ExpireReservesAutoFill
858
            - pref: ExpireReservesAutoFill
859
              choices:
859
              choices:
860
                  1: "Do"
860
                  1: "Do"
Lines 869-875 Circulation: Link Here
869
            - 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
869
            - 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
870
            - pref: ExpireReservesMaxPickUpDelayCharge
870
            - pref: ExpireReservesMaxPickUpDelayCharge
871
              class: currency
871
              class: currency
872
            - "."
872
            - '.<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.'
873
        -
873
        -
874
            - The holds queue should prioritize filling a hold by matching the patron's home library with an item having a matching
874
            - The holds queue should prioritize filling a hold by matching the patron's home library with an item having a matching
875
            - pref: HoldsQueuePrioritizeBranch
875
            - pref: HoldsQueuePrioritizeBranch
Lines 979-985 Circulation: Link Here
979
              choices:
979
              choices:
980
                  1: allow
980
                  1: allow
981
                  0: "don't allow"
981
                  0: "don't allow"
982
            - expired holds to be canceled on days the library is closed per the calendar.
982
            - '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.'
983
        -
983
        -
984
            - pref: ExcludeHolidaysFromMaxPickUpDelay
984
            - pref: ExcludeHolidaysFromMaxPickUpDelay
985
              choices:
985
              choices:
Lines 1124-1129 Circulation: Link Here
1124
                  1: block
1124
                  1: block
1125
                  0: allow
1125
                  0: allow
1126
            - renewing of items from the staff interface and via the <code>misc/cronjobs/automatic_renewals.pl</code> cronjob.
1126
            - renewing of items from the staff interface and via the <code>misc/cronjobs/automatic_renewals.pl</code> cronjob.
1127
        -
1128
            - pref: ReserveExpiration
1129
              choices:
1130
                  1: Enable
1131
                  0: "Disable"
1132
            - 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.
1127
    Fines policy:
1133
    Fines policy:
1128
        -
1134
        -
1129
            - pref: finesCalendar
1135
            - pref: finesCalendar
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (+1 lines)
Lines 1032-1037 Link Here
1032
            relatives_borrowernumbers.push("[% b | html %]");
1032
            relatives_borrowernumbers.push("[% b | html %]");
1033
        [% END %]
1033
        [% END %]
1034
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
1034
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
1035
        var ReserveExpiration = [% ( Koha.Preference('ReserveExpiration') ) ? 1 : 0 | html %];
1035
    </script>
1036
    </script>
1036
    [% Asset.js("js/pages/circulation.js") | $raw %]
1037
    [% Asset.js("js/pages/circulation.js") | $raw %]
1037
    [% IF Koha.Preference('ClaimReturnedLostValue') || Koha.Preference('BundleLostValue') %]
1038
    [% IF Koha.Preference('ClaimReturnedLostValue') || Koha.Preference('BundleLostValue') %]
(-)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 121-127 Link Here
121
                    <th class="anti-the">Title</th>
121
                    <th class="anti-the">Title</th>
122
                    <th>Author</th>
122
                    <th>Author</th>
123
                    <th>Placed on</th>
123
                    <th>Placed on</th>
124
                    <th>Expires on</th>
124
                    [% IF Koha.Preference('ReserveExpiration') %]
125
                        <th>Expires on</th>
126
                    [% END %]
125
                    <th>Pick up location</th>
127
                    <th>Pick up location</th>
126
                    <th>Hold priority</th>
128
                    <th>Hold priority</th>
127
                </tr>
129
                </tr>
Lines 132-138 Link Here
132
                        <td>[% reserve.title | html %]</td>
134
                        <td>[% reserve.title | html %]</td>
133
                        <td>[% reserve.author | html %]</td>
135
                        <td>[% reserve.author | html %]</td>
134
                        <td data-sort="[% reserve.reservedate | html %]">[% reserve.reservedate | $KohaDates %]</td>
136
                        <td data-sort="[% reserve.reservedate | html %]">[% reserve.reservedate | $KohaDates %]</td>
135
                        <td data-sort="[% reserve.expirationdate | html %]">[% reserve.expirationdate | $KohaDates %]</td>
137
                        [% IF Koha.Preference('ReserveExpiration') %]
138
                            <td data-sort="[% reserve.expirationdate | html %]">[% reserve.expirationdate | $KohaDates %]</td>
139
                        [% END %]
136
                        <td>[% reserve.waiting_at | html %]</td>
140
                        <td>[% reserve.waiting_at | html %]</td>
137
                        <td>[% reserve.priority | html %]</td>
141
                        <td>[% reserve.priority | html %]</td>
138
                    </tr>
142
                    </tr>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt (+1 lines)
Lines 765-770 Link Here
765
            relatives_borrowernumbers.push("[% b | html %]");
765
            relatives_borrowernumbers.push("[% b | html %]");
766
        [% END %]
766
        [% END %]
767
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
767
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
768
        var ReserveExpiration = [% ( Koha.Preference('ReserveExpiration') ) ? 1 : 0 | html %];
768
    </script>
769
    </script>
769
    [% Asset.js("js/pages/circulation.js") | $raw %]
770
    [% Asset.js("js/pages/circulation.js") | $raw %]
770
    [% IF Koha.Preference('ClaimReturnedLostValue') %]
771
    [% IF Koha.Preference('ClaimReturnedLostValue') %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (-4 / +6 lines)
Lines 601-610 Link Here
601
                                </li>
601
                                </li>
602
                            [% END %]
602
                            [% END %]
603
603
604
                            <li>
604
                            [% IF Koha.Preference('ReserveExpiration') %]
605
                                <label for="to">Hold expires on date:</label>
605
                                <li>
606
                                <input id="expiration_date" name="expiration_date" id="to" size="10" type="text" class="flatpickr" data-flatpickr-futuredate="true" />
606
                                    <label for="to">Hold expires on date:</label>
607
                            </li>
607
                                    <input id="expiration_date" name="expiration_date" id="to" size="10" type="text" class="flatpickr" data-flatpickr-futuredate="true" />
608
                                </li>
609
                            [% END %]
608
610
609
                                <li id="non_priority_list_item">
611
                                <li id="non_priority_list_item">
610
                                    <label for="non_priority">Non priority hold:</label>
612
                                    <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 => 69;
20
use Test::More tests => 70;
21
use Test::MockModule;
21
use Test::MockModule;
22
use Test::Warn;
22
use Test::Warn;
23
23
Lines 1363-1368 subtest 'ModReserveAffect logging' => sub { Link Here
1363
    like( $log->info, qr{$expected}, 'Timestamp logged is the current one' );
1363
    like( $log->info, qr{$expected}, 'Timestamp logged is the current one' );
1364
};
1364
};
1365
1365
1366
subtest 'ReserveExpiration syspref tests' => sub {
1367
1368
    plan tests => 2;
1369
1370
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 1 );
1371
1372
    my $expirationdate = dt_from_string->add( days => 1 );
1373
    my $hold = $builder->build_object(
1374
        {   class => 'Koha::Holds',
1375
            value => { expirationdate => $expirationdate }
1376
        }
1377
    );
1378
1379
    # Disable expiration date for reserves
1380
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 0 );
1381
1382
    my $reverted = C4::Reserves::RevertWaitingStatus({ itemnumber => $hold->itemnumber });
1383
1384
    is( $reverted->expirationdate, undef, "Expiration date should be removed with reserve expiration disabled" );
1385
1386
    # Re-enable expiration date for reserves
1387
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 1 );
1388
1389
    $hold = $builder->build_object(
1390
        {   class => 'Koha::Holds',
1391
            value => { expirationdate => $expirationdate }
1392
        }
1393
    );
1394
1395
    $reverted = C4::Reserves::RevertWaitingStatus({ itemnumber => $hold->itemnumber });
1396
1397
    is( $reverted->expirationdate, undef, "Expiration date is still removed because we can't reset to the original expiration date" );
1398
};
1399
1366
sub count_hold_print_messages {
1400
sub count_hold_print_messages {
1367
    my $message_count = $dbh->selectall_arrayref(q{
1401
    my $message_count = $dbh->selectall_arrayref(q{
1368
        SELECT COUNT(*)
1402
        SELECT COUNT(*)
1369
- 

Return to bug 24194