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

(-)a/C4/ILSDI/Services.pm (-2 / +8 lines)
Lines 777-783 sub HoldTitle { Link Here
777
    return { code => 'cannotBeTransferred' } unless $biblio->can_be_transferred({ to => $destination });
777
    return { code => 'cannotBeTransferred' } unless $biblio->can_be_transferred({ to => $destination });
778
778
779
    my $resdate = $cgi->param('start_date');
779
    my $resdate = $cgi->param('start_date');
780
    my $expdate = $cgi->param('expiry_date');
780
    my $expdate;
781
    if ( C4::Context->preference('ReserveExpiration') and $cgi->param('expiry_date') ) {
782
        $expdate = $cgi->param('expiry_date');
783
    }
781
784
782
    # Add the reserve
785
    # Add the reserve
783
    #    $branch,    $borrowernumber, $biblionumber,
786
    #    $branch,    $borrowernumber, $biblionumber,
Lines 872-878 sub HoldItem { Link Here
872
    return { code => $canitembereserved } unless $canitembereserved eq 'OK';
875
    return { code => $canitembereserved } unless $canitembereserved eq 'OK';
873
876
874
    my $resdate = $cgi->param('start_date');
877
    my $resdate = $cgi->param('start_date');
875
    my $expdate = $cgi->param('expiry_date');
878
    my $expdate;
879
    if ( C4::Context->preference('ReserveExpiration') and $cgi->param('expiry_date') ) {
880
        $expdate = $cgi->param('expiry_date');
881
    }
876
882
877
    # Add the reserve
883
    # Add the reserve
878
    my $priority = C4::Reserves::CalculatePriority($biblionumber);
884
    my $priority = C4::Reserves::CalculatePriority($biblionumber);
(-)a/C4/Reserves.pm (-2 / +2 lines)
Lines 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 2163-2169 sub RevertWaitingStatus { Link Here
2163
            priority    => 1,
2163
            priority    => 1,
2164
            found       => undef,
2164
            found       => undef,
2165
            waitingdate => undef,
2165
            waitingdate => undef,
2166
            expirationdate => $hold->patron_expiration_date,
2166
            expirationdate => undef,
2167
            itemnumber  => $hold->item_level_hold ? $hold->itemnumber : undef,
2167
            itemnumber  => $hold->item_level_hold ? $hold->itemnumber : undef,
2168
        }
2168
        }
2169
    )->store();
2169
    )->store();
(-)a/Koha/Club/Hold.pm (-1 / +1 lines)
Lines 125-131 sub add { Link Here
125
                borrowernumber  => $patron_id,
125
                borrowernumber  => $patron_id,
126
                biblionumber    => $params->{biblio_id},
126
                biblionumber    => $params->{biblio_id},
127
                priority        => $priority,
127
                priority        => $priority,
128
                expiration_date => $params->{expiration_date},
128
                expiration_date => C4::Context->preference('ReserveExpiration') ? $params->{expiration_date} : undef,
129
                notes           => $params->{notes},
129
                notes           => $params->{notes},
130
                title           => $biblio->title,
130
                title           => $biblio->title,
131
                itemnumber      => $params->{item_id},
131
                itemnumber      => $params->{item_id},
(-)a/Koha/Hold.pm (-15 / +25 lines)
Lines 220-229 sub set_waiting { Link Here
220
        desk_id => $desk_id,
220
        desk_id => $desk_id,
221
    };
221
    };
222
222
223
    my $new_expiration_date;
224
225
    if ( C4::Context->preference('ReserveExpiration') ) {
226
223
    my $max_pickup_delay = C4::Context->preference("ReservesMaxPickUpDelay");
227
    my $max_pickup_delay = C4::Context->preference("ReservesMaxPickUpDelay");
224
    my $cancel_on_holidays = C4::Context->preference('ExpireReservesOnHolidays');
228
    my $cancel_on_holidays = C4::Context->preference('ExpireReservesOnHolidays');
225
229
226
    my $new_expiration_date = $today->clone->add(days => $max_pickup_delay);
230
    $new_expiration_date = $today->clone->add(days => $max_pickup_delay);
227
231
228
    if ( C4::Context->preference("ExcludeHolidaysFromMaxPickUpDelay") ) {
232
    if ( C4::Context->preference("ExcludeHolidaysFromMaxPickUpDelay") ) {
229
        my $itemtype = $self->item ? $self->item->effective_itemtype : $self->biblio->itemtype;
233
        my $itemtype = $self->item ? $self->item->effective_itemtype : $self->biblio->itemtype;
Lines 235-259 sub set_waiting { Link Here
235
            }
239
            }
236
        );
240
        );
