|
Lines 403-409
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 403 |
end_date: checkout.due_date, |
403 |
end_date: checkout.due_date, |
| 404 |
item_id: checkout.item_id, |
404 |
item_id: checkout.item_id, |
| 405 |
patron_id: checkout.patron_id, |
405 |
patron_id: checkout.patron_id, |
| 406 |
start_date: new Date().toISOString(), |
406 |
start_date: dayjs().format(), |
| 407 |
}; |
407 |
}; |
| 408 |
bookings.unshift(booking); |
408 |
bookings.unshift(booking); |
| 409 |
} |
409 |
} |
|
Lines 929-960
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 929 |
// Range set, update hidden fields and set available items |
929 |
// Range set, update hidden fields and set available items |
| 930 |
else if (selectedDates[0] && selectedDates[1]) { |
930 |
else if (selectedDates[0] && selectedDates[1]) { |
| 931 |
// set form fields from picker |
931 |
// set form fields from picker |
| 932 |
let picker_start = dayjs(selectedDates[0]); |
932 |
// Extract local date and send as explicit UTC day boundaries |
| 933 |
let picker_end = dayjs(selectedDates[1]).endOf( |
933 |
// This preserves the user's selected DATE regardless of browser timezone |
| 934 |
"day" |
934 |
// Using dayjs.utc() ensures startOf/endOf operate in UTC, not browser TZ |
|
|
935 |
let startDate = dayjs(selectedDates[0]).format( |
| 936 |
"YYYY-MM-DD" |
| 937 |
); |
| 938 |
let endDate = dayjs(selectedDates[1]).format( |
| 939 |
"YYYY-MM-DD" |
| 935 |
); |
940 |
); |
| 936 |
$("#booking_start_date").val( |
941 |
$("#booking_start_date").val( |
| 937 |
picker_start.toISOString() |
942 |
dayjs |
|
|
943 |
.utc(startDate) |
| 944 |
.startOf("day") |
| 945 |
.toISOString() |
| 938 |
); |
946 |
); |
| 939 |
$("#booking_end_date").val( |
947 |
$("#booking_end_date").val( |
| 940 |
picker_end.toISOString() |
948 |
dayjs |
|
|
949 |
.utc(endDate) |
| 950 |
.endOf("day") |
| 951 |
.toISOString() |
| 941 |
); |
952 |
); |
| 942 |
|
953 |
|
| 943 |
// set available items in select2 |
954 |
// set available items in select2 |
| 944 |
let booked_items = bookings.filter( |
955 |
let booked_items = bookings.filter( |
| 945 |
function (booking) { |
956 |
function (booking) { |
| 946 |
let start_date = flatpickr.parseDate( |
957 |
// Parse and normalize dates to start-of-day for consistent comparison |
|
|
958 |
let start_date = dayjs( |
| 947 |
booking.start_date |
959 |
booking.start_date |
| 948 |
); |
960 |
) |
| 949 |
let end_date = flatpickr.parseDate( |
961 |
.startOf("day") |
| 950 |
booking.end_date |
962 |
.toDate(); |
| 951 |
); |
963 |
let end_date = dayjs(booking.end_date) |
|
|
964 |
.startOf("day") |
| 965 |
.toDate(); |
| 966 |
let selectedStart = dayjs( |
| 967 |
selectedDates[0] |
| 968 |
) |
| 969 |
.startOf("day") |
| 970 |
.toDate(); |
| 971 |
let selectedEnd = dayjs( |
| 972 |
selectedDates[1] |
| 973 |
) |
| 974 |
.startOf("day") |
| 975 |
.toDate(); |
| 976 |
|
| 952 |
// This booking ends before the start of the new booking |
977 |
// This booking ends before the start of the new booking |
| 953 |
if (end_date <= selectedDates[0]) { |
978 |
if (end_date < selectedStart) { |
| 954 |
return false; |
979 |
return false; |
| 955 |
} |
980 |
} |
| 956 |
// This booking starts after then end of the new booking |
981 |
// This booking starts after the end of the new booking |
| 957 |
if (start_date >= selectedDates[1]) { |
982 |
if (start_date > selectedEnd) { |
| 958 |
return false; |
983 |
return false; |
| 959 |
} |
984 |
} |
| 960 |
// This booking overlaps |
985 |
// This booking overlaps |
|
Lines 1021-1028
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 1021 |
const item_id = booking.item_id; |
1046 |
const item_id = booking.item_id; |
| 1022 |
|
1047 |
|
| 1023 |
// Iterate through each date within the range of start_date and end_date |
1048 |
// Iterate through each date within the range of start_date and end_date |
| 1024 |
let currentDate = dayjs(start_date); |
1049 |
// Use dayjs to maintain browser timezone consistency |
| 1025 |
while (currentDate.isSameOrBefore(end_date, "day")) { |
1050 |
let currentDate = dayjs(start_date).startOf("day"); |
|
|
1051 |
const endDate = dayjs(end_date).startOf("day"); |
| 1052 |
while (currentDate.isSameOrBefore(endDate, "day")) { |
| 1053 |
// Format in browser timezone - no UTC conversion |
| 1026 |
const currentDateStr = currentDate.format("YYYY-MM-DD"); |
1054 |
const currentDateStr = currentDate.format("YYYY-MM-DD"); |
| 1027 |
|
1055 |
|
| 1028 |
// If the date key doesn't exist in the hash, create an empty array for it |
1056 |
// If the date key doesn't exist in the hash, create an empty array for it |
|
Lines 1046-1054
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 1046 |
periodPicker.config.onDayCreate.push( |
1074 |
periodPicker.config.onDayCreate.push( |
| 1047 |
function dayCreate(dObj, dStr, instance, dayElem) { |
1075 |
function dayCreate(dObj, dStr, instance, dayElem) { |
| 1048 |
const currentDate = dayElem.dateObj; |
1076 |
const currentDate = dayElem.dateObj; |
| 1049 |
const dateString = currentDate |
1077 |
// Format in browser timezone to match bookingsByDate keys |
| 1050 |
.toISOString() |
1078 |
const dateString = |
| 1051 |
.split("T")[0]; |
1079 |
dayjs(currentDate).format("YYYY-MM-DD"); |
| 1052 |
|
1080 |
|
| 1053 |
const isBold = boldDates.some( |
1081 |
const isBold = boldDates.some( |
| 1054 |
boldDate => |
1082 |
boldDate => |
|
Lines 2259-2270
$("#placeBookingForm").on("submit", function (e) {
Link Here
|
| 2259 |
bookings_table.api().ajax.reload(); |
2287 |
bookings_table.api().ajax.reload(); |
| 2260 |
} |
2288 |
} |
| 2261 |
if (typeof timeline !== "undefined" && timeline !== null) { |
2289 |
if (typeof timeline !== "undefined" && timeline !== null) { |
|
|
2290 |
// Convert to library timezone for timeline display |
| 2291 |
const startServerTz = dayjs(data.start_date).tz($timezone()); |
| 2292 |
const endServerTz = dayjs(data.end_date).tz($timezone()); |
| 2262 |
timeline.itemsData.add({ |
2293 |
timeline.itemsData.add({ |
| 2263 |
id: data.booking_id, |
2294 |
id: data.booking_id, |
| 2264 |
booking: data.booking_id, |
2295 |
booking: data.booking_id, |
| 2265 |
patron: data.patron_id, |
2296 |
patron: data.patron_id, |
| 2266 |
start: dayjs(data.start_date).toDate(), |
2297 |
start: $toDisplayDate(startServerTz), |
| 2267 |
end: dayjs(data.end_date).toDate(), |
2298 |
end: $toDisplayDate(endServerTz), |
| 2268 |
content: $patron_to_html(booking_patron, { |
2299 |
content: $patron_to_html(booking_patron, { |
| 2269 |
display_cardnumber: true, |
2300 |
display_cardnumber: true, |
| 2270 |
url: false, |
2301 |
url: false, |
|
Lines 2368-2379
$("#placeBookingForm").on("submit", function (e) {
Link Here
|
| 2368 |
bookings_table.api().ajax.reload(); |
2399 |
bookings_table.api().ajax.reload(); |
| 2369 |
} |
2400 |
} |
| 2370 |
if (typeof timeline !== "undefined" && timeline !== null) { |
2401 |
if (typeof timeline !== "undefined" && timeline !== null) { |
|
|
2402 |
// Convert to library timezone for timeline display |
| 2403 |
const startServerTz = dayjs(data.start_date).tz($timezone()); |
| 2404 |
const endServerTz = dayjs(data.end_date).tz($timezone()); |
| 2371 |
timeline.itemsData.update({ |
2405 |
timeline.itemsData.update({ |
| 2372 |
id: data.booking_id, |
2406 |
id: data.booking_id, |
| 2373 |
booking: data.booking_id, |
2407 |
booking: data.booking_id, |
| 2374 |
patron: data.patron_id, |
2408 |
patron: data.patron_id, |
| 2375 |
start: dayjs(data.start_date).toDate(), |
2409 |
start: $toDisplayDate(startServerTz), |
| 2376 |
end: dayjs(data.end_date).toDate(), |
2410 |
end: $toDisplayDate(endServerTz), |
| 2377 |
content: $patron_to_html(booking_patron, { |
2411 |
content: $patron_to_html(booking_patron, { |
| 2378 |
display_cardnumber: true, |
2412 |
display_cardnumber: true, |
| 2379 |
url: false, |
2413 |
url: false, |
| 2380 |
- |
|
|