From 360ba1d8ae5cb55506655cafe17d6a7cdf7c5bd0 Mon Sep 17 00:00:00 2001 From: Volodymyr Rohach Date: Tue, 15 Oct 2024 21:01:04 +0200 Subject: [PATCH] MODSOURMAN-1228: Update default mapping for Date type, Date 1, and Date 2 fields (#936) * MODSOURMAN-1228: Feature implemented. * MODSOURMAN-1228: Rule desc improved. * MODSOURMAN-1228: Useless field "description" removed. * MODSOURMAN-1228: Documentation improved. --- NEWS.md | 1 + RuleProcessorApi.md | 59 +++++++++++++++++++ descriptors/ModuleDescriptor-template.json | 5 +- .../processor/MappingParametersProvider.java | 20 ++++++- .../main/resources/rules/marc_bib_rules.json | 53 +++++++++++++++++ .../org/folio/rest/impl/AbstractRestTest.java | 3 + .../changeManager/ChangeManagerAPITest.java | 1 + .../MappingParametersProviderTest.java | 5 ++ .../org/folio/mapping/mappedBibRecord.json | 1 + .../org/folio/services/marc_bib_rules.json | 53 +++++++++++++++++ .../folio/services/marc_mapping_params.json | 1 + 11 files changed, 200 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 824b4c1b7..0b2b87ef8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -19,6 +19,7 @@ * [MODSOURMAN-1212](https://folio-org.atlassian.net/browse/MODSOURMAN-1212) Update MARC bib-instance default mapping for subject source and subject type * [MODDATAIMP-1085](https://folio-org.atlassian.net/browse/MODDATAIMP-1085) Provide module permissions for subject types and sources * [MODDICORE-415](https://folio-org.atlassian.net/browse/MODDICORE-415) Adjust mapping of Subject source specified in subfield 2 +* [MODSOURMAN-1228](https://folio-org.atlassian.net/browse/MODSOURMAN-1212) Update default mapping for Date type, Date 1, and Date 2 fields ## 2023-03-22 v3.8.0 * [MODSOURMAN-1131](https://folio-org.atlassian.net/browse/MODSOURMAN-1131) The import of file for creating orders is completed with errors diff --git a/RuleProcessorApi.md b/RuleProcessorApi.md index bf2fc0e28..96aa5cfe8 100644 --- a/RuleProcessorApi.md +++ b/RuleProcessorApi.md @@ -798,6 +798,65 @@ If ending punctuation of the last mapped subfield of the field is a period or co ``` ##### **NOTE**: Regarding ending punctuation - if the mapped text ends with (".", ",", ";") then it will be(the last symbol) removed for the matching with Contributor Type. +#### Map single JsonObject +If there is a need to map not arrays or string but json object with simple fields inside (strings), there can be used "createSingleObject" rule, which will create a single json object with specified fields: + +```json +Building Dates json object: +{ +"target": "dates.dateTypeId", +"description": "Date type ID", +"subfield": [], +"createSingleObject": true, +"rules": [ +{ +"conditions": [ +{ +"type": "set_date_type_id" +} +] +} +] +}, +{ +"target": "dates.date1", +"description": "Date 1", +"subfield": [], +"createSingleObject": true, +"rules": [ +{ +"conditions": [ +{ +"type": "char_select", +"parameter": { +"from": 7, +"to": 11 +} +} +] +} +] +}, +{ +"target": "dates.date2", +"description": "Date 2", +"subfield": [], +"createSingleObject": true, +"rules": [ +{ +"conditions": [ +{ +"type": "char_select", +"parameter": { +"from": 11, +"to": 15 +} +} +] +} +] +} +``` # ### REST API When the source-record-manager starts up, it performs initialization for default mapping rules for given tenant. diff --git a/descriptors/ModuleDescriptor-template.json b/descriptors/ModuleDescriptor-template.json index 517420f8d..50786051c 100644 --- a/descriptors/ModuleDescriptor-template.json +++ b/descriptors/ModuleDescriptor-template.json @@ -312,6 +312,8 @@ "inventory-storage.statistical-codes.collection.get", "inventory-storage.subject-sources.collection.get", "inventory-storage.subject-types.collection.get", + "inventory-storage.subject-types.collection.get", + "inventory-storage.instance-date-types.collection.get", "mapping-metadata.get", "orders.po-lines.collection.get", "source-storage.records.get", @@ -608,7 +610,8 @@ "inventory-storage.statistical-code-types.collection.get", "inventory-storage.statistical-codes.collection.get", "inventory-storage.subject-sources.collection.get", - "inventory-storage.subject-types.collection.get" + "inventory-storage.subject-types.collection.get", + "inventory-storage.instance-date-types.collection.get" ] } ] diff --git a/mod-source-record-manager-server/src/main/java/org/folio/services/mappers/processor/MappingParametersProvider.java b/mod-source-record-manager-server/src/main/java/org/folio/services/mappers/processor/MappingParametersProvider.java index 5d25a8392..88e028401 100644 --- a/mod-source-record-manager-server/src/main/java/org/folio/services/mappers/processor/MappingParametersProvider.java +++ b/mod-source-record-manager-server/src/main/java/org/folio/services/mappers/processor/MappingParametersProvider.java @@ -48,6 +48,8 @@ import org.folio.Identifiertypes; import org.folio.IllPolicy; import org.folio.Illpolicies; +import org.folio.InstanceDateType; +import org.folio.InstanceDateTypes; import org.folio.InstanceFormat; import org.folio.InstanceNoteType; import org.folio.InstanceRelationshipType; @@ -134,6 +136,7 @@ public class MappingParametersProvider { private static final String AUTHORITY_SOURCE_FILES_RESPONSE_PARAM = "authoritySourceFiles"; private static final String SUBJECTS_SOURCES_RESPONSE_PARAM = "subjectSources"; private static final String SUBJECTS_TYPES_RESPONSE_PARAM = "subjectTypes"; + private static final String INSTANCE_DATE_TYPES_RESPONSE_PARAM = "instanceDateTypes"; private static final String CONFIGS_VALUE_RESPONSE = "configs"; private static final String VALUE_RESPONSE = "value"; @@ -193,6 +196,7 @@ private Future initializeParameters(MappingParameters mapping Future> authoritySourceFilesFuture = getAuthoritySourceFiles(okapiParams); Future> subjectSourcesFuture = getSubjectSources(okapiParams); Future> subjectTypesFuture = getSubjectTypes(okapiParams); + Future> instanceDateTypesFuture = getInstanceDateTypes(okapiParams); Future> marcFieldProtectionSettingsFuture = getMarcFieldProtectionSettings(okapiParams); Future tenantConfigurationZoneFuture = getTenantConfigurationZone(okapiParams); Future> linkingRulesFuture = getLinkingRules(okapiParams); @@ -202,7 +206,7 @@ private Future initializeParameters(MappingParameters mapping contributorTypesFuture, contributorNameTypesFuture, electronicAccessRelationshipsFuture, instanceNoteTypesFuture, alternativeTitleTypesFuture, issuanceModesFuture, instanceStatusesFuture, natureOfContentTermsFuture, instanceRelationshipTypesFuture, holdingsTypesFuture, holdingsNoteTypesFuture, illPoliciesFuture, callNumberTypesFuture, statisticalCodesFuture, statisticalCodeTypesFuture, locationsFuture, materialTypesFuture, itemDamagedStatusesFuture, - loanTypesFuture, itemNoteTypesFuture, authorityNoteTypesFuture, authoritySourceFilesFuture,subjectSourcesFuture, subjectTypesFuture, marcFieldProtectionSettingsFuture, tenantConfigurationZoneFuture, + loanTypesFuture, itemNoteTypesFuture, authorityNoteTypesFuture, authoritySourceFilesFuture,subjectSourcesFuture, subjectTypesFuture, instanceDateTypesFuture, marcFieldProtectionSettingsFuture, tenantConfigurationZoneFuture, linkingRulesFuture)) .map(ar -> mappingParams @@ -236,6 +240,7 @@ private Future initializeParameters(MappingParameters mapping .withAuthoritySourceFiles(authoritySourceFilesFuture.result()) .withSubjectSources(subjectSourcesFuture.result()) .withSubjectTypes(subjectTypesFuture.result()) + .withInstanceDateTypes(instanceDateTypesFuture.result()) .withMarcFieldProtectionSettings(marcFieldProtectionSettingsFuture.result()) .withTenantConfigurationZone(tenantConfigurationZoneFuture.result()) .withLinkingRules(linkingRulesFuture.result()) @@ -486,6 +491,19 @@ private Future> getSubjectTypes(OkapiConnectionParams params) response -> response.mapTo(SubjectTypes.class).getSubjectTypes()); } + /** + * Requests for Instance Date Types from application Settings (mod-inventory-storage) + * * + * + * @param params Okapi connection parameters + * @return List Instance date types + */ + private Future> getInstanceDateTypes(OkapiConnectionParams params) { + String instanceDateTypesUrl = "/instance-date-types?limit=" + settingsLimit; + return loadData(params, instanceDateTypesUrl, INSTANCE_DATE_TYPES_RESPONSE_PARAM, + response -> response.mapTo(InstanceDateTypes.class).getInstanceDateTypes()); + } + /** * Requests for tenant configuration from mod-configuration. * * diff --git a/mod-source-record-manager-server/src/main/resources/rules/marc_bib_rules.json b/mod-source-record-manager-server/src/main/resources/rules/marc_bib_rules.json index b966b17a0..8d9c5e393 100644 --- a/mod-source-record-manager-server/src/main/resources/rules/marc_bib_rules.json +++ b/mod-source-record-manager-server/src/main/resources/rules/marc_bib_rules.json @@ -69,6 +69,59 @@ ] } ] + }, + { + "target": "dates.dateTypeId", + "description": "Date type ID", + "subfield": [], + "createSingleObject": true, + "rules": [ + { + "conditions": [ + { + "type": "set_date_type_id" + } + ] + } + ] + }, + { + "target": "dates.date1", + "description": "Date 1", + "subfield": [], + "createSingleObject": true, + "rules": [ + { + "conditions": [ + { + "type": "char_select", + "parameter": { + "from": 7, + "to": 11 + } + } + ] + } + ] + }, + { + "target": "dates.date2", + "description": "Date 2", + "subfield": [], + "createSingleObject": true, + "rules": [ + { + "conditions": [ + { + "type": "char_select", + "parameter": { + "from": 11, + "to": 15 + } + } + ] + } + ] } ], "010": [ diff --git a/mod-source-record-manager-server/src/test/java/org/folio/rest/impl/AbstractRestTest.java b/mod-source-record-manager-server/src/test/java/org/folio/rest/impl/AbstractRestTest.java index daf3c4176..f71b424b8 100644 --- a/mod-source-record-manager-server/src/test/java/org/folio/rest/impl/AbstractRestTest.java +++ b/mod-source-record-manager-server/src/test/java/org/folio/rest/impl/AbstractRestTest.java @@ -126,6 +126,8 @@ public abstract class AbstractRestTest { protected static final String FIELD_PROTECTION_SETTINGS_URL = "/field-protection-settings/marc?limit=1000"; protected static final String SUBJECT_SOURCES_URL = "/subject-sources?limit=1000"; protected static final String SUBJECT_TYPES_URL = "/subject-types?limit=1000"; + protected static final String INSTANCE_DATE_TYPES_URL = "/instance-date-types?limit=1000"; + protected static final String TENANT_CONFIGURATION_ZONE_SETTINGS_URL = "/configurations/entries?query=" + URLEncoder.encode("(module==ORG and configName==localeSettings)", StandardCharsets.UTF_8); @@ -504,6 +506,7 @@ public void setUp(TestContext context) throws IOException { WireMock.stubFor(get(AUTHORITY_SOURCE_FILES_URL).willReturn(okJson(new JsonObject().put("authoritySourceFiles", new JsonArray()).toString()))); WireMock.stubFor(get(SUBJECT_SOURCES_URL).willReturn(okJson(new JsonObject().put("subjectSources", new JsonArray()).toString()))); WireMock.stubFor(get(SUBJECT_TYPES_URL).willReturn(okJson(new JsonObject().put("subjectTypes", new JsonArray()).toString()))); + WireMock.stubFor(get(INSTANCE_DATE_TYPES_URL).willReturn(okJson(new JsonObject().put("instanceDateTypes", new JsonArray()).toString()))); WireMock.stubFor(get(FIELD_PROTECTION_SETTINGS_URL).willReturn(okJson(new JsonObject().put("marcFieldProtectionSettings", new JsonArray()).toString()))); WireMock.stubFor(get(TENANT_CONFIGURATION_ZONE_SETTINGS_URL).willReturn(okJson(new JsonObject().put("configs", new JsonArray()).toString()))); diff --git a/mod-source-record-manager-server/src/test/java/org/folio/rest/impl/changeManager/ChangeManagerAPITest.java b/mod-source-record-manager-server/src/test/java/org/folio/rest/impl/changeManager/ChangeManagerAPITest.java index 22c96c834..be1946c1f 100644 --- a/mod-source-record-manager-server/src/test/java/org/folio/rest/impl/changeManager/ChangeManagerAPITest.java +++ b/mod-source-record-manager-server/src/test/java/org/folio/rest/impl/changeManager/ChangeManagerAPITest.java @@ -1366,6 +1366,7 @@ public void shouldProcessChunksAndRequestForMappingParameters1Time(TestContext t verify(1, getRequestedFor(urlEqualTo(AUTHORITY_SOURCE_FILES_URL))); verify(1, getRequestedFor(urlEqualTo(SUBJECT_SOURCES_URL))); verify(1, getRequestedFor(urlEqualTo(SUBJECT_TYPES_URL))); + verify(1, getRequestedFor(urlEqualTo(INSTANCE_DATE_TYPES_URL))); verify(1, getRequestedFor(urlEqualTo(FIELD_PROTECTION_SETTINGS_URL))); verify(1, getRequestedFor(urlEqualTo(TENANT_CONFIGURATION_ZONE_SETTINGS_URL))); async.complete(); diff --git a/mod-source-record-manager-server/src/test/java/org/folio/services/mappers/processor/MappingParametersProviderTest.java b/mod-source-record-manager-server/src/test/java/org/folio/services/mappers/processor/MappingParametersProviderTest.java index 40f3b4a98..f4d9f3f5d 100644 --- a/mod-source-record-manager-server/src/test/java/org/folio/services/mappers/processor/MappingParametersProviderTest.java +++ b/mod-source-record-manager-server/src/test/java/org/folio/services/mappers/processor/MappingParametersProviderTest.java @@ -68,6 +68,7 @@ public class MappingParametersProviderTest { protected static final String AUTHORITY_SOURCE_FILES_URL = "/authority-source-files?limit=0"; protected static final String SUBJECT_SOURCES_URL = "/subject-sources?limit=0"; protected static final String SUBJECT_TYPES_URL = "/subject-types?limit=0"; + protected static final String INSTANCE_DATE_TYPE_URL = "/instance-date-types?limit=0"; protected static final String FIELD_PROTECTION_SETTINGS_URL = "/field-protection-settings/marc?limit=0"; @@ -211,6 +212,10 @@ public void setUp() throws Exception { get(SUBJECT_TYPES_URL) .willReturn( okJson(new JsonObject().put("subjectTypes", new JsonArray()).toString()))); + WireMock.stubFor( + get(INSTANCE_DATE_TYPE_URL) + .willReturn( + okJson(new JsonObject().put("instanceDateTypes", new JsonArray()).toString()))); WireMock.stubFor( get(FIELD_PROTECTION_SETTINGS_URL) .willReturn( diff --git a/mod-source-record-manager-server/src/test/resources/org/folio/mapping/mappedBibRecord.json b/mod-source-record-manager-server/src/test/resources/org/folio/mapping/mappedBibRecord.json index 58b1ca402..b01c2b664 100644 --- a/mod-source-record-manager-server/src/test/resources/org/folio/mapping/mappedBibRecord.json +++ b/mod-source-record-manager-server/src/test/resources/org/folio/mapping/mappedBibRecord.json @@ -149,6 +149,7 @@ "publicationFrequency": [], "publicationRange": [], "electronicAccess": [], + "dates":{"date1":"1982","date2":"9999"}, "instanceTypeId": "fe19bae4-da28-472b-be90-d442e2428ead", "instanceFormatIds": [], "physicalDescriptions": [ diff --git a/mod-source-record-manager-server/src/test/resources/org/folio/services/marc_bib_rules.json b/mod-source-record-manager-server/src/test/resources/org/folio/services/marc_bib_rules.json index b560e0fc3..c9d7a60b9 100644 --- a/mod-source-record-manager-server/src/test/resources/org/folio/services/marc_bib_rules.json +++ b/mod-source-record-manager-server/src/test/resources/org/folio/services/marc_bib_rules.json @@ -69,6 +69,59 @@ ] } ] + }, + { + "target": "dates.dateTypeId", + "description": "Date type ID", + "subfield": [], + "createSingleObject": true, + "rules": [ + { + "conditions": [ + { + "type": "set_date_type_id" + } + ] + } + ] + }, + { + "target": "dates.date1", + "description": "Date 1", + "subfield": [], + "createSingleObject": true, + "rules": [ + { + "conditions": [ + { + "type": "char_select", + "parameter": { + "from": 7, + "to": 11 + } + } + ] + } + ] + }, + { + "target": "dates.date2", + "description": "Date 2", + "subfield": [], + "createSingleObject": true, + "rules": [ + { + "conditions": [ + { + "type": "char_select", + "parameter": { + "from": 11, + "to": 15 + } + } + ] + } + ] } ], "010": [ diff --git a/mod-source-record-manager-server/src/test/resources/org/folio/services/marc_mapping_params.json b/mod-source-record-manager-server/src/test/resources/org/folio/services/marc_mapping_params.json index 3adefa6c6..28277d250 100644 --- a/mod-source-record-manager-server/src/test/resources/org/folio/services/marc_mapping_params.json +++ b/mod-source-record-manager-server/src/test/resources/org/folio/services/marc_mapping_params.json @@ -30,6 +30,7 @@ "authoritySourceFiles": [], "subjectSources": [], "subjectTypes": [], + "instanceDateTypes": [], "organizations": null, "linkingRules": [], "acquisitionsUnits":null,