237
        my $calendar = Koha::Calendar->new( branchcode => $self->branchcode, days_mode => $daysmode );
241
        my $calendar = Koha::Calendar->new( branchcode => $self->branchcode, days_mode => $daysmode );
238
239
        $new_expiration_date = $calendar->days_forward( dt_from_string(), $max_pickup_delay );
242
        $new_expiration_date = $calendar->days_forward( dt_from_string(), $max_pickup_delay );
240
    }
243
    }
241
244
242
    # If patron's requested expiration date is prior to the
245
    if ( C4::Context->preference('ExpireReservesMaxPickUpDelay') ) {
243
    # calculated one, we keep the patron's one.
246
        # If patron's requested expiration date is prior to the
244
    if ( $self->patron_expiration_date ) {
247
        # calculated one, we keep the patron's one.
245
        my $requested_expiration = dt_from_string( $self->patron_expiration_date );
248
        if ( $self->patron_expiration_date ) {
246
249
            my $requested_expiration = dt_from_string( $self->patron_expiration_date );
247
        my $cmp =
250
248
          $requested_expiration
251
            my $cmp =
249
          ? DateTime->compare( $requested_expiration, $new_expiration_date )
252
              $requested_expiration
250
          : 0;
253
              ? DateTime->compare( $requested_expiration, $new_expiration_date )
251
254
              : 0;
252
        $new_expiration_date =
255
253
          $cmp == -1 ? $requested_expiration : $new_expiration_date;
256
            $new_expiration_date =
257
              $cmp == -1 ? $requested_expiration : $new_expiration_date;
258
          }
259
    } else {
260
        # if holds don't need a waiting expiration date to be expired automatically, don't set one
261
        $new_expiration_date = undef;
254
    }
262
    }
255
263
256
    $values->{expirationdate} = $new_expiration_date->ymd;
264
    } # ReserveExpiration
265
266
    $values->{expirationdate} = $new_expiration_date ? $new_expiration_date->ymd : undef;
257
267
258
    $self->set($values)->store();
268
    $self->set($values)->store();
