Bug 32910: (follow-up) Replace v4 icon names with v6
[koha.git] / koha-tmpl / intranet-tmpl / prog / en / modules / circ / curbside_pickups.tt
1 [% USE KohaDates %]
2 [% USE Koha %]
3 [% USE ItemTypes %]
4 [% USE Branches %]
5 [% USE AuthorisedValues %]
6 [% USE Asset %]
7 [% USE raw %]
8 [% USE To %]
9 [% SET footerjs = 1 %]
10 [% INCLUDE 'doc-head-open.inc' %]
11 <title>Curbside pickups &rsaquo; Circulation &rsaquo; Koha</title>
12 <style>
13     #pickup-times {
14         width: 50%;
15     }
16     .pickup_time input[type='radio'] {
17         display: none;
18     }
19     .pickup_time {
20         margin: .2em;
21     }
22     .pickup_time label {
23         background-color: #ffffcc;
24         display: inline-block;
25         cursor: pointer;
26         width: 5rem;
27         text-align: center;
28     }
29     .pickup_time input[type='radio']:checked + label {
30         background-color: #bcdb89;
31     }
32     .pickup_time input[type='radio']:disabled+ label {
33         background-color: #ff9090;
34     }
35 </style>
36 [% INCLUDE 'doc-head-close.inc' %]
37 </head>
38
39 [% SET today_iso = date.format(date.now, format = '%Y-%m-%d') %]
40
41 <body id="circ_curbside-pickups" class="circ">
42     [% INCLUDE 'header.inc' %]
43     [% INCLUDE 'cat-search.inc' %]
44
45 [% WRAPPER 'sub-header.inc' %]
46     [% WRAPPER breadcrumbs %]
47         [% WRAPPER breadcrumb_item %]
48             <a href="/cgi-bin/koha/circ/circulation-home.pl">Circulation</a>
49         [% END %]
50         [% WRAPPER breadcrumb_item bc_active = 1 %]
51             <span>Curbside pickups</span>
52         [% END %]
53     [% END #/ WRAPPER breadcrumbs %]
54 [% END #/ WRAPPER sub-header.inc %]
55
56 [% BLOCK waiting_holds %]
57     [% SET waiting_holds = cp.patron.holds.search( found => 'W', branchcode => Branches.GetLoggedInBranchcode ) %]
58     [% FOREACH h IN waiting_holds %]
59        <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% h.biblionumber | uri %]">[% h.biblio.title | html %]</a> ([% h.biblio.author | html %], <a href="/cgi-bin/koha/catalogue/moredetail.pl?itemnumber=[% h.itemnumber | html %]&biblionumber=[% h.biblionumber | html %]#item[% h.itemnumber | html %]">[% h.item.barcode | html %]</a>)<br/>
60     [% END %]
61 [% END %]
62
63 [% BLOCK patron_info %]
64     <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% cp.borrowernumber | uri %]">[% cp.patron.firstname | html %] [% cp.patron.surname | html %] ([% cp.patron.cardnumber | html %])</a>
65     [% IF cp.notes %]
66         <br/>
67         <span>Notes: </span>[% cp.notes | html %]
68     [% END %]
69     [% IF cp.patron.debarred %]
70         <br/>
71         <span class="patron_restricted">Patron's account is restricted</span>
72     [% END %]
73     [% IF cp.patron.has_overdues %]
74         <br />
75         <span class="patron_overdues">Patron has items overdue</span>
76     [% END %]
77 [% END %]
78
79 <div class="main container-fluid">
80     <div class="row">
81         <div class="col-sm-12">
82             <main>
83                 <div class="row">
84                 [% IF Koha.Preference('CircSidebar') %]
85                     <div class="col-sm-10 col-sm-push-2">
86                 [% ELSE %]
87                     <div class="col-sm-12">
88                 [% END %]
89
90                 <h1>Curbside pickups</h1>
91
92                 [% UNLESS policy.enabled %]
93                     <div class="dialog alert">
94                         Curbside pickups are not enabled for your library.
95                     </div>
96                     [% INCLUDE 'intranet-bottom.inc' %]
97                     [% STOP %]
98                 [% END %]
99
100                 [% FOR m IN messages %]
101                     <div class="dialog [% m.type | html %]">
102                         [% SWITCH m.code %]
103                         [% CASE 'not_enabled' %]
104                             <span>The curbside pickup feature is not enabled for this library.</span>
105                         [% CASE 'library_is_closed' %]
106                             <span>Cannot create a curbside pickup for this day, it is a holiday.</span>
107                         [% CASE 'no_waiting_holds' %]
108                             <span>This patron does not have waiting holds.</span>
109                         [% CASE 'too_many_pickups' %]
110                             <span>This patron already has a scheduled pickup for this library.</span>
111                         [% CASE 'no_matching_slots' %]
112                             <span>Wrong slot selected.</span>
113                         [% CASE 'no_more_pickups_available' %]
114                             <span>There are no more pickups available for this slot. Please choose another one.</span>
115                         [% CASE 'cannot_checkout' %]
116                             <span>Unable to check the items out to [% INCLUDE 'patron-title.inc' patron=m.patron %]</span>
117                         [% CASE %]
118                             <span>[% m.code | html %]</span>
119                         [% END %]
120                     </div>
121                 [% END %]
122
123                 <form method="post" class="refresh-form">
124                     <p>
125                         <input type="hidden" name="tab" id="current-tab" value="[% tab | html %]" />
126                         <button type="submit" class="btn btn-default"><i class="fa-solid fa-rotate" aria-hidden="true"></i> Refresh</button>
127
128                         <label>
129                             [% IF auto_refresh %]
130                                 <input type="checkbox" id="auto_refresh" name="auto_refresh" checked="checked" />
131                             [% ELSE %]
132                                 <input type="checkbox" id="auto_refresh" name="auto_refresh" />
133                             [% END %]
134                             Refresh automatically every <input type="text" inputmode="numeric" pattern="[0-9]*" id="refresh_delay" name="refresh_delay" value="[% refresh_delay || 60 | html %]" size="3" /> seconds.
135                         </label>
136
137                         <span id="refresh_info"></span>
138                     </p>
139                 </form>
140
141                 [% SET to_be_staged = curbside_pickups.filter_by_to_be_staged %]
142                 [% SET staged_and_ready = curbside_pickups.filter_by_staged_and_ready %]
143                 [% SET patron_outside = curbside_pickups.filter_by_patron_outside %]
144                 [% SET delivered_today = curbside_pickups.filter_by_delivered %]
145                 <div id="pickup-tabs" class="toptabs">
146                     <ul class="nav nav-tabs" role="tablist">
147                         [% IF !tab OR tab == 'to-be-staged' %]
148                         <li role="presentation" class="active">
149                         [% ELSE %]
150                         <li role="presentation">
151                         [% END %]
152                             <a id="to-be-staged-tab"      href="#to-be-staged" role="tab" data-toggle="tab">To be staged ([% to_be_staged.count | html %])</a>
153                         </li>
154                         [% IF tab == 'staged-and-ready' %]
155                         <li role="presentation" class="active">
156                         [% ELSE %]
157                         <li role="presentation">
158                         [% END %]
159                             <a id="staged-and-ready-tab"  href="#staged-and-ready" role="tab" data-toggle="tab">Staged & ready ([% staged_and_ready.count | html %])</a>
160                         </li>
161                         [% IF tab == 'patron-is-outside' %]
162                         <li role="presentation" class="active">
163                         [% ELSE %]
164                         <li role="presentation">
165                         [% END %]
166                             <a id="patron-is-outside-tab" href="#patron-is-outside" role="tab" data-toggle="tab">Patron is outside ([% patron_outside.count | html %])</a>
167                         </li>
168                         [% IF tab == 'delivered-today' %]
169                         <li role="presentation" class="active">
170                         [% ELSE %]
171                         <li role="presentation">
172                         [% END %]
173                             <a id="delivered-today-tab"   href="#delivered-today" role="tab" data-toggle="tab">Delivered today ([% delivered_today.count | html %])</a>
174                         </li>
175                         [% IF tab == 'schedule-pickup' %]
176                         <li role="presentation" class="active">
177                         [% ELSE %]
178                         <li role="presentation">
179                         [% END %]
180                             <a id="schedule-pickup-tab"   href="#schedule-pickup" role="tab" data-toggle="tab">Schedule pickup</a>
181                         </li>
182                     </ul>
183
184                     <div class="tab-content">
185                         [% IF !tab OR tab == 'to-be-staged' %]
186                         <div id="to-be-staged" role="tabpanel" class="tab-pane active">
187                         [% ELSE %]
188                         <div id="to-be-staged" role="tabpanel" class="tab-pane">
189                         [% END %]
190                             [% IF to_be_staged.count %]
191                                 <table class="table table-striped">
192                                     <thead>
193                                         <tr>
194                                             <th>Pickup date/time</th>
195                                             <th>Patron</th>
196                                             <th>Items for pickup</th>
197                                             <th>Action</th>
198                                         </tr>
199                                     </thead>
200                                     <tbody>
201                                         [% FOREACH cp IN to_be_staged %]
202                                             [% UNLESS cp.staged_datetime %]
203                                                 <tr class="[% class | html %]">
204                                                     <td>[% cp.scheduled_pickup_datetime | $KohaDates with_hours = 1 %]</td>
205                                                     <td>
206                                                         [% PROCESS patron_info %]
207                                                     </td>
208                                                     <td>
209                                                         [% PROCESS waiting_holds %]
210                                                     </td>
211                                                     <td>
212                                                         <form method="post" class="form">
213                                                             <input type="hidden" name="op" value="mark-as-staged"/>
214                                                             <input type="hidden" name="tab" value="to-be-staged"/>
215                                                             <input type="hidden" name="id" value="[% cp.id | html %]"/>
216                                                             <p>
217                                                                 <button type="submit" class="btn btn-default mark-as-staged-and-ready-btn"><i class="fa fa-check" aria-hidden="true"></i> Mark as <i>staged & ready</i></button>
218                                                             </p>
219                                                         </form>
220
221                                                         <form method="post" class="form">
222                                                             <input type="hidden" name="op" value="cancel"/>
223                                                             <input type="hidden" name="tab" value="to-be-staged"/>
224                                                             <input type="hidden" name="id" value="[% cp.id | html %]"/>
225                                                             <p>
226                                                                 <button type="submit" class="btn btn-default cancel-btn"><i class="fa fa-ban" aria-hidden="true"></i> Cancel</button>
227                                                             </p>
228                                                         </form>
229                                                     </td>
230                                                 </tr>
231                                             [% END %]
232                                         [% END %]
233                                     </tbody>
234                                 </table>
235                             [% ELSE %]
236                                 <span>There are no pickups to be staged.</span>
237                             [% END %]
238                         </div>
239
240                         [% IF tab == "staged-and-ready" %]
241                         <div id="staged-and-ready" role="tabpanel" class="tab-pane active">
242                         [% ELSE %]
243                         <div id="staged-and-ready" role="tabpanel" class="tab-pane">
244                         [% END %]
245                             [% IF staged_and_ready.count %]
246                                 <table class="table table-striped">
247                                     <thead>
248                                         <tr>
249                                             <th>Pickup date/time</th>
250                                             <th>Patron</th>
251                                             <th>Items for pickup</th>
252                                             <th>Staged by</th>
253                                             <th>Action</th>
254                                         </tr>
255                                     </thead>
256                                     <tbody>
257                                         [% FOREACH cp IN staged_and_ready %]
258                                             [% IF cp.staged_datetime && !cp.arrival_datetime %]
259                                                 <tr class="[% class | html %]">
260                                                     <td>[% cp.scheduled_pickup_datetime | $KohaDates with_hours = 1 %]</td>
261                                                     <td>
262                                                         [% PROCESS patron_info %]
263                                                     </td>
264                                                     <td>
265                                                         [% PROCESS waiting_holds %]
266                                                     </td>
267                                                     <td>
268                                                         [% cp.staged_by_staff.firstname | html %] [% cp.staged_by_staff.surname | html %]
269                                                     </td>
270                                                     <td>
271                                                         <form method="post" class="form">
272                                                             <input type="hidden" name="op" value="mark-patron-has-arrived"/>
273                                                             <input type="hidden" name="tab" value="staged-and-ready"/>
274                                                             <input type="hidden" name="id" value="[% cp.id | html %]"/>
275                                                             <p>
276                                                                 <button type="submit" class="btn btn-default patron-has-arrived-btn"><i class="fa-solid fa-location-dot" aria-hidden="true"></i> Patron has arrived</button>
277                                                             </p>
278                                                         </form>
279
280                                                         <form method="post" class="form">
281                                                             <input type="hidden" name="op" value="mark-as-delivered"/>
282                                                             <input type="hidden" name="tab" value="staged-and-ready"/>
283                                                             <input type="hidden" name="id" value="[% cp.id | html %]"/>
284                                                             <p>
285                                                                 <button type="submit" class="btn btn-default mark-as-delivered-btn"><i class="fa-solid fa-envelope" aria-hidden="true"></i> Mark as <i>delivered</i></button>
286                                                             </p>
287                                                         </form>
288
289                                                         <form method="post" class="form">
290                                                             <input type="hidden" name="op" value="mark-as-unstaged"/>
291                                                             <input type="hidden" name="tab" value="staged-and-ready"/>
292                                                             <input type="hidden" name="id" value="[% cp.id | html %]"/>
293                                                             <p>
294                                                                 <button type="submit" class="btn btn-default mark-as-to-be-staged-btn"><i class="fa fa-undo" aria-hidden="true"></i> Mark as <i>to be staged</i></button>
295                                                             </p>
296                                                         </form>
297                                                     </td>
298                                                 </tr>
299                                             [% END %]
300                                         [% END %]
301                                     </tbody>
302                                 </table>
303                             [% ELSE %]
304                                 <span>There are no pickups staged and ready.</span>
305                             [% END %]
306                         </div>
307
308                         [% IF tab == "patron-is-outside" %]
309                         <div id="patron-is-outside" role="tabpanel" class="tab-pane active">
310                         [% ELSE %]
311                         <div id="patron-is-outside" role="tabpanel" class="tab-pane">
312                         [% END %]
313                             [% IF patron_outside.count %]
314                                 <table class="table table-striped">
315                                     <thead>
316                                         <tr>
317                                             <th>Pickup date/time</th>
318                                             <th>Patron</th>
319                                             <th>Items for pickup</th>
320                                             <th>Staged by</th>
321                                             <th>Action</th>
322                                         </tr>
323                                     </thead>
324                                     <tbody>
325                                         [% FOREACH cp IN patron_outside %]
326                                             [% IF cp.arrival_datetime && !cp.delivered_datetime %]
327                                                 <tr class="[% class | html %]">
328                                                     <td>[% cp.scheduled_pickup_datetime | $KohaDates with_hours = 1 %]</td>
329                                                     <td>
330                                                         [% PROCESS patron_info %]
331                                                     </td>
332                                                     <td>
333                                                         [% PROCESS waiting_holds %]
334                                                     </td>
335                                                     <td>
336                                                         [% cp.staged_by_staff.firstname | html %] [% cp.staged_by_staff.surname | html %]
337                                                     </td>
338                                                     <td>
339                                                         <form method="post" class="form">
340                                                             <input type="hidden" name="op" value="mark-as-delivered"/>
341                                                             <input type="hidden" name="tab" value="patron-is-outside"/>
342                                                             <input type="hidden" name="id" value="[% cp.id | html %]"/>
343                                                             <p>
344                                                                 <button type="submit" class="btn btn-default mark-as-delivered-btn"><i class="fa-solid fa-envelope" aria-hidden="true"></i> Mark as delivered</button>
345                                                             </p>
346                                                         </form>
347
348                                                         <form method="post" class="form">
349                                                             <input type="hidden" name="op" value="mark-as-staged"/>
350                                                             <input type="hidden" name="tab" value="patron-is-outside"/>
351                                                             <input type="hidden" name="id" value="[% cp.id | html %]"/>
352                                                             <p>
353                                                                 <button type="submit" class="btn btn-default mark-as-staged-and-ready-btn"><i class="fa fa-undo" aria-hidden="true"></i> Mark as <i>staged & ready</i></button>
354                                                             </p>
355                                                         </form>
356
357                                                         <form method="post" class="form">
358                                                             <input type="hidden" name="op" value="mark-as-unstaged"/>
359                                                             <input type="hidden" name="tab" value="patron-is-outside"/>
360                                                             <input type="hidden" name="id" value="[% cp.id | html %]"/>
361                                                             <p>
362                                                                 <button type="submit" class="btn btn-default mark-as-to-be-staged-btn"><i class="fa fa-undo" aria-hidden="true"></i> Mark as <i>to be staged</i></button>
363                                                             </p>
364                                                         </form>
365                                                     </td>
366                                                 </tr>
367                                             [% END %]
368                                         [% END %]
369                                     </tbody>
370                                 </table>
371                             [% ELSE %]
372                                 <span>There are no patrons waiting outside.</span>
373                             [% END %]
374                         </div>
375
376                         [% IF tab == "delivered-today" %]
377                         <div id="delivered-today" role="tabpanel" class="tab-pane active">
378                         [% ELSE %]
379                         <div id="delivered-today" role="tabpanel" class="tab-pane">
380                         [% END %]
381                             [% IF delivered_today.count %]
382                                 <table class="table table-striped">
383                                     <thead>
384                                         <tr>
385                                             <th>Deliver date/time</th>
386                                             <th>Patron</th>
387                                             <th>Items checked out</th>
388                                         </tr>
389                                     </thead>
390                                     <tbody>
391                                         [% FOREACH cp IN delivered_today %]
392                                             [% IF cp.delivered_datetime %]
393                                                 <tr class="[% class | html %]">
394                                                     <td>[% cp.delivered_datetime | $KohaDates with_hours = 1 %]</td>
395                                                     <td>
396                                                         [% PROCESS patron_info %]
397                                                     </td>
398                                                     <td>
399                                                     [% FOREACH c IN cp.checkouts %]
400                                                         [% IF date.format(c.issuedate, format = '%Y-%m-%d') == today_iso %]
401                                                             <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% c.item.biblionumber | uri %]">[% c.item.biblio.title | html %]</a> ([% c.item.biblio.author | html %], <a href="/cgi-bin/koha/catalogue/moredetail.pl?itemnumber=[% c.itemnumber | html %]&biblionumber=[% c.item.biblionumber | html %]#item[% c.itemnumber | html %]">[% c.item.barcode | html %]</a>)<br/>
402                                                         [% END %]
403                                                     [% END %]
404                                                 </td>
405                                             </tr>
406                                         [% END %]
407                                     [% END %]
408                                 </tbody>
409                             </table>
410                         [% ELSE %]
411                             <span>No pickups have been delivered today.</span>
412                         [% END %]
413                     </div>
414
415                     [% IF tab == "schedule-pickup" %]
416                     <div id="schedule-pickup" role="tabpanel" class="tab-pane active">
417                     [% ELSE %]
418                     <div id="schedule-pickup" role="tabpanel" class="tab-pane">
419                     [% END %]
420                         [% IF !patron || ( patron && existing_curbside_pickups.count >= 1 ) %]
421                             [% IF existing_curbside_pickups.count >= 1 %]
422                                 <div class="dialog alert">
423                                     [% patron.firstname | html %] [% patron.surname | html %] ([% patron.cardnumber | html %]) already has a scheduled pickup for this library.
424                                 </div>
425                             [% END %]
426                             <div class="form-group">
427                                 <label class="sr-only" for="input-patron-cardnumber">Cardnumber</label>
428                                 <div class="input-group">
429                                     <div class="input-group-addon">Search a patron</div>
430                                     <input autocomplete="off" id="find-patron" class="form-control" type="text" style="width:25%" class="noEnterSubmit" placeholder="Enter patron cardnumber or name"//>
431                                 </div>
432                             </div>
433                         [% ELSE %]
434                             [% SET waiting_holds = patron.holds.search( found => 'W', branchcode => Branches.GetLoggedInBranchcode ) %]
435                             [% IF !policy.enable_waiting_holds_only || waiting_holds.count > 0 %]
436                                 <form id="create-pickup" method="post">
437                                     <fieldset class="rows" style="float: none;">
438                                         <input type="hidden" name="borrowernumber" value="[% patron.id | html %]"/>
439                                         <input type="hidden" name="op" value="create-pickup"/>
440                                         <input type="hidden" name="tab" value="schedule-pickup"/>
441                                         <ol>
442                                             <li>
443                                                 <label>Patron: </label>
444                                                 <span>[% INCLUDE 'patron-title.inc' patron=patron %]</span>
445                                                 <a title="Search for another patron" href="/cgi-bin/koha/circ/curbside_pickups.pl?tab=schedule-pickup"><i class="fa fa-search"></i></a>
446                                             </li>
447
448                                             <li>
449                                                 <label>Items ready for pickup: </label>
450                                                 <span>
451                                                     [% IF waiting_holds.count %]
452                                                         [% FOREACH h IN waiting_holds %]
453                                                             <p>
454                                                                 <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% h.biblionumber | uri %]">[% h.biblio.title | html %]</a> ([% h.biblio.author | html %], <a href="/cgi-bin/koha/catalogue/moredetail.pl?itemnumber=[% h.itemnumber | html %]&biblionumber=[% h.biblionumber | html %]#item[% h.itemnumber | html %]">[% h.item.barcode | html %]</a>)
455                                                             </p>
456                                                         [% END %]
457                                                     [% ELSE %]
458                                                         <span>There are no waiting holds for this patron at this library.</span>
459                                                     [% END %]
460                                                 </span>
461                                             </li>
462
463                                             <li>
464                                                 <label for="pickup_date">Pickup date: </label>
465                                                 <input id="pickup_date" name="pickup_date" required="required" class="flatpickr" data-flatpickr-futureinclusive="true" />
466                                             </li>
467
468                                             <li id="pickup-times" class="radio"></li>
469
470                                             <li>
471                                                 <label for="notes">Notes: </label>
472                                                 <input id="notes" name="notes" type="text" />
473                                             </li>
474                                         </ol>
475                                     </fieldset>
476
477                                     <fieldset class="action">
478                                         <input type="submit" id="schedule-pickup-button" class="btn btn-primary" value="Submit" />
479                                     </fieldset>
480                                 </form>
481                             [% ELSE %]
482                                 <div class="dialog alert">The patron does not have waitings holds.</div>
483                             [% END %]
484                         [% END %]
485                     </div>
486                 </div>
487                 </div>
488                 [% IF Koha.Preference('CircSidebar') %]
489                     </div> <!-- /.col-sm-10.col-sm-push-2 -->
490                         <div class="col-sm-2 col-sm-pull-10">
491                             <aside>
492                                 [% INCLUDE 'circ-nav.inc' %]
493                             </aside>
494                         </div> <!-- /.col-sm-2.col-sm-pull-10 -->
495                     </div> <!-- /.row -->
496                 [% END %]
497             </main>
498         </div>
499     </div> <!-- /.row -->
500
501 [% MACRO jsinclude BLOCK %]
502     [% Asset.js("lib/dayjs/dayjs.min.js") | $raw %]
503     [% Asset.js("lib/dayjs/plugin/isSameOrAfter.js") | $raw %]
504     [% Asset.js("lib/dayjs/plugin/customParseFormat.js") | $raw %]
505     <script>dayjs.extend(window.dayjs_plugin_isSameOrAfter)</script>
506     <script>dayjs.extend(window.dayjs_plugin_customParseFormat)</script>
507     [% INCLUDE 'calendar.inc' %]
508     [% INCLUDE 'js-patron-format.inc' %]
509     <script>
510         let pickups = [% To.json(curbside_pickups.unblessed) | $raw %];
511         let policy = [% To.json(policy.unblessed) | $raw %];
512
513         let existingPickupMoments = [];
514         pickups.forEach(function(pickup){
515             let scheduled_pickup_datetime = pickup.scheduled_pickup_datetime;
516             let pickupMoment = dayjs(scheduled_pickup_datetime);
517
518             existingPickupMoments.push(pickupMoment);
519         });
520
521         let opening_slots = [% To.json(policy.opening_slots.unblessed) | $raw %];
522         let slots_per_day = {};
523         opening_slots.forEach(function(slot){
524             let day = slot.day;
525             if(!slots_per_day[day]) slots_per_day[day] = [];
526             slots_per_day[day].push(slot);
527         });
528
529         $(document).ready(function() {
530
531             $('#schedule-pickup-tab').on('click', function() {
532                 $('#input-patron-cardnumber').focus();
533             });
534
535             const pickup_date = document.querySelector("#pickup_date");
536             if ( pickup_date ) {
537                 const fp = pickup_date._flatpickr;
538                 fp.set('disable', [function(date) {
539                     return !slots_per_day.hasOwnProperty(date.getDay());
540                 }]);
541             }
542
543             $("#pickup_date").on('change', function() {
544
545                 $('#pickup-times').empty();
546                 $('#schedule-pickup-button').prop( 'disabled', 1 );
547
548                 var currentDate = $(this).val();
549
550                 let selectedDate = dayjs(currentDate);
551
552                 let pickupSlots = [];
553                 let available_count = 0;
554                 let dow = selectedDate.day(); // Sunday is 0 (at least for now)
555                 if (!slots_per_day[dow]){
556                     $('#pickup-times').html("<div>"+_("No pickup time defined for this day.")+"</div>");
557                     return;
558                 }
559
560                 slots_per_day[dow].sort((a, b) => a.start_hour - b.start_hour).forEach(function(slot){
561                     let pickup_interval = policy.pickup_interval;
562                     if (!pickup_interval) {
563                         $('#pickup-times').html("<div>"+_("No pickup time defined for this day.")+"</div>");
564                         return;
565                     }
566
567                     let listStartMoment = selectedDate.hour(slot.start_hour).minute(slot.start_minute);
568                     let listEndMoment = selectedDate.hour(slot.end_hour).minute(slot.end_minute);
569
570                     let keep_going = true;
571                     let now = dayjs();
572
573                     // Initialize pickup slots starting at opening time
574                     let pickupIntervalStartMoment = listStartMoment;
575                     let pickupIntervalEndMoment   = listStartMoment.add(pickup_interval, 'minutes');
576                     while (keep_going) {
577                         let available = true;
578                         let display_slot = true
579
580                         if (pickupIntervalStartMoment.isBefore(now)) {
581                             // Slots in the past are unavailable
582                             available = false;
583                             display_slot = false;
584                         }
585
586                         if (pickupIntervalEndMoment.isAfter(listEndMoment)) {
587                             // Slots after the end of pickup times for the day are unavailable
588                             available = false;
589                         }
590
591                         let pickups_scheduled = 0;
592                         existingPickupMoments.forEach(function(pickupMoment){
593                             // An existing pickup time
594                             if (pickupMoment.isSameOrAfter(pickupIntervalStartMoment) && pickupMoment.isBefore(pickupIntervalEndMoment)) {
595                                 // This calculated pickup is in use by another scheduled pickup
596                                 pickups_scheduled++;
597                             }
598                         });
599
600                         if (pickups_scheduled >= policy.patrons_per_interval) {
601                             available = false;
602                         }
603
604                         if ( display_slot ) {
605                             pickupSlots.push(
606                                 {
607                                     "available": available,
608                                     "moment": pickupIntervalStartMoment,
609                                     "pickups_scheduled": pickups_scheduled
610                                 }
611                             );
612                         }
613
614                         if ( available ) {
615                             available_count++;
616                         }
617
618                         pickupIntervalStartMoment = pickupIntervalEndMoment;
619                         pickupIntervalEndMoment = pickupIntervalStartMoment.add(pickup_interval, 'minutes');
620                         if (pickupIntervalEndMoment.isAfter(listEndMoment)) {
621                             // This latest slot is after the end of pickup times for the day, so we can stop
622                             keep_going = false;
623                         }
624                     }
625                 });
626
627                 for (let i = 0; i < pickupSlots.length; i++) {
628                     let pickupSlot = pickupSlots[i];
629                     let optText = pickupSlot.moment.format("HH:mm");
630                     let optValue = pickupSlot.moment.format("YYYY-MM-DD HH:mm:ss");
631                     let pickups_scheduled = pickupSlot.pickups_scheduled;
632                     let disabled = pickupSlot.available ? "" : "disabled";
633                     $("#pickup-times").append(`<span class="pickup_time"><input type="radio" id="slot_${i}" name="pickup_time" value="${optValue}" ${disabled} /> <label for="slot_${i}">${optText} (${pickups_scheduled})</label></span>`);
634                 }
635
636                 $('#pickup-times').show();
637                 $('#schedule-pickup-button').prop( 'disabled', available_count <= 0 );
638             });
639
640             $("#create-pickup").on('submit', function(){
641                 if ( ! $("input[type='radio']:checked").length ) {
642                     alert(_("Please select a date and a pickup time"))
643                     return false;
644                 }
645                 return true;
646             });
647
648             if ( $("#find-patron").length ) {
649                 patron_autocomplete($("#find-patron"), { 'on-select-callback': function( event, ui ) {
650                         window.location.href = "/cgi-bin/koha/circ/curbside_pickups.pl?op=find-patron&borrowernumber=" + ui.item.patron_id;
651                         return false;
652                     }
653                 });
654             }
655
656             $("#pickup-tabs a[data-toggle='tab']").on("shown.bs.tab", function (e) {
657                 $("#current-tab").val($(this).attr('href').substring(1)); // Remove #
658             });
659             $("#auto_refresh,#refresh_delay").on("change", function(){
660                 set_interval_if_needed();
661             });
662
663             set_interval_if_needed();
664
665         });
666
667         let refresh_interval_id = 0;
668         let countdown_interval_id = 0;
669         function set_interval(refresh_delay_ms){
670             clear_intervals();
671             let next_refresh = new Date();
672             next_refresh.setSeconds(next_refresh.getSeconds() + refresh_delay_ms / 1000);
673
674             countdown_interval_id = setInterval(function() {
675                 const now = new Date().getTime();
676                 const seconds = Math.floor(( next_refresh - now + 1 ) / 1000);
677                 if ( seconds > 0 ) {
678                     $("#refresh_info").text(_("Refresh in %s seconds").format(seconds));
679                 } else {
680                     $("#refresh_info").text(""); // In case something is going wrong
681                 }
682             }, 1000);
683
684             setInterval(function() {
685                 $(".refresh-form:visible").submit();
686             }, refresh_delay_ms);
687         }
688         function clear_intervals(){
689             if (refresh_interval_id) {
690                 clearInterval(refresh_interval_id);
691                 refresh_interval_id = 0;
692             }
693             if (countdown_interval_id) {
694                 clearInterval(countdown_interval_id);
695                 countdown_interval_id = 0;
696             }
697         }
698
699         function set_interval_if_needed(){
700             const refresh_delay = $("#refresh_delay").val();
701             const auto_refresh = $("#auto_refresh").is(":checked");
702
703             if (auto_refresh && refresh_delay){
704                 set_interval(refresh_delay * 1000);
705             } else {
706                 clear_intervals();
707             }
708         }
709     </script>
710 [% END %]
711
712
713 [% INCLUDE 'intranet-bottom.inc' %]