From 034909d7b00a8f5fa4ea19878c16d387a42907d6 Mon Sep 17 00:00:00 2001
From: Pedro Amorim <pedro.amorim@ptfs-europe.com>
Date: Wed, 8 Nov 2023 11:35:29 -0100
Subject: [PATCH] Bug 35287: Vue - Add additional fields support to ERM
 Licenses

Test plan, k-t-d:
1) Add a new additional field for the newly supported 'erm_licenses', visit:
/cgi-bin/koha/admin/additional-fields.pl?tablename=erm_licenses
2) Create 4 fields by clicking on '+ New field'
2.1) 'text non-repeatable'
2.2) 'text repeatable', check the 'repeatable' box
2.3) 'av non-repeatable', pick an authorised value category
2.4) 'av repeatable', pick an authorised value category and check the 'repeatable' box
3) Add a new ERM license, visit:
/cgi-bin/koha/erm/licenses/add
4) Notice there is now a 'Additional fields' section at the bottom listing the fields we created
5) Fill in the mandatory regular license fields and play around with the additional fields
5.1) Put in some text in the text fields, test out the 'clear' and '+new' buttons
5.2) Select some AV options from the AV fields, deselect them, notice the repeatable one allows for multiple selection, the non-repeatable one does not
6) Save the license. On the list table, click on the license name (to navigate to the show page), or if license id=1, visit:
/cgi-bin/koha/erm/licenses/1
7) Notice the additional fields are listed there, AV fields show their human readable description, not the AV code. Repeatable fields are shown comma separated
8) Edit the license, visit:
/cgi-bin/koha/erm/licenses/edit/1
9) Play around again, do some more inserting and deletion of additional fields. Save. Notice everything is as expected.

Searchable testing:
10) Go back to the additional fields admin panel, visit:
/cgi-bin/koha/admin/additional-fields.pl?tablename=erm_licenses
11) Edit one field (AV or not) that you have inserted some data in, in the previous steps, and tick the 'searchable' box
12) Go back to licenses, visit:
/cgi-bin/koha/erm/licenses
13) Notice the searchable additional field now has its own column in the licenses list table
14) If the searchable field is AV, it has a dropdown with the AV values of the same AV category
15) If the searchable field not AV, it has a text input that allows for normal text search
16) If the searchable field is repeatable and has multiple values, its displayed in comma separated

Signed-off-by: Edith Speller <edith.speller@ukhsa.gov.uk>
Signed-off-by: Michaela Sieber <michaela.sieber@kit.edu>
---
 .../js/vue/components/ERM/LicensesFormAdd.vue | 12 +++++
 .../js/vue/components/ERM/LicensesList.vue    | 51 ++++++++++++++++++-
 .../js/vue/components/ERM/LicensesShow.vue    | 13 ++++-
 .../prog/js/vue/fetch/erm-api-client.js       |  2 +-
 4 files changed, 74 insertions(+), 4 deletions(-)

diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/LicensesFormAdd.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/LicensesFormAdd.vue
index b14f93bb250..8752224b385 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/LicensesFormAdd.vue
+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/LicensesFormAdd.vue
@@ -109,6 +109,11 @@
                         </li>
                     </ol>
                 </fieldset>
+                <AdditionalFieldsEntry
+                    tablename="erm_licenses"
+                    :additional_field_values="license.extended_attributes"
+                    @additional-fields-changed="additionalFieldsChanged"
+                />
                 <UserRoles
                     :user_type="$__('License user %s')"
                     :user_roles="license.user_roles"
@@ -134,6 +139,7 @@ import { inject } from "vue"
 import flatPickr from "vue-flatpickr-component"
 import UserRoles from "./UserRoles.vue"
 import Documents from "./Documents.vue"
+import AdditionalFieldsEntry from "../AdditionalFieldsEntry.vue"
 import FormSelectVendors from "../FormSelectVendors.vue"
 import { setMessage, setWarning } from "../../messages"
 import { APIClient } from "../../fetch/api-client.js"
@@ -166,6 +172,7 @@ export default {
                 ended_on: undefined,
                 user_roles: [],
                 documents: [],
+                extended_attributes: [],
             },
             initialized: false,
         }
@@ -228,6 +235,7 @@ export default {
 
             delete license.license_id
             delete license.vendor
+            delete license._strings
 
             if (license.vendor_id == "") {
                 license.vendor_id = null
@@ -260,12 +268,16 @@ export default {
                 )
             }
         },
+        additionalFieldsChanged(additionalFieldValues) {
+            this.license.extended_attributes = additionalFieldValues
+        },
     },
     components: {
         flatPickr,
         UserRoles,
         Documents,
         FormSelectVendors,
+        AdditionalFieldsEntry,
     },
     name: "LicensesFormAdd",
 }
diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/LicensesList.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/LicensesList.vue
index 93cd1dba6e3..7243dd17888 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/LicensesList.vue
+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/LicensesList.vue
@@ -12,6 +12,8 @@
             <KohaTable
                 ref="table"
                 v-bind="tableOptions"
+                :searchable_additional_fields="searchable_additional_fields"
+                :searchable_av_options="searchable_av_options"
                 @show="doShow"
                 @edit="doEdit"
                 @delete="doDelete"
@@ -64,10 +66,12 @@ export default {
                     button_title: this.$__("New license"),
                 },
             ],
+            searchable_additional_fields: [],
+            searchable_av_options: [],
             tableOptions: {
                 columns: this.getTableColumns(),
                 url: "/api/v1/erm/licenses",
-                options: { embed: "vendor" },
+                options: { embed: "vendor,extended_attributes,+strings" },
                 table_settings: this.license_table_settings,
                 add_filters: true,
                 filters_options: {
@@ -89,7 +93,15 @@ export default {
     },
     beforeRouteEnter(to, from, next) {
         next(vm => {
-            vm.getLicenseCount().then(() => (vm.initialized = true))
+            vm.getLicenseCount().then(() =>
+                vm
+                    .getSearchableAdditionalFields()
+                    .then(() =>
+                        vm
+                            .getSearchableAVOptions()
+                            .then(() => (vm.initialized = true))
+                    )
+            )
         })
     },
     methods: {
@@ -102,6 +114,41 @@ export default {
                 error => {}
             )
         },
+        async getSearchableAdditionalFields() {
+            const client = APIClient.additional_fields
+            await client.additional_fields.getAll("erm_licenses").then(
+                searchable_additional_fields => {
+                    this.searchable_additional_fields =
+                        searchable_additional_fields.filter(
+                            field => field.searchable
+                        )
+                },
+                error => {}
+            )
+        },
+        async getSearchableAVOptions() {
+            const client_av = APIClient.authorised_values
+            let av_cat_array = this.searchable_additional_fields
+                .filter(field => field.authorised_value_category)
+                .map(field => field.authorised_value_category)
+
+            await client_av.values
+                .getCategoriesWithValues([
+                    ...new Set(av_cat_array.map(av_cat => '"' + av_cat + '"')),
+                ]) // unique
+                .then(av_categories => {
+                    av_cat_array.forEach(av_cat => {
+                        let av_match = av_categories.find(
+                            element => element.category_name == av_cat
+                        )
+                        this.searchable_av_options[av_cat] =
+                            av_match.authorised_values.map(av => ({
+                                value: av.value,
+                                label: av.description,
+                            }))
+                    })
+                })
+        },
         doShow: function ({ license_id }, dt, event) {
             event.preventDefault()
             this.$router.push({ name: "LicensesShow", params: { license_id } })
diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/LicensesShow.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/LicensesShow.vue
index 19c853f4aa0..3ba0e5c63d8 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/LicensesShow.vue
+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/LicensesShow.vue
@@ -132,6 +132,12 @@
                     </li>
                 </ol>
             </fieldset>
+            <AdditionalFieldsDisplay
+                tablename="erm_licenses"
+                :additional_field_values="
+                    license._strings.additional_field_values
+                "
+            />
             <fieldset class="action">
                 <router-link
                     :to="{ name: 'LicensesList' }"
@@ -147,6 +153,7 @@
 <script>
 import { inject } from "vue"
 import { APIClient } from "../../fetch/api-client.js"
+import AdditionalFieldsDisplay from "../AdditionalFieldsDisplay.vue"
 
 export default {
     setup() {
@@ -177,6 +184,8 @@ export default {
                 type: "",
                 status: "",
                 user_roles: [],
+                extended_attributes: [],
+                _strings: [],
                 started_on: undefined,
                 ended_on: undefined,
             },
@@ -227,7 +236,9 @@ export default {
             )
         },
     },
-    components: {},
+    components: {
+        AdditionalFieldsDisplay,
+    },
     name: "LicensesShow",
 }
 </script>
diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/erm-api-client.js b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/erm-api-client.js
index f563f617019..e10010d234d 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/erm-api-client.js
+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/erm-api-client.js
@@ -66,7 +66,7 @@ export class ERMAPIClient extends HttpClient {
                     endpoint: "licenses/" + id,
                     headers: {
                         "x-koha-embed":
-                            "user_roles,user_roles.patron,vendor,documents",
+                            "user_roles,user_roles.patron,vendor,documents,extended_attributes,+strings",
                     },
                 }),
             getAll: (query, params) =>
-- 
2.39.2