diff --git a/data-import-support/src/main/java/org/folio/dataimport/util/marc/MarcFieldEditor.java b/data-import-support/src/main/java/org/folio/dataimport/util/marc/MarcFieldEditor.java index 881dbd3..d6830cd 100644 --- a/data-import-support/src/main/java/org/folio/dataimport/util/marc/MarcFieldEditor.java +++ b/data-import-support/src/main/java/org/folio/dataimport/util/marc/MarcFieldEditor.java @@ -31,16 +31,17 @@ private MarcFieldEditor() { * @param replace if true, replaces an existing field with the same tag; if false, appends a new field */ public static void addOrReplaceControlField(Record marcRecord, String tag, String value, boolean replace) { - var newControlField = MarcFactory.newInstance().newControlField(tag, value); + ControlField newField = MarcFactory.newInstance().newControlField(tag, value); if (replace) { - ControlField existing = (ControlField) marcRecord.getVariableField(tag); - if (existing != null) { - marcRecord.removeVariableField(existing); + List controlFields = marcRecord.getControlFields(); + for (int i = 0; i < controlFields.size(); i++) { + if (tag.equals(controlFields.get(i).getTag())) { + controlFields.set(i, newField); + return; + } } - marcRecord.addVariableField(newControlField); - } else { - marcRecord.addVariableField(newControlField); } + marcRecord.addVariableField(newField); } /** diff --git a/data-import-support/src/test/java/org/folio/dataimport/util/marc/MarcFieldEditorTest.java b/data-import-support/src/test/java/org/folio/dataimport/util/marc/MarcFieldEditorTest.java index b12b98f..08edc6f 100644 --- a/data-import-support/src/test/java/org/folio/dataimport/util/marc/MarcFieldEditorTest.java +++ b/data-import-support/src/test/java/org/folio/dataimport/util/marc/MarcFieldEditorTest.java @@ -81,6 +81,27 @@ void shouldReplaceControlFieldInPlace_whenReplaceIsTrueAndFieldExists() { assertThat(MarcFieldEditor.getControlFieldValue(marcRecord, "005")).isEqualTo("new-value"); } + @DisplayName("should keep the replaced control field at its original position, not append it at the end — " + + "regression guard against removeVariableField+addVariableField which would move the field to the tail") + @Test + void shouldKeepReplacedControlFieldAtOriginalPosition_notAppendedAtEnd() { + // arrange: realistic fixture with 001 < 005 < 008 — same order as parsedMarcRecord.json used in + // AdditionalFieldsUtilTest; 005 sits between two other control fields + Record marcRecord = newRecord(); + marcRecord.addVariableField(FACTORY.newControlField("001", "ybp7406411")); + marcRecord.addVariableField(FACTORY.newControlField("005", "20120404100627.6")); + marcRecord.addVariableField(FACTORY.newControlField("008", "120329s2011 sz a")); + + // act + MarcFieldEditor.addOrReplaceControlField(marcRecord, "005", "20240909120000.0", true); + + // assert: 005 is still at index 1 (between 001 and 008), not moved to the end + List controlFields = marcRecord.getControlFields(); + assertThat(controlFields).hasSize(3); + assertThat(controlFields.stream().map(VariableField::getTag)).containsExactly("001", "005", "008"); + assertThat(MarcFieldEditor.getControlFieldValue(marcRecord, "005")).isEqualTo("20240909120000.0"); + } + @DisplayName("should create a new ff-indicator data field and add the subfield when no matching field exists") @Test void shouldCreateNewDataField_whenNoExistingFieldMatchesIndicators() {