259
269
(-)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 591-596 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
591
('RequireCashRegister','0',NULL,'Require a cash register when collecting a payment','YesNo'),
591
('RequireCashRegister','0',NULL,'Require a cash register when collecting a payment','YesNo'),
592
('RequirePaymentType','0','','Require staff to select a payment type when a payment is made','YesNo'),
592
('RequirePaymentType','0','','Require staff to select a payment type when a payment is made','YesNo'),
593
('RequireStrongPassword','1','','Require a strong login password for staff and patrons','YesNo'),
593
('RequireStrongPassword','1','','Require a strong login password for staff and patrons','YesNo'),
594
('ReserveExpiration', 1, NULL, 'Enable the use of expiration date in holds module.', 'YesNo'),
594
('ReservesControlBranch','PatronLibrary','ItemHomeLibrary|PatronLibrary','Branch checked for members reservations rights','Choice'),
595
('ReservesControlBranch','PatronLibrary','ItemHomeLibrary|PatronLibrary','Branch checked for members reservations rights','Choice'),
595
('ReservesMaxPickUpDelay','7','','Define the Maximum delay to pick up an item on hold','Integer'),
596
('ReservesMaxPickUpDelay','7','','Define the Maximum delay to pick up an item on hold','Integer'),
596
('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'),
597
('ReservesNeedReturns','1','','If ON, a hold placed on an item available in this library must be checked-in, otherwise, a hold on a specific item, that is in the library & available is considered available','YesNo'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc (-1 / +5 lines)
Lines 11-17 Link Here
11
        <th>Patron</th>
11
        <th>Patron</th>
12
        <th>Notes</th>
12
        <th>Notes</th>
13
        <th>Date</th>
13
        <th>Date</th>
14
        <th>Expiration</th>
14
        [% IF Koha.Preference('ReserveExpiration') %]
15
            <th>Expiration</th>
16
        [% END %]
15
        <th>Pickup library</th>
17
        <th>Pickup library</th>
16
        <th>Details</th>
18
        <th>Details</th>
17
        [% IF ( CAN_user_reserveforothers_modify_holds_priority ) %]
19
        [% IF ( CAN_user_reserveforothers_modify_holds_priority ) %]
Lines 122-130 Link Here
122
                    [% hold.date | $KohaDates %]
124
                    [% hold.date | $KohaDates %]
123
                [% END %]
125
                [% END %]
124
            </td>
126
            </td>
127
            [% IF Koha.Preference('ReserveExpiration') %]
125
            <td>
128
            <td>
126
                <input type="text" class="flatpickr" data-flatpickr-futuredate="true" value="[% hold.expirationdate | html %]" size="10" name="expirationdate" />
129
                <input type="text" class="flatpickr" data-flatpickr-futuredate="true" value="[% hold.expirationdate | html %]" size="10" name="expirationdate" />
127
            </td>
130
            </td>
131
            [% END %]
128
            <td>
132
            <td>
129
                [%- IF ( hold.found ) -%]
133
                [%- IF ( hold.found ) -%]
130
                    <input type="hidden" name="pickup" value="[% hold.wbrcode | html %]" />
134
                    <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 35-41 Link Here
35
                [% END %]
37
                [% END %]
36
                </td>
38
                </td>
37
              [% END %]
39
              [% END %]
40
              [% IF Koha.Preference('ReserveExpiration') %]
38
                <td><span data-order="[% reserveloo.expirationdate | html %]">[% reserveloo.expirationdate | $KohaDates %]</span></td>
41
                <td><span data-order="[% reserveloo.expirationdate | html %]">[% reserveloo.expirationdate | $KohaDates %]</span></td>
42
              [% END %]
39
                <td>
43
                <td>
40
                    [% INCLUDE 'biblio-title.inc' biblio=reserveloo.biblio link = 1 %]
44
                    [% INCLUDE 'biblio-title.inc' biblio=reserveloo.biblio link = 1 %]
41
                        [% UNLESS ( item_level_itypes ) %]
45
                        [% UNLESS ( item_level_itypes ) %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (-4 / +10 lines)
Lines 751-763 Circulation: Link Here
751
            - Mark a hold as problematic if it has been waiting for more than
751
            - Mark a hold as problematic if it has been waiting for more than
752
            - pref: ReservesMaxPickUpDelay
752
            - pref: ReservesMaxPickUpDelay
753
              class: integer
753
              class: integer
754
            - days.
754
            - '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.'
755
        -
755
        -
756
            - pref: ExpireReservesMaxPickUpDelay
756
            - pref: ExpireReservesMaxPickUpDelay
757
              choices:
757
              choices:
758
                  1: Allow
758
                  1: Allow
759
                  0: "Don't allow"
759
                  0: "Don't allow"
760
            - '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>'
760
            - '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>'
761
            - pref: ExpireReservesAutoFill
761
            - pref: ExpireReservesAutoFill
762
              choices:
762
              choices:
763
                  1: "Do"
763
                  1: "Do"
Lines 772-778 Circulation: Link Here
772
            - 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
772
            - 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
773
            - pref: ExpireReservesMaxPickUpDelayCharge
773
            - pref: ExpireReservesMaxPickUpDelayCharge
774
              class: currency
774
              class: currency
775
            - "."
775
            - '.<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.'
776
        -
776
        -
777
            - Satisfy holds using items from the libraries
777
            - Satisfy holds using items from the libraries
778
            - pref: StaticHoldsQueueWeight
778
            - pref: StaticHoldsQueueWeight
Lines 855-861 Circulation: Link Here
855
              choices:
855
              choices:
856
                  1: allow
856
                  1: allow
857
                  0: "don't allow"
857
                  0: "don't allow"
858
            - expired holds to be canceled on days the library is closed per the calendar.
858
            - '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.'
859
        -
859
        -
860
            - pref: ExcludeHolidaysFromMaxPickUpDelay
860
            - pref: ExcludeHolidaysFromMaxPickUpDelay
861
              choices:
861
              choices:
Lines 984-989 Circulation: Link Here
984
                  1: block
984
                  1: block
985
                  0: allow
985
                  0: allow
986
            - renewing of items from the staff interface and via the <code>misc/cronjobs/automatic_renewals.pl</code> cronjob.
986
            - renewing of items from the staff interface and via the <code>misc/cronjobs/automatic_renewals.pl</code> cronjob.
987
        -
988
            - pref: ReserveExpiration
989
              choices:
990
                  1: Enable
991
                  0: "Disable"
992
            - 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.
987
    Interlibrary loans:
993
    Interlibrary loans:
988
        -
994
        -
989
            - pref: ILLModule
995
            - pref: ILLModule
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (+1 lines)
Lines 1053-1058 Link Here
1053
            relatives_borrowernumbers.push("[% b | html %]");
1053
            relatives_borrowernumbers.push("[% b | html %]");
1054
        [% END %]
1054
        [% END %]
1055
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
1055
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
1056
        var ReserveExpiration = [% ( Koha.Preference('ReserveExpiration') ) ? 1 : 0 | html %];
1056
    </script>
1057
    </script>
1057
    [% Asset.js("js/pages/circulation.js") | $raw %]
1058
    [% Asset.js("js/pages/circulation.js") | $raw %]
1058
    [% Asset.js("js/checkouts.js") | $raw %]
1059
    [% Asset.js("js/checkouts.js") | $raw %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/holdshistory.tt (-5 / +16 lines)
Lines 136-147 Link Here
136
    [% INCLUDE 'str/members-menu.inc' %]
136
    [% INCLUDE 'str/members-menu.inc' %]
137
    [% Asset.js("js/members-menu.js") | $raw %]
137
    [% Asset.js("js/members-menu.js") | $raw %]
138
    <script>
138
    <script>
139
        var ReserveExpiration = [% ( Koha.Preference('ReserveExpiration') ) ? 1 : 0 | html %];
140
        var show_itemtype_column = [% ( show_itemtype_column ) ? 1 : 0 | html %];
141
        var table_settings = [% TablesSettings.GetTableSettings('members', 'holdshistory', 'holdshistory-table', 'json') | $raw %];
139
        $(document).ready(function() {
142
        $(document).ready(function() {
140
            var table_settings = [% TablesSettings.GetTableSettings('members', 'holdshistory', 'holdshistory-table', 'json') | $raw %];
143
            table_settings['columns'].forEach(function(thisCol) {
141
            [% UNLESS show_itemtype_column %]
144
                if( show_itemtype_column == 0 && thisCol.columnname == "itemtype" ){
142
              //Remove item type column settings
145
                    thisCol.cannot_be_modified = 1;
143
              table_settings['columns'] = table_settings['columns'].filter(function(c){return c['columnname'] != 'itemtype';});
146
                    thisCol.cannot_be_toggled = 1;
144
            [% END %]
147
                    thisCol.is_hidden = 1;
148
                }
149
                if( ReserveExpiration == 0 && thisCol.columnname == "expirationdate" ){
150
                    thisCol.cannot_be_modified = 1;
151
                    thisCol.cannot_be_toggled = 1;
152
                    thisCol.is_hidden = 1;
153
                }
154
            });
155
145
            var table = KohaTable("table_holdshistory", {
156
            var table = KohaTable("table_holdshistory", {
146
                "sPaginationType": "full",
157
                "sPaginationType": "full",
147
                "aaSorting": [[4, 'desc']]
158
                "aaSorting": [[4, 'desc']]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-print.tt (-2 / +6 lines)
Lines 115-121 Link Here
115
                    <th>Title</th>
115
                    <th>Title</th>
116
                    <th>Author</th>
116
                    <th>Author</th>
117
                    <th>Placed on</th>
117
                    <th>Placed on</th>
118
                    <th>Expires on</th>
118
                    [% IF Koha.Preference('ReserveExpiration') %]
119
                        <th>Expires on</th>
120
                    [% END %]
119
                    <th>Pick up location</th>
121
                    <th>Pick up location</th>
120
                </tr>
122
                </tr>
121
            </thead>
123
            </thead>
Lines 125-131 Link Here
125
                        <td>[% reserve.title | html %]</td>
127
                        <td>[% reserve.title | html %]</td>
126
                        <td>[% reserve.author | html %]</td>
128
                        <td>[% reserve.author | html %]</td>
127
                        <td>[% reserve.reservedate | $KohaDates %]</td>
129
                        <td>[% reserve.reservedate | $KohaDates %]</td>
128
                        <td>[% reserve.expirationdate | $KohaDates %]</td>
130
                        [% IF Koha.Preference('ReserveExpiration') %]
131
                            <td>[% reserve.expirationdate | $KohaDates %]</td>
132
                        [% END %]
129
                        <td>[% reserve.waiting_at | html %]</td>
133
                        <td>[% reserve.waiting_at | html %]</td>
130
                    </tr>
134
                    </tr>
131
                [% END %]
135
                [% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt (+1 lines)
Lines 860-865 Link Here
860
            relatives_borrowernumbers.push("[% b | html %]");
860
            relatives_borrowernumbers.push("[% b | html %]");
861
        [% END %]
861
        [% END %]
862
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
862
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
863
        var ReserveExpiration = [% ( Koha.Preference('ReserveExpiration') ) ? 1 : 0 | html %];
863
    </script>
864
    </script>
864
    [% Asset.js("js/pages/circulation.js") | $raw %]
865
    [% Asset.js("js/pages/circulation.js") | $raw %]
865
    [% Asset.js("js/checkouts.js") | $raw %]
866
    [% Asset.js("js/checkouts.js") | $raw %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (-4 / +6 lines)
Lines 588-597 Link Here
588
                                </li>
588
                                </li>
589
                            [% END %]
589
                            [% END %]
590
590
591
                            <li>
591
                            [% IF Koha.Preference('ReserveExpiration') %]
592
                                <label for="to">Hold expires on date:</label>
592
                                <li>
593
                                <input id="expiration_date" name="expiration_date" id="to" size="10" type="text" class="flatpickr" data-flatpickr-futuredate="true" />
593
                                    <label for="to">Hold expires on date:</label>
594
                            </li>
594
                                    <input id="expiration_date" name="expiration_date" id="to" size="10" type="text" class="flatpickr" data-flatpickr-futuredate="true" />
595
                                </li>
596
                            [% END %]
595
597
596
                            [% UNLESS ( multi_hold ) %]
598
                            [% UNLESS ( multi_hold ) %]
597
                                <li>
599
                                <li>
(-)a/koha-tmpl/intranet-tmpl/prog/js/holds.js (-1 / +4 lines)
Lines 223-229 $(document).ready(function() { Link Here
223
                            else { return oObj.branchcode.escapeHtml() || ""; }
223
                            else { return oObj.branchcode.escapeHtml() || ""; }
224
                        }
224
                        }
225
                    },
225
                    },
226
                    { "data": { _: "expirationdate_formatted", "sort": "expirationdate" } },
226
                    {
227
                        "visible": ReserveExpiration,
228
                        "data": { _: "expirationdate_formatted", "sort": "expirationdate" }
229
                    },
227
                    {
230
                    {
228
                        "mDataProp": function( oObj ) {
231
                        "mDataProp": function( oObj ) {
229
                            if ( oObj.priority && parseInt( oObj.priority ) && parseInt( oObj.priority ) > 0 ) {
232
                            if ( oObj.priority && parseInt( oObj.priority ) && parseInt( oObj.priority ) > 0 ) {
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/includes/holds-table.inc (-14 / +18 lines)
Lines 16-22 Link Here
16
                    [% ELSE %]
16
                    [% ELSE %]
17
                        <th class="psort">Placed on</th>
17
                        <th class="psort">Placed on</th>
18
                    [% END %]
18
                    [% END %]
19
                    <th>Expires on</th>
19
                    [% IF Koha.Preference('ReserveExpiration') %]
20
                        <th>Expires on</th>
21
                    [% END %]
20
                    [% UNLESS( singleBranchMode) %]
22
                    [% UNLESS( singleBranchMode) %]
21
                        <th>Pick up location</th>
23
                        <th>Pick up location</th>
22
                    [% END %]
24
                    [% END %]
Lines 65-84 Link Here
65
                                [% HOLD.reservedate | $KohaDates %]
67
                                [% HOLD.reservedate | $KohaDates %]
66
                            </span>
68
                            </span>
67
                        </td>
69
                        </td>
68
                        [% IF ! HOLD.found %]
70
                        [% IF Koha.Preference('ReserveExpiration') %]
69
                            <td class="expirationdate" data-order="[% HOLD.expirationdate | html %]">
71
                            [% IF ! HOLD.found %]
70
                                [% IF ( HOLD.expirationdate ) %]
72
                                <td class="expirationdate" data-order="[% HOLD.expirationdate | html %]">
71
                                    <span class="tdlabel">Expiration:</span>
73
                                    [% IF ( HOLD.expirationdate ) %]
72
                                    [% HOLD.expirationdate | $KohaDates %]
74
                                        <span class="tdlabel">Expiration:</span>
73
                                [% ELSE %]
75
                                        [% HOLD.expirationdate | $KohaDates %]
74
                                    <span class="tdlabel">Expiration:</span>
76
                                    [% ELSE %]
75
                                    Never expires
77
                                        <span class="tdlabel">Expiration:</span>
76
                                [% END %]
78
                                        Never expires
77
                        [% ELSE %]
79
                                    [% END %]
78
                            <td class="expirationdate" data-order="0000-00-00">
80
                            [% ELSE %]
79
                                -
81
                                <td class="expirationdate" data-order="0000-00-00">
82
                                    -
83
                            [% END %]
84
                            </td>
80
                        [% END %]
85
                        [% END %]
81
                        </td>
82
                        [% UNLESS( singleBranchMode) %]
86
                        [% UNLESS( singleBranchMode) %]
83
                            <td class="branch">
87
                            <td class="branch">
84
                                <span class="tdlabel">Pick up location:</span>
88
                                <span class="tdlabel">Pick up location:</span>
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-holdshistory.tt (-6 / +10 lines)
Lines 106-112 Link Here
106
                                        <th>Barcode</th>
106
                                        <th>Barcode</th>
107
                                        <th>Library</th>
107
                                        <th>Library</th>
108
                                        <th>Hold date</th>
108
                                        <th>Hold date</th>
109
                                        <th>Expiration date</th>
109
                                        [% IF Koha.Preference('ReserveExpiration') %]
110
                                            <th>Expiration date</th>
111
                                        [% END %]
110
                                        <th>Waiting date</th>
112
                                        <th>Waiting date</th>
111
                                        <th>Cancellation date</th>
113
                                        <th>Cancellation date</th>
112
                                        [% IF show_itemtype_column %]
114
                                        [% IF show_itemtype_column %]
Lines 123-133 Link Here
123
                                        <td>[% hold.item.barcode | html %]</td>
125
                                        <td>[% hold.item.barcode | html %]</td>
124
                                        <td>[% Branches.GetName( hold.branchcode ) | html %]</td>
126
                                        <td>[% Branches.GetName( hold.branchcode ) | html %]</td>
125
                                        <td data-order="[% hold.reservedate | html %]">[% hold.reservedate | $KohaDates %]</td>
127
                                        <td data-order="[% hold.reservedate | html %]">[% hold.reservedate | $KohaDates %]</td>
126
                                        <td data-order="[% hold.expirationdate | html %]">
128
                                        [% IF Koha.Preference('ReserveExpiration') %]
127
                                            [% IF hold.expirationdate %]
129
                                            <td data-order="[% hold.expirationdate | html %]">
128
                                                [% hold.expirationdate | $KohaDates %]
130
                                                [% IF hold.expirationdate %]
129
                                            [% END %]
131
                                                    [% hold.expirationdate | $KohaDates %]
130
                                        </td>
132
                                                [% END %]
133
                                            </td>
134
                                        [% END %]
131
                                        <td data-order="[% hold.waitingdate | html %]">
135
                                        <td data-order="[% hold.waitingdate | html %]">
132
                                            [% IF hold.waitingdate %]
136
                                            [% IF hold.waitingdate %]
133
                                                [% hold.waitingdate | $KohaDates %]
137
                                                [% hold.waitingdate | $KohaDates %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reserve.tt (+2 lines)
Lines 295-305 Link Here
295
                                                    </li>
295
                                                    </li>
296
                                                [% END %]
296
                                                [% END %]
297
297
298
                                                [% IF Koha.Preference('ReserveExpiration') %]
298
                                                <li>
299
                                                <li>
299
                                                    <label for="to[% bibitemloo.biblionumber | html %]">Hold not needed after:</label>
300
                                                    <label for="to[% bibitemloo.biblionumber | html %]">Hold not needed after:</label>
300
                                                    <input type="text" name="expiration_date_[% bibitemloo.biblionumber | html %]" id="to[% bibitemloo.biblionumber | html %]" size="10" class="flatpickr futuredate" />
301
                                                    <input type="text" name="expiration_date_[% bibitemloo.biblionumber | html %]" id="to[% bibitemloo.biblionumber | html %]" size="10" class="flatpickr futuredate" />
301
                                                    <span class="date-format to" data-biblionumber="[% bibitemloo.biblionumber | html %]">[% INCLUDE 'date-format.inc' %]</span>
302
                                                    <span class="date-format to" data-biblionumber="[% bibitemloo.biblionumber | html %]">[% INCLUDE 'date-format.inc' %]</span>
302
                                                </li>
303
                                                </li>
304
                                                [% END %]
303
305
304
                                                [% IF Koha.Preference('AllowHoldItemTypeSelection') %]
306
                                                [% IF Koha.Preference('AllowHoldItemTypeSelection') %]
305
                                                    <li>
307
                                                    <li>
(-)a/misc/cronjobs/holds/cancel_expired_holds.pl (-1 / +3 lines)
Lines 73-76 pod2usage(1) if $help; Link Here
73
73
74
cronlogaction();
74
cronlogaction();
75
75
76
C4::Reserves::CancelExpiredReserves($reason);
76
if( C4::Context->preference('ReserveExpiration') ) {
77
    C4::Reserves::CancelExpiredReserves($reason);
78
}
(-)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 1408-1413 subtest 'ModReserveAffect logging' => sub { Link Here
1408
    like( $log->info, qr{$expected}, 'Timestamp logged is the current one' );
1408
    like( $log->info, qr{$expected}, 'Timestamp logged is the current one' );
1409
};
1409
};
1410
1410
1411
subtest 'ReserveExpiration syspref tests' => sub {
1412
1413
    plan tests => 2;
1414
1415
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 1 );
1416
1417
    my $expirationdate = dt_from_string->add( days => 1 );
1418
    my $hold = $builder->build_object(
1419
        {   class => 'Koha::Holds',
1420
            value => { expirationdate => $expirationdate }
1421
        }
1422
    );
1423
1424
    # Disable expiration date for reserves
1425
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 0 );
1426
1427
    my $reverted = C4::Reserves::RevertWaitingStatus({ itemnumber => $hold->itemnumber });
1428
1429
    is( $reverted->expirationdate, undef, "Expiration date should be removed with reserve expiration disabled" );
1430
1431
    # Re-enable expiration date for reserves
1432
    t::lib::Mocks::mock_preference( 'ReserveExpiration', 1 );
1433
1434
    $hold = $builder->build_object(
1435
        {   class => 'Koha::Holds',
1436
            value => { expirationdate => $expirationdate }
1437
        }
1438
    );
1439
1440
    $reverted = C4::Reserves::RevertWaitingStatus({ itemnumber => $hold->itemnumber });
1441
1442
    is( $reverted->expirationdate, undef, "Expiration date is still removed because we can't reset to the original expiration date" );
1443
};
1444
1411
sub count_hold_print_messages {
1445
sub count_hold_print_messages {
1412
    my $message_count = $dbh->selectall_arrayref(q{
1446
    my $message_count = $dbh->selectall_arrayref(q{
1413
        SELECT COUNT(*)
1447
        SELECT COUNT(*)
1414
- 

Return to bug 24194