diff --git a/src/main/java/org/folio/bulkops/service/BulkOperationService.java b/src/main/java/org/folio/bulkops/service/BulkOperationService.java index d17a8e38..4fab62a2 100644 --- a/src/main/java/org/folio/bulkops/service/BulkOperationService.java +++ b/src/main/java/org/folio/bulkops/service/BulkOperationService.java @@ -23,6 +23,8 @@ import static org.folio.bulkops.domain.dto.UpdateActionType.SET_TO_FALSE_INCLUDING_ITEMS; import static org.folio.bulkops.domain.dto.UpdateActionType.SET_TO_TRUE_INCLUDING_ITEMS; import static org.folio.bulkops.domain.dto.UpdateOptionType.SUPPRESS_FROM_DISCOVERY; +import static org.folio.bulkops.util.Constants.ADMINISTRATIVE_NOTE; +import static org.folio.bulkops.util.Constants.ADMINISTRATIVE_NOTES; import static org.folio.bulkops.util.Constants.FIELD_ERROR_MESSAGE_PATTERN; import static org.folio.bulkops.util.Constants.MSG_HOLDING_NO_CHANGE_REQUIRED_SUPPRESSED_ITEMS_UPDATED; import static org.folio.bulkops.util.Constants.MSG_HOLDING_NO_CHANGE_REQUIRED_UNSUPPRESSED_ITEMS_UPDATED; @@ -473,8 +475,7 @@ private UnifiedTable buildPreviewFromCsvFile(String pathToFile, Class row.setRow(SpecialCharacterEscaper.restore(row.getRow()))); return table; } catch (Exception e) { @@ -483,6 +484,20 @@ private UnifiedTable buildPreviewFromCsvFile(String pathToFile, Class clazz) { + table.getHeader().forEach(cell -> { + if (ADMINISTRATIVE_NOTES.equalsIgnoreCase(cell.getValue())) { + cell.setValue(ADMINISTRATIVE_NOTE); + } + }); + if (clazz == Item.class) { + noteTableUpdater.extendTableWithItemNotesTypes(table); + } + if (clazz == HoldingsRecord.class) { + noteTableUpdater.extendTableWithHoldingsNotesTypes(table); + } + } + public BulkOperation startBulkOperation(UUID bulkOperationId, UUID xOkapiUserId, BulkOperationStart bulkOperationStart) { var step = bulkOperationStart.getStep(); var approach = bulkOperationStart.getApproach(); diff --git a/src/main/java/org/folio/bulkops/service/NoteTableUpdater.java b/src/main/java/org/folio/bulkops/service/NoteTableUpdater.java index 10c82259..c8171212 100644 --- a/src/main/java/org/folio/bulkops/service/NoteTableUpdater.java +++ b/src/main/java/org/folio/bulkops/service/NoteTableUpdater.java @@ -23,6 +23,7 @@ import java.util.Arrays; import java.util.List; +import java.util.Set; @Component @RequiredArgsConstructor @@ -39,6 +40,7 @@ public class NoteTableUpdater { public void extendTableWithHoldingsNotesTypes(UnifiedTable unifiedTable) { var noteTypeNames = holdingsReferenceService.getAllHoldingsNoteTypes().stream() .map(HoldingsNoteType::getName) + .map(this::concatNotePostfixIfRequired) .sorted() .toList(); @@ -49,6 +51,7 @@ public void extendTableWithHoldingsNotesTypes(UnifiedTable unifiedTable) { public void extendTableWithItemNotesTypes(UnifiedTable unifiedTable) { var noteTypeNames = itemReferenceService.getAllItemNoteTypes().stream() .map(NoteType::getName) + .map(this::concatNotePostfixIfRequired) .sorted() .toList(); @@ -56,6 +59,12 @@ public void extendTableWithItemNotesTypes(UnifiedTable unifiedTable) { unifiedTable.getRows().forEach(row -> extendRowWithNotesData(ITEM_NOTE_POSITION, row, noteTypeNames)); } + private String concatNotePostfixIfRequired(String noteTypeName) { + return Set.of("Binding", "Electronic bookplate", "Provenance", "Reproduction").contains(noteTypeName) ? + noteTypeName + " note" : + noteTypeName; + } + private void extendHeadersWithItemNoteTypeNames(int notesInitialPosition, List headers, List noteTypeNames) { var headerToReplace = headers.get(notesInitialPosition); var cellsToInsert = noteTypeNames.stream() diff --git a/src/main/java/org/folio/bulkops/util/Constants.java b/src/main/java/org/folio/bulkops/util/Constants.java index b706f63f..ffad14e7 100644 --- a/src/main/java/org/folio/bulkops/util/Constants.java +++ b/src/main/java/org/folio/bulkops/util/Constants.java @@ -43,4 +43,6 @@ public class Constants { public static final String MSG_HOLDING_NO_CHANGE_REQUIRED_UNSUPPRESSED_ITEMS_UPDATED = "No change in value for holdings record required, associated unsuppressed item(s) have been updated."; public static final String MSG_HOLDING_NO_CHANGE_REQUIRED_SUPPRESSED_ITEMS_UPDATED = "No change in value for holdings record required, associated suppressed item(s) have been updated."; public static final String STAFF_ONLY = "(staff only)"; + public static final String ADMINISTRATIVE_NOTES = "Administrative Notes"; + public static final String ADMINISTRATIVE_NOTE = "Administrative Note"; } diff --git a/src/test/java/org/folio/bulkops/service/BulkOperationServiceTest.java b/src/test/java/org/folio/bulkops/service/BulkOperationServiceTest.java index e92de73a..384d8772 100644 --- a/src/test/java/org/folio/bulkops/service/BulkOperationServiceTest.java +++ b/src/test/java/org/folio/bulkops/service/BulkOperationServiceTest.java @@ -3,6 +3,8 @@ import static java.util.Objects.nonNull; import static org.folio.bulkops.domain.dto.EntityType.HOLDINGS_RECORD; import static org.folio.bulkops.domain.dto.EntityType.ITEM; +import static org.folio.bulkops.util.Constants.ADMINISTRATIVE_NOTE; +import static org.folio.bulkops.util.Constants.ADMINISTRATIVE_NOTES; import static org.folio.bulkops.util.Constants.MSG_NO_CHANGE_REQUIRED; import static org.folio.bulkops.util.UnifiedTableHeaderBuilder.getHeaders; import static org.folio.bulkops.domain.dto.BulkOperationStep.COMMIT; @@ -71,6 +73,7 @@ import org.folio.bulkops.domain.dto.BulkOperationRuleRuleDetails; import org.folio.bulkops.domain.dto.BulkOperationStart; import org.folio.bulkops.domain.dto.BulkOperationStep; +import org.folio.bulkops.domain.dto.Cell; import org.folio.bulkops.domain.dto.EntityType; import org.folio.bulkops.domain.dto.IdentifierType; import org.folio.bulkops.domain.dto.OperationStatusType; @@ -897,9 +900,9 @@ void shouldReturnPreviewIfAvailable(String fileName, EntityType entityType, Bulk if (USER.equals(entityType)) { assertThat(table.getHeader(), equalTo(getHeaders(User.class))); } else if (EntityType.ITEM.equals(entityType)) { - assertThat(table.getHeader(), equalTo(getHeaders(Item.class))); + assertThat(table.getHeader(), equalTo(renameAdministrativeNotesHeader(getHeaders(Item.class)))); } else if (EntityType.HOLDINGS_RECORD.equals(entityType)) { - assertThat(table.getHeader(), equalTo(getHeaders(HoldingsRecord.class))); + assertThat(table.getHeader(), equalTo(renameAdministrativeNotesHeader(getHeaders(HoldingsRecord.class)))); } assertTrue(table.getRows().stream() .map(Row::getRow) @@ -1140,4 +1143,13 @@ private BulkOperation buildBulkOperation(String fileName, EntityType entityType, .build(); }; } + + private List renameAdministrativeNotesHeader(List headers) { + headers.forEach(cell -> { + if (ADMINISTRATIVE_NOTES.equalsIgnoreCase(cell.getValue())) { + cell.setValue(ADMINISTRATIVE_NOTE); + } + }); + return headers; + } } diff --git a/src/test/java/org/folio/bulkops/service/ItemNoteTableUpdaterTest.java b/src/test/java/org/folio/bulkops/service/ItemNoteTableUpdaterTest.java index 85f24ecd..501438bd 100644 --- a/src/test/java/org/folio/bulkops/service/ItemNoteTableUpdaterTest.java +++ b/src/test/java/org/folio/bulkops/service/ItemNoteTableUpdaterTest.java @@ -13,6 +13,7 @@ import static org.mockito.Mockito.when; import org.folio.bulkops.domain.bean.HoldingsNoteType; +import org.folio.bulkops.domain.bean.HoldingsRecord; import org.folio.bulkops.domain.bean.Item; import org.folio.bulkops.domain.bean.NoteType; import org.folio.bulkops.domain.dto.Cell; @@ -32,12 +33,12 @@ @ExtendWith(MockitoExtension.class) class ItemNoteTableUpdaterTest { private static final int ACTION_NOTE_POSITION = ITEM_NOTE_POSITION; - private static final int BINDING_POSITION = ITEM_NOTE_POSITION + 1; - private static final int NOTE_POSITION = ITEM_NOTE_POSITION + 2; + private static final int NOTE_POSITION = ITEM_NOTE_POSITION + 1; + private static final int OTHER_POSITION = ITEM_NOTE_POSITION + 2; private static final int ACTION_HOLDINGS_NOTE_POSITION = HOLDINGS_NOTE_POSITION; - private static final int BINDING_HOLDINGS_POSITION = HOLDINGS_NOTE_POSITION + 1; - private static final int NOTE_HOLDINGS_POSITION = HOLDINGS_NOTE_POSITION + 2; + private static final int NOTE_HOLDINGS_POSITION = HOLDINGS_NOTE_POSITION + 1; + private static final int OTHER_HOLDINGS_POSITION = HOLDINGS_NOTE_POSITION + 2; @Mock private ItemReferenceService itemReferenceService; @@ -51,7 +52,7 @@ class ItemNoteTableUpdaterTest { void shouldExtendTableWithItemNoteTypes() { var table = UnifiedTableHeaderBuilder.getEmptyTableWithHeaders(Item.class); var row = Arrays.stream(new String[table.getHeader().size()]).collect(Collectors.toCollection(ArrayList::new)); - row.set(ITEM_NOTE_POSITION, "Action note;Action note text;false|Note;Note text;false|Binding;Binding text;false"); + row.set(ITEM_NOTE_POSITION, "Action note;Action note text;false|Note;Note text;false|Other;Other text;false"); table.setRows(List.of(new Row().row(row))); var expectedTableSize = table.getHeader().size() + 2; @@ -59,7 +60,7 @@ void shouldExtendTableWithItemNoteTypes() { when(itemReferenceService.getAllItemNoteTypes()) .thenReturn(List.of(NoteType.builder().name("Action note").build(), NoteType.builder().name("Note").build(), - NoteType.builder().name("Binding").build())); + NoteType.builder().name("Other").build())); noteTableUpdater.extendTableWithItemNotesTypes(table); @@ -67,13 +68,13 @@ void shouldExtendTableWithItemNoteTypes() { var headerNames = table.getHeader().stream().map(Cell::getValue).toList(); assertThat(headerNames.indexOf("Action note"), is(ACTION_NOTE_POSITION)); assertThat(headerNames.indexOf("Note"), is(NOTE_POSITION)); - assertThat(headerNames.indexOf("Binding"), is(BINDING_POSITION)); + assertThat(headerNames.indexOf("Other"), is(OTHER_POSITION)); var modifiedRow = table.getRows().get(0).getRow(); assertThat(modifiedRow, hasSize(expectedTableSize)); assertEquals("Action note text", modifiedRow.get(ACTION_NOTE_POSITION)); assertEquals("Note text", modifiedRow.get(NOTE_POSITION)); - assertEquals("Binding text", modifiedRow.get(BINDING_POSITION)); + assertEquals("Other text", modifiedRow.get(OTHER_POSITION)); } @Test @@ -87,7 +88,7 @@ void shouldExtendTableWithEmptyItemsNotes() { when(itemReferenceService.getAllItemNoteTypes()) .thenReturn(List.of(NoteType.builder().name("Action note").build(), NoteType.builder().name("Note").build(), - NoteType.builder().name("Binding").build())); + NoteType.builder().name("Other").build())); noteTableUpdater.extendTableWithItemNotesTypes(table); @@ -95,20 +96,20 @@ void shouldExtendTableWithEmptyItemsNotes() { var headerNames = table.getHeader().stream().map(Cell::getValue).toList(); assertThat(headerNames.indexOf("Action note"), is(ACTION_NOTE_POSITION)); assertThat(headerNames.indexOf("Note"), is(NOTE_POSITION)); - assertThat(headerNames.indexOf("Binding"), is(BINDING_POSITION)); + assertThat(headerNames.indexOf("Other"), is(OTHER_POSITION)); var modifiedRow = table.getRows().get(0).getRow(); assertThat(modifiedRow, hasSize(expectedTableSize)); assertNull(modifiedRow.get(ACTION_NOTE_POSITION)); assertNull(modifiedRow.get(NOTE_POSITION)); - assertNull(modifiedRow.get(BINDING_POSITION)); + assertNull(modifiedRow.get(OTHER_POSITION)); } @Test void shouldAddStaffOnlyPostfixWhenRequiredForItemNotes() { var table = UnifiedTableHeaderBuilder.getEmptyTableWithHeaders(Item.class); var row = Arrays.stream(new String[table.getHeader().size()]).collect(Collectors.toCollection(ArrayList::new)); - row.set(ITEM_NOTE_POSITION, "Action note;Action note text;true|Note;Note text;false|Binding;Binding text;true"); + row.set(ITEM_NOTE_POSITION, "Action note;Action note text;true|Note;Note text;false|Other;Other text;true"); table.setRows(List.of(new Row().row(row))); var expectedTableSize = table.getHeader().size() + 2; @@ -116,7 +117,7 @@ void shouldAddStaffOnlyPostfixWhenRequiredForItemNotes() { when(itemReferenceService.getAllItemNoteTypes()) .thenReturn(List.of(NoteType.builder().name("Action note").build(), NoteType.builder().name("Note").build(), - NoteType.builder().name("Binding").build())); + NoteType.builder().name("Other").build())); noteTableUpdater.extendTableWithItemNotesTypes(table); @@ -124,20 +125,20 @@ void shouldAddStaffOnlyPostfixWhenRequiredForItemNotes() { var headerNames = table.getHeader().stream().map(Cell::getValue).toList(); assertThat(headerNames.indexOf("Action note"), is(ACTION_NOTE_POSITION)); assertThat(headerNames.indexOf("Note"), is(NOTE_POSITION)); - assertThat(headerNames.indexOf("Binding"), is(BINDING_POSITION)); + assertThat(headerNames.indexOf("Other"), is(OTHER_POSITION)); var modifiedRow = table.getRows().get(0).getRow(); assertThat(modifiedRow, hasSize(expectedTableSize)); assertTrue(modifiedRow.get(ACTION_NOTE_POSITION).contains(STAFF_ONLY)); assertFalse(modifiedRow.get(NOTE_POSITION).contains(STAFF_ONLY)); - assertTrue(modifiedRow.get(BINDING_POSITION).contains(STAFF_ONLY)); + assertTrue(modifiedRow.get(OTHER_POSITION).contains(STAFF_ONLY)); } @Test void shouldExtendTableWithHoldingsNoteTypes() { var table = UnifiedTableHeaderBuilder.getEmptyTableWithHeaders(Item.class); var row = Arrays.stream(new String[table.getHeader().size()]).collect(Collectors.toCollection(ArrayList::new)); - row.set(HOLDINGS_NOTE_POSITION, "Action note;Action note text;false|Note;Note text;false|Binding;Binding text;false"); + row.set(HOLDINGS_NOTE_POSITION, "Action note;Action note text;false|Note;Note text;false|Other;Other text;false"); table.setRows(List.of(new Row().row(row))); var expectedTableSize = table.getHeader().size() + 2; @@ -145,7 +146,7 @@ void shouldExtendTableWithHoldingsNoteTypes() { when(holdingsReferenceService.getAllHoldingsNoteTypes()) .thenReturn(List.of(HoldingsNoteType.builder().name("Action note").build(), HoldingsNoteType.builder().name("Note").build(), - HoldingsNoteType.builder().name("Binding").build())); + HoldingsNoteType.builder().name("Other").build())); noteTableUpdater.extendTableWithHoldingsNotesTypes(table); @@ -153,13 +154,13 @@ void shouldExtendTableWithHoldingsNoteTypes() { var headerNames = table.getHeader().stream().map(Cell::getValue).toList(); assertThat(headerNames.indexOf("Action note"), is(ACTION_HOLDINGS_NOTE_POSITION)); assertThat(headerNames.indexOf("Note"), is(NOTE_HOLDINGS_POSITION)); - assertThat(headerNames.indexOf("Binding"), is(BINDING_HOLDINGS_POSITION)); + assertThat(headerNames.indexOf("Other"), is(OTHER_HOLDINGS_POSITION)); var modifiedRow = table.getRows().get(0).getRow(); assertThat(modifiedRow, hasSize(expectedTableSize)); assertEquals("Action note text", modifiedRow.get(ACTION_HOLDINGS_NOTE_POSITION)); assertEquals("Note text", modifiedRow.get(NOTE_HOLDINGS_POSITION)); - assertEquals("Binding text", modifiedRow.get(BINDING_HOLDINGS_POSITION)); + assertEquals("Other text", modifiedRow.get(OTHER_HOLDINGS_POSITION)); } @@ -174,7 +175,7 @@ void shouldExtendTableWithEmptyHoldingsNotes() { when(holdingsReferenceService.getAllHoldingsNoteTypes()) .thenReturn(List.of(HoldingsNoteType.builder().name("Action note").build(), HoldingsNoteType.builder().name("Note").build(), - HoldingsNoteType.builder().name("Binding").build())); + HoldingsNoteType.builder().name("Other").build())); noteTableUpdater.extendTableWithHoldingsNotesTypes(table); @@ -182,20 +183,20 @@ void shouldExtendTableWithEmptyHoldingsNotes() { var headerNames = table.getHeader().stream().map(Cell::getValue).toList(); assertThat(headerNames.indexOf("Action note"), is(ACTION_HOLDINGS_NOTE_POSITION)); assertThat(headerNames.indexOf("Note"), is(NOTE_HOLDINGS_POSITION)); - assertThat(headerNames.indexOf("Binding"), is(BINDING_HOLDINGS_POSITION)); + assertThat(headerNames.indexOf("Other"), is(OTHER_HOLDINGS_POSITION)); var modifiedRow = table.getRows().get(0).getRow(); assertThat(modifiedRow, hasSize(expectedTableSize)); assertNull(modifiedRow.get(ACTION_HOLDINGS_NOTE_POSITION)); assertNull(modifiedRow.get(NOTE_HOLDINGS_POSITION)); - assertNull(modifiedRow.get(BINDING_HOLDINGS_POSITION)); + assertNull(modifiedRow.get(OTHER_HOLDINGS_POSITION)); } @Test void shouldAddStaffOnlyPostfixWhenRequiredForHoldingsNotes() { var table = UnifiedTableHeaderBuilder.getEmptyTableWithHeaders(Item.class); var row = Arrays.stream(new String[table.getHeader().size()]).collect(Collectors.toCollection(ArrayList::new)); - row.set(HOLDINGS_NOTE_POSITION, "Action note;Action note text;true|Note;Note text;false|Binding;Binding text;true"); + row.set(HOLDINGS_NOTE_POSITION, "Action note;Action note text;true|Note;Note text;false|Other;Other text;true"); table.setRows(List.of(new Row().row(row))); var expectedTableSize = table.getHeader().size() + 2; @@ -203,7 +204,7 @@ void shouldAddStaffOnlyPostfixWhenRequiredForHoldingsNotes() { when(holdingsReferenceService.getAllHoldingsNoteTypes()) .thenReturn(List.of(HoldingsNoteType.builder().name("Action note").build(), HoldingsNoteType.builder().name("Note").build(), - HoldingsNoteType.builder().name("Binding").build())); + HoldingsNoteType.builder().name("Other").build())); noteTableUpdater.extendTableWithHoldingsNotesTypes(table); @@ -211,12 +212,50 @@ void shouldAddStaffOnlyPostfixWhenRequiredForHoldingsNotes() { var headerNames = table.getHeader().stream().map(Cell::getValue).toList(); assertThat(headerNames.indexOf("Action note"), is(ACTION_HOLDINGS_NOTE_POSITION)); assertThat(headerNames.indexOf("Note"), is(NOTE_HOLDINGS_POSITION)); - assertThat(headerNames.indexOf("Binding"), is(BINDING_HOLDINGS_POSITION)); + assertThat(headerNames.indexOf("Other"), is(OTHER_HOLDINGS_POSITION)); var modifiedRow = table.getRows().get(0).getRow(); assertThat(modifiedRow, hasSize(expectedTableSize)); assertTrue(modifiedRow.get(ACTION_HOLDINGS_NOTE_POSITION).contains(STAFF_ONLY)); assertFalse(modifiedRow.get(NOTE_HOLDINGS_POSITION).contains(STAFF_ONLY)); - assertTrue(modifiedRow.get(BINDING_HOLDINGS_POSITION).contains(STAFF_ONLY)); + assertTrue(modifiedRow.get(OTHER_HOLDINGS_POSITION).contains(STAFF_ONLY)); + } + + @Test + void shouldAddNotePostfixWhenRequiredForHoldingsNoteTypeNames() { + var table = UnifiedTableHeaderBuilder.getEmptyTableWithHeaders(HoldingsRecord.class); + var row = Arrays.stream(new String[table.getHeader().size()]).collect(Collectors.toCollection(ArrayList::new)); + table.setRows(List.of(new Row().row(row))); + + when(holdingsReferenceService.getAllHoldingsNoteTypes()) + .thenReturn(List.of(HoldingsNoteType.builder().name("Binding").build(), + HoldingsNoteType.builder().name("Electronic bookplate").build(), + HoldingsNoteType.builder().name("Provenance").build(), + HoldingsNoteType.builder().name("Reproduction").build())); + + noteTableUpdater.extendTableWithHoldingsNotesTypes(table); + + var headerNames = table.getHeader().stream().map(Cell::getValue).toList(); + List.of("Binding", "Electronic bookplate", "Provenance", "Reproduction").forEach(name -> + assertTrue(headerNames.contains(name + " note"))); + } + + @Test + void shouldAddNotePostfixWhenRequiredForItemNoteTypeNames() { + var table = UnifiedTableHeaderBuilder.getEmptyTableWithHeaders(Item.class); + var row = Arrays.stream(new String[table.getHeader().size()]).collect(Collectors.toCollection(ArrayList::new)); + table.setRows(List.of(new Row().row(row))); + + when(itemReferenceService.getAllItemNoteTypes()) + .thenReturn(List.of(NoteType.builder().name("Binding").build(), + NoteType.builder().name("Electronic bookplate").build(), + NoteType.builder().name("Provenance").build(), + NoteType.builder().name("Reproduction").build())); + + noteTableUpdater.extendTableWithItemNotesTypes(table); + + var headerNames = table.getHeader().stream().map(Cell::getValue).toList(); + List.of("Binding", "Electronic bookplate", "Provenance", "Reproduction").forEach(name -> + assertTrue(headerNames.contains(name + " note"))); } }