From 166f7d56c6ddbf9aa1e64defeee73df097eb77a5 Mon Sep 17 00:00:00 2001 From: Paul Derscheid Date: Wed, 16 Apr 2025 15:41:05 +0000 Subject: [PATCH] Bug 37829: Add additional fields support to modal, tables To test: 1) Setup: a) Apply the db seed provided: koha-mysql < test_bug_37829.sql --- or --- b) Setup authorised values and additional fields manually: i) Navigate to Administration -> Authorized Values and click '+ New Category'. ii) Define a new authorised value category (e.g., prefix with BOOKINGS_ for easy identification). iii) Click '+ Add a new authorized value'. iv) Add a value, filling in at least 'Authorized Value' and 'Description'. v) Save the value. vi) Navigate to Administration -> Additional Fields. vii) Click 'Bookings (bookings)'. viii)Click '+ New field'. ix) Add a plain text field (fill 'Name' and save). x) Add a repeatable text field. xi) Add a field tied to your previously created authorized value category. xii) Add another field tied to any authorised value (e.g., YES_NO) and make it repeatable. 2) Item Configuration: Make an item bookable. Either: a) Navigate to Administration -> Item types, select an item type (e.g., BK), and check 'bookable'. b) Navigate to the 'Items' view for a specific item (catalogue/moredetail.pl) and set Priority -> Bookable -> 'Yes'. 3) Create Booking: Click the 'Place booking' button on the item's record. The configured additional fields should load dynamically in the modal. 4) Fill and Save Booking: Fill out the default booking fields and then the additional fields. Use the 'Remove' and 'New' buttons for repeatable fields. Save the booking. 5) Verify Display in Tables: Confirm that the additional fields for the booking are displayed correctly in the following locations: a) The bookings table within the bibliographic record's detail view. b) The 'Check out' view (circ/circulation.pl -> Bookings tab). c) The 'Patron's details' view (members/moremember.pl -> Bookings tab). d) The 'Bookings to collect' view (circ/pendingbookings.pl) (adjust filters if necessary). 6) Verify Edit/Move Functionality: Return to the bookings view of the bibliographic record. a) Verify the additional fields are correctly pre-filled and saved when you move the booking using the timeline component. b) Verify the additional fields are correctly pre-filled and saved when you edit the booking using the edit button in the bookings table. 7) Repeat Testing: Repeat steps 4 through 6.b with additional bookings to ensure consistency. 8) Sign-off and/or give your feedback. Here's some things I'd would still like to improve/try: - Incorporate the neighboring additional-fields-entry.js to have a single library for additional fields - Restructure the buttons to be consistent with other usage of additional fields in Koha (noticed this way to late) - Test this with the freshly added support for additional fields on branches (libraries) - Make the additional field values searchable in the table - Clean up and DRY some of the JSDoc types (but this could easily become its own tree of bugs if done from the source :D) - Use mockData.js for the mocha tests instead of hardcoding them I actually need this for a customer and the current state will be alright for that, but now it's good enough to work and improve it together. --- .../prog/en/modules/bookings/list.tt | 85 +++++++++++++------ .../prog/en/modules/catalogue/ISBDdetail.tt | 1 + .../prog/en/modules/catalogue/MARCdetail.tt | 1 + .../prog/en/modules/catalogue/detail.tt | 1 + .../prog/en/modules/catalogue/imageviewer.tt | 1 + .../en/modules/catalogue/labeledMARCdetail.tt | 2 + .../prog/en/modules/catalogue/moredetail.tt | 2 + .../prog/en/modules/circ/circulation.tt | 1 + .../prog/en/modules/circ/pendingbookings.tt | 35 +++++++- .../prog/en/modules/members/moremember.tt | 1 + .../prog/js/modals/place_booking.js | 42 ++++++++- .../intranet-tmpl/prog/js/tables/bookings.js | 32 ++++++- 12 files changed, 172 insertions(+), 32 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/bookings/list.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/bookings/list.tt index b744f730a4a..227ed55e43b 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/bookings/list.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/bookings/list.tt @@ -62,6 +62,7 @@ + [% Asset.js("js/additional-fields.js") | $raw %] [% Asset.js("js/modals/place_booking.js") | $raw %] [% Asset.js("js/cancel_booking_modal.js") | $raw %] [% Asset.js("js/combobox.js") | $raw %] @@ -84,12 +85,24 @@ type: "GET", }); var bookings = $.ajax({ - url: "/api/v1/biblios/%s/bookings?_per_page=-1".format(biblionumber), - headers: { "x-koha-embed": "patron" }, - dataType: "json", - type: "GET", + url: '/api/v1/biblios/%s/bookings?_per_page=-1'.format(biblionumber), + headers: { 'x-koha-embed': ['patron', 'extended_attributes'] }, + dataType: 'json', + type: 'GET', }); - + var extended_attribute_types; + var authorised_values; + AdditionalFields.fetchAndProcessExtendedAttributes("booking") + .then(types => { + extended_attribute_types = types; + const catArray = Object.values(types) + .map(attr => attr.authorised_value_category_name) + .filter(Boolean); + return AdditionalFields.fetchAndProcessAuthorizedValues(catArray); + }) + .then(values => { + authorised_values = values; + }); $.when(items, bookings).then( function (items, bookings) { var itemsSet = new vis.DataSet([ @@ -122,6 +135,7 @@ pickup_library: booking.pickup_library_id, start: $toDisplayDate(startServerTz), end: $toDisplayDate(endServerTz), + extended_attributes: booking.extended_attributes, content: !isActive ? `${patronContent}` : patronContent, className: booking.status === "cancelled" ? "cancelled" : "", ...(permissions.CAN_user_circulate_manage_bookings ? { editable: !["cancelled", "completed"].includes(booking.status) ? { remove: true, updateTime: true } : false } : { editable: false }), @@ -175,26 +189,23 @@ // set end datetime hours and minutes to the end of the day let endDate = dayjs(data.end).endOf("day"); - $("#placeBookingModal").modal( - "show", - $( - ' @@ -399,6 +425,13 @@ escape_str(row.start_date), escape_str(row.end_date), escape_str(row.item.item_type_id), + escape_str(JSON.stringify(row.extended_attributes + .filter(attribute => attribute.record_id == row.booking_id) + .map(attribute => ({ + field_id: attribute.field_id, + value: attribute.value + })) + )), _("Edit") ); result += ` diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/ISBDdetail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/ISBDdetail.tt index 85c511aa8a3..9c88cc74fb7 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/ISBDdetail.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/ISBDdetail.tt @@ -87,6 +87,7 @@ [% IF Koha.Preference('EnableBooking') %] [% INCLUDE 'calendar.inc' %] [% INCLUDE 'select2.inc' %] + [% Asset.js("js/additional-fields.js") | $raw %] [% Asset.js("js/modals/place_booking.js") | $raw %] [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/MARCdetail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/MARCdetail.tt index 66a5774709d..cba194021a1 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/MARCdetail.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/MARCdetail.tt @@ -211,6 +211,7 @@ [% IF Koha.Preference('EnableBooking') %] [% INCLUDE 'calendar.inc' %] [% INCLUDE 'select2.inc' %] + [% Asset.js("js/additional-fields.js") | $raw %] [% Asset.js("js/modals/place_booking.js") | $raw %] [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt index 763cda06baf..547b6af23de 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt @@ -1735,6 +1735,7 @@ [% Asset.js("js/browser.js") | $raw %] [% IF Koha.Preference('EnableBooking') %] + [% Asset.js("js/additional-fields.js") | $raw %] [% Asset.js("js/modals/place_booking.js") | $raw %] [% END %] [% Asset.js("js/catalog.js") | $raw %] + [% Asset.js("js/additional-fields.js") | $raw %] + [% Asset.js("js/modals/place_booking.js") | $raw %] [% Asset.js("js/browser.js") | $raw %] [% IF Koha.Preference('EnableBooking') %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/moredetail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/moredetail.tt index f9313d0dd20..c7549338162 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/moredetail.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/moredetail.tt @@ -593,6 +593,8 @@ dayjs.extend(window.dayjs_plugin_isSameOrBefore); [% Asset.js("js/catalog.js") | $raw %] + [% Asset.js("js/additional-fields.js") | $raw %] + [% Asset.js("js/modals/place_booking.js") | $raw %] [% Asset.js("js/browser.js") | $raw %] [% Asset.js("js/checkout_renewals_modal.js") | $raw %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt index 672d27da176..f7b3ecb038f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt @@ -1111,6 +1111,7 @@ [% END %] [% Asset.js("js/holds.js") | $raw %] [% INCLUDE 'calendar.inc' %] + [% Asset.js("js/additional-fields.js") | $raw %] [% Asset.js("js/cancel_booking_modal.js") | $raw %] [% Asset.js("js/combobox.js") | $raw %] [% INCLUDE 'js-biblio-format.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/pendingbookings.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/pendingbookings.tt index 6b008e35045..2e006736c09 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/pendingbookings.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/pendingbookings.tt @@ -115,6 +115,8 @@ [% INCLUDE 'datatables.inc' %] [% INCLUDE 'js-biblio-format.inc' %] [% INCLUDE 'js-date-format.inc' %] + [% INCLUDE 'js-patron-format.inc' %] + [% Asset.js("js/additional-fields.js") | $raw %]