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

(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (-1961 lines)
Lines 1-1960 Link Here
1
[% USE raw %]
2
[% USE To %]
3
[% USE Asset %]
4
[% USE JSON.Escape %]
5
[% USE Koha %]
6
[% USE Biblio %]
7
[% USE KohaDates %]
8
[% USE Branches %]
9
[% USE Categories %]
10
[% USE ItemTypes %]
11
[% USE AuthorisedValues %]
12
[% USE Price %]
13
[% USE TablesSettings %]
14
[% SET reserve_input_type = 'radio' %]
15
[% IF ( Koha.Preference('DisplayMultiItemHolds') ) %]
16
    [% SET reserve_input_type = 'checkbox' %]
17
[% END %]
18
[% PROCESS 'i18n.inc' %]
19
[% SET footerjs = 1 %]
20
[% INCLUDE 'doc-head-open.inc' %]
21
[% SET libraries = Branches.all %]
22
[% SET categories = Categories.all.unblessed %]
23
[% SET columns = ['name', 'cardnumber', 'dateofbirth', 'category', 'branch', 'address', 'phone'] %]
24
[% PROCESS "patron-search.inc" %]
25
<title
26
    >[% FILTER collapse %]
27
        [% UNLESS ( multi_hold ) %]
28
            [% title_in_title = INCLUDE 'biblio-title-head.inc' %]
29
            [% tx("Place a hold on {title}", { title = title_in_title }) | html %]
30
            &rsaquo;
31
        [% ELSE %]
32
            [% t("Confirm holds") | html %]
33
            &rsaquo;
34
        [% END %]
35
        [% t("Holds") | html %]
36
        &rsaquo; [% t("Circulation") | html %] &rsaquo; [% t("Koha") | html %]
37
    [% END %]</title
38
>
39
[% INCLUDE 'doc-head-close.inc' %]
40
[% FILTER collapse %]
41
    <style>
42
        a.hold-arrow {
43
            display: inline-block;
44
            padding: 3px;
45
        }
46
        a.hold-arrow:link,
47
        a.hold-arrow:visited {
48
            color: #538200;
49
        }
50
51
        a.hold-arrow:hover,
52
        a.hold-arrow:active {
53
            color: #75b700;
54
        }
55
56
        .hold-arrow:hover i,
57
        .hold-arrow:active i {
58
            border-color: #75b700;
59
        }
60
61
        a.cancel-hold {
62
            display: inline-block;
63
            padding: 3px;
64
        }
65
66
        a.cancel-hold:link,
67
        a.cancel-hold:visited {
68
            color: #c00;
69
            font-size: 130%;
70
        }
71
72
        .icon-move-hold-up::before {
73
            content: "\f062";
74
        }
75
76
        .icon-move-hold-top {
77
            border-top: 2px solid #538200;
78
            display: inline;
79
        }
80
81
        .icon-move-hold-top::before {
82
            content: "\f062";
83
        }
84
85
        .icon-move-hold-bottom {
86
            border-bottom: 2px solid #538200;
87
            display: inline;
88
        }
89
90
        .icon-move-hold-bottom::before {
91
            content: "\f063";
92
        }
93
94
        .icon-move-hold-down::before {
95
            content: "\f063";
96
        }
97
98
        .icon-unset-lowest::before {
99
            content: "\f050";
100
        }
101
102
        .icon-set-lowest::before {
103
            content: "\f04e";
104
        }
105
        :disabled {
106
            opacity: 0.5;
107
        }
108
    </style>
109
[% END %]
110
</head>
111
112
<body id="circ_request" class="catalog">
113
114
[% WRAPPER 'header.inc' %]
115
    [% INCLUDE 'circ-search.inc' %]
116
[% END %]
117
118
[% WRAPPER 'sub-header.inc' %]
119
    [% WRAPPER breadcrumbs %]
120
        [% WRAPPER breadcrumb_item %]
121
            <a href="/cgi-bin/koha/catalogue/search.pl">Catalog</a>
122
        [% END %]
123
        [% UNLESS ( multi_hold ) %]
124
            [% WRAPPER breadcrumb_item %]
125
                [% INCLUDE 'biblio-title.inc' link =1 %]
126
            [% END %]
127
            [% WRAPPER breadcrumb_item bc_active= 1 %]
128
                <span>Place a hold</span>
129
            [% END %]
130
        [% ELSE %]
131
            [% IF ( patron ) %]
132
                [% WRAPPER breadcrumb_item bc_active= 1 %]
133
                    <span>Place holds</span>
134
                [% END %]
135
            [% ELSE %]
136
                [% IF clubcount %]
137
                    [% WRAPPER breadcrumb_item bc_active= 1 %]
138
                        <span>Search patrons or clubs</span>
139
                    [% END %]
140
                [% ELSE %]
141
                    [% WRAPPER breadcrumb_item bc_active= 1 %]
142
                        <span>Search patrons</span>
143
                    [% END %]
144
                [% END %]
145
            [% END %]
146
        [% END # UNLESS multi_hold %]
147
    [% END #/ WRAPPER breadcrumbs %]
148
[% END #/ WRAPPER sub-header.inc %]
149
150
[%# No sidebar menu when placing multiple holds or biblio not found %]
151
[% SET aside = (multi_hold || nobiblio) ? '' : 'biblio-view-menu' %]
152
[% WRAPPER 'main-container.inc' aside=aside wide_centered=1 %]
153
    <h1>Holds</h1>
154
155
    [% IF ( nobiblio ) %]
156
        <div class="alert alert-warning">
157
            [% IF (multi_hold) %]
158
                <strong>Cannot place hold:</strong> one or more records don't exist.
159
            [% ELSE %]
160
                <strong>Cannot place hold:</strong> this record doesn't exist.
161
            [% END %]
162
        </div>
163
    [% END %]
164
    [% IF ( noitems ) %]
165
        <div class="alert alert-warning">
166
            [% IF (multi_hold) %]
167
                <strong>Cannot place hold:</strong> one or more records without items attached.
168
            [% ELSE %]
169
                <strong>Cannot place hold:</strong> this record has no items attached.
170
            [% END %]
171
        </div>
172
    [% END %]
173
174
    [% IF ( failed_holds ) %]
175
        <div class="alert alert-warning">
176
            <strong>One or more holds were not placed due to following errors:</strong>
177
            <ul>
178
                [% FOREACH fail IN failed_holds %]
179
                    <li>
180
                        [% SWITCH fail %]
181
                        [% CASE 'damaged' %]
182
                            <span>Item is damaged</span>
183
                        [% CASE 'ageRestricted' %]
184
                            <span>The record and its items are age restricted</span>
185
                        [% CASE 'tooManyHoldsForThisRecord' %]
186
                            <span>Patron exceeded the number of concurrent holds for this record</span>
187
                        [% CASE 'tooManyReservesToday' %]
188
                            <span>Patron reached daily holds limit</span>
189
                        [% CASE 'tooManyReserves' %]
190
                            <span>Too many holds already</span>
191
                        [% CASE 'notReservable' %]
192
                            <span>Not holdable</span>
193
                        [% CASE 'cannotReserveFromOtherBranches' %]
194
                            <span>Patron from a different library</span>
195
                        [% CASE 'branchNotInHoldGroup' %]
196
                            <span>Holds are not allowed from patron's library</span>
197
                        [% CASE 'itemAlreadyOnHold' %]
198
                            <span>Patron already has a hold for failed item(s)</span>
199
                        [% CASE 'cannotBeTransferred' %]
200
                            <span>Cannot be transferred to pickup library</span>
201
                        [% CASE 'pickupNotInHoldGroup' %]
202
                            <span>The chosen pickup location is not allowed</span>
203
                        [% CASE 'noReservesAllowed' %]
204
                            <span>No holds are allowed on failed item(s)</span>
205
                        [% CASE 'libraryNotPickupLocation' %]
206
                            <span>Library is not a valid pickup location</span>
207
                        [% CASE 'no_valid_pickup_location' %]
208
                            <span>No valid pickup location</span>
209
                        [% CASE 'notforloan' %]
210
                            <span>Not for loan</span>
211
                        [% CASE 'items_available' %]
212
                            <span>There are items available in the library</span>
213
                        [% CASE 'not_placed' %]
214
                            <span>Error when placing hold</span>
215
                        [% CASE %]
216
                            <span>Error: [% fail | html %]</span>
217
                        [% END %]
218
                    </li>
219
                [% END %]
220
            </ul>
221
        </div>
222
    [% END %]
223
224
    [% UNLESS ( multi_hold ) %]
225
        <h2>Place a hold on [% INCLUDE 'biblio-title.inc' link = 1 %] [% IF biblio.author %]by [% biblio.author | html %][% END %]</h2>
226
    [% ELSE %]
227
        <h2>
228
            [% IF ( patron ) %]
229
                <span>Place holds</span>
230
            [% ELSE %]
231
                [% IF clubcount %]
232
                    <span>Search patrons or clubs</span>
233
                [% ELSE %]
234
                    <span>Search patrons</span>
235
                [% END %]
236
            [% END %]
237
        </h2>
238
    [% END %]
239
240
    [% UNLESS club OR patron OR patron.borrowernumber OR noitems OR nobiblio %]
241
        [% IF ( messageborrower ) %]
242
            <div class="alert alert-warning">
243
                <h3>Patron not found</h3>
244
                <p>No patron with this name, please, try another</p>
245
            </div>
246
        [% END %]
247
248
        [% IF ( messageclub ) %]
249
            <div class="alert alert-warning">
250
                <h3>Club not found</h3>
251
                <p>No club with this name, please, try another</p>
252
            </div>
253
        [% END %]
254
        <fieldset>
255
            [% UNLESS multi_hold %]
256
                [% IF clubcount %]
257
                    <h2>Search patrons or clubs</h2>
258
                [% ELSE %]
259
                    <h2>Search patrons</h2>
260
                [% END %]
261
            [% END %]
262
263
            [% WRAPPER tabs id= "circ_holds_select" %]
264
                [% WRAPPER tabs_nav %]
265
                    [% WRAPPER tab_item tabname= "holds_patronsearch_pane" bt_active= 1 %]<span>Patrons</span>[% END %]
266
                    [% IF clubcount %]
267
                        [% WRAPPER tab_item tabname= "holds_clubsearch_pane" %]<span>Clubs</span>[% END %]
268
                    [% END %]
269
                [% END # /WRAPPER tabs_nav %]
270
271
                [% WRAPPER tab_panels %]
272
                    [% WRAPPER tab_panel tabname="holds_patronsearch_pane" bt_active= 1 %]
273
                        [% PROCESS patron_search_filters_simple %]
274
275
                        [% PROCESS patron_search_table table_id => 'table_borrowers', open_on_row_click => 1 %]
276
                    [% END # /tab_panel# %]
277
                    [% IF clubcount %]
278
                        [% WRAPPER tab_panel tabname="holds_clubsearch_pane" %]
279
                            <form id="holds_clubsearch" action="request.pl" method="get">
280
                                <div class="hint">Enter club ID or partial name:</div>
281
                                <input type="text" size="40" id="club" class="focus" name="findclub" autocomplete="off" />
282
                                <input type="hidden" name="form_submitted" value="1" />
283
                                <input type="submit" class="btn btn-primary" value="Search" />
284
                                [% FOREACH biblionumber IN biblionumbers %]
285
                                    <input type="hidden" name="biblionumber" value="[% biblionumber | html %]" />
286
                                [% END %]
287
                            </form>
288
                            <!-- /#holds_patronsearch -->
289
                            [% IF clubs %]
290
                                [% INCLUDE 'clubs-table.inc' destination = "holds" %]
291
                            [% END %]
292
                        [% END # /tab_panel# %]
293
                    [% END # /IF clubcount %]
294
                [% END # /WRAPPER tab_panels %]
295
            [% END # /WRAPPER tabs %]
296
        </fieldset>
297
    [% ELSIF club %]
298
        <div class="alert alert-warning visually-hidden clubalert"> </div>
299
        <fieldset class="rows">
300
            <legend>Hold details</legend>
301
            <form action="/api/v1/clubs/[% club.id | html %]/holds" method="post" name="form" id="club-request-form">
302
                [% INCLUDE 'csrf-token.inc' %]
303
                <input type="hidden" name="op" value="cud-noop" />
304
305
                [% IF ( multi_hold ) %]
306
                    <input type="hidden" name="request" value="any" />
307
                    [% FOREACH biblioloo IN biblioloop %]
308
                        [% UNLESS biblioloo.none_avail %]
309
                            <input type="hidden" name="holdable_bibs" id="holdable_bibs" value="[% biblioloo.biblionumber | html %]" />
310
                            <input type="hidden" name="title_[% biblioloo.biblionumber | html %]" value="[% biblioloo.title | html %]" />
311
                            <input type="hidden" name="rank_[% biblioloo.biblionumber | html %]" value="[% biblioloo.rank | html %]" />
312
                        [% END %]
313
                    [% END %]
314
                [% ELSE %]
315
                    <input type="hidden" name="holdable_bibs" id="holdable_bibs" value="[% biblio.biblionumber | html %]" />
316
                    <input type="hidden" name="title" value="[% biblio.title | html %]" />
317
                    <input type="hidden" name="rank-request" value="[% fixedRank | html %]" />
318
                [% END # /IF multi_hold %]
319
                <ol>
320
                    <li> <span class="label">Club: </span> [% club.name | html %] </li>
321
                    <li> <span class="label">Description: </span> [% club.description | html %] </li>
322
                    <li>
323
                        <label for="pickup">Pickup at:</label>
324
                        <select name="pickup" id="pickup_club">
325
                            [% PROCESS options_for_libraries libraries => Branches.all({ selected => club.branchcode, search_params => { pickup_location => 1 } }) %]
326
                        </select>
327
                    </li>
328
                    <li>
329
                        <label for="default_patron_home">Pickup at patron's home library when possible:</label>
330
                        <input type="checkbox" id="default_patron_home" name="default_patron_home" />
331
                    </li>
332
                </ol>
333
                <h2 style="padding: 0 1em;">Members</h2>
334
                <ol>
335
                    [% FOREACH member IN members %]
336
                        [% SET patron = member.patron %]
337
                        <li style="padding: 0.5em 1em;">
338
                            <div>[% INCLUDE 'patron-title.inc' patron => patron no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 %]</div>
339
                            [% IF member.exceeded_maxreserves %]
340
                                <div>
341
                                    <i class="fa fa-error"></i>
342
                                    <strong>Too many holds: </strong> Patron can only place a maximum of [% maxreserves | html %] total holds.
343
                                </div>
344
                            [% END %]
345
                            [% IF ( patron.is_expired ) %]
346
                                <div>
347
                                    <i class="fa-solid fa-triangle-exclamation"></i>
348
                                    <strong>Account has expired</strong>
349
                                </div>
350
                            [% END %]
351
                            [% IF patron.is_debarred %]
352
                                <div>
353
                                    <i class="fa-solid fa-triangle-exclamation"></i>
354
                                    <strong>Patron has restrictions</strong>
355
                                </div>
356
                            [% END %]
357
                            [% IF member.amount_outstanding && Koha.Preference('maxoutstanding') && member.amount_outstanding > Koha.Preference('maxoutstanding') %]
358
                                <div>
359
                                    <i class="fa-solid fa-triangle-exclamation"></i>
360
                                    <strong>Patron has outstanding fines: [% member.amount_outstanding | $Price %]</strong>
361
                                </div>
362
                            [% END %]
363
364
                            [% IF ( member.diffbranch ) %]
365
                                <div>
366
                                    <i class="fa-solid fa-triangle-exclamation"></i>
367
                                    <strong>Pickup library is different.</strong> Patron's home library: ([% Branches.GetName(patron.branchcode) | html %] / [% patron.branchcode | html %] )
368
                                </div>
369
                            [% END %]
370
                        </li>
371
                    [% END %]
372
                </ol>
373
                [% UNLESS ( multi_hold ) %]
374
                    <fieldset class="action">
375
                        <input type="submit" class="btn btn-primary" value="Place hold" />
376
                    </fieldset>
377
                [% ELSE %]
378
                    <table id="requesttitles">
379
                        <tr>
380
                            <th>&nbsp;</th>
381
                            <th>Title</th>
382
                            [% UNLESS Koha.Preference('item-level_itypes') %]
383
                                <th>Item type</th>
384
                            [% END %]
385
                            <th>Priority</th>
386
                            <th>Information</th>
387
                        </tr>
388
                        [% FOREACH biblioloo IN biblioloop %]
389
                            <tr [% IF biblioloo.warn %]class="onissue"[% END %]>
390
                                <td>
391
                                    [% UNLESS ( biblioloo.warn ) %]
392
                                        <input class="multi_hold_item_checkbox" type="checkbox" checked="checked" title="[% biblioloo.biblionumber | html %]" />
393
                                    [% END %]
394
                                </td>
395
                                <td>
396
                                    <ul>
397
                                        <li>
398
                                            <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblioloo.biblionumber | uri %]">[% biblioloo.title | html %]</a>
399
                                            [% IF biblioloo.author %]by [% biblioloo.author | html %][% END %]
400
                                        </li>
401
                                        [% IF ( biblioloo.publicationyear ) %]
402
                                            <li> <span class="label">Publication year:</span> [% biblioloo.publicationyear | html %] </li>
403
                                        [% END %]
404
                                    </ul>
405
                                    [% IF ( biblioloo.warn ) %]
406
                                        <span class="not_holdable" title="[% biblioloo.biblionumber | html %]"></span>
407
                                    [% END %]
408
                                </td>
409
                                [% UNLESS Koha.Preference('item-level_itypes') %]
410
                                    <td>
411
                                        <img
412
                                            class="itemtype-image"
413
                                            src="[% biblioloo.itemtype.image_location| html %]"
414
                                            alt="[% biblioloo.itemtype.translated_description | html %]"
415
                                            title="[% biblioloo.itemtype.translated_description | html %]"
416
                                        />
417
                                    </td>
418
                                [% END %]
419
                                <td>[% biblioloo.rank | html %]</td>
420
                                <td>
421
                                    [% IF ( biblioloo.checked_previously ) %]
422
                                        <span>Patron has previously checked out this title</span><br />
423
                                    [% END %]
424
                                    [% IF ( biblioloo.alreadyres ) %]
425
                                        <ul>
426
                                            <li> [% INCLUDE 'patron-title.inc' patron => patron no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 %] <strong>already has a hold</strong> on this item </li>
427
                                        </ul>
428
                                    [% END %]
429
                                    [% IF ( biblioloo.none_avail || biblioloo.noitems ) %]
430
                                        <ul
431
                                            ><li> <strong>No items are available</strong> to be placed on hold</li></ul
432
                                        >
433
                                    [% END %]
434
                                </td>
435
                            </tr>
436
                        [% END # /FOREACH biblioloo %]
437
                    </table>
438
                    <!-- /#requesttitles -->
439
                [% END %]
440
            </form>
441
        </fieldset>
442
    [% ELSIF NOT ( noitems || nobiblio ) # /UNLESS patron %]
443
444
        [% IF ( checked_previously && !multi_hold ) %]
445
            <div class="alert alert-warning">
446
                <ul>
447
                    <li>Patron has previously checked out this title</li>
448
                </ul>
449
            </div>
450
        [% END %]
451
452
        [% IF ( no_reserves_allowed || exceeded_maxreserves || exceeded_holds_per_record || alreadyreserved || none_available || alreadypossession || ageRestricted || recall ) %]
453
            <div class="alert alert-warning">
454
                [% UNLESS ( multi_hold ) %]
455
                    <h3>Cannot place hold</h3>
456
                    <ul>
457
                        [% IF ( no_reserves_allowed ) %]
458
                            <li><strong>No holds allowed:</strong> [% INCLUDE 'patron-title.inc' patron => patron no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 %] cannot place a hold on any of these items.</li>
459
                        [% ELSIF ( exceeded_maxreserves ) %]
460
                            <li
461
                                ><strong>Too many holds:</strong> [% INCLUDE 'patron-title.inc' patron => patron no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 %] can only place a maximum of [% maxreserves | html %] total
462
                                holds.</li
463
                            >
464
                        [% ELSIF ( exceeded_holds_per_record ) %]
465
                            <li
466
                                ><strong>Too many holds for this record:</strong> [% INCLUDE 'patron-title.inc' patron => patron no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 %] can only place a maximum of
467
                                [% max_holds_for_record | html %] hold(s) on this record.</li
468
                            >
469
                        [% ELSIF ( alreadypossession ) %]
470
                            <li>[% INCLUDE 'patron-title.inc' patron => patron no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 hide_patron_infos_if_needed => 1 %] <strong>is already in possession</strong> of one item.</li>
471
                        [% ELSIF ( alreadyreserved ) %]
472
                            <li>[% INCLUDE 'patron-title.inc' patron => patron no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 %] <strong>already has a hold</strong> on this item.</li>
473
                        [% ELSIF ( ageRestricted ) %]
474
                            <li><strong>Age restricted</strong></li>
475
                        [% ELSIF ( none_available ) %]
476
                            <li> <strong>No items are available</strong> to be placed on hold.</li>
477
                        [% ELSIF ( maxreserves ) %]
478
                            <li
479
                                ><strong>Too many holds:</strong>
480
                                [% INCLUDE 'patron-title.inc' patron => patron no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 %] has too many holds.</li
481
                            >
482
                        [% ELSIF ( recall ) %]
483
                            <li>[% INCLUDE 'patron-title.inc' patron => patron no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 %] has <strong>already placed a recall</strong> on this item.</li>
484
                        [% END # /IF exceeded_maxreserves %]
485
                    </ul>
486
                [% ELSE # UNLESS multi_hold %]
487
                    <h3>Cannot place hold on some items</h3>
488
                    [% IF (no_reserves_allowed ) %]
489
                        <li><strong>No holds allowed:</strong> [% INCLUDE 'patron-title.inc' patron => patron no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 %] cannot place holds on some of these title's items.</li>
490
                    [% ELSIF ( exceeded_maxreserves ) %]
491
                        <li
492
                            ><strong>Too many holds:</strong> [% INCLUDE 'patron-title.inc' patron => patron no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 %] can place [% new_reserves_allowed | html %] of the requested
493
                            [% new_reserves_count | html %] holds for a maximum of [% maxreserves | html %] total holds.</li
494
                        >
495
                    [% ELSIF ( exceeded_holds_per_record ) %]
496
                        [% FOREACH biblioloo IN biblioloop %]
497
                            [% IF (biblioloo.tooManyHoldsForThisRecord) %]
498
                                <li
499
                                    ><strong>Too many holds for <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblioloo.biblionumber | uri %]"> [% biblioloo.title | html %]</a>:</strong>
500
                                    [% INCLUDE 'patron-title.inc' patron => patron no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 %] can only place a maximum of [% max_holds_for_record | html %] hold(s) on this
501
                                    record.</li
502
                                >
503
                            [% END %]
504
                        [% END %]
505
                    [% ELSIF ( none_available ) %]
506
                        <li><strong>No items available: </strong>One or more records have no items that can be held</li>
507
                    [% END # /IF exceeded_maxreserves %]
508
                [% END # /UNLESS multi_hold %]
509
            </div>
510
        [% END # /IF ( exceeded_maxreserves || ... %]
511
512
        [% IF ( patron.is_expired || diffbranch || patron.is_debarred || ( amount_outstanding && Koha.Preference('maxoutstanding') && amount_outstanding > Koha.Preference('maxoutstanding') ) ) %]
513
            <div class="alert alert-info">
514
                <ul>
515
                    [% IF ( patron.is_expired ) %]
516
                        <li>[% INCLUDE 'patron-title.inc' patron => patron no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 %]: <strong>Account has expired</strong></li>
517
                    [% END %]
518
519
                    [% IF patron.is_debarred %]
520
                        <li>[% INCLUDE 'patron-title.inc' patron => patron no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 %]: <strong>Patron has restrictions</strong></li>
521
                    [% END %]
522
523
                    [% IF amount_outstanding && Koha.Preference('maxoutstanding') && amount_outstanding > Koha.Preference('maxoutstanding') %]
524
                        <li
525
                            >[% INCLUDE 'patron-title.inc' patron => patron no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 link_to => 'members_pay' %]:
526
                            <strong>Patron has outstanding fines: [% amount_outstanding | $Price %]</strong></li
527
                        >
528
                    [% END %]
529
530
                    [% IF ( diffbranch ) %]
531
                        <li
532
                            ><strong>Pickup library is different. </strong>Patron: [% INCLUDE 'patron-title.inc' patron => patron no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 %] Patron's home library:
533
                            ([% Branches.GetName(patron.branchcode) | html %] / [% patron.branchcode | html %] )</li
534
                        >
535
                    [% END %]
536
                </ul>
537
                <!-- /.dialog.message -->
538
            </div>
539
        [% END # /IF patron.is_expired || diffbranch ... %]
540
541
        [% IF ( messageborrower ) %]
542
            <div class="alert alert-warning">
543
                <h3>Patron not found:</h3>
544
                <p>Name or barcode not found. Please try an other </p>
545
            </div>
546
        [% END %]
547
548
        <div class="alert alert-warning visually-hidden holdalert"> </div>
549
550
        [% UNLESS ( multi_hold ) %]
551
            <form action="placerequest.pl" method="post" name="form" id="hold-request-form">
552
                [% INCLUDE 'csrf-token.inc' %]
553
                <input type="hidden" name="op" value="cud-placerequest" />
554
                <fieldset class="rows">
555
                    <legend>Hold details</legend>
556
557
                    <input type="hidden" name="borrowernumber" value="[% patron.borrowernumber | html %]" />
558
                    [% FOREACH biblionumber IN biblionumbers %]
559
                        <input type="hidden" name="biblionumber" value="[% biblionumber | html %]" />
560
                    [% END %]
561
                    <input type="hidden" name="holdable_bibs" id="holdable_bibs" value="[% biblio.biblionumber | html %]" />
562
                    <input type="hidden" name="title" value="[% biblio.title | html %]" />
563
                    <input type="hidden" name="rank-request" value="[% fixedRank | html %]" />
564
565
                    <ol>
566
                        <li>
567
                            <span class="label">Patron:</span>
568
                            [% IF ( patron.borrowernumber ) %]
569
                                [% INCLUDE 'patron-title.inc' patron => patron no_title => 1 hide_patron_infos_if_needed => 1 %]
570
                            [% ELSE %]
571
                                Not defined yet
572
                            [% END %]
573
                        </li>
574
575
                        <li>
576
                            <span class="label">Estimated priority:</span>
577
                            <strong>[% fixedRank | html %]</strong>
578
                        </li>
579
580
                        <li>
581
                            <label for="holdnotes">Notes:</label>
582
                            <textarea id="holdnotes" name="notes" cols="30" rows="1"></textarea>
583
                        </li>
584
585
                        [% IF Koha.Preference('AllowHoldItemTypeSelection') %]
586
                            <li>
587
                                <label for="itemtype">Request specific item type:</label>
588
                                <select name="itemtype" id="itemtype">
589
                                    <option value="">Any item type</option>
590
                                    [%- FOREACH itemtype IN available_itemtypes %]
591
                                        <option value="[% itemtype | html %]">[% ItemTypes.GetDescription( itemtype ) | html %]</option>
592
                                    [%- END %]
593
                                </select>
594
                            </li>
595
                        [% END %]
596
597
                        [% IF ( Koha.Preference('AllowHoldDateInFuture') ) %]
598
                            <li>
599
                                <label for="from">Hold starts on date:</label>
600
                                <input id="reserve_date" name="reserve_date" id="from" size="10" type="text" data-date_to="expiration_date" class="flatpickr" data-flatpickr-futureinclusive="true" />
601
                            </li>
602
                        [% END %]
603
604
                        <li>
605
                            <label for="to">Hold expires on date:</label>
606
                            <input id="expiration_date" name="expiration_date" id="to" size="10" type="text" class="flatpickr" data-flatpickr-futuredate="true" />
607
                        </li>
608
609
                        <li id="non_priority_list_item">
610
                            <label for="non_priority">Non priority hold:</label>
611
                            <input name="non_priority" id="non_priority" type="checkbox" />
612
                            <span class="hint">A non priority hold doesn't prevent a current checkout from renewing</span>
613
                        </li>
614
                    </ol>
615
                </fieldset>
616
                <fieldset class="rows any_specific">
617
                    <legend>
618
                        [% IF force_hold_level == 'item' || force_hold_level == 'item_group' %]
619
                            <input type="radio" id="requestany" name="request" disabled="true" />
620
                        [% ELSIF force_hold_level == 'record' %]
621
                            <input type="radio" id="requestany" checked="checked" value="Any" disabled="true" />
622
                            <input type="hidden" name="request" value="Any" />
623
                            <span class="error"><i>(Required)</i></span>
624
                        [% ELSE %]
625
                            <input type="radio" id="requestany" name="request" checked="checked" value="Any" />
626
                        [% END %]
627
                        <label for="requestany" class="inline"> Hold next available item </label>
628
                    </legend>
629
                    <input type="hidden" name="alreadyreserved" value="[% alreadyreserved | html %]" />
630
                    <fieldset class="enable_request_any disable_request_group disable_request_specific">
631
                        [% IF force_hold_level == 'item' # Patron has placed a item level hold previously for this record %]
632
                            <span class="error">
633
                                <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
634
                                Hold must be item level
635
                            </span>
636
                        [% ELSIF force_hold_level == 'item_group' # Patron has placed an item group level hold previously for this record %]
637
                            <span class="error">
638
                                <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
639
                                Hold must be item group level
640
                            </span>
641
                        [% ELSE %]
642
                            <ol>
643
                                <li>
644
                                    <label for="pickup">Pickup at:</label>
645
                                    <select name="pickup" id="pickup-next-avail" data-biblio-id="[% biblio.biblionumber | html %]" data-patron-id="[% patron.borrowernumber | html %]" data-pickup-location-source="biblio">
646
                                        [% PROCESS options_for_libraries libraries => Branches.pickup_locations({ search_params => { biblio => biblionumber, patron => patron }, selected => pickup }) %]
647
                                    </select>
648
                                </li>
649
650
                                [% IF Koha.Preference('AllowHoldItemTypeSelection') %]
651
                                    <li>
652
                                        <label for="itemtype">Request specific item type:</label>
653
                                        <select name="itemtype" id="itemtype">
654
                                            <option value="">Any item type</option>
655
                                            [%- FOREACH itemtype IN available_itemtypes %]
656
                                                <option value="[% itemtype | html %]">[% ItemTypes.GetDescription( itemtype ) | html %]</option>
657
                                            [%- END %]
658
                                        </select>
659
                                    </li>
660
                                [% END %]
661
                                [% UNLESS remaining_holds_for_record == 1 %]
662
                                    <li>
663
                                        <label for="holds_to_place_count">Holds to place (count)</label>
664
                                        <input type="text" inputmode="numeric" pattern="[0-9]*" id="holds_to_place_count" name="holds_to_place_count" value="1" />
665
                                    </li>
666
                                [% ELSE %]
667
                                    <input type="hidden" name="holds_to_place_count" value="1" />
668
                                [% END %]
669
                            </ol>
670
                        [% END %]
671
672
                        <fieldset class="action">
673
                            [% IF ( patron.borrowernumber ) %]
674
                                [% IF ( override_required ) %]
675
                                    <button type="submit" id="hold_grp_btn" class="btn btn-primary warning"><i class="fa fa-exclamation-triangle "></i> Place hold</button>
676
                                [% ELSIF ( none_available ) %]
677
                                    <button type="submit" id="hold_grp_btn" disabled="disabled" class="btn btn-primary btn-disabled">Place hold</button>
678
                                [% ELSE %]
679
                                    <button type="submit" id="hold_grp_btn" class="btn btn-primary">Place hold</button>
680
                                [% END %]
681
                            [% END %]
682
                        </fieldset>
683
                    </fieldset>
684
                </fieldset>
685
686
                <hr />
687
688
                [% biblio_info = biblioloop.0 %]
689
                <!-- ItemGroup level holds -->
690
                [% IF Koha.Preference('EnableItemGroupHolds') && biblio_info.object.item_groups.count %]
691
                    <fieldset class="rows any_specific">
692
                        <legend>
693
                            [% IF force_hold_level == 'item_group' %]
694
                                <input type="radio" class="requestgrp" id="requestgrp" name="request" checked="checked" disabled="true" />
695
                                <span class="error"><i>(Required)</i></span>
696
                            [% ELSIF force_hold_level == 'item' || force_hold_level == 'record' %]
697
                                <input type="radio" class="requestgrp" id="requestgrp" name="request" disabled="true" />
698
                            [% ELSE %]
699
                                <input type="radio" class="requestgrp" id="requestgrp" name="request" />
700
                            [% END %]
701
                            <label for="requestgrp" class="inline"> Hold next available item from an item group </label>
702
                        </legend>
703
704
                        <fieldset class="enable_request_group disable_request_any disable_request_specific">
705
                            [% IF force_hold_level == 'record' # Patron has placed a record level hold previously for this record %]
706
                                <span class="error">
707
                                    <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
708
                                    Hold must be record level
709
                                </span>
710
                            [% ELSIF force_hold_level == 'item' # Patron has placed an item level hold previously for this record %]
711
                                <span class="error">
712
                                    <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
713
                                    Hold must be item level
714
                                </span>
715
                            [% ELSE %]
716
                                <ul>
717
                                    <li>
718
                                        <label for="pickup">Pickup at:</label>
719
                                        <select name="pickup" id="pickup-item-group" data-biblio-id="[% biblio.biblionumber | html %]" data-patron-id="[% patron.borrowernumber | html %]" data-pickup-location-source="biblio">
720
                                            [% PROCESS options_for_libraries libraries => Branches.pickup_locations({ search_params => { biblio => biblionumber, patron => patron }, selected => pickup }) %]
721
                                        </select>
722
                                    </li>
723
                                    <li>
724
                                        <table id="requestgroup">
725
                                            <thead>
726
                                                <tr>
727
                                                    <th>Hold</th>
728
                                                    <th>Item group</th>
729
                                                    <th>Holdable items</th>
730
                                                </tr>
731
                                            </thead>
732
                                            <tbody>
733
                                                [% FOREACH g IN biblio_info.object.item_groups.search({}, { order_by => ['display_order'] }) %]
734
                                                    [% IF g.items.count %]
735
                                                        <tr>
736
                                                            <td>
737
                                                                <input id="item_group_id_[% g.id | html %]" class="requestgrp" type="radio" name="item_group_id" value="[% g.id | html %]" />
738
                                                            </td>
739
                                                            <td>
740
                                                                <label for="item_group_id_[% g.id | html %]">[% g.description | html %]</label>
741
                                                            </td>
742
                                                            <td>
743
                                                                [% FOREACH i IN g.items %]
744
                                                                    <div><a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=[% i.biblionumber | uri %]#item[% i.itemnumber | uri %]">[% i.barcode | html %]</a></div>
745
                                                                [% END %]
746
                                                            </td>
747
                                                        </tr>
748
                                                    [% ELSE %]
749
                                                        <tr>
750
                                                            <td>
751
                                                                <input id="item_group_id_[% g.id | html %]" class="requestgrp" type="radio" name="item_group_id" value="[% g.id | html %]" disabled="disabled" />
752
                                                            </td>
753
                                                            <td>
754
                                                                <label for="item_group_id_[% g.id | html %]">[% g.description | html %]</label>
755
                                                            </td>
756
                                                            <td>
757
                                                                <div class="error">No holdable items in this item group.</div>
758
                                                            </td>
759
                                                        </tr>
760
                                                    [% END %]
761
                                                [% END %]
762
                                            </tbody>
763
                                        </table>
764
                                    </li>
765
                                </ul>
766
                            [% END %]
767
                            <fieldset class="action">
768
                                [% IF ( patron.borrowernumber ) %]
769
                                    [% IF ( override_required ) %]
770
                                        <button type="submit" id="hold_any_btn" class="btn btn-primary warning"><i class="fa fa-exclamation-triangle "></i> Place hold</button>
771
                                    [% ELSIF ( none_available ) %]
772
                                        <button type="submit" id="hold_any_btn" disabled="disabled" class="btn btn-primary btn-disabled">Place hold</button>
773
                                    [% ELSE %]
774
                                        <button type="submit" id="hold_any_btn" class="btn btn-primary">Place hold</button>
775
                                    [% END %]
776
                                [% END %]
777
                            </fieldset>
778
                        </fieldset>
779
                    </fieldset>
780
                [% END %]
781
                <!-- /ItemGroup level holds -->
782
783
                <fieldset class="rows any_specific">
784
                    <legend>
785
                        [% IF force_hold_level == 'item' %]
786
                            <input type="radio" id="requestspecificitem" name="request" class="requestspecific" checked="checked" disabled="disabled" />
787
                            <span class="error"><em>(Required)</em></span>
788
                        [% ELSIF force_hold_level == 'record' || force_hold_level == 'item_group' %]
789
                            <input type="radio" id="requestspecificitem" name="request" class="requestspecific" disabled="disabled" />
790
                        [% ELSE %]
791
                            <input type="radio" id="requestspecificitem" name="request" class="requestspecific" />
792
                        [% END %]
793
                        <label for="requestspecificitem" class="inline"> Hold a specific item </label>
794
                    </legend>
795
796
                    <fieldset class="enable_request_specific disable_request_any disable_request_group">
797
                        <ol>
798
                            [% UNLESS Koha.Preference('item-level_itypes') %]
799
                                <li>
800
                                    <span class="label">Item type:</span>
801
                                    [% biblio_info.itemtype.translated_description | html %]
802
                                </li>
803
                            [% END %]
804
805
                            [% IF ( biblio_info.biblioitem.publicationyear ) %]
806
                                <li>
807
                                    <span class="label">Publication year:</span>
808
                                    [% biblio_info.biblioitem.publicationyear | html %]
809
                                </li>
810
                            [% END %]
811
                        </ol>
812
813
                        <table id="requestspecific">
814
                            <thead>
815
                                <tr>
816
                                    <th>Hold</th>
817
                                    <th>Allowed pickup locations</th>
818
                                    [% IF Koha.Preference('item-level_itypes') %]
819
                                        <th>Item type</th>
820
                                    [% END %]
821
                                    <th>Barcode</th>
822
                                    [% IF Koha.Preference('EnableItemGroupHolds') && biblio_info.object.item_groups.count %]
823
                                        <th>Item group</th>
824
                                    [% END %]
825
                                    <th>Home library</th>
826
                                    <th>Last location</th>
827
                                    [% IF itemdata_ccode %]
828
                                        <th>Collection</th>
829
                                    [% END %]
830
                                    <th>Call number</th>
831
                                    <th>Copy number</th>
832
                                    [% IF itemdata_enumchron %]
833
                                        <th>Vol no.</th>
834
                                    [% END %]
835
                                    <th>Information</th>
836
                                </tr>
837
                            </thead>
838
                            <tbody>
839
                                [% SET selected = 0 %]
840
                                [% FOREACH itemloo IN biblio_info.itemloop %]
841
                                    [% UNLESS ( itemloo.hide ) %]
842
                                        <tr class="[% itemloo.backgroundcolor | html %]">
843
                                            <td>
844
                                                [% IF force_hold_level == 'record' # Patron has placed a record level hold previously for this record %]
845
                                                    <span class="error">
846
                                                        <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
847
                                                        Hold must be record level
848
                                                    </span>
849
                                                [% ELSIF force_hold_level == 'item_group' %]
850
                                                    <span class="error">
851
                                                        <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
852
                                                        Hold must be item group level
853
                                                    </span>
854
                                                [% ELSIF ( itemloo.available ) %]
855
                                                    <input type="[% reserve_input_type | html %]" name="checkitem" class="requestspecific" value="[% itemloo.itemnumber | html %]" />
856
                                                [% ELSIF ( itemloo.override ) %]
857
                                                    <input type="[% reserve_input_type | html %]" name="checkitem" class="needsoverride requestspecific" value="[% itemloo.itemnumber | html %]" />
858
                                                    <i class="fa fa-exclamation-triangle fa-lg" style="color:gold" title="Requires override of hold policy"></i>
859
                                                [% ELSE %]
860
                                                    <span class="error">
861
                                                        <i class="fa fa-times fa-lg" title="Cannot be put on hold"></i>
862
                                                        [% IF itemloo.not_holdable %]
863
                                                            [% IF itemloo.not_holdable == 'damaged' %]
864
                                                                <span>Item damaged</span>
865
                                                            [% ELSIF itemloo.not_holdable == 'ageRestricted' %]
866
                                                                <span>Age restricted</span>
867
                                                            [% ELSIF itemloo.not_holdable == 'tooManyHoldsForThisRecord' %]
868
                                                                <span>Exceeded max holds per record</span>
869
                                                            [% ELSIF itemloo.not_holdable == 'tooManyReservesToday' %]
870
                                                                <span>Daily hold limit reached for patron</span>
871
                                                            [% ELSIF itemloo.not_holdable == 'tooManyReserves' %]
872
                                                                <span>Too many holds</span>
873
                                                            [% ELSIF itemloo.not_holdable == 'notReservable' %]
874
                                                                <span>Not holdable</span>
875
                                                            [% ELSIF itemloo.not_holdable == 'cannotReserveFromOtherBranches' %]
876
                                                                <span>Patron is from different library</span>
877
                                                            [% ELSIF itemloo.not_holdable == 'branchNotInHoldGroup' %]
878
                                                                <span>Cannot place hold from patron's library</span>
879
                                                            [% ELSIF itemloo.not_holdable == 'itemAlreadyOnHold' %]
880
                                                                <span>Patron already has hold for this item</span>
881
                                                            [% ELSIF itemloo.not_holdable == 'cannotBeTransferred' %]
882
                                                                <span>Cannot be transferred to pickup library</span>
883
                                                            [% ELSIF itemloo.not_holdable == 'pickupNotInHoldGroup' %]
884
                                                                <span>Only pickup locations within the same hold group are allowed</span>
885
                                                            [% ELSIF itemloo.not_holdable == 'noReservesAllowed' %]
886
                                                                <span>No holds are allowed on this item</span>
887
                                                            [% ELSIF itemloo.not_holdable == 'libraryNotPickupLocation' %]
888
                                                                <span>Library is not a pickup location</span>
889
                                                            [% ELSIF itemloo.not_holdable == 'no_valid_pickup_location' %]
890
                                                                <span>No valid pickup location</span>
891
                                                            [% ELSIF itemloo.not_holdable == 'notforloan' %]
892
                                                                <span>Not for loan</span>
893
                                                            [% ELSE %]
894
                                                                <span>[% itemloo.not_holdable | html %]</span>
895
                                                            [% END %]
896
                                                        [% END %]
897
                                                    </span>
898
                                                [% END # /IF force_hold_level %]
899
                                            </td>
900
                                            <td>
901
                                                [% IF (itemloo.pickup_locations_count > 0) || Koha.Preference('AllowHoldPolicyOverride') %]
902
                                                    <select
903
                                                        name="item_pickup_[% itemloo.itemnumber | html %]"
904
                                                        class="pickup_locations requestspecific"
905
                                                        style="width:100%;"
906
                                                        data-item-id="[% itemloo.itemnumber | html %]"
907
                                                        data-patron-id="[% patron.borrowernumber | html %]"
908
                                                        data-pickup-location-source="item"
909
                                                    >
910
                                                        [% IF (itemloo.default_pickup_location) %]
911
                                                            <option value="[% itemloo.default_pickup_location.branchcode | html %]" selected="selected">[% itemloo.default_pickup_location.branchname | html %]</option>
912
                                                        [% END %]
913
                                                    </select>
914
                                                [% END %]
915
                                            </td>
916
                                            [% IF Koha.Preference('item-level_itypes') %]
917
                                                <td>
918
                                                    [% UNLESS ( noItemTypeImages ) %]
919
                                                        [% IF ( itemloo.itemtype.image_location) %]<img class="itemtype-image" src="[% itemloo.itemtype.image_location | html %]" alt="" /> <br />[% END %]
920
                                                    [% END %]
921
                                                    <span class="itypetext">[% itemloo.itemtype.translated_description | html %]</span>
922
                                                </td>
923
                                            [% END %]
924
                                            <td> [% itemloo.barcode | html %] </td>
925
                                            [% IF Koha.Preference('EnableItemGroupHolds') && biblio_info.object.item_groups.count %]
926
                                                <td> [% itemloo.object.item_group.description | html %] </td>
927
                                            [% END %]
928
                                            <td> [% Branches.GetName( itemloo.homebranch ) | html %] </td>
929
                                            <td> [% Branches.GetName( itemloo.holdingbranch ) | html %] </td>
930
                                            [% IF itemdata_ccode %]
931
                                                <td> [% IF ( itemloo.ccode ) %][% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.ccode', authorised_value => itemloo.ccode ) | html %][% END %] </td>
932
                                            [% END %]
933
                                            <td> [% itemloo.itemcallnumber | html %] </td>
934
                                            <td> [% IF ( itemloo.copynumber ) %][% itemloo.copynumber | html %][% ELSE %]&nbsp;[% END %] </td>
935
                                            [% IF itemdata_enumchron %]
936
                                                <td> [% itemloo.enumchron | html %] </td>
937
                                            [% END %]
938
                                            <td [% IF itemloo.onloan %]data-order="[% itemloo.date_due | html %]"[% END %]>
939
                                                [% IF ( itemloo.onloan ) %]
940
                                                    <span class="checkedout">Due [% itemloo.date_due | $KohaDates as_due_date => 1 %]</span>
941
                                                [% ELSE %]
942
                                                    [% IF ( itemloo.transfertwhen ) %]
943
                                                        <span
944
                                                            >In transit from [% Branches.GetName( itemloo.transfertfrom ) | html %], to [% Branches.GetName( itemloo.transfertto ) | html %], since
945
                                                            [% itemloo.transfertwhen | $KohaDates %]</span
946
                                                        >
947
                                                    [% END %]
948
                                                [% END %]
949
950
                                                [% IF ( itemloo.reservedate ) %]
951
                                                    [% IF ( itemloo.nocancel ) %]
952
                                                        <span>Can't be cancelled when item is in transit</span>
953
                                                    [% ELSE %]
954
                                                        [% IF ( itemloo.waitingdate ) %]
955
                                                            [% IF ( itemloo.canreservefromotherbranches ) %]
956
                                                                <span
957
                                                                    >Waiting for [% INCLUDE 'patron-title.inc' patron=itemloo.ReservedFor %] at [% Branches.GetName( itemloo.ExpectedAtLibrary ) | html %] since
958
                                                                    [% itemloo.waitingdate | $KohaDates %]</span
959
                                                                >
960
                                                            [% ELSE %]
961
                                                                <span>Waiting at [% Branches.GetName( itemloo.ExpectedAtLibrary ) | html %] since [% itemloo.waitingdate | $KohaDates %]</span>
962
                                                            [% END %]
963
                                                        [% ELSE %]
964
                                                            [% IF ( itemloo.canreservefromotherbranches ) %]
965
                                                                [% IF itemloo.reservedate %]
966
                                                                    <span>On hold for [% INCLUDE 'patron-title.inc' patron=itemloo.ReservedFor %] expected at [% Branches.GetName( itemloo.ExpectedAtLibrary ) | html %] since</span>
967
                                                                [% ELSE %]
968
                                                                    <span>On hold expected at [% Branches.GetName( itemloo.ExpectedAtLibrary ) | html %]</span>
969
                                                                [% END %]
970
                                                            [% ELSIF itemloo.reservedate %]
971
                                                                <span>On hold expected at [% Branches.GetName( itemloo.ExpectedAtLibrary ) | html %] since [% itemloo.reservedate | $KohaDates %]</span>
972
                                                            [% ELSE %]
973
                                                                <span>On hold expected at [% Branches.GetName( itemloo.ExpectedAtLibrary ) | html %]</span>
974
                                                            [% END %]
975
                                                        [% END %]
976
                                                    [% END # /IF itemloo.nocancel %]
977
                                                [% ELSE %]
978
                                                    Not on hold
979
                                                [% END # /IF itemloo.reservedate %]
980
981
                                                [% IF itemloo.item_level_holds == "N" %]
982
                                                    <br />Item level hold not allowed from OPAC
983
                                                [% ELSIF itemloo.item_level_holds == "F" %]
984
                                                    <br />Item level hold forced from OPAC
985
                                                [% END %]
986
987
                                                [% IF ( itemloo.itemlost ) %]
988
                                                    <span class="lost">[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.itemlost', authorised_value => itemloo.itemlost ) | html %]</span>
989
                                                [% END %]
990
991
                                                [% IF ( itemloo.damaged ) %]
992
                                                    <span class="dmg">[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.damaged', authorised_value => itemloo.damaged ) | html %]</span>
993
                                                [% END %]
994
995
                                                [% IF ( itemloo.withdrawn ) %]
996
                                                    <span class="wdn">[% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.withdrawn', authorised_value => itemloo.withdrawn ) | html %]</span>
997
                                                [% END %]
998
999
                                                [% IF ( itemloo.notforloan ) %]
1000
                                                    <span class="nfl">Not for loan ([% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.notforloan', authorised_value => itemloo.notforloan ) | html %])</span>
1001
                                                [% ELSIF ( itemloo.notforloanitype ) %]
1002
                                                    <span class="nfl">Not for loan (Itemtype not for loan)</span>
1003
                                                [% END %]
1004
                                            </td>
1005
                                        </tr>
1006
                                    [% END # / UNLESS itemloo.hide %]
1007
                                [% END # /FOREACH itemloo %]
1008
                            </tbody>
1009
                        </table>
1010
                        <!-- /#requestspecific -->
1011
1012
                        [% IF hiddencount %]
1013
                            <p class="hiddencount">
1014
                                <a href="request.pl?biblionumber=[% biblio_info.biblionumber | uri %]&amp;borrowernumber=[% borrowernumber | uri %]&amp;showallitems=1">Show all items ([% hiddencount | html %] hidden)</a>
1015
                            </p>
1016
                        [% END # /IF hiddencount %]
1017
                        <fieldset class="action">
1018
                            [% IF ( patron.borrowernumber ) %]
1019
                                [% IF ( override_required ) %]
1020
                                    <button type="submit" id="hold_item_btn" class="btn btn-primary warning"><i class="fa fa-exclamation-triangle "></i> Place hold</button>
1021
                                [% ELSIF ( none_available ) %]
1022
                                    <button type="submit" id="hold_item_btn" disabled="disabled" class="btn btn-primary btn-disabled">Place hold</button>
1023
                                [% ELSE %]
1024
                                    <button type="submit" id="hold_item_btn" class="btn btn-primary">Place hold</button>
1025
                                [% END %]
1026
                            [% END %]
1027
                        </fieldset>
1028
                    </fieldset>
1029
                </fieldset>
1030
                <!-- /.rows any_specific -->
1031
            </form>
1032
            <!-- /#hold-request-form -->
1033
        [% ELSE # /UNLESS multi_hold %]
1034
            <form action="placerequest.pl" method="post" name="form" id="hold-request-form">
1035
                <fieldset class="rows">
1036
                    <legend>Hold details</legend>
1037
                    [% INCLUDE 'csrf-token.inc' %]
1038
                    <input type="hidden" name="op" value="cud-placerequest" />
1039
                    <input type="hidden" name="multi_holds" id="multi_holds" value="1" />
1040
                    <input type="hidden" name="request" value="any" />
1041
                    <input type="hidden" name="borrowernumber" value="[% patron.borrowernumber | html %]" />
1042
                    [% FOREACH biblioloo IN biblioloop %]
1043
                        <input type="hidden" name="biblionumber" id="biblionumber" value="[% biblioloo.biblionumber | html %]" />
1044
                        [% UNLESS biblioloo.none_avail %]
1045
                            <input type="hidden" name="title_[% biblioloo.biblionumber | html %]" value="[% biblioloo.title | html %]" />
1046
                            <input type="hidden" name="rank_[% biblioloo.biblionumber | html %]" value="[% biblioloo.rank | html %]" />
1047
                        [% END %]
1048
                    [% END %]
1049
1050
                    <ol>
1051
                        <li>
1052
                            <span class="label">Patron:</span>
1053
                            [% IF ( patron.borrowernumber ) %]
1054
                                [% INCLUDE 'patron-title.inc' patron => patron no_title => 1 hide_patron_infos_if_needed => 1 %]
1055
                            [% ELSE %]
1056
                                Not defined yet
1057
                            [% END %]
1058
                        </li>
1059
1060
                        <li>
1061
                            <label for="holdnotes">Notes:</label>
1062
                            <textarea id="holdnotes" name="notes" cols="30" rows="1"></textarea>
1063
                        </li>
1064
                        <li>
1065
                            <label for="pickup">Pickup at:</label>
1066
                            <select name="pickup" id="pickup_multi" data-patron-id="[% patron.borrowernumber | html %]">
1067
                                <option value="" selected="selected"></option>
1068
                                [% FOREACH pickup_location IN multi_pickup_locations %]
1069
                                    <option value="[% pickup_location.branchcode | html %]">[% pickup_location.branchname | html %]</option>
1070
                                [% END %]
1071
                            </select>
1072
                        </li>
1073
                        [% IF ( Koha.Preference('AllowHoldDateInFuture') ) %]
1074
                            <li>
1075
                                <label for="from">Hold starts on date:</label>
1076
                                <input id="reserve_date" name="reserve_date" id="from" size="10" type="text" data-date_to="expiration_date" class="flatpickr" data-flatpickr-futureinclusive="true" />
1077
                            </li>
1078
                        [% END %]
1079
1080
                        <li>
1081
                            <label for="to">Hold expires on date:</label>
1082
                            <input id="expiration_date" name="expiration_date" id="to" size="10" type="text" class="flatpickr" data-flatpickr-futuredate="true" />
1083
                        </li>
1084
                    </ol>
1085
                    <table id="requesttitles">
1086
                        <tr>
1087
                            <th>&nbsp;</th>
1088
                            <th>Pickup location</th>
1089
                            <th>Title</th>
1090
                            [% UNLESS Koha.Preference('item-level_itypes') %]
1091
                                <th>Item type</th>
1092
                            [% END %]
1093
                            <th>Priority</th>
1094
                            <th>Information</th>
1095
                        </tr>
1096
                        [% FOREACH biblioloo IN biblioloop %]
1097
                            <tr [% IF biblioloo.warn %]class="onissue"[% END %]>
1098
                                <td>
1099
                                    [% UNLESS ( biblioloo.warn ) %]
1100
                                        <input
1101
                                            id="holdable_bibs"
1102
                                            name="holdable_bibs"
1103
                                            class="multi_hold_item_checkbox"
1104
                                            type="checkbox"
1105
                                            checked="checked"
1106
                                            title="[% biblioloo.biblionumber | html %]"
1107
                                            value="[% biblioloo.biblionumber | html %]"
1108
                                        />
1109
                                    [% END %]
1110
                                </td>
1111
                                <td>
1112
                                    [% UNLESS ( biblioloo.none_avail || biblioloo.noitems ) %]
1113
                                        <select
1114
                                            name="pickup_[% biblioloo.biblionumber | html %]"
1115
                                            class="multi_pickup_select"
1116
                                            data-biblio-id="[% biblioloo.biblionumber | html %]"
1117
                                            data-patron-id="[% patron.borrowernumber | html %]"
1118
                                            data-pickup-locations="[% biblioloo.pickup_locations_codes.json | $raw %]"
1119
                                        >
1120
                                            <option value=""></option>
1121
                                            [% FOREACH pickup_location IN biblioloo.pickup_locations %]
1122
                                                <option value="[% pickup_location.branchcode | html %]">[% pickup_location.branchname | html %]</option>
1123
                                            [% END %]
1124
                                        </select>
1125
                                    [% END %]
1126
                                </td>
1127
                                <td>
1128
                                    <ul>
1129
                                        <li>
1130
                                            <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblioloo.biblionumber | uri %]">[% biblioloo.title | html %]</a>
1131
                                            [% IF biblioloo.author %]by [% biblioloo.author | html %][% END %]
1132
                                        </li>
1133
                                        [% IF ( biblioloo.publicationyear ) %]
1134
                                            <li> <span class="label">Publication year:</span> [% biblioloo.publicationyear | html %] </li>
1135
                                        [% END %]
1136
                                    </ul>
1137
                                    [% IF ( biblioloo.warn ) %]
1138
                                        <span class="not_holdable" title="[% biblioloo.biblionumber | html %]"></span>
1139
                                    [% END %]
1140
                                </td>
1141
                                [% UNLESS Koha.Preference('item-level_itypes') %]
1142
                                    <td>
1143
                                        <img src="[% biblioloo.itemtype.image_location | html %]" alt="[% biblioloo.itemtype.translated_description | html %]" title="[% biblioloo.itemtype.translated_description | html %]" />
1144
                                    </td>
1145
                                [% END %]
1146
                                <td>[% biblioloo.rank | html %]</td>
1147
                                <td>
1148
                                    [% IF ( biblioloo.checked_previously ) %]
1149
                                        <span>Patron has previously checked out this title</span><br />
1150
                                    [% END %]
1151
                                    [% IF ( biblioloo.alreadyres ) %]
1152
                                        <ul>
1153
                                            <li> [% INCLUDE 'patron-title.inc' patron => patron no_title => 1 no_cardnumber => 1 hide_patron_infos_if_needed => 1 %] <strong>already has a hold</strong> on this item </li>
1154
                                        </ul>
1155
                                    [% END %]
1156
                                    [% IF ( biblioloo.none_avail || biblioloo.noitems ) %]
1157
                                        <ul
1158
                                            ><li> <strong>No items are available</strong> to be placed on hold</li></ul
1159
                                        >
1160
                                    [% END %]
1161
                                </td>
1162
                            </tr>
1163
                        [% END # /FOREACH biblioloo %]
1164
                    </table>
1165
                    <!-- /#requesttitles -->
1166
                </fieldset>
1167
                <fieldset class="action">
1168
                    [% IF ( patron AND patron.borrowernumber ) %]
1169
                        [% IF ( override_required ) %]
1170
                            <button type="submit" id="hold_multi_btn" class="btn btn-primary warning"><i class="fa fa-exclamation-triangle "></i> Place holds</button>
1171
                        [% ELSIF ( no_bibs_available ) %]
1172
                            <button type="submit" id="hold_multi_btn" class="btn btn-primary btn-disabled" disabled="disabled">Place holds</button>
1173
                        [% ELSIF ( none_available ) %]
1174
                            <button type="submit" id="hold_multi_btn" class="btn btn-primary">Place holds</button>
1175
                        [% ELSE %]
1176
                            <button type="submit" id="hold_multi_btn" class="btn btn-primary" id="multi_hold_submit">Place holds</button>
1177
                        [% END %]
1178
                    [% END # /IF patron %]
1179
                </fieldset>
1180
                <!-- /.action -->
1181
            </form>
1182
            <!-- /#hold-request-form -->
1183
        [% END # /UNLESS multi_hold %]
1184
    [% END %]
1185
1186
    [% UNLESS ( patron ) %]
1187
        [% UNLESS borrowers %]
1188
            [% SET hold_count = biblio.holds.count | html %]
1189
            [% IF hold_count %]
1190
                <label for="always_show_holds">Always show holds</label>
1191
                [% IF always_show_holds == 'DONT' %]
1192
                    <input type="checkbox" name="always_show_holds" id="always_show_holds" value="DO" />
1193
                    [% UNLESS reserveloop %]
1194
                        <a class="btn btn-default" value="Show holds" id="show_holds_now" href="/cgi-bin/koha/reserve/request.pl?biblionumber=[% biblio.biblionumber | uri %]&show_holds_now=1">Show holds ([% hold_count | html %])</a>
1195
                    [% END %]
1196
                [% ELSE %]
1197
                    <input type="checkbox" name="always_show_holds" value="DO" id="always_show_holds" checked="checked" />
1198
                [% END %]
1199
            [% END %]
1200
        [% END %]
1201
        [% IF ( reserveloop ) %]
1202
            <form id="existing_holds" name="T[% time | html %]" action="modrequest.pl" method="post" style="display:block">
1203
                [% INCLUDE 'csrf-token.inc' %]
1204
                [% IF ( multi_hold ) %]
1205
                    [% FOREACH biblionumber IN biblionumbers %]
1206
                        <input type="hidden" name="biblionumber" value="[% biblionumber | html %]" />
1207
                    [% END %]
1208
                [% END %]
1209
1210
                [% IF enqueued %]
1211
                    <div class="alert alert-info">
1212
                        <p>The job has been enqueued! It will be processed as soon as possible.</p>
1213
                        <p><a href="/cgi-bin/koha/admin/background_jobs.pl?op=view&id=[% job_id | uri %]" title="View detail of the enqueued job">View detail of the enqueued job</a></p>
1214
                    </div>
1215
                [% END %]
1216
1217
                <h2>Existing holds</h2>
1218
                <div id="toolbar" class="btn-toolbar sticky">
1219
                    <div class="btn-group">
1220
                        <input type="hidden" name="op" value="cud-modifyall" />
1221
                        <input type="submit" class="btn btn-primary" name="submit" value="Update hold(s)" />
1222
                    </div>
1223
                    <div class="btn-group">
1224
                        <button class="btn cancel_selected_holds" data-bulk="true"></button>
1225
                    </div>
1226
                    <fieldset id="cancellation-reason-fieldset" class="action" style="display:none">
1227
                        [% SET hold_cancellation = AuthorisedValues.GetAuthValueDropbox('HOLD_CANCELLATION') %]
1228
                        [% IF hold_cancellation.count %]
1229
                            <label for="cancellation-reason">Cancellation reason: </label>
1230
                            <select class="cancellation-reason" name="cancellation-reason" id="cancellation-reason">
1231
                                <option value="">No reason given</option>
1232
                                [% FOREACH reason IN hold_cancellation %]
1233
                                    <option value="[% reason.authorised_value | html %]">[% reason.lib | html %]</option>
1234
                                [% END %]
1235
                            </select>
1236
                        [% END %]
1237
                    </fieldset>
1238
                </div>
1239
                <div class="page-section">
1240
                    [% FOREACH biblioloo IN biblioloop %]
1241
                        [% IF ( biblioloo.reserveloop ) %]
1242
                            <div class="hold_title" id="hold_title_[% biblioloo.biblionumber | html %]">
1243
                                [% IF ( multi_hold ) %]
1244
                                    <h3>
1245
                                        <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblioloo.biblionumber | uri %]"> [% biblioloo.title | html %] </a>
1246
                                        <span class="badge text-bg-info"><span>[% biblioloo.reserveloop.size | html %] [% tn('Hold', 'Holds', biblioloo.reserveloop.size) | $raw %]</span></span>
1247
                                    </h3>
1248
                                [% END %]
1249
1250
                                [% IF Koha.Preference('HoldsSplitQueue') == 'branch' %]
1251
1252
                                    [% SET branchcodes = [] %]
1253
1254
                                    [% FOREACH h IN biblioloo.reserveloop %]
1255
                                        [% branchcodes.push( h.branchcode ) %]
1256
                                    [% END %]
1257
                                    [% branchcodes = branchcodes.unique %]
1258
                                    [% IF ( branchcodes.empty ) %]
1259
                                        <div class="alert alert-info"> There are no holds on this title. </div>
1260
                                    [% ELSE %]
1261
1262
                                        [% FOREACH b IN branchcodes.sort %]
1263
                                            [% SET holds_by_branch = [] %]
1264
                                            [% FOREACH h IN biblioloo.reserveloop %]
1265
                                                [% IF h.branchcode == b %]
1266
                                                    [% holds_by_branch.push( h ) %]
1267
                                                [% END %]
1268
                                            [% END %]
1269
                                            <div class="holds_by_library">
1270
                                                <h4>[% Branches.GetName( b ) | html %]</h4>
1271
1272
                                                [% INCLUDE holds_table.inc holds=holds_by_branch %]
1273
                                            </div>
1274
                                        [% END # /FOREACh b %]
1275
                                    [% END # /IF ( branchcodes.empty ) %]
1276
                                [% ELSIF Koha.Preference('HoldsSplitQueue') == 'itemtype' %]
1277
1278
                                    [% SET itemtypes = [] %]
1279
1280
                                    [% FOREACH h IN biblioloo.reserveloop %]
1281
                                        [% SET hold_itemtype = h.object.item.effective_itemtype || h.itemtype %]
1282
                                        [% itemtypes.push( hold_itemtype ) %]
1283
                                    [% END %]
1284
                                    [% itemtypes = itemtypes.unique %]
1285
                                    [% IF ( itemtypes.empty ) %]
1286
                                        <div class="alert alert-info"> There are no holds on this title. </div>
1287
                                    [% ELSE %]
1288
1289
                                        [% FOREACH i IN itemtypes.sort %]
1290
                                            [% SET holds_by_itemtype = [] %]
1291
                                            [% FOREACH h IN biblioloo.reserveloop %]
1292
                                                [% SET hold_itemtype = h.object.item.effective_itemtype || h.itemtype %]
1293
                                                [% IF hold_itemtype == i %]
1294
                                                    [% holds_by_itemtype.push( h ) %]
1295
                                                [% END %]
1296
                                            [% END %]
1297
1298
                                            <div class="holds_by_itemtype">
1299
                                                [% IF i %]
1300
                                                    <h4>[% ItemTypes.GetDescription( i ) | html %]</h4>
1301
                                                [% ELSE %]
1302
                                                    <h4>Any item type</h4>
1303
                                                [% END %]
1304
                                                [% INCLUDE holds_table.inc holds=holds_by_itemtype %]
1305
                                            </div>
1306
                                        [% END # /FOREACH i %]
1307
                                    [% END # /IF ( itemtypes.empty ) %]
1308
                                [% ELSIF Koha.Preference('HoldsSplitQueue') == 'branch_itemtype' %]
1309
                                    [% SET branchcodes = [] %]
1310
1311
                                    [% FOREACH h IN biblioloo.reserveloop %]
1312
                                        [% branchcodes.push( h.branchcode ) %]
1313
                                    [% END %]
1314
                                    [% branchcodes = branchcodes.unique %]
1315
                                    [% IF ( branchcodes.empty ) %]
1316
                                        <div class="alert alert-info"> There are no holds on this title. </div>
1317
                                    [% ELSE %]
1318
1319
                                        [% FOREACH b IN branchcodes.sort %]
1320
                                            <div class="holds_by_library">
1321
                                                <h4 class="library_holds">[% Branches.GetName( b ) | html %]</h4>
1322
                                                [% SET holds_by_branch = [] %]
1323
                                                [% FOREACH h IN biblioloo.reserveloop %]
1324
                                                    [% IF h.branchcode == b %]
1325
                                                        [% holds_by_branch.push( h ) %]
1326
                                                    [% END %]
1327
                                                [% END %]
1328
1329
                                                [% SET itemtypes = [] %]
1330
                                                [% FOREACH h IN holds_by_branch %]
1331
                                                    [% SET hold_itemtype = h.object.item.effective_itemtype || h.itemtype %]
1332
                                                    [% itemtypes.push( hold_itemtype ) %]
1333
                                                [% END %]
1334
                                                [% itemtypes = itemtypes.unique %]
1335
1336
                                                [% FOREACH i IN itemtypes.sort %]
1337
                                                    <div class="holds_by_itemtype">
1338
                                                        <h5 class="itemtype_holds">
1339
                                                            [% IF i %]
1340
                                                                [% ItemTypes.GetDescription( i ) | html %]
1341
                                                            [% ELSE %]
1342
                                                                <span>Any item type</span>
1343
                                                            [% END %]
1344
                                                        </h5>
1345
1346
                                                        [% SET holds_by_itemtype = [] %]
1347
                                                        [% FOREACH h IN holds_by_branch %]
1348
                                                            [% SET hold_itemtype = h.object.item.effective_itemtype || h.itemtype %]
1349
                                                            [% IF hold_itemtype == i %]
1350
                                                                [% holds_by_itemtype.push( h ) %]
1351
                                                            [% END %]
1352
                                                        [% END %]
1353
                                                        [% INCLUDE holds_table.inc holds=holds_by_itemtype %]
1354
                                                    </div>
1355
                                                    <!-- /.holds_by_itemtype -->
1356
                                                [% END %]
1357
                                            </div>
1358
                                            <!-- /.holds_by_library -->
1359
                                        [% END # /FOREACH b %]
1360
                                    [% END # /IF ( branchcodes.empty ) %]
1361
                                [% ELSE %]
1362
1363
                                    [% IF ( biblioloo.reserveloop.size ) %]
1364
                                        [% INCLUDE holds_table.inc holds=biblioloo.reserveloop %]
1365
                                    [% ELSE %]
1366
                                        <div class="alert alert-info"> There are no holds on this title. </div>
1367
                                    [% END %]
1368
                                [% END # /IF HoldsSplitQueue %]
1369
                            </div>
1370
                            <!-- /hold_title -->
1371
                        [% END # /IF biblioloo.reserveloop %]
1372
                    [% END # FOREACH biblioloo %]
1373
                </div>
1374
            </form>
1375
            <!-- /#existing_holds -->
1376
        [% END # IF reserveloop %]
1377
    [% END # UNLESS patron %]
1378
[% END %]
1379
1380
<div id="cancelModal" class="modal" tabindex="-1" role="dialog" aria-hidden="true">
1381
    <div class="modal-dialog">
1382
        <div class="modal-content">
1383
            <div class="modal-header">
1384
                <h1 class="modal-title">Confirm deletion</h1>
1385
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
1386
            </div>
1387
1388
            <form id="cancel_modal_form" method="post" action="request.pl">
1389
                [% INCLUDE 'csrf-token.inc' %]
1390
                <div id="inputs">
1391
                    <input type="hidden" name="op" value="cud-cancel" />
1392
                </div>
1393
1394
                <div class="modal-body">
1395
                    <p>Are you sure you want to cancel this hold?</p>
1396
                    <div id="cancel_hold_alert" class="alert alert-danger" style="display:none;"></div>
1397
                    <fieldset class="action">
1398
                        [% SET hold_cancellation = AuthorisedValues.GetAuthValueDropbox('HOLD_CANCELLATION') %]
1399
                        [% IF hold_cancellation.count %]
1400
                            <label for="modal-cancellation-reason">Cancellation reason: </label>
1401
                            <select class="cancellation-reason" name="cancellation-reason" id="modal-cancellation-reason">
1402
                                <option value="">No reason given</option>
1403
                                [% FOREACH reason IN hold_cancellation %]
1404
                                    <option value="[% reason.authorised_value | html %]">[% reason.lib | html %]</option>
1405
                                [% END %]
1406
                            </select>
1407
                        [% END %]
1408
                    </fieldset>
1409
                </div>
1410
1411
                <div class="modal-footer">
1412
                    <button id="cancelModalConfirmBtn" type="submit" class="btn btn-danger">Confirm cancellation</button>
1413
                    <button type="button" class="btn btn-default" data-bs-dismiss="modal">Cancel</button>
1414
                </div>
1415
            </form>
1416
        </div>
1417
    </div>
1418
</div>
1419
<div id="hold-actions">
1420
    <form id="hold-actions-form"> [% INCLUDE 'csrf-token.inc' %] </form>
1421
</div>
1422
1423
[% MACRO jsinclude BLOCK %]
1424
    [% INCLUDE 'datatables.inc' %]
1425
    [% INCLUDE 'calendar.inc' %]
1426
    [% INCLUDE 'select2.inc' %]
1427
    [% Asset.js("js/holds.js") | $raw %]
1428
    [% Asset.js("js/form-submit.js") | $raw %]
1429
1430
    [% SET url_biblio_params = "biblionumber=" _ biblionumbers.join("&amp;biblionumber=") %]
1431
    [% IF multi_hold %]
1432
        [% SET url_biblio_params = url_biblio_params _ "&amp;multi_hold=1" %]
1433
    [% END %]
1434
    <script>
1435
        $(document).ready(function () {
1436
            hold_table_settings = [% TablesSettings.GetTableSettings( 'circ', 'holds', 'patron_holds_table', 'json' ) | $raw %];
1437
            $("#patron_holds_table").kohaTable(
1438
                {
1439
                    bPaginate: false,
1440
                    bKohaColumnsUseNames: true,
1441
                },
1442
                hold_table_settings
1443
            );
1444
        });
1445
        var biblionumbers = [[% biblionumbers.join(', ') | $raw %]];
1446
        var borrowernumber = "[% patron.borrowernumber | $raw %]";
1447
        var patron_homebranch = "[% To.json( Branches.GetName( patron.branchcode ) ) | $raw %]";
1448
        var override_items = {[% FOREACH biblio_info IN biblioloop %][% FOREACH itemloo IN biblio_info.itemloop %][% IF ( itemloo.override ) %]
1449
        [% itemloo.itemnumber | html %]: {
1450
            homebranch: "[% To.json( Branches.GetName( itemloo.homebranch ) ) | $raw %]",
1451
            holdallowed: "[% itemloo.holdallowed | html %]"
1452
            },
1453
            [% END %][% END %][% END %]
1454
        };
1455
        var ERROR_MAP = {
1456
            damaged: _("Item damaged"),
1457
            ageRestricted: _("Age restricted"),
1458
            tooManyHoldsForThisRecord: _("Exceeded max holds per record"),
1459
            tooManyReservesToday: _("Daily hold limit reached for patron"),
1460
            tooManyReserves: _("Too many holds"),
1461
            notReservable: _("Not holdable"),
1462
            noReservesAllowed: _("No reserves allowed"),
1463
            cannotReserveFromOtherBranches: _("Patron is from different library"),
1464
            itemAlreadyOnHold: _("Patron already has hold for this item"),
1465
            cannotBeTransferred: _("Cannot be transferred to pickup library"),
1466
            pickupNotInHoldGroup: _("Only pickup locations within the same hold group are allowed")
1467
        }
1468
1469
        var MSG_CANCEL_SELECTED = _("Cancel selected (%s)");
1470
        var MSG_CANCEL_ALERT    = _("This action will cancel <span class='badge'>%s</span> hold(s).");
1471
        $.fn.select2.defaults.set("width", "100%" );
1472
        $.fn.select2.defaults.set("dropdownAutoWidth", true );
1473
1474
        $(document).ready(function() {
1475
            $('#cancellation-reason-fieldset').hide();
1476
            $('.rank-request').on('change', function() {
1477
                if ( $(".rank-request option:selected[value='del']").length ) {
1478
                    $('#cancellation-reason-fieldset').show();
1479
                } else {
1480
                    $('#cancellation-reason-fieldset').hide();
1481
                }
1482
            });
1483
1484
            if( $("#circ_holds_select").length > 0 ){
1485
                [% SET active = clubs ? 1 : 0 %]
1486
                /* Set active tab based on whether a club search was submitted */
1487
                var tabs = $("#circ_holds_select li:eq(" + [% active | $raw %] + ") a").tab("show");
1488
                $( tabs[0].hash ).find("input.focus").focus();
1489
1490
                /* Change active focus when tabs change */
1491
                $("#circ_holds_select a[data-bs-toggle='tab']").on("shown.bs.tab", function (e) {
1492
                    active_tab = e.target.hash;
1493
                    $( active_tab ).find("input.focus").focus();
1494
                });
1495
            }
1496
1497
1498
            ToggleHoldsToPlace();
1499
            $("#requestany,.requestspecific[name='request'],.requestgrp").on('change', function(){
1500
                ToggleHoldsToPlace();
1501
            });
1502
1503
            [% IF Koha.Preference('UseBranchTransferLimits') %]
1504
                $("#pickup,#pickup-next-avail,#pickup-item-group").on('change', function(){
1505
                    var pickup = $(this).val();
1506
                    var url = "?pickup=" + pickup;
1507
                    url += "&borrowernumber=" + borrowernumber;
1508
                    url += "&biblionumber=" + biblionumbers[0];
1509
                    window.location.replace(url);
1510
                });
1511
            [% END %]
1512
1513
            var my_table = $("#requestspecific").kohaTable({
1514
                paginate: false,
1515
                dom: '<"top pager"ilf>t',
1516
            });
1517
1518
            $("#club-request-form").on("submit", function() {
1519
                let $t = $(this);
1520
                $('.clubalert, .holdalert').addClass('hide');
1521
                const data = {
1522
                    pickup_library_id: $('select[name="pickup"]').val()
1523
                };
1524
                if($('input[name="checkitem"]:checked').length)
1525
                    data.item_id = $('input[name="checkitem"]:checked').val();
1526
                if($('input[name="item_group_id"]:checked').length)
1527
                    data.item_group_id = $('input[name="item_group_id"]:checked').val();
1528
                if($('input[name="borrowernumber"]').length)
1529
                    data.patron_id = $('input[name="borrowernumber"]').val();
1530
                if($('textarea[name="notes"]').length)
1531
                    data.notes = $('textarea[name="notes"]').val()||null;
1532
                if($('input[name="itemtype"]').length) {
1533
                    data.item_type = $('input[name="itemtype"]').val()||null;
1534
                }
1535
                if($('input[name="default_patron_home"]:checked').length) {
1536
                    data.default_patron_home = 1;
1537
                }
1538
1539
                const count = $('input[name="holds_to_place_count"]').length?$('input[name="holds_to_place_count"]').val():1;
1540
                var newloc = 'request.pl?';
1541
                biblionumbers.forEach(function (biblionumber) {
1542
                    newloc += '&biblionumber=' + biblionumber;
1543
                });
1544
1545
                biblionumbers.forEach(function(biblionumber) {
1546
                    data.biblio_id = biblionumber;
1547
                    let options = {
1548
                        url: $t.attr('action'),
1549
                        method: $t.attr('method').toUpperCase(),
1550
                        contentType: 'application/json',
1551
                        data: JSON.stringify(data)
1552
                    };
1553
                    for(let i = 0; i < count; i++) {
1554
                        $.ajax(options)
1555
                        .then(function(result) {
1556
                            document.location = newloc;
1557
                        })
1558
                        .fail(function(err) {
1559
                            var message = err.responseJSON.error;
1560
                            var match = err.responseJSON.error.match(/Reason: (\w+)\s*$/);
1561
                            if(match && ERROR_MAP[match[1]]) {
1562
                                message = '<div><strong>'+_("Cannot place hold")+'</strong></div><div>'+ERROR_MAP[match[1]]+'</div>'
1563
                            }
1564
                            $('.clubalert, .holdalert').removeClass('hide').html(message);
1565
                        });
1566
                    }
1567
                });
1568
1569
                return false;
1570
            });
1571
1572
            [% UNLESS ( multi_hold ) %]
1573
                $("#hold-request-form").on("submit", function(e){
1574
                    return check(e, $(this));
1575
                });
1576
            [% ELSE %]
1577
                $("#hold-request-form").on("submit", function(){
1578
                    return checkMultiHold();
1579
                });
1580
            [% END %]
1581
1582
            $(".pickup_location_dropdown").each( function () {
1583
                $(this).pickup_locations_dropdown();
1584
            });
1585
1586
            $("#pickup_multi").select2({
1587
                width: '30%',
1588
                allowClear: true
1589
            });
1590
1591
            $('.multi_pickup_select').select2({
1592
                width: '100%',
1593
                allowClear: true
1594
            });
1595
1596
            $("#pickup_multi").on("change", function() {
1597
                var selection = $(this).val();
1598
                if ( selection != '' ) {
1599
                    $(".multi_pickup_select").each(function() {
1600
                        var valid_pickup_locations = $(this).data('pickup-locations');
1601
                        if ( valid_pickup_locations.includes(selection) ) {
1602
                            $(this).val(selection);
1603
                            $(this).trigger("change");
1604
                        }
1605
                    });
1606
                }
1607
            });
1608
1609
            $("#pickup,#pickup-item-group,#pickup-next-avail").each( function () {
1610
                $(this).pickup_locations_dropdown();
1611
            });
1612
1613
            $(".pickup_locations").each(function () {
1614
                $(this).pickup_locations_dropdown();
1615
            });
1616
        });
1617
1618
        function ToggleHoldsToPlace() {
1619
            if ( $("#requestany").prop('checked') ) {
1620
                $(".disable_request_any").prop('disabled',true).addClass('disabled').removeClass('enabled');
1621
                $(".enable_request_any").prop('disabled',false).removeClass('disabled').addClass('enabled');
1622
                $(".requestspecific,.requestgrp").prop('checked', false);
1623
            } else if( $(".requestspecific").prop('checked') ) {
1624
                $(".disable_request_specific").prop('disabled',true).addClass('disabled').removeClass('enabled');
1625
                $(".enable_request_specific").prop('disabled',false).removeClass('disabled').addClass('enabled');
1626
                $("#requestany,.requestgrp").prop('checked', false);
1627
            } else {
1628
                $(".disable_request_group").prop('disabled',true).addClass('disabled').removeClass('enabled');
1629
                $(".enable_request_group").prop('disabled',false).removeClass('disabled').addClass('enabled');
1630
                $("#requestany,.requestspecific").prop('checked', false);
1631
            }
1632
        }
1633
1634
        $('.any_specific').click(function() {
1635
            const fieldset = $(this).find('fieldset:first');
1636
1637
            if ( fieldset.hasClass('disabled') ) {
1638
                $('.enable_request_specific, .enable_request_any, .enable_request_group').removeClass('enabled');
1639
                const specific_cb = $(this).find('#requestspecificitem');
1640
                const any_cb = $(this).find('#requestany');
1641
                const itemgroup_cb = $(this).find('#requestgrp');
1642
1643
                if ( specific_cb.length ) {
1644
                    specific_cb.prop('checked', true);
1645
                } else if ( any_cb.length ) {
1646
                    any_cb.prop('checked', true);
1647
                } else {
1648
                    itemgroup_cb.prop('checked', true);
1649
                }
1650
1651
                fieldset.removeClass('disabled').addClass('enabled');
1652
                ToggleHoldsToPlace();
1653
            }
1654
        });
1655
1656
        function check( e, table ) {
1657
1658
            var msg = "";
1659
1660
            if ( $(".requestspecific").is(":checked") ) {
1661
                // requestany not selected, go through the item-specific cases
1662
                var selected_items = $('#requestspecific input[name="checkitem"]:checked');
1663
                if ( selected_items.length > 0 ) {
1664
                    // got item-specific hold requests in the form!
1665
                    // verify they have a pickup location selected
1666
1667
                    if ( selected_items.closest('tr').find(".pickup_locations").val() == '' ) {
1668
1669
                        msg = _("- Please select a pickup location for the item") + "\n"
1670
                    }
1671
                }
1672
                else {
1673
                    msg = _("- Please select an item to place a hold") + "\n";
1674
                }
1675
            } else if ( $("#requestgrp").is(":checked") ) {
1676
                var selected_group = $('#requestgroup input[type="radio"]:checked');
1677
                if( selected_group.length > 0 ){
1678
                    if( $("#pickup-item-group").length < 1 || $("#pickup-item-grp").val() == "" ){
1679
                        msg = _("- Please select a pickup location for this hold" + "\n");
1680
                    }
1681
                } else {
1682
                    msg = (_("- Please select an item group to place a hold") + "\n");
1683
                }
1684
            } else {
1685
                // Requesting next available
1686
                if( $("#pickup-next-avail").length < 1 || $("#pickup-next-avail").val() == "" || $('#pickup-next-avail').val() === null ){
1687
                    msg = _("- Please select a pickup location for this hold") + "\n";
1688
                }
1689
            }
1690
1691
1692
            if (msg == "") {
1693
                $('#hold-request-form').preventDoubleFormSubmit();
1694
                return(true);
1695
            } else {
1696
                e.preventDefault();
1697
                alert(msg);
1698
                return(false);
1699
            }
1700
        }
1701
1702
        function checkMultiHold() {
1703
1704
            var selected_bibs = $(".multi_hold_item_checkbox:checked");
1705
            if ( selected_bibs.length > 0 ) {
1706
                // there are biblios selected in the form!
1707
                // verify they have a pickup location selected
1708
1709
                var pickup_not_set = 0;
1710
                selected_bibs.each(function() {
1711
                    if ( $(this).closest('tr').find(".multi_pickup_select").val() === "" ) {
1712
                        pickup_not_set++;
1713
                    }
1714
                    else {
1715
                        var bibnum = $(this).attr("title");
1716
                    }
1717
                });
1718
                if ( pickup_not_set > 0 ) {
1719
                    alert( _("Please make sure all selected titles have a pickup location set") + "\n" );
1720
                    return false;
1721
                }
1722
            }
1723
            else {
1724
                alert( _("Please select at least one title") + "\n" );
1725
                return false;
1726
            }
1727
1728
            $('#hold-request-form').preventDoubleFormSubmit();
1729
1730
            return true;
1731
        }
1732
1733
         $(document).ready(function() {
1734
1735
            $("#always_show_holds").change(function(){
1736
                if( $(this).prop('checked') ){
1737
                    document.cookie = 'always_show_holds=DO';
1738
                } else {
1739
                    document.cookie = 'always_show_holds=DONT';
1740
                }
1741
            });
1742
            $("input.needsoverride").click(function() { // This must be before the radio button/checkbox switch logic
1743
                var itemnumber = this.value;
1744
                var msg = '';
1745
1746
                switch (override_items[itemnumber].holdallowed) {
1747
                    case "not_allowed": msg = _("This item normally cannot be put on hold."); break;
1748
                    case "from_home_library": msg = _("This item normally cannot be put on hold except for patrons from %s.").format(override_items[itemnumber].homebranch); break;
1749
                }
1750
1751
                msg += "\n\n" + _("Place hold on this item?");
1752
1753
                return confirm(msg);
1754
            });
1755
            $("button.warning").click(function() {
1756
                return confirm( _("None of these items can normally be put on hold for this patron.") + "\n\n" + _("Place hold?") );
1757
            });
1758
            var prev_rank_request;
1759
            $("select[name=rank-request]").on("focus", function() {
1760
                prev_rank_request = $(this).val();
1761
                var row = $(this).parents("tr:first");
1762
            }).change(function() {
1763
                var row = $(this).parents("tr:first");
1764
                var value = parseInt($(this).val());
1765
                var found_holds = $("select[name='rank-request'][disabled='disabled']").length ; //Count how many are found
1766
                if( !isNaN(value) ) {  //If moved to 'del'
1767
                    var after = row.parent().find(`tr:nth-child(${value+found_holds})`); //Go to the row 1 after the new value (and skip found holds)
1768
                    if (prev_rank_request > value) {
1769
                        row.insertBefore(after);
1770
                    } else {
1771
                        row.insertAfter(after);
1772
                    }
1773
                }
1774
1775
                var next_priority = 1;
1776
                $("select[name=rank-request]").each(function () {
1777
                    if( isNaN( $(this).val() ) ){ return true; } //Don't reset found or del holds
1778
                    $(this).val(next_priority);
1779
                    next_priority++;
1780
                });
1781
            });
1782
1783
            $(".clear-date").on("click",function(e){
1784
                e.preventDefault();
1785
                var fieldID = this.id.replace("clear-date-","");
1786
                $("#" + fieldID).val("");
1787
            });
1788
1789
            // Confirm cancellation of hold
1790
            let cancel_link;
1791
            $(".cancel-hold").on("click",function(e) {
1792
                e.preventDefault;
1793
                cancel_link = $(this);
1794
                $("#cancel_modal_form #inputs").empty();
1795
                    let reserve_id = cancel_link.data('id');
1796
                    let biblionumber = cancel_link.data('biblionumber');
1797
                    $("#cancel_modal_form #inputs").append('<input type="hidden" name="reserve_id" value="' + reserve_id + '">');
1798
                    $("#cancel_modal_form #inputs").append('<input type="hidden" name="biblionumber" value="' + biblionumber + '">');
1799
                    $("#cancel_modal_form #inputs").append('<input type="hidden" name="op" value="cud-cancel">');
1800
                $('#cancelModal').modal('show');
1801
                return false;
1802
            });
1803
1804
            [% UNLESS ( patron || patron.borrowernumber || borrowers || noitems || nobiblio ) %]
1805
                [% IF ( PatronAutoComplete ) %]
1806
                    patron_autocomplete($(".search_patron_filter"), { 'link-to': 'reserve', 'url-params': '[% url_biblio_params | url %]' });
1807
                [% END %]
1808
            [% END %]
1809
1810
            [% IF Koha.Preference('EnableItemGroupHolds') %]
1811
                $(':radio[name="item_group_id"]').change(function(){
1812
                    $('input[name="checkitem"]').prop('checked', false);
1813
                });
1814
1815
                $('input[name="checkitem"]').change(function(){
1816
                    $(':radio[name="item_group_id"]').prop('checked', false);
1817
                });
1818
            [% END %]
1819
1820
            if(!localStorage.selectedHolds  || document.referrer.replace(/\?.*/, '') !== document.location.origin+document.location.pathname) {
1821
                localStorage.selectedHolds = [];
1822
            }
1823
1824
            $('.holds_table .select_hold').each(function() {
1825
                if(localStorage.selectedHolds.includes($(this).data('id'))) {
1826
                    $(this).prop('checked', true);
1827
                }
1828
            });
1829
1830
            $('.holds_table .select_hold_all').each(function() {
1831
                var table = $(this).parents('.holds_table');
1832
                var count = $('.select_hold:not(:checked)', table).length;
1833
                $('.select_hold_all', table).prop('checked', !count);
1834
            });
1835
1836
            $('.cancel_selected_holds').html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked').length));
1837
1838
            $('.holds_table .select_hold_all').click(function() {
1839
                var table = $(this).parents('.holds_table');
1840
                var count = $('.select_hold:checked', table).length;
1841
                $('.select_hold', table).prop('checked', !count);
1842
                $(this).prop('checked', !count);
1843
                $('.cancel_selected_holds').html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked').length));
1844
                $('#cancel_hold_alert').html( MSG_CANCEL_ALERT.format($('.holds_table .select_hold:checked').length));
1845
                $('#cancel_hold_alert').show();
1846
                localStorage.selectedHolds = $('.holds_table .select_hold:checked').toArray().map(el => $(el).data('id'));
1847
            });
1848
1849
            $('.holds_table .select_hold').click(function() {
1850
                var table = $(this).parents('.holds_table');
1851
                var count = $('.select_hold:not(:checked)', table).length;
1852
                $('.select_hold_all', table).prop('checked', !count);
1853
                $('.cancel_selected_holds').html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked').length));
1854
                $('#cancel_hold_alert').html( MSG_CANCEL_ALERT.format($('.holds_table .select_hold:checked').length));
1855
                $('#cancel_hold_alert').show();
1856
                localStorage.selectedHolds = $('.holds_table .select_hold:checked').toArray().map(el => $(el).data('id'));
1857
            });
1858
1859
            $('.cancel_selected_holds').click(function(e) {
1860
                e.preventDefault();
1861
                if($('.holds_table .select_hold:checked').length) {
1862
                    cancel_link = $(this);
1863
                    $("#cancel_modal_form #inputs").empty();
1864
                    biblionumbers.forEach( function(biblionumber){
1865
                        $("#cancel_modal_form #inputs").append('<input type="hidden" name="biblionumber" value="'+biblionumber+'">');
1866
                    });
1867
                    $("#cancel_modal_form #inputs").append('<input type="hidden" name="op" value="cud-cancel_bulk">');
1868
                    let hold_ids= $('.holds_table .select_hold:checked').toArray().map(el => $(el).data('id')).join(',');
1869
                    $("#cancel_modal_form #inputs").append('<input type="hidden" name="ids" value="' + hold_ids + '">');
1870
                    delete localStorage.selectedHolds;
1871
                    $('#cancelModal').modal('show');
1872
                }
1873
                return false;
1874
            });
1875
1876
            $(".hold-arrow").click(function(e) {
1877
                e.preventDefault();
1878
                let arrowForm = $("#hold-actions-form").attr({
1879
                    action: 'request.pl',
1880
                    method: 'post'
1881
                });
1882
                let arrow_op = $("<input />").attr({
1883
                    name: 'op',
1884
                    type: 'hidden',
1885
                    value: $(this).data('op')
1886
                });
1887
                let arrow_where = $("<input />").attr({
1888
                    name: 'where',
1889
                    type: 'hidden',
1890
                    value: $(this).data('where')
1891
                });
1892
                let arrow_fp = $("<input />").attr({
1893
                    name: 'first_priority',
1894
                    type: 'hidden',
1895
                    value: $(this).data('first_priority')
1896
                });
1897
                let arrow_lp = $("<input />").attr({
1898
                    name: 'last_priority',
1899
                    type: 'hidden',
1900
                    value: $(this).data('last_priority')
1901
                });
1902
                let arrow_pp = $("<input />").attr({
1903
                    name: 'prev_priority',
1904
                    type: 'hidden',
1905
                    value: $(this).data('prev_priority')
1906
                });
1907
                let arrow_np = $("<input />").attr({
1908
                    name: 'next_priority',
1909
                    type: 'hidden',
1910
                    value: $(this).data('next_priority')
1911
                });
1912
                let arrow_bn = $("<input />").attr({
1913
                    name: 'borrowernumber',
1914
                    type: 'hidden',
1915
                    value: $(this).data('borrowernumber')
1916
                });
1917
                let arrow_bb = $("<input />").attr({
1918
                    name: 'biblionumber',
1919
                    type: 'hidden',
1920
                    value: $(this).data('biblionumber')
1921
                });
1922
                let arrow_ri = $("<input />").attr({
1923
                    name: 'reserve_id',
1924
                    type: 'hidden',
1925
                    value: $(this).data('reserve_id')
1926
                });
1927
                let arrow_date = $("<input />").attr({
1928
                    name: 'date',
1929
                    type: 'hidden',
1930
                    value: $(this).data('date')
1931
                });
1932
                arrowForm.append(arrow_op,arrow_where,arrow_fp,arrow_lp,arrow_pp,arrow_np,arrow_bn,arrow_bb,arrow_ri,arrow_date);
1933
                $("#hold-actions-form").submit();
1934
                return true;
1935
            })
1936
        });
1937
    </script>
1938
    <script>
1939
        table_settings = [% TablesSettings.GetTableSettings( 'circ', 'circulation', 'table_borrowers', 'json' ) | $raw %];
1940
    </script>
1941
    [% UNLESS patron %]
1942
        [% SET search_results_block_id = 'holds_patronsearch_pane_panel' %]
1943
        [%# adjusting variable for patron-search.inc %]
1944
        [% PROCESS patron_search_js table_id => 'table_borrowers', categories => categories, libraries => libraries, columns => columns, open_on_row_click => 1, on_click_url => '/cgi-bin/koha/reserve/request.pl?' _ url_biblio_params, redirect_if_one_result => 1, redirect_url => '/cgi-bin/koha/reserve/request.pl?' _ url_biblio_params, redirect_if_attribute_equal => 'cardnumber' %]
1945
        <script>
1946
            $(document).ready(function () {
1947
                $("#holds_patronsearch").on("submit", filter);
1948
            });
1949
        </script>
1950
    [% END %]
1951
    <script>
1952
        $(".printholdslip").click(function () {
1953
            var reserve_id = $(this).attr("data-reserve_id");
1954
            window.open("/cgi-bin/koha/circ/hold-transfer-slip.pl?reserve_id=" + reserve_id);
1955
            return false;
1956
        });
1957
    </script>
1958
[% END %]
1959
1960
[% INCLUDE 'intranet-bottom.inc' %]
1961
- 

Return to bug 39371