Bugzilla – Attachment 188778 Details for
Bug 39438
Add additional fields to agreements periods
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 39438: Add additional fields support to ERM agreement periods
Bug-39438-Add-additional-fields-support-to-ERM-agr.patch (text/plain), 14.26 KB, created by
Martin Renvoize (ashimema)
on 2025-10-31 09:20:10 UTC
(
hide
)
Description:
Bug 39438: Add additional fields support to ERM agreement periods
Filename:
MIME Type:
Creator:
Martin Renvoize (ashimema)
Created:
2025-10-31 09:20:10 UTC
Size:
14.26 KB
patch
obsolete
>From f38bf5f9e859d2224ad15275dd2a47be0b02386c Mon Sep 17 00:00:00 2001 >From: Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk> >Date: Wed, 22 Oct 2025 17:09:30 +0100 >Subject: [PATCH] Bug 39438: Add additional fields support to ERM agreement > periods > >This patch enables additional fields functionality for agreement periods >in the ERM (Electronic Resource Management) module, allowing libraries >to define custom metadata fields for agreement period records. > >Changes include: >- Update Koha::AdditionalField to support erm_agreement_periods table >- Modify API definitions to include extended_attributes in responses >- Add erm_agreement_periods option to additional fields admin interface >- Enhance Vue components to display and manage additional field values >- Update ShowElement component to handle period-specific attributes > >Test plan: >1. Navigate to Administration > Additional fields >2. Create new fields for "Agreement periods" >3. Edit an ERM agreement and add/edit period information >4. Verify additional fields appear and can be populated >5. Confirm values are saved and displayed correctly > >Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> >--- > Koha/AdditionalField.pm | 21 +++++++------- > Koha/ERM/Agreement.pm | 9 +++++- > Koha/ERM/Agreement/Period.pm | 2 +- > Koha/ERM/Agreement/Periods.pm | 2 +- > Koha/REST/V1/ExtendedAttributeTypes.pm | 21 +++++++------- > .../definitions/erm_agreement_period.yaml | 10 +++++++ > api/v1/swagger/paths/erm_agreements.yaml | 2 ++ > .../paths/extended_attribute_types.yaml | 1 + > .../en/modules/admin/additional-fields.tt | 1 + > .../prog/js/fetch/erm-api-client.js | 2 +- > .../vue/components/ERM/AgreementResource.vue | 16 ++++++++-- > .../prog/js/vue/components/ShowElement.vue | 29 +++++++++++++++++-- > 12 files changed, 88 insertions(+), 28 deletions(-) > >diff --git a/Koha/AdditionalField.pm b/Koha/AdditionalField.pm >index bf5e5c08146..82a16a86725 100644 >--- a/Koha/AdditionalField.pm >+++ b/Koha/AdditionalField.pm >@@ -55,16 +55,17 @@ sub to_api { > my ( $self, $params ) = @_; > > my $table_to_resource = { >- 'accountlines:credit' => 'credit', >- 'accountlines:debit' => 'debit', >- 'aqbasket' => 'basket', >- 'aqinvoices' => 'invoice', >- 'erm_licenses' => 'license', >- 'erm_agreements' => 'agreement', >- 'erm_packages' => 'package', >- 'aqorders' => 'order', >- 'aqbooksellers:vendor' => 'vendor', >- 'erm_titles' => 'title' >+ 'accountlines:credit' => 'credit', >+ 'accountlines:debit' => 'debit', >+ 'aqbasket' => 'basket', >+ 'aqinvoices' => 'invoice', >+ 'erm_licenses' => 'license', >+ 'erm_agreements' => 'agreement', >+ 'erm_packages' => 'package', >+ 'aqorders' => 'order', >+ 'aqbooksellers:vendor' => 'vendor', >+ 'erm_titles' => 'title', >+ 'erm_agreement_periods' => 'agreement_period' > }; > > my $json = $self->SUPER::to_api($params); >diff --git a/Koha/ERM/Agreement.pm b/Koha/ERM/Agreement.pm >index 6961d074a7b..00167a653ea 100644 >--- a/Koha/ERM/Agreement.pm >+++ b/Koha/ERM/Agreement.pm >@@ -27,6 +27,7 @@ use Koha::Acquisition::Bookseller; > > use base qw(Koha::Object::Mixin::AdditionalFields Koha::Object); > >+use Koha::ERM::Agreement::Period; > use Koha::ERM::Agreement::Periods; > use Koha::ERM::Agreement::Licenses; > use Koha::ERM::Agreement::Relationships; >@@ -60,7 +61,13 @@ sub periods { > $self->periods->delete; > > for my $period (@$periods) { >- $self->_result->add_to_erm_agreement_periods($period); >+ my $extended_attributes = delete $period->{extended_attributes} // []; >+ my @extended_attributes = >+ map { { 'id' => $_->{field_id}, 'value' => $_->{value} } } @{$extended_attributes}; >+ $period->{agreement_id} = $self->agreement_id; >+ >+ my $stored_period = Koha::ERM::Agreement::Period->new($period)->store; >+ $stored_period->extended_attributes( \@extended_attributes ); > } > } > ); >diff --git a/Koha/ERM/Agreement/Period.pm b/Koha/ERM/Agreement/Period.pm >index 20e5a6cfb80..5f40a95e429 100644 >--- a/Koha/ERM/Agreement/Period.pm >+++ b/Koha/ERM/Agreement/Period.pm >@@ -19,7 +19,7 @@ use Modern::Perl; > > use Koha::Database; > >-use base qw(Koha::Object); >+use base qw(Koha::Object::Mixin::AdditionalFields Koha::Object); > > =head1 NAME > >diff --git a/Koha/ERM/Agreement/Periods.pm b/Koha/ERM/Agreement/Periods.pm >index 07f70bbdc41..d65eeb08544 100644 >--- a/Koha/ERM/Agreement/Periods.pm >+++ b/Koha/ERM/Agreement/Periods.pm >@@ -21,7 +21,7 @@ use Koha::Database; > > use Koha::ERM::Agreement::Period; > >-use base qw(Koha::Objects); >+use base qw(Koha::Objects::Mixin::AdditionalFields Koha::Objects); > > =head1 NAME > >diff --git a/Koha/REST/V1/ExtendedAttributeTypes.pm b/Koha/REST/V1/ExtendedAttributeTypes.pm >index 782880210e6..d0892efae3f 100644 >--- a/Koha/REST/V1/ExtendedAttributeTypes.pm >+++ b/Koha/REST/V1/ExtendedAttributeTypes.pm >@@ -46,16 +46,17 @@ sub list { > > # FIXME: Maybe not the best place for this mapping > my $resource_to_table = { >- basket => 'aqbasket', >- credit => 'accountlines:credit', >- debit => 'accountlines:debit', >- invoice => 'aqinvoices', >- license => 'erm_licenses', >- agreement => 'erm_agreements', >- package => 'erm_packages', >- order => 'aqorders', >- vendor => 'aqbooksellers:vendor', >- title => 'erm_titles' >+ basket => 'aqbasket', >+ credit => 'accountlines:credit', >+ debit => 'accountlines:debit', >+ invoice => 'aqinvoices', >+ license => 'erm_licenses', >+ agreement => 'erm_agreements', >+ package => 'erm_packages', >+ order => 'aqorders', >+ vendor => 'aqbooksellers:vendor', >+ title => 'erm_titles', >+ agreement_period => 'erm_agreement_periods' > }; > > return try { >diff --git a/api/v1/swagger/definitions/erm_agreement_period.yaml b/api/v1/swagger/definitions/erm_agreement_period.yaml >index e439d4868c7..6e78c1d0a9a 100644 >--- a/api/v1/swagger/definitions/erm_agreement_period.yaml >+++ b/api/v1/swagger/definitions/erm_agreement_period.yaml >@@ -28,6 +28,16 @@ properties: > type: > - string > - "null" >+ extended_attributes: >+ description: Related additional field values >+ type: >+ - array >+ items: >+ $ref: extended_attribute_value.yaml >+ _strings: >+ type: >+ - object >+ - "null" > additionalProperties: false > required: > - started_on >diff --git a/api/v1/swagger/paths/erm_agreements.yaml b/api/v1/swagger/paths/erm_agreements.yaml >index 933192191a8..84f26b9142f 100644 >--- a/api/v1/swagger/paths/erm_agreements.yaml >+++ b/api/v1/swagger/paths/erm_agreements.yaml >@@ -189,6 +189,8 @@ > type: string > enum: > - periods >+ - periods.extended_attributes >+ - periods+strings > - user_roles > - user_roles.patron > - agreement_licenses >diff --git a/api/v1/swagger/paths/extended_attribute_types.yaml b/api/v1/swagger/paths/extended_attribute_types.yaml >index 675a80a2506..2324519b6fd 100644 >--- a/api/v1/swagger/paths/extended_attribute_types.yaml >+++ b/api/v1/swagger/paths/extended_attribute_types.yaml >@@ -25,6 +25,7 @@ > - subscription > - vendor > - title >+ - agreement_period > - $ref: "../swagger.yaml#/parameters/match" > - $ref: "../swagger.yaml#/parameters/order_by" > - $ref: "../swagger.yaml#/parameters/page" >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/additional-fields.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/additional-fields.tt >index 3dbb35ca67c..294cc25a0e4 100755 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/additional-fields.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/additional-fields.tt >@@ -147,6 +147,7 @@ > [% WRAPPER table_option value="erm_licenses" %]Licenses[% END %] > [% WRAPPER table_option value="erm_packages" %]Packages[% END %] > [% WRAPPER table_option value="erm_titles" %]Titles[% END %] >+ [% WRAPPER table_option value="erm_agreement_periods" %]Agreement periods[% END %] > </ul> > [% END %] > [% IF CAN_user_updatecharges_remaining_permissions || CAN_user_parameters_manage_accounts %] >diff --git a/koha-tmpl/intranet-tmpl/prog/js/fetch/erm-api-client.js b/koha-tmpl/intranet-tmpl/prog/js/fetch/erm-api-client.js >index ef1737f4afc..830b80f7317 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/fetch/erm-api-client.js >+++ b/koha-tmpl/intranet-tmpl/prog/js/fetch/erm-api-client.js >@@ -21,7 +21,7 @@ export class ERMAPIClient { > endpoint: "agreements/" + id, > headers: { > "x-koha-embed": >- "periods,user_roles,user_roles.patron,agreement_licenses,agreement_licenses.license,agreement_relationships,agreement_relationships.related_agreement,documents,agreement_packages,agreement_packages.package,vendor,extended_attributes,+strings", >+ "periods,periods.extended_attributes,periods+strings,user_roles,user_roles.patron,agreement_licenses,agreement_licenses.license,agreement_relationships,agreement_relationships.related_agreement,documents,agreement_packages,agreement_packages.package,vendor,extended_attributes,+strings", > }, > }), > getAll: (query, params) => >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementResource.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementResource.vue >index 006004065aa..f5e9d2b2ab4 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementResource.vue >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementResource.vue >@@ -169,6 +169,7 @@ export default { > type: "table", > columnData: "periods", > hidden: agreement => !!agreement.periods?.length, >+ includeAdditionalFields: true, > columns: [ > { > name: $__("Period start"), >@@ -208,6 +209,7 @@ export default { > ended_on: null, > cancellation_deadline: null, > notes: null, >+ extended_attributes: [], > }, > }, > }, >@@ -251,6 +253,12 @@ export default { > label: $__("Notes"), > indexRequired: true, > }, >+ { >+ name: "additional_fields", >+ type: "additional_fields", >+ extended_attributes_resource_type: >+ "agreement_period", >+ }, > ], > hideIn: ["List"], > }, >@@ -781,8 +789,12 @@ export default { > } > > agreement.periods = agreement.periods.map( >- ({ agreement_id, agreement_period_id, ...keepAttrs }) => >- keepAttrs >+ ({ >+ agreement_id, >+ agreement_period_id, >+ _strings, >+ ...keepAttrs >+ }) => keepAttrs > ); > > agreement.user_roles = agreement.user_roles.map( >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ShowElement.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ShowElement.vue >index 4b28e552307..34e50d36bf9 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ShowElement.vue >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ShowElement.vue >@@ -55,7 +55,7 @@ > <table> > <thead> > <th >- v-for="column in attribute.columns" >+ v-for="column in tableColumns" > :key="column.name + 'head'" > > > {{ column.name }} >@@ -67,7 +67,7 @@ > v-bind:key="counter" > > > <td >- v-for="dataColumn in attribute.columns" >+ v-for="dataColumn in tableColumns" > :key="dataColumn.name + 'data'" > > > <template >@@ -196,6 +196,30 @@ export default { > ); > return option.description; > }); >+ const tableColumns = computed(() => { >+ const tableData = props.resource[attribute.value.columnData]; >+ const columns = attribute.value.columns; >+ if (attribute.value.includeAdditionalFields && tableData?.length) { >+ const additionalFieldColumns = tableData.reduce((acc, curr) => { >+ if (curr._strings?.additional_field_values.length) { >+ curr._strings.additional_field_values.forEach(av => { >+ if (!acc.includes(av.field_label)) { >+ acc.push(av.field_label); >+ } >+ curr[av.field_label] = av.value_str; >+ }); >+ } >+ return acc; >+ }, []); >+ additionalFieldColumns.forEach(col => { >+ columns.push({ >+ name: col, >+ value: col, >+ }); >+ }); >+ } >+ return columns; >+ }); > > return { > ...baseElement, >@@ -203,6 +227,7 @@ export default { > attribute, > formatValue, > radioOptionText, >+ tableColumns, > }; > }, > props: { >-- >2.51.1
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 39438
:
188307
|
188778
|
188779
|
189021
|
189022
|
189023