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 |
- |
|
|