From 3c03bcbec267b52f91b335f5e712c29173458f83 Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Thu, 22 May 2025 07:45:53 +0100 Subject: [PATCH] Bug 37707: First draft This patch adds calculation of pre and post booking days into the disableDate function. I'm not sure I like it for display yet, but functionally it works --- .../prog/js/modals/place_booking.js | 192 ++++++++++++------ 1 file changed, 131 insertions(+), 61 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/js/modals/place_booking.js b/koha-tmpl/intranet-tmpl/prog/js/modals/place_booking.js index 4e8d2e83fa9..df965c324c5 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/modals/place_booking.js +++ b/koha-tmpl/intranet-tmpl/prog/js/modals/place_booking.js @@ -93,29 +93,29 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { let $patron = $("") .append( "" + - (patron.surname - ? escape_str(patron.surname) + ", " - : "") + - (patron.firstname - ? escape_str(patron.firstname) + " " - : "") + - (patron.cardnumber - ? " (" + escape_str(patron.cardnumber) + ")" - : "") + - "" + - (patron.date_of_birth - ? ' ' + - $get_age(patron.date_of_birth) + - " " + - __("years") + - "" - : "") + - (patron.library - ? ' ' + - escape_str(patron.library.name) + - "" - : "") + - "" + (patron.surname + ? escape_str(patron.surname) + ", " + : "") + + (patron.firstname + ? escape_str(patron.firstname) + " " + : "") + + (patron.cardnumber + ? " (" + escape_str(patron.cardnumber) + ")" + : "") + + "" + + (patron.date_of_birth + ? ' ' + + $get_age(patron.date_of_birth) + + " " + + __("years") + + "" + : "") + + (patron.library + ? ' ' + + escape_str(patron.library.name) + + "" + : "") + + "" ) .addClass(loggedInClass); return $patron; @@ -212,10 +212,10 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { ) { let option = $( '" + pickup_location.library_id + + '">' + + pickup_location.name + + "" ); option.attr( @@ -414,8 +414,8 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { if ( !$("#booking_itemtype").find( "option[value='" + - item.item_type.item_type_id + - "']" + item.item_type.item_type_id + + "']" ).length ) { // Create a DOM Option and de-select by default @@ -468,19 +468,29 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { continue; } - let start_date = flatpickr.parseDate( - booking.start_date + // Apply lead and trail periods to the booking dates + let start_date = dayjs(booking.start_date); + let end_date = dayjs(booking.end_date); + + // Apply lead period - subtract leadDays from start_date + let start_date_with_lead = start_date.subtract( + leadDays, + "day" ); - let end_date = flatpickr.parseDate( - booking.end_date + + // Apply trail period - add trailDays to end_date + let end_date_with_trail = end_date.add( + trailDays, + "day" ); // patron has selected a start date (end date checks) if (selectedDates[0]) { - // new booking start date is between existing booking start and end dates + // new booking start date is between existing booking start (with lead) and end (with trail) dates if ( - selectedDates[0] >= start_date && - selectedDates[0] <= end_date + selectedDates[0] >= + start_date_with_lead && + selectedDates[0] <= end_date_with_trail ) { if (booking.item_id) { if ( @@ -505,10 +515,10 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { } } - // new booking end date would be between existing booking start and end dates + // new booking end date would be between existing booking start (with lead) and end (with trail) dates else if ( - date >= start_date && - date <= end_date + date >= start_date_with_lead && + date <= end_date_with_trail ) { if (booking.item_id) { if ( @@ -535,8 +545,9 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { // new booking would span existing booking else if ( - selectedDates[0] <= start_date && - date >= end_date + selectedDates[0] <= + start_date_with_lead && + date >= end_date_with_trail ) { if (booking.item_id) { if ( @@ -579,8 +590,8 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { // patron has not yet selected a start date (start date checks) else if ( - date <= end_date && - date >= start_date + date <= end_date_with_trail && + date >= start_date_with_lead ) { // same item, disable date if ( @@ -753,7 +764,7 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { for (let i = 0; i < renewalsAllowed; i++) { nextDate.setDate( nextDate.getDate() + - parseInt(renewalLength) + parseInt(renewalLength) ); boldDates.push(new Date(nextDate)); } @@ -769,8 +780,8 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { const maxDate = new Date(startDate.getTime()); maxDate.setDate( maxDate.getDate() + - totalIssueLength + - parseInt(trailDays) + totalIssueLength + + parseInt(trailDays) ); // Apply disabled style to inclusive trailDays in maxDate @@ -874,15 +885,28 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { // Create a bookings store keyed on date let bookingsByDate = {}; + // Iterate through the bookings array bookings.forEach(booking => { const start_date = flatpickr.parseDate(booking.start_date); const end_date = flatpickr.parseDate(booking.end_date); const item_id = booking.item_id; - // Iterate through each date within the range of start_date and end_date - let currentDate = new Date(start_date); - while (currentDate <= end_date) { + // Apply lead period - subtract leadDays from start_date + let start_date_with_lead = new Date(start_date); + start_date_with_lead.setDate( + start_date_with_lead.getDate() - leadDays + ); + + // Apply trail period - add trailDays to end_date + let end_date_with_trail = new Date(end_date); + end_date_with_trail.setDate( + end_date_with_trail.getDate() + trailDays + ); + + // Iterate through each date within the range of start_date (with lead) and end_date (with trail) + let currentDate = new Date(start_date_with_lead); + while (currentDate <= end_date_with_trail) { const currentDateStr = currentDate .toISOString() .split("T")[0]; @@ -932,6 +956,52 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { const dots = document.createElement("span"); dots.className = "event-dots"; dayElem.appendChild(dots); + + // Check if this date is in a lead or trail period + let isLeadOrTrail = false; + + // Check for each booking if this date is within its lead or trail period + for (booking of bookings) { + const start_date = flatpickr.parseDate( + booking.start_date + ); + const end_date = flatpickr.parseDate( + booking.end_date + ); + + // Lead period check + let lead_start = new Date(start_date); + lead_start.setDate( + lead_start.getDate() - leadDays + ); + + // Trail period check + let trail_end = new Date(end_date); + trail_end.setDate( + trail_end.getDate() + trailDays + ); + + // Check if current date is in lead period but before start_date + let isInLeadPeriod = + currentDate >= lead_start && + currentDate < start_date; + + // Check if current date is in trail period but after end_date + let isInTrailPeriod = + currentDate <= trail_end && + currentDate > end_date; + + if (isInLeadPeriod || isInTrailPeriod) { + isLeadOrTrail = true; + break; + } + } + + // Add a special class for dates in lead/trail periods + if (isLeadOrTrail) { + dayElem.classList.add("booking-lead-trail"); + } + bookingsByDate[dateString].forEach(item => { const dot = document.createElement("span"); dot.className = "event item_" + item; @@ -953,8 +1023,8 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { ); const startDate = periodPicker.selectedDates[0] ? dayjs(periodPicker.selectedDates[0]).startOf( - "day" - ) + "day" + ) : null; const leadStart = startDate @@ -980,7 +1050,7 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { dayElem.classList.toggle( "leadRange", elemDate.isSameOrAfter(leadStart) && - elemDate.isBefore(leadEnd) + elemDate.isBefore(leadEnd) ); dayElem.classList.toggle( "leadRangeEnd", @@ -993,7 +1063,7 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { dayElem.classList.toggle( "trailRange", elemDate.isAfter(trailStart) && - elemDate.isSameOrBefore(trailEnd) + elemDate.isSameOrBefore(trailEnd) ); dayElem.classList.toggle( "trailRangeEnd", @@ -1216,8 +1286,8 @@ $("#placeBookingForm").on("submit", function (e) { // Set feedback $("#transient_result").replaceWith( '
' + - __("Booking successfully placed") + - "
" + __("Booking successfully placed") + + "" ); // Close modal @@ -1227,8 +1297,8 @@ $("#placeBookingForm").on("submit", function (e) { posting.fail(function (data) { $("#booking_result").replaceWith( '
' + - __("Failure") + - "
" + __("Failure") + + "" ); }); } else { @@ -1285,8 +1355,8 @@ $("#placeBookingForm").on("submit", function (e) { // Set feedback $("#transient_result").replaceWith( '
' + - __("Booking successfully updated") + - "
" + __("Booking successfully updated") + + "" ); // Close modal @@ -1296,8 +1366,8 @@ $("#placeBookingForm").on("submit", function (e) { putting.fail(function (data) { $("#booking_result").replaceWith( '
' + - __("Failure") + - "
" + __("Failure") + + "" ); }); } -- 2.49.0