|
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 907-938
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 907 |
// Range set, update hidden fields and set available items |
907 |
// Range set, update hidden fields and set available items |
| 908 |
else if (selectedDates[0] && selectedDates[1]) { |
908 |
else if (selectedDates[0] && selectedDates[1]) { |
| 909 |
// set form fields from picker |
909 |
// set form fields from picker |
| 910 |
let picker_start = dayjs(selectedDates[0]); |
910 |
// Extract local date and send as explicit UTC day boundaries |
| 911 |
let picker_end = dayjs(selectedDates[1]).endOf( |
911 |
// This preserves the user's selected DATE regardless of browser timezone |
| 912 |
"day" |
912 |
// Using dayjs.utc() ensures startOf/endOf operate in UTC, not browser TZ |
|
|
913 |
let startDate = dayjs(selectedDates[0]).format( |
| 914 |
"YYYY-MM-DD" |
| 915 |
); |
| 916 |
let endDate = dayjs(selectedDates[1]).format( |
| 917 |
"YYYY-MM-DD" |
| 913 |
); |
918 |
); |
| 914 |
$("#booking_start_date").val( |
919 |
$("#booking_start_date").val( |
| 915 |
picker_start.toISOString() |
920 |
dayjs |
|
|
921 |
.utc(startDate) |
| 922 |
.startOf("day") |
| 923 |
.toISOString() |
| 916 |
); |
924 |
); |
| 917 |
$("#booking_end_date").val( |
925 |
$("#booking_end_date").val( |
| 918 |
picker_end.toISOString() |
926 |
dayjs |
|
|
927 |
.utc(endDate) |
| 928 |
.endOf("day") |
| 929 |
.toISOString() |
| 919 |
); |
930 |
); |
| 920 |
|
931 |
|
| 921 |
// set available items in select2 |
932 |
// set available items in select2 |
| 922 |
let booked_items = bookings.filter( |
933 |
let booked_items = bookings.filter( |
| 923 |
function (booking) { |
934 |
function (booking) { |
| 924 |
let start_date = flatpickr.parseDate( |
935 |
// Parse and normalize dates to start-of-day for consistent comparison |
|
|
936 |
let start_date = dayjs( |
| 925 |
booking.start_date |
937 |
booking.start_date |
| 926 |
); |
938 |
) |
| 927 |
let end_date = flatpickr.parseDate( |
939 |
.startOf("day") |
| 928 |
booking.end_date |
940 |
.toDate(); |
| 929 |
); |
941 |
let end_date = dayjs(booking.end_date) |
|
|
942 |
.startOf("day") |
| 943 |
.toDate(); |
| 944 |
let selectedStart = dayjs( |
| 945 |
selectedDates[0] |
| 946 |
) |
| 947 |
.startOf("day") |
| 948 |
.toDate(); |
| 949 |
let selectedEnd = dayjs( |
| 950 |
selectedDates[1] |
| 951 |
) |
| 952 |
.startOf("day") |
| 953 |
.toDate(); |
| 954 |
|
| 930 |
// This booking ends before the start of the new booking |
955 |
// This booking ends before the start of the new booking |
| 931 |
if (end_date <= selectedDates[0]) { |
956 |
if (end_date < selectedStart) { |
| 932 |
return false; |
957 |
return false; |
| 933 |
} |
958 |
} |
| 934 |
// This booking starts after then end of the new booking |
959 |
// This booking starts after the end of the new booking |
| 935 |
if (start_date >= selectedDates[1]) { |
960 |
if (start_date > selectedEnd) { |
| 936 |
return false; |
961 |
return false; |
| 937 |
} |
962 |
} |
| 938 |
// This booking overlaps |
963 |
// This booking overlaps |
|
Lines 999-1006
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 999 |
const item_id = booking.item_id; |
1024 |
const item_id = booking.item_id; |
| 1000 |
|
1025 |
|
| 1001 |
// Iterate through each date within the range of start_date and end_date |
1026 |
// Iterate through each date within the range of start_date and end_date |
| 1002 |
let currentDate = dayjs(start_date); |
1027 |
// Use dayjs to maintain browser timezone consistency |
| 1003 |
while (currentDate.isSameOrBefore(end_date, "day")) { |
1028 |
let currentDate = dayjs(start_date).startOf("day"); |
|
|
1029 |
const endDate = dayjs(end_date).startOf("day"); |
| 1030 |
while (currentDate.isSameOrBefore(endDate, "day")) { |
| 1031 |
// Format in browser timezone - no UTC conversion |
| 1004 |
const currentDateStr = currentDate.format("YYYY-MM-DD"); |
1032 |
const currentDateStr = currentDate.format("YYYY-MM-DD"); |
| 1005 |
|
1033 |
|
| 1006 |
// If the date key doesn't exist in the hash, create an empty array for it |
1034 |
// If the date key doesn't exist in the hash, create an empty array for it |
|
Lines 1024-1032
$("#placeBookingModal").on("show.bs.modal", function (e) {
Link Here
|
| 1024 |
periodPicker.config.onDayCreate.push( |
1052 |
periodPicker.config.onDayCreate.push( |
| 1025 |
function dayCreate(dObj, dStr, instance, dayElem) { |
1053 |
function dayCreate(dObj, dStr, instance, dayElem) { |
| 1026 |
const currentDate = dayElem.dateObj; |
1054 |
const currentDate = dayElem.dateObj; |
| 1027 |
const dateString = currentDate |
1055 |
// Format in browser timezone to match bookingsByDate keys |
| 1028 |
.toISOString() |
1056 |
const dateString = |
| 1029 |
.split("T")[0]; |
1057 |
dayjs(currentDate).format("YYYY-MM-DD"); |
| 1030 |
|
1058 |
|
| 1031 |
const isBold = boldDates.some( |
1059 |
const isBold = boldDates.some( |
| 1032 |
boldDate => |
1060 |
boldDate => |
|
Lines 2237-2248
$("#placeBookingForm").on("submit", function (e) {
Link Here
|
| 2237 |
bookings_table.api().ajax.reload(); |
2265 |
bookings_table.api().ajax.reload(); |
| 2238 |
} |
2266 |
} |
| 2239 |
if (typeof timeline !== "undefined" && timeline !== null) { |
2267 |
if (typeof timeline !== "undefined" && timeline !== null) { |
|
|
2268 |
// Convert to library timezone for timeline display |
| 2269 |
const startServerTz = dayjs(data.start_date).tz($timezone()); |
| 2270 |
const endServerTz = dayjs(data.end_date).tz($timezone()); |
| 2240 |
timeline.itemsData.add({ |
2271 |
timeline.itemsData.add({ |
| 2241 |
id: data.booking_id, |
2272 |
id: data.booking_id, |
| 2242 |
booking: data.booking_id, |
2273 |
booking: data.booking_id, |
| 2243 |
patron: data.patron_id, |
2274 |
patron: data.patron_id, |
| 2244 |
start: dayjs(data.start_date).toDate(), |
2275 |
start: $toDisplayDate(startServerTz), |
| 2245 |
end: dayjs(data.end_date).toDate(), |
2276 |
end: $toDisplayDate(endServerTz), |
| 2246 |
content: $patron_to_html(booking_patron, { |
2277 |
content: $patron_to_html(booking_patron, { |
| 2247 |
display_cardnumber: true, |
2278 |
display_cardnumber: true, |
| 2248 |
url: false, |
2279 |
url: false, |
|
Lines 2346-2357
$("#placeBookingForm").on("submit", function (e) {
Link Here
|
| 2346 |
bookings_table.api().ajax.reload(); |
2377 |
bookings_table.api().ajax.reload(); |
| 2347 |
} |
2378 |
} |
| 2348 |
if (typeof timeline !== "undefined" && timeline !== null) { |
2379 |
if (typeof timeline !== "undefined" && timeline !== null) { |
|
|
2380 |
// Convert to library timezone for timeline display |
| 2381 |
const startServerTz = dayjs(data.start_date).tz($timezone()); |
| 2382 |
const endServerTz = dayjs(data.end_date).tz($timezone()); |
| 2349 |
timeline.itemsData.update({ |
2383 |
timeline.itemsData.update({ |
| 2350 |
id: data.booking_id, |
2384 |
id: data.booking_id, |
| 2351 |
booking: data.booking_id, |
2385 |
booking: data.booking_id, |
| 2352 |
patron: data.patron_id, |
2386 |
patron: data.patron_id, |
| 2353 |
start: dayjs(data.start_date).toDate(), |
2387 |
start: $toDisplayDate(startServerTz), |
| 2354 |
end: dayjs(data.end_date).toDate(), |
2388 |
end: $toDisplayDate(endServerTz), |
| 2355 |
content: $patron_to_html(booking_patron, { |
2389 |
content: $patron_to_html(booking_patron, { |
| 2356 |
display_cardnumber: true, |
2390 |
display_cardnumber: true, |
| 2357 |
url: false, |
2391 |
url: false, |
| 2358 |
- |
|
|