diff --git a/pom.xml b/pom.xml
index cdf7caac..3c26b34d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -303,6 +303,7 @@
${basedir}/ramls/settings/organization_collection.json
${basedir}/ramls/settings/subjectSources.json
${basedir}/ramls/settings/subjectTypes.json
+ ${basedir}/ramls/settings/instanceDateTypes.json
${basedir}/ramls/settings/acquisitions_unit.json
${basedir}/ramls/settings/acquisitions_unit_collection.json
${basedir}/ramls/settings/acquisition_method.json
diff --git a/ramls/instance.json b/ramls/instance.json
index 3826dc7d..7d8e4e19 100644
--- a/ramls/instance.json
+++ b/ramls/instance.json
@@ -310,6 +310,11 @@
"type": "object",
"description": "Instance Dates",
"properties": {
+ "dateTypeId": {
+ "type": "string",
+ "description": "Date type ID",
+ "$ref": "raml-storage/raml-util/schemas/uuid.schema"
+ },
"date1": {
"type": "string",
"description": "Date 1",
diff --git a/ramls/settings/instanceDateType.json b/ramls/settings/instanceDateType.json
new file mode 100644
index 00000000..22881f4e
--- /dev/null
+++ b/ramls/settings/instanceDateType.json
@@ -0,0 +1,59 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "description": "An instance date type that indicates the type of dates given in Date 1 and Date 2",
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique ID of the instance date type; a UUID",
+ "readonly": true
+ },
+ "name": {
+ "type": "string",
+ "description": "Name of the instance date type",
+ "readonly": true
+ },
+ "code": {
+ "type": "string",
+ "description": "Code of the instance date type",
+ "maxLength": 1,
+ "readonly": true
+ },
+ "displayFormat": {
+ "type": "object",
+ "description": "Describes how to format Date 1 and Date 2",
+ "properties": {
+ "delimiter": {
+ "type": "string",
+ "description": "Delimiter that will be used to format Date 1 and Date 2",
+ "example": ",",
+ "readonly": true
+ },
+ "keepDelimiter": {
+ "type": "boolean",
+ "description": "Define if formated date string should keep delimiter if one of dates is not exist",
+ "example": false,
+ "readonly": true
+ }
+ },
+ "readonly": true,
+ "additionalProperties": false
+ },
+ "source": {
+ "type": "string",
+ "description": "label indicating where the instance date type entry originates from, i.e. 'folio' or 'local'",
+ "enum": [
+ "folio",
+ "local"
+ ],
+ "readonly": true
+ },
+ "metadata": {
+ "type": "object",
+ "$ref": "../raml-storage/raml-util/schemas/metadata.schema",
+ "readonly": true
+ }
+ },
+ "additionalProperties": false
+}
+
diff --git a/ramls/settings/instanceDateTypes.json b/ramls/settings/instanceDateTypes.json
new file mode 100644
index 00000000..c2e10ea3
--- /dev/null
+++ b/ramls/settings/instanceDateTypes.json
@@ -0,0 +1,19 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "description": "A collection of instance date types",
+ "type": "object",
+ "properties": {
+ "instanceDateTypes": {
+ "description": "List of instance date types",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "$ref": "instanceDateType.json"
+ }
+ },
+ "totalRecords": {
+ "description": "Estimated or exact total number of records",
+ "type": "integer"
+ }
+ }
+}
diff --git a/src/main/java/org/folio/processing/mapping/defaultmapper/processor/functions/NormalizationFunction.java b/src/main/java/org/folio/processing/mapping/defaultmapper/processor/functions/NormalizationFunction.java
index f76cbdfb..522ea127 100644
--- a/src/main/java/org/folio/processing/mapping/defaultmapper/processor/functions/NormalizationFunction.java
+++ b/src/main/java/org/folio/processing/mapping/defaultmapper/processor/functions/NormalizationFunction.java
@@ -14,6 +14,7 @@
import org.folio.HoldingsNoteType;
import org.folio.HoldingsType;
import org.folio.IdentifierType;
+import org.folio.InstanceDateType;
import org.folio.InstanceFormat;
import org.folio.InstanceNoteType;
import org.folio.InstanceType;
@@ -199,6 +200,38 @@ private String concatSubFields(JsonObject ruleParameter, List subfield
}
},
+ SET_DATE_TYPE_ID() {
+ private static final String DEFAULT_DATE_TYPE = "No attempt to code";
+
+ @Override
+ public String apply(RuleExecutionContext context) {
+ String subFieldValue = context.getSubFieldValue();
+ char sixthChar = subFieldValue.charAt(6);
+ List dateTypes = context.getMappingParameters().getInstanceDateTypes();
+ if (dateTypes == null || dateTypes.isEmpty()) {
+ return StringUtils.EMPTY;
+ }
+ String defaultDateTypeId = findDateTypeId(dateTypes, StringUtils.EMPTY);
+ return matchInstanceDateTypeViaCode(sixthChar, dateTypes, defaultDateTypeId);
+ }
+
+ private String findDateTypeId(List dates, String defaultId) {
+ return dates.stream()
+ .filter(date -> date.getName().equalsIgnoreCase(DEFAULT_DATE_TYPE))
+ .findFirst()
+ .map(InstanceDateType::getId)
+ .orElse(defaultId);
+ }
+
+ private String matchInstanceDateTypeViaCode(char sixthChar, List instanceDateTypes, String defaultId) {
+ return instanceDateTypes.stream()
+ .filter(instanceFormat -> instanceFormat.getCode().equalsIgnoreCase(String.valueOf(sixthChar)))
+ .findFirst()
+ .map(InstanceDateType::getId)
+ .orElse(defaultId);
+ }
+ },
+
SET_PUBLISHER_ROLE() {
@Override
public String apply(RuleExecutionContext context) {
diff --git a/src/main/java/org/folio/processing/mapping/defaultmapper/processor/parameters/MappingParameters.java b/src/main/java/org/folio/processing/mapping/defaultmapper/processor/parameters/MappingParameters.java
index b31de4c5..288ddc62 100644
--- a/src/main/java/org/folio/processing/mapping/defaultmapper/processor/parameters/MappingParameters.java
+++ b/src/main/java/org/folio/processing/mapping/defaultmapper/processor/parameters/MappingParameters.java
@@ -17,6 +17,7 @@
import org.folio.HoldingsType;
import org.folio.IdentifierType;
import org.folio.IllPolicy;
+import org.folio.InstanceDateType;
import org.folio.InstanceFormat;
import org.folio.InstanceNoteType;
import org.folio.InstanceRelationshipType;
@@ -57,6 +58,7 @@ public class MappingParameters {
private List instanceNoteTypes = new ArrayList<>();
private List alternativeTitleTypes = new ArrayList<>();
private List issuanceModes = new ArrayList<>();
+ private List instanceDateTypes = new ArrayList<>();
private List instanceStatuses = new ArrayList<>();
private List natureOfContentTerms = new ArrayList<>();
private List instanceRelationshipTypes = new ArrayList<>();
@@ -180,6 +182,15 @@ public MappingParameters withIssuanceModes(List issuanceModes) {
return this;
}
+ public List getInstanceDateTypes() {
+ return instanceDateTypes;
+ }
+
+ public MappingParameters withInstanceDateTypes(List instanceDateTypes) {
+ this.instanceDateTypes = new UnmodifiableList<>(instanceDateTypes);
+ return this;
+ }
+
public void setInitialized(boolean initialized) {
this.initialized = initialized;
}
diff --git a/src/test/java/org/folio/processing/mapping/functions/NormalizationFunctionTest.java b/src/test/java/org/folio/processing/mapping/functions/NormalizationFunctionTest.java
index 1cacba7f..4ba4e531 100644
--- a/src/test/java/org/folio/processing/mapping/functions/NormalizationFunctionTest.java
+++ b/src/test/java/org/folio/processing/mapping/functions/NormalizationFunctionTest.java
@@ -5,6 +5,7 @@
import org.apache.commons.lang3.StringUtils;
import org.folio.AuthorityNoteType;
import org.folio.ClassificationType;
+import org.folio.InstanceDateType;
import org.folio.InstanceType;
import org.folio.ElectronicAccessRelationship;
import org.folio.InstanceFormat;
@@ -270,6 +271,81 @@ public void CAPITALIZE_shouldReturnExpectedResult() {
}
}
+ @Test
+ public void SET_DATE_TYPE_ID_shouldReturnExpectedResult() {
+ // given
+ String expectedInstanceDateTypeId = UUID.randomUUID().toString();
+ InstanceDateType firstInstanceDateType = new InstanceDateType()
+ .withId(UUID.randomUUID().toString())
+ .withName("No attempt to code")
+ .withCode("|");
+
+ InstanceDateType secondInstanceDateType = new InstanceDateType()
+ .withId(expectedInstanceDateTypeId)
+ .withName("Single known date/probable date")
+ .withCode("s");
+
+ InstanceDateType thirdInstanceDateType = new InstanceDateType()
+ .withId(UUID.randomUUID().toString())
+ .withName("Range of years of bulk of collection")
+ .withCode("k");
+
+ RuleExecutionContext context = new RuleExecutionContext();
+ context.setSubFieldValue("901214s19910101nyua");
+ context.setMappingParameters(new MappingParameters().withInstanceDateTypes(Arrays.asList(firstInstanceDateType, secondInstanceDateType, thirdInstanceDateType)));
+ // when
+ String actualInstanceDateTypeId = runFunction("set_date_type_id", context);
+ // then
+ assertEquals(expectedInstanceDateTypeId, actualInstanceDateTypeId);
+ }
+
+ @Test
+ public void SET_DATE_TYPE_ID_shouldReturnUnspecifiedIssuanceModeIdIfNoMatchedExists() {
+ // given
+ String expectedInstanceDateTypeId = UUID.randomUUID().toString();
+ InstanceDateType instanceDateType = new InstanceDateType()
+ .withId(expectedInstanceDateTypeId)
+ .withName("No attempt to code")
+ .withCode("|");
+
+ RuleExecutionContext context = new RuleExecutionContext();
+ context.setSubFieldValue("zzzzzzzzzz");
+ context.setMappingParameters(new MappingParameters().withInstanceDateTypes(Collections.singletonList(instanceDateType)));
+ // when
+ String actualInstanceDateTypeId = runFunction("set_date_type_id", context);
+ // then
+ assertEquals(expectedInstanceDateTypeId, actualInstanceDateTypeId);
+ }
+ @Test
+ public void SET_DATE_TYPE_ID_shouldReturnEmptyStringIfNoMatchedExistsAndUnspecifiedInstanceTypeIdNotExists() {
+ // given
+ String expectedInstanceDateTypeId = UUID.randomUUID().toString();
+ InstanceDateType instanceDateTypeId = new InstanceDateType()
+ .withId(expectedInstanceDateTypeId)
+ .withName("Detailed date")
+ .withCode("e");
+
+ RuleExecutionContext context = new RuleExecutionContext();
+ context.setSubFieldValue("zzzzzzzzzz");
+ context.setMappingParameters(new MappingParameters().withInstanceDateTypes(Collections.singletonList(instanceDateTypeId)));
+ // when
+ String actualInstanceDateTypeId = runFunction("set_date_type_id", context);
+ // then
+ assertEquals(StringUtils.EMPTY, actualInstanceDateTypeId);
+ }
+
+ @Test
+ public void SET_DATE_TYPE_MODE_ID_shouldReturnEmptyStringIfNoSettingsSpecified() {
+ // given
+ RuleExecutionContext context = new RuleExecutionContext();
+ context.setMappingParameters(new MappingParameters());
+ context.setSubFieldValue("901214s19910101nyua");
+ // when
+ String actualInstanceDateTypeId = runFunction("set_date_type_id", context);
+ // then
+ assertEquals(StringUtils.EMPTY, actualInstanceDateTypeId);
+ }
+
@Test
public void SET_PUBLISHER_ROLE_shouldReturnExpectedResult() {
// given
diff --git a/src/test/resources/org/folio/processing/mapping/instance/rules.json b/src/test/resources/org/folio/processing/mapping/instance/rules.json
index b70cf9a0..eae10f58 100644
--- a/src/test/resources/org/folio/processing/mapping/instance/rules.json
+++ b/src/test/resources/org/folio/processing/mapping/instance/rules.json
@@ -70,6 +70,22 @@
}
]
},
+ {
+ "target": "dates.dateTypeId",
+ "description": "Date type ID",
+ "subfield": [],
+ "createSingleObject": true,
+ "rules": [
+ {
+ "description": "",
+ "conditions": [
+ {
+ "type": "set_date_type_id"
+ }
+ ]
+ }
+ ]
+ },
{
"target": "dates.date1",
"description": "Date 1",