From 080fccc0c5681d0d9be312c04ced1d6b86b91f8e Mon Sep 17 00:00:00 2001 From: Matt Blenkinsop 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 Signed-off-by: Lucas Gass --- 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 bf5e5c0814..82a16a8672 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 6961d074a7..00167a653e 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 20e5a6cfb8..5f40a95e42 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 07f70bbdc4..d65eeb0854 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 34442704ef..1218f0740a 100644 --- a/Koha/REST/V1/ExtendedAttributeTypes.pm +++ b/Koha/REST/V1/ExtendedAttributeTypes.pm @@ -44,16 +44,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' }; my @tables; diff --git a/api/v1/swagger/definitions/erm_agreement_period.yaml b/api/v1/swagger/definitions/erm_agreement_period.yaml index e439d4868c..6e78c1d0a9 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 933192191a..84f26b9142 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 675a80a250..2324519b6f 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 3dbb35ca67..294cc25a0e 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 %] [% 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 68091565a4..b2655b64f8 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 cf76bb2988..51a76cbeec 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"), @@ -211,6 +212,7 @@ export default { ended_on: null, cancellation_deadline: null, notes: null, + extended_attributes: [], }, }, }, @@ -254,6 +256,12 @@ export default { label: $__("Notes"), indexRequired: true, }, + { + name: "additional_fields", + type: "additional_fields", + extended_attributes_resource_type: + "agreement_period", + }, ], hideIn: ["List"], }, @@ -797,8 +805,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 4b28e55230..34e50d36bf 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 @@
{{ column.name }} @@ -67,7 +67,7 @@ v-bind:key="counter" >