From 8c093883617f17256b46cd23f8f56203088b9b57 Mon Sep 17 00:00:00 2001 From: martin-nhs <127403254+martin-nhs@users.noreply.github.com> Date: Thu, 8 Aug 2024 13:35:01 +0100 Subject: [PATCH 01/20] [NIAD-3148] Add method to TestUtility.java `getEhrFolderComponent` --- .../adaptors/pss/translator/TestUtility.java | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/TestUtility.java b/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/TestUtility.java index 019eef5d2..c56908b7b 100644 --- a/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/TestUtility.java +++ b/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/TestUtility.java @@ -1,19 +1,22 @@ package uk.nhs.adaptors.pss.translator; import org.hl7.v3.CV; +import org.hl7.v3.RCMRMT030101UKComponent3; import org.hl7.v3.RCMRMT030101UKEhrComposition; import org.hl7.v3.RCMRMT030101UKEhrExtract; +import org.hl7.v3.RCMRMT030101UKEhrFolder; import java.util.function.Function; +import java.util.function.Predicate; public final class TestUtility { private TestUtility() { } public static final Function GET_EHR_COMPOSITION = extract -> extract - .getComponent().get(0) + .getComponent().getFirst() .getEhrFolder() - .getComponent().get(0) + .getComponent().getFirst() .getEhrComposition(); public static CV createCv(String code, String codeSystem, String displayName) { @@ -28,6 +31,29 @@ public static CV createCv(String code) { return createCv(code, "", ""); } + /** + * An EHR Extract has a cardinality of one to many components, each component (based + * of the UK05 schema) can contain one and only one EHR Folder. This utility method provides + * a means of extracting a single component from within a target EHR Folder based on a predicate. + * @param extract The EHR Extract to be filtered. + * @param extractComponentIndex The index of the component which houses the EHR Folder. + * @param searchCriteriaPredicate The predicate to find the component. + * @return The found RCMRMT030101UKComponent3, or else a ComponentDoesNotExistException will be thrown. + */ + public static RCMRMT030101UKComponent3 getEhrFolderComponent(RCMRMT030101UKEhrExtract extract, + int extractComponentIndex, + Predicate searchCriteriaPredicate) { + final RCMRMT030101UKEhrFolder targetFolder = extract + .getComponent() + .get(extractComponentIndex) + .getEhrFolder(); + + return targetFolder.getComponent().stream() + .filter(searchCriteriaPredicate) + .findFirst() + .orElseThrow(ComponentDoesNotExistException::new); + } + public static class NoConfidentialityCodePresentException extends RuntimeException { private static final String EXCEPTION_MESSAGE = "No confidentiality code is present within the test file."; @@ -35,4 +61,12 @@ public NoConfidentialityCodePresentException() { super(EXCEPTION_MESSAGE); } } + + public static class ComponentDoesNotExistException extends RuntimeException { + private static final String EXCEPTION_MESSAGE = "No component could not be found."; + + public ComponentDoesNotExistException() { + super(EXCEPTION_MESSAGE); + } + } } From e6a8954f7059d716d0b784cbb32451f8d5647b04 Mon Sep 17 00:00:00 2001 From: martin-nhs <127403254+martin-nhs@users.noreply.github.com> Date: Thu, 8 Aug 2024 14:25:53 +0100 Subject: [PATCH 02/20] [NIAD-3148] Add method to TestUtility.java `getEhrFolderComponent` --- .../adaptors/pss/translator/TestUtility.java | 29 +++++-------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/TestUtility.java b/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/TestUtility.java index c56908b7b..44906659d 100644 --- a/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/TestUtility.java +++ b/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/TestUtility.java @@ -6,8 +6,8 @@ import org.hl7.v3.RCMRMT030101UKEhrExtract; import org.hl7.v3.RCMRMT030101UKEhrFolder; +import java.util.List; import java.util.function.Function; -import java.util.function.Predicate; public final class TestUtility { private TestUtility() { } @@ -34,24 +34,19 @@ public static CV createCv(String code) { /** * An EHR Extract has a cardinality of one to many components, each component (based * of the UK05 schema) can contain one and only one EHR Folder. This utility method provides - * a means of extracting a single component from within a target EHR Folder based on a predicate. - * @param extract The EHR Extract to be filtered. - * @param extractComponentIndex The index of the component which houses the EHR Folder. - * @param searchCriteriaPredicate The predicate to find the component. - * @return The found RCMRMT030101UKComponent3, or else a ComponentDoesNotExistException will be thrown. + * a means of extracting ALL components from within a target EHR Folder. + * @param extract The EHR Extract. + * @param extractComponentIndex The index of the RCMRMT030101UKComponent which houses the EHR Folder. + * @return A list of RCMRMT030101UKComponent3. */ - public static RCMRMT030101UKComponent3 getEhrFolderComponent(RCMRMT030101UKEhrExtract extract, - int extractComponentIndex, - Predicate searchCriteriaPredicate) { + public static List getEhrFolderComponent(RCMRMT030101UKEhrExtract extract, + int extractComponentIndex) { final RCMRMT030101UKEhrFolder targetFolder = extract .getComponent() .get(extractComponentIndex) .getEhrFolder(); - return targetFolder.getComponent().stream() - .filter(searchCriteriaPredicate) - .findFirst() - .orElseThrow(ComponentDoesNotExistException::new); + return targetFolder.getComponent(); } public static class NoConfidentialityCodePresentException extends RuntimeException { @@ -61,12 +56,4 @@ public NoConfidentialityCodePresentException() { super(EXCEPTION_MESSAGE); } } - - public static class ComponentDoesNotExistException extends RuntimeException { - private static final String EXCEPTION_MESSAGE = "No component could not be found."; - - public ComponentDoesNotExistException() { - super(EXCEPTION_MESSAGE); - } - } } From 5073d117516cad260efa6f65ab11f50073a727ed Mon Sep 17 00:00:00 2001 From: martin-nhs <127403254+martin-nhs@users.noreply.github.com> Date: Thu, 8 Aug 2024 14:33:08 +0100 Subject: [PATCH 03/20] [NIAD-3148] Add some unit tests for current logic --- .../util/DatabaseImmunizationCheckerTest.java | 101 ++++++++++++++ .../xml/Immunization/ehr_extract.xml | 122 +++++++++++++++++ ...valid_immunization_with_no_translation.xml | 122 +++++++++++++++++ ...ll_valid_immunization_with_translation.xml | 123 ++++++++++++++++++ 4 files changed, 468 insertions(+) create mode 100644 gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationCheckerTest.java create mode 100644 gp2gp-translator/src/test/resources/xml/Immunization/ehr_extract.xml create mode 100644 gp2gp-translator/src/test/resources/xml/Immunization/full_valid_immunization_with_no_translation.xml create mode 100644 gp2gp-translator/src/test/resources/xml/Immunization/full_valid_immunization_with_translation.xml diff --git a/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationCheckerTest.java b/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationCheckerTest.java new file mode 100644 index 000000000..a07762554 --- /dev/null +++ b/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationCheckerTest.java @@ -0,0 +1,101 @@ +package uk.nhs.adaptors.pss.translator.util; + +import jakarta.xml.bind.JAXBException; +import org.hl7.v3.RCMRMT030101UKComponent3; +import org.hl7.v3.RCMRMT030101UKEhrExtract; +import org.hl7.v3.RCMRMT030101UKObservationStatement; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.nhs.adaptors.connector.dao.ImmunizationSnomedCTDao; +import uk.nhs.adaptors.connector.model.ImmunizationSnomedCT; +import uk.nhs.adaptors.pss.translator.FileFactory; + +import java.io.File; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.mockito.Mockito.when; +import static uk.nhs.adaptors.pss.translator.TestUtility.getEhrFolderComponent; +import static uk.nhs.adaptors.pss.translator.util.XmlUnmarshallUtil.unmarshallFile; + +@ExtendWith(MockitoExtension.class) +class DatabaseImmunizationCheckerTest { + @Mock + private ImmunizationSnomedCTDao immunizationSnomedCTDao; + + @InjectMocks + private DatabaseImmunizationChecker databaseImmunizationChecker; + + @Captor + private ArgumentCaptor snomedCtIdCaptor; + + private static final String TEST_FILES_DIRECTORY = "Immunization"; + + @Test + void When_IsObservationStatementImmunization_With_ImmunizationCode_Expect_True() throws JAXBException { + final String expectedCode = "3955997015"; + final RCMRMT030101UKObservationStatement observationStatement = getObservationStatementFromExtract( + "full_valid_immunization_with_no_translation.xml"); + final ImmunizationSnomedCT immunizationSnomedCT = ImmunizationSnomedCT.builder() + .conceptId(expectedCode) + .build(); + + when(immunizationSnomedCTDao.getImmunizationSnomednUsingConceptId( + snomedCtIdCaptor.capture() + )).thenReturn(immunizationSnomedCT); + + final boolean result = databaseImmunizationChecker.isImmunization(observationStatement); + + assertAll( + () -> assertThat(result).isTrue(), + () -> assertThat(snomedCtIdCaptor.getValue()).isEqualTo(expectedCode) + ); + } + + @Test + void When_IsObservationStatementImmunization_With_ImmunizationCodeAndNonImmunizationTranslation_Expect_True() throws JAXBException { + final String snomedCode = "142934010"; + final String readsV2Code = "65E..00"; + final RCMRMT030101UKObservationStatement observationStatement = getObservationStatementFromExtract( + "full_valid_immunization_with_translation.xml" + ); + + final ImmunizationSnomedCT immunizationSnomedCT = ImmunizationSnomedCT.builder() + .conceptId(snomedCode) + .build(); + + when(immunizationSnomedCTDao.getImmunizationSnomednUsingConceptId( + snomedCtIdCaptor.capture() + )).thenReturn(null, immunizationSnomedCT); + + final boolean result = databaseImmunizationChecker.isImmunization(observationStatement); + + assertAll( + () -> assertThat(result).isTrue(), + () -> assertThat(snomedCtIdCaptor.getAllValues().getFirst()).isEqualTo(readsV2Code), + () -> assertThat(snomedCtIdCaptor.getAllValues().get(1)).isEqualTo(snomedCode) + ); + } + + private RCMRMT030101UKObservationStatement getObservationStatementFromExtract(String filename) throws JAXBException { + final RCMRMT030101UKEhrExtract ehrExtract = getEhrExtractFromFile(filename); + final List components = getEhrFolderComponent(ehrExtract, 0); + + return components.getFirst() + .getEhrComposition() + .getComponent() + .getFirst() + .getObservationStatement(); + } + + private RCMRMT030101UKEhrExtract getEhrExtractFromFile(String filename) throws JAXBException { + final File file = FileFactory.getXmlFileFor(TEST_FILES_DIRECTORY, filename); + return unmarshallFile(file, RCMRMT030101UKEhrExtract.class); + } +} \ No newline at end of file diff --git a/gp2gp-translator/src/test/resources/xml/Immunization/ehr_extract.xml b/gp2gp-translator/src/test/resources/xml/Immunization/ehr_extract.xml new file mode 100644 index 000000000..b43d70913 --- /dev/null +++ b/gp2gp-translator/src/test/resources/xml/Immunization/ehr_extract.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + General Medical Practitioner + + + + Dr + helen + tallantyre + + + + + + + + + + + Summary Event Entry + + + +
+ + + + + + + + + + + + + + + +
+ + + + + + + [Manufacturer: Phizer], [Batch Number: 1] + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gp2gp-translator/src/test/resources/xml/Immunization/full_valid_immunization_with_no_translation.xml b/gp2gp-translator/src/test/resources/xml/Immunization/full_valid_immunization_with_no_translation.xml new file mode 100644 index 000000000..b43d70913 --- /dev/null +++ b/gp2gp-translator/src/test/resources/xml/Immunization/full_valid_immunization_with_no_translation.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + General Medical Practitioner + + + + Dr + helen + tallantyre + + + + + + + + + + + Summary Event Entry + + + +
+ + + + + + + + + + + + + + + +
+ + + + + + + [Manufacturer: Phizer], [Batch Number: 1] + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gp2gp-translator/src/test/resources/xml/Immunization/full_valid_immunization_with_translation.xml b/gp2gp-translator/src/test/resources/xml/Immunization/full_valid_immunization_with_translation.xml new file mode 100644 index 000000000..63b82c344 --- /dev/null +++ b/gp2gp-translator/src/test/resources/xml/Immunization/full_valid_immunization_with_translation.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + General Medical Practitioner + + + + Dr + helen + tallantyre + + + + + + + + + + + Summary Event Entry + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + [Manufacturer: Phizer], [Batch Number: 1] + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 60306be351616d09a7ec49bfdd1bd65601f72fe2 Mon Sep 17 00:00:00 2001 From: martin-nhs <127403254+martin-nhs@users.noreply.github.com> Date: Thu, 8 Aug 2024 14:34:27 +0100 Subject: [PATCH 04/20] [NIAD-3148] Remove redundant test file --- .../xml/Immunization/ehr_extract.xml | 122 ------------------ 1 file changed, 122 deletions(-) delete mode 100644 gp2gp-translator/src/test/resources/xml/Immunization/ehr_extract.xml diff --git a/gp2gp-translator/src/test/resources/xml/Immunization/ehr_extract.xml b/gp2gp-translator/src/test/resources/xml/Immunization/ehr_extract.xml deleted file mode 100644 index b43d70913..000000000 --- a/gp2gp-translator/src/test/resources/xml/Immunization/ehr_extract.xml +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - General Medical Practitioner - - - - Dr - helen - tallantyre - - - - - - - - - - - Summary Event Entry - - - -
- - - - - - - - - - - - - - - -
- - - - - - - [Manufacturer: Phizer], [Batch Number: 1] - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 112533675fe03653a560658788f9cca0f92f3543 Mon Sep 17 00:00:00 2001 From: martin-nhs <127403254+martin-nhs@users.noreply.github.com> Date: Thu, 8 Aug 2024 14:37:05 +0100 Subject: [PATCH 05/20] [NIAD-3148] Initial refactor of DatabaseImmunizationChecker.java --- .../util/DatabaseImmunizationChecker.java | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/gp2gp-translator/src/main/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationChecker.java b/gp2gp-translator/src/main/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationChecker.java index 781d20136..d865bd378 100644 --- a/gp2gp-translator/src/main/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationChecker.java +++ b/gp2gp-translator/src/main/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationChecker.java @@ -6,26 +6,39 @@ import lombok.RequiredArgsConstructor; import uk.nhs.adaptors.connector.dao.ImmunizationSnomedCTDao; -import uk.nhs.adaptors.connector.model.ImmunizationSnomedCT; -@RequiredArgsConstructor(onConstructor = @__(@Autowired)) @Component +@RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class DatabaseImmunizationChecker implements ImmunizationChecker { private final ImmunizationSnomedCTDao immunizationSnomedDao; @Override public boolean isImmunization(RCMRMT030101UKObservationStatement observationStatement) { - ImmunizationSnomedCT immunizationCode = null; + final boolean translationIsPresent = !observationStatement.getCode().getTranslation().isEmpty(); - if (!observationStatement.getCode().getTranslation().isEmpty()) { - immunizationCode = immunizationSnomedDao - .getImmunizationSnomednUsingConceptId(observationStatement.getCode().getTranslation().get(0).getCode()); - } + if (translationIsPresent) { + final boolean isImmunization = isTranslationCodeImmunization(observationStatement); - if (immunizationCode == null) { - immunizationCode = immunizationSnomedDao.getImmunizationSnomednUsingConceptId(observationStatement.getCode().getCode()); + if (isImmunization) { + return true; + } } - return immunizationCode != null; + return isCodeImmunization(observationStatement); + } + + private boolean isTranslationCodeImmunization(RCMRMT030101UKObservationStatement observationStatement) { + final String code = observationStatement.getCode() + .getTranslation() + .getFirst() + .getCode(); + + return immunizationSnomedDao.getImmunizationSnomednUsingConceptId(code) != null; + } + + private boolean isCodeImmunization(RCMRMT030101UKObservationStatement observationStatement) { + final String code = observationStatement.getCode().getCode(); + + return immunizationSnomedDao.getImmunizationSnomednUsingConceptId(code) != null; } -} +} \ No newline at end of file From a30b77acea69efe09419f397de603cfadbe90368 Mon Sep 17 00:00:00 2001 From: martin-nhs <127403254+martin-nhs@users.noreply.github.com> Date: Thu, 8 Aug 2024 16:27:43 +0100 Subject: [PATCH 06/20] [NIAD-3148] Create DatabaseImmunizationCheckerTest --- .../DatabaseImmunizationCheckerIT.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 gp2gp-translator/src/integrationTest/java/uk/nhs/adaptors/pss/translator/DatabaseImmunizationCheckerIT.java diff --git a/gp2gp-translator/src/integrationTest/java/uk/nhs/adaptors/pss/translator/DatabaseImmunizationCheckerIT.java b/gp2gp-translator/src/integrationTest/java/uk/nhs/adaptors/pss/translator/DatabaseImmunizationCheckerIT.java new file mode 100644 index 000000000..eac033792 --- /dev/null +++ b/gp2gp-translator/src/integrationTest/java/uk/nhs/adaptors/pss/translator/DatabaseImmunizationCheckerIT.java @@ -0,0 +1,56 @@ +package uk.nhs.adaptors.pss.translator; + +import org.hl7.v3.RCMRMT030101UKObservationStatement; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import uk.nhs.adaptors.pss.translator.util.DatabaseImmunizationChecker; + +import static org.assertj.core.api.Assertions.assertThat; +import static uk.nhs.adaptors.pss.translator.TestUtility.createCd; + +@ExtendWith(SpringExtension.class) +@SpringBootTest +class DatabaseImmunizationCheckerIT { + private static final String SNOMED_CODE_SYSTEM = "2.16.840.1.113883.2.1.3.2.4.15"; + private static final String DISPLAY_NAME = "Administration of yellow fever vaccine"; + + @Autowired + private DatabaseImmunizationChecker databaseImmunizationChecker; + + @Test + void When_Immunization_With_SnomedDescriptionId_Expect_True() { + final String immunizationDescriptionSnomedId = "67308009"; + final RCMRMT030101UKObservationStatement observationStatement = + new RCMRMT030101UKObservationStatement(); + + observationStatement.setCode(createCd( + immunizationDescriptionSnomedId, + SNOMED_CODE_SYSTEM, + DISPLAY_NAME + )); + + final boolean result = databaseImmunizationChecker.isImmunization(observationStatement); + + assertThat(result).isTrue(); + } + + @Test + void When_Immunization_With_SnomedConceptId_Expect_True() { + final String immunizationConceptSnomedId = "67308009"; + final RCMRMT030101UKObservationStatement observationStatement = + new RCMRMT030101UKObservationStatement(); + + observationStatement.setCode(createCd( + immunizationConceptSnomedId, + SNOMED_CODE_SYSTEM, + DISPLAY_NAME + )); + + final boolean result = databaseImmunizationChecker.isImmunization(observationStatement); + + assertThat(result).isTrue(); + } +} From 30caf9083d7fd49aa790f0d9470b3bc1b2f7ae92 Mon Sep 17 00:00:00 2001 From: martin-nhs <127403254+martin-nhs@users.noreply.github.com> Date: Thu, 8 Aug 2024 16:28:31 +0100 Subject: [PATCH 07/20] [NIAD-3148] Create utility to create CD values --- .../java/uk/nhs/adaptors/pss/translator/TestUtility.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/TestUtility.java b/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/TestUtility.java index 44906659d..68f12356d 100644 --- a/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/TestUtility.java +++ b/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/TestUtility.java @@ -1,5 +1,6 @@ package uk.nhs.adaptors.pss.translator; +import org.hl7.v3.CD; import org.hl7.v3.CV; import org.hl7.v3.RCMRMT030101UKComponent3; import org.hl7.v3.RCMRMT030101UKEhrComposition; @@ -31,6 +32,14 @@ public static CV createCv(String code) { return createCv(code, "", ""); } + public static CD createCd(String code, String codeSystem, String displayName) { + final CD cd = new CD(); + cd.setCode(code); + cd.setCodeSystem(codeSystem); + cd.setDisplayName(displayName); + return cd; + } + /** * An EHR Extract has a cardinality of one to many components, each component (based * of the UK05 schema) can contain one and only one EHR Folder. This utility method provides From e4a52cfa98603d13c01b9ec728da34dc63bc8715 Mon Sep 17 00:00:00 2001 From: martin-nhs <127403254+martin-nhs@users.noreply.github.com> Date: Thu, 8 Aug 2024 16:29:57 +0100 Subject: [PATCH 08/20] [NIAD-3148] Add functionality to create-database-postgres.sql to join the description ID and concept ID --- .../select_immunization_concept_id.sql | 2 +- .../ImmunizationSnomedCTDao/verify_immunizations_loaded.sql | 2 +- snomed-database-loader/create-database-postgres.sql | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/select_immunization_concept_id.sql b/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/select_immunization_concept_id.sql index 5643878e0..9025b662b 100644 --- a/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/select_immunization_concept_id.sql +++ b/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/select_immunization_concept_id.sql @@ -1 +1 @@ -SELECT i.conceptid FROM "snomedct".immunization_codes i WHERE conceptid = :conceptId; \ No newline at end of file +SELECT i.conceptid FROM "snomedct".immunization_codes i WHERE conceptid = :sctid OR descriptionid = :sctid; \ No newline at end of file diff --git a/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/verify_immunizations_loaded.sql b/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/verify_immunizations_loaded.sql index 1a4387058..b84e5d90e 100644 --- a/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/verify_immunizations_loaded.sql +++ b/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/verify_immunizations_loaded.sql @@ -1,7 +1,7 @@ -- the conceptIds being checked for below represent the immunization root codes and those immunization codes outside -- of the root code hierarchy, as described in the snomed-database-loader README.md file -SELECT COUNT(i.conceptid) = 16 -- total number of codes +SELECT COUNT(DISTINCT i.conceptid) = 16 -- total number of codes FROM "snomedct".immunization_codes i WHERE i.conceptid IN ( '787859002', '127785005', '304250009', '90351000119108','713404003','2997511000001102', diff --git a/snomed-database-loader/create-database-postgres.sql b/snomed-database-loader/create-database-postgres.sql index de787168a..6b6dd0b2e 100644 --- a/snomed-database-loader/create-database-postgres.sql +++ b/snomed-database-loader/create-database-postgres.sql @@ -70,8 +70,9 @@ WITH RECURSIVE immunization_heirarchy AS ( JOIN immunization_heirarchy i ON r.destinationId = i.conceptId WHERE r.typeId = '116680003' -- relationshipType (typeId) is 'IsA' (child of) ) -SELECT conceptId -FROM immunization_heirarchy; +SELECT ih.conceptId, ds.id as descriptionid +FROM immunization_heirarchy ih +JOIN snomedct.description_s ds on ih.conceptId = ds.conceptid; CREATE INDEX immunization_codes_conceptid_idx ON immunization_codes USING btree (conceptid); From 48065776893c320526a22b38e5faf71e5472c9bc Mon Sep 17 00:00:00 2001 From: martin-nhs <127403254+martin-nhs@users.noreply.github.com> Date: Thu, 8 Aug 2024 16:30:56 +0100 Subject: [PATCH 09/20] [NIAD-3148] Method signature renamed to `getImmunizationSnomedUsingConceptOrDescriptionId` --- .../nhs/adaptors/connector/dao/ImmunizationSnomedCTDao.java | 2 +- .../pss/translator/util/DatabaseImmunizationChecker.java | 4 ++-- .../pss/translator/util/DatabaseImmunizationCheckerTest.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/db-connector/src/main/java/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao.java b/db-connector/src/main/java/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao.java index 790842dbe..b29cb9d4b 100644 --- a/db-connector/src/main/java/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao.java +++ b/db-connector/src/main/java/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao.java @@ -9,7 +9,7 @@ public interface ImmunizationSnomedCTDao { @SqlQuery("select_immunization_concept_id") @UseClasspathSqlLocator - ImmunizationSnomedCT getImmunizationSnomednUsingConceptId(@Bind("conceptId") String conceptId); + ImmunizationSnomedCT getImmunizationSnomedUsingConceptOrDescriptionId(@Bind("sctid") String sctId); @SqlQuery("verify_immunizations_loaded") @UseClasspathSqlLocator diff --git a/gp2gp-translator/src/main/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationChecker.java b/gp2gp-translator/src/main/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationChecker.java index d865bd378..3d5219af5 100644 --- a/gp2gp-translator/src/main/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationChecker.java +++ b/gp2gp-translator/src/main/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationChecker.java @@ -33,12 +33,12 @@ private boolean isTranslationCodeImmunization(RCMRMT030101UKObservationStatement .getFirst() .getCode(); - return immunizationSnomedDao.getImmunizationSnomednUsingConceptId(code) != null; + return immunizationSnomedDao.getImmunizationSnomedUsingConceptOrDescriptionId(code) != null; } private boolean isCodeImmunization(RCMRMT030101UKObservationStatement observationStatement) { final String code = observationStatement.getCode().getCode(); - return immunizationSnomedDao.getImmunizationSnomednUsingConceptId(code) != null; + return immunizationSnomedDao.getImmunizationSnomedUsingConceptOrDescriptionId(code) != null; } } \ No newline at end of file diff --git a/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationCheckerTest.java b/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationCheckerTest.java index a07762554..78ec40488 100644 --- a/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationCheckerTest.java +++ b/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationCheckerTest.java @@ -46,7 +46,7 @@ void When_IsObservationStatementImmunization_With_ImmunizationCode_Expect_True() .conceptId(expectedCode) .build(); - when(immunizationSnomedCTDao.getImmunizationSnomednUsingConceptId( + when(immunizationSnomedCTDao.getImmunizationSnomedUsingConceptOrDescriptionId( snomedCtIdCaptor.capture() )).thenReturn(immunizationSnomedCT); @@ -70,7 +70,7 @@ void When_IsObservationStatementImmunization_With_ImmunizationCodeAndNonImmuniza .conceptId(snomedCode) .build(); - when(immunizationSnomedCTDao.getImmunizationSnomednUsingConceptId( + when(immunizationSnomedCTDao.getImmunizationSnomedUsingConceptOrDescriptionId( snomedCtIdCaptor.capture() )).thenReturn(null, immunizationSnomedCT); From b4db52d339412516486a1acac23d63d7f894ba25 Mon Sep 17 00:00:00 2001 From: martin-nhs <127403254+martin-nhs@users.noreply.github.com> Date: Thu, 8 Aug 2024 20:41:26 +0100 Subject: [PATCH 10/20] [NIAD-3148] Address problem with test-load-immunization-codes.sh --- snomed-database-loader/test-load-immunization-codes.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snomed-database-loader/test-load-immunization-codes.sh b/snomed-database-loader/test-load-immunization-codes.sh index 4e470f880..4175bc282 100755 --- a/snomed-database-loader/test-load-immunization-codes.sh +++ b/snomed-database-loader/test-load-immunization-codes.sh @@ -38,7 +38,7 @@ databaseUri="postgresql://${PS_DB_OWNER_NAME}:${POSTGRES_PASSWORD}@${PS_DB_HOST} function checkImmunizationCodesAreLoaded() { for immunizationCode; do - count=$(psql "${databaseUri}" -t -A -c "SELECT COUNT(conceptId) FROM ${snomedCtSchema}.immunization_codes WHERE conceptId ='${immunizationCode}'") + count=$(psql "${databaseUri}" -t -A -c "SELECT COUNT(DISTINCT conceptId) FROM ${snomedCtSchema}.immunization_codes WHERE conceptId ='${immunizationCode}'") if [ "${count}" != 1 ] then echo "immunization code not loaded: ${immunizationCode}" From 6854754499d33111cc680cac46981aced5cec5e9 Mon Sep 17 00:00:00 2001 From: MartinWheelerMT Date: Fri, 9 Aug 2024 13:31:56 +0100 Subject: [PATCH 11/20] Add DirtiesContext to DatabaseImmunizationCheckerIT --- .../adaptors/pss/translator/DatabaseImmunizationCheckerIT.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gp2gp-translator/src/integrationTest/java/uk/nhs/adaptors/pss/translator/DatabaseImmunizationCheckerIT.java b/gp2gp-translator/src/integrationTest/java/uk/nhs/adaptors/pss/translator/DatabaseImmunizationCheckerIT.java index eac033792..5bf2c8c5e 100644 --- a/gp2gp-translator/src/integrationTest/java/uk/nhs/adaptors/pss/translator/DatabaseImmunizationCheckerIT.java +++ b/gp2gp-translator/src/integrationTest/java/uk/nhs/adaptors/pss/translator/DatabaseImmunizationCheckerIT.java @@ -5,6 +5,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit.jupiter.SpringExtension; import uk.nhs.adaptors.pss.translator.util.DatabaseImmunizationChecker; @@ -13,6 +14,7 @@ @ExtendWith(SpringExtension.class) @SpringBootTest +@DirtiesContext class DatabaseImmunizationCheckerIT { private static final String SNOMED_CODE_SYSTEM = "2.16.840.1.113883.2.1.3.2.4.15"; private static final String DISPLAY_NAME = "Administration of yellow fever vaccine"; From b5ed36a1be14da43198b108258443f16323cceaa Mon Sep 17 00:00:00 2001 From: martin-nhs <127403254+martin-nhs@users.noreply.github.com> Date: Fri, 9 Aug 2024 16:25:03 +0100 Subject: [PATCH 12/20] [NIAD-3148] Address PR to https://github.com/NHSDigital/nia-patient-switching-standard-adaptor/pull/752#discussion_r1710246171 --- .../uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao.java | 2 +- .../ImmunizationSnomedCTDao/select_immunization_concept_id.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/db-connector/src/main/java/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao.java b/db-connector/src/main/java/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao.java index b29cb9d4b..6b1b688ef 100644 --- a/db-connector/src/main/java/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao.java +++ b/db-connector/src/main/java/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao.java @@ -9,7 +9,7 @@ public interface ImmunizationSnomedCTDao { @SqlQuery("select_immunization_concept_id") @UseClasspathSqlLocator - ImmunizationSnomedCT getImmunizationSnomedUsingConceptOrDescriptionId(@Bind("sctid") String sctId); + ImmunizationSnomedCT getImmunizationSnomedUsingConceptOrDescriptionId(@Bind("snomedId") String snomedId); @SqlQuery("verify_immunizations_loaded") @UseClasspathSqlLocator diff --git a/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/select_immunization_concept_id.sql b/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/select_immunization_concept_id.sql index 9025b662b..7c4147bef 100644 --- a/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/select_immunization_concept_id.sql +++ b/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/select_immunization_concept_id.sql @@ -1 +1 @@ -SELECT i.conceptid FROM "snomedct".immunization_codes i WHERE conceptid = :sctid OR descriptionid = :sctid; \ No newline at end of file +SELECT i.conceptid FROM "snomedct".immunization_codes i WHERE conceptid = :snomedId OR descriptionid = :snomedId; \ No newline at end of file From 71c4a5bb1138ea7f850d66c85e7ccd3734a160de Mon Sep 17 00:00:00 2001 From: martin-nhs <127403254+martin-nhs@users.noreply.github.com> Date: Fri, 9 Aug 2024 16:32:27 +0100 Subject: [PATCH 13/20] [NIAD-3148] Address PR comments https://github.com/NHSDigital/nia-patient-switching-standard-adaptor/pull/752/files#r1710239250 and https://github.com/NHSDigital/nia-patient-switching-standard-adaptor/pull/752/files#r1710234310 --- .../DatabaseImmunizationCheckerIT.java | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/gp2gp-translator/src/integrationTest/java/uk/nhs/adaptors/pss/translator/DatabaseImmunizationCheckerIT.java b/gp2gp-translator/src/integrationTest/java/uk/nhs/adaptors/pss/translator/DatabaseImmunizationCheckerIT.java index 5bf2c8c5e..543f6c8ea 100644 --- a/gp2gp-translator/src/integrationTest/java/uk/nhs/adaptors/pss/translator/DatabaseImmunizationCheckerIT.java +++ b/gp2gp-translator/src/integrationTest/java/uk/nhs/adaptors/pss/translator/DatabaseImmunizationCheckerIT.java @@ -1,5 +1,6 @@ package uk.nhs.adaptors.pss.translator; +import org.hl7.v3.CD; import org.hl7.v3.RCMRMT030101UKObservationStatement; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -12,27 +13,24 @@ import static org.assertj.core.api.Assertions.assertThat; import static uk.nhs.adaptors.pss.translator.TestUtility.createCd; -@ExtendWith(SpringExtension.class) @SpringBootTest @DirtiesContext +@ExtendWith(SpringExtension.class) class DatabaseImmunizationCheckerIT { - private static final String SNOMED_CODE_SYSTEM = "2.16.840.1.113883.2.1.3.2.4.15"; - private static final String DISPLAY_NAME = "Administration of yellow fever vaccine"; + private static final String SNOMED_CODE_SYSTEM_OID = "2.16.840.1.113883.2.1.3.2.4.15"; + private static final String DISPLAY_NAME = "Influenza vaccination"; @Autowired private DatabaseImmunizationChecker databaseImmunizationChecker; @Test void When_Immunization_With_SnomedDescriptionId_Expect_True() { - final String immunizationDescriptionSnomedId = "67308009"; + final String immunizationDescriptionSnomedId = "142934010"; + final CD cd = getCdForSnomedId(immunizationDescriptionSnomedId); final RCMRMT030101UKObservationStatement observationStatement = new RCMRMT030101UKObservationStatement(); - observationStatement.setCode(createCd( - immunizationDescriptionSnomedId, - SNOMED_CODE_SYSTEM, - DISPLAY_NAME - )); + observationStatement.setCode(cd); final boolean result = databaseImmunizationChecker.isImmunization(observationStatement); @@ -41,18 +39,23 @@ void When_Immunization_With_SnomedDescriptionId_Expect_True() { @Test void When_Immunization_With_SnomedConceptId_Expect_True() { - final String immunizationConceptSnomedId = "67308009"; + final String immunizationConceptSnomedId = "86198006"; + final CD cd = getCdForSnomedId(immunizationConceptSnomedId); final RCMRMT030101UKObservationStatement observationStatement = new RCMRMT030101UKObservationStatement(); - observationStatement.setCode(createCd( - immunizationConceptSnomedId, - SNOMED_CODE_SYSTEM, - DISPLAY_NAME - )); + observationStatement.setCode(cd); final boolean result = databaseImmunizationChecker.isImmunization(observationStatement); assertThat(result).isTrue(); } + + private CD getCdForSnomedId(String snomedId) { + return createCd( + snomedId, + SNOMED_CODE_SYSTEM_OID, + DISPLAY_NAME + ); + } } From c617824dfc3333805bb684ef81065bef44ed9c1c Mon Sep 17 00:00:00 2001 From: martin-nhs <127403254+martin-nhs@users.noreply.github.com> Date: Fri, 9 Aug 2024 16:33:58 +0100 Subject: [PATCH 14/20] [NIAD-3148] Address PR comment https://github.com/NHSDigital/nia-patient-switching-standard-adaptor/pull/752/files#r1710219516 --- .../test/java/uk/nhs/adaptors/pss/translator/TestUtility.java | 4 ++-- .../pss/translator/util/DatabaseImmunizationCheckerTest.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/TestUtility.java b/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/TestUtility.java index 68f12356d..7f2743c71 100644 --- a/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/TestUtility.java +++ b/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/TestUtility.java @@ -48,8 +48,8 @@ public static CD createCd(String code, String codeSystem, String displayName) { * @param extractComponentIndex The index of the RCMRMT030101UKComponent which houses the EHR Folder. * @return A list of RCMRMT030101UKComponent3. */ - public static List getEhrFolderComponent(RCMRMT030101UKEhrExtract extract, - int extractComponentIndex) { + public static List getEhrFolderComponents(RCMRMT030101UKEhrExtract extract, + int extractComponentIndex) { final RCMRMT030101UKEhrFolder targetFolder = extract .getComponent() .get(extractComponentIndex) diff --git a/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationCheckerTest.java b/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationCheckerTest.java index 78ec40488..05afd3bb6 100644 --- a/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationCheckerTest.java +++ b/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationCheckerTest.java @@ -21,7 +21,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; import static org.mockito.Mockito.when; -import static uk.nhs.adaptors.pss.translator.TestUtility.getEhrFolderComponent; +import static uk.nhs.adaptors.pss.translator.TestUtility.getEhrFolderComponents; import static uk.nhs.adaptors.pss.translator.util.XmlUnmarshallUtil.unmarshallFile; @ExtendWith(MockitoExtension.class) @@ -85,7 +85,7 @@ void When_IsObservationStatementImmunization_With_ImmunizationCodeAndNonImmuniza private RCMRMT030101UKObservationStatement getObservationStatementFromExtract(String filename) throws JAXBException { final RCMRMT030101UKEhrExtract ehrExtract = getEhrExtractFromFile(filename); - final List components = getEhrFolderComponent(ehrExtract, 0); + final List components = getEhrFolderComponents(ehrExtract, 0); return components.getFirst() .getEhrComposition() From a0a14c5773c61138f87ccd439eb2ee1cbb186d72 Mon Sep 17 00:00:00 2001 From: martin-nhs <127403254+martin-nhs@users.noreply.github.com> Date: Fri, 9 Aug 2024 16:39:27 +0100 Subject: [PATCH 15/20] [NIAD-3148] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d91be773..9cd05aacb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,9 @@ corresponding FHIR resource will now be [appropriately populated][nopat-docs]. corresponding FHIR resource will now be [appropriately populated][nopat-docs]. * If a `bloodPressure` record includes a `confidentialityCode`, the `meta.security` field of the corresponding FHIR resource will now be [appropriately populated][nopat-docs]. +* Fixed bug where the PS adaptor would incorrectly map an immunization to observation, +the adaptor now checks if the Snomed CT ID against the Concept ID and the Description ID +if a match is found, it is an immunization. ### Fixed * Resolved issue where the SNOMED import script would reject a password containing a '%' character. From d0033c8e34380be169b65674c0bf5df719c0bc83 Mon Sep 17 00:00:00 2001 From: martin-nhs <127403254+martin-nhs@users.noreply.github.com> Date: Fri, 9 Aug 2024 16:41:17 +0100 Subject: [PATCH 16/20] [NIAD-3148] Update CHANGELOG.md --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cd05aacb..32d89a31d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,9 +20,9 @@ corresponding FHIR resource will now be [appropriately populated][nopat-docs]. corresponding FHIR resource will now be [appropriately populated][nopat-docs]. * If a `bloodPressure` record includes a `confidentialityCode`, the `meta.security` field of the corresponding FHIR resource will now be [appropriately populated][nopat-docs]. -* Fixed bug where the PS adaptor would incorrectly map an immunization to observation, -the adaptor now checks if the Snomed CT ID against the Concept ID and the Description ID -if a match is found, it is an immunization. +* Addressed a bug in the PS adaptor where immunizations were incorrectly mapped to observations. +The adaptor now verifies the Snomed CT ID against both the Concept ID and the Description ID, ensuring +that immunizations are correctly identified when a match is found. ### Fixed * Resolved issue where the SNOMED import script would reject a password containing a '%' character. From d00968d9acdfc77bad09df42e4ec9efa674a17e7 Mon Sep 17 00:00:00 2001 From: martin-nhs <127403254+martin-nhs@users.noreply.github.com> Date: Mon, 12 Aug 2024 10:09:24 +0100 Subject: [PATCH 17/20] [NIAD-3148] Address PR comment https://github.com/NHSDigital/nia-patient-switching-standard-adaptor/pull/752#discussion_r1712639550 --- .../mapper/ImmunizationSnomedCTMapper.java | 6 ++++-- .../connector/model/ImmunizationSnomedCT.java | 2 +- .../select_immunization_concept_id.sql | 2 +- .../verify_immunizations_loaded.sql | 4 ++-- .../util/DatabaseImmunizationCheckerTest.java | 4 ++-- .../create-database-postgres.sql | 15 +++++++++------ 6 files changed, 19 insertions(+), 14 deletions(-) diff --git a/db-connector/src/main/java/uk/nhs/adaptors/connector/mapper/ImmunizationSnomedCTMapper.java b/db-connector/src/main/java/uk/nhs/adaptors/connector/mapper/ImmunizationSnomedCTMapper.java index def9d215c..317e0f215 100644 --- a/db-connector/src/main/java/uk/nhs/adaptors/connector/mapper/ImmunizationSnomedCTMapper.java +++ b/db-connector/src/main/java/uk/nhs/adaptors/connector/mapper/ImmunizationSnomedCTMapper.java @@ -11,10 +11,12 @@ @Component public class ImmunizationSnomedCTMapper implements RowMapper { + private static final String COLUMN_NAME = "concept_and_description_ids"; + @Override public ImmunizationSnomedCT map(ResultSet rs, StatementContext ctx) throws SQLException { return ImmunizationSnomedCT.builder() - .conceptId(rs.getString("conceptId")) + .snomedId(rs.getString(COLUMN_NAME)) .build(); } -} +} \ No newline at end of file diff --git a/db-connector/src/main/java/uk/nhs/adaptors/connector/model/ImmunizationSnomedCT.java b/db-connector/src/main/java/uk/nhs/adaptors/connector/model/ImmunizationSnomedCT.java index ccfae59b5..e696a2aa3 100644 --- a/db-connector/src/main/java/uk/nhs/adaptors/connector/model/ImmunizationSnomedCT.java +++ b/db-connector/src/main/java/uk/nhs/adaptors/connector/model/ImmunizationSnomedCT.java @@ -8,5 +8,5 @@ @Setter @Builder public class ImmunizationSnomedCT { - private String conceptId; + private String snomedId; } \ No newline at end of file diff --git a/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/select_immunization_concept_id.sql b/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/select_immunization_concept_id.sql index 7c4147bef..57bacec82 100644 --- a/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/select_immunization_concept_id.sql +++ b/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/select_immunization_concept_id.sql @@ -1 +1 @@ -SELECT i.conceptid FROM "snomedct".immunization_codes i WHERE conceptid = :snomedId OR descriptionid = :snomedId; \ No newline at end of file +SELECT i.concept_and_description_ids FROM "snomedct".immunization_codes i WHERE i.concept_and_description_ids = :snomedId; \ No newline at end of file diff --git a/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/verify_immunizations_loaded.sql b/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/verify_immunizations_loaded.sql index b84e5d90e..ff2c75939 100644 --- a/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/verify_immunizations_loaded.sql +++ b/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/verify_immunizations_loaded.sql @@ -1,9 +1,9 @@ -- the conceptIds being checked for below represent the immunization root codes and those immunization codes outside -- of the root code hierarchy, as described in the snomed-database-loader README.md file -SELECT COUNT(DISTINCT i.conceptid) = 16 -- total number of codes +SELECT COUNT(DISTINCT i.concept_and_description_ids) = 16 -- total number of codes FROM "snomedct".immunization_codes i -WHERE i.conceptid IN ( +WHERE i.concept_and_description_ids IN ( '787859002', '127785005', '304250009', '90351000119108','713404003','2997511000001102', '308101000000104','1036721000000101', '1373691000000102', '945831000000105', '542931000000103', '735981009', '90640007', '571631000119106', '764141000000106', '170399005' diff --git a/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationCheckerTest.java b/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationCheckerTest.java index 05afd3bb6..43fda4050 100644 --- a/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationCheckerTest.java +++ b/gp2gp-translator/src/test/java/uk/nhs/adaptors/pss/translator/util/DatabaseImmunizationCheckerTest.java @@ -43,7 +43,7 @@ void When_IsObservationStatementImmunization_With_ImmunizationCode_Expect_True() final RCMRMT030101UKObservationStatement observationStatement = getObservationStatementFromExtract( "full_valid_immunization_with_no_translation.xml"); final ImmunizationSnomedCT immunizationSnomedCT = ImmunizationSnomedCT.builder() - .conceptId(expectedCode) + .snomedId(expectedCode) .build(); when(immunizationSnomedCTDao.getImmunizationSnomedUsingConceptOrDescriptionId( @@ -67,7 +67,7 @@ void When_IsObservationStatementImmunization_With_ImmunizationCodeAndNonImmuniza ); final ImmunizationSnomedCT immunizationSnomedCT = ImmunizationSnomedCT.builder() - .conceptId(snomedCode) + .snomedId(snomedCode) .build(); when(immunizationSnomedCTDao.getImmunizationSnomedUsingConceptOrDescriptionId( diff --git a/snomed-database-loader/create-database-postgres.sql b/snomed-database-loader/create-database-postgres.sql index 6b6dd0b2e..3fc9099bf 100644 --- a/snomed-database-loader/create-database-postgres.sql +++ b/snomed-database-loader/create-database-postgres.sql @@ -56,12 +56,12 @@ WITH RECURSIVE immunization_heirarchy AS ( SELECT DISTINCT sourceId AS conceptId FROM snomedct.relationship_s WHERE typeId = '116680003' -- relationshipType (typeId) = 'IsA' (meaning child of) - AND ( - -- these are the root conceptIds - destinationId IN ('787859002','127785005','304250009','90351000119108','713404003') + AND ( + -- these are the root conceptIds + destinationId IN ('787859002','127785005','304250009','90351000119108','713404003') OR -- ensure the original root conceptIds are also included - sourceId IN ('787859002','127785005','304250009','90351000119108','713404003')) + sourceId IN ('787859002','127785005','304250009','90351000119108','713404003')) UNION -- Recursively find child records -- if no records are found then the maximum depth for this recursion has been reached @@ -70,12 +70,15 @@ WITH RECURSIVE immunization_heirarchy AS ( JOIN immunization_heirarchy i ON r.destinationId = i.conceptId WHERE r.typeId = '116680003' -- relationshipType (typeId) is 'IsA' (child of) ) -SELECT ih.conceptId, ds.id as descriptionid +SELECT ih.conceptId as concept_and_description_ids +FROM immunization_heirarchy ih +UNION ALL +SELECT ds.id FROM immunization_heirarchy ih JOIN snomedct.description_s ds on ih.conceptId = ds.conceptid; CREATE INDEX immunization_codes_conceptid_idx ON immunization_codes - USING btree (conceptid); + USING btree (concept_and_description_ids); CREATE MATERIALIZED VIEW preferred_terms AS SELECT d.id, d.conceptid, d.term, d.active From d7c8d10a5d1bfc785031cd18763b984177e85810 Mon Sep 17 00:00:00 2001 From: martin-nhs <127403254+martin-nhs@users.noreply.github.com> Date: Mon, 12 Aug 2024 10:15:44 +0100 Subject: [PATCH 18/20] [NIAD-3148] Address PR comment https://github.com/NHSDigital/nia-patient-switching-standard-adaptor/pull/752#discussion_r1712639550 --- snomed-database-loader/test-load-immunization-codes.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snomed-database-loader/test-load-immunization-codes.sh b/snomed-database-loader/test-load-immunization-codes.sh index 4175bc282..7548ff6fc 100755 --- a/snomed-database-loader/test-load-immunization-codes.sh +++ b/snomed-database-loader/test-load-immunization-codes.sh @@ -38,7 +38,7 @@ databaseUri="postgresql://${PS_DB_OWNER_NAME}:${POSTGRES_PASSWORD}@${PS_DB_HOST} function checkImmunizationCodesAreLoaded() { for immunizationCode; do - count=$(psql "${databaseUri}" -t -A -c "SELECT COUNT(DISTINCT conceptId) FROM ${snomedCtSchema}.immunization_codes WHERE conceptId ='${immunizationCode}'") + count=$(psql "${databaseUri}" -t -A -c "SELECT COUNT(DISTINCT concept_and_description_ids) FROM ${snomedCtSchema}.immunization_codes WHERE concept_and_description_ids ='${immunizationCode}'") if [ "${count}" != 1 ] then echo "immunization code not loaded: ${immunizationCode}" From 6f65eb26c14776c809ac50d78d808bcd2f353fa9 Mon Sep 17 00:00:00 2001 From: martin-nhs <127403254+martin-nhs@users.noreply.github.com> Date: Mon, 12 Aug 2024 10:24:02 +0100 Subject: [PATCH 19/20] [NIAD-3148] Changed test-load-immunization-codes.sh, now if a given environment variable is not present, it will display a summary of all variables not present, saving time. --- .../test-load-immunization-codes.sh | 30 +++++-------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/snomed-database-loader/test-load-immunization-codes.sh b/snomed-database-loader/test-load-immunization-codes.sh index 7548ff6fc..9e2730251 100755 --- a/snomed-database-loader/test-load-immunization-codes.sh +++ b/snomed-database-loader/test-load-immunization-codes.sh @@ -8,29 +8,13 @@ rootImmunizationCodes=('787859002' '127785005' '304250009' '90351000119108' '713 childImmunizationCodes=('2997511000001102' '308101000000104' '1036721000000101' '1373691000000102' '945831000000105') immunizationCodesNotInImmunizationHierarchy=('542931000000103' '735981009' '90640007' '571631000119106' '764141000000106' '170399005' ) - -if [ -z ${PS_DB_OWNER_NAME} ] -then - echo "Please set the following env var: PS_DB_OWNER_NAME, e.g. \"export PS_DB_OWNER_NAME='postgres'\"" - exit 1 -fi - -if [ -z ${PS_DB_HOST} ] -then - echo "Please set the following env var: PS_DB_HOST, e.g. \"export PS_DB_HOST='localhost'\"" - exit 1 -fi - -if [ -z ${PS_DB_PORT} ] -then - echo "Please set the following env var: PS_DB_PORT, e.g. \"export PS_DB_PORT='5432'\"" - exit 1 -fi - -if [ -z ${POSTGRES_PASSWORD} ] -then - echo "Please set the following env var: POSTGRES_PASSWORD, e.g. \"export POSTGRES_PASSWORD='********'\"" - exit 1 +if [ -z ${PS_DB_OWNER_NAME} ] || [ -z ${PS_DB_HOST} ] || [ -z ${PS_DB_PORT} ] || [ -z ${POSTGRES_PASSWORD} ]; then + echo "The following environment variables are required for this script:" + [ -z ${PS_DB_OWNER_NAME} ] && echo "> PS_DB_OWNER_NAME, e.g. \"export PS_DB_OWNER_NAME='postgres'\"" + [ -z ${PS_DB_HOST} ] && echo "> PS_DB_HOST, e.g. \"export PS_DB_HOST='localhost'\"" + [ -z ${PS_DB_PORT} ] && echo "> PS_DB_PORT, e.g. \"export PS_DB_PORT='5432'\"" + [ -z ${POSTGRES_PASSWORD} ] && echo "> POSTGRES_PASSWORD, e.g. \"export POSTGRES_PASSWORD='********'\"" + exit 1 fi databaseUri="postgresql://${PS_DB_OWNER_NAME}:${POSTGRES_PASSWORD}@${PS_DB_HOST}:${PS_DB_PORT}/${dbName}" From 7dbe0372b39b448705c23ba222a794956c190ee5 Mon Sep 17 00:00:00 2001 From: martin-nhs <127403254+martin-nhs@users.noreply.github.com> Date: Mon, 12 Aug 2024 12:48:48 +0100 Subject: [PATCH 20/20] [NIAD-3148] Address Adrian's PR comment regarding name change --- .../connector/mapper/ImmunizationSnomedCTMapper.java | 5 +++-- .../select_immunization_concept_id.sql | 2 +- .../ImmunizationSnomedCTDao/verify_immunizations_loaded.sql | 4 ++-- snomed-database-loader/create-database-postgres.sql | 4 ++-- snomed-database-loader/test-load-immunization-codes.sh | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/db-connector/src/main/java/uk/nhs/adaptors/connector/mapper/ImmunizationSnomedCTMapper.java b/db-connector/src/main/java/uk/nhs/adaptors/connector/mapper/ImmunizationSnomedCTMapper.java index 317e0f215..4aa889f66 100644 --- a/db-connector/src/main/java/uk/nhs/adaptors/connector/mapper/ImmunizationSnomedCTMapper.java +++ b/db-connector/src/main/java/uk/nhs/adaptors/connector/mapper/ImmunizationSnomedCTMapper.java @@ -11,12 +11,13 @@ @Component public class ImmunizationSnomedCTMapper implements RowMapper { - private static final String COLUMN_NAME = "concept_and_description_ids"; + private static final String COLUMN_NAME = "concept_or_description_id"; @Override public ImmunizationSnomedCT map(ResultSet rs, StatementContext ctx) throws SQLException { + final String conceptOrDescriptionId = rs.getString(COLUMN_NAME); return ImmunizationSnomedCT.builder() - .snomedId(rs.getString(COLUMN_NAME)) + .snomedId(conceptOrDescriptionId) .build(); } } \ No newline at end of file diff --git a/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/select_immunization_concept_id.sql b/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/select_immunization_concept_id.sql index 57bacec82..8269f3afb 100644 --- a/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/select_immunization_concept_id.sql +++ b/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/select_immunization_concept_id.sql @@ -1 +1 @@ -SELECT i.concept_and_description_ids FROM "snomedct".immunization_codes i WHERE i.concept_and_description_ids = :snomedId; \ No newline at end of file +SELECT i.concept_or_description_id FROM "snomedct".immunization_codes i WHERE i.concept_or_description_id = :snomedId; \ No newline at end of file diff --git a/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/verify_immunizations_loaded.sql b/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/verify_immunizations_loaded.sql index ff2c75939..9800a657c 100644 --- a/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/verify_immunizations_loaded.sql +++ b/db-connector/src/main/resources/uk/nhs/adaptors/connector/dao/ImmunizationSnomedCTDao/verify_immunizations_loaded.sql @@ -1,9 +1,9 @@ -- the conceptIds being checked for below represent the immunization root codes and those immunization codes outside -- of the root code hierarchy, as described in the snomed-database-loader README.md file -SELECT COUNT(DISTINCT i.concept_and_description_ids) = 16 -- total number of codes +SELECT COUNT(DISTINCT i.concept_or_description_id) = 16 -- total number of codes FROM "snomedct".immunization_codes i -WHERE i.concept_and_description_ids IN ( +WHERE i.concept_or_description_id IN ( '787859002', '127785005', '304250009', '90351000119108','713404003','2997511000001102', '308101000000104','1036721000000101', '1373691000000102', '945831000000105', '542931000000103', '735981009', '90640007', '571631000119106', '764141000000106', '170399005' diff --git a/snomed-database-loader/create-database-postgres.sql b/snomed-database-loader/create-database-postgres.sql index 3fc9099bf..538af7d21 100644 --- a/snomed-database-loader/create-database-postgres.sql +++ b/snomed-database-loader/create-database-postgres.sql @@ -70,7 +70,7 @@ WITH RECURSIVE immunization_heirarchy AS ( JOIN immunization_heirarchy i ON r.destinationId = i.conceptId WHERE r.typeId = '116680003' -- relationshipType (typeId) is 'IsA' (child of) ) -SELECT ih.conceptId as concept_and_description_ids +SELECT ih.conceptId as concept_or_description_id FROM immunization_heirarchy ih UNION ALL SELECT ds.id @@ -78,7 +78,7 @@ FROM immunization_heirarchy ih JOIN snomedct.description_s ds on ih.conceptId = ds.conceptid; CREATE INDEX immunization_codes_conceptid_idx ON immunization_codes - USING btree (concept_and_description_ids); + USING btree (concept_or_description_id); CREATE MATERIALIZED VIEW preferred_terms AS SELECT d.id, d.conceptid, d.term, d.active diff --git a/snomed-database-loader/test-load-immunization-codes.sh b/snomed-database-loader/test-load-immunization-codes.sh index 9e2730251..b4ec6ca1e 100755 --- a/snomed-database-loader/test-load-immunization-codes.sh +++ b/snomed-database-loader/test-load-immunization-codes.sh @@ -22,7 +22,7 @@ databaseUri="postgresql://${PS_DB_OWNER_NAME}:${POSTGRES_PASSWORD}@${PS_DB_HOST} function checkImmunizationCodesAreLoaded() { for immunizationCode; do - count=$(psql "${databaseUri}" -t -A -c "SELECT COUNT(DISTINCT concept_and_description_ids) FROM ${snomedCtSchema}.immunization_codes WHERE concept_and_description_ids ='${immunizationCode}'") + count=$(psql "${databaseUri}" -t -A -c "SELECT COUNT(DISTINCT concept_or_description_id) FROM ${snomedCtSchema}.immunization_codes WHERE concept_or_description_id ='${immunizationCode}'") if [ "${count}" != 1 ] then echo "immunization code not loaded: ${immunizationCode}"