|
Lines 129-173
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 129 |
placeholder: __("Search for a patron"), |
129 |
placeholder: __("Search for a patron"), |
| 130 |
}); |
130 |
}); |
| 131 |
|
131 |
|
| 132 |
// Lead and Trail days syncing |
132 |
// Circulation rules update |
| 133 |
let leadDays = 0; |
133 |
let leadDays = 0; |
| 134 |
let trailDays = 0; |
134 |
let trailDays = 0; |
| 135 |
let boldDates = []; |
135 |
let boldDates = []; |
| 136 |
let issueLength; |
136 |
let issueLength; |
| 137 |
let renewalLength; |
137 |
let renewalLength; |
| 138 |
let renewalsAllowed; |
138 |
let renewalsAllowed; |
|
|
139 |
|
| 140 |
// Note: For now, we apply the pickup library rules for issuelength, renewalsallowed and renewalperiod. |
| 141 |
// This effectively makes these circulation rules hard coded to CircControl: ItemHomeLibrary + HomeOrHolding: holdingbranch |
| 142 |
// Whilst it would be beneficial to make this follow those rules more closely, this would require some significant thinking |
| 143 |
// around how to best display this in the calender component for the 'Any item' case. |
| 139 |
function getCirculationRules() { |
144 |
function getCirculationRules() { |
| 140 |
let rules_url = "/api/v1/circulation_rules"; |
145 |
let rules_url = "/api/v1/circulation_rules"; |
| 141 |
$.ajax({ |
146 |
if (booking_patron && pickup_library_id && booking_itemtype_id) { |
| 142 |
url: rules_url, |
147 |
$.ajax({ |
| 143 |
type: "GET", |
148 |
url: rules_url, |
| 144 |
dataType: "json", |
149 |
type: "GET", |
| 145 |
data: { |
150 |
dataType: "json", |
| 146 |
patron_category_id: booking_patron.category_id, |
151 |
data: { |
| 147 |
item_type_id: booking_itemtype_id, |
152 |
patron_category_id: booking_patron.category_id, |
| 148 |
library_id: pickup_library_id, |
153 |
item_type_id: booking_itemtype_id, |
| 149 |
rules: "bookings_lead_period,bookings_trail_period,issuelength,renewalsallowed,renewalperiod", |
154 |
library_id: pickup_library_id, |
| 150 |
}, |
155 |
rules: "bookings_lead_period,bookings_trail_period,issuelength,renewalsallowed,renewalperiod", |
| 151 |
success: function (response) { |
156 |
}, |
| 152 |
let rules = response[0]; |
157 |
success: function (response) { |
| 153 |
issueLength = rules.issuelength; |
158 |
let rules = response[0]; |
| 154 |
renewalsAllowed = rules.renewalsallowed; |
159 |
issueLength = rules.issuelength; |
| 155 |
renewalLength = rules.renewalperiod; |
160 |
renewalsAllowed = rules.renewalsallowed; |
| 156 |
leadDays = rules.bookings_lead_period; |
161 |
renewalLength = rules.renewalperiod; |
| 157 |
trailDays = rules.bookings_trail_period; |
162 |
leadDays = rules.bookings_lead_period; |
| 158 |
|
163 |
trailDays = rules.bookings_trail_period; |
| 159 |
// redraw pariodPicker taking selected item into account |
164 |
|
| 160 |
periodPicker.redraw(); |
165 |
// redraw pariodPicker taking selected item into account |
| 161 |
|
166 |
periodPicker.redraw(); |
| 162 |
// Enable flatpickr now we have data we need |
167 |
|
| 163 |
if (dataFetched) { |
168 |
// Enable flatpickr now we have data we need |
| 164 |
$("#period_fields :input").prop("disabled", false); |
169 |
if (dataFetched) { |
| 165 |
} |
170 |
$("#period_fields :input").prop("disabled", false); |
| 166 |
}, |
171 |
} |
| 167 |
error: function (xhr, status, error) { |
172 |
}, |
| 168 |
console.log("Circulation rules fetch failed: ", error); |
173 |
error: function (xhr, status, error) { |
| 169 |
}, |
174 |
console.log("Circulation rules fetch failed: ", error); |
| 170 |
}); |
175 |
}, |
|
|
176 |
}); |
| 177 |
} else { |
| 178 |
$("#period_fields :input").prop("disabled", true); |
| 179 |
} |
| 171 |
} |
180 |
} |
| 172 |
|
181 |
|
| 173 |
// Pickup location select2 |
182 |
// Pickup location select2 |
|
Lines 304-309
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 304 |
"&_per_page=-1", |
313 |
"&_per_page=-1", |
| 305 |
dataType: "json", |
314 |
dataType: "json", |
| 306 |
type: "GET", |
315 |
type: "GET", |
|
|
316 |
headers: { |
| 317 |
"x-koha-embed": "item_type", |
| 318 |
}, |
| 307 |
}); |
319 |
}); |
| 308 |
|
320 |
|
| 309 |
// Fetch list of existing bookings |
321 |
// Fetch list of existing bookings |
|
Lines 350-361
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 350 |
|
362 |
|
| 351 |
// Total bookable items |
363 |
// Total bookable items |
| 352 |
let bookable = 0; |
364 |
let bookable = 0; |
| 353 |
|
|
|
| 354 |
let itemtypes = new Set(); |
| 355 |
for (item of bookable_items) { |
365 |
for (item of bookable_items) { |
| 356 |
bookable++; |
366 |
bookable++; |
| 357 |
|
367 |
|
| 358 |
// Populate item select (NOTE: Do we still need this check for pre-existing select option here?) |
368 |
// Populate item select |
| 359 |
if ( |
369 |
if ( |
| 360 |
!$("#booking_item_id").find( |
370 |
!$("#booking_item_id").find( |
| 361 |
"option[value='" + item.item_id + "']" |
371 |
"option[value='" + item.item_id + "']" |
|
Lines 378-395
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 378 |
$("#booking_item_id").append(newOption); |
388 |
$("#booking_item_id").append(newOption); |
| 379 |
} |
389 |
} |
| 380 |
|
390 |
|
| 381 |
// Build list of itemtypes |
391 |
// Populate item types select |
| 382 |
itemtypes.add(item.effective_item_type_id); |
392 |
if ( |
| 383 |
} |
393 |
!$("#booking_itemtype").find( |
| 384 |
|
394 |
"option[value='" + |
| 385 |
// Filter itemtypes |
395 |
item.item_type.item_type_id + |
| 386 |
$("#booking_itemtype option").each(function () { |
396 |
"']" |
| 387 |
const optionValue = $(this).val(); |
397 |
).length |
| 388 |
if (!itemtypes.has(optionValue)) { |
398 |
) { |
| 389 |
$(this).remove(); |
399 |
// Create a DOM Option and de-select by default |
|
|
400 |
let newTypeOption = new Option( |
| 401 |
escape_str(item.item_type.description), |
| 402 |
item.item_type.item_type_id, |
| 403 |
false, |
| 404 |
false |
| 405 |
); |
| 406 |
$("#booking_itemtype").append(newTypeOption); |
| 390 |
} |
407 |
} |
| 391 |
}); |
408 |
} |
| 392 |
$("#booking_itemtype").trigger("change"); |
409 |
$("#booking_itemtype").val(null).trigger("change"); |
| 393 |
|
410 |
|
| 394 |
// Set disable function for periodPicker |
411 |
// Set disable function for periodPicker |
| 395 |
let disableExists = periodPicker.config.disable.filter( |
412 |
let disableExists = periodPicker.config.disable.filter( |
|
Lines 572-599
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 572 |
} |
589 |
} |
| 573 |
|
590 |
|
| 574 |
// Setup listener for itemtype select2 |
591 |
// Setup listener for itemtype select2 |
| 575 |
$("#booking_itemtype").on("select2:select", function (e) { |
592 |
$("#booking_itemtype").on("change", function (e) { |
| 576 |
booking_itemtype_id = e.params.data.id |
593 |
let selectedValue = $(this).val(); // Get selected value (null if cleared) |
| 577 |
? e.params.data.id |
594 |
booking_itemtype_id = selectedValue ? selectedValue : null; |
| 578 |
: null; |
595 |
|
| 579 |
|
596 |
// Handle item selectionue |
| 580 |
// Disable items not of this itemtype |
597 |
if (!booking_itemtype_id) { |
| 581 |
$("#booking_item_id > option").each(function () { |
598 |
// Enable all items for selection |
| 582 |
let option = $(this); |
599 |
$("#booking_item_id > option").prop("disabled", false); |
| 583 |
if (option.val() != 0) { |
600 |
} else { |
| 584 |
let item_itemtype = option.data("itemtype"); |
601 |
// Disable items not of this itemtype |
| 585 |
if (item_itemtype == booking_itemtype_id) { |
602 |
$("#booking_item_id > option").each(function () { |
| 586 |
if ( |
603 |
let option = $(this); |
| 587 |
option.data("available") && |
604 |
if (option.val() != 0) { |
| 588 |
option.data("pickup") |
605 |
let item_itemtype = option.data("itemtype"); |
| 589 |
) { |
606 |
if (item_itemtype == booking_itemtype_id) { |
| 590 |
option.prop("disabled", false); |
607 |
if ( |
|
|
608 |
option.data("available") && |
| 609 |
option.data("pickup") |
| 610 |
) { |
| 611 |
option.prop("disabled", false); |
| 612 |
} |
| 613 |
} else { |
| 614 |
option.prop("disabled", true); |
| 591 |
} |
615 |
} |
| 592 |
} else { |
|
|
| 593 |
option.prop("disabled", true); |
| 594 |
} |
616 |
} |
| 595 |
} |
617 |
}); |
| 596 |
}); |
618 |
} |
| 597 |
$("#booking_item_id").trigger("change.select2"); |
619 |
$("#booking_item_id").trigger("change.select2"); |
| 598 |
|
620 |
|
| 599 |
// Update circulation rules |
621 |
// Update circulation rules |
|
Lines 671-676
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 671 |
|
693 |
|
| 672 |
// Disable patron selection change |
694 |
// Disable patron selection change |
| 673 |
$("#booking_patron_id").prop("disabled", true); |
695 |
$("#booking_patron_id").prop("disabled", true); |
|
|
696 |
|
| 697 |
pickup_library_id = $("#pickup_library_id").val(); |
| 698 |
|
| 699 |
// Populate circulation rules |
| 700 |
getCirculationRules(); |
| 674 |
}); |
701 |
}); |
| 675 |
|
702 |
|
| 676 |
// Set onChange for flatpickr |
703 |
// Set onChange for flatpickr |
|
Lines 1230-1236
$("#placeBookingModal").on("hidden.bs.modal", function (e) {
Link Here
|
| 1230 |
$("#booking_item_id").prop("disabled", true); |
1257 |
$("#booking_item_id").prop("disabled", true); |
| 1231 |
|
1258 |
|
| 1232 |
// Reset itemtype select |
1259 |
// Reset itemtype select |
| 1233 |
$("#booking_itemtype").val(0).trigger("change"); |
1260 |
$("#booking_itemtype").val(null).trigger("change"); |
| 1234 |
$("#booking_itemtype").prop("disabled", true); |
1261 |
$("#booking_itemtype").prop("disabled", true); |
| 1235 |
booking_itemtype_id = undefined; |
1262 |
booking_itemtype_id = undefined; |
| 1236 |
|
1263 |
|
| 1237 |
- |
|
|