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

(-)a/Koha/REST/V1/Holds.pm (-2 / +3 lines)
Lines 278-285 sub edit { Link Here
278
278
279
        $pickup_library_id //= $hold->branchcode;
279
        $pickup_library_id //= $hold->branchcode;
280
        my $priority         = $body->{priority} // $hold->priority;
280
        my $priority         = $body->{priority} // $hold->priority;
281
        my $hold_date       = $body->{hold_date}       // $hold->reservedate;
281
        my $hold_date       = exists $body->{hold_date}       ? $body->{hold_date}       : $hold->reservedate;
282
        my $expiration_date = $body->{expiration_date} // $hold->expirationdate;
282
        my $expiration_date = exists $body->{expiration_date} ? $body->{expiration_date} : $hold->expirationdate;
283
283
284
284
        # suspended_until can also be set to undef
285
        # suspended_until can also be set to undef
285
        my $suspended_until = $body->{suspended_until} || $hold->suspend_until;
286
        my $suspended_until = $body->{suspended_until} || $hold->suspend_until;
(-)a/api/v1/swagger/definitions/hold.yaml (+10 lines)
Lines 123-128 properties: Link Here
123
      - object
123
      - object
124
      - "null"
124
      - "null"
125
    description: The item
125
    description: The item
126
  item_group:
127
    type:
128
      - object
129
      - "null"
130
    description: The item group
131
  patron:
132
    type:
133
      - object
134
      - "null"
135
    description: The patron
126
  pickup_library:
136
  pickup_library:
127
    type:
137
    type:
128
      - object
138
      - object
(-)a/api/v1/swagger/paths/holds.yaml (-2 / +9 lines)
Lines 104-109 Link Here
104
            - cancellation_requested
104
            - cancellation_requested
105
            - biblio
105
            - biblio
106
            - pickup_library
106
            - pickup_library
107
            - patron
108
            - item
109
            - item_group
107
        collectionFormat: csv
110
        collectionFormat: csv
108
    produces:
111
    produces:
109
      - application/json
112
      - application/json
Lines 289-299 Link Here
289
              format: date-time
292
              format: date-time
290
            hold_date:
293
            hold_date:
291
              description: Hold date
294
              description: Hold date
292
              type: string
295
              type: 
296
                - string
297
                - "null"
293
              format: date
298
              format: date
294
            expiration_date:
299
            expiration_date:
295
              description: Hold's expiration date
300
              description: Hold's expiration date
296
              type: string
301
              type: 
302
                - string
303
                - "null"
297
              format: date
304
              format: date
298
          additionalProperties: false
305
          additionalProperties: false
299
    consumes:
306
    consumes:
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc (-254 / +4 lines)
Lines 5-277 Link Here
5
[% #This include depends on the asset js/form-submit.js. Any template making use of this include must import form-submit.js as well. %]
5
[% #This include depends on the asset js/form-submit.js. Any template making use of this include must import form-submit.js as well. %]
6
[% #FIXME can form-submit.js be imported into this file directly? %]
6
[% #FIXME can form-submit.js be imported into this file directly? %]
7
7
8
<table id="patron_holds_table" class="holds_table">
8
<table id="patron_holds_table_[% biblio_id | html %]_[% split_data | html %]" class="holds_table" data-total-holds="[% total_holds | html %]">
9
    <thead>
9
    <thead>
10
        <tr>
10
        <tr>
11
            <th id="checkbox" data-colname="checkbox"><input type="checkbox" class="select_hold_all"/></th>
11
            <th id="checkbox" data-colname="checkbox"><input type="checkbox" class="select_hold_all"/></th>
12
            <th id="priority" data-colname="priority">Priority</th>
12
            <th id="priority" data-colname="priority">Priority</th>
13
            [% IF ( CAN_user_reserveforothers_modify_holds_priority ) %]
13
            <th id="change_priority" data-colname="change_priority">Change priority</th>
14
                <th id="change_priority" data-colname="change_priority">Change priority</th>
15
            [% END %]
16
            <th id="patron" data-colname="patron">Patron</th>
14
            <th id="patron" data-colname="patron">Patron</th>
17
            <th id="notes" data-colname="notes">Notes</th>
15
            <th id="notes" data-colname="notes">Notes</th>
18
            <th id="date" data-colname="date">Date</th>
16
            <th id="date" data-colname="date">Date</th>
19
            <th id="expiration" data-colname="expiration">Expiration</th>
17
            <th id="expiration" data-colname="expiration">Expiration</th>
20
            <th id="pickup_library" data-colname="pickup_library">Pickup library</th>
18
            <th id="pickup_library" data-colname="pickup_library">Pickup library</th>
21
            <th id="details" data-colname="details">Details</th>
19
            <th id="details" data-colname="details">Details</th>
22
            [% IF ( CAN_user_reserveforothers_modify_holds_priority ) %]
20
            <th id="set_lowest_priority" data-colname="set_lowest_priority"><span style="display:none;">Set lowest priority</span><i class="fa fa-lg fa-rotate-90 fa-fast-forward" title="Toggle set to lowest priority"></i></th>
23
                <th id="set_lowest_priority" data-colname="set_lowest_priority"><span style="display:none;">Set lowest priority</span><i class="fa fa-lg fa-rotate-90 fa-fast-forward" title="Toggle set to lowest priority"></i></th>
24
            [% END %]
25
            <th id="delete" data-colname="delete">Delete</th>
21
            <th id="delete" data-colname="delete">Delete</th>
26
            <th id="suspend" data-colname="suspend">Suspend</th>
22
            <th id="suspend" data-colname="suspend">Suspend</th>
27
            <th id="print_slip" data-colname="print_slip">Print hold/transfer slip</th>
23
            <th id="print_slip" data-colname="print_slip">Print hold/transfer slip</th>
28
        </tr>
24
        </tr>
29
    </thead>
25
    </thead>
30
    [%- SET first_priority = 0 -%]
31
    [%- SET found_holds = 0 -%]
32
    [%- SET last_priority  = holds.last.priority -%]
33
34
    [% SET all_priorities = [] %]
35
    [% FOREACH hold IN holds %]
36
        [% all_priorities.push( hold.priority ) %]
37
    [% END %]
38
39
    <tbody>
40
        [% FOREACH hold IN holds %]
41
        [%- IF !hold.found && first_priority == 0 -%]
42
            [%- first_priority = hold.priority -%]
43
            [%- found_holds = loop.index() -%]
44
        [%- END -%]
45
        [%- IF Koha.Preference('HoldsSplitQueueNumbering') == 'actual' -%]
46
            [%- this_priority = hold.priority -%]
47
        [%- ELSE -%]
48
            [%- this_priority = loop.count() - found_holds -%]
49
        [%- END -%]
50
            [% IF hold.suspend %]
51
                <tr class="suspend">
52
            [% ELSE %]
53
                <tr>
54
            [% END %]
55
                <td><input type="checkbox" class="select_hold" data-id="[% hold.reserve_id | html %]"/></td>
56
                <td>
57
                    <input type="hidden" name="reserve_id" value="[% hold.reserve_id | html %]" />
58
                    <input type="hidden" name="borrowernumber" value="[% hold.borrowernumber | html %]" />
59
                    <input type="hidden" name="biblionumber" value="[% hold.biblionumber | html %]" />
60
                    [% IF ( CAN_user_reserveforothers_modify_holds_priority ) %]
61
                        [% IF Koha.Preference('HoldsSplitQueue') == "nothing" && !hold.found %]
62
                            <select name="rank-request" class="rank-request" data-hold-id="[% hold.reserve_id | html %]">
63
                            [% IF ( CAN_user_reserveforothers_modify_holds_priority ) %]
64
                                [% FOREACH priority IN all_priorities %]
65
                                    [% IF priority == this_priority %]
66
                                        <option value="[% priority | html %]" selected="selected">[% priority | html %]</option>
67
                                    [% ELSE %]
68
                                        <option value="[% priority | html %]">[% priority | html %]</option>
69
                                    [% END %]
70
                                [% END %]
71
                            [% ELSE %]
72
                                <option value="[% hold.priority | html %]" selected="selected">[% this_priority | html %]</option>
73
                            [% END %]
74
                                <option value="del">del</option>
75
                            </select>
76
                        [% ELSE %]
77
                            <input type="hidden" name="rank-request" class="rank-request" value="[% hold.priority | html %]" data-hold-id="[% hold.reserve_id | html %]">
78
                            <select name="rank-request" class="rank-request" disabled="disabled" data-hold-id="[% hold.reserve_id | html %]">
79
                            [% IF ( hold.found ) %]
80
                                [% IF ( hold.intransit ) %]
81
                                    <option value="T" selected="selected">In transit</option>
82
                                [% ELSIF (hold.inprocessing) %]
83
                                    <option value="P" selected="selected">In processing</option>
84
                                [% ELSE %]
85
                                    <option value="W" selected="selected">Waiting</option>
86
                                [% END %]
87
                            [% ELSE %]
88
                                <option value="[% hold.priority | html %]" selected="selected">[% this_priority | html %]</option>
89
                            [% END %]
90
                            </select>
91
                        [% END %]
92
                    [% ELSE %]
93
                        <input type="hidden" name="rank-request" class="rank-request" value="[% hold.priority | html %]" data-hold-id="[% hold.reserve_id | html %]">
94
                        [% hold.priority | html %]
95
                    [% END %]
96
                </td>
97
                [%- IF ( CAN_user_reserveforothers_modify_holds_priority ) -%]
98
                [%- UNLESS hold.found -%]
99
                        [%- SET prev_priority  = loop.prev.priority -%]
100
                        [%- SET next_priority  = loop.next.priority -%]
101
                        <td style="white-space:nowrap;">
102
                            <a class="hold-arrow" title="Move hold up" data-op="cud-move" data-where="up" data-first_priority="[% first_priority | html %]" data-last_priority="[% last_priority | html %]" data-prev_priority="[% prev_priority | html %]" data-next_priority="[% next_priority | html %]" data-borrowernumber="[% hold.borrowernumber | html %]" data-biblionumber="[% hold.biblionumber | html %]" data-reserve_id="[% hold.reserve_id | html %]" data-date="[% hold.date | html %]">
103
                                <i class="fa fa-lg icon-move-hold-up" aria-hidden="true"></i>
104
                            </a>
105
106
                            <a class="hold-arrow" title="Move hold to top" data-op="cud-move" data-where="top" data-first_priority="[% first_priority | html %]" data-last_priority="[% last_priority | html %]" data-prev_priority="[% prev_priority | html %]" data-next_priority="[% next_priority | html %]" data-borrowernumber="[% hold.borrowernumber | html %]" data-biblionumber="[% hold.biblionumber | html %]" data-reserve_id="[% hold.reserve_id | html %]" data-date="[% hold.date | html %]">
107
                                <i class="fa fa-lg icon-move-hold-top" aria-hidden="true"></i>
108
                            </a>
109
110
                            <a class="hold-arrow" title="Move hold to bottom" data-op="cud-move" data-where="bottom" data-first_priority="[% first_priority | html %]" data-last_priority="[% last_priority | html %]" data-prev_priority="[% prev_priority | html %]" data-next_priority="[% next_priority | html %]" data-borrowernumber="[% hold.borrowernumber | html %]" data-biblionumber="[% hold.biblionumber | html %]" data-reserve_id="[% hold.reserve_id | html %]" data-date="[% hold.date | html %]">
111
                                <i class="fa fa-lg icon-move-hold-bottom" aria-hidden="true"></i>
112
                            </a>
113
114
                            <a class="hold-arrow" title="Move hold down" data-op="cud-move" data-where="down" data-first_priority="[% first_priority | html %]" data-last_priority="[% last_priority | html %]" data-prev_priority="[% prev_priority | html %]" data-next_priority="[% next_priority | html %]" data-borrowernumber="[% hold.borrowernumber | html %]" data-biblionumber="[% hold.biblionumber | html %]" data-reserve_id="[% hold.reserve_id | html %]" data-date="[% hold.date | html %]">
115
                                <i class="fa fa-lg icon-move-hold-down" aria-hidden="true"></i>
116
                            </a>
117
                        </td>
118
            [%- ELSE -%]
119
                <td></td>
120
            [%- END -%]
121
                [%- END -%]
122
                <td>
123
                    [% INCLUDE 'patron-title.inc' patron=hold.patron hide_patron_infos_if_needed=1 %]
124
                </td>
125
                <td>[% hold.notes | html | html_line_break %]</td>
126
                <td data-order="[% hold.date| html %]">
127
                    [% IF Koha.Preference('AllowHoldDateInFuture') %]
128
                        <input type="text" class="flatpickr" value="[% hold.date | html %]" required="required" size="10" name="reservedate" />
129
                    [% ELSE %]
130
                        [% hold.date | $KohaDates %]
131
                    [% END %]
132
                </td>
133
                <td>
134
                    <input type="text" class="flatpickr" data-flatpickr-futuredate="true" value="[% hold.expirationdate | html %]" size="10" name="expirationdate" />
135
                </td>
136
                <td>
137
                    [%- IF ( hold.found ) -%]
138
                        <input type="hidden" name="pickup" value="[% hold.wbrcode | html %]" />
139
                        [%- IF ( hold.atdestination ) -%]
140
                                Item waiting at <strong> [% hold.wbrname | html %]</strong>[% IF hold.desk_name %], [% hold.desk_name | html %],[% END %] since [% hold.waiting_date | $KohaDates %]
141
                        [%- ELSIF (hold.intransit) -%]
142
                            Item being transferred to <strong> [% hold.wbrname | html %]</strong>
143
                        [%- ELSIF (hold.inprocessing) -%]
144
                            Item being processed at <strong> [% hold.wbrname | html %]</strong>
145
                        [%- ELSE -%]
146
                            Hold expected at <strong>[% hold.wbrname | html %]</strong>, please checkin to verify status
147
                        [%- END -%]
148
                    [%- ELSE -%]
149
                        [%- IF Koha.Preference('IndependentBranches') && Branches.all().size == 1 -%]
150
                            [% Branches.GetName(hold.branchcode) | html %] <input type="hidden" name="pickup" value="[% hold.branchcode | html %]" />
151
                        [%- ELSE -%]
152
                            <select class="pickup_location_dropdown"
153
                                    data-selected="[% hold.branchcode | html %]"
154
                                    data-hold-id="[% hold.reserve_id | html %]"
155
                                    data-pickup-location-source="hold"
156
                                    name="pickup">
157
                                <option selected="selected" value="[% hold.branchcode | html %]">[% Branches.GetName(hold.branchcode) | html %]</option>
158
                                <option value="" disabled="disabled" class="loading">Loading...</option>
159
                            </select>
160
                            <img class="loading_[% hold.reserve_id | html %]" src="[% interface | html %]/[% theme | html %]/img/spinner-small.gif" alt="" style="display:none;"/>
161
                        [%- END -%]
162
                    [%- END -%]
163
                </td>
164
                <td>
165
                    [%- IF ( hold.found ) -%]
166
                        <a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=[% hold.biblionumber | uri %]&amp;itemnumber=[% hold.itemnumber | uri %]#item[% hold.itemnumber | uri %]">
167
                            [%- IF ( hold.barcodenumber ) -%]
168
                                [%- hold.barcodenumber | html -%]
169
                            [%- ELSE -%]
170
                                <span>No barcode</span>
171
                            [%- END -%]
172
                            <input type="hidden" name="itemnumber" value="[% hold.itemnumber | html %]" />
173
                        </a>
174
                    [%- ELSE -%]
175
                        [%- IF ( hold.item_level_hold ) -%]
176
                            <em>
177
                                [%- IF ! hold.change_hold_type_allowed -%]
178
                                    <span>Only item</span>
179
                                    <a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=[% hold.biblionumber | uri %]&amp;itemnumber=[% hold.itemnumber | uri %]#item[% hold.itemnumber | uri %]">
180
                                        [%- IF ( hold.barcodenumber ) -%]
181
                                            [%- hold.barcodenumber | html -%]
182
                                        [%- ELSE -%]
183
                                            <span>No barcode</span>
184
                                        [%- END -%]
185
                                        <input type="hidden" name="itemnumber" value="[% hold.itemnumber | html %]" />
186
                                    </a>
187
                                [%- ELSE -%]
188
                                        <select name="change_hold_type_[% hold.reserve_id | html %]">
189
                                        <option selected="selected" value="">Only item [%- IF ( hold.barcodenumber ) -%]
190
                                            [%- hold.barcodenumber | html -%]
191
                                        [%- ELSE -%]
192
                                            No barcode
193
                                        [%- END -%]
194
                                        </option>
195
                                        <option value="1">Next available</option>
196
                                    </select>
197
                                    [%- IF ( hold.itemnumber ) -%]
198
                                        <input type="hidden" name="itemnumber" value="[% hold.itemnumber | html %]" />
199
                                    [%- END -%]
200
                                    [%- IF hold.itemtype -%]
201
                                        <span style="display:none">Next available [% ItemTypes.GetDescription( hold.itemtype ) | html %] item</span>
202
                                    [%- ELSE -%]
203
                                        <span style="display:none">Next available</span>
204
                                    [%- END -%]
205
                                [%- END -%]
206
                            </em>
207
                        [%- ELSE -%]
208
                            [%- IF hold.itemtype -%]
209
                                <em>Next available [% ItemTypes.GetDescription( hold.itemtype ) | html %] item</em>
210
                            [%- ELSIF hold.object.item_group -%]
211
                                <em>Next available item from group <strong>[% hold.object.item_group.description | html %]</strong></em>
212
                            [%- ELSE -%]
213
                                <em>Next available</em>
214
                            [%- END -%]
215
216
                            <input type="hidden" name="itemnumber" value="" />
217
                        [%- END -%]
218
                    [%- END -%]
219
                    [%- IF hold.non_priority -%]
220
                        <br><i>Non priority hold</i>
221
                    [%- END -%]
222
                </td>
223
                [%- IF ( CAN_user_reserveforothers_modify_holds_priority ) -%]
224
                [%- UNLESS hold.found -%]
225
                        <td>
226
                                [% IF ( hold.lowestPriority ) %]
227
                                    <a class="hold-arrow" title="Remove lowest priority" data-op="cud-setLowestPriority" data-borrowernumber="[% hold.borrowernumber | html %]" data-biblionumber="[% hold.biblionumber | html %]" data-reserve_id="[% hold.reserve_id | html %]" data-date="[% hold.date | html %]">
228
                                        <i class="fa fa-lg fa-rotate-90 icon-unset-lowest" aria-hidden="true"></i>
229
                                [% ELSE %]
230
                                    <a class="hold-arrow" title="Set lowest priority" data-op="cud-setLowestPriority" data-borrowernumber="[% hold.borrowernumber | html %]" data-biblionumber="[% hold.biblionumber | html %]" data-reserve_id="[% hold.reserve_id | html %]" data-date="[% hold.date | html %]">
231
                                        <i class="fa fa-lg fa-rotate-90 icon-set-lowest" aria-hidden="true"></i>
232
                                [% END %]
233
                            </a>
234
                        </td>
235
            [%- ELSE -%]
236
                <td></td>
237
            [%- END -%]
238
                [%- END -%]
239
                <td>
240
                    <a class="cancel-hold" title="Cancel hold" data-borrowernumber="[% hold.borrowernumber | html %]" data-biblionumber="[% hold.biblionumber | html %]" data-id="[% hold.reserve_id | html %]" href="#">
241
                        <i class="fa fa-trash" aria-label="Cancel hold"></i>
242
                    </a>
243
                </td>
244
                <td>
245
                    [% IF Koha.Preference('SuspendHoldsIntranet') %]
246
                        [% UNLESS ( hold.found ) %]
247
                            [% IF ( hold.suspend ) %]
248
                                <button class="btn btn-default btn-xs unsuspend-hold" data-reserve-id="[% hold.reserve_id | html %]" data-biblionumber="[% hold.biblionumber | html %]">
249
                                    <i class="fa fa-play" aria-hidden="true"></i> Unsuspend
250
                                </button>
251
                            [% ELSE %]
252
                                <button class="btn btn-default btn-xs suspend-hold" data-reserve-id="[% hold.reserve_id | html %]" data-biblionumber="[% hold.biblionumber | html %]">
253
                                    <i class="fa fa-pause" aria-hidden="true"></i> Suspend
254
                                </button>
255
                            [% END %]
256
257
                            [% IF Koha.Preference('AutoResumeSuspendedHolds') %]
258
                                <label for="suspend_until_[% hold.reserve_id | html %]">[% IF ( hold.suspend ) %] on [% ELSE %] until [% END %]</label>
259
                                <input type="text" name="suspend_until_[% hold.reserve_id | html %]" id="suspend_until_[% hold.reserve_id | html %]" size="10" value="[% hold.suspend_until | html %]" class="flatpickr" data-flatpickr-futuredate="true" />
260
                            [%- ELSE -%]
261
                                <input type="hidden" name="suspend_until_[% hold.reserve_id | html %]" id="suspend_until_[% hold.reserve_id | html %]" value=""/>
262
                            [%- END -%]
263
                        [%- END -%]
264
                    [%- END # IF SuspendHoldsIntranet -%]
265
                    [%- IF ( hold.found ) -%]
266
                        <a class="btn btn-default  submit-form-link" href="#" id="revert_hold_[% hold.reserve_id | html %]" data-op="cud-move" data-where="down" data-first_priority="[% first_priority | html %]" data-last_priority="[% last_priority | html %]" data-prev_priority="0" data-next_priority="1" data-borrowernumber="[% hold.borrowernumber | html %]" data-biblionumber="[% hold.biblionumber | html %]" data-itemnumber="[% hold.itemnumber | html %]" data-reserve_id="[% hold.reserve_id | html %]" data-date="[% hold.date | html %]" data-action="request.pl" data-method="post">[% IF hold.intransit %]Revert transit status[% ELSE %]Revert waiting status[% END %]</a>
267
                    [%- END -%]
268
                </td>
269
                [% IF ( hold.intransit || hold.atdestination ) %]
270
                    <td><input class="printholdslip" type="button" name="printholdslip" value="Print slip" data-reserve_id="[% hold.reserve_id | html %]"></td>
271
                [% ELSE %]
272
                    <td></td>
273
                [% END %]
274
            </tr>
275
        [% END %]
276
    </tbody>
277
</table>
26
</table>
27
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (-250 / +90 lines)
Lines 1230-1236 Link Here
1230
                        [% END %]
1230
                        [% END %]
1231
                    [% END %]
1231
                    [% END %]
1232
                [% END %]
1232
                [% END %]
1233
                [% IF ( reserveloop ) %]
1233
                [% IF ( total_holds ) %]
1234
                    <form id="existing_holds" name="T[% time | html %]" action="modrequest.pl" method="post" style="display:block">
1234
                    <form id="existing_holds" name="T[% time | html %]" action="modrequest.pl" method="post" style="display:block">
1235
                        [% INCLUDE 'csrf-token.inc' %]
1235
                        [% INCLUDE 'csrf-token.inc' %]
1236
                        [% IF ( multi_hold ) %]
1236
                        [% IF ( multi_hold ) %]
Lines 1248-1257 Link Here
1248
1248
1249
                        <h2>Existing holds</h2>
1249
                        <h2>Existing holds</h2>
1250
                        <div id="toolbar" class="btn-toolbar sticky">
1250
                        <div id="toolbar" class="btn-toolbar sticky">
1251
                            <div class="btn-group">
1252
                                <input type="hidden" name="op" value="cud-modifyall">
1253
                                <input type="submit" class="btn btn-primary" name="submit" value="Update hold(s)" />
1254
                            </div>
1255
                            <div class="btn-group">
1251
                            <div class="btn-group">
1256
                                <button class="btn cancel_selected_holds" data-bulk="true"></button>
1252
                                <button class="btn cancel_selected_holds" data-bulk="true"></button>
1257
                            </div>
1253
                            </div>
Lines 1271-1417 Link Here
1271
                        <div class="page-section">
1267
                        <div class="page-section">
1272
1268
1273
                        [% FOREACH biblioloo IN biblioloop %]
1269
                        [% FOREACH biblioloo IN biblioloop %]
1274
                            [% IF ( biblioloo.reserveloop ) %]
1270
                            [% IF ( biblioloo.total_holds ) %]
1275
                                <div class="hold_title" id="hold_title_[% biblioloo.biblionumber | html %]">
1271
                                <div class="hold_title" id="hold_title_[% biblioloo.biblionumber | html %]">
1276
                                    [% IF ( multi_hold ) %]
1272
                                    [% IF ( multi_hold ) %]
1277
                                        <h3>
1273
                                        <h3>
1278
                                            <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblioloo.biblionumber | uri %]">
1274
                                            <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblioloo.biblionumber | uri %]">
1279
                                                [% biblioloo.title | html %]
1275
                                                [% biblioloo.title | html %]
1280
                                            </a> <span class="badge text-bg-info"><span>[% biblioloo.reserveloop.size | html %] [% tn('Hold', 'Holds', biblioloo.reserveloop.size) | $raw %]</span></span>
1276
                                            </a> <span class="badge text-bg-info"><span>[% biblioloo.total_holds | html %] [% tn('Hold', 'Holds', biblioloo.total_holds) | $raw %]</span></span>
1281
                                        </h3>
1277
                                        </h3>
1282
                                    [% END %]
1278
                                    [% END %]
1283
1279
1284
                                    [% IF Koha.Preference('HoldsSplitQueue') == 'branch' %]
1280
                                    [% IF Koha.Preference('HoldsSplitQueue') == 'branch' %]
1285
1281
                                        [% IF biblioloo.hold_branches.empty %]
1286
                                        [% SET branchcodes = [] %]
1282
                                            <div class="holds_by_library">
1287
1283
                                                <h4>Any library</h4>
1288
                                        [% FOREACH h IN biblioloo.reserveloop %]
1284
                                                [% INCLUDE holds_table.inc biblio_id=biblioloo.biblionumber total_holds=biblioloo.total_holds split_data="any" %]
1289
                                            [% branchcodes.push( h.branchcode ) %]
1290
                                        [% END %]
1291
                                        [% branchcodes = branchcodes.unique %]
1292
                                        [% IF ( branchcodes.empty ) %]
1293
                                            <div class="alert alert-info">
1294
                                                There are no holds on this title.
1295
                                            </div>
1285
                                            </div>
1296
                                        [% ELSE %]
1286
                                        [% ELSE %]
1297
1287
                                            [% FOREACH b IN biblioloo.hold_branches %]
1298
                                            [% FOREACH b IN branchcodes.sort %]
1299
                                                [% SET holds_by_branch = [] %]
1300
                                                [% FOREACH h IN biblioloo.reserveloop %]
1301
                                                    [% IF h.branchcode == b %]
1302
                                                        [% holds_by_branch.push( h ) %]
1303
                                                    [% END %]
1304
                                                [% END %]
1305
                                                <div class="holds_by_library">
1288
                                                <div class="holds_by_library">
1306
                                                    <h4>[% Branches.GetName( b ) | html %]</h4>
1289
                                                    <h4>[% Branches.GetName( b ) | html %]</h4>
1307
1290
1308
                                                    [% INCLUDE holds_table.inc holds=holds_by_branch %]
1291
                                                    [% INCLUDE holds_table.inc biblio_id=biblioloo.biblionumber total_holds=biblioloo.total_holds split_data=b %]
1309
                                                </div>
1292
                                                </div>
1310
                                            [% END # /FOREACh b %]
1293
                                            [% END %]
1311
                                        [% END # /IF ( branchcodes.empty ) %]
1294
                                        [% END # /IF hold_branches.empty %]
1312
1295
1313
                                    [% ELSIF Koha.Preference('HoldsSplitQueue') == 'itemtype' %]
1296
                                    [% ELSIF Koha.Preference('HoldsSplitQueue') == 'itemtype' %]
1314
1297
1315
                                        [% SET itemtypes = [] %]
1298
                                        [% IF biblioloo.hold_itemtypes.empty %]
1316
1299
                                            <div class="holds_by_itemtype">
1317
                                        [% FOREACH h IN biblioloo.reserveloop %]
1300
                                                <h4>Any item type</h4>
1318
                                            [% SET hold_itemtype = h.object.item.effective_itemtype || h.itemtype %]
1301
                                                [% INCLUDE holds_table.inc biblio_id=biblioloo.biblionumber total_holds=biblioloo.total_holds split_data="any" %]
1319
                                            [% itemtypes.push( hold_itemtype ) %]
1320
                                        [% END %]
1321
                                        [% itemtypes = itemtypes.unique %]
1322
                                        [% IF ( itemtypes.empty ) %]
1323
                                            <div class="alert alert-info">
1324
                                                There are no holds on this title.
1325
                                            </div>
1302
                                            </div>
1326
                                        [% ELSE %]
1303
                                        [% ELSE %]
1327
1304
                                            [% FOREACH i IN biblioloo.hold_itemtypes %]
1328
                                            [% FOREACH i IN itemtypes.sort %]
1329
                                                [% SET holds_by_itemtype = [] %]
1330
                                                [% FOREACH h IN biblioloo.reserveloop %]
1331
                                                    [% SET hold_itemtype = h.object.item.effective_itemtype || h.itemtype %]
1332
                                                    [% IF hold_itemtype == i %]
1333
                                                        [% holds_by_itemtype.push( h ) %]
1334
                                                    [% END %]
1335
                                                [% END %]
1336
1337
                                                <div class="holds_by_itemtype">
1305
                                                <div class="holds_by_itemtype">
1338
                                                    [% IF i %]
1306
                                                    [% IF i && i != 'any' %]
1339
                                                        <h4>[% ItemTypes.GetDescription( i ) | html %]</h4>
1307
                                                        <h4>[% ItemTypes.GetDescription( i ) | html %]</h4>
1340
                                                    [% ELSE %]
1308
                                                    [% ELSE %]
1341
                                                        <h4>Any item type</h4>
1309
                                                        <h4>Any item type</h4>
1342
                                                    [% END %]
1310
                                                    [% END %]
1343
                                                    [% INCLUDE holds_table.inc holds=holds_by_itemtype %]
1311
                                                    [% INCLUDE holds_table.inc biblio_id=biblioloo.biblionumber total_holds=biblioloo.total_holds split_data=i %]
1344
                                                </div>
1312
                                                </div>
1345
                                            [% END # /FOREACH i %]
1313
                                            [% END %]
1346
                                        [% END # /IF ( itemtypes.empty ) %]
1314
                                        [% END # /IF hold_split.empty %]
1347
1315
1348
                                    [% ELSIF Koha.Preference('HoldsSplitQueue') == 'branch_itemtype' %]
1316
                                    [% ELSIF Koha.Preference('HoldsSplitQueue') == 'branch_itemtype' %]
1349
                                        [% SET branchcodes = [] %]
1350
1351
                                        [% FOREACH h IN biblioloo.reserveloop %]
1352
                                            [% branchcodes.push( h.branchcode ) %]
1353
                                        [% END %]
1354
                                        [% branchcodes = branchcodes.unique %]
1355
                                        [% IF ( branchcodes.empty ) %]
1356
                                            <div class="alert alert-info">
1357
                                                There are no holds on this title.
1358
                                            </div>
1359
                                        [% ELSE %]
1360
1317
1361
                                            [% FOREACH b IN branchcodes.sort %]
1318
                                        [% FOREACH b IN biblioloo.hold_branches %]
1362
                                                <div class="holds_by_library">
1319
                                            <div class="holds_by_library">
1363
                                                    <h4 class="library_holds">[% Branches.GetName( b ) | html %]</h4>
1320
                                                <h4>[% Branches.GetName( b ) | html %]</h4>
1364
                                                    [% SET holds_by_branch = [] %]
1321
                                                [% FOREACH i IN biblioloo.hold_itemtypes %]
1365
                                                    [% FOREACH h IN biblioloo.reserveloop %]
1322
                                                    <div class="holds_by_itemtype">
1366
                                                        [% IF h.branchcode == b %]
1323
                                                        [% IF i && i != 'any' %]
1367
                                                            [% holds_by_branch.push( h ) %]
1324
                                                            <h4>[% ItemTypes.GetDescription( i ) | html %]</h4>
1325
                                                        [% ELSE %]
1326
                                                            <h4>Any item type</h4>
1368
                                                        [% END %]
1327
                                                        [% END %]
1369
                                                    [% END %]
1328
                                                        [% SET split_data = b _ "_" _ i %]
1370
1329
                                                        [% INCLUDE holds_table.inc biblio_id=biblioloo.biblionumber total_holds=biblioloo.total_holds split_data=split_data %]
1371
                                                    [% SET itemtypes = [] %]
1330
                                                    </div>
1372
                                                    [% FOREACH h IN holds_by_branch %]
1331
                                                [% END %]
1373
                                                        [% SET hold_itemtype = h.object.item.effective_itemtype || h.itemtype %]
1374
                                                        [% itemtypes.push( hold_itemtype ) %]
1375
                                                    [% END %]
1376
                                                    [% itemtypes = itemtypes.unique %]
1377
1378
                                                    [% FOREACH i IN itemtypes.sort %]
1379
                                                        <div class="holds_by_itemtype">
1380
                                                            <h5 class="itemtype_holds">
1381
                                                                [% IF i %]
1382
                                                                    [% ItemTypes.GetDescription( i ) | html %]
1383
                                                                [% ELSE %]
1384
                                                                    <span>Any item type</span>
1385
                                                                [% END %]
1386
                                                            </h5>
1387
1388
                                                            [% SET holds_by_itemtype = [] %]
1389
                                                            [% FOREACH h IN holds_by_branch %]
1390
                                                                [% SET hold_itemtype = h.object.item.effective_itemtype || h.itemtype %]
1391
                                                                [% IF hold_itemtype == i %]
1392
                                                                    [% holds_by_itemtype.push( h ) %]
1393
                                                                [% END %]
1394
                                                            [% END %]
1395
                                                            [% INCLUDE holds_table.inc holds=holds_by_itemtype %]
1396
                                                        </div> <!-- /.holds_by_itemtype -->
1397
                                                    [% END %]
1398
                                                </div> <!-- /.holds_by_library -->
1399
                                            [% END # /FOREACH b %]
1400
                                        [% END # /IF ( branchcodes.empty ) %]
1401
1402
                                    [% ELSE %]
1403
1404
                                        [% IF ( biblioloo.reserveloop.size ) %]
1405
                                            [% INCLUDE holds_table.inc holds=biblioloo.reserveloop %]
1406
                                        [% ELSE %]
1407
                                            <div class="alert alert-info">
1408
                                                There are no holds on this title.
1409
                                            </div>
1332
                                            </div>
1410
                                        [% END %]
1333
                                        [% END %]
1411
1334
1335
                                    [% ELSE %]
1336
                                        [% INCLUDE holds_table.inc biblio_id=biblioloo.biblionumber total_holds=biblioloo.total_holds split_data="any"%]
1412
                                    [% END # /IF HoldsSplitQueue %]
1337
                                    [% END # /IF HoldsSplitQueue %]
1413
                                </div> <!-- /hold_title -->
1338
                                </div> <!-- /hold_title -->
1414
                            [% END # /IF biblioloo.reserveloop %]
1339
                            [% ELSE %]
1340
                                <div class="note">
1341
                                    There are no holds on this title.
1342
                                </div>
1343
                            [% END # /IF ( biblioloo.total_holds ) %]
1415
                        [% END # FOREACH biblioloo %]
1344
                        [% END # FOREACH biblioloo %]
1416
                        </div>
1345
                        </div>
1417
                    </form> <!-- /#existing_holds -->
1346
                    </form> <!-- /#existing_holds -->
Lines 1484-1489 Link Here
1484
    [% INCLUDE 'calendar.inc' %]
1413
    [% INCLUDE 'calendar.inc' %]
1485
    [% INCLUDE 'columns_settings.inc' %]
1414
    [% INCLUDE 'columns_settings.inc' %]
1486
    [% INCLUDE 'select2.inc' %]
1415
    [% INCLUDE 'select2.inc' %]
1416
    <script>
1417
        hold_table_settings = [% TablesSettings.GetTableSettings( 'circ', 'holds', 'patron_holds_table', 'json' ) | $raw %];
1418
    </script>
1487
    [% Asset.js("js/holds.js") | $raw%]
1419
    [% Asset.js("js/holds.js") | $raw%]
1488
    [% Asset.js("js/form-submit.js") | $raw%]
1420
    [% Asset.js("js/form-submit.js") | $raw%]
1489
1421
Lines 1493-1506 Link Here
1493
    [% END %]
1425
    [% END %]
1494
1426
1495
    <script>
1427
    <script>
1496
        $(document).ready(function () {
1497
            hold_table_settings = [% TablesSettings.GetTableSettings( 'circ', 'holds', 'patron_holds_table', 'json' ) | $raw %];
1498
            KohaTable("patron_holds_table", {
1499
                "bPaginate":false,
1500
                "bKohaColumnsUseNames": true,
1501
           }, hold_table_settings);
1502
        });
1503
        var biblionumbers = [[% biblionumbers.join(', ') | $raw %]];
1428
        var biblionumbers = [[% biblionumbers.join(', ') | $raw %]];
1429
        var hold_branches = {[% FOREACH biblio_info IN biblioloop %] [% biblio_info.biblionumber | html %]: ["[% biblio_info.hold_branches.join('", "') | $raw %]"], [% END %]};
1430
        var hold_itemtypes = {[% FOREACH biblio_info IN biblioloop %] [% biblio_info.biblionumber | html %]: ["[% biblio_info.hold_itemtypes.join('", "') | $raw %]"], [% END %]};
1431
        var HoldsSplitQueue = "[% Koha.Preference('HoldsSplitQueue') | html %]";
1432
        var HoldsSplitQueueNumbering = "[% Koha.Preference('HoldsSplitQueueNumbering') | html %]";
1433
        var SuspendHoldsIntranet = [% ( Koha.Preference('SuspendHoldsIntranet') ) ? 1 : 0 | html %];
1434
        var AutoResumeSuspendedHolds = [% ( Koha.Preference('AutoResumeSuspendedHolds') ) ? 1 : 0 | html %];
1435
        var AllowHoldDateInFuture = [% ( Koha.Preference('AllowHoldDateInFuture') ) ? 1 : 0 | html %];
1436
        var HidePatronName = [% ( Koha.Preference('HidePatronName') ) ? 1 : 0 | html %];
1437
        var CAN_user_reserveforothers_modify_holds_priority = [%CAN_user_reserveforothers_modify_holds_priority ? 1 : 0 | html %];
1504
        var borrowernumber = "[% patron.borrowernumber | $raw %]";
1438
        var borrowernumber = "[% patron.borrowernumber | $raw %]";
1505
        var patron_homebranch = "[% To.json( Branches.GetName( patron.branchcode ) ) | $raw %]";
1439
        var patron_homebranch = "[% To.json( Branches.GetName( patron.branchcode ) ) | $raw %]";
1506
        var override_items = {[% FOREACH biblio_info IN biblioloop %][% FOREACH itemloo IN biblio_info.itemloop %][% IF ( itemloo.override ) %]
1440
        var override_items = {[% FOREACH biblio_info IN biblioloop %][% FOREACH itemloo IN biblio_info.itemloop %][% IF ( itemloo.override ) %]
Lines 1530-1535 Link Here
1530
        $.fn.select2.defaults.set("dropdownAutoWidth", true );
1464
        $.fn.select2.defaults.set("dropdownAutoWidth", true );
1531
1465
1532
        $(document).ready(function() {
1466
        $(document).ready(function() {
1467
            biblionumbers.forEach(function(biblionumber) {
1468
                let branches = hold_branches[biblionumber];
1469
                let itemtypes = hold_itemtypes[biblionumber];
1470
                switch (HoldsSplitQueue) {
1471
                    case 'branch':
1472
                        branches.forEach(function(branch) {
1473
                            load_patron_holds_table(biblionumber, {name: HoldsSplitQueue, value: branch});
1474
                        });
1475
                        break;
1476
                    case 'itemtype':
1477
                        itemtypes.forEach(function(itemtype) {
1478
                            load_patron_holds_table(biblionumber, {name: HoldsSplitQueue, value: itemtype});
1479
                        });
1480
                        break;
1481
                    case 'branch_itemtype':
1482
                        branches.forEach(function(branch) {
1483
                            itemtypes.forEach(function(itemtype) {
1484
                                load_patron_holds_table(biblionumber, {name: HoldsSplitQueue, value: branch + '_' + itemtype});
1485
                            });
1486
                        });
1487
                        break;
1488
                    default:
1489
                        load_patron_holds_table(biblionumber, {name: 'any', value: 'any'});
1490
                }
1491
            });
1533
            $('#cancellation-reason-fieldset').hide();
1492
            $('#cancellation-reason-fieldset').hide();
1534
            $('.rank-request').on('change', function() {
1493
            $('.rank-request').on('change', function() {
1535
                if ( $(".rank-request option:selected[value='del']").length ) {
1494
                if ( $(".rank-request option:selected[value='del']").length ) {
Lines 1846-1864 Link Here
1846
            });
1805
            });
1847
1806
1848
            // Confirm cancellation of hold
1807
            // Confirm cancellation of hold
1849
            let cancel_link;
1808
            // let cancel_link;
1850
            $(".cancel-hold").on("click",function(e) {
1809
            // $(".cancel-hold").on("click",function(e) {
1851
                e.preventDefault;
1810
            //     e.preventDefault;
1852
                cancel_link = $(this);
1811
            //     cancel_link = $(this);
1853
                $("#cancel_modal_form #inputs").empty();
1812
            //     $("#cancel_modal_form #inputs").empty();
1854
                    let reserve_id = cancel_link.data('id');
1813
            //         let reserve_id = cancel_link.data('id');
1855
                    let biblionumber = cancel_link.data('biblionumber');
1814
            //         let biblionumber = cancel_link.data('biblionumber');
1856
                    $("#cancel_modal_form #inputs").append('<input type="hidden" name="reserve_id" value="' + reserve_id + '">');
1815
            //         $("#cancel_modal_form #inputs").append('<input type="hidden" name="reserve_id" value="' + reserve_id + '">');
1857
                    $("#cancel_modal_form #inputs").append('<input type="hidden" name="biblionumber" value="' + biblionumber + '">');
1816
            //         $("#cancel_modal_form #inputs").append('<input type="hidden" name="biblionumber" value="' + biblionumber + '">');
1858
                    $("#cancel_modal_form #inputs").append('<input type="hidden" name="op" value="cud-cancel">');
1817
            //         $("#cancel_modal_form #inputs").append('<input type="hidden" name="op" value="cud-cancel">');
1859
                $('#cancelModal').modal('show');
1818
            //     $('#cancelModal').modal('show');
1860
                return false;
1819
            //     return false;
1861
            });
1820
            // });
1862
1821
1863
            [% UNLESS ( patron || patron.borrowernumber || borrowers || noitems || nobiblio ) %]
1822
            [% UNLESS ( patron || patron.borrowernumber || borrowers || noitems || nobiblio ) %]
1864
                [% IF ( PatronAutoComplete ) %]
1823
                [% IF ( PatronAutoComplete ) %]
Lines 1880-1997 Link Here
1880
                localStorage.selectedHolds = [];
1839
                localStorage.selectedHolds = [];
1881
            }
1840
            }
1882
1841
1883
            $('.holds_table .select_hold').each(function() {
1884
                if(localStorage.selectedHolds.includes($(this).data('id'))) {
1885
                    $(this).prop('checked', true);
1886
                }
1887
            });
1888
1889
            $('.holds_table .select_hold_all').each(function() {
1890
                var table = $(this).parents('.holds_table');
1891
                var count = $('.select_hold:not(:checked)', table).length;
1892
                $('.select_hold_all', table).prop('checked', !count);
1893
            });
1894
1895
            $('.cancel_selected_holds').html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked').length));
1896
1897
            $('.holds_table .select_hold_all').click(function() {
1898
                var table = $(this).parents('.holds_table');
1899
                var count = $('.select_hold:checked', table).length;
1900
                $('.select_hold', table).prop('checked', !count);
1901
                $(this).prop('checked', !count);
1902
                $('.cancel_selected_holds').html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked').length));
1903
                $('#cancel_hold_alert').html( MSG_CANCEL_ALERT.format($('.holds_table .select_hold:checked').length));
1904
                $('#cancel_hold_alert').show();
1905
                localStorage.selectedHolds = $('.holds_table .select_hold:checked').toArray().map(el => $(el).data('id'));
1906
            });
1907
1908
            $('.holds_table .select_hold').click(function() {
1909
                var table = $(this).parents('.holds_table');
1910
                var count = $('.select_hold:not(:checked)', table).length;
1911
                $('.select_hold_all', table).prop('checked', !count);
1912
                $('.cancel_selected_holds').html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked').length));
1913
                $('#cancel_hold_alert').html( MSG_CANCEL_ALERT.format($('.holds_table .select_hold:checked').length));
1914
                $('#cancel_hold_alert').show();
1915
                localStorage.selectedHolds = $('.holds_table .select_hold:checked').toArray().map(el => $(el).data('id'));
1916
            });
1917
1918
            $('.cancel_selected_holds').click(function(e) {
1919
                e.preventDefault();
1920
                if($('.holds_table .select_hold:checked').length) {
1921
                    cancel_link = $(this);
1922
                    $("#cancel_modal_form #inputs").empty();
1923
                    biblionumbers.forEach( function(biblionumber){
1924
                        $("#cancel_modal_form #inputs").append('<input type="hidden" name="biblionumber" value="'+biblionumber+'">');
1925
                    });
1926
                    $("#cancel_modal_form #inputs").append('<input type="hidden" name="op" value="cud-cancel_bulk">');
1927
                    let hold_ids= $('.holds_table .select_hold:checked').toArray().map(el => $(el).data('id')).join(',');
1928
                    $("#cancel_modal_form #inputs").append('<input type="hidden" name="ids" value="' + hold_ids + '">');
1929
                    delete localStorage.selectedHolds;
1930
                    $('#cancelModal').modal('show');
1931
                }
1932
                return false;
1933
            });
1934
1935
            $(".hold-arrow").click(function(e) {
1936
                e.preventDefault();
1937
                let arrowForm = $("#hold-actions-form").attr({
1938
                    action: 'request.pl',
1939
                    method: 'post'
1940
                });
1941
                let arrow_op = $("<input />").attr({
1942
                    name: 'op',
1943
                    type: 'hidden',
1944
                    value: $(this).data('op')
1945
                });
1946
                let arrow_where = $("<input />").attr({
1947
                    name: 'where',
1948
                    type: 'hidden',
1949
                    value: $(this).data('where')
1950
                });
1951
                let arrow_fp = $("<input />").attr({
1952
                    name: 'first_priority',
1953
                    type: 'hidden',
1954
                    value: $(this).data('first_priority')
1955
                });
1956
                let arrow_lp = $("<input />").attr({
1957
                    name: 'last_priority',
1958
                    type: 'hidden',
1959
                    value: $(this).data('last_priority')
1960
                });
1961
                let arrow_pp = $("<input />").attr({
1962
                    name: 'prev_priority',
1963
                    type: 'hidden',
1964
                    value: $(this).data('prev_priority')
1965
                });
1966
                let arrow_np = $("<input />").attr({
1967
                    name: 'next_priority',
1968
                    type: 'hidden',
1969
                    value: $(this).data('next_priority')
1970
                });
1971
                let arrow_bn = $("<input />").attr({
1972
                    name: 'borrowernumber',
1973
                    type: 'hidden',
1974
                    value: $(this).data('borrowernumber')
1975
                });
1976
                let arrow_bb = $("<input />").attr({
1977
                    name: 'biblionumber',
1978
                    type: 'hidden',
1979
                    value: $(this).data('biblionumber')
1980
                });
1981
                let arrow_ri = $("<input />").attr({
1982
                    name: 'reserve_id',
1983
                    type: 'hidden',
1984
                    value: $(this).data('reserve_id')
1985
                });
1986
                let arrow_date = $("<input />").attr({
1987
                    name: 'date',
1988
                    type: 'hidden',
1989
                    value: $(this).data('date')
1990
                });
1991
                arrowForm.append(arrow_op,arrow_where,arrow_fp,arrow_lp,arrow_pp,arrow_np,arrow_bn,arrow_bb,arrow_ri,arrow_date);
1992
                $("#hold-actions-form").submit();
1993
                return true;
1994
            })
1995
        });
1842
        });
1996
</script>
1843
</script>
1997
1844
Lines 2008-2020 Link Here
2008
            });
1855
            });
2009
        </script>
1856
        </script>
2010
    [% END %]
1857
    [% END %]
2011
    <script>
2012
        $('.printholdslip').click(function(){
2013
            var reserve_id = $(this).attr('data-reserve_id');
2014
            window.open("/cgi-bin/koha/circ/hold-transfer-slip.pl?reserve_id=" + reserve_id);
2015
            return false;
2016
        })
2017
    </script>
2018
[% END %]
1858
[% END %]
2019
1859
2020
[% INCLUDE 'intranet-bottom.inc' %]
1860
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/js/holds.js (+547 lines)
Lines 498-500 $(document).ready(function() { Link Here
498
    });
498
    });
499
499
500
});
500
});
501
502
async function load_patron_holds_table(biblio_id, split_data) {
503
    const { name: split_name, value: split_value } = split_data;
504
    const table_id = `#patron_holds_table_${biblio_id}_${split_value}`;
505
    hold_table_settings.table = `patron_holds_table_${biblio_id}_${split_data.value}`;
506
    let url = `/api/v1/holds/?q={"me.biblio_id":${biblio_id}`;
507
508
    if (split_name === 'branch' && split_value !== 'any') {
509
        url += `, "me.pickup_library_id":"${split_value}"`;
510
    } else if (split_name === 'itemtype' && split_value !== 'any') {
511
        url += `, "me.itemtype":"${split_value}"`;
512
    } else if (split_name === 'branch_itemtype') {
513
        const [branch, itemtype] = split_value.split('_');
514
        url += itemtype === 'any' 
515
            ? `, "me.pickup_library_id":"${branch}"`
516
            : `, "me.pickup_library_id":"${branch}", "me.itemtype":"${itemtype}"`;
517
    }
518
519
    url += '}';
520
    const totalHolds = $(table_id).data('total-holds');
521
    const totalHoldsSelect = parseInt(totalHolds)+1;
522
    let pageStart;
523
    var holdsQueueTable = $(table_id).kohaTable({
524
        ajax: {
525
            url: url,
526
            data: function (params) {
527
                pageStart = params.start;
528
                var query = {
529
                    "_per_page": params.length,
530
                    "_page": params.start / params.length + 1,
531
                    "_order_by": "priority",
532
                    "_match": "exact"
533
                };  
534
                return query;
535
            },
536
        },
537
        embed: ['patron', 'item', 'item_group'],
538
        columnDefs: [
539
            {
540
                targets: [2, 3],
541
                className: 'dt-body-nowrap'
542
            },
543
            {
544
                targets: [3, 9],
545
                visible: CAN_user_reserveforothers_modify_holds_priority ? true : false
546
            },
547
548
        ],
549
        columns: [
550
            {   
551
                data: "hold_id",
552
                orderable: false,
553
                searchable: false,
554
                render: function( data, type, row, meta ) {
555
                    return '<input type="checkbox" class="select_hold" data-id="'+data+'"/>';
556
                }
557
            },
558
            {
559
                data: "priority",
560
                orderable: false,
561
                searchable: false,
562
                render: function(data, type, row, meta) {
563
                    let select = '<select name="rank-request" class="rank-request" data-id="'+row.hold_id;
564
                    if(CAN_user_reserveforothers_modify_holds_priority && split_name == 'any') {
565
                        for ( var i=0; i < totalHoldsSelect; i++ ){
566
                            let selected;
567
                            let value;
568
                            let desc;
569
                            if (data == i && row.status == 'T') {
570
                                select += '" disabled="disabled">';
571
                                selected = " selected='selected' ";
572
                                value = 'T';
573
                                desc = 'In transit';
574
                            } else if (data == i && row.status == 'P') {
575
                                select += '" disabled="disabled">';
576
                                selected = " selected='selected' ";
577
                                value = 'P';
578
                                desc = 'In processing';
579
                            } else if (data == i && row.status == 'W'){
580
                                select += '" disabled="disabled">';
581
                                selected = " selected='selected' ";
582
                                value = 'W';
583
                                desc = 'Waiting';
584
                            } else if (data == i && !row.status) {
585
                                select += '">';
586
                                selected = " selected='selected' ";
587
                                value = data;
588
                                desc = data;
589
                            } else {
590
                                if (i != 0) {
591
                                    select += '">';
592
                                    value = i;
593
                                    desc = i;
594
                                } else {
595
                                    select += '">';
596
                                }
597
                            }
598
                            if (value) {
599
                                select += '<option value="'+ value +'"'+selected+'>'+desc+'</option>';
600
                            }
601
                        }
602
                    }else {
603
                        if (row.status == 'T') {
604
                            select += '" disabled="disabled"><option value="T" selected="selected">In transit</option></select>';
605
                        } else if (row.status == 'P') {
606
                            select += '" disabled="disabled"><option value="P" selected="selected">In processing</option></select>';
607
                        } else if (row.status == 'W') {
608
                            select += '" disabled="disabled"><option value="W" selected="selected">Waiting</option></select>';
609
                        } else {
610
                            if (HoldsSplitQueue !== "nothing" && HoldsSplitQueueNumbering === 'virtual') {
611
                                let virtualPriority = pageStart + meta.row + 1;
612
                                select += '" disabled="disabled"><option value="'+ data +'" selected="selected">'+ virtualPriority +'</option></select>';
613
                            } else {
614
                                select += '" disabled="disabled"><option value="'+ data +'" selected="selected">'+ data +'</option></select>';
615
                            }
616
                        }
617
                    }
618
                    select += '</select>';
619
                    return select;
620
                }
621
            },
622
            {
623
                data: "",
624
                orderable: false,
625
                searchable: false,
626
                render: function(data, type, row, meta) {
627
                    if (row.status) {
628
                        return null;
629
                    }
630
                    let buttons = '<a class="hold-arrow move-hold" title="Move hold up" href="#" data-move-hold="up" data-priority="'+row.priority+'" reserve_id="'+row.hold_id+'"><i class="fa fa-lg icon-move-hold-up" aria-hidden="true"></i></a>';
631
                    buttons += '<a class="hold-arrow move-hold" title="Move hold to top" href="#" data-move-hold="top" data-priority="'+row.priority+'" reserve_id="'+row.hold_id+'"><i class="fa fa-lg icon-move-hold-top" aria-hidden="true"></i></a>';
632
                    buttons += '<a class="hold-arrow move-hold" title="Move hold to bottom" href="#" data-move-hold="bottom" data-priority="'+row.priority+'" reserve_id="'+row.hold_id+'"><i class="fa fa-lg icon-move-hold-bottom" aria-hidden="true"></i></a>';
633
                    buttons += '<a class="hold-arrow move-hold" title="Move hold down" href="#" data-move-hold="down" data-priority="'+row.priority+'" reserve_id="'+row.hold_id+'"><i class="fa fa-lg icon-move-hold-down" aria-hidden="true"></i></a>';
634
                    return buttons;
635
                }
636
            },
637
            {
638
                data: "patron.cardnumber",
639
                orderable: false,
640
                searchable: true,
641
                render: function(data, type, row, meta) {
642
                    if(data == null) {
643
                        let library = libraries.find(library => library._id == row.pickup_library_id);
644
                        return __("A patron from library %s").format(library.name);
645
                    } else {
646
                        return '<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber='+row.patron.patron_id+'">'+data+'</a>';
647
                    }
648
                }
649
            },
650
            {
651
                data: "notes", 
652
                orderable: false,
653
                searchable: false,
654
                render: function(data, type, row, meta) {
655
                    return data;
656
                }
657
            },
658
            {
659
                data: "hold_date",
660
                orderable: false,
661
                searchable: false,
662
                render: function(data, type, row, meta) {
663
                    if (AllowHoldDateInFuture) {
664
                        return '<input type="text" class="holddate" value="'+$date(data, {dateformat:"rfc3339"})+'" size="10" name="hold_date" data-id="'+row.hold_id+'" data-current-date="'+data+'"/>';
665
                    } else {
666
                        return $date(data);
667
                    }
668
                }
669
            },
670
            {
671
                data: "expiration_date",
672
                orderable: false,
673
                searchable: false,
674
                render: function(data, type, row, meta) {
675
                    return '<input type="text" class="expirationdate" value="'+$date(data, {dateformat:"rfc3339"})+'" size="10" name="expiration_date" data-id="'+row.hold_id+'" data-current-date="'+data+'"/>';
676
                }
677
            },
678
            {
679
                data: "pickup_library_id",
680
                orderable: false,
681
                searchable: false,
682
                render: function(data, type, row, meta) {
683
                    var branchSelect='<select priority='+row.priority+' class="hold_location_select" data-id="'+row.hold_id+'" reserve_id="'+row.hold_id+'" name="pick-location" data-pickup-location-source="hold">';
684
                    var libraryname;
685
                    for ( var i=0; i < libraries.length; i++ ){
686
                        var selectedbranch;
687
                        var setbranch;
688
                        if( libraries[i]._id == data ){
689
                            selectedbranch = " selected='selected' ";
690
                            setbranch = __(" (current) ");
691
                            libraryname = libraries[i]._str;
692
                        } else if ( libraries[i].pickup_location == false ) {
693
                            continue;
694
                        } else{
695
                            selectedbranch = '';
696
                            setbranch = '';
697
                        }
698
                        branchSelect += '<option value="'+ libraries[i]._id.escapeHtml() +'"'+selectedbranch+'>'+libraries[i]._str.escapeHtml()+setbranch+'</option>';
699
                    }
700
                    branchSelect +='</select>';
701
                    if ( row.status == 'T' ) {
702
                        return __("Item being transferred to <strong>%s</strong>").format(libraryname);
703
                    } else if (row.status == 'P') {
704
                        return __("Item being processed at <strong>%s</strong>").format(libraryname);
705
                    }
706
                    else if (row.status == 'W') {
707
                        return __("Item waiting at <strong>%s</strong> since %s").format(libraryname, $date(row.waiting_date));
708
                    } else {
709
                        return branchSelect;
710
                    }
711
                }
712
            },
713
            {
714
                data: "",
715
                orderable: false,
716
                searchable: false,
717
                render: function(data, type, row, meta) {
718
                    if (row.item_id) {
719
                        return '<a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber='+row.biblio_id+'&itemnumber='+row.item_id+'">'+row.item.external_id+'</a>'
720
                    } else if (row.item_group_id) {
721
                        return __("Next available item from group <strong>%s</strong>").format( row.item_group.description );
722
                    } else {
723
                        if (row.non_priority) {
724
                            return '<em>'+__("Next available")+'</em><br/><i>'+__("Non priority hold")+'</i>';
725
                        } else {
726
                            return '<em>'+__("Next available")+'</em>';
727
                        }
728
                    }
729
                }
730
            },
731
            {
732
                data: "",
733
                orderable: false,
734
                searchable: false,
735
                render: function(data, type, row, meta) {
736
                    if (row.item_id) {
737
                        return null
738
                    } else {
739
                        if(row.lowest_priority){
740
                            return '<a class="hold-arrow toggle-lowest-priority" title="Remove lowest priority" href="#" data-op="cud-setLowestPriority" data-borrowernumber="'+ row.patron_id +'" data-biblionumber="'+ biblio_id +'" data-reserve_id="'+ row.hold_id +'" data-date="'+ row.hold_date +'"><i class="fa fa-lg fa-rotate-90 icon-unset-lowest" aria-hidden="true"></i></a>';
741
                        } else {
742
                            return '<a class="hold-arrow toggle-lowest-priority" title="Set lowest priority" href="#" data-op="cud-setLowestPriority" data-borrowernumber="'+ row.patron_id +'" data-biblionumber="'+ biblio_id +'" data-reserve_id="'+ row.hold_id +'" data-date="'+ row.hold_date +'"><i class="fa fa-lg fa-rotate-90 icon-set-lowest" aria-hidden="true"></i></a>';
743
                        }
744
                    }
745
                }
746
            },
747
            {
748
                data: "hold_id",
749
                orderable: false,
750
                searchable: false,
751
                render: function(data, type, row, meta) {
752
                    return '<a class="cancel-hold" title="Cancel hold" reserve_id="'+data+'" href="#"><i class="fa fa-trash" aria-label="Cancel hold"></i></a>';
753
                }
754
            },
755
            {
756
                data: "hold_id",
757
                orderable: false,
758
                searchable: false,
759
                render: function(data, type, row, meta) {
760
                    if (row.status) {
761
                        var link_value = row.status == 'T' ? __("Revert transit status") : __("Revert waiting status");
762
                        return '<a class="btn btn-default submit-form-link" href="#" id="revert_hold_'+data+'" data-op="cud-move" data-where="down" data-first_priority="1" data-last_priority="'+ totalHolds +'" data-prev_priority="0" data-next_priority="1" data-borrowernumber="'+ row.patron_id +'" data-biblionumber="'+ biblio_id +'" data-itemnumber="'+ row.item_id +'" data-reserve_id="'+ row.hold_id +'" data-date="'+ row.hold_date +'" data-action="request.pl" data-method="post">'+ link_value +'</a>';
763
                    } else {
764
                        let td = '';
765
                        if (SuspendHoldsIntranet) {
766
                            td += '<button class="btn btn-default btn-xs toggle-suspend" data-id="'+data+'" data-biblionumber="'+biblio_id+'" data-suspended="'+row.suspended+'">'
767
                            if ( row.suspended ) {
768
                                td += '<i class="fa fa-play" aria-hidden="true"></i> '+__("Resume")+'</button>';
769
                            } else {
770
                                td += '<i class="fa fa-pause" aria-hidden="true"></i> '+__("Suspend")+'</button>';
771
                            }
772
                            if (AutoResumeSuspendedHolds) {
773
                                if (row.suspended) {
774
                                    td += '<label for="suspend_until_'+data+'">'+__("Suspend on")+' </label>';
775
                                } else {
776
                                    td += '<label for="suspend_until_'+data+'">'+__("Suspend until")+' </label>';
777
                                }
778
                                td += '<input type="text" name="suspend_until_'+data+'" data-id="'+data+'" size="10" value="'+$date(row.suspended_until, {dateformat:"rfc3339"})+'" class="suspenddate" data-flatpickr-futuredate="true" data-suspend-date="'+row.suspended_until+'" />';
779
                            }
780
                            return td;
781
                        } else {
782
                            return null;
783
                        }
784
                    }
785
                }
786
            },
787
            {
788
                data: "hold_id",
789
                orderable: false,
790
                searchable: false,
791
                render: function(data, type, row, meta) {
792
                    if (row.status == 'W' || row.status == 'T') {
793
                        return '<a class="btn btn-default btn-xs printholdslip" data-reserve_id="'+data+'">'+__("Print slip")+'</a>';
794
                    } else {
795
                        return '';
796
                    }
797
                }
798
            },
799
        ]
800
    },hold_table_settings);
801
    $(table_id).on( 'draw.dt', function () {
802
        // Remove the search box. Don't know why it isn't working in the table settings
803
        $(this).parent().find(".pager .table_controls .dt-search").remove();
804
        $(this).parent().find(".pager .table_controls .dt-buttons .dt_button_clear_filter").remove();
805
        var MSG_CANCEL_SELECTED = _("Cancel selected (%s)");
806
        $('.cancel_selected_holds').html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked').length));
807
        $('.holds_table .select_hold').each(function() {
808
            if(localStorage.selectedHolds && localStorage.selectedHolds.includes($(this).data('id'))) {
809
                $(this).prop('checked', true);
810
            }
811
        });
812
        $('.holds_table .select_hold_all').on("click",function() {
813
            var table = $(this).parents('.holds_table');
814
            var count = $('.select_hold:checked', table).length;
815
            $('.select_hold', table).prop('checked', !count);
816
            $(this).prop('checked', !count);
817
            $(this).parent().parent().toggleClass('selected');
818
            $('.cancel_selected_holds').html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked').length));
819
            localStorage.selectedHolds = $('.holds_table .select_hold:checked').toArray().map(el => $(el).data('id'));
820
821
        });
822
        $('.holds_table .select_hold').on("click", function() {
823
            var table = $(this).parents('.holds_table');
824
            var count = $('.select_hold:not(:checked)', table).length;
825
            $('.select_hold_all', table).prop('checked', !count);
826
            $(this).parent().parent().toggleClass('selected');
827
            $('.cancel_selected_holds').html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked').length));
828
            localStorage.selectedHolds = $('.holds_table .select_hold:checked').toArray().map(el => $(el).data('id'));
829
        });
830
        $(".cancel-hold").on("click",function(e) {
831
            e.preventDefault;
832
            var res_id = $(this).attr('reserve_id');
833
            $('.select_hold').prop('checked', false);
834
            $('.select_hold_all').prop('checked', false);
835
            $('.cancel_selected_holds').html(MSG_CANCEL_SELECTED.format(0));
836
            $('#cancelModal').modal('show').find('#cancelModalConfirmBtn').attr("data-id", res_id);
837
            delete localStorage.selectedHolds;
838
        });
839
        $('.cancel_selected_holds').on("click", function(e) {
840
            e.preventDefault();
841
            if($('.holds_table .select_hold:checked').length) {
842
                delete localStorage.selectedHolds;
843
                $('#cancelModal').modal('show');
844
            }
845
            return false;
846
        });
847
        // Remove any previously attached handlers
848
        $("#cancelModalConfirmBtn").off("click");
849
        // Attach the handler to the button
850
        $("#cancelModalConfirmBtn").one("click",function(e) {
851
            e.preventDefault();
852
            let hold_ids;
853
            const hold_id = $('#cancelModal').modal('show').find('#cancelModalConfirmBtn').attr("data-id");
854
            let reason = $("#modal-cancellation-reason").val();
855
            if (hold_id) {
856
                hold_ids = [hold_id];
857
            } else {
858
                hold_ids = $('.holds_table .select_hold:checked').toArray().map(el => $(el).data('id'));
859
            }
860
            $('#cancelModal').find('.modal-footer #cancelModalConfirmBtn').before('<img src="/intranet-tmpl/prog/img/spinner-small.gif" alt="" style="padding-right: 10px;"/>');
861
            deleteHolds(hold_ids, reason);
862
            $('#cancelModal').modal('show').find('#cancelModalConfirmBtn').attr("data-id", "");
863
            
864
        });
865
        async function deleteHolds (hold_ids, reason) {
866
            for (const hold_id of hold_ids) {
867
                await deleteHold(hold_id, reason);
868
                $('#cancelModal').find('.modal-body').append('<p class="hold-cancelled">'+__("Hold")+' '+hold_id+' '+__("cancelled")+'</p>');
869
                await new Promise(resolve => setTimeout(resolve, 1000));
870
            }
871
872
            holdsQueueTable.api().ajax.reload(null, false);
873
            setTimeout(() => {
874
                $('#cancelModal').modal('hide');
875
                $('#cancelModal').find('.modal-footer #cancelModalConfirmBtn').prev('img').remove();
876
                $('#cancelModal').find('.modal-body').find('.hold-cancelled').remove();
877
            });
878
        }
879
        async function deleteHold(hold_id, reason) {
880
            try {
881
                await $.ajax({
882
                    method: "DELETE",
883
                    url: '/api/v1/holds/' + encodeURIComponent(hold_id),
884
                    data: JSON.stringify(reason),
885
                });
886
            } catch (error) {
887
                console.error("Error when deleting hold: " + hold_id);
888
            }
889
        }
890
        $(".holddate, .expirationdate").flatpickr({
891
            onReady: function(selectedDates, dateStr, instance) {
892
                $(instance.altInput)
893
                    .wrap("<span class='flatpickr_wrapper'></span>")
894
                    .after($("<a/>")
895
                        .attr("href", "#")
896
                        .addClass("clear_date")
897
                        .addClass("fa fa-times")
898
                        .addClass("ps-2")
899
                        .on("click", function(e) {
900
                            e.preventDefault();
901
                            instance.clear();
902
                        })
903
                        .attr("aria-hidden", true)
904
                    );
905
            },
906
            onChange: function (selectedDates, dateStr, instance){
907
                let hold_id = $(instance.input).attr('data-id');
908
                let fieldname = $(instance.input).attr('name');
909
                let current_date = $(instance.input).attr('data-current-date');
910
                dateStr = dateStr ? dateStr : null;
911
                let req = fieldname == "hold_date" ? { "hold_date": dateStr } : { "expiration_date": dateStr };
912
                if (current_date != dateStr) {
913
                    $.ajax({
914
                        method: "PATCH",
915
                        url: '/api/v1/holds/' + encodeURIComponent(hold_id),
916
                        contentType: 'application/json',
917
                        data: JSON.stringify(req),
918
                        success: function( data ){ holdsQueueTable.api().ajax.reload(null, false); },
919
                        error: function( jqXHR, textStatus, errorThrown) {
920
                            holdsQueueTable.api().ajax.reload(null, false);
921
                        },
922
                    });
923
                }
924
            }
925
        });
926
        $(".suspenddate").flatpickr({
927
            onReady: function(selectedDates, dateStr, instance) {
928
                $(instance.altInput)
929
                    .wrap("<span class='flatpickr_wrapper'></span>")
930
                    .after($("<a/>")
931
                        .attr("href", "#")
932
                        .addClass("clear_date")
933
                        .addClass("fa fa-times")
934
                        .addClass("ps-2")
935
                        .on("click", function(e) {
936
                            e.preventDefault();
937
                            instance.clear();
938
                        })
939
                        .attr("aria-hidden", true)
940
                    );
941
            },
942
        });
943
        $(".toggle-suspend").one("click",function(e) {
944
            e.preventDefault();
945
            const hold_id = $(this).data('id');
946
            const suspended = $(this).attr('data-suspended');
947
            const input = $(`.suspenddate[data-id="${hold_id}"]`);
948
            const method = suspended == 'true' ? 'DELETE' : 'POST';
949
            let end_date = input.val() && method == 'POST' ? input.val() : null;
950
            let params = (end_date !== null && end_date !== '') ? JSON.stringify({ "end_date": end_date }) : null;
951
            $.ajax({
952
                method: method,
953
                url: '/api/v1/holds/' + encodeURIComponent(hold_id) +'/suspension',
954
                contentType: 'application/json',
955
                data: params,
956
                success: function( data ){ 
957
                    holdsQueueTable.api().ajax.reload(null, false); 
958
                },
959
                error: function( jqXHR, textStatus, errorThrown) {
960
                    holdsQueueTable.api().ajax.reload(null, false);
961
                    alert('There was an error:'+textStatus+" "+errorThrown);
962
                },
963
            });
964
        });
965
        $(".rank-request").on("change", function(e){
966
            e.preventDefault();
967
            const hold_id = $(this).data('id');
968
            let priority = e.target.value;
969
            $.ajax({
970
                method: "PUT",
971
                url: '/api/v1/holds/' + encodeURIComponent(hold_id) +'/priority',
972
                data: JSON.stringify(priority),
973
                success: function( data ){ holdsQueueTable.api().ajax.reload(null, false); },
974
                error: function( jqXHR, textStatus, errorThrown) {
975
                    alert('There was an error:'+textStatus+" "+errorThrown);
976
                },
977
            });
978
        });
979
        $(".move-hold").one("click", function(e){
980
            e.preventDefault();
981
            let toPosition = $(this).attr('data-move-hold');
982
            let priority = $(this).attr('data-priority');
983
            var res_id = $(this).attr('reserve_id');
984
            var moveTo;
985
            if (toPosition == 'up'){
986
                moveTo = parseInt(priority)-1;
987
            }
988
            if (toPosition == 'down'){
989
                moveTo = parseInt(priority)+1;
990
            }
991
            if (toPosition == 'top'){
992
                moveTo = 1;
993
            }
994
            if (toPosition == 'bottom'){
995
                moveTo = totalHolds;
996
            }
997
            $.ajax({
998
                method: "PUT",
999
                url: '/api/v1/holds/' + encodeURIComponent(res_id) +'/priority',
1000
                data: JSON.stringify(moveTo),
1001
                success: function( data ){
1002
                    holdsQueueTable.api().ajax.reload(null, false);
1003
                },
1004
                error: function( jqXHR, textStatus, errorThrown) {
1005
                    alert('There was an error:'+textStatus+" "+errorThrown);
1006
                },
1007
            });
1008
        });
1009
        $(".toggle-lowest-priority").one("click", function(e){
1010
            e.preventDefault();
1011
            var res_id = $(this).attr('data-reserve_id');
1012
            $.ajax({
1013
                method: "PUT",
1014
                url: '/api/v1/holds/' + encodeURIComponent(res_id) +'/lowest_priority',
1015
                success: function( data ){ holdsQueueTable.api().ajax.reload(null, false); },
1016
                error: function( jqXHR, textStatus, errorThrown) {
1017
                    alert('There was an error:'+textStatus+" "+errorThrown);
1018
                },
1019
            });
1020
        });
1021
        $(".hold_location_select").on("change", function(){
1022
            $(this).prop("disabled",true);
1023
            var cur_select = $(this);
1024
            var res_id = $(this).attr('reserve_id');
1025
            $(this).after('<div id="updating_reserveno'+res_id+'" class="waiting"><img src="/intranet-tmpl/prog/img/spinner-small.gif" alt="" /><span class="waiting_msg"></span></div>');
1026
            let api_url = '/api/v1/holds/' + encodeURIComponent(res_id) + '/pickup_location';
1027
            $.ajax({
1028
                method: "PUT",
1029
                url: api_url,
1030
                data: JSON.stringify({ "pickup_library_id": $(this).val() }),
1031
                headers: { "x-koha-override": "any" },
1032
                success: function( data ){ holdsQueueTable.api().ajax.reload(null, false); },
1033
                error: function( jqXHR, textStatus, errorThrown) {
1034
                    alert('There was an error:'+textStatus+" "+errorThrown);
1035
                    cur_select.prop("disabled",false);
1036
                    $("#updating_reserveno"+res_id).remove();
1037
                    cur_select.val( cur_select.children('option[selected="selected"]').val() );
1038
                },
1039
            });
1040
        });
1041
        $('.printholdslip').one('click', function(){
1042
            var reserve_id = $(this).attr('data-reserve_id');
1043
            window.open("/cgi-bin/koha/circ/hold-transfer-slip.pl?reserve_id=" + reserve_id);
1044
            return false;
1045
        });
1046
    });
1047
}
(-)a/reserve/request.pl (-54 / +27 lines)
Lines 603-608 if ( ( $findborrower && $borrowernumber_hold || $findclub && $club_hold ) Link Here
603
603
604
        # existingreserves building
604
        # existingreserves building
605
        my @reserveloop;
605
        my @reserveloop;
606
        my $total_holds = 0;
607
        my $hold_branches = [];
608
        my $hold_itemtypes = [];
606
        my $always_show_holds = $input->cookie('always_show_holds');
609
        my $always_show_holds = $input->cookie('always_show_holds');
607
        $template->param( always_show_holds => $always_show_holds );
610
        $template->param( always_show_holds => $always_show_holds );
608
        my $show_holds_now = $input->param('show_holds_now');
611
        my $show_holds_now = $input->param('show_holds_now');
Lines 618-678 if ( ( $findborrower && $borrowernumber_hold || $findclub && $club_hold ) Link Here
618
                    )->unblessed
621
                    )->unblessed
619
                }
622
                }
620
            };
623
            };
621
            my @reserves = Koha::Holds->search( { biblionumber => $biblionumber }, { order_by => 'priority' } )->as_list;
624
            $total_holds = Koha::Holds->search( { biblionumber => $biblionumber } )->count;
622
            foreach my $res (
625
            my $branches = Koha::Holds->search(
623
                sort {
626
                {
624
                    my $a_found = $a->found() || '';
627
                    biblionumber => $biblionumber,
625
                    my $b_found = $a->found() || '';
628
                },
626
                    $a_found cmp $b_found;
629
                {
627
                } @reserves
630
                    select   => [ { distinct => 'branchcode' } ],
628
              )
631
                    as       => [qw( branchcode )],
629
            {
630
                my %reserve;
631
                if ( $res->is_found() ) {
632
                    $reserve{'holdingbranch'} = $res->item()->holdingbranch();
633
                    $reserve{'biblionumber'}  = $res->item()->biblionumber();
634
                    $reserve{'barcodenumber'} = $res->item()->barcode();
635
                    $reserve{'wbrcode'}       = $res->branchcode();
636
                    $reserve{'itemnumber'}    = $res->itemnumber();
637
                    $reserve{'wbrname'}       = $res->branch()->branchname();
638
                    $reserve{'atdestination'} = $res->is_at_destination();
639
                    $reserve{'desk_name'}     = ( $res->desk() ) ? $res->desk()->desk_name() : '' ;
640
                    $reserve{'found'}     = $res->is_found();
641
                    $reserve{'inprocessing'} = $res->is_in_processing();
642
                    $reserve{'intransit'} = $res->is_in_transit();
643
                }
644
                elsif ( $res->priority() > 0 ) {
645
                    if ( my $item = $res->item() )  {
646
                        $reserve{'itemnumber'}      = $item->id();
647
                        $reserve{'barcodenumber'}   = $item->barcode();
648
                        $reserve{'item_level_hold'} = 1;
649
                    }
650
                }
632
                }
651
                $reserve{'expirationdate'} = $res->expirationdate;
633
            )->unblessed;
652
                $reserve{'date'}           = $res->reservedate;
634
            $hold_branches = [ map { $_->{branchcode} } @$branches ];
653
                $reserve{'borrowernumber'} = $res->borrowernumber();
635
            my $itemtypes = Koha::Holds->search(
654
                $reserve{'biblionumber'}   = $res->biblionumber();
636
                {
655
                $reserve{'patron'}         = $res->borrower;
637
                    biblionumber => $biblionumber,
656
                $reserve{'notes'}          = $res->reservenotes();
638
                },
657
                $reserve{'waiting_date'}   = $res->waitingdate();
639
                {
658
                $reserve{'ccode'}          = $res->item() ? $res->item()->ccode() : undef;
640
                    select   => [ { distinct => 'itemtype' } ],
659
                $reserve{'barcode'}        = $res->item() ? $res->item()->barcode() : undef;
641
                    as       => [qw( itemtype )],
660
                $reserve{'priority'}       = $res->priority();
661
                $reserve{'lowestPriority'} = $res->lowestPriority();
662
                $reserve{'suspend'}        = $res->suspend();
663
                $reserve{'suspend_until'}  = $res->suspend_until();
664
                $reserve{'reserve_id'}     = $res->reserve_id();
665
                $reserve{itemtype}         = $res->itemtype();
666
                $reserve{branchcode}       = $res->branchcode();
667
                $reserve{non_priority}     = $res->non_priority();
668
                $reserve{object}           = $res;
669
670
                if ( $holds_count_per_patron->{ $reserve{'borrowernumber'} } == 1 ) {
671
                    $reserve{'change_hold_type_allowed'} = 1;
672
                }
642
                }
673
643
            )->unblessed;
674
                push( @reserveloop, \%reserve );
644
            $hold_itemtypes = [ map { $_->{itemtype} ? $_->{itemtype} : 'any' } @$itemtypes ];
675
            }
676
        }
645
        }
677
646
678
        # get the time for the form name...
647
        # get the time for the form name...
Lines 700-710 if ( ( $findborrower && $borrowernumber_hold || $findclub && $club_hold ) Link Here
700
        $biblioloopiter{author} = $biblio->author;
669
        $biblioloopiter{author} = $biblio->author;
701
        $biblioloopiter{rank} = $fixedRank;
670
        $biblioloopiter{rank} = $fixedRank;
702
        $biblioloopiter{reserveloop} = \@reserveloop;
671
        $biblioloopiter{reserveloop} = \@reserveloop;
672
        $biblioloopiter{total_holds} = $total_holds;
673
        $biblioloopiter{hold_branches} = $hold_branches;
674
        $biblioloopiter{hold_itemtypes} = $hold_itemtypes;
703
675
704
        if (@reserveloop) {
676
        if (@reserveloop) {
705
            $template->param( reserveloop => \@reserveloop );
677
            $template->param( reserveloop => \@reserveloop );
706
        }
678
        }
707
679
680
        $template->param( total_holds => $total_holds );
681
708
        if ( $patron && $multi_hold ) {
682
        if ( $patron && $multi_hold ) {
709
            # Add the valid pickup locations
683
            # Add the valid pickup locations
710
            my @pickup_locations = $biblio->pickup_locations({ patron => $patron })->as_list;
684
            my @pickup_locations = $biblio->pickup_locations({ patron => $patron })->as_list;
711
- 

Return to bug 23269