From d56b392013400d36889bc4fd0295f99f8d63567e Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Mon, 21 Oct 2024 16:36:49 +0100 Subject: [PATCH] Bug 37354: Fix circ rule selections Only expose the bookings calendar picker input if we have enough detail already defined to pick the corresponding circulation rules. We currently use the item pickup location for selecting which rules to apply, this corresponds to hard coding CircControl=ItemHomeLibrary + ItemHomeOrHolding=holdingbranch for this use case. We can't easily change this to match those rules dynamically without rethinking the 'Any item' functionality and displays in the flatpickr. We may revisit this at some point in the future should that become a requirement. Signed-off-by: Nick Clemens --- .../prog/en/includes/modals/place_booking.inc | 6 +- .../prog/js/modals/place_booking.js | 159 ++++++++++-------- 2 files changed, 94 insertions(+), 71 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/modals/place_booking.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/modals/place_booking.inc index f9b662b5a14..e15df51bc3b 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/modals/place_booking.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/modals/place_booking.inc @@ -33,11 +33,7 @@
  • - [% SET itemtypes = ItemTypes.Get() %] -
  • 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 728dc76d3f4..27d271f5703 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/modals/place_booking.js +++ b/koha-tmpl/intranet-tmpl/prog/js/modals/place_booking.js @@ -129,45 +129,54 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { placeholder: __("Search for a patron"), }); - // Lead and Trail days syncing + // Circulation rules update let leadDays = 0; let trailDays = 0; let boldDates = []; let issueLength; let renewalLength; let renewalsAllowed; + + // Note: For now, we apply the pickup library rules for issuelength, renewalsallowed and renewalperiod. + // This effectively makes these circulation rules hard coded to CircControl: ItemHomeLibrary + HomeOrHolding: holdingbranch + // Whilst it would be beneficial to make this follow those rules more closely, this would require some significant thinking + // around how to best display this in the calender component for the 'Any item' case. function getCirculationRules() { let rules_url = "/api/v1/circulation_rules"; - $.ajax({ - url: rules_url, - type: "GET", - dataType: "json", - data: { - patron_category_id: booking_patron.category_id, - item_type_id: booking_itemtype_id, - library_id: pickup_library_id, - rules: "bookings_lead_period,bookings_trail_period,issuelength,renewalsallowed,renewalperiod", - }, - success: function (response) { - let rules = response[0]; - issueLength = rules.issuelength; - renewalsAllowed = rules.renewalsallowed; - renewalLength = rules.renewalperiod; - leadDays = rules.bookings_lead_period; - trailDays = rules.bookings_trail_period; - - // redraw pariodPicker taking selected item into account - periodPicker.redraw(); - - // Enable flatpickr now we have data we need - if (dataFetched) { - $("#period_fields :input").prop("disabled", false); - } - }, - error: function (xhr, status, error) { - console.log("Circulation rules fetch failed: ", error); - }, - }); + if (booking_patron && pickup_library_id && booking_itemtype_id) { + $.ajax({ + url: rules_url, + type: "GET", + dataType: "json", + data: { + patron_category_id: booking_patron.category_id, + item_type_id: booking_itemtype_id, + library_id: pickup_library_id, + rules: "bookings_lead_period,bookings_trail_period,issuelength,renewalsallowed,renewalperiod", + }, + success: function (response) { + let rules = response[0]; + issueLength = rules.issuelength; + renewalsAllowed = rules.renewalsallowed; + renewalLength = rules.renewalperiod; + leadDays = rules.bookings_lead_period; + trailDays = rules.bookings_trail_period; + + // redraw pariodPicker taking selected item into account + periodPicker.redraw(); + + // Enable flatpickr now we have data we need + if (dataFetched) { + $("#period_fields :input").prop("disabled", false); + } + }, + error: function (xhr, status, error) { + console.log("Circulation rules fetch failed: ", error); + }, + }); + } else { + $("#period_fields :input").prop("disabled", true); + } } // Pickup location select2 @@ -304,6 +313,9 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { "&_per_page=-1", dataType: "json", type: "GET", + headers: { + "x-koha-embed": "item_type", + }, }); // Fetch list of existing bookings @@ -350,12 +362,10 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { // Total bookable items let bookable = 0; - - let itemtypes = new Set(); for (item of bookable_items) { bookable++; - // Populate item select (NOTE: Do we still need this check for pre-existing select option here?) + // Populate item select if ( !$("#booking_item_id").find( "option[value='" + item.item_id + "']" @@ -378,18 +388,25 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { $("#booking_item_id").append(newOption); } - // Build list of itemtypes - itemtypes.add(item.effective_item_type_id); - } - - // Filter itemtypes - $("#booking_itemtype option").each(function () { - const optionValue = $(this).val(); - if (!itemtypes.has(optionValue)) { - $(this).remove(); + // Populate item types select + if ( + !$("#booking_itemtype").find( + "option[value='" + + item.item_type.item_type_id + + "']" + ).length + ) { + // Create a DOM Option and de-select by default + let newTypeOption = new Option( + escape_str(item.item_type.description), + item.item_type.item_type_id, + false, + false + ); + $("#booking_itemtype").append(newTypeOption); } - }); - $("#booking_itemtype").trigger("change"); + } + $("#booking_itemtype").val(null).trigger("change"); // Set disable function for periodPicker let disableExists = periodPicker.config.disable.filter( @@ -572,28 +589,33 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { } // Setup listener for itemtype select2 - $("#booking_itemtype").on("select2:select", function (e) { - booking_itemtype_id = e.params.data.id - ? e.params.data.id - : null; - - // Disable items not of this itemtype - $("#booking_item_id > option").each(function () { - let option = $(this); - if (option.val() != 0) { - let item_itemtype = option.data("itemtype"); - if (item_itemtype == booking_itemtype_id) { - if ( - option.data("available") && - option.data("pickup") - ) { - option.prop("disabled", false); + $("#booking_itemtype").on("change", function (e) { + let selectedValue = $(this).val(); // Get selected value (null if cleared) + booking_itemtype_id = selectedValue ? selectedValue : null; + + // Handle item selectionue + if (!booking_itemtype_id) { + // Enable all items for selection + $("#booking_item_id > option").prop("disabled", false); + } else { + // Disable items not of this itemtype + $("#booking_item_id > option").each(function () { + let option = $(this); + if (option.val() != 0) { + let item_itemtype = option.data("itemtype"); + if (item_itemtype == booking_itemtype_id) { + if ( + option.data("available") && + option.data("pickup") + ) { + option.prop("disabled", false); + } + } else { + option.prop("disabled", true); } - } else { - option.prop("disabled", true); } - } - }); + }); + } $("#booking_item_id").trigger("change.select2"); // Update circulation rules @@ -671,6 +693,11 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { // Disable patron selection change $("#booking_patron_id").prop("disabled", true); + + pickup_library_id = $("#pickup_library_id").val(); + + // Populate circulation rules + getCirculationRules(); }); // Set onChange for flatpickr @@ -1230,7 +1257,7 @@ $("#placeBookingModal").on("hidden.bs.modal", function (e) { $("#booking_item_id").prop("disabled", true); // Reset itemtype select - $("#booking_itemtype").val(0).trigger("change"); + $("#booking_itemtype").val(null).trigger("change"); $("#booking_itemtype").prop("disabled", true); booking_itemtype_id = undefined; -- 2.47.0