]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/templates-bootstrap/opac/parts/place_hold.tt2
LP2061136 - Stamping 1405 DB upgrade script
[Evergreen.git] / Open-ILS / src / templates-bootstrap / opac / parts / place_hold.tt2
1 [%  PROCESS "opac/parts/misc_util.tt2";
2     PROCESS "opac/parts/hold_error_messages.tt2";
3     PROCESS "opac/parts/metarecord_hold_filters.tt2";
4 %]
5 <script>
6 // Toggle the activation date input and check the suspend checkbox.
7 // If JavaScript is disabled, the CSS will handle the former, but
8 // the latter will not happen.
9 function toggleActivationDate() {
10     var cb = document.getElementById("hold_suspend");
11     var block = document.getElementById("toggled-block-suspend");
12     var anchor = document.getElementById("actDateToggle");
13     var actText = "[%- l('Hide activation date') -%]";
14     var inActText = "[%- l('Set activation date') -%]";
15     // Check for not equal to block so it works on first click.
16     if (block.style.display != "block") {
17         block.style.display = "block";
18         anchor.innerHTML = "<i class='fas fa-calendar' aria-hidden='true'></i> " + actText;
19         if (cb.checked != true) cb.checked = true;
20     } else {
21         block.style.display = "none";
22         anchor.innerHTML = "<i class='fas fa-calendar' aria-hidden='true'></i> " + inActText;
23     }
24     // Prevent the href from being followed, thus overriding the CSS.
25     return false;
26 }
27
28 // Maybe enable or disable the num_copies select when the user selects
29 // or deselects a part.
30 function maybeToggleNumCopies(obj) {
31     var numCopies = document.getElementById("num_copies");
32     // Only if numCopies exists.
33     if (numCopies) {
34         var objValue;
35         if (obj.type == 'radio') {
36             if (obj.checked) objValue = obj.value;
37             else return;
38         } else {
39             objValue = obj.value;
40         }
41         if (objValue && objValue != '') {
42             if (numCopies.value != '1') numCopies.value = '1';
43             if (!numCopies.disabled) numCopies.disabled = true;
44         } else {
45             if (numCopies.disabled) numCopies.disabled = false;
46         }
47     }
48 }
49
50 //Doublecheck whether their default pickup library is valid. Should only be invalid if pulled from disabled home library when the page loads, but adding more checks just in case
51 function checkValidPickupLib()
52 {
53     let org_selector = document.getElementById('pickup_lib');
54     if (org_selector != null && org_selector[org_selector.selectedIndex].disabled == true) {
55
56         //Are they at the default message or the warning?
57         if (org_selector[org_selector.selectedIndex].value == -1){
58             document.getElementById("place_hold_submit").disabled = true;
59             org_selector.style.backgroundColor= "#FFF1A5";
60             org_selector.invalid = true;
61         }
62         else{
63             org_selector.style.backgroundColor= "#FFF1A5";
64             org_selector.invalid = true;
65             document.getElementById("pickup-lib-unavailable-warning").hidden = false;
66             document.getElementById("place_hold_submit").disabled = true;
67         }
68     }
69     else {
70         org_selector.invalid = false;
71         org_selector.style.backgroundColor = "#fff";
72         document.getElementById("pickup-lib-unavailable-warning").hidden = true;
73         document.getElementById("place_hold_submit").disabled = false;
74     }
75 }
76
77 //Create and add a generic option for the start of the selector
78 function createDefaultOption()
79 {
80     let org_selector = document.getElementById('pickup_lib');
81
82     let null_option = document.createElement("option");
83     null_option.innerText = "[% l('Choose a pickup location') %]";
84     null_option.disabled = true;
85     null_option.value = -1;
86     null_option.style.backgroundColor = "#fff";
87     org_selector.add(null_option, 0);
88 }
89
90 //Check if org valid once when the page loads and then every time you change it could be valid again, so check again
91 document.addEventListener("DOMContentLoaded", () => {
92     let org_selector = document.getElementById('pickup_lib');
93
94     //Keep original colors of org unit dropdown for the sake of readability
95     let options = org_selector.children;
96     //We also need the list of all orgs in the list
97     let lib_ids = Array(options.length).fill(0);
98     for (let i = 0; i < options.length; i++){
99         options[i].style.backgroundColor= "#fff";
100         lib_ids[i] = options[i].value;
101     }
102
103     //If the user's default pickup library is not in the dropdown (probably due to being hidden from the OPAC)
104     let default_lib = [% GET ctx.default_pickup_lib %];
105     if (!lib_ids.includes(default_lib.toString())){
106         //Create and use the default message instead
107         createDefaultOption();
108         org_selector.selectedIndex = 0;
109     }
110
111     checkValidPickupLib(); 
112     document.getElementById('pickup_lib').addEventListener("change", checkValidPickupLib);
113
114     });
115
116
117 </script>
118 <div class='container'>
119 <hr>
120    <h3>[% l('Place Hold') %]</h3>
121
122     [% some_holds_allowed = -1 %]
123
124     <!-- loop through the holds and display status of request where appropriate -->
125         [% FOR hdata IN ctx.hold_data;
126             attrs = {marc_xml => hdata.marc_xml};
127             PROCESS get_marc_attrs args=attrs;
128             this_hold_disallowed = 0;
129
130             IF CGI.param('hold_type') == 'M';
131               IF hdata.metarecord_filters.formats.size == 0;
132                 this_hold_disallowed = 1;
133                 # if this is the first hold and it is disallowed,
134                 # assume all holds are, until we proven otherwise
135                 SET some_holds_allowed = 0 IF some_holds_allowed == -1;
136               ELSE; some_holds_allowed = 1; END;
137             END %]
138
139        [% IF loop.first %]
140     <form method="post" name="PlaceHold" onsubmit="return validateHoldForm()" >
141         <input type="hidden" name="hold_type" value="[% CGI.param('hold_type') | html %]" />
142         [%
143             redirect = CGI.param('hold_source_page') || CGI.param('redirect_to') || CGI.referer;
144             # since we have to be logged in to get this far, return to a secure page
145             redirect = redirect.replace('^http:', 'https:')
146         %]
147         <input type="hidden" name="redirect_to" value="[% redirect | html %]" />
148         <input type="hidden" name="hold_source_page" value="[% CGI.param('hold_source_page') | html %]" />
149
150         <!-- Adding hidden fields so that parameters are maintained in
151         searchbar throughout the place hold process. -->
152         <input type="hidden" name="locg" value="[% CGI.param('locg') | html %]" />
153         <input type="hidden" name="qtype" value="[% CGI.param('qtype') | html %]" />
154         <input type="hidden" name="query" value="[% CGI.param('query') | html %]" />
155         [%
156             usr_barcode = CGI.param('usr_barcode') | html;
157             is_requestor = CGI.param('is_requestor');
158
159            IF is_requestor == '';
160                is_requestor = '0';
161            END;
162
163            IF is_requestor == '0' && usr_barcode == ctx.staff_recipient.card.barcode;
164                usr_barcode = '';
165            END;
166         %]
167
168         [% IF ctx.is_staff %]
169         <p class="staff-hold">
170             <input type="radio" id="hold_usr_is_requestor_not"
171                 onchange="staff_hold_usr_input_disabler(this);"
172                 name="hold_usr_is_requestor" value="0"
173                 />
174             <label for="hold_usr_is_requestor_not">
175                 [% l("Place hold for patron by barcode:") %]
176             </label>
177             <input type="text" name="hold_usr" id="hold_usr_input"
178               aria-label="[% l('Barcode') %]"
179               value="[% usr_barcode | html %]"
180               onpaste="return debounce_barcode_change(event)"
181               onkeydown="return debounce_barcode_change(event)" autofocus />
182             <span id="patron_name"></span>
183             <span id="patron_usr_barcode_not_found" style="display: none">
184               [% l('Patron barcode was not found') %]
185             </span>
186             [% IF ctx.is_browser_staff %]
187             <button id="hold_usr_search" type="button" class="btn btn-action" style="display: none;">[% l('Patron Search') %]</button>
188             [% END %]
189             <br />
190             <input type="hidden" id="staff_barcode"
191               value="[% ctx.staff_recipient.card.barcode | html %]"/>
192             <span>
193                 <input type="radio" id="hold_usr_is_requestor"
194                     onchange="staff_hold_usr_input_disabler(this);"
195                     name="hold_usr_is_requestor" value="1" />
196                 <label for="hold_usr_is_requestor">
197                     [% l("Place this hold for me ([_1] [_2])", ctx.user.first_given_name, ctx.user.family_name) | html %]
198                 </label>
199             </span>
200             [% IF CGI.param('hold_type') == 'T' AND ctx.hold_subscriptions.size > 0 AND NOT CGI.param('from_basket') %]
201               <br />
202               <!-- request for a reading group / subscription -->
203               <input type="radio" id="hold_usr_is_subscription"
204                   onchange="staff_hold_usr_input_disabler(this);"
205                   name="hold_usr_is_requestor" value="2"
206                   />
207               <label for="hold_usr_is_subscription">
208                   [% l("Place hold for patron Hold Group:") %]
209               </label>
210               <select id='select_hold_subscription' name='hold_subscription'>
211                   <option selected='selected' value=''>[% l('- Hold Groups -') %]</option>
212                   [% FOR sub IN ctx.hold_subscriptions %]
213                   <option value='[% sub.id %]'>[% sub.name | html %]</option>
214                   [% END %]
215               </select>
216             [% END %]
217             <br/>
218             <label>
219               <input id="override_blocks_subscription" name="override" type="checkbox" checked="checked"/>
220               [% l("Override all hold-blocking conditions possible?") %]
221             </label>
222         </p>
223         [% END %]
224         [% END %]
225
226         <table>
227             <tr>
228                 <td>
229                     [% IF !this_hold_disallowed %]
230                     <input type="hidden" name="hold_target" value="[% hdata.target.id | html %]" />
231                     [% END %]
232                     <div class='hold-items-list-title'>
233                         <!-- If hold is for grouped formats/editions (metarecord), show short title - else, show complete title -->
234                         [% IF CGI.param('hold_type') == 'M' %]
235                             [% attrs.title | html %]
236                         [% ELSE %]
237                             [% attrs.title_extended | html %]
238                         [% END %]
239                     </div>
240                     [% IF hdata.parts AND !this_hold_disallowed %]
241                         [% IF hdata.parts.size > 0 %]
242                         <div class='hold-div'>
243                             [% IF enable.radio.parts == 'true' %]
244                                 <span class='hold-span'><label for='select_hold_part'>[%
245                                l('Select a Part:')
246                                %]</label></span>
247                              <div class='radio-parts-selection'>
248                              [% IF !hdata.part_required %]
249                                 <span class='parts-radio-option'>
250                                  <input type='radio' name='part' value='' onchange='maybeToggleNumCopies(this);' required>[% l('All Parts') %]</span>
251                               [% END %]
252                                [% FOR part IN hdata.parts %]
253                                  <span class='parts-radio-option'><input type='radio' name='part' id=[% part.id %] value=[% part.id %] onchange='maybeToggleNumCopies(this);' required>
254                                   <label for=[% part.id %]>[% part.label | html %]</label></span>
255                               [% END %]
256                               </div>
257                           [% ELSE %]
258                             <span style='font-weight: bold;'><label for='select_hold_part'>[%
259                                 hdata.part_required ? l('Select a Part:') : l('Select a Part (optional):')
260                             %]</label></span>
261                             <select id='select_hold_part' name='part' onchange='maybeToggleNumCopies(this);'>
262                                 [% IF !hdata.part_required %]
263                                 <option selected='selected' value=''>[% l('- All Parts -') %]</option>
264                                 [% END %]
265                                 [% FOR part IN hdata.parts %]
266                                 <option value='[% part.id %]'>[% part.label | html %]</option>
267                                 [% END %]
268                             </select>
269                           [% END %]
270                         </div>
271                         [% ELSE %]
272                         <input type='hidden' name='part' value=''/>
273                         [% END %]
274                     [% END %]
275             [% INCLUDE "opac/parts/multi_hold_select.tt2" IF NOT (this_hold_disallowed AND hdata.part_required); %]
276
277                 </td>
278             </tr>
279
280             [% IF this_hold_disallowed %]
281               <tr><td>
282                 <div class="mr_holds_no_formats">
283                 [% l('This item does not have any formats available for holds placement') %]
284                 </div>
285               </td></tr>
286             [% END %]
287
288             [%  IF !loop.last AND ctx.hold_data.size > 1 %]
289             <tr class="holds_item_row_separator"><td> </td></tr>
290             [% END %]
291 </table>
292         [% END %]
293
294
295         [% IF some_holds_allowed %]
296
297         <p class="w-50">
298             [%- org_select_id = 'pickup_lib'; -%]
299             <label for="[% org_select_id %]" class="font-weight-bold">[%l('Pickup location:') %]</label>
300             [% PROCESS "opac/parts/org_selector.tt2";
301                 INCLUDE build_org_selector name='pickup_lib'
302                     value=ctx.default_pickup_lib id=org_select_id
303                     can_have_vols_only=1 hold_pickup_lib=1 %]
304             <label id="pickup-lib-unavailable-warning" for="[% org_select_id %]" class= "font-weight-bold" style= "color: #D0343A" aria-live="polite" hidden>[% l('* Pickup location unavailable. Please choose a different pickup location.') %]</label>
305             <!-- <label id="choose-pickup-lib-warning" for ="[% org_select_id %]" class="font-weight-light" aria-live="polite" hidden>[% l('* Please choose a pickup location') %]</label>             
306             -->
307             
308         </p>
309
310             <span class="font-weight-bold">[% l('Notify when hold is ready for pickup?') %]</span>
311             <p>
312              <div class="form-check m-2">
313                 <input class="form-check-input hold-alert-method" type="checkbox" value="t" id="email_notify" name="email_notify" [% IF !ctx.user.email %]disabled="true"[% ELSIF ctx.default_email_notify %]checked="checked"[% END %]>
314                 <label class="form-check-label" for="email_notify">
315                    [% l('Yes, by Email') %]
316
317                      [% IF !ctx.user.email and !ctx.is_staff; l('<br>No configured Email address. See "My Account" for setting your Email address.'); ELSE; %] : <span id="email_address"><b name="email_address">[% ctx.user.email %]</b></span>[% END %]
318                 </label>
319             </div>
320
321
322                 <p>
323
324                 </p>
325                 [%- IF allow_phone_notifications == 'true' %]
326                 <div class="form-check m-2">
327                     <input class="form-check-input hold-alert-method" type="checkbox" id="phone_notify_checkbox" name="phone_notify_checkbox" [% IF ctx.default_phone_notify %]checked="checked"[% END %]>
328                     <label class="form-check-label" for="phone_notify_checkbox">
329                     [% l('Yes, by Phone') %]
330                     </label>
331                 </div>
332
333                 <p>
334                     <label>[% l('Phone Number:') %]<input type="text" class="form-control" name="phone_notify" [% setting = 'opac.default_phone';
335                     IF ctx.user_setting_map.$setting; %] value='[% ctx.user_setting_map.$setting | html %]'
336                     [%- ELSIF ctx.user.day_phone; %] value='[% ctx.user.day_phone | html %]' [% END %]/></label>
337                 </p>
338                 [%- END -%]
339                 [% IF ctx.get_org_setting(ctx.search_ou, 'sms.enable') == 1 %]
340                 <input class="hold-alert-method" type="checkbox" id="sms_notify_checkbox" name="sms_notify_checkbox"
341                     [% IF ctx.default_sms_notify %]checked="checked"[% END %]/>
342                     <label for="sms_notify_checkbox">[% l('Yes, by Text Messaging') %]</label><br/>
343                 <p>
344                     [% INCLUDE "opac/parts/sms_carrier_selector.tt2" %]<br/>
345                     [% INCLUDE "opac/parts/sms_number_textbox.tt2" %]<br/>
346                 </p>
347                 [% END %]
348             </p>
349             <div>
350
351              [% IF ctx.hold_data.size > 0; %]
352             <div class="form-check m-2">
353                 <input class="form-check-input" type="checkbox" value="t" id="hold_suspend" name="hold_suspend">
354                 <label class="form-check-label" for="hold_suspend">
355                 [% IF ctx.hold_data.size == 1;
356                     l('Suspend this hold?');
357                 ELSE;
358                     l('Suspend these holds?');
359                 END %]
360                   <a href="#" aria-label="[% l('A suspended hold will retain its place in the queue, but will not be fulfilled until it has been activated.') %]" title="[% l('A suspended hold will retain its place in the queue, but will not be fulfilled until it has been activated.') %]" data-toggle="tooltip">
361                     <i class="fas fa-question-circle" aria-hidden="true"></i>
362                 </a>
363                 </label>
364             </div>
365                 [% END %]
366
367
368
369
370                 <a class="btn btn-sm btn-action m-2" id="actDateToggle" href="#toggled-block-suspend" onclick="return toggleActivationDate();"><i class="fas fa-calendar" aria-hidden="true"></i> [% l('Set activation date') %]</a>
371             </div>
372             <blockquote id="toggled-block-suspend">
373             <label for="thaw_date">[% l('Activate on') %]
374               <div class="input-group date" data-provide="datepicker">
375                 <input type="text" class="form-control" name="thaw_date" id="thaw_date" value="[% thaw_date | html %]" data-date-format="mm/dd/yyyy" />
376                 <div class="input-group-addon">
377                     <span class="glyphicon glyphicon-th"></span>
378                 </div>
379             </div>
380             </blockquote>
381
382          [% IF CGI.param('from_basket') %]
383
384            <div class="form-check m-2">
385                     <input class="form-check-input" type="checkbox" value="" id="clear_cart" />
386                     <label class="form-check-label" for="clear_cart">
387                         [% l('Clear basket after holds are requested?') %]
388                     </label>
389                 </div>
390         [% END %]
391                  [% IF NOT metarecords.disabled AND ctx.hold_data.size == 1 %]
392                         [% IF CGI.param('hold_type') == 'T' AND hdata.record.metarecord AND !hdata.part_required %]
393                         <!-- Grab the bre_id so that we can restore it if user accidentally clicks advanced options -->
394                            [% bre_id = hdata.target.id %]
395                             <a  id='advanced_hold_link' class="btn btn-sm btn-link"
396                                 href="[% mkurl('', {hold_type => 'M', hold_target => hdata.record.metarecord.id, bre_id => bre_id}) %]"><i class="fas fa-cog" aria-hidden="true"></i>
397                                 [% l('Advanced Hold Options') %]</a>
398                         [% END %]
399                         [% IF CGI.param('hold_type') == 'M' AND CGI.param('bre_id') %]
400                             <input type="hidden" name="bre_id" value="[% CGI.param('bre_id') %]" />
401                             <a id='basic_hold_link' class="btn btn-sm btn-link"
402                                href="[% mkurl('', {hold_target => CGI.param('bre_id'), hold_type => 'T'}) %]"><i class="fas fa-cog" aria-hidden="true"></i>
403                                 [% l('Basic Hold Options') %]</a>
404                         [% END %]
405                         [% IF hdata.metarecord_filters.formats.size OR # should this be size > 1
406                             (hdata.metarecord_filters.langs.size && hdata.metarecord_filters.langs.size > 1);
407                             PROCESS metarecord_hold_filters_selector hold_data=hdata;
408                         END;
409                     END %]
410         <div class="py-3">
411         <button id="place_hold_submit" type="submit" name="submit"  class="btn btn-confirm" ><i class="fas fa-check"></i> [% l('Submit') %]</button>
412         [% END # some_holds_allowed %]
413         <button type="reset" name="cancel" onclick="window.location='[% redirect | html %]'" id="holds_cancel" class="btn btn-deny"><i class="fas fa-ban" aria-hidden="true"></i> [% l('Cancel') %]</button>
414         </div>
415     </form>
416 </div>
417