|
Lines 93-121
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 93 |
let $patron = $("<span></span>") |
93 |
let $patron = $("<span></span>") |
| 94 |
.append( |
94 |
.append( |
| 95 |
"" + |
95 |
"" + |
| 96 |
(patron.surname |
96 |
(patron.surname |
| 97 |
? escape_str(patron.surname) + ", " |
97 |
? escape_str(patron.surname) + ", " |
| 98 |
: "") + |
98 |
: "") + |
| 99 |
(patron.firstname |
99 |
(patron.firstname |
| 100 |
? escape_str(patron.firstname) + " " |
100 |
? escape_str(patron.firstname) + " " |
| 101 |
: "") + |
101 |
: "") + |
| 102 |
(patron.cardnumber |
102 |
(patron.cardnumber |
| 103 |
? " (" + escape_str(patron.cardnumber) + ")" |
103 |
? " (" + escape_str(patron.cardnumber) + ")" |
| 104 |
: "") + |
104 |
: "") + |
| 105 |
"<small>" + |
105 |
"<small>" + |
| 106 |
(patron.date_of_birth |
106 |
(patron.date_of_birth |
| 107 |
? ' <span class="age_years">' + |
107 |
? ' <span class="age_years">' + |
| 108 |
$get_age(patron.date_of_birth) + |
108 |
$get_age(patron.date_of_birth) + |
| 109 |
" " + |
109 |
" " + |
| 110 |
__("years") + |
110 |
__("years") + |
| 111 |
"</span>" |
111 |
"</span>" |
| 112 |
: "") + |
112 |
: "") + |
| 113 |
(patron.library |
113 |
(patron.library |
| 114 |
? ' <span class="ac-library">' + |
114 |
? ' <span class="ac-library">' + |
| 115 |
escape_str(patron.library.name) + |
115 |
escape_str(patron.library.name) + |
| 116 |
"</span>" |
116 |
"</span>" |
| 117 |
: "") + |
117 |
: "") + |
| 118 |
"</small>" |
118 |
"</small>" |
| 119 |
) |
119 |
) |
| 120 |
.addClass(loggedInClass); |
120 |
.addClass(loggedInClass); |
| 121 |
return $patron; |
121 |
return $patron; |
|
Lines 212-221
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 212 |
) { |
212 |
) { |
| 213 |
let option = $( |
213 |
let option = $( |
| 214 |
'<option value="' + |
214 |
'<option value="' + |
| 215 |
pickup_location.library_id + |
215 |
pickup_location.library_id + |
| 216 |
'">' + |
216 |
'">' + |
| 217 |
pickup_location.name + |
217 |
pickup_location.name + |
| 218 |
"</option>" |
218 |
"</option>" |
| 219 |
); |
219 |
); |
| 220 |
|
220 |
|
| 221 |
option.attr( |
221 |
option.attr( |
|
Lines 414-421
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 414 |
if ( |
414 |
if ( |
| 415 |
!$("#booking_itemtype").find( |
415 |
!$("#booking_itemtype").find( |
| 416 |
"option[value='" + |
416 |
"option[value='" + |
| 417 |
item.item_type.item_type_id + |
417 |
item.item_type.item_type_id + |
| 418 |
"']" |
418 |
"']" |
| 419 |
).length |
419 |
).length |
| 420 |
) { |
420 |
) { |
| 421 |
// Create a DOM Option and de-select by default |
421 |
// Create a DOM Option and de-select by default |
|
Lines 468-486
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 468 |
continue; |
468 |
continue; |
| 469 |
} |
469 |
} |
| 470 |
|
470 |
|
| 471 |
let start_date = flatpickr.parseDate( |
471 |
// Apply lead and trail periods to the booking dates |
| 472 |
booking.start_date |
472 |
let start_date = dayjs(booking.start_date); |
|
|
473 |
let end_date = dayjs(booking.end_date); |
| 474 |
|
| 475 |
// Apply lead period - subtract leadDays from start_date |
| 476 |
let start_date_with_lead = start_date.subtract( |
| 477 |
leadDays, |
| 478 |
"day" |
| 473 |
); |
479 |
); |
| 474 |
let end_date = flatpickr.parseDate( |
480 |
|
| 475 |
booking.end_date |
481 |
// Apply trail period - add trailDays to end_date |
|
|
482 |
let end_date_with_trail = end_date.add( |
| 483 |
trailDays, |
| 484 |
"day" |
| 476 |
); |
485 |
); |
| 477 |
|
486 |
|
| 478 |
// patron has selected a start date (end date checks) |
487 |
// patron has selected a start date (end date checks) |
| 479 |
if (selectedDates[0]) { |
488 |
if (selectedDates[0]) { |
| 480 |
// new booking start date is between existing booking start and end dates |
489 |
// new booking start date is between existing booking start (with lead) and end (with trail) dates |
| 481 |
if ( |
490 |
if ( |
| 482 |
selectedDates[0] >= start_date && |
491 |
selectedDates[0] >= |
| 483 |
selectedDates[0] <= end_date |
492 |
start_date_with_lead && |
|
|
493 |
selectedDates[0] <= end_date_with_trail |
| 484 |
) { |
494 |
) { |
| 485 |
if (booking.item_id) { |
495 |
if (booking.item_id) { |
| 486 |
if ( |
496 |
if ( |
|
Lines 505-514
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 505 |
} |
515 |
} |
| 506 |
} |
516 |
} |
| 507 |
|
517 |
|
| 508 |
// new booking end date would be between existing booking start and end dates |
518 |
// new booking end date would be between existing booking start (with lead) and end (with trail) dates |
| 509 |
else if ( |
519 |
else if ( |
| 510 |
date >= start_date && |
520 |
date >= start_date_with_lead && |
| 511 |
date <= end_date |
521 |
date <= end_date_with_trail |
| 512 |
) { |
522 |
) { |
| 513 |
if (booking.item_id) { |
523 |
if (booking.item_id) { |
| 514 |
if ( |
524 |
if ( |
|
Lines 535-542
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 535 |
|
545 |
|
| 536 |
// new booking would span existing booking |
546 |
// new booking would span existing booking |
| 537 |
else if ( |
547 |
else if ( |
| 538 |
selectedDates[0] <= start_date && |
548 |
selectedDates[0] <= |
| 539 |
date >= end_date |
549 |
start_date_with_lead && |
|
|
550 |
date >= end_date_with_trail |
| 540 |
) { |
551 |
) { |
| 541 |
if (booking.item_id) { |
552 |
if (booking.item_id) { |
| 542 |
if ( |
553 |
if ( |
|
Lines 579-586
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 579 |
|
590 |
|
| 580 |
// patron has not yet selected a start date (start date checks) |
591 |
// patron has not yet selected a start date (start date checks) |
| 581 |
else if ( |
592 |
else if ( |
| 582 |
date <= end_date && |
593 |
date <= end_date_with_trail && |
| 583 |
date >= start_date |
594 |
date >= start_date_with_lead |
| 584 |
) { |
595 |
) { |
| 585 |
// same item, disable date |
596 |
// same item, disable date |
| 586 |
if ( |
597 |
if ( |
|
Lines 753-759
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 753 |
for (let i = 0; i < renewalsAllowed; i++) { |
764 |
for (let i = 0; i < renewalsAllowed; i++) { |
| 754 |
nextDate.setDate( |
765 |
nextDate.setDate( |
| 755 |
nextDate.getDate() + |
766 |
nextDate.getDate() + |
| 756 |
parseInt(renewalLength) |
767 |
parseInt(renewalLength) |
| 757 |
); |
768 |
); |
| 758 |
boldDates.push(new Date(nextDate)); |
769 |
boldDates.push(new Date(nextDate)); |
| 759 |
} |
770 |
} |
|
Lines 769-776
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 769 |
const maxDate = new Date(startDate.getTime()); |
780 |
const maxDate = new Date(startDate.getTime()); |
| 770 |
maxDate.setDate( |
781 |
maxDate.setDate( |
| 771 |
maxDate.getDate() + |
782 |
maxDate.getDate() + |
| 772 |
totalIssueLength + |
783 |
totalIssueLength + |
| 773 |
parseInt(trailDays) |
784 |
parseInt(trailDays) |
| 774 |
); |
785 |
); |
| 775 |
|
786 |
|
| 776 |
// Apply disabled style to inclusive trailDays in maxDate |
787 |
// Apply disabled style to inclusive trailDays in maxDate |
|
Lines 874-888
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 874 |
|
885 |
|
| 875 |
// Create a bookings store keyed on date |
886 |
// Create a bookings store keyed on date |
| 876 |
let bookingsByDate = {}; |
887 |
let bookingsByDate = {}; |
|
|
888 |
|
| 877 |
// Iterate through the bookings array |
889 |
// Iterate through the bookings array |
| 878 |
bookings.forEach(booking => { |
890 |
bookings.forEach(booking => { |
| 879 |
const start_date = flatpickr.parseDate(booking.start_date); |
891 |
const start_date = flatpickr.parseDate(booking.start_date); |
| 880 |
const end_date = flatpickr.parseDate(booking.end_date); |
892 |
const end_date = flatpickr.parseDate(booking.end_date); |
| 881 |
const item_id = booking.item_id; |
893 |
const item_id = booking.item_id; |
| 882 |
|
894 |
|
| 883 |
// Iterate through each date within the range of start_date and end_date |
895 |
// Apply lead period - subtract leadDays from start_date |
| 884 |
let currentDate = new Date(start_date); |
896 |
let start_date_with_lead = new Date(start_date); |
| 885 |
while (currentDate <= end_date) { |
897 |
start_date_with_lead.setDate( |
|
|
898 |
start_date_with_lead.getDate() - leadDays |
| 899 |
); |
| 900 |
|
| 901 |
// Apply trail period - add trailDays to end_date |
| 902 |
let end_date_with_trail = new Date(end_date); |
| 903 |
end_date_with_trail.setDate( |
| 904 |
end_date_with_trail.getDate() + trailDays |
| 905 |
); |
| 906 |
|
| 907 |
// Iterate through each date within the range of start_date (with lead) and end_date (with trail) |
| 908 |
let currentDate = new Date(start_date_with_lead); |
| 909 |
while (currentDate <= end_date_with_trail) { |
| 886 |
const currentDateStr = currentDate |
910 |
const currentDateStr = currentDate |
| 887 |
.toISOString() |
911 |
.toISOString() |
| 888 |
.split("T")[0]; |
912 |
.split("T")[0]; |
|
Lines 932-937
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 932 |
const dots = document.createElement("span"); |
956 |
const dots = document.createElement("span"); |
| 933 |
dots.className = "event-dots"; |
957 |
dots.className = "event-dots"; |
| 934 |
dayElem.appendChild(dots); |
958 |
dayElem.appendChild(dots); |
|
|
959 |
|
| 960 |
// Check if this date is in a lead or trail period |
| 961 |
let isLeadOrTrail = false; |
| 962 |
|
| 963 |
// Check for each booking if this date is within its lead or trail period |
| 964 |
for (booking of bookings) { |
| 965 |
const start_date = flatpickr.parseDate( |
| 966 |
booking.start_date |
| 967 |
); |
| 968 |
const end_date = flatpickr.parseDate( |
| 969 |
booking.end_date |
| 970 |
); |
| 971 |
|
| 972 |
// Lead period check |
| 973 |
let lead_start = new Date(start_date); |
| 974 |
lead_start.setDate( |
| 975 |
lead_start.getDate() - leadDays |
| 976 |
); |
| 977 |
|
| 978 |
// Trail period check |
| 979 |
let trail_end = new Date(end_date); |
| 980 |
trail_end.setDate( |
| 981 |
trail_end.getDate() + trailDays |
| 982 |
); |
| 983 |
|
| 984 |
// Check if current date is in lead period but before start_date |
| 985 |
let isInLeadPeriod = |
| 986 |
currentDate >= lead_start && |
| 987 |
currentDate < start_date; |
| 988 |
|
| 989 |
// Check if current date is in trail period but after end_date |
| 990 |
let isInTrailPeriod = |
| 991 |
currentDate <= trail_end && |
| 992 |
currentDate > end_date; |
| 993 |
|
| 994 |
if (isInLeadPeriod || isInTrailPeriod) { |
| 995 |
isLeadOrTrail = true; |
| 996 |
break; |
| 997 |
} |
| 998 |
} |
| 999 |
|
| 1000 |
// Add a special class for dates in lead/trail periods |
| 1001 |
if (isLeadOrTrail) { |
| 1002 |
dayElem.classList.add("booking-lead-trail"); |
| 1003 |
} |
| 1004 |
|
| 935 |
bookingsByDate[dateString].forEach(item => { |
1005 |
bookingsByDate[dateString].forEach(item => { |
| 936 |
const dot = document.createElement("span"); |
1006 |
const dot = document.createElement("span"); |
| 937 |
dot.className = "event item_" + item; |
1007 |
dot.className = "event item_" + item; |
|
Lines 953-960
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 953 |
); |
1023 |
); |
| 954 |
const startDate = periodPicker.selectedDates[0] |
1024 |
const startDate = periodPicker.selectedDates[0] |
| 955 |
? dayjs(periodPicker.selectedDates[0]).startOf( |
1025 |
? dayjs(periodPicker.selectedDates[0]).startOf( |
| 956 |
"day" |
1026 |
"day" |
| 957 |
) |
1027 |
) |
| 958 |
: null; |
1028 |
: null; |
| 959 |
|
1029 |
|
| 960 |
const leadStart = startDate |
1030 |
const leadStart = startDate |
|
Lines 980-986
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 980 |
dayElem.classList.toggle( |
1050 |
dayElem.classList.toggle( |
| 981 |
"leadRange", |
1051 |
"leadRange", |
| 982 |
elemDate.isSameOrAfter(leadStart) && |
1052 |
elemDate.isSameOrAfter(leadStart) && |
| 983 |
elemDate.isBefore(leadEnd) |
1053 |
elemDate.isBefore(leadEnd) |
| 984 |
); |
1054 |
); |
| 985 |
dayElem.classList.toggle( |
1055 |
dayElem.classList.toggle( |
| 986 |
"leadRangeEnd", |
1056 |
"leadRangeEnd", |
|
Lines 993-999
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 993 |
dayElem.classList.toggle( |
1063 |
dayElem.classList.toggle( |
| 994 |
"trailRange", |
1064 |
"trailRange", |
| 995 |
elemDate.isAfter(trailStart) && |
1065 |
elemDate.isAfter(trailStart) && |
| 996 |
elemDate.isSameOrBefore(trailEnd) |
1066 |
elemDate.isSameOrBefore(trailEnd) |
| 997 |
); |
1067 |
); |
| 998 |
dayElem.classList.toggle( |
1068 |
dayElem.classList.toggle( |
| 999 |
"trailRangeEnd", |
1069 |
"trailRangeEnd", |
|
Lines 1216-1223
$("#placeBookingForm").on("submit", function (e) {
Link Here
|
| 1216 |
// Set feedback |
1286 |
// Set feedback |
| 1217 |
$("#transient_result").replaceWith( |
1287 |
$("#transient_result").replaceWith( |
| 1218 |
'<div id="transient_result" class="alert alert-info">' + |
1288 |
'<div id="transient_result" class="alert alert-info">' + |
| 1219 |
__("Booking successfully placed") + |
1289 |
__("Booking successfully placed") + |
| 1220 |
"</div>" |
1290 |
"</div>" |
| 1221 |
); |
1291 |
); |
| 1222 |
|
1292 |
|
| 1223 |
// Close modal |
1293 |
// Close modal |
|
Lines 1227-1234
$("#placeBookingForm").on("submit", function (e) {
Link Here
|
| 1227 |
posting.fail(function (data) { |
1297 |
posting.fail(function (data) { |
| 1228 |
$("#booking_result").replaceWith( |
1298 |
$("#booking_result").replaceWith( |
| 1229 |
'<div id="booking_result" class="alert alert-danger">' + |
1299 |
'<div id="booking_result" class="alert alert-danger">' + |
| 1230 |
__("Failure") + |
1300 |
__("Failure") + |
| 1231 |
"</div>" |
1301 |
"</div>" |
| 1232 |
); |
1302 |
); |
| 1233 |
}); |
1303 |
}); |
| 1234 |
} else { |
1304 |
} else { |
|
Lines 1285-1292
$("#placeBookingForm").on("submit", function (e) {
Link Here
|
| 1285 |
// Set feedback |
1355 |
// Set feedback |
| 1286 |
$("#transient_result").replaceWith( |
1356 |
$("#transient_result").replaceWith( |
| 1287 |
'<div id="transient_result" class="alert alert-info">' + |
1357 |
'<div id="transient_result" class="alert alert-info">' + |
| 1288 |
__("Booking successfully updated") + |
1358 |
__("Booking successfully updated") + |
| 1289 |
"</div>" |
1359 |
"</div>" |
| 1290 |
); |
1360 |
); |
| 1291 |
|
1361 |
|
| 1292 |
// Close modal |
1362 |
// Close modal |
|
Lines 1296-1303
$("#placeBookingForm").on("submit", function (e) {
Link Here
|
| 1296 |
putting.fail(function (data) { |
1366 |
putting.fail(function (data) { |
| 1297 |
$("#booking_result").replaceWith( |
1367 |
$("#booking_result").replaceWith( |
| 1298 |
'<div id="booking_result" class="alert alert-danger">' + |
1368 |
'<div id="booking_result" class="alert alert-danger">' + |
| 1299 |
__("Failure") + |
1369 |
__("Failure") + |
| 1300 |
"</div>" |
1370 |
"</div>" |
| 1301 |
); |
1371 |
); |
| 1302 |
}); |
1372 |
}); |
| 1303 |
} |
1373 |
} |
| 1304 |
- |
|
|