From c7199cf746962fce83e3c015556c488b010378b1 Mon Sep 17 00:00:00 2001 From: Siva Reddy Date: Wed, 12 Jul 2023 12:31:44 +0530 Subject: [PATCH 01/47] Incrementing development version to 1.2.0-SNAPSHOT (#220) --- admin/pom.xml | 2 +- bahmni-emr-api/pom.xml | 2 +- bahmni-mapping/pom.xml | 2 +- bahmni-test-commons/pom.xml | 2 +- bahmnicore-api/pom.xml | 2 +- bahmnicore-omod/pom.xml | 2 +- bahmnicore-ui/pom.xml | 2 +- obs-relation/pom.xml | 2 +- openmrs-elis-atomfeed-client-omod/pom.xml | 2 +- pom.xml | 2 +- reference-data/api/pom.xml | 2 +- reference-data/omod/pom.xml | 2 +- reference-data/pom.xml | 2 +- vagrant-deploy/pom.xml | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/admin/pom.xml b/admin/pom.xml index 5d0b1f918e..66185a5bf6 100644 --- a/admin/pom.xml +++ b/admin/pom.xml @@ -5,7 +5,7 @@ bahmni org.bahmni.module - 1.1.0 + 1.2.0-SNAPSHOT admin diff --git a/bahmni-emr-api/pom.xml b/bahmni-emr-api/pom.xml index 07b54b23a3..65f185b134 100644 --- a/bahmni-emr-api/pom.xml +++ b/bahmni-emr-api/pom.xml @@ -5,7 +5,7 @@ bahmni org.bahmni.module - 1.1.0 + 1.2.0-SNAPSHOT 4.0.0 diff --git a/bahmni-mapping/pom.xml b/bahmni-mapping/pom.xml index 088608dea3..0625d9428d 100644 --- a/bahmni-mapping/pom.xml +++ b/bahmni-mapping/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.1.0 + 1.2.0-SNAPSHOT bahmni-mapping jar diff --git a/bahmni-test-commons/pom.xml b/bahmni-test-commons/pom.xml index 66d9eebd93..a65be4f4ae 100644 --- a/bahmni-test-commons/pom.xml +++ b/bahmni-test-commons/pom.xml @@ -14,7 +14,7 @@ bahmni org.bahmni.module - 1.1.0 + 1.2.0-SNAPSHOT diff --git a/bahmnicore-api/pom.xml b/bahmnicore-api/pom.xml index 10091dd454..2b447e3a7e 100644 --- a/bahmnicore-api/pom.xml +++ b/bahmnicore-api/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.1.0 + 1.2.0-SNAPSHOT bahmnicore-api jar diff --git a/bahmnicore-omod/pom.xml b/bahmnicore-omod/pom.xml index 41093c9f8a..d987a02bc7 100644 --- a/bahmnicore-omod/pom.xml +++ b/bahmnicore-omod/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.1.0 + 1.2.0-SNAPSHOT bahmnicore-omod jar diff --git a/bahmnicore-ui/pom.xml b/bahmnicore-ui/pom.xml index e36464d61e..c43c0c1438 100644 --- a/bahmnicore-ui/pom.xml +++ b/bahmnicore-ui/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.1.0 + 1.2.0-SNAPSHOT bahmnicore-ui jar diff --git a/obs-relation/pom.xml b/obs-relation/pom.xml index 01e9ea70cb..959203f92d 100644 --- a/obs-relation/pom.xml +++ b/obs-relation/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.1.0 + 1.2.0-SNAPSHOT obs-relationship jar diff --git a/openmrs-elis-atomfeed-client-omod/pom.xml b/openmrs-elis-atomfeed-client-omod/pom.xml index 975310a6f0..bf1ac4e8b1 100644 --- a/openmrs-elis-atomfeed-client-omod/pom.xml +++ b/openmrs-elis-atomfeed-client-omod/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.1.0 + 1.2.0-SNAPSHOT openelis-atomfeed-client-omod jar diff --git a/pom.xml b/pom.xml index 60c9313938..6f197a3bc3 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.1.0 + 1.2.0-SNAPSHOT pom Bahmni EMR Core https://github.com/Bahmni/bahmni-core.git diff --git a/reference-data/api/pom.xml b/reference-data/api/pom.xml index 70230b80bd..dccf8ecc3e 100644 --- a/reference-data/api/pom.xml +++ b/reference-data/api/pom.xml @@ -5,7 +5,7 @@ reference-data org.bahmni.module - 1.1.0 + 1.2.0-SNAPSHOT 4.0.0 diff --git a/reference-data/omod/pom.xml b/reference-data/omod/pom.xml index ed63d5ff79..3d7a3df678 100644 --- a/reference-data/omod/pom.xml +++ b/reference-data/omod/pom.xml @@ -5,7 +5,7 @@ reference-data org.bahmni.module - 1.1.0 + 1.2.0-SNAPSHOT 4.0.0 diff --git a/reference-data/pom.xml b/reference-data/pom.xml index 0a68cb93e9..c7e84fd69c 100644 --- a/reference-data/pom.xml +++ b/reference-data/pom.xml @@ -10,7 +10,7 @@ org.bahmni.module bahmni - 1.1.0 + 1.2.0-SNAPSHOT reference-data pom diff --git a/vagrant-deploy/pom.xml b/vagrant-deploy/pom.xml index ce9267d4c4..5b8d62805b 100644 --- a/vagrant-deploy/pom.xml +++ b/vagrant-deploy/pom.xml @@ -5,7 +5,7 @@ bahmni org.bahmni.module - 1.1.0 + 1.2.0-SNAPSHOT 4.0.0 From 4258998e103ced043a24fbfe0f2f06d3c0bda9ae Mon Sep 17 00:00:00 2001 From: Siva Reddy Date: Wed, 12 Jul 2023 14:34:04 +0530 Subject: [PATCH 02/47] Siva Reddy | Removing Packaging of lombok dependency (#211) --- pom.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 6f197a3bc3..bb00381821 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ 1.32.0 1.5.0 2.6.2 - 1.16.0 + 1.18.20 4.7.0 1.13.0 1.1.0 @@ -586,7 +586,8 @@ org.projectlombok lombok - 1.18.20 + ${lombokVersion} + provided From 0aa400132f92dc9ecd5204fbed73389beb3b1096 Mon Sep 17 00:00:00 2001 From: Siva Reddy Date: Wed, 12 Jul 2023 23:18:23 +0530 Subject: [PATCH 03/47] BS-91 | Merge snomed-master to product master (#212) * BS-68 | Create new REST endpoint for Diagnosis Search (#175) * BS-68 | Siva Reddy | Create New Rest End Point for Diagnosis Search * BS-68 | Siva Reddy | Adding Test Cases for New Rest End Point * BS-68 | Siva Reddy | Updating Global Proerty Name * BS-68 | Siva Reddy | Adding terminology services dependency * BS-68 | Siva Reddy | Updated Rest End Point for Diagnosis Search * BS-68 | Siva Reddy | Publishing SNOMED specific Bahmnicore OMOD * BS-68 | Siva Reddy | Updated Dependencies from terminology services module * Siva Reddy | BS-68 | Updating Rest End Point, TS module dependencies * Siva Reddy | BS-68 | Update Package of FHIR TS module * Siva Reddy | BS-42 | deployment to SNOMED Environment (#183) * Siva Reddy | BS-7 | Diagnosis Save (#189) * Siva Reddy | BS-7 | Changes for saving a concept * Siva Reddy | BS-7 | Tests for Diagnosis Concept Presave Command * Siva Reddy | BS-7 | Support for multiple locales * Siva Reddy | BS-7 | Updating artefact name * Siva Reddy | BS-7 | Minor code fixes * Siva Reddy | BS-7 | Incorporating PR comments * Bs 84 remove imp (#208) * BS-68 | Create new REST endpoint for Diagnosis Search (#175) * BS-68 | Siva Reddy | Create New Rest End Point for Diagnosis Search * BS-68 | Siva Reddy | Adding Test Cases for New Rest End Point * BS-68 | Siva Reddy | Updating Global Proerty Name * BS-68 | Siva Reddy | Adding terminology services dependency * BS-68 | Siva Reddy | Updated Rest End Point for Diagnosis Search * BS-68 | Siva Reddy | Publishing SNOMED specific Bahmnicore OMOD * BS-68 | Siva Reddy | Updated Dependencies from terminology services module * Siva Reddy | BS-68 | Updating Rest End Point, TS module dependencies * Siva Reddy | BS-68 | Update Package of FHIR TS module * Siva Reddy | BS-42 | deployment to SNOMED Environment (#183) * Siva Reddy | BS-7 | Diagnosis Save (#189) * Siva Reddy | BS-7 | Changes for saving a concept * Siva Reddy | BS-7 | Tests for Diagnosis Concept Presave Command * Siva Reddy | BS-7 | Support for multiple locales * Siva Reddy | BS-7 | Updating artefact name * Siva Reddy | BS-7 | Minor code fixes * Siva Reddy | BS-7 | Incorporating PR comments * Bs-34 | removed all fhirterminody api and omod reference * Bs-84 | added required bean definition and remove component scan * Bs-34 | updated controller test cases * Bs-34 | removed fhir required module * Bs-34 | removed dependencies of fhirterminology services * Bs-34 | added test cases --------- Co-authored-by: Siva Reddy * Siva Reddy | Removed unused dependencies (#210) * BS-91 | Siva Reddy | Revert bahmnicore api,omod artefact names to merge into product master --------- Co-authored-by: manimaarans <110804183+manimaarans@users.noreply.github.com> --- bahmni-emr-api/pom.xml | 6 + .../service/BahmniDiagnosisService.java | 9 ++ .../service/TsConceptSearchService.java | 12 ++ .../impl/BahmniDiagnosisServiceImpl.java | 29 +++- .../impl/TsConceptSearchServiceImpl.java | 129 ++++++++++++++++++ .../resources/moduleApplicationContext.xml | 63 +++++++++ .../impl/BahmniDiagnosisServiceImplTest.java | 33 ++++- .../impl/TsConceptSearchServiceImplTest.java | 88 ++++++++++++ .../BahmniConceptSearchController.java | 35 +++++ bahmnicore-omod/src/main/resources/config.xml | 16 ++- .../BahmniConceptSearchControllerTest.java | 92 +++++++++++++ 11 files changed, 503 insertions(+), 9 deletions(-) create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/TsConceptSearchService.java create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/TsConceptSearchServiceImpl.java create mode 100644 bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/TsConceptSearchServiceImplTest.java create mode 100644 bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniConceptSearchController.java create mode 100644 bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniConceptSearchControllerTest.java diff --git a/bahmni-emr-api/pom.xml b/bahmni-emr-api/pom.xml index 65f185b134..77df76dc48 100644 --- a/bahmni-emr-api/pom.xml +++ b/bahmni-emr-api/pom.xml @@ -68,6 +68,12 @@ org.bahmni.module bahmni-commons-api + + org.openmrs.module + webservices.rest-omod-common + ${openMRSWebServicesVersion} + test + org.openmrs.web openmrs-web diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniDiagnosisService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniDiagnosisService.java index fa0b3845fa..3a2497ccfb 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniDiagnosisService.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniDiagnosisService.java @@ -1,12 +1,21 @@ package org.bahmni.module.bahmnicore.service; +import org.openmrs.Concept; +import org.openmrs.ConceptSource; import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; import java.text.ParseException; +import java.util.Collection; import java.util.List; public interface BahmniDiagnosisService { void delete(String diagnosisObservationUuid); List getBahmniDiagnosisByPatientAndVisit(String patientUuid,String visitUuid); List getBahmniDiagnosisByPatientAndDate(String patientUuid, String date) throws ParseException; + + boolean isExternalTerminologyServerLookupNeeded(); + + Collection getDiagnosisSets(); + + List getConceptSourcesForDiagnosisSearch(); } diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/TsConceptSearchService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/TsConceptSearchService.java new file mode 100644 index 0000000000..085da4c723 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/TsConceptSearchService.java @@ -0,0 +1,12 @@ +package org.bahmni.module.bahmnicore.service; + +import org.openmrs.annotation.Authorized; +import org.openmrs.api.OpenmrsService; +import org.openmrs.module.webservices.rest.SimpleObject; + +import java.util.List; + +public interface TsConceptSearchService extends OpenmrsService { + @Authorized(value = {"Get Concepts"}) + List getConcepts(String query, Integer limit, String locale); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniDiagnosisServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniDiagnosisServiceImpl.java index 58fb31a996..d5c19eb7ce 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniDiagnosisServiceImpl.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniDiagnosisServiceImpl.java @@ -1,12 +1,15 @@ package org.bahmni.module.bahmnicore.service.impl; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; import org.bahmni.module.bahmnicore.service.BahmniDiagnosisService; import org.openmrs.Concept; +import org.openmrs.ConceptSource; import org.openmrs.Obs; import org.openmrs.Patient; import org.openmrs.Person; import org.openmrs.Visit; +import org.openmrs.api.AdministrationService; import org.openmrs.api.ConceptService; import org.openmrs.api.EncounterService; import org.openmrs.api.ObsService; @@ -21,6 +24,7 @@ import org.openmrs.module.emrapi.encounter.DiagnosisMapper; import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import java.text.ParseException; @@ -32,8 +36,11 @@ import java.util.Iterator; import java.util.List; -@Component public class BahmniDiagnosisServiceImpl implements BahmniDiagnosisService { + + private static final String BAHMNI_EXTERNAL_TERMINOLOGY_SERVER_LOOKUP_NEEDED = "bahmni.lookupExternalTerminologyServer"; + private static final boolean DEFAULT_EXTERNAL_TERMINOLOGY_SERVER_LOOKUP_NEEDED = false; + private EncounterService encounterService; private ObsService obsService; private VisitService visitService; @@ -42,9 +49,10 @@ public class BahmniDiagnosisServiceImpl implements BahmniDiagnosisService { private BahmniDiagnosisMetadata bahmniDiagnosisMetadata; private ConceptService conceptService; private EmrApiProperties emrApiProperties; + private AdministrationService administrationService; @Autowired - public BahmniDiagnosisServiceImpl(EncounterService encounterService, ObsService obsService, VisitService visitService, PatientService patientService, DiagnosisMapper diagnosisMapper, BahmniDiagnosisMetadata bahmniDiagnosisMetadata, ConceptService conceptService, EmrApiProperties emrApiProperties) { + public BahmniDiagnosisServiceImpl(EncounterService encounterService, ObsService obsService, VisitService visitService, PatientService patientService, DiagnosisMapper diagnosisMapper, BahmniDiagnosisMetadata bahmniDiagnosisMetadata, ConceptService conceptService, EmrApiProperties emrApiProperties, @Qualifier("adminService") AdministrationService administrationService) { this.encounterService = encounterService; this.obsService = obsService; this.visitService = visitService; @@ -53,6 +61,7 @@ public BahmniDiagnosisServiceImpl(EncounterService encounterService, ObsService this.bahmniDiagnosisMetadata = bahmniDiagnosisMetadata; this.conceptService = conceptService; this.emrApiProperties = emrApiProperties; + this.administrationService = administrationService; } @Override @@ -201,4 +210,20 @@ private void voidObsAndItsChildren(Obs obs) { voidObsAndItsChildren(childObs); } } + + @Override + public boolean isExternalTerminologyServerLookupNeeded() { + String externalTSLookupNeeded = administrationService.getGlobalProperty(BAHMNI_EXTERNAL_TERMINOLOGY_SERVER_LOOKUP_NEEDED); + return StringUtils.isNotBlank(externalTSLookupNeeded) ? Boolean.valueOf(externalTSLookupNeeded) : DEFAULT_EXTERNAL_TERMINOLOGY_SERVER_LOOKUP_NEEDED; + } + + @Override + public Collection getDiagnosisSets() { + return emrApiProperties.getDiagnosisSets(); + } + + @Override + public List getConceptSourcesForDiagnosisSearch() { + return emrApiProperties.getConceptSourcesForDiagnosisSearch(); + } } diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/TsConceptSearchServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/TsConceptSearchServiceImpl.java new file mode 100644 index 0000000000..ed4d7ee11a --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/TsConceptSearchServiceImpl.java @@ -0,0 +1,129 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.apache.commons.lang3.LocaleUtils; +import org.bahmni.module.bahmnicore.service.BahmniDiagnosisService; +import org.bahmni.module.bahmnicore.service.TsConceptSearchService; +import org.openmrs.Concept; +import org.openmrs.ConceptMap; +import org.openmrs.ConceptName; +import org.openmrs.ConceptReferenceTerm; +import org.openmrs.ConceptSearchResult; +import org.openmrs.ConceptSource; +import org.openmrs.api.context.Context; +import org.openmrs.module.emrapi.concept.EmrConceptService; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.util.LocaleUtility; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Set; + +public class TsConceptSearchServiceImpl implements TsConceptSearchService { + private BahmniDiagnosisService bahmniDiagnosisService; + + private EmrConceptService emrConceptService; + + + @Autowired + public TsConceptSearchServiceImpl(BahmniDiagnosisService bahmniDiagnosisService, EmrConceptService emrConceptService) { + this.bahmniDiagnosisService = bahmniDiagnosisService; + this.emrConceptService = emrConceptService; + } + + @Override + public List getConcepts(String query, Integer limit, String locale) { + boolean externalTerminologyServerLookupNeeded = bahmniDiagnosisService.isExternalTerminologyServerLookupNeeded(); + if (externalTerminologyServerLookupNeeded) { + return new ArrayList<>(); + } else { + return getDiagnosisConcepts(query, limit, locale); + } + } + + private List getDiagnosisConcepts(String query, Integer limit, String locale) { + Collection diagnosisSets = bahmniDiagnosisService.getDiagnosisSets(); + List conceptSources = bahmniDiagnosisService.getConceptSourcesForDiagnosisSearch(); + Locale searchLocale = getSearchLocale(locale); + List conceptSearchResults = + emrConceptService.conceptSearch(query, LocaleUtility.getDefaultLocale(), null, diagnosisSets, conceptSources, limit); + ConceptSource conceptSource = conceptSources.isEmpty() ? null : conceptSources.get(0); + return createListResponse(conceptSearchResults, conceptSource, searchLocale); + } + + private List createListResponse(List resultList, + ConceptSource conceptSource, Locale searchLocale) { + List allDiagnoses = new ArrayList<>(); + + for (ConceptSearchResult diagnosis : resultList) { + SimpleObject diagnosisObject = new SimpleObject(); + ConceptName conceptName = diagnosis.getConcept().getName(searchLocale); + if (conceptName == null) { + conceptName = diagnosis.getConcept().getName(); + } + diagnosisObject.add("conceptName", conceptName.getName()); + diagnosisObject.add("conceptUuid", diagnosis.getConcept().getUuid()); + if (diagnosis.getConceptName() != null) { + diagnosisObject.add("matchedName", diagnosis.getConceptName().getName()); + } + ConceptReferenceTerm term = getConceptReferenceTermByConceptSource(diagnosis.getConcept(), conceptSource); + if (term != null) { + diagnosisObject.add("code", term.getCode()); + } + allDiagnoses.add(diagnosisObject); + } + return allDiagnoses; + } + + private ConceptReferenceTerm getConceptReferenceTermByConceptSource(Concept concept, ConceptSource conceptSource) { + Collection conceptMappings = concept.getConceptMappings(); + if (conceptMappings != null && conceptSource != null) { + for (ConceptMap cm : conceptMappings) { + ConceptReferenceTerm term = cm.getConceptReferenceTerm(); + if (conceptSource.equals(term.getConceptSource())) { + return term; + } + } + } + return null; + } + + private Locale getSearchLocale(String localeStr) { + if (localeStr == null) { + return Context.getLocale(); + } + Locale locale; + try { + locale = LocaleUtils.toLocale(localeStr); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException(localeErrorMessage("emrapi.conceptSearch.invalidLocale", localeStr)); + } + if (allowedLocale(locale)) { + return locale; + } else { + throw new IllegalArgumentException(localeErrorMessage("emrapi.conceptSearch.unsupportedLocale", localeStr)); + } + } + + private boolean allowedLocale(Locale locale) { + Set allowedLocales = new HashSet<>(Context.getAdministrationService().getAllowedLocales()); + return allowedLocales.contains(locale); + } + + private String localeErrorMessage(String msgKey, String localeStr) { + return Context.getMessageSourceService().getMessage(msgKey, new Object[]{localeStr}, Context.getLocale()); + } + + @Override + public void onStartup() { + + } + + @Override + public void onShutdown() { + + } +} diff --git a/bahmnicore-api/src/main/resources/moduleApplicationContext.xml b/bahmnicore-api/src/main/resources/moduleApplicationContext.xml index 050ba579e1..78c1a50cd4 100644 --- a/bahmnicore-api/src/main/resources/moduleApplicationContext.xml +++ b/bahmnicore-api/src/main/resources/moduleApplicationContext.xml @@ -165,4 +165,67 @@ + + + + + org.bahmni.module.bahmnicore.service.TsConceptSearchService + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.bahmni.module.bahmnicore.service.BahmniDiagnosisService + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniDiagnosisServiceImplTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniDiagnosisServiceImplTest.java index 81bf87a96b..1c050d0e3a 100644 --- a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniDiagnosisServiceImplTest.java +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniDiagnosisServiceImplTest.java @@ -9,7 +9,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; -import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.openmrs.Concept; @@ -18,6 +17,7 @@ import org.openmrs.Patient; import org.openmrs.Person; import org.openmrs.Visit; +import org.openmrs.api.AdministrationService; import org.openmrs.api.ConceptService; import org.openmrs.api.EncounterService; import org.openmrs.api.ObsService; @@ -29,9 +29,9 @@ import org.openmrs.module.emrapi.EmrApiProperties; import org.openmrs.module.emrapi.diagnosis.Diagnosis; import org.openmrs.module.emrapi.encounter.DiagnosisMapper; -import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; import org.openmrs.util.LocaleUtility; import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @@ -44,17 +44,17 @@ import java.util.Set; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyList; -import static org.mockito.Mockito.anyListOf; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +@PowerMockIgnore("javax.management.*") @PrepareForTest(LocaleUtility.class) @RunWith(PowerMockRunner.class) public class BahmniDiagnosisServiceImplTest { @@ -75,8 +75,11 @@ public class BahmniDiagnosisServiceImplTest { @Mock private EmrApiProperties emrApiProperties; + @Mock + private AdministrationService administrationService; + @InjectMocks - private BahmniDiagnosisServiceImpl bahmniDiagnosisService = new BahmniDiagnosisServiceImpl(encounterService, obsService, visitService, patientService, diagnosisMapper, bahmniDiagnosisMetadata, conceptService, emrApiProperties); + private BahmniDiagnosisServiceImpl bahmniDiagnosisService = new BahmniDiagnosisServiceImpl(encounterService, obsService, visitService, patientService, diagnosisMapper, bahmniDiagnosisMetadata, conceptService, emrApiProperties, administrationService); private String initialDiagnosisObsUUID = "initialDiagnosisObsUUID"; private String modifiedDiagnosisObsUUID = "modifiedDiagnosisObsUUID"; @@ -92,6 +95,7 @@ public void setUp() throws Exception { PowerMockito.mockStatic(LocaleUtility.class); PowerMockito.when(LocaleUtility.getLocalesInOrder()).thenReturn(new HashSet<>(Arrays.asList(Locale.getDefault()))); + when(administrationService.getGlobalProperty(eq("bahmni.lookupExternalTerminologyServer"))).thenReturn("false"); } @Test @@ -225,6 +229,25 @@ public void shouldReturnEmptyListIfNoVisitFound() throws Exception { assertEquals(0, bahmniDiagnosisRequests.size()); } + @Test + public void shouldReturnFalseWhenNoExternalTerminologyServerLookupNeeded() { + boolean externalTerminologyServerLookupNeeded = bahmniDiagnosisService.isExternalTerminologyServerLookupNeeded(); + assertFalse(externalTerminologyServerLookupNeeded); + } + + @Test + public void shouldReturnTrueWhenExternalTerminologyServerLookupNeeded() { + when(administrationService.getGlobalProperty(eq("bahmni.lookupExternalTerminologyServer"))).thenReturn("TRUE"); + boolean externalTerminologyServerLookupNeeded = bahmniDiagnosisService.isExternalTerminologyServerLookupNeeded(); + assertTrue(externalTerminologyServerLookupNeeded); + } + + @Test + public void shouldCallDiagosisSetofSetsInEmrApiWhenNoExternalTerminologyServerLookupNeeded() { + bahmniDiagnosisService.getDiagnosisSets(); + verify(emrApiProperties, times(1)).getDiagnosisSets(); + } + private Diagnosis getDiagnosis() { Diagnosis diagnosis = new Diagnosis(); Obs diagnosisObs = new DiagnosisBuilder() diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/TsConceptSearchServiceImplTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/TsConceptSearchServiceImplTest.java new file mode 100644 index 0000000000..a577ca7eac --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/TsConceptSearchServiceImplTest.java @@ -0,0 +1,88 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.service.BahmniDiagnosisService; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.ConceptSearchResult; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.openmrs.module.emrapi.concept.EmrConceptService; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.util.LocaleUtility; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +import static org.junit.Assert.*; + + +import static org.mockito.Mockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(Context.class) +@PowerMockIgnore("javax.management.*") +public class TsConceptSearchServiceImplTest { + + + @Mock + BahmniDiagnosisService bahmniDiagnosisService; + @Mock + EmrConceptService emrConceptService; + @InjectMocks + TsConceptSearchServiceImpl tsConceptSearchService; + @Mock + private UserContext userContext; + @Mock + private AdministrationService administrationService; + + String searchTerm = "Malaria"; + int searchLimit = 20; + String locale = LocaleUtility.getDefaultLocale().toString(); + List locales = Collections.singletonList(LocaleUtility.getDefaultLocale()); + @Before + public void setUp() { + PowerMockito.mockStatic(Context.class); + Locale defaultLocale = new Locale("en", "GB"); + when(Context.getLocale()).thenReturn(defaultLocale); + when(Context.getAdministrationService()).thenReturn(administrationService); + when(administrationService.getAllowedLocales()).thenReturn(locales); + } + + @Test + public void shouldReturnEmptyListWhenExternalTerminologyServerLookUpIsEnabled() { + when(bahmniDiagnosisService.isExternalTerminologyServerLookupNeeded()).thenReturn(true); + List diagnosisList = tsConceptSearchService.getConcepts(searchTerm, searchLimit, locale); + assertNotNull(diagnosisList); + assertEquals(0, diagnosisList.size()); + } + @Test + public void shouldReturnListFromEmrConceptServiceWhenExternalTerminologyServerLookUpIsNotEnabled() { + Concept malariaConcept = new Concept(); + ConceptName malariaConceptName = new ConceptName(searchTerm, LocaleUtility.getDefaultLocale()); + String malariaConceptUuid = "uuid1"; + malariaConcept.setUuid(malariaConceptUuid); + malariaConcept.setFullySpecifiedName(malariaConceptName); + malariaConcept.setPreferredName(malariaConceptName); + ConceptSearchResult conceptSearchResult = new ConceptSearchResult(searchTerm, malariaConcept, malariaConceptName); + + when(emrConceptService.conceptSearch(searchTerm, LocaleUtility.getDefaultLocale(), null, Collections.EMPTY_LIST, Collections.EMPTY_LIST, searchLimit)).thenReturn(Collections.singletonList(conceptSearchResult)); + when(bahmniDiagnosisService.isExternalTerminologyServerLookupNeeded()).thenReturn(false); + List diagnosisList = tsConceptSearchService.getConcepts(searchTerm, searchLimit, locale); + assertNotNull(diagnosisList); + assertEquals(1, diagnosisList.size()); + assertEquals(diagnosisList.get(0).get("conceptName"), searchTerm); + assertEquals(diagnosisList.get(0).get("conceptUuid"), malariaConceptUuid); + } + +} \ No newline at end of file diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniConceptSearchController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniConceptSearchController.java new file mode 100644 index 0000000000..81c578e638 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniConceptSearchController.java @@ -0,0 +1,35 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.service.TsConceptSearchService; +import org.bahmni.module.bahmnicore.service.impl.TsConceptSearchServiceImpl; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +import static org.springframework.web.bind.annotation.ValueConstants.DEFAULT_NONE; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmni/terminologies") +public class BahmniConceptSearchController extends BaseRestController { + + private TsConceptSearchService tsConceptSearchService; + + + + @Autowired + public BahmniConceptSearchController(TsConceptSearchService tsConceptSearchService) { + this.tsConceptSearchService = tsConceptSearchService; + } + + @RequestMapping(method = RequestMethod.GET, value = "concepts") + @ResponseBody + public Object search(@RequestParam("term") String query, @RequestParam Integer limit, + @RequestParam(required = false, defaultValue = DEFAULT_NONE) String locale) throws Exception { + return tsConceptSearchService.getConcepts(query, limit, locale); + } +} diff --git a/bahmnicore-omod/src/main/resources/config.xml b/bahmnicore-omod/src/main/resources/config.xml index f8c64188a8..e916179e24 100644 --- a/bahmnicore-omod/src/main/resources/config.xml +++ b/bahmnicore-omod/src/main/resources/config.xml @@ -1,7 +1,7 @@ - + - + @MODULE_ID@ @@ -167,6 +167,12 @@ A list of UUIDs indicating extra Patient Identifier Types that should be displayed + + bahmni.lookupExternalTerminologyServer + false + Property used to determine whether external terminology server being used or not + + bahmni.enableEmailPrescriptionOption false @@ -179,4 +185,10 @@ Enable or disable Groovy script execution for obs value calculation on encounter save + + bahmni.diagnosisSetForNewDiagnosisConcepts + + UUID of set member of diagnosis set of sets. New Diagnosis concepts from terminology server will be added to this set + + diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniConceptSearchControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniConceptSearchControllerTest.java new file mode 100644 index 0000000000..56bf23e3f4 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniConceptSearchControllerTest.java @@ -0,0 +1,92 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.service.BahmniDiagnosisService; +import org.bahmni.module.bahmnicore.service.TsConceptSearchService; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.ConceptSearchResult; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.context.Context; +import org.openmrs.module.emrapi.concept.EmrConceptService; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.util.LocaleUtility; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +@PowerMockIgnore("javax.management.*") +@RunWith(PowerMockRunner.class) +@PrepareForTest(Context.class) +public class BahmniConceptSearchControllerTest { + + @Mock + private BahmniDiagnosisService bahmniDiagnosisService; + + @Mock + private EmrConceptService emrService; + + @Mock + private TsConceptSearchService tsConceptSearchService; + + @Mock + private AdministrationService administrationService; + + @InjectMocks + private BahmniConceptSearchController bahmniConceptSearchController; + + String searchTerm = "Malaria"; + int searchLimit = 20; + String locale = LocaleUtility.getDefaultLocale().toString(); + List locales = Collections.singletonList(LocaleUtility.getDefaultLocale()); + + @Before + public void setUp() throws Exception { + initMocks(this); + PowerMockito.mockStatic(Context.class); + when(Context.getAdministrationService()).thenReturn(administrationService); + when(administrationService.getAllowedLocales()).thenReturn(locales); + } + + @Test + public void shouldSearchDiagnosisByNameFromDiagnosisSetOfSetsWhenNoExternalTerminologyServerUsed() throws Exception { + String malariaConceptUuid = "uuid1"; + SimpleObject MalariaObject = new SimpleObject(); + MalariaObject.add("conceptName", searchTerm); + MalariaObject.add("conceptUuid", malariaConceptUuid); + MalariaObject.add("matchedName", searchTerm); + + when(tsConceptSearchService.getConcepts(searchTerm, searchLimit, locale)).thenReturn(Collections.singletonList(MalariaObject)); + + List searchResults = (List< SimpleObject >) bahmniConceptSearchController.search(searchTerm, searchLimit, locale); + + assertNotNull(searchResults); + assertEquals(searchResults.size(), 1); + assertEquals(searchResults.get(0).get("conceptName"), searchTerm); + assertEquals(searchResults.get(0).get("conceptUuid"), malariaConceptUuid); + } + + @Test + public void shouldSearchDiagnosisByNameFromExternalTerminologyServerAndShouldReturnEmptyList() throws Exception { + when(tsConceptSearchService.getConcepts(searchTerm, searchLimit, locale)).thenReturn(new ArrayList<>()); + + List searchResults = (List< SimpleObject >) bahmniConceptSearchController.search(searchTerm, searchLimit, locale); + assertNotNull(searchResults); + assertEquals(searchResults.size(), 0); + } +} From 0336ce0159d63940245e107e2d85bedc808e9dac Mon Sep 17 00:00:00 2001 From: Arjun G <91885483+Arjun-Go@users.noreply.github.com> Date: Thu, 13 Jul 2023 12:45:31 +0530 Subject: [PATCH 04/47] BAH-3079 | add. medications tagged as inpatient to be fetched in active and inactive drug orders (#221) --- .../impl/BahmniDrugOrderServiceImpl.java | 28 +++++++++++++------ .../impl/BahmniDrugOrderServiceImplTest.java | 3 +- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImpl.java index 5f54ca0c5b..2c9bb6faa8 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImpl.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImpl.java @@ -97,11 +97,17 @@ public Map getDiscontinuedDrugOrders(List drugOrder public List getInactiveDrugOrders(String patientUuid, Set concepts, Set drugConceptsToBeExcluded, Collection encounters) { Patient patient = openmrsPatientService.getPatientByUuid(patientUuid); - CareSetting careSettingByName = orderService.getCareSettingByName(CareSetting.CareSettingType.OUTPATIENT.toString()); + CareSetting outPatientCareSetting = orderService.getCareSettingByName(CareSetting.CareSettingType.OUTPATIENT.toString()); + CareSetting inPatientCareSetting = orderService.getCareSettingByName(CareSetting.CareSettingType.INPATIENT.toString()); Date asOfDate = new Date(); - List orders = orderDao.getInactiveOrders(patient, orderService.getOrderTypeByName("Drug order"), - careSettingByName, asOfDate, concepts, drugConceptsToBeExcluded, encounters); - return mapOrderToDrugOrder(orders); + List outPatientOrders = orderDao.getInactiveOrders(patient, orderService.getOrderTypeByName("Drug order"), + outPatientCareSetting, asOfDate, concepts, drugConceptsToBeExcluded, encounters); + List inPatientOrders = orderDao.getInactiveOrders(patient, orderService.getOrderTypeByName("Drug order"), + inPatientCareSetting, asOfDate, concepts, drugConceptsToBeExcluded, encounters); + List allActiveDrugOrders = new ArrayList<>(); + allActiveDrugOrders.addAll(outPatientOrders); + allActiveDrugOrders.addAll(inPatientOrders); + return mapOrderToDrugOrder(allActiveDrugOrders); } @Override @@ -204,10 +210,16 @@ private List getFrequencies() { private List getActiveDrugOrders(String patientUuid, Date asOfDate, Set conceptsToFilter, Set conceptsToExclude, Date startDate, Date endDate, Collection encounters) { Patient patient = openmrsPatientService.getPatientByUuid(patientUuid); - CareSetting careSettingByName = orderService.getCareSettingByName(CareSetting.CareSettingType.OUTPATIENT.toString()); - List orders = orderDao.getActiveOrders(patient, orderService.getOrderTypeByName("Drug order"), - careSettingByName, asOfDate, conceptsToFilter, conceptsToExclude, startDate, endDate, encounters); - return mapOrderToDrugOrder(orders); + CareSetting outPatientCareSetting = orderService.getCareSettingByName(CareSetting.CareSettingType.OUTPATIENT.toString()); + CareSetting inPatientCareSetting = orderService.getCareSettingByName(CareSetting.CareSettingType.INPATIENT.toString()); + List outPatientOrders = orderDao.getActiveOrders(patient, orderService.getOrderTypeByName("Drug order"), + outPatientCareSetting, asOfDate, conceptsToFilter, conceptsToExclude, startDate, endDate, encounters); + List inPatientOrders = orderDao.getActiveOrders(patient, orderService.getOrderTypeByName("Drug order"), + inPatientCareSetting, asOfDate, conceptsToFilter, conceptsToExclude, startDate, endDate, encounters); + List allActiveDrugOrders = new ArrayList<>(); + allActiveDrugOrders.addAll(outPatientOrders); + allActiveDrugOrders.addAll(inPatientOrders); + return mapOrderToDrugOrder(allActiveDrugOrders); } private List mapOrderToDrugOrder(List orders){ diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImplTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImplTest.java index db08d279f4..cbc9983503 100644 --- a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImplTest.java +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImplTest.java @@ -33,6 +33,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; +import static org.mockito.Mockito.times; import static org.mockito.MockitoAnnotations.initMocks; public class BahmniDrugOrderServiceImplTest { @@ -85,7 +86,7 @@ public void shouldGetActiveDrugOrdersOfAPatientProgram() throws ParseException { bahmniDrugOrderService.getDrugOrders(PATIENT_UUID, true, conceptsToFilter, null, PATIENT_PROGRAM_UUID); final Date value = dateArgumentCaptor.getValue(); - verify(orderDao).getActiveOrders(mockPatient, mockOrderType, mockCareSetting, value, conceptsToFilter, null, null, null, encounters); + verify(orderDao, times(2)).getActiveOrders(mockPatient, mockOrderType, mockCareSetting, value, conceptsToFilter, null, null, null, encounters); } @Test From e07f38750fa9c9774e2c0af1eaa19efed7047341 Mon Sep 17 00:00:00 2001 From: Siva Reddy Date: Tue, 18 Jul 2023 15:09:55 +0530 Subject: [PATCH 05/47] BAH-3110 | Upgrade OpenMRS version to 2.5.12 (#222) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bb00381821..3cdbf81185 100644 --- a/pom.xml +++ b/pom.xml @@ -45,7 +45,7 @@ UTF-8 - 2.5.10 + 2.5.12 2.39.0 5.2.14.RELEASE 1.10.1 From e129f788731fbb37e43d605945be9f2ee844e0a3 Mon Sep 17 00:00:00 2001 From: angshuman sarkar Date: Thu, 20 Jul 2023 05:38:55 +0000 Subject: [PATCH 06/47] BAH-3037 | adding provider attribute for "login locations" (#223) --- bahmnicore-omod/src/main/resources/liquibase.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/bahmnicore-omod/src/main/resources/liquibase.xml b/bahmnicore-omod/src/main/resources/liquibase.xml index 4dc74425a5..9afe7fcdd6 100644 --- a/bahmnicore-omod/src/main/resources/liquibase.xml +++ b/bahmnicore-omod/src/main/resources/liquibase.xml @@ -4558,4 +4558,17 @@ + + + + SELECT count(*) FROM provider_attribute_type where name="Login Locations"; + + + Adding provider attribute type - Login Locations + + INSERT INTO provider_attribute_type (name, description, datatype, min_occurs, creator, date_created, retired, uuid) + VALUES ("Login Locations","Specific locations for providers to login", "org.openmrs.customdatatype.datatype.LocationDatatype", 0, 1, NOW(), 0, UUID()); + + + From 201d4f08439973e3b0f9201d77f2b4b80de56974 Mon Sep 17 00:00:00 2001 From: deeptirawat1510 <111413203+deeptirawat1510@users.noreply.github.com> Date: Tue, 29 Aug 2023 11:47:37 +0530 Subject: [PATCH 07/47] [BAH-3180]Exception Handler for OrderEntryException to ensure duplicate drugs can't be added (#229) Co-authored-by: yenugukeerthana --- .../controller/BahmniEncounterController.java | 25 ++++++++++++++----- .../BahmniEncounterControllerTest.java | 19 ++++++++++++++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniEncounterController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniEncounterController.java index f79dd3f5b8..b79abf3ab9 100644 --- a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniEncounterController.java +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniEncounterController.java @@ -1,9 +1,12 @@ package org.bahmni.module.bahmnicore.web.v1_0.controller; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; import org.bahmni.module.bahmnicore.web.v1_0.VisitClosedException; import org.openmrs.Encounter; import org.openmrs.Visit; import org.openmrs.api.EncounterService; +import org.openmrs.api.OrderEntryException; import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterSearchParameters; import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.BahmniEncounterTransactionMapper; @@ -14,16 +17,15 @@ import org.openmrs.module.webservices.rest.web.RestConstants; import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.*; import java.util.Date; +import java.util.HashMap; +import java.util.Map; import static org.bahmni.module.bahmnicore.util.MiscUtils.setUuidsForObservations; @@ -35,6 +37,7 @@ public class BahmniEncounterController extends BaseRestController { private EncounterTransactionMapper encounterTransactionMapper; private BahmniEncounterTransactionService bahmniEncounterTransactionService; private BahmniEncounterTransactionMapper bahmniEncounterTransactionMapper; + private static Logger logger = LogManager.getLogger(BahmniEncounterController.class); public BahmniEncounterController() { } @@ -100,5 +103,15 @@ public BahmniEncounterTransaction get(String encounterUuid) { EncounterTransaction encounterTransaction = encounterTransactionMapper.map(encounter, includeAll); return bahmniEncounterTransactionMapper.map(encounterTransaction, includeAll); } + @ExceptionHandler(OrderEntryException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ResponseEntity handleOrderEntryException(OrderEntryException ex) { + Map errorBody = new HashMap<>(); + errorBody.put("message", "[" + ex.getMessage() + "]"); + Map responseBody = new HashMap<>(); + responseBody.put("error", errorBody); + logger.warn("OrderEntryException: " + ex.getMessage()); + return new ResponseEntity(responseBody, HttpStatus.BAD_REQUEST); + } } diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniEncounterControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniEncounterControllerTest.java index 94b60992b0..22412cc755 100644 --- a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniEncounterControllerTest.java +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniEncounterControllerTest.java @@ -8,15 +8,19 @@ import org.openmrs.Encounter; import org.openmrs.Visit; import org.openmrs.api.EncounterService; +import org.openmrs.api.OrderEntryException; import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterSearchParameters; import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.BahmniEncounterTransactionMapper; import org.openmrs.module.bahmniemrapi.encountertransaction.service.BahmniEncounterTransactionService; import org.openmrs.module.emrapi.encounter.EmrEncounterService; import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.Map; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; @@ -91,5 +95,20 @@ public void shouldThrowVisitClosedExceptionIfEncounterVisitIsClosed() throws Exc bahmniEncounterController.delete("410491d2-b617-42ad-bf0f-de2fc9b42998","Undo Discharge"); } + @Test + public void shouldThrowBadRequestStatusCodeForOrderEntryException() throws Exception{ + bahmniEncounterController = new BahmniEncounterController(encounterService, emrEncounterService, null, bahmniEncounterTransactionService, bahmniEncounterTransactionMapper); + + OrderEntryException mockException = new OrderEntryException("Order.cannot.have.more.than.one"); + + ResponseEntity response = bahmniEncounterController.handleOrderEntryException(mockException); + + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + + Map responseBody = (Map) response.getBody(); + Map errorBody = (Map) responseBody.get("error"); + + assertEquals("[Order.cannot.have.more.than.one]", errorBody.get("message")); + } } \ No newline at end of file From 536c8f94af7b700dfd2ad803d40e83b6f49f8274 Mon Sep 17 00:00:00 2001 From: Rahul Ramesh <121226043+rahu1ramesh@users.noreply.github.com> Date: Fri, 6 Oct 2023 11:43:55 +0530 Subject: [PATCH 08/47] [Rahul] | BAH-3228 | Add. Bump Bahmni Commons Version Bahmni Commons Version 1.0.0 -> 1.1.0-SNAPSHOT --- .gitignore | 2 ++ pom.xml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ab4edec445..ac7e5e5d4c 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ classes/ sass-external bahmnicore-omod/src/main/webapp/resources/styles/bahmnicore.css .mvn/wrapper/*.jar +.vscode + # Eclipse project files .settings diff --git a/pom.xml b/pom.xml index 3cdbf81185..8438c5fc2b 100644 --- a/pom.xml +++ b/pom.xml @@ -69,7 +69,7 @@ 1.4.0 2.13.0 1.6.2 - 1.0.0 + 1.1.0-SNAPSHOT 4.13 From ab8c5d1a7d321c939aa455bd53557c01be6fab4f Mon Sep 17 00:00:00 2001 From: anubhavBeehyv <123312249+anubhavBeehyv@users.noreply.github.com> Date: Fri, 20 Oct 2023 11:15:32 +0530 Subject: [PATCH 09/47] BAH-2962 | Added sms sending functionality . (#231) * Added SMS sending functionality on patient registration. --- bahmnicore-api/pom.xml | 4 + .../module/bahmnicore/events/BahmniEvent.java | 26 +++++++ .../bahmnicore/events/BahmniEventType.java | 16 ++++ .../bahmnicore/events/EncounterEvent.java | 19 +++++ .../bahmnicore/events/PatientEvent.java | 24 ++++++ .../events/advice/EncounterAdvice.java | 61 +++++++++++++++ .../events/advice/PatientAdvice.java | 61 +++++++++++++++ .../PatientSmsEventListener.java | 78 +++++++++++++++++++ .../eventPublisher/BahmniEventPublisher.java | 21 +++++ .../util/BahmniAsyncThreadExecutor.java | 28 +++++++ ...java => EmailCommunicationController.java} | 9 +-- bahmnicore-omod/src/main/resources/config.xml | 21 ++++- pom.xml | 2 +- 13 files changed, 361 insertions(+), 9 deletions(-) create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/BahmniEvent.java create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/BahmniEventType.java create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/EncounterEvent.java create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/PatientEvent.java create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/advice/EncounterAdvice.java create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/advice/PatientAdvice.java create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/eventListener/PatientSmsEventListener.java create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/eventPublisher/BahmniEventPublisher.java create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/BahmniAsyncThreadExecutor.java rename bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/{TransmissionController.java => EmailCommunicationController.java} (93%) diff --git a/bahmnicore-api/pom.xml b/bahmnicore-api/pom.xml index 2b447e3a7e..4aaf0cf22a 100644 --- a/bahmnicore-api/pom.xml +++ b/bahmnicore-api/pom.xml @@ -83,6 +83,10 @@ joda-time 2.0 + + org.bahmni.module + communication-api + org.bahmni.module bahmni-emr-api diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/BahmniEvent.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/BahmniEvent.java new file mode 100644 index 0000000000..1681c1e017 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/BahmniEvent.java @@ -0,0 +1,26 @@ +package org.bahmni.module.bahmnicore.events; + +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; + +import java.time.LocalDateTime; +import java.util.UUID; + +public class BahmniEvent { + + private static final long version = 1L; + public UserContext userContext; + public String eventId; + public BahmniEventType eventType; + public String payloadId; + public LocalDateTime publishedDateTime; + + public BahmniEvent(BahmniEventType bahmniEventType) { + this.eventType = bahmniEventType; + this.eventId = UUID.randomUUID().toString(); + this.publishedDateTime = LocalDateTime.now(); + this.userContext= Context.getUserContext(); + this.payloadId=""; + } +} + diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/BahmniEventType.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/BahmniEventType.java new file mode 100644 index 0000000000..0f2dd642ce --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/BahmniEventType.java @@ -0,0 +1,16 @@ +package org.bahmni.module.bahmnicore.events; + +public enum BahmniEventType { + BAHMNI_PATIENT_CREATED("bahmni-patient"), + BAHMNI_PATIENT_UPDATED("bahmni-patient"), + BAHMNI_ENCOUNTER_CREATED("bahmni-encounter"), + BAHMNI_ENCOUNTER_UPDATED("bahmni-encounter"); + + private final String topic; + BahmniEventType(String topic) { + this.topic = topic; + } + public String topic() { + return topic; + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/EncounterEvent.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/EncounterEvent.java new file mode 100644 index 0000000000..a3b0107902 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/EncounterEvent.java @@ -0,0 +1,19 @@ +package org.bahmni.module.bahmnicore.events; + +import org.openmrs.Encounter; + +public class EncounterEvent extends BahmniEvent { + + private Encounter encounter; + + public EncounterEvent(BahmniEventType bahmniEventType, Encounter encounter) { + super(bahmniEventType); + this.encounter = encounter; + this.payloadId=encounter.getUuid(); + } + + public Encounter getEncounter() { + return encounter; + } +} + diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/PatientEvent.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/PatientEvent.java new file mode 100644 index 0000000000..dba79af640 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/PatientEvent.java @@ -0,0 +1,24 @@ +package org.bahmni.module.bahmnicore.events; + +import org.openmrs.Patient; +import org.openmrs.api.context.Context; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.UUID; + +public class PatientEvent extends BahmniEvent { + + private Patient patient; + + public PatientEvent(BahmniEventType bahmniEventType, Patient patient) { + super(bahmniEventType); + this.patient = patient; + this.payloadId=patient.getUuid(); + } + + public Patient getPatient() { + return patient; + } +} + diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/advice/EncounterAdvice.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/advice/EncounterAdvice.java new file mode 100644 index 0000000000..649a21f563 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/advice/EncounterAdvice.java @@ -0,0 +1,61 @@ +package org.bahmni.module.bahmnicore.events.advice; + +import com.google.common.collect.Sets; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.bahmnicore.events.BahmniEventType; +import org.bahmni.module.bahmnicore.events.EncounterEvent; +import org.bahmni.module.bahmnicore.events.eventPublisher.BahmniEventPublisher; +import org.openmrs.Encounter; +import org.openmrs.api.context.Context; +import org.springframework.aop.AfterReturningAdvice; +import org.springframework.aop.MethodBeforeAdvice; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import static org.bahmni.module.bahmnicore.events.BahmniEventType.BAHMNI_ENCOUNTER_CREATED; +import static org.bahmni.module.bahmnicore.events.BahmniEventType.BAHMNI_ENCOUNTER_UPDATED; + + +public class EncounterAdvice implements AfterReturningAdvice, MethodBeforeAdvice { + + private final Logger log = LogManager.getLogger(this.getClass()); + private final BahmniEventPublisher eventPublisher; + private final ThreadLocal> threadLocal = new ThreadLocal<>(); + private final String ENCOUNTER_ID_KEY = "encounterId"; + private final Set adviceMethodNames = Sets.newHashSet("saveEncounter"); + + public EncounterAdvice() { + this.eventPublisher = Context.getRegisteredComponent("bahmniEventPublisher", BahmniEventPublisher.class); + } + + @Override + public void afterReturning(Object returnValue, Method method, Object[] arguments, Object target) { + if (adviceMethodNames.contains(method.getName())) { + Map encounterInfo = threadLocal.get(); + if (encounterInfo != null) { + BahmniEventType eventType = encounterInfo.get(ENCOUNTER_ID_KEY) == null ? BAHMNI_ENCOUNTER_CREATED : BAHMNI_ENCOUNTER_UPDATED; + threadLocal.remove(); + + Encounter encounter = (Encounter) returnValue; + EncounterEvent encounterEvent = new EncounterEvent(eventType, encounter); + eventPublisher.publishEvent(encounterEvent); + + log.info("Successfully published event with uuid : " + encounter.getUuid()); + } + } + } + + @Override + public void before(Method method, Object[] objects, Object o) { + if (adviceMethodNames.contains(method.getName())) { + Encounter encounter = (Encounter) objects[0]; + Map encounterInfo = new HashMap<>(1); + encounterInfo.put(ENCOUNTER_ID_KEY, encounter.getId()); + threadLocal.set(encounterInfo); + } + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/advice/PatientAdvice.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/advice/PatientAdvice.java new file mode 100644 index 0000000000..50bbd77e02 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/advice/PatientAdvice.java @@ -0,0 +1,61 @@ +package org.bahmni.module.bahmnicore.events.advice; + +import com.google.common.collect.Sets; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.bahmnicore.events.BahmniEventType; +import org.bahmni.module.bahmnicore.events.PatientEvent; +import org.bahmni.module.bahmnicore.events.eventPublisher.BahmniEventPublisher; +import org.openmrs.Patient; +import org.openmrs.api.context.Context; +import org.springframework.aop.AfterReturningAdvice; +import org.springframework.aop.MethodBeforeAdvice; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import static org.bahmni.module.bahmnicore.events.BahmniEventType.BAHMNI_PATIENT_CREATED; +import static org.bahmni.module.bahmnicore.events.BahmniEventType.BAHMNI_PATIENT_UPDATED; + + +public class PatientAdvice implements AfterReturningAdvice, MethodBeforeAdvice { + + private final Logger log = LogManager.getLogger(PatientAdvice.class); + private final BahmniEventPublisher eventPublisher; + private final ThreadLocal> threadLocal = new ThreadLocal<>(); + private final String PATIENT_ID_KEY = "patientId"; + private final Set adviceMethodNames = Sets.newHashSet("savePatient"); + + public PatientAdvice() { + this.eventPublisher = Context.getRegisteredComponent("bahmniEventPublisher", BahmniEventPublisher.class); + } + + @Override + public void afterReturning(Object returnValue, Method method, Object[] arguments, Object target) { + if (adviceMethodNames.contains(method.getName())) { + Map patientInfo = threadLocal.get(); + if (patientInfo != null) { + BahmniEventType eventType = patientInfo.get(PATIENT_ID_KEY) == null ? BAHMNI_PATIENT_CREATED : BAHMNI_PATIENT_UPDATED; + threadLocal.remove(); + + Patient patient = (Patient) returnValue; + PatientEvent patientEvent =new PatientEvent(eventType,patient); + eventPublisher.publishEvent(patientEvent); + + log.info("Successfully published event with uuid : " + patient.getUuid()); + } + } + } + @Override + public void before(Method method, Object[] objects, Object o) { + if (adviceMethodNames.contains(method.getName())) { + Patient patient = (Patient) objects[0]; + + Map patientInfo = new HashMap<>(1); + patientInfo.put(PATIENT_ID_KEY, patient.getId()); + threadLocal.set(patientInfo); + } + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/eventListener/PatientSmsEventListener.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/eventListener/PatientSmsEventListener.java new file mode 100644 index 0000000000..0a527134a8 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/eventListener/PatientSmsEventListener.java @@ -0,0 +1,78 @@ +package org.bahmni.module.bahmnicore.events.eventListener; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.bahmni.module.bahmnicore.events.BahmniEventType; +import org.bahmni.module.bahmnicore.events.PatientEvent; +import org.bahmni.module.communication.service.CommunicationService; +import org.bahmni.module.communication.service.MessageBuilderService; +import org.openmrs.Patient; +import org.openmrs.PersonAttribute; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.context.Context; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +@Component +public class PatientSmsEventListener { + + private final Log log = LogFactory.getLog(this.getClass()); + + + @Async("BahmniAsyncThreadExecutor") + @EventListener + public void onApplicationEvent(PatientEvent event) { + try { + Context.openSession(); + Context.setUserContext(event.userContext); + if (event.eventType == BahmniEventType.BAHMNI_PATIENT_CREATED) { + handlePatientCreatedEvent(event.getPatient()); + } + } catch(Exception e){ + log.error("Exception occurred during event processing", e); + } finally{ + Context.closeSession(); + } + } + + private void handlePatientCreatedEvent(Patient patient) { + AdministrationService administrationService = Context.getService(AdministrationService.class); + boolean patientRegistrationSMSProperty = Boolean.parseBoolean(administrationService.getGlobalProperty("sms.enableRegistrationSMSAlert","false")); + if (!patientRegistrationSMSProperty) + return; + String phoneNumber = getPhoneNumber(patient); + if (phoneNumber != null) { + MessageBuilderService messageBuilderService = Context.getRegisteredComponent("messageBuilderService", MessageBuilderService.class); + CommunicationService communicationService = Context.getRegisteredComponent("communicationService", CommunicationService.class); + String message=messageBuilderService.getRegistrationMessage(createArgumentsMapForPatientRegistration(patient)); + communicationService.sendSMS(phoneNumber, message); + } + } + + public Map createArgumentsMapForPatientRegistration(Patient patient) { + String helpdeskNumber = Context.getAdministrationService().getGlobalPropertyObject("clinic.helpDeskNumber").getPropertyValue(); + Map arguments = new HashMap<>(); + arguments.put("location", Context.getUserContext().getLocation().getName()); + arguments.put("identifier", patient.getPatientIdentifier().getIdentifier()); + arguments.put("patientname", patient.getGivenName() + " " + patient.getFamilyName()); + arguments.put("gender", patient.getGender()); + arguments.put("age", patient.getAge().toString()); + arguments.put("helpdesknumber", helpdeskNumber); + return arguments; + } + + private String getPhoneNumber(Patient patient) { + PersonAttribute phoneNumber = patient.getAttribute("phoneNumber"); + if (phoneNumber == null) { + log.info("No mobile number found for the patient. SMS not sent."); + return null; + } + return phoneNumber.getValue(); + } +} + + diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/eventPublisher/BahmniEventPublisher.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/eventPublisher/BahmniEventPublisher.java new file mode 100644 index 0000000000..0ff4b9bdbb --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/eventPublisher/BahmniEventPublisher.java @@ -0,0 +1,21 @@ +package org.bahmni.module.bahmnicore.events.eventPublisher; + +import org.bahmni.module.bahmnicore.events.BahmniEvent; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.ApplicationEventPublisherAware; +import org.springframework.lang.NonNull; +import org.springframework.stereotype.Component; + +@Component +public class BahmniEventPublisher implements ApplicationEventPublisherAware { + + private ApplicationEventPublisher eventPublisher; + + @Override + public void setApplicationEventPublisher(@NonNull ApplicationEventPublisher applicationEventPublisher) { + this.eventPublisher = applicationEventPublisher; + } + public void publishEvent(BahmniEvent event) { + this.eventPublisher.publishEvent(event); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/BahmniAsyncThreadExecutor.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/BahmniAsyncThreadExecutor.java new file mode 100644 index 0000000000..db49d734e7 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/BahmniAsyncThreadExecutor.java @@ -0,0 +1,28 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public License, + * v. 2.0. If a copy of the MPL was not distributed with this file, You can + * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under + * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. + * + * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS + * graphic logo is a trademark of OpenMRS Inc. + */ +package org.bahmni.module.bahmnicore.util; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; + +@Configuration +@EnableAsync +public class BahmniAsyncThreadExecutor { + + @Bean(name = "BahmniAsyncThreadExecutor") + public Executor threadPoolTaskExecutor() { + ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor(); + return threadPoolTaskExecutor; + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/TransmissionController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/EmailCommunicationController.java similarity index 93% rename from bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/TransmissionController.java rename to bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/EmailCommunicationController.java index b348113ebe..28cac1ad84 100644 --- a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/TransmissionController.java +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/EmailCommunicationController.java @@ -9,9 +9,8 @@ import org.apache.http.impl.DefaultHttpResponseFactory; import org.apache.http.message.BasicStatusLine; import org.bahmni.module.bahmnicore.web.v1_0.contract.BahmniMailContent; -import org.bahmni.module.communication.api.CommunicationService; -import org.bahmni.module.communication.model.MailContent; import org.bahmni.module.communication.model.Recipient; +import org.bahmni.module.communication.service.CommunicationService; import org.openmrs.Patient; import org.openmrs.api.PatientService; import org.openmrs.api.context.Context; @@ -26,8 +25,8 @@ import org.springframework.web.bind.annotation.PathVariable; @Controller -@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/patient/{patientUuid}/send/") -public class TransmissionController extends BaseRestController { +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/patient/{patientUuid}/send/")//change to send-prescription-email +public class EmailCommunicationController extends BaseRestController { private final Log log = LogFactory.getLog(this.getClass()); @@ -58,4 +57,4 @@ public Object sendEmail(@RequestBody BahmniMailContent bahmniMailContent, @PathV return response; } -} +} \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/config.xml b/bahmnicore-omod/src/main/resources/config.xml index e916179e24..d33c63144f 100644 --- a/bahmnicore-omod/src/main/resources/config.xml +++ b/bahmnicore-omod/src/main/resources/config.xml @@ -136,7 +136,7 @@ BahmniConfig.hbm.xml EntityMapping.hbm.xml EntityMappingType.hbm.xml - + @@ -146,7 +146,7 @@ bahmni.relationshipTypeMap - Relationship Type Map format Eg:{ "patient": ["Sibling", "Parent"],"provider": ["Doctor"]}.If no value is specified default is patient relationship. + Relationship Type Map format Eg:{ "patient": ["Sibling", "Parent"],"provider": ["Doctor"]}.If no value is specified default is patient relationship. @@ -188,7 +188,22 @@ bahmni.diagnosisSetForNewDiagnosisConcepts - UUID of set member of diagnosis set of sets. New Diagnosis concepts from terminology server will be added to this set + UUID of set member of diagnosis set of sets. New Diagnosis concepts from terminology server will be added to this set + + sms.enableRegistrationSMSAlert + false + Boolean to enable sending sms when patient registers + + + + + org.openmrs.api.PatientService + org.bahmni.module.bahmnicore.events.advice.PatientAdvice + + + org.openmrs.api.EncounterService + org.bahmni.module.bahmnicore.events.advice.EncounterAdvice + diff --git a/pom.xml b/pom.xml index 8438c5fc2b..06d7e780de 100644 --- a/pom.xml +++ b/pom.xml @@ -573,7 +573,7 @@ org.bahmni.module communication-api - 1.1.0 + 1.2.0-SNAPSHOT jar provided From 62dab0f1917107df1a078efef04b7760d122d8dc Mon Sep 17 00:00:00 2001 From: Siva Reddy Date: Fri, 24 Nov 2023 10:09:35 +0530 Subject: [PATCH 10/47] BAH-3266 | Siva Reddy | Fetching concepts from default locale if no concepts in requested locale (#235) * BAH-3266 | Siva Reddy | Fetching concepts from default locale if no concepts in requested locale * BAH-3266 | Review comments --- .../bahmnicore/dao/impl/ObsDaoImpl.java | 11 +- .../module/bahmnicore/util/MiscUtils.java | 20 ++++ .../search/BahmniConceptSearchHandler.java | 42 ++++++- .../BahmniConceptSearchHandlerTest.java | 106 ++++++++++++++++++ 4 files changed, 176 insertions(+), 3 deletions(-) create mode 100644 bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchHandlerTest.java diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/ObsDaoImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/ObsDaoImpl.java index 474d564a60..15a276bee0 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/ObsDaoImpl.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/ObsDaoImpl.java @@ -15,6 +15,7 @@ import org.openmrs.Person; import org.openmrs.api.ConceptNameType; import org.openmrs.api.context.Context; +import org.openmrs.util.LocaleUtility; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; @@ -24,6 +25,7 @@ import java.util.Collection; import java.util.Date; import java.util.List; +import java.util.Locale; import static java.util.Objects.nonNull; @@ -77,7 +79,7 @@ public List getObsByPatientAndVisit(String patientUuid, List concep " where obs.person.uuid = :patientUuid " + " and cn.concept = obs.concept.conceptId " + " and cn.name in (:conceptNames) " + - " and cn.locale = :locale " + + " and cn.locale in (:locale) " + " and cn.conceptNameType = :conceptNameType " + " and cn.voided = false and obs.voided = false "); @@ -106,13 +108,18 @@ public List getObsByPatientAndVisit(String patientUuid, List concep query.append(" order by obs.obsDatetime desc "); } + List localeList = new ArrayList<>(); + localeList.add(Context.getLocale()); + if (!LocaleUtility.getDefaultLocale().equals(Context.getLocale())) { + localeList.add(LocaleUtility.getDefaultLocale()); + } Query queryToGetObservations = sessionFactory.getCurrentSession().createQuery(query.toString()); queryToGetObservations.setMaxResults(limit); queryToGetObservations.setString("patientUuid", patientUuid); queryToGetObservations.setParameterList("conceptNames", conceptNames); queryToGetObservations.setParameter("conceptNameType", ConceptNameType.FULLY_SPECIFIED); - queryToGetObservations.setString("locale", Context.getLocale().getLanguage()); + queryToGetObservations.setParameterList("locale", localeList); if (null != obsIgnoreList && obsIgnoreList.size() > 0) { queryToGetObservations.setParameterList("obsIgnoreList", obsIgnoreList); } diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/MiscUtils.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/MiscUtils.java index 9db4592d01..73042231b6 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/MiscUtils.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/MiscUtils.java @@ -2,8 +2,11 @@ import org.apache.commons.collections.CollectionUtils; import org.openmrs.Concept; +import org.openmrs.ConceptName; import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.util.LocaleUtility; import java.util.ArrayList; import java.util.Collection; @@ -18,6 +21,9 @@ public static List getConceptsForNames(List conceptNames, Conce List rootConcepts = new ArrayList<>(); for (String rootConceptName : conceptNames) { Concept concept = conceptService.getConceptByName(rootConceptName); + if (concept == null) { + concept = getConceptInDefaultLocale(conceptService, rootConceptName); + } if (concept != null) { rootConcepts.add(concept); } @@ -26,6 +32,20 @@ public static List getConceptsForNames(List conceptNames, Conce } return new ArrayList<>(); } + private static Concept getConceptInDefaultLocale(ConceptService conceptService, String rootConceptName) { + if (LocaleUtility.getDefaultLocale().equals(Context.getLocale())) { + return null; + } + List conceptsByName = conceptService.getConceptsByName(rootConceptName, LocaleUtility.getDefaultLocale(), false); + for (Concept concept : conceptsByName) { + for (ConceptName conceptname : concept.getNames()) { + if (conceptname.getName().equalsIgnoreCase(rootConceptName) && (conceptname.isPreferred() || conceptname.isFullySpecifiedName())) { + return concept; + } + } + } + return null; + } public static void setUuidsForObservations(Collection bahmniObservations) { for (BahmniObservation bahmniObservation : bahmniObservations) { diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchHandler.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchHandler.java index 30ae7c0881..d401b7c432 100644 --- a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchHandler.java +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchHandler.java @@ -3,8 +3,10 @@ import org.apache.commons.collections.CollectionUtils; import org.openmrs.Concept; import org.openmrs.ConceptName; +import org.openmrs.ConceptSearchResult; import org.openmrs.api.APIException; import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; import org.openmrs.module.webservices.rest.web.RequestContext; import org.openmrs.module.webservices.rest.web.RestConstants; import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; @@ -14,6 +16,7 @@ import org.openmrs.module.webservices.rest.web.resource.impl.EmptySearchResult; import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.openmrs.util.LocaleUtility; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @@ -21,6 +24,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Locale; +import java.util.stream.Collectors; @Component public class BahmniConceptSearchHandler implements SearchHandler { @@ -35,10 +40,22 @@ public SearchConfig getSearchConfig() { return new SearchConfig("byFullySpecifiedName", RestConstants.VERSION_1 + "/concept", Arrays.asList("1.8.* - 2.*"), searchQuery); } + /** + * Searches for concepts by the given parameters. (Currently only supports name and locale (optional)) + * @return a list of concepts matching the given parameters. + * @throws APIException + * Should return concepts in the specified locale if specified. + * Should return concepts in the default locale as well as logged in locale if locale is not specified. + */ + @Override public PageableResult search(RequestContext context) throws ResponseException { String conceptName = context.getParameter("name"); - List conceptsByName = conceptService.getConceptsByName(conceptName); + List localeList = getLocales(context); + + List conceptsSearchResult = conceptService.getConcepts(conceptName, localeList, false, null, null, null, null, null, 0, null); + List conceptsByName = conceptsSearchResult.stream().map(conceptSearchResult -> conceptSearchResult.getConcept()).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(conceptsByName)) { return new EmptySearchResult(); } else { @@ -59,4 +76,27 @@ public PageableResult search(RequestContext context) throws ResponseException { } } + /** + * Returns list of unique locales based on the context.getParameter("locale") parameter + * Should return List of results for locales: If locale is specified, then return results for that locale. + * If locale is not specified, then return results for logged in locale and default locale. + */ + + private List getLocales(RequestContext context) { + String locale = context.getParameter("locale"); + + List localeList = new ArrayList<>(); + + if (locale != null) { + localeList.add(LocaleUtility.fromSpecification(locale)); + } else { + localeList.add(Context.getLocale()); + if (!LocaleUtility.getDefaultLocale().equals(Context.getLocale())) { + localeList.add(LocaleUtility.getDefaultLocale()); + } + } + + return localeList; + } + } diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchHandlerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchHandlerTest.java new file mode 100644 index 0000000000..5bdbd50bb0 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchHandlerTest.java @@ -0,0 +1,106 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.ConceptSearchResult; +import org.openmrs.api.ConceptNameType; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.UserContext; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; +import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; +import org.openmrs.util.LocaleUtility; +import org.springframework.beans.factory.annotation.Qualifier; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class BahmniConceptSearchHandlerTest { + + @Mock + @Qualifier("conceptService") + private ConceptService conceptService; + + @Mock + RequestContext requestContext; + + @Mock + UserContext userContext; + + @InjectMocks + private BahmniConceptSearchHandler bahmniConceptSearchHandler; + + + @Test + public void shouldSearchByQuestion() { + SearchConfig searchConfig = bahmniConceptSearchHandler.getSearchConfig(); + assertEquals(searchConfig.getId(), "byFullySpecifiedName"); + } + + @Test + public void shouldSupportVersions1_8To2() { + SearchConfig searchConfig = bahmniConceptSearchHandler.getSearchConfig(); + assertTrue(searchConfig.getSupportedOpenmrsVersions().contains("1.8.* - 2.*")); + } + + @Test + public void shouldSearchByGivenLocale_whenLocaleIsSpecified() { + List conceptSearchResults = new ArrayList<>(); + ConceptSearchResult result = new ConceptSearchResult(); + Concept concept = new Concept(); + concept.setId(123); + ConceptName conceptNameFullySpecified = new ConceptName(); + conceptNameFullySpecified.setConceptNameType(ConceptNameType.FULLY_SPECIFIED); + conceptNameFullySpecified.setName("Nutritional Values"); + concept.setNames(Collections.singleton(conceptNameFullySpecified)); + result.setConcept(concept); + conceptSearchResults.add(result); + + List localeList = new ArrayList<>(); + localeList.add(Locale.FRENCH); + + when(conceptService.getConcepts(anyString(), anyList(), anyBoolean(), isNull(), isNull(), isNull(), isNull(), isNull(), any(Integer.class), isNull())).thenReturn(conceptSearchResults); + when(requestContext.getLimit()).thenReturn(10); + when(requestContext.getParameter("locale")).thenReturn("fr"); + when(requestContext.getParameter("name")).thenReturn("Nutritional Values"); + + + NeedsPaging searchResults = (NeedsPaging) bahmniConceptSearchHandler.search(requestContext); + + verify(conceptService, times(1)).getConcepts("Nutritional Values", localeList, false, null, null, null, null, null, 0, null); + assertEquals(1, searchResults.getPageOfResults().size()); + assertEquals(1, localeList.size()); + assertEquals(new Integer(123) , searchResults.getPageOfResults().get(0).getId()); + } + + @Test + public void shouldSearchByLoggedInLocaleAndDefaultLocale_whenLocaleIsNotSpecified() { + when(requestContext.getParameter("name")).thenReturn("Nutritional Values"); + + bahmniConceptSearchHandler.search(requestContext); + List localeList = new ArrayList<>(); + localeList.add(LocaleUtility.getDefaultLocale()); + + verify(conceptService, times(1)).getConcepts("Nutritional Values", localeList, false, null, null, null, null, null, 0, null); + } +} From 45a3bd43cc501133f0cef7374af4b41b50886ee3 Mon Sep 17 00:00:00 2001 From: angshuman sarkar Date: Thu, 7 Dec 2023 04:14:08 +0000 Subject: [PATCH 11/47] BAH-3181 | Enable locale specific concept search and also return FSN in defaultLocale (#236) Updated /bahmnicore/observations API to take in optional locale parameter, so that concepts are searched in the locale. Observation.conceptFSN returns the FSN in implementation/default locale --- .../contract/BahmniObservation.java | 9 ++++ .../mapper/OMRSObsToBahmniObsMapper.java | 34 +++++++++++-- .../mapper/ObsRelationshipMapper.java | 6 +-- .../mapper/ObsRelationshipMapperTest.java | 10 ++-- .../bahmnicore/service/impl/BahmniBridge.java | 5 +- .../service/impl/BahmniObsServiceImpl.java | 8 ++-- .../service/impl/BahmniBridgeTest.java | 2 +- .../impl/BahmniObsServiceImplTest.java | 6 +-- .../BahmniObservationsController.java | 48 ++++++++++++++++--- 9 files changed, 99 insertions(+), 29 deletions(-) diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniObservation.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniObservation.java index cad649dd35..62f85be997 100644 --- a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniObservation.java +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniObservation.java @@ -43,6 +43,7 @@ public class BahmniObservation implements Comparable{ private String interpretation; private String status; private String encounterTypeName; + private String conceptFSN; @JsonIgnore private Serializable complexData; @@ -431,4 +432,12 @@ public String getEncounterTypeName() { public void setEncounterTypeName(String encounterTypeName) { this.encounterTypeName = encounterTypeName; } + + public void setConceptFSN(String conceptFSN) { + this.conceptFSN = conceptFSN; + } + + public String getConceptFSN() { + return this.conceptFSN; + } } diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/OMRSObsToBahmniObsMapper.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/OMRSObsToBahmniObsMapper.java index 512c6ef393..bf4c88fcff 100644 --- a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/OMRSObsToBahmniObsMapper.java +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/OMRSObsToBahmniObsMapper.java @@ -2,13 +2,17 @@ import org.apache.commons.collections.CollectionUtils; import org.openmrs.Concept; +import org.openmrs.ConceptName; import org.openmrs.EncounterProvider; import org.openmrs.Obs; +import org.openmrs.api.ConceptNameType; import org.openmrs.module.bahmniemrapi.drugorder.mapper.BahmniProviderMapper; import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.parameters.AdditionalBahmniObservationFields; import org.openmrs.module.emrapi.encounter.ObservationMapper; import org.openmrs.module.emrapi.encounter.matcher.ObservationTypeMatcher; +import org.openmrs.module.emrapi.utils.HibernateLazyLoader; +import org.openmrs.util.LocaleUtility; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -16,6 +20,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Locale; @Component(value = "omrsObsToBahmniObsMapper") public class OMRSObsToBahmniObsMapper { @@ -33,9 +38,10 @@ public OMRSObsToBahmniObsMapper(ETObsToBahmniObsMapper etObsToBahmniObsMapper, O public Collection map(List obsList, Collection rootConcepts) { Collection bahmniObservations = new ArrayList<>(); + Locale implementationLocale = LocaleUtility.getDefaultLocale(); for (Obs obs : obsList) { if(observationTypeMatcher.getObservationType(obs).equals(ObservationTypeMatcher.ObservationType.OBSERVATION)){ - BahmniObservation bahmniObservation =map(obs); + BahmniObservation bahmniObservation = map(obs, implementationLocale); if(CollectionUtils.isNotEmpty(rootConcepts )){ bahmniObservation.setConceptSortWeight(ConceptSortWeightUtil.getSortWeightFor(bahmniObservation.getConcept().getName(), rootConcepts)); } @@ -45,7 +51,7 @@ public Collection map(List obsList, Collection return bahmniObservations; } - public BahmniObservation map(Obs obs) { + public BahmniObservation map(Obs obs, Locale implementationLocale) { if(obs == null) return null; String obsGroupUuid = obs.getObsGroup() == null? null : obs.getObsGroup().getUuid(); @@ -61,6 +67,28 @@ public BahmniObservation map(Obs obs) { for (EncounterProvider encounterProvider : obs.getEncounter().getEncounterProviders()) { additionalBahmniObservationFields.addProvider(bahmniProviderMapper.map(encounterProvider.getProvider())); } - return etObsToBahmniObsMapper.map(observationMapper.map(obs), additionalBahmniObservationFields, Collections.singletonList(obs.getConcept()), true); + BahmniObservation bahmniObservation = etObsToBahmniObsMapper.map(observationMapper.map(obs), additionalBahmniObservationFields, Collections.singletonList(obs.getConcept()), true); + bahmniObservation.setConceptFSN(getConceptFSNInDefaultLocale(obs, implementationLocale)); + return bahmniObservation; + } + + private String getConceptFSNInDefaultLocale(Obs obs, Locale implementationLocale) { + if (obs.getConcept() == null) { + return null; + } + Concept concept = new HibernateLazyLoader().load(obs.getConcept()); + if (implementationLocale == null) { + return concept.getName().getName(); + } + ConceptName fsn = concept.getName(implementationLocale, ConceptNameType.FULLY_SPECIFIED, null); + if (fsn == null) { + fsn = concept.getNames().stream().filter(name -> !name.getVoided() && name.getLocale().equals(implementationLocale) + && name.getConceptNameType().equals(ConceptNameType.FULLY_SPECIFIED)).findFirst().orElse(null); + } + if (fsn != null) { + return fsn.getName(); + } else { + return concept.getName().getName(); + } } } diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ObsRelationshipMapper.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ObsRelationshipMapper.java index d8eadc662b..b7d37510a4 100644 --- a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ObsRelationshipMapper.java +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ObsRelationshipMapper.java @@ -34,7 +34,7 @@ public List map(List bahmniObservations, S new org.openmrs.module.bahmniemrapi.obsrelation.contract.ObsRelationship(); targetObsRelation.setRelationshipType(obsRelationship.getObsRelationshipType().getName()); targetObsRelation.setUuid(obsRelationship.getUuid()); - targetObsRelation.setTargetObs(OMRSObsToBahmniObsMapper.map(obsRelationship.getTargetObs())); + targetObsRelation.setTargetObs(OMRSObsToBahmniObsMapper.map(obsRelationship.getTargetObs(), null)); bahmniObservation.setTargetObsRelation(targetObsRelation); // bahmniObservation.setProviders(providers); } @@ -47,8 +47,8 @@ public List map(List obsRelationships) { List bahmniObservations = new ArrayList<>(); for (ObsRelationship obsRelationship : obsRelationships) { - BahmniObservation sourceObservation = OMRSObsToBahmniObsMapper.map(obsRelationship.getSourceObs()); - BahmniObservation targetObservation = OMRSObsToBahmniObsMapper.map(obsRelationship.getTargetObs()); + BahmniObservation sourceObservation = OMRSObsToBahmniObsMapper.map(obsRelationship.getSourceObs(), null); + BahmniObservation targetObservation = OMRSObsToBahmniObsMapper.map(obsRelationship.getTargetObs(), null); sourceObservation.setProviders(encounterProviderMapper.convert(obsRelationship.getSourceObs().getEncounter().getEncounterProviders())); org.openmrs.module.bahmniemrapi.obsrelation.contract.ObsRelationship targetObsRelation = diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ObsRelationshipMapperTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ObsRelationshipMapperTest.java index 6ce71e0e0d..350e6abde9 100644 --- a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ObsRelationshipMapperTest.java +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ObsRelationshipMapperTest.java @@ -72,7 +72,7 @@ public void shouldMapObsRelationshipForBahmniObservations() { BahmniObservation sourceObservation = getBahmniObservation(sourceObsUuid); BahmniObservation targetObservation = getBahmniObservation(targetObsUuid); - when(OMRSObsToBahmniObsMapper.map(targetObs)).thenReturn(targetObservation); + when(OMRSObsToBahmniObsMapper.map(targetObs, null)).thenReturn(targetObservation); ArrayList bahmniObservations = new ArrayList<>(); bahmniObservations.add(sourceObservation); @@ -81,7 +81,7 @@ public void shouldMapObsRelationshipForBahmniObservations() { List mappedBahmniObservations = obsRelationshipMapper.map(bahmniObservations, "encounter-uuid"); verify(obsrelationService).getRelationsWhereSourceObsInEncounter("encounter-uuid"); - verify(OMRSObsToBahmniObsMapper, times(1)).map(targetObs); + verify(OMRSObsToBahmniObsMapper, times(1)).map(targetObs, null); assertEquals(2, mappedBahmniObservations.size()); assertEquals(sourceObsUuid, mappedBahmniObservations.get(0).getUuid()); assertEquals(targetObsUuid, mappedBahmniObservations.get(0).getTargetObsRelation().getTargetObs().getUuid()); @@ -112,8 +112,8 @@ public void shouldMapMultipleObsRelationshipForBahmniObservations() { BahmniObservation targetObservation1 = getBahmniObservation(targetObs1Uuid); BahmniObservation targetObservation2 = getBahmniObservation(targetObs2Uuid); - when(OMRSObsToBahmniObsMapper.map(targetObs1)).thenReturn(targetObservation1); - when(OMRSObsToBahmniObsMapper.map(targetObs2)).thenReturn(targetObservation2); + when(OMRSObsToBahmniObsMapper.map(targetObs1, null)).thenReturn(targetObservation1); + when(OMRSObsToBahmniObsMapper.map(targetObs2, null)).thenReturn(targetObservation2); ArrayList bahmniObservations = new ArrayList<>(); bahmniObservations.add(sourceObservation1); @@ -124,7 +124,7 @@ public void shouldMapMultipleObsRelationshipForBahmniObservations() { List mappedBahmniObservations = obsRelationshipMapper.map(bahmniObservations, "encounter-uuid"); verify(obsrelationService).getRelationsWhereSourceObsInEncounter("encounter-uuid"); - verify(OMRSObsToBahmniObsMapper, times(2)).map(any(Obs.class)); + verify(OMRSObsToBahmniObsMapper, times(2)).map(any(Obs.class), any()); assertEquals(4, mappedBahmniObservations.size()); assertEquals(sourceObs1Uuid, mappedBahmniObservations.get(0).getUuid()); assertEquals(targetObs1Uuid, mappedBahmniObservations.get(0).getTargetObsRelation().getTargetObs().getUuid()); diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniBridge.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniBridge.java index 695225a196..a875997c7b 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniBridge.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniBridge.java @@ -18,7 +18,6 @@ import org.openmrs.api.context.Context; import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.OMRSObsToBahmniObsMapper; -import org.openmrs.module.emrapi.encounter.OrderMapper; import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; import org.openmrs.module.emrapi.encounter.mapper.OrderMapper1_12; import org.springframework.beans.factory.annotation.Autowired; @@ -240,13 +239,13 @@ else if (o1.getDateActivated().after(o2.getDateActivated())) public BahmniObservation getChildObsFromParentObs(String parentObsGroupUuid, String childConceptName){ Concept childConcept = conceptService.getConceptByName(childConceptName); - return omrsObsToBahmniObsMapper.map(obsDao.getChildObsFromParent(parentObsGroupUuid, childConcept)); + return omrsObsToBahmniObsMapper.map(obsDao.getChildObsFromParent(parentObsGroupUuid, childConcept), null); } public BahmniObservation getLatestBahmniObservationFor(String conceptName){ Obs obs = latestObs(conceptName); if(obs != null) { - return omrsObsToBahmniObsMapper.map(obs); + return omrsObsToBahmniObsMapper.map(obs, null); } return null; } diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImpl.java index 5261d0f361..698b3db31a 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImpl.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImpl.java @@ -21,9 +21,7 @@ import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.OMRSObsToBahmniObsMapper; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import java.util.*; @@ -93,7 +91,7 @@ private boolean programDoesNotHaveEncounters(String patientProgramUuid, Collecti private List convertToBahmniObservation(List observations) { List bahmniObservations = new ArrayList<>(); for (Obs observation : observations) { - BahmniObservation bahmniObservation = omrsObsToBahmniObsMapper.map(observation); + BahmniObservation bahmniObservation = omrsObsToBahmniObsMapper.map(observation, null); bahmniObservation.setObservationDateTime(observation.getObsDatetime()); bahmniObservations.add(bahmniObservation); } @@ -265,7 +263,7 @@ public Collection getInitialObservationsForPatientProgram(Str @Override public BahmniObservation getBahmniObservationByUuid(String observationUuid) { Obs obs = obsService.getObsByUuid(observationUuid); - return omrsObsToBahmniObsMapper.map(obs); + return omrsObsToBahmniObsMapper.map(obs, null); } @Override @@ -274,7 +272,7 @@ public BahmniObservation getRevisedBahmniObservationByUuid(String observationUui if (obs.getVoided()) { obs = getRevisionObs(obs); } - return omrsObsToBahmniObsMapper.map(obs); + return omrsObsToBahmniObsMapper.map(obs, null); } @Override diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniBridgeTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniBridgeTest.java index 58bdfad7c3..492d909346 100644 --- a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniBridgeTest.java +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniBridgeTest.java @@ -151,7 +151,7 @@ public void shouldGetChildObservationFromParent() throws Exception { bahmniObs.setUuid("observation uuid"); PowerMockito.when(obsDao.getChildObsFromParent("parent obs uuid", vitalsConcept)).thenReturn(obs); - PowerMockito.when(omrsObsToBahmniObsMapper.map(obs)).thenReturn(bahmniObs); + PowerMockito.when(omrsObsToBahmniObsMapper.map(obs, null)).thenReturn(bahmniObs); Assert.assertEquals("observation uuid", bahmniBridge.getChildObsFromParentObs("parent obs uuid", "vital concept name").getUuid()); } diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImplTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImplTest.java index d988bcb71e..4cb5f5e368 100644 --- a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImplTest.java +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImplTest.java @@ -214,12 +214,12 @@ public void shouldGetBahmniObservationByObservationUuid() throws Exception { Obs obs = new Obs(); BahmniObservation expectedBahmniObservation = new BahmniObservation(); when(obsService.getObsByUuid(observationUuid)).thenReturn(obs); - when(omrsObsToBahmniObsMapper.map(obs)).thenReturn(expectedBahmniObservation); + when(omrsObsToBahmniObsMapper.map(obs, null)).thenReturn(expectedBahmniObservation); BahmniObservation actualBahmniObservation = bahmniObsService.getBahmniObservationByUuid(observationUuid); verify(obsService, times(1)).getObsByUuid(observationUuid); - verify(omrsObsToBahmniObsMapper, times(1)).map(obs); + verify(omrsObsToBahmniObsMapper, times(1)).map(obs, null); assertNotNull(actualBahmniObservation); assertEquals(expectedBahmniObservation, actualBahmniObservation); } @@ -262,7 +262,7 @@ public void shouldReturnBahmniObservationWhenGetObsForFormBuilderFormsCalled() { when(visitDao.getVisitIdsFor(patientUuid, numberOfVisits)).thenReturn(visitIds); when(obsDao.getObsForFormBuilderForms(patientUuid, formNames, visitIds, encounters, null, null)) .thenReturn(singletonList(observation)); - when(omrsObsToBahmniObsMapper.map(observation)).thenReturn(bahmniObservation); + when(omrsObsToBahmniObsMapper.map(observation, null)).thenReturn(bahmniObservation); Collection bahmniObservations = bahmniObsService.getObsForFormBuilderForms(patientUuid, formNames, numberOfVisits, null, null, patientProgramUuid); diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniObservationsController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniObservationsController.java index 137b651df3..0af0d32376 100644 --- a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniObservationsController.java +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniObservationsController.java @@ -1,17 +1,21 @@ package org.bahmni.module.bahmnicore.web.v1_0.controller.display.controls; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.bahmni.module.bahmnicore.extensions.BahmniExtensions; import org.bahmni.module.bahmnicore.obs.ObservationsAdder; import org.bahmni.module.bahmnicore.service.BahmniObsService; import org.bahmni.module.bahmnicore.util.MiscUtils; import org.openmrs.Concept; +import org.openmrs.ConceptSearchResult; import org.openmrs.Visit; +import org.openmrs.api.APIException; import org.openmrs.api.ConceptService; import org.openmrs.api.VisitService; import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; import org.openmrs.module.webservices.rest.web.RestConstants; import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.openmrs.util.LocaleUtility; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @@ -21,8 +25,15 @@ import java.text.ParseException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Locale; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; @Controller @RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/observations") @@ -47,27 +58,52 @@ public BahmniObservationsController(BahmniObsService bahmniObsService, ConceptSe @ResponseBody public Collection get(@RequestParam(value = "patientUuid", required = true) String patientUUID, @RequestParam(value = "concept", required = true) List rootConceptNames, + @RequestParam(value = "locale", required = false) String locale, @RequestParam(value = "scope", required = false) String scope, @RequestParam(value = "numberOfVisits", required = false) Integer numberOfVisits, @RequestParam(value = "obsIgnoreList", required = false) List obsIgnoreList, @RequestParam(value = "filterObsWithOrders", required = false, defaultValue = "true") Boolean filterObsWithOrders ) throws ParseException { - List rootConcepts = MiscUtils.getConceptsForNames(rootConceptNames, conceptService); - + List conceptList = searchConceptsByName(rootConceptNames, identifyLocale(locale)); Collection observations; if (ObjectUtils.equals(scope, LATEST)) { - observations = bahmniObsService.getLatest(patientUUID, rootConcepts, numberOfVisits, obsIgnoreList, filterObsWithOrders, null); + observations = bahmniObsService.getLatest(patientUUID, conceptList, numberOfVisits, obsIgnoreList, filterObsWithOrders, null); } else if (ObjectUtils.equals(scope, INITIAL)) { - observations = bahmniObsService.getInitial(patientUUID, rootConcepts, numberOfVisits, obsIgnoreList, filterObsWithOrders, null); + observations = bahmniObsService.getInitial(patientUUID, conceptList, numberOfVisits, obsIgnoreList, filterObsWithOrders, null); } else { - observations = bahmniObsService.observationsFor(patientUUID, rootConcepts, numberOfVisits, obsIgnoreList, filterObsWithOrders, null, null, null); + observations = bahmniObsService.observationsFor(patientUUID, conceptList, numberOfVisits, obsIgnoreList, filterObsWithOrders, null, null, null); } - sendObsToGroovyScript(getConceptNames(rootConcepts), observations); + sendObsToGroovyScript(getConceptNames(conceptList), observations); return observations; } + private List searchConceptsByName(List conceptNames, Locale searchLocale) { + Set conceptSet = new LinkedHashSet<>(); + if (CollectionUtils.isNotEmpty(conceptNames)) { + List localeList = Collections.singletonList(searchLocale); + for (String name : conceptNames) { + List conceptsSearchResult = conceptService.getConcepts(name, localeList, false, null, null, null, null, null, 0, null); + List conceptsByName = conceptsSearchResult.stream().map(conceptSearchResult -> conceptSearchResult.getConcept()).collect(Collectors.toList()); + conceptSet.addAll(conceptsByName); + } + } + return new ArrayList<>(conceptSet); + } + + private Locale identifyLocale(String locale) { + if (locale != null && !locale.isEmpty()) { + Locale searchLocale = LocaleUtility.fromSpecification(locale); + if (searchLocale.getLanguage().isEmpty()) { + throw new APIException("Invalid locale: " + locale); + } + return searchLocale; + } else { + return LocaleUtility.getDefaultLocale(); + } + } + @RequestMapping(method = RequestMethod.GET, params = {"visitUuid"}) @ResponseBody public Collection get(@RequestParam(value = "visitUuid", required = true) String visitUuid, From 6fa213cff637eba97687f8a6a8f1457ed373a14f Mon Sep 17 00:00:00 2001 From: vijayanandtwks <113415613+vijayanandtwks@users.noreply.github.com> Date: Fri, 15 Dec 2023 09:05:26 +0530 Subject: [PATCH 12/47] BAH-3336 | Patient Stage dropdown is empty in programs module [Env - Docker.standard] (#237) * BAH-3336 | Arjun, Vijay | fix patient stage dropdown showing empty results in programs module * BAH-3336 | Vijay, Gokul | incorporate deskcheck comments * BAH-3336 | Vijay | incorporate PR comments with additional constraint --- bahmnicore-omod/src/main/resources/liquibase.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/bahmnicore-omod/src/main/resources/liquibase.xml b/bahmnicore-omod/src/main/resources/liquibase.xml index 9afe7fcdd6..1589787665 100644 --- a/bahmnicore-omod/src/main/resources/liquibase.xml +++ b/bahmnicore-omod/src/main/resources/liquibase.xml @@ -4571,4 +4571,18 @@ + + + + SELECT COUNT(*) FROM program_attribute_type where name = 'Stage' AND datatype = + 'org.bahmni.module.bahmnicore.customdatatype.datatype.CodedConceptDatatype'; + + + Update datatype of patient stage program attribute type + + UPDATE program_attribute_type SET datatype = 'org.openmrs.customdatatype.datatype.ConceptDatatype' WHERE + name = 'Stage' AND datatype = 'org.bahmni.module.bahmnicore.customdatatype.datatype.CodedConceptDatatype'; + + + From 1d8a3ff0d6d3eb7cb329673afb6ddbddce5450c9 Mon Sep 17 00:00:00 2001 From: riyaTw <126869458+riyaTw@users.noreply.github.com> Date: Mon, 18 Dec 2023 19:43:08 +0530 Subject: [PATCH 13/47] Add. Accession number for lab test performed in OpenElis to orders table (#238) * BAH-3416 | Add. Accession number for lab test performed in OpenElis to orders table | [Riya/Sweety] * BAH-3416 | Refactor. Optimised code | [Riya/Sweety] * BAH-3416 | Refactor. Optimised code | [Riya/Sweety] --- .../worker/OpenElisAccessionEventWorker.java | 17 ++++++++ .../OpenElisAccessionEventWorkerTest.java | 43 +++++++++++++++++-- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorker.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorker.java index 74d1c75c8b..e1e5d15066 100644 --- a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorker.java +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorker.java @@ -250,6 +250,23 @@ private Obs createObsWith(String textValue, Concept concept, Date obsDateTime) { protected Set associateTestResultsToOrder(OpenElisAccession openElisAccession) throws ParseException { Encounter orderEncounter = encounterService.getEncounterByUuid(openElisAccession.getAccessionUuid()); + + if (!orderEncounter.getOrders().isEmpty()) { + for (OpenElisTestDetail testDetail : openElisAccession.getTestDetails()) { + if (testDetail == null || testDetail.getStatus() == null) { + continue; + } + for (Order order : orderEncounter.getOrders()) { + if (testDetail.getTestUuid().equals(order.getConcept().getUuid())) { + if ("Canceled".equals(testDetail.getStatus())) { + continue; + } + order.setAccessionNumber(openElisAccession.getAccessionUuid()); + } + } + } + } + final EncounterType labResultEncounterType = getLabResultEncounterType(); final Set allTests = openElisAccession.getTestDetails(); diff --git a/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorkerTest.java b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorkerTest.java index c87d993d9e..5192bd818d 100644 --- a/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorkerTest.java +++ b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorkerTest.java @@ -1,7 +1,5 @@ package org.bahmni.module.elisatomfeedclient.api.worker; -import java.util.HashMap; -import java.util.Map; import org.bahmni.module.elisatomfeedclient.api.Constants; import org.bahmni.module.elisatomfeedclient.api.ElisAtomFeedProperties; import org.bahmni.module.elisatomfeedclient.api.builder.OpenElisAccessionBuilder; @@ -35,8 +33,13 @@ import java.util.Arrays; import java.util.Collections; import java.util.Date; +import java.util.HashMap; import java.util.HashSet; - +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.mockito.Matchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -143,6 +146,38 @@ public void shouldUpdateEncounterWhenAccessionHasNewOrder() throws Exception { verify(bahmniVisitAttributeSaveCommand).save(previousEncounter); } + @Test + public void shouldUpdateEncounterWithAccessionNumberWhenItsGenerated() throws Exception { + Encounter orderEncounter = getEncounterWithTests("test1", "test2", "test3"); + final Visit visit = new Visit(); + visit.setId(1); + orderEncounter.setVisit(visit); + visit.setEncounters(new HashSet<>(Arrays.asList(orderEncounter))); + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder().withTestUuid("test1").build(); + OpenElisTestDetail test2 = new OpenElisTestDetailBuilder().withTestUuid("test2").build(); + OpenElisTestDetail test3 = new OpenElisTestDetailBuilder().withTestUuid("test3").build(); + test1.setStatus("Not started"); + test2.setStatus("Canceled"); + test3.setStatus("Not started"); + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withTestDetails(new HashSet<>(Arrays.asList(test1, test2, test3))).build(); + + stubAccession(openElisAccession); + when(encounterService.getEncounterByUuid(openElisAccession.getAccessionUuid())).thenReturn(orderEncounter); + when(accessionMapper.findOrInitializeVisit(any(Patient.class), any(Date.class), any(String.class))).thenReturn(visit); + when(encounterService.saveEncounter(orderEncounter)).thenReturn(orderEncounter); + accessionEventWorker.associateTestResultsToOrder(openElisAccession); + + List orderAccessionNumbers = orderEncounter.getOrders().stream() + .map(Order::getAccessionNumber) + .collect(Collectors.toList()); + + verify(encounterService, times(1)).getEncounterByUuid(openElisAccession.getAccessionUuid()); + + assertEquals("1234", orderAccessionNumbers.get(0)); + assertNotEquals("1234", orderAccessionNumbers.get(1)); + assertEquals("1234", orderAccessionNumbers.get(2)); + } + @Test public void shouldUpdateEncounterWhenAccessionHasRemovedOrderFromPreviousEncounter() throws Exception { Encounter previousEncounter = getEncounterWithTests("test1", "test2", "test3"); @@ -228,8 +263,10 @@ private Encounter getEncounterWithTests(String... testUuids) { for (String testUuid : testUuids) { Order order = new Order(); Concept concept = new Concept(); + concept.setId(123); concept.setUuid(testUuid); order.setConcept(concept); + order.setAccessionNumber(null); encounter.addOrder(order); encounter.setEncounterType(new EncounterType()); Patient patient = new Patient(); From 759e3dfe06d9b48c02da37db51fd4b240fdd11c6 Mon Sep 17 00:00:00 2001 From: riyaTw <126869458+riyaTw@users.noreply.github.com> Date: Thu, 21 Dec 2023 12:58:37 +0530 Subject: [PATCH 14/47] BAH-3416 | Fix. Add accession number for lab panel test --- .../api/worker/OpenElisAccessionEventWorker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorker.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorker.java index e1e5d15066..8b375970e3 100644 --- a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorker.java +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorker.java @@ -257,7 +257,7 @@ protected Set associateTestResultsToOrder(OpenElisAccession openElisA continue; } for (Order order : orderEncounter.getOrders()) { - if (testDetail.getTestUuid().equals(order.getConcept().getUuid())) { + if (testDetail.getTestUuid().equals(order.getConcept().getUuid()) || order.getConcept().getUuid().equals(testDetail.getPanelUuid())) { if ("Canceled".equals(testDetail.getStatus())) { continue; } From 3c1a9cd36b943384fa0a49d8217ff0649d118a8c Mon Sep 17 00:00:00 2001 From: SanoferSameera <79590907+SanoferSameera@users.noreply.github.com> Date: Wed, 27 Dec 2023 13:08:04 +0530 Subject: [PATCH 15/47] Updated. Bahmni java util version (#241) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 06d7e780de..9ed8e7821c 100644 --- a/pom.xml +++ b/pom.xml @@ -63,7 +63,7 @@ 1.3.0 1.3.0 1.0.0 - 0.94.3 + 0.94.4-SNAPSHOT 4.0.1 2.17.1 1.4.0 From d0b60bbdd5bf58a872b91836810f77190500ae43 Mon Sep 17 00:00:00 2001 From: SanoferSameera <79590907+SanoferSameera@users.noreply.github.com> Date: Wed, 3 Jan 2024 18:33:50 +0530 Subject: [PATCH 16/47] BAH-3361 | Updated. emrapi version (#242) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9ed8e7821c..1918cd8609 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.23.0 1.3.0 0.2.15 - 1.32.0 + 1.35.0-SNAPSHOT 1.5.0 2.6.2 1.18.20 From 21f340a806713bb4ccf94c8bccf857e22327f7c5 Mon Sep 17 00:00:00 2001 From: poojadeshpande01 <92026860+poojadeshpande01@users.noreply.github.com> Date: Wed, 10 Jan 2024 13:19:12 +0530 Subject: [PATCH 17/47] BAH 3407|Fix of locale issue in the visit search handler (#244) * BAH-3407|Fix locale issue in search handler * BAH-3407|Add null check for concept list * BAH-3407| Fix VisitFormsSearchHandlerTest test cases * BAH-3407 | Refactor. used conceptsByName method and fix tests * BAH-3407| Refactor. Usage of locale in VisitFormsSearchHandler * BAH-3407| Refactor. Usage of locale in VisitFormsSearchHandler and test * BAH-3407| Refactor. Use of searchLocale or default. * BAH-3407 | Refactor. get concept name in default locale if null in user locale * BAH-3407 | Extracted identify locale method to separate class * BAH-3407 | Fix. test failures * BAH-3407| Add tests for LocaleResolver class. * BAH-3407 | Add. test case for searching concept in default locale if match not found in user locale * BAH-3407| Refactor. Use of static identify locale method. * BAH-3407| Add check for concept to choose correct locale * BAH-3407| Fix VisitFormsSearchHandlerTest * BAH-3407 | Refactor. pass false instead of null * BAH-3407 | Fix. test failures --------- Co-authored-by: SanoferSameera --- .../service/impl/BahmniObsServiceImpl.java | 13 ++- .../bahmnicore/web/v1_0/LocaleResolver.java | 21 ++++ .../BahmniObservationsController.java | 15 +-- .../v1_0/search/VisitFormsSearchHandler.java | 37 ++++--- .../web/v1_0/LocaleResolverTest.java | 38 +++++++ .../search/VisitFormsSearchHandlerTest.java | 101 ++++++++++++++---- 6 files changed, 182 insertions(+), 43 deletions(-) create mode 100644 bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/LocaleResolver.java create mode 100644 bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/LocaleResolverTest.java diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImpl.java index 698b3db31a..5c9087d468 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImpl.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImpl.java @@ -18,8 +18,10 @@ import org.openmrs.api.ConceptService; import org.openmrs.api.ObsService; import org.openmrs.api.VisitService; +import org.openmrs.api.context.Context; import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.OMRSObsToBahmniObsMapper; +import org.openmrs.util.LocaleUtility; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -69,11 +71,20 @@ public Collection observationsFor(String patientUuid, Collect private List getConceptNames(Collection concepts) { List conceptNames = new ArrayList<>(); for (Concept concept : concepts) { - conceptNames.add(concept.getName().getName()); + if(concept != null) { + conceptNames.add(getConceptName(concept, Context.getLocale())); + } } return conceptNames; } + private String getConceptName(Concept concept, Locale searchLocale) { + if (concept.getName(searchLocale) != null) + return concept.getName(searchLocale).getName(); + else + return concept.getName(LocaleUtility.getDefaultLocale()).getName(); + } + @Override public Collection observationsFor(String patientUuid, Concept rootConcept, Concept childConcept, Integer numberOfVisits, Date startDate, Date endDate, String patientProgramUuid) { Collection encounters = programWorkflowService.getEncountersByPatientProgramUuid(patientProgramUuid); diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/LocaleResolver.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/LocaleResolver.java new file mode 100644 index 0000000000..cb53511c5a --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/LocaleResolver.java @@ -0,0 +1,21 @@ +package org.bahmni.module.bahmnicore.web.v1_0; + +import org.openmrs.api.APIException; +import org.openmrs.util.LocaleUtility; + +import java.util.Locale; + +public class LocaleResolver { + + public static Locale identifyLocale(String locale) { + if (locale != null && !locale.isEmpty()) { + Locale searchLocale = LocaleUtility.fromSpecification(locale); + if (searchLocale.getLanguage().isEmpty()) { + throw new APIException("Invalid locale: " + locale); + } + return searchLocale; + } else { + return LocaleUtility.getDefaultLocale(); + } + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniObservationsController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniObservationsController.java index 0af0d32376..b3ac3f1410 100644 --- a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniObservationsController.java +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniObservationsController.java @@ -6,6 +6,7 @@ import org.bahmni.module.bahmnicore.obs.ObservationsAdder; import org.bahmni.module.bahmnicore.service.BahmniObsService; import org.bahmni.module.bahmnicore.util.MiscUtils; +import org.bahmni.module.bahmnicore.web.v1_0.LocaleResolver; import org.openmrs.Concept; import org.openmrs.ConceptSearchResult; import org.openmrs.Visit; @@ -35,6 +36,8 @@ import java.util.Set; import java.util.stream.Collectors; +import static org.bahmni.module.bahmnicore.web.v1_0.LocaleResolver.identifyLocale; + @Controller @RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/observations") public class BahmniObservationsController extends BaseRestController { @@ -92,18 +95,6 @@ private List searchConceptsByName(List conceptNames, Locale sea return new ArrayList<>(conceptSet); } - private Locale identifyLocale(String locale) { - if (locale != null && !locale.isEmpty()) { - Locale searchLocale = LocaleUtility.fromSpecification(locale); - if (searchLocale.getLanguage().isEmpty()) { - throw new APIException("Invalid locale: " + locale); - } - return searchLocale; - } else { - return LocaleUtility.getDefaultLocale(); - } - } - @RequestMapping(method = RequestMethod.GET, params = {"visitUuid"}) @ResponseBody public Collection get(@RequestParam(value = "visitUuid", required = true) String visitUuid, diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/VisitFormsSearchHandler.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/VisitFormsSearchHandler.java index f0614a6eb8..4100ff7c5e 100644 --- a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/VisitFormsSearchHandler.java +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/VisitFormsSearchHandler.java @@ -2,12 +2,14 @@ import org.apache.commons.collections.CollectionUtils; import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.bahmni.module.bahmnicore.web.v1_0.LocaleResolver; import org.openmrs.Concept; import org.openmrs.Encounter; import org.openmrs.Obs; import org.openmrs.Patient; import org.openmrs.PatientProgram; import org.openmrs.Visit; +import org.openmrs.api.APIException; import org.openmrs.api.context.Context; import org.openmrs.module.episodes.Episode; import org.openmrs.module.episodes.service.EpisodeService; @@ -20,22 +22,22 @@ import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; import org.openmrs.module.webservices.rest.web.response.InvalidSearchException; import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.openmrs.util.LocaleUtility; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Locale; import static java.util.Arrays.asList; +import static org.bahmni.module.bahmnicore.web.v1_0.LocaleResolver.identifyLocale; @Component public class VisitFormsSearchHandler implements SearchHandler { @Autowired private EpisodeService episodeService; - private final String ALL_OBSERVATION_TEMPLATES = "All Observation Templates"; private final String QUERY_INFORMATION = "Allows you to search All Observation Templates by patientUuid"; @@ -52,6 +54,7 @@ public PageableResult search(RequestContext context) throws ResponseException { String patientProgramUuid = context.getRequest().getParameter("patientProgramUuid"); int numberOfVisits = Integer.parseInt(context.getRequest().getParameter("numberOfVisits")); String[] conceptNames = context.getRequest().getParameterValues("conceptNames"); + Locale searchLocale = identifyLocale(context.getRequest().getSession().getAttribute("locale").toString()); Patient patient = Context.getPatientService().getPatientByUuid(patientUuid); if (patient == null) { @@ -59,9 +62,14 @@ public PageableResult search(RequestContext context) throws ResponseException { } List conceptNamesList = new ArrayList<>(); if (conceptNames == null) { - conceptNamesList = getConcepts(Context.getConceptService().getConcept(ALL_OBSERVATION_TEMPLATES).getSetMembers()); + List concepts = Context.getConceptService().getConceptsByName(ALL_OBSERVATION_TEMPLATES, Locale.ENGLISH, false); + if(!concepts.isEmpty()){ + for (Concept concept : concepts) { + conceptNamesList = getConcepts(concept.getSetMembers(), searchLocale); + } + } } else { - conceptNamesList = Arrays.asList(conceptNames); + conceptNamesList = asList(conceptNames); } List encounterList; @@ -71,12 +79,12 @@ public PageableResult search(RequestContext context) throws ResponseException { encounterList = getEncountersFor(numberOfVisits, patient); } - List finalObsList = getObservations(patient, conceptNamesList, encounterList); + List finalObsList = getObservations(patient, conceptNamesList, encounterList, searchLocale); return new NeedsPaging(finalObsList, context); } - private List getObservations(Patient patient, List conceptNames, List encounterList) { + private List getObservations(Patient patient, List conceptNames, List encounterList, Locale searchLocale) { List finalObsList = new ArrayList<>(); if (CollectionUtils.isEmpty(encounterList)) { return finalObsList; @@ -86,8 +94,8 @@ private List getObservations(Patient patient, List conceptNames, Li for (Obs obs : initialObsList) { String name = null; - if(obs.getConcept()!= null && obs.getConcept().getFullySpecifiedName(Locale.ENGLISH) != null){ - name = obs.getConcept().getFullySpecifiedName(Locale.ENGLISH).getName(); + if(obs.getConcept()!= null){ + name = getConceptName(obs.getConcept(), searchLocale); } if (conceptNames.contains(name)) { finalObsList.add(obs); @@ -113,18 +121,23 @@ private List getEncountersWithinProgram(String patientProgramUuid) { return encounterList; } - private List getConcepts(List concepts) { + private List getConcepts(List concepts, Locale searchLocale) { List conceptNames = new ArrayList<>(); if (concepts == null) return conceptNames; - for (Concept concept : concepts) { - conceptNames.add(concept.getFullySpecifiedName(Locale.ENGLISH).getName()); + conceptNames.add(getConceptName(concept, searchLocale)); } - return conceptNames; } + private String getConceptName(Concept concept, Locale searchLocale) { + if(concept.getFullySpecifiedName(searchLocale) != null) + return concept.getFullySpecifiedName(searchLocale).getName(); + else + return concept.getFullySpecifiedName(LocaleUtility.getDefaultLocale()).getName(); + } + private List listOfVisitsNeeded(int numberOfVisits, Patient patient) { List visitsByPatient = Context.getVisitService().getVisitsByPatient(patient); int subsetVisits = numberOfVisits; diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/LocaleResolverTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/LocaleResolverTest.java new file mode 100644 index 0000000000..1cd47ee7b9 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/LocaleResolverTest.java @@ -0,0 +1,38 @@ +package org.bahmni.module.bahmnicore.web.v1_0; + +import static org.bahmni.module.bahmnicore.web.v1_0.LocaleResolver.identifyLocale; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import org.junit.Test; +import org.openmrs.util.LocaleUtility; + +import java.util.Locale; + +public class LocaleResolverTest { + + @Test + public void shouldReturnDefaultLocaleIfNull() { + Locale locale = identifyLocale(null); + assertEquals(LocaleUtility.getDefaultLocale(), locale); + } + + @Test + public void shouldReturnDefaultLocaleIfEmpty() { + Locale locale = identifyLocale(""); + assertEquals(LocaleUtility.getDefaultLocale(), locale); + } + + @Test + public void shouldReturnParsedLocaleIfValid() { + Locale locale = identifyLocale("en_US"); + assertEquals(new Locale("en", "US"), locale); + } + + @Test(expected = AssertionError.class) + public void shouldThrowExceptionIfInvalidLocale() { + identifyLocale("invalid"); + fail("Should have thrown exception"); + } + +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/VisitFormsSearchHandlerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/VisitFormsSearchHandlerTest.java index 3b5f9d66db..5135e6952c 100644 --- a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/VisitFormsSearchHandlerTest.java +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/VisitFormsSearchHandlerTest.java @@ -1,6 +1,7 @@ package org.bahmni.module.bahmnicore.web.v1_0.search; import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.bahmni.module.bahmnicore.web.v1_0.LocaleResolver; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -27,17 +28,21 @@ import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; import org.openmrs.module.webservices.rest.web.response.InvalidSearchException; +import org.openmrs.util.LocaleUtility; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Locale; +import static org.bahmni.module.bahmnicore.web.v1_0.LocaleResolver.identifyLocale; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @@ -50,8 +55,9 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; +import static org.powermock.api.mockito.PowerMockito.mockStatic; -@PrepareForTest(Context.class) +@PrepareForTest({Context.class, LocaleUtility.class, LocaleResolver.class}) @RunWith(PowerMockRunner.class) public class VisitFormsSearchHandlerTest { @@ -73,14 +79,18 @@ public class VisitFormsSearchHandlerTest { private BahmniProgramWorkflowService programWorkflowService; @Mock private EpisodeService episodeService; - private Patient patient; private Concept concept; private Obs obs; + private final List concepts = new ArrayList<>(); + private final String conceptNames = null; + @Before public void before() throws Exception { initMocks(this); + mockStatic(LocaleUtility.class); + mockStatic(LocaleResolver.class); setUp(); } @@ -98,10 +108,16 @@ public Obs createObs(Concept concept) { public void setUp() throws Exception { HttpServletRequest req = Mockito.mock(HttpServletRequest.class); + HttpSession session = Mockito.mock(HttpSession.class); + when(context.getLimit()).thenReturn(3); when(context.getRequest()).thenReturn(req); + when(context.getRequest().getSession()).thenReturn(session); when(context.getRequest().getParameter("patient")).thenReturn("patientUuid"); when(context.getRequest().getParameter("numberOfVisits")).thenReturn("10"); + when(context.getRequest().getSession().getAttribute("locale")).thenReturn(Locale.ENGLISH); + when(identifyLocale(any())).thenReturn(Locale.ENGLISH); + when(LocaleUtility.getDefaultLocale()).thenReturn(Locale.ENGLISH); String[] conceptNames = {"Vitals"}; when(context.getRequest().getParameterValues("conceptNames")).thenReturn(conceptNames); @@ -115,6 +131,8 @@ public void setUp() throws Exception { PowerMockito.when(Context.getConceptService()).thenReturn(conceptService); concept = createConcept("Vitals", "en"); + PowerMockito.when(identifyLocale(any())).thenReturn(Locale.ENGLISH); + Visit visit = new Visit(); PowerMockito.when(Context.getVisitService()).thenReturn(visitService); PowerMockito.when(Context.getVisitService().getVisitsByPatient(patient)).thenReturn(Arrays.asList(visit)); @@ -140,12 +158,40 @@ public void shouldSupportVersions1_10To2() { } @Test - public void shouldReturnConceptSpecificObsIfConceptNameIsSpecified() throws Exception { + public void shouldReturnConceptSpecificObsIfConceptNameIsSpecified() { String [] conceptNames = new String[]{"Vitals"}; when(context.getRequest().getParameterValues("conceptNames")).thenReturn(conceptNames); concept = createConcept("Vitals", "en"); - PowerMockito.when(conceptService.getConcept("All Observation Templates")).thenReturn(concept); + PowerMockito.when(obsService.getObservations(any(List.class), any(List.class), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(false))).thenReturn(Arrays.asList(obs)); + NeedsPaging searchResults = (NeedsPaging) visitFormsSearchHandler.search(context); + assertThat(searchResults.getPageOfResults().size(), is(equalTo(1))); + } + + @Test + public void shouldReturnConceptSpecificObsIfConceptNameIsFoundInUserLocale() { + PowerMockito.when(identifyLocale(any())).thenReturn(Locale.FRENCH); + + String [] conceptNames = new String[]{"Vitals_fr"}; + when(context.getRequest().getParameterValues("conceptNames")).thenReturn(conceptNames); + + Concept obsConcept = createConcept("Vitals_fr", "fr"); + Obs obs = createObs(obsConcept); + + PowerMockito.when(obsService.getObservations(any(List.class), any(List.class), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(false))).thenReturn(Arrays.asList(obs)); + NeedsPaging searchResults = (NeedsPaging) visitFormsSearchHandler.search(context); + assertThat(searchResults.getPageOfResults().size(), is(equalTo(1))); + } + + @Test + public void shouldReturnConceptSpecificObsIfConceptNameIsNullInUserLocaleButFoundInDefaultSearch() { + PowerMockito.when(identifyLocale(any())).thenReturn(Locale.FRENCH); + + String [] conceptNames = new String[]{"Vitals"}; + when(context.getRequest().getParameterValues("conceptNames")).thenReturn(conceptNames); + + Concept obsConcept = createConcept("Vitals", "en"); + Obs obs = createObs(obsConcept); PowerMockito.when(obsService.getObservations(any(List.class), any(List.class), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(false))).thenReturn(Arrays.asList(obs)); NeedsPaging searchResults = (NeedsPaging) visitFormsSearchHandler.search(context); @@ -153,7 +199,8 @@ public void shouldReturnConceptSpecificObsIfConceptNameIsSpecified() throws Exce } @Test - public void shouldReturnAllObsIfConceptNameIsNotSpecified() throws Exception { + public void shouldReturnConceptSpecificObsIfConceptNameIsFoundInDefaultLocale() { + PowerMockito.when(identifyLocale(any())).thenReturn(Locale.FRENCH); when(context.getRequest().getParameterValues("conceptNames")).thenReturn(null); @@ -162,7 +209,27 @@ public void shouldReturnAllObsIfConceptNameIsNotSpecified() throws Exception { Concept historyConcept = createConcept("History and Examination", "en"); parentConcept.addSetMember(historyConcept); - PowerMockito.when(conceptService.getConcept("All Observation Templates")).thenReturn(parentConcept); + when(conceptService.getConceptsByName("All Observation Templates", Locale.ENGLISH, false)).thenReturn(Arrays.asList(parentConcept)); + + Concept obsConcept = createConcept("History and Examination", "en"); + Obs obs = createObs(obsConcept); + + PowerMockito.when(obsService.getObservations(any(List.class), any(List.class), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(false))).thenReturn(Arrays.asList(obs)); + NeedsPaging searchResults = (NeedsPaging) visitFormsSearchHandler.search(context); + assertThat(searchResults.getPageOfResults().size(), is(equalTo(1))); + } + + @Test + public void shouldReturnAllObsIfConceptNameIsNotSpecified() { + + when(context.getRequest().getParameterValues("conceptNames")).thenReturn(null); + Concept parentConcept = new Concept(); + parentConcept.addSetMember(concept); + Concept historyConcept = createConcept("History and Examination", "en"); + parentConcept.addSetMember(historyConcept); + + when(conceptService.getConceptsByName("All Observation Templates", Locale.ENGLISH, false)).thenReturn(Arrays.asList(parentConcept)); + Obs obs2 = createObs(historyConcept); PowerMockito.when(obsService.getObservations(any(List.class), any(List.class), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(false))).thenReturn(Arrays.asList(obs, obs2)); @@ -171,7 +238,7 @@ public void shouldReturnAllObsIfConceptNameIsNotSpecified() throws Exception { } @Test - public void shouldReturnEmptyObservationsIfAllConceptNamesAreInvalid() throws Exception { + public void shouldReturnEmptyObservationsIfAllConceptNamesAreInvalid() { String[] conceptNames = {null, null}; when(context.getRequest().getParameterValues("conceptNames")).thenReturn(conceptNames); @@ -181,9 +248,7 @@ public void shouldReturnEmptyObservationsIfAllConceptNamesAreInvalid() throws Ex Concept historyConcept = createConcept("History and Examination", "en"); parentConcept.addSetMember(historyConcept); - PowerMockito.when(conceptService.getConcept("All Observation Templates")).thenReturn(parentConcept); PowerMockito.when(Context.getConceptService()).thenReturn(conceptService); - PowerMockito.when(conceptService.getConceptByName(null)).thenReturn(null); Obs obs2 = createObs(historyConcept); @@ -200,9 +265,9 @@ public void shouldThrowExceptionIfThePatienUuidIsNull(){ } @Test - public void shouldGetObservationsWithinThePatientProgramIfThePatientProgramUuidIsPassed() throws Exception { - when(conceptService.getConcept("All Observation Templates")).thenReturn(concept); + public void shouldGetObservationsWithinThePatientProgramIfThePatientProgramUuidIsPassed() { when(context.getRequest().getParameterValues("conceptNames")).thenReturn(null); + when(conceptService.getConceptsByName("conceptNames",Locale.ENGLISH,null)).thenReturn(concepts); String patientProgramUuid = "patient-program-uuid"; when(context.getRequest().getParameter("patientProgramUuid")).thenReturn(patientProgramUuid); when(Context.getService(BahmniProgramWorkflowService.class)).thenReturn(programWorkflowService); @@ -217,7 +282,7 @@ public void shouldGetObservationsWithinThePatientProgramIfThePatientProgramUuidI visitFormsSearchHandler.search(context); - verify(conceptService, times(1)).getConcept("All Observation Templates"); + verify(conceptService, times(1)).getConceptsByName("All Observation Templates",Locale.ENGLISH, false); verify(programWorkflowService, times(1)).getPatientProgramByUuid(patientProgramUuid); verify(episodeService, times(1)).getEpisodeForPatientProgram(patientProgram); verify(visitService, never()).getVisitsByPatient(patient); @@ -226,9 +291,9 @@ public void shouldGetObservationsWithinThePatientProgramIfThePatientProgramUuidI } @Test - public void shouldNotFetchAnyObservationsIfThereIsNoEpisodeForTheProgram() throws Exception { - when(conceptService.getConcept("All Observation Templates")).thenReturn(concept); + public void shouldNotFetchAnyObservationsIfThereIsNoEpisodeForTheProgram() { when(context.getRequest().getParameterValues("conceptNames")).thenReturn(null); + when(conceptService.getConceptsByName("conceptNames",Locale.ENGLISH, null)).thenReturn(concepts); String patientProgramUuid = "patient-program-uuid"; when(context.getRequest().getParameter("patientProgramUuid")).thenReturn(patientProgramUuid); when(Context.getService(BahmniProgramWorkflowService.class)).thenReturn(programWorkflowService); @@ -241,7 +306,7 @@ public void shouldNotFetchAnyObservationsIfThereIsNoEpisodeForTheProgram() throw visitFormsSearchHandler.search(context); - verify(conceptService, times(1)).getConcept("All Observation Templates"); + verify(conceptService, times(1)).getConceptsByName("All Observation Templates", Locale.ENGLISH, false); verify(programWorkflowService, times(1)).getPatientProgramByUuid(patientProgramUuid); verify(episodeService, times(1)).getEpisodeForPatientProgram(patientProgram); verify(visitService, never()).getVisitsByPatient(patient); @@ -250,8 +315,8 @@ public void shouldNotFetchAnyObservationsIfThereIsNoEpisodeForTheProgram() throw } @Test - public void shouldNotFetchAnyObservationsIfThereAreNoEncountersInEpisode() throws Exception { - when(conceptService.getConcept("All Observation Templates")).thenReturn(concept); + public void shouldNotFetchAnyObservationsIfThereAreNoEncountersInEpisode() { + when(conceptService.getConceptsByName(conceptNames, Locale.ENGLISH, null)).thenReturn(concepts); when(context.getRequest().getParameterValues("conceptNames")).thenReturn(null); String patientProgramUuid = "patient-program-uuid"; when(context.getRequest().getParameter("patientProgramUuid")).thenReturn(patientProgramUuid); @@ -266,7 +331,7 @@ public void shouldNotFetchAnyObservationsIfThereAreNoEncountersInEpisode() throw visitFormsSearchHandler.search(context); - verify(conceptService, times(1)).getConcept("All Observation Templates"); + verify(conceptService, times(1)).getConceptsByName("All Observation Templates", Locale.ENGLISH, false); verify(programWorkflowService, times(1)).getPatientProgramByUuid(patientProgramUuid); verify(episodeService, times(1)).getEpisodeForPatientProgram(patientProgram); verify(visitService, never()).getVisitsByPatient(patient); From 09a996c3d8573d6eb83778a3d263ec5f235f12d6 Mon Sep 17 00:00:00 2001 From: poojadeshpande01 <92026860+poojadeshpande01@users.noreply.github.com> Date: Fri, 12 Jan 2024 10:28:57 +0530 Subject: [PATCH 18/47] BAH 3455| Locale issue while sending request with diagnoses (#247) * Add locale of concept in BahmniDiagnosisMetadata * Fix tests of BahmniDiagnosisMetadataTest * Refactor import statement * Add Locale import statement * BAH-3455 | Refactored imports --------- Co-authored-by: SanoferSameera --- .../helper/BahmniDiagnosisMetadata.java | 16 +++++++++++----- .../helper/BahmniDiagnosisMetadataTest.java | 5 +++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/diagnosis/helper/BahmniDiagnosisMetadata.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/diagnosis/helper/BahmniDiagnosisMetadata.java index ea35d9169a..81be0b3332 100644 --- a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/diagnosis/helper/BahmniDiagnosisMetadata.java +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/diagnosis/helper/BahmniDiagnosisMetadata.java @@ -18,6 +18,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Set; import static java.util.stream.Collectors.toList; @@ -37,16 +38,21 @@ public class BahmniDiagnosisMetadata { private EncounterTransactionMapper encounterTransactionMapper; + private Concept getConceptsByNameAndLocale(String name, Locale locale) { + List conceptList = conceptService.getConceptsByName(name, locale, false); + return conceptList.isEmpty() ? null : conceptList.get(0); + } + public Concept getBahmniInitialDiagnosisConcept() { - return conceptService.getConceptByName(BAHMNI_INITIAL_DIAGNOSIS); + return getConceptsByNameAndLocale(BAHMNI_INITIAL_DIAGNOSIS, Locale.ENGLISH); } public Concept getBahmniDiagnosisRevisedConcept() { - return conceptService.getConceptByName(BAHMNI_DIAGNOSIS_REVISED); + return getConceptsByNameAndLocale(BAHMNI_DIAGNOSIS_REVISED, Locale.ENGLISH); } public Concept getBahmniDiagnosisStatusConcept() { - return conceptService.getConceptByName(BAHMNI_DIAGNOSIS_STATUS); + return getConceptsByNameAndLocale(BAHMNI_DIAGNOSIS_STATUS, Locale.ENGLISH); } @Autowired @@ -179,8 +185,8 @@ public Obs findMatchingDiagnosis(Collection observations, BahmniDiagnosis b private boolean isDiagnosisNotRevised(Obs obs) { return !obs.getGroupMembers(false).stream() .anyMatch(groupMember -> { - return groupMember.getConcept().equals(getBahmniDiagnosisRevisedConcept()) - && groupMember.getValueAsBoolean();}); + return groupMember.getConcept().equals(getBahmniDiagnosisRevisedConcept()) + && groupMember.getValueAsBoolean();}); } private boolean isDiagnosisMatching(Obs obs, EncounterTransaction.Diagnosis diagnosis) { diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/diagnosis/helper/BahmniDiagnosisMetadataTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/diagnosis/helper/BahmniDiagnosisMetadataTest.java index 0d2bb1f73b..ed831ba371 100644 --- a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/diagnosis/helper/BahmniDiagnosisMetadataTest.java +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/diagnosis/helper/BahmniDiagnosisMetadataTest.java @@ -32,6 +32,7 @@ import org.powermock.modules.junit4.PowerMockRunner; import java.util.Arrays; +import java.util.List; import java.util.Locale; import static org.hamcrest.CoreMatchers.is; @@ -82,7 +83,7 @@ public void shouldMatchCodedDiagnosis() { Obs diagnosisObs = new ObsBuilder().withConcept(diagnosisSetConcept) .withGroupMembers( - new ObsBuilder().withConcept(codedDiagnosisConcept) + new ObsBuilder().withConcept(codedDiagnosisConcept) .withValue(feverConcept).build(), new ObsBuilder().withConcept(conceptForName("Diagnosis Order")) .withValue(conceptForName("Primary")).build(), @@ -213,7 +214,7 @@ public void shouldNotConsiderRevisedObsWhileFindingMatchingObs() throws Exceptio when(properties.getDiagnosisMetadata().getCodedDiagnosisConcept()).thenReturn(codedDiagnosisConcept); when(properties.getDiagnosisMetadata().getNonCodedDiagnosisConcept()).thenReturn(nonCodedDiagnosisConcept); when(conceptService.getTrueConcept()).thenReturn(conceptTrue); - when(conceptService.getConceptByName(BAHMNI_DIAGNOSIS_REVISED)).thenReturn(revised); + when(conceptService.getConceptsByName(BAHMNI_DIAGNOSIS_REVISED,Locale.ENGLISH,false)).thenReturn(Arrays.asList(revised)); Concept feverConcept = conceptForName("Fever"); Obs aCodedDiagnosisObs = new ObsBuilder().withConcept(diagnosisSetConcept) From 18478dab03796c30f15e4b14820b4d99350e6a44 Mon Sep 17 00:00:00 2001 From: poojadeshpande01 <92026860+poojadeshpande01@users.noreply.github.com> Date: Mon, 22 Jan 2024 14:06:19 +0530 Subject: [PATCH 19/47] BAH-3473 | Locale Issue while uploading the patient visit document. (#248) * Add method to get concept by name and locale and refactor occurance. * Refactor import statement. * Add locale import statement. * Refactor Imports. * Add Locale Imports. --- .../service/impl/VisitDocumentServiceImpl.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/document/service/impl/VisitDocumentServiceImpl.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/document/service/impl/VisitDocumentServiceImpl.java index b674ec7075..87d1c00ebf 100644 --- a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/document/service/impl/VisitDocumentServiceImpl.java +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/document/service/impl/VisitDocumentServiceImpl.java @@ -29,7 +29,8 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -//comment + +import java.util.Locale; @Service public class VisitDocumentServiceImpl implements VisitDocumentService { @@ -87,8 +88,13 @@ private void linkDocumentAndImpressionObs(VisitDocumentRequest visitDocumentRequ } } + private Concept getConceptsByNameAndLocale(String name, Locale locale) { + List conceptList = conceptService.getConceptsByName(name, locale, false); + return conceptList.isEmpty() ? null : conceptList.get(0); + } + private void updateEncounter(Encounter encounter, Date encounterDateTime, List documents) { - Concept imageConcept = conceptService.getConceptByName(DOCUMENT_OBS_GROUP_CONCEPT_NAME); + Concept imageConcept = getConceptsByNameAndLocale(DOCUMENT_OBS_GROUP_CONCEPT_NAME, Locale.ENGLISH); for (Document document : documents) { Concept testConcept = conceptService.getConceptByUuid(document.getTestUuid()); From 9e641745a4f1ca1f5e7afa862e6f4940b8ea085b Mon Sep 17 00:00:00 2001 From: SanoferSameera <79590907+SanoferSameera@users.noreply.github.com> Date: Tue, 23 Jan 2024 11:05:08 +0530 Subject: [PATCH 20/47] BAH-3454 | Refactor. search concepts in both user and default locale (#249) * BAH-3454 | Refactor. search concepts in both user and default locale * BAH-3454 | Fix. test --- .../BahmniConceptSearchByDataTypeHandler.java | 24 ++++++++++++++++++- ...mniConceptSearchByDataTypeHandlerTest.java | 6 ++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchByDataTypeHandler.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchByDataTypeHandler.java index 1a0f4b5b24..af0b2c4f74 100644 --- a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchByDataTypeHandler.java +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchByDataTypeHandler.java @@ -4,6 +4,7 @@ import org.openmrs.ConceptDatatype; import org.openmrs.ConceptSearchResult; import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; import org.openmrs.module.webservices.rest.web.RequestContext; import org.openmrs.module.webservices.rest.web.RestConstants; import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; @@ -12,6 +13,7 @@ import org.openmrs.module.webservices.rest.web.resource.api.SearchQuery; import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.openmrs.util.LocaleUtility; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @@ -19,6 +21,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Locale; @Component public class BahmniConceptSearchByDataTypeHandler implements SearchHandler { @@ -54,8 +57,10 @@ public PageableResult search(RequestContext context) throws ResponseException { List concepts = new ArrayList<>(); + List localeList = getLocales(context); + List conceptsByName = - conceptService.getConcepts(conceptName, null, false, null, null, conceptDatatypes, null, null, context.getStartIndex(), context.getLimit()); + conceptService.getConcepts(conceptName, localeList, false, null, null, conceptDatatypes, null, null, context.getStartIndex(), context.getLimit()); for (ConceptSearchResult csr : conceptsByName) { if (csr.getConcept() != null) @@ -66,4 +71,21 @@ public PageableResult search(RequestContext context) throws ResponseException { } + private List getLocales(RequestContext context) { + String locale = context.getParameter("locale"); + + List localeList = new ArrayList<>(); + + if (locale != null) { + localeList.add(LocaleUtility.fromSpecification(locale)); + } else { + localeList.add(Context.getLocale()); + if (!LocaleUtility.getDefaultLocale().equals(Context.getLocale())) { + localeList.add(LocaleUtility.getDefaultLocale()); + } + } + + return localeList; + } + } diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchByDataTypeHandlerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchByDataTypeHandlerTest.java index 6458a0a987..bc0bc6f888 100644 --- a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchByDataTypeHandlerTest.java +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchByDataTypeHandlerTest.java @@ -16,6 +16,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Locale; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; @@ -68,12 +69,15 @@ public void shouldDelegateSearchOfConceptsToConceptService() { ConceptDatatype conceptDatatype = new ConceptDatatype(); conceptDatatype.setId(1); conceptDatatypes.add(conceptDatatype); + List localeList = new ArrayList<>(); + localeList.add(Locale.ENGLISH); when(conceptService.getConceptDatatypeByName(DATA_TYPES)).thenReturn(conceptDatatype); - when(conceptService.getConcepts(NAME, null, false, null, null, conceptDatatypes, + when(conceptService.getConcepts(NAME, localeList, false, null, null, conceptDatatypes, null, null, 0, 10)).thenReturn(conceptSearchResults); when(requestContext.getParameter("name")).thenReturn(NAME); when(requestContext.getParameter("dataTypes")).thenReturn(DATA_TYPES); + when(requestContext.getParameter("locale")).thenReturn(Locale.ENGLISH.toString()); when(requestContext.getLimit()).thenReturn(10); NeedsPaging searchResults = (NeedsPaging) bahmniConceptSearchByDataTypeHandler.search(requestContext); From 7ffa7d5fcfe165db5aff86d18b12deb988fc3ae5 Mon Sep 17 00:00:00 2001 From: SanoferSameera <79590907+SanoferSameera@users.noreply.github.com> Date: Tue, 30 Jan 2024 11:21:07 +0530 Subject: [PATCH 21/47] BAH-3499 | Add. diagnosis search in user locale (#250) --- .../bahmnicore/service/impl/TsConceptSearchServiceImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/TsConceptSearchServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/TsConceptSearchServiceImpl.java index ed4d7ee11a..0dca3fe209 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/TsConceptSearchServiceImpl.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/TsConceptSearchServiceImpl.java @@ -50,6 +50,10 @@ private List getDiagnosisConcepts(String query, Integer limit, Str Locale searchLocale = getSearchLocale(locale); List conceptSearchResults = emrConceptService.conceptSearch(query, LocaleUtility.getDefaultLocale(), null, diagnosisSets, conceptSources, limit); + if(!LocaleUtility.getDefaultLocale().equals(searchLocale)) { + conceptSearchResults.addAll(emrConceptService.conceptSearch(query, searchLocale, null, diagnosisSets, conceptSources, limit)); + } + ConceptSource conceptSource = conceptSources.isEmpty() ? null : conceptSources.get(0); return createListResponse(conceptSearchResults, conceptSource, searchLocale); } From 414cc2917e60131379112dc59e79842d7bc41d07 Mon Sep 17 00:00:00 2001 From: MOHANKUMAR T <31698165+mohan-13@users.noreply.github.com> Date: Mon, 5 Feb 2024 15:20:45 +0530 Subject: [PATCH 22/47] BAH-3513 | Fix. Disable encounter search when patient does not have visit (#251) * BAH-3513 | Fix. Disable encounter search when patient does not have visit. - When a new patient uuid without visit is passed, encounterSearch happens without any criteria leading to OutOfMemoryError. * BAH-3513 | Add. Message for the condition block added --- .../impl/BahmniFormDetailsServiceImpl.java | 6 +++ .../BahmniFormDetailsServiceImplTest.java | 43 +++++++++++-------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/service/impl/BahmniFormDetailsServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/service/impl/BahmniFormDetailsServiceImpl.java index c6d369459f..cb09203f9c 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/service/impl/BahmniFormDetailsServiceImpl.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/service/impl/BahmniFormDetailsServiceImpl.java @@ -57,6 +57,12 @@ public BahmniFormDetailsServiceImpl(PatientService patientService, VisitService public Collection getFormDetails(String patientUuid, FormType formType, int numberOfVisits) { Patient patient = getPatient(patientUuid); List visits = visitService.getVisitsByPatient(patient); + + //Warning: This check is needed to avoid getEncounters returning ALL non-voided encounters of all patients leading to OutOfMemoryError:Java Heap + //Refer: https://bahmni.atlassian.net/browse/BAH-3513 + if(visits.isEmpty()) + return Collections.emptyList(); + List limitedVisits = limitVisits(visits, numberOfVisits); List encounters = getEncounters(limitedVisits); diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/forms2/service/impl/BahmniFormDetailsServiceImplTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/forms2/service/impl/BahmniFormDetailsServiceImplTest.java index 5ec1a9a612..84d96f4bc6 100644 --- a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/forms2/service/impl/BahmniFormDetailsServiceImplTest.java +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/forms2/service/impl/BahmniFormDetailsServiceImplTest.java @@ -166,14 +166,36 @@ public void shouldReturnFormDetailsGivenPatientUuidFormTypeAsV2AndNumberOfVisits @Test public void shouldReturnEmptyCollectionsOfFormDetailsIfPatientDoesNotHaveVisits() { when(visitService.getVisitsByPatient(patient)).thenReturn(Collections.emptyList()); - shouldReturnEmptyCollectionsOfFormDetailsIfPatientDoesNotHaveVisitsOrEncounters(); + Collection formDetailsCollection = bahmniFormDetailsService.getFormDetails(patientUuid, FormType.FORMS2, -1); + + assertEquals(0, formDetailsCollection.size()); + + verify(patientService, times(1)).getPatientByUuid(patientUuid); + verify(visitService, times(1)).getVisitsByPatient(patient); + verify(encounterService, times(0)).getEncounters(any(EncounterSearchCriteria.class)); + + verify(patient, times(0)).getPerson(); + verify(obsService, times(0)).getObservations(anyListOf(Person.class), + anyListOf(Encounter.class), any(), any(), any(), any(), any(), any(), any(), any(), any(), + any(Boolean.class)); } @Test public void shouldReturnEmptyCollectionsOfFormDetailsIfPatientDoesNotHaveEncounters() { when(encounterService.getEncounters(any(EncounterSearchCriteria.class))).thenReturn(Collections.emptyList()); - shouldReturnEmptyCollectionsOfFormDetailsIfPatientDoesNotHaveVisitsOrEncounters(); + Collection formDetailsCollection = bahmniFormDetailsService.getFormDetails(patientUuid, FormType.FORMS2, -1); + + assertEquals(0, formDetailsCollection.size()); + + verify(patientService, times(1)).getPatientByUuid(patientUuid); + verify(visitService, times(1)).getVisitsByPatient(patient); + verify(encounterService, times(1)).getEncounters(any(EncounterSearchCriteria.class)); + + verify(patient, times(0)).getPerson(); + verify(obsService, times(0)).getObservations(anyListOf(Person.class), + anyListOf(Encounter.class), any(), any(), any(), any(), any(), any(), any(), any(), any(), + any(Boolean.class)); } @Test @@ -314,21 +336,4 @@ private void verifyCommonMockCalls() { any(Boolean.class)); } - private void shouldReturnEmptyCollectionsOfFormDetailsIfPatientDoesNotHaveVisitsOrEncounters() { - - Collection formDetailsCollection = bahmniFormDetailsService.getFormDetails(patientUuid, FormType.FORMS2, -1); - - assertEquals(0, formDetailsCollection.size()); - - verify(patientService, times(1)).getPatientByUuid(patientUuid); - verify(visitService, times(1)).getVisitsByPatient(patient); - verify(encounterService, times(1)).getEncounters(any(EncounterSearchCriteria.class)); - - verify(patient, times(0)).getPerson(); - verify(obsService, times(0)).getObservations(anyListOf(Person.class), - anyListOf(Encounter.class), any(), any(), any(), any(), any(), any(), any(), any(), any(), - any(Boolean.class)); - - } - } From 0947dbe863690da38a9f8a0f1774bee3b9356f76 Mon Sep 17 00:00:00 2001 From: Parvathy Babu <102500787+parvathy00@users.noreply.github.com> Date: Thu, 29 Feb 2024 13:11:19 +0530 Subject: [PATCH 23/47] BAH-3606 | Add. panelName property in tabularResult (#254) --- .../laborder/contract/LabOrderResults.java | 2 +- .../laborder/contract/TabularLabOrderResults.java | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/contract/LabOrderResults.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/contract/LabOrderResults.java index 8f029fb640..828b99ccae 100644 --- a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/contract/LabOrderResults.java +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/contract/LabOrderResults.java @@ -33,7 +33,7 @@ private TabularLabOrderResults tabulate() { dateMap.put(orderDate, new TabularLabOrderResults.DateLabel(dateLabelIndexCounter++, orderDate.toString("dd-MMM-yyyy"))); } if(orderMap.get(result.getTestName()) == null) { - orderMap.put(result.getTestName(), new TabularLabOrderResults.TestOrderLabel(testOrderLabelCounter++, result.getTestName(), result.getMinNormal(), result.getMaxNormal(), result.getTestUnitOfMeasurement())); + orderMap.put(result.getTestName(), new TabularLabOrderResults.TestOrderLabel(testOrderLabelCounter++, result.getTestName(), result.getMinNormal(), result.getMaxNormal(), result.getTestUnitOfMeasurement(), result.getPanelName())); } if(result.getResult() != null || result.getReferredOut() || result.getUploadedFileName() != null) { diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/contract/TabularLabOrderResults.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/contract/TabularLabOrderResults.java index 2d89b5e0ec..3dd72e608e 100644 --- a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/contract/TabularLabOrderResults.java +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/contract/TabularLabOrderResults.java @@ -55,18 +55,21 @@ public static class TestOrderLabel { private Double minNormal; private Double maxNormal; private String testUnitOfMeasurement; + private String panelName; @JsonCreator public TestOrderLabel(@JsonProperty("index")Integer index, @JsonProperty("testName")String testName, @JsonProperty("minNormal")Double minNormal, @JsonProperty("maxNormal")Double maxNormal, - @JsonProperty("testUnitOfMeasurement")String testUnitOfMeasurement) { + @JsonProperty("testUnitOfMeasurement")String testUnitOfMeasurement, + @JsonProperty("panelName")String panelName) { this.index = index; this.testName = testName; this.minNormal = minNormal; this.maxNormal = maxNormal; this.testUnitOfMeasurement = testUnitOfMeasurement; + this.panelName = panelName; } public Integer getIndex() { @@ -108,8 +111,15 @@ public String getTestUnitOfMeasurement() { public void setTestUnitOfMeasurement(String testUnitOfMeasurement) { this.testUnitOfMeasurement = testUnitOfMeasurement; } - } + public String getPanelName() { + return panelName; + } + + public void setPanelName(String panelName) { + this.panelName = panelName; + } + } public static class CoordinateValue { private Date accessionDateTime; From 7408af9044b2ccb71a319989d54743a63ec36f56 Mon Sep 17 00:00:00 2001 From: Parvathy Babu <102500787+parvathy00@users.noreply.github.com> Date: Tue, 26 Mar 2024 15:56:28 +0530 Subject: [PATCH 24/47] Parvathy | BAH-2833 | Add. Size Limit To The Patient Documents (#256) --- .../controller/VisitDocumentController.java | 15 ++++- .../VisitDocumentControllerTest.java | 63 ++++++++++++++++++- pom.xml | 6 ++ 3 files changed, 78 insertions(+), 6 deletions(-) diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentController.java index a036ca94a0..2051eb46d1 100644 --- a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentController.java +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentController.java @@ -35,6 +35,7 @@ public class VisitDocumentController extends BaseRestController { private static final String INSUFFICIENT_PRIVILEGE = "Insufficient privilege"; private static final String INVALID_USER_PRIVILEGE = "User [%d] does not have required privilege to delete patient file [%s]"; private final String baseVisitDocumentUrl = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/visitDocument"; + @Autowired private VisitDocumentService visitDocumentService; @@ -62,23 +63,31 @@ public VisitDocumentResponse save(@RequestBody VisitDocumentRequest visitDocumen @RequestMapping(method = RequestMethod.POST, value = baseVisitDocumentUrl + "/uploadDocument") @ResponseBody - public HashMap saveDocument(@RequestBody Document document) { + public ResponseEntity> saveDocument(@RequestBody Document document) { try { - HashMap savedDocument = new HashMap<>(); + HashMap savedDocument = new HashMap<>(); Patient patient = Context.getPatientService().getPatientByUuid(document.getPatientUuid()); String encounterTypeName = document.getEncounterTypeName(); + Long maxDocumentSizeMb = Long.parseLong(System.getenv("DOCUMENT_MAX_SIZE_MB")); + Long maxDocumentSizeBytes = maxDocumentSizeMb * 1024 * 1024; + if (StringUtils.isEmpty(encounterTypeName)) { encounterTypeName = administrationService.getGlobalProperty("bahmni.encounterType.default"); } String fileName = sanitizeFileName(document.getFileName()); Paths.get(fileName); + if (document.getContent().length() > maxDocumentSizeBytes) { + logger.warn("Uploaded document size is greater than the maximum size " + maxDocumentSizeMb + "MB"); + savedDocument.put("maxDocumentSizeMB", maxDocumentSizeMb); + return new ResponseEntity<>(savedDocument, HttpStatus.PAYLOAD_TOO_LARGE); + } // Old files will follow: patientid-encounterName-uuid.ext (eg. 6-Patient-Document-706a448b-3f10-11e4-adec-0800271c1b75.png) // New ones will follow: patientid_encounterName_uuid__filename.ext (eg. 6-Patient-Document-706a448b-3f10-11e4-adec-0800271c1b75__doc1.png) String url = patientDocumentService.saveDocument(patient.getId(), encounterTypeName, document.getContent(), document.getFormat(), document.getFileType(), fileName); savedDocument.put("url", url); - return savedDocument; + return new ResponseEntity<>(savedDocument, HttpStatus.OK); } catch (Exception e) { throw new InvalidInputException("Could not save patient document", e); } diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentControllerTest.java index 1e03acc5f9..e0ed25b547 100644 --- a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentControllerTest.java +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentControllerTest.java @@ -7,6 +7,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.contrib.java.lang.system.EnvironmentVariables; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.InjectMocks; @@ -29,13 +30,14 @@ import org.springframework.http.ResponseEntity; import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.any; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; +import java.util.Base64; import java.util.HashMap; @PrepareForTest(Context.class) @@ -59,9 +61,15 @@ public class VisitDocumentControllerTest { @Rule public ExpectedException expectedException = ExpectedException.none(); + @Rule + public final EnvironmentVariables environmentVariables + = new EnvironmentVariables(); + + @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); + environmentVariables.set("DOCUMENT_MAX_SIZE_MB","7"); } @Test @@ -189,9 +197,10 @@ public void shouldSaveIfFileNameNotWithSpecialCharsOtherThanDashAndUnderscoreIsP Document document = new Document("abcd", "jpeg", "consultation", "patient-uuid", "image", "file-name"); - HashMap mapWithUrl = visitDocumentController.saveDocument(document); + ResponseEntity> responseEntity = visitDocumentController.saveDocument(document); + HashMap mapWithUrl = responseEntity.getBody(); if (mapWithUrl!=null) { - String documentSavedPath = mapWithUrl.get("url"); + String documentSavedPath = (String) mapWithUrl.get("url"); if (documentSavedPath!=null) { assertTrue(documentSavedPath.endsWith("__file-name.jpeg")); } @@ -202,4 +211,52 @@ public void shouldSaveIfFileNameNotWithSpecialCharsOtherThanDashAndUnderscoreIsP verify(patientDocumentService, times(1)).saveDocument(1, "consultation", "abcd", "jpeg", document.getFileType(), document.getFileName()); } + @Test + public void shouldReturn413PayloadTooLargeIfDocumentSizeExceedsLimit() throws Exception { + PowerMockito.mockStatic(Context.class); + when(Context.getPatientService()).thenReturn(patientService); + + Patient patient = new Patient(); + patient.setId(1); + patient.setUuid("patient-uuid"); + when(patientService.getPatientByUuid("patient-uuid")).thenReturn(patient); + + when(administrationService.getGlobalProperty("bahmni.encounterType.default")).thenReturn("consultation"); + + Document document = new Document("abcd", "jpeg", null, "patient-uuid", "image", "file-name"); + + byte[] largeContent = new byte[8 * 1024 * 1024]; + String base64Content = Base64.getEncoder().encodeToString(largeContent); + document.setContent(base64Content); + System.out.println(document.getContent().length()); + + ResponseEntity> responseEntity = visitDocumentController.saveDocument(document); + + Assert.assertEquals(HttpStatus.PAYLOAD_TOO_LARGE, responseEntity.getStatusCode()); + } + + @Test + public void shouldSaveDocumentIfDocumentSizeIsLessThanSizeLimit() throws Exception { + PowerMockito.mockStatic(Context.class); + when(Context.getPatientService()).thenReturn(patientService); + + Patient patient = new Patient(); + patient.setId(1); + patient.setUuid("patient-uuid"); + when(patientService.getPatientByUuid("patient-uuid")).thenReturn(patient); + + when(administrationService.getGlobalProperty("bahmni.encounterType.default")).thenReturn("consultation"); + + Document document = new Document("abcd", "jpeg", null, "patient-uuid", "image", "file-name"); + + byte[] largeContent = new byte[2 * 1024 * 1024]; + String base64Content = Base64.getEncoder().encodeToString(largeContent); + document.setContent(base64Content); + + ResponseEntity> responseEntity = visitDocumentController.saveDocument(document); + + Assert.assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + + verify(patientDocumentService, times(1)).saveDocument(1, "consultation", base64Content, "jpeg", document.getFileType(), document.getFileName()); + } } diff --git a/pom.xml b/pom.xml index 1918cd8609..1b33d663f6 100644 --- a/pom.xml +++ b/pom.xml @@ -312,6 +312,12 @@ pom test + + com.github.stefanbirkner + system-rules + 1.19.0 + test + org.openmrs.tools openmrs-tools From 450a43b22b08053eb148ab52b246ccded9ad0183 Mon Sep 17 00:00:00 2001 From: Parvathy Babu <102500787+parvathy00@users.noreply.github.com> Date: Fri, 29 Mar 2024 17:08:57 +0530 Subject: [PATCH 25/47] Parvathy | BAH-3720 | Fix. applicationDataDirectory File Path (#257) --- .../bahmnicore/dao/impl/ApplicationDataDirectoryImpl.java | 6 +++++- .../api/worker/OpenElisAccessionEventWorker.java | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/ApplicationDataDirectoryImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/ApplicationDataDirectoryImpl.java index 5ddc3fbdaf..c29fefce6e 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/ApplicationDataDirectoryImpl.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/ApplicationDataDirectoryImpl.java @@ -9,7 +9,11 @@ public class ApplicationDataDirectoryImpl implements ApplicationDataDirectory { @Override public File getFile(String relativePath) { - return new File(OpenmrsUtil.getApplicationDataDirectory() + relativePath); + String applicationDataDirectory = OpenmrsUtil.getApplicationDataDirectory(); + if (!applicationDataDirectory.endsWith(File.separator)) { + applicationDataDirectory += File.separator; + } + return new File(applicationDataDirectory + relativePath); } @Override diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorker.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorker.java index 8b375970e3..0f35f094df 100644 --- a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorker.java +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorker.java @@ -143,7 +143,11 @@ public void process(Event event) { void runInterceptor(Class className, Object object) { GroovyClassLoader gcl = new GroovyClassLoader(); - File directory = new File(OpenmrsUtil.getApplicationDataDirectory() + "elisFeedInterceptor"); + String applicationDataDirectory = OpenmrsUtil.getApplicationDataDirectory(); + if (!applicationDataDirectory.endsWith(File.separator)) { + applicationDataDirectory += File.separator; + } + File directory = new File(applicationDataDirectory + "elisFeedInterceptor"); File[] files = directory.listFiles(); if (files != null) { for (File file : files) { From 0b4ce7dfd2be1f74fa142691cebbecff0c3790c6 Mon Sep 17 00:00:00 2001 From: Parvathy Babu <102500787+parvathy00@users.noreply.github.com> Date: Fri, 29 Mar 2024 17:46:54 +0530 Subject: [PATCH 26/47] Parvathy | BAH-3720 | Fix. Append applicationDataDirectory File Path With File Separator (#258) --- .../bahmnicore/dao/impl/ApplicationDataDirectoryImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/ApplicationDataDirectoryImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/ApplicationDataDirectoryImpl.java index c29fefce6e..2cfa4627e7 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/ApplicationDataDirectoryImpl.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/ApplicationDataDirectoryImpl.java @@ -10,7 +10,7 @@ public class ApplicationDataDirectoryImpl implements ApplicationDataDirectory { @Override public File getFile(String relativePath) { String applicationDataDirectory = OpenmrsUtil.getApplicationDataDirectory(); - if (!applicationDataDirectory.endsWith(File.separator)) { + if (!applicationDataDirectory.endsWith(File.separator) && !relativePath.startsWith(File.separator)) { applicationDataDirectory += File.separator; } return new File(applicationDataDirectory + relativePath); From 3645144a2a48bb0099f5d68a9228b2a03437d93b Mon Sep 17 00:00:00 2001 From: Parvathy Babu <102500787+parvathy00@users.noreply.github.com> Date: Thu, 4 Apr 2024 10:29:53 +0530 Subject: [PATCH 27/47] BAH-2833 | Fix. Handle Error Due To Empty Document Size Limit In Bahmni Standard (#259) --- .../v1_0/controller/VisitDocumentController.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentController.java index 2051eb46d1..080e759682 100644 --- a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentController.java +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentController.java @@ -68,8 +68,7 @@ public ResponseEntity> saveDocument(@RequestBody Documen HashMap savedDocument = new HashMap<>(); Patient patient = Context.getPatientService().getPatientByUuid(document.getPatientUuid()); String encounterTypeName = document.getEncounterTypeName(); - Long maxDocumentSizeMb = Long.parseLong(System.getenv("DOCUMENT_MAX_SIZE_MB")); - Long maxDocumentSizeBytes = maxDocumentSizeMb * 1024 * 1024; + String maxDocumentSize = System.getenv("DOCUMENT_MAX_SIZE_MB"); if (StringUtils.isEmpty(encounterTypeName)) { encounterTypeName = administrationService.getGlobalProperty("bahmni.encounterType.default"); @@ -77,10 +76,14 @@ public ResponseEntity> saveDocument(@RequestBody Documen String fileName = sanitizeFileName(document.getFileName()); Paths.get(fileName); - if (document.getContent().length() > maxDocumentSizeBytes) { - logger.warn("Uploaded document size is greater than the maximum size " + maxDocumentSizeMb + "MB"); - savedDocument.put("maxDocumentSizeMB", maxDocumentSizeMb); - return new ResponseEntity<>(savedDocument, HttpStatus.PAYLOAD_TOO_LARGE); + if (!StringUtils.isEmpty(maxDocumentSize)) { + Long maxDocumentSizeMb = Long.parseLong(maxDocumentSize); + Long maxDocumentSizeBytes = maxDocumentSizeMb * 1024 * 1024; + if (document.getContent().length() > maxDocumentSizeBytes) { + logger.warn("Uploaded document size is greater than the maximum size " + maxDocumentSizeMb + "MB"); + savedDocument.put("maxDocumentSizeMB", maxDocumentSizeMb); + return new ResponseEntity<>(savedDocument, HttpStatus.PAYLOAD_TOO_LARGE); + } } // Old files will follow: patientid-encounterName-uuid.ext (eg. 6-Patient-Document-706a448b-3f10-11e4-adec-0800271c1b75.png) // New ones will follow: patientid_encounterName_uuid__filename.ext (eg. 6-Patient-Document-706a448b-3f10-11e4-adec-0800271c1b75__doc1.png) From 8c6391db4f33f75864431e207ffbdd6cb80d8927 Mon Sep 17 00:00:00 2001 From: deepthi-mantena <96411257+deepthi-mantena@users.noreply.github.com> Date: Thu, 4 Apr 2024 14:30:54 +0530 Subject: [PATCH 28/47] Deepthi M|BAH-3706| Updated openmrsAtomfeedVersion to 2.6.3. (#260) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1b33d663f6..8f16b17f7a 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 0.2.15 1.35.0-SNAPSHOT 1.5.0 - 2.6.2 + 2.6.3 1.18.20 4.7.0 1.13.0 From cb426078dda10b6135adde5eec49cec2f18e626f Mon Sep 17 00:00:00 2001 From: kavitha-sundararajan <90255023+kavitha-sundararajan@users.noreply.github.com> Date: Tue, 7 May 2024 12:09:07 +0530 Subject: [PATCH 29/47] BAH-3117 | Ability to add, edit and delete notes in OT module (#261) * BAH-3117|Bindu|Ability to add, edit, delete notes for OT module * BAH-3117| void and create note when provider is not matching --- .../contract/NoteRequestResponse.java | 78 +++++++++++ .../bahmni/module/bahmnicore/dao/NoteDao.java | 29 ++++ .../bahmnicore/dao/impl/NoteDaoImpl.java | 106 +++++++++++++++ .../module/bahmnicore/mapper/NoteMapper.java | 34 +++++ .../bahmni/module/bahmnicore/model/Note.java | 127 ++++++++++++++++++ .../module/bahmnicore/model/NoteType.java | 43 ++++++ .../bahmnicore/service/NoteService.java | 47 +++++++ .../service/impl/NoteServiceImpl.java | 109 +++++++++++++++ .../bahmnicore/validator/NoteValidator.java | 42 ++++++ .../src/main/resources/NoteType.hbm.xml | 33 +++++ .../src/main/resources/Notes.hbm.xml | 44 ++++++ .../resources/moduleApplicationContext.xml | 34 +++++ .../service/impl/NoteServiceImplIT.java | 123 +++++++++++++++++ .../validator/NoteValidatorTest.java | 101 ++++++++++++++ .../src/test/resources/notesData.xml | 7 + .../src/test/resources/test-hibernate.cfg.xml | 2 + .../controller/BahmniNotesController.java | 89 ++++++++++++ bahmnicore-omod/src/main/resources/config.xml | 4 +- .../src/main/resources/liquibase.xml | 94 +++++++++++++ 19 files changed, 1145 insertions(+), 1 deletion(-) create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/NoteRequestResponse.java create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/NoteDao.java create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/NoteDaoImpl.java create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/NoteMapper.java create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/Note.java create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/NoteType.java create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/NoteService.java create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/NoteServiceImpl.java create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/validator/NoteValidator.java create mode 100644 bahmnicore-api/src/main/resources/NoteType.hbm.xml create mode 100644 bahmnicore-api/src/main/resources/Notes.hbm.xml create mode 100644 bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/NoteServiceImplIT.java create mode 100644 bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/validator/NoteValidatorTest.java create mode 100644 bahmnicore-api/src/test/resources/notesData.xml create mode 100644 bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniNotesController.java diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/NoteRequestResponse.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/NoteRequestResponse.java new file mode 100644 index 0000000000..be92dddd13 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/NoteRequestResponse.java @@ -0,0 +1,78 @@ +package org.bahmni.module.bahmnicore.contract; + +import java.util.Date; + +public class NoteRequestResponse { + + private String uuid; + + private Integer noteId; + + private String noteText; + + private String noteTypeName; + + private Date noteDate; + + private String LocationName; + + private String providerUuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public Integer getNoteId() { + return noteId; + } + + public void setNoteId(Integer noteId) { + this.noteId = noteId; + } + + public String getNoteText() { + return noteText; + } + + public void setNoteText(String noteText) { + this.noteText = noteText; + } + + public Date getNoteDate() { + return noteDate; + } + + public void setNoteDate(Date noteDate) { + this.noteDate = noteDate; + } + + public String getNoteTypeName() { + return noteTypeName; + } + + public void setNoteTypeName(String noteTypeName) { + this.noteTypeName = noteTypeName; + } + + public String getLocationName() { + return LocationName; + } + + public void setLocationName(String locationName) { + LocationName = locationName; + } + + public String getProviderUuid() { + return providerUuid; + } + + public void setProviderUuid(String providerUuid) { + this.providerUuid = providerUuid; + } +} + + diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/NoteDao.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/NoteDao.java new file mode 100644 index 0000000000..3cc137c4ff --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/NoteDao.java @@ -0,0 +1,29 @@ +package org.bahmni.module.bahmnicore.dao; + +import java.util.Date; +import java.util.List; + +import org.bahmni.module.bahmnicore.model.Note; +import org.bahmni.module.bahmnicore.model.NoteType; +import org.openmrs.api.db.DAOException; + +public interface NoteDao { + + Note createNote(Note note); + + Note getNoteById(Integer noteId); + + Note updateNote(Note note); + + void deleteNote(Note note); + + Note voidNote(Note note); + + Note getNote(Date noteDate, String noteType); + + NoteType getNoteType(String name); + + List getNotes(Date startDate, Date endDate, String noteType); + + Note getNoteByUuid(String uuid); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/NoteDaoImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/NoteDaoImpl.java new file mode 100644 index 0000000000..793f05a61d --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/NoteDaoImpl.java @@ -0,0 +1,106 @@ +package org.bahmni.module.bahmnicore.dao.impl; + + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.bahmni.module.bahmnicore.dao.NoteDao; +import org.bahmni.module.bahmnicore.model.Note; +import org.bahmni.module.bahmnicore.model.NoteType; +import org.hibernate.query.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.openmrs.api.APIException; + +public class NoteDaoImpl implements NoteDao { + + protected final static Log log = LogFactory.getLog(NoteDaoImpl.class); + + private SessionFactory sessionFactory; + + public NoteDaoImpl() { + } + + public void setSessionFactory(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + public Note getNoteById(Integer id) { + log.info("Get note " + id); + return (Note) sessionFactory.getCurrentSession().get(Note.class, id); + } + + public Note createNote(Note note) { + log.debug("Creating new note"); + sessionFactory.getCurrentSession().save(note); + return note; + } + + public NoteType getNoteType(String name){ + List noteType = new ArrayList<>(); + Session currentSession = sessionFactory.getCurrentSession(); + Query query = currentSession.createQuery("select noteType from NoteType noteType " + + "where noteType.name = :name"); + query.setParameter("name", name); + noteType.addAll(query.list()); + return CollectionUtils.isEmpty(noteType) ? null : noteType.get(0); + + } + + public Note updateNote(Note note) { + log.debug("Updating existing note"); + sessionFactory.getCurrentSession().save(note); + return note; + } + + public void deleteNote(Note note) { + log.debug("Deleting existing note"); + sessionFactory.getCurrentSession().delete(note); + } + + public Note voidNote(Note note) throws APIException { + sessionFactory.getCurrentSession().save(note); + return note; + } + + @Override + public Note getNote(Date noteDate, String noteType) { + List notes = new ArrayList<>(); + StringBuilder query = new StringBuilder("select note from Note note " + + "where note.noteDate = :noteDate " + + "and note.noteType.name = :noteType " + + "and note.voided = false"); + + Query queryToGetNotes = sessionFactory.getCurrentSession().createQuery(query.toString()); + queryToGetNotes.setParameter("noteDate", noteDate); + queryToGetNotes.setParameter("noteType", noteType); + + notes.addAll(queryToGetNotes.list()); + return CollectionUtils.isEmpty(notes) ? null : notes.get(0); + } + + @Override + public List getNotes(Date startDate, Date endDate, String noteType) { + List notes = new ArrayList<>(); + Session currentSession = sessionFactory.getCurrentSession(); + Query query = currentSession.createQuery( + "select note from Note note " + + "where note.noteDate between :startDate and :endDate " + + "and note.noteType.name = :noteType" + + " and note.voided = false"); + query.setParameter("startDate", startDate); + query.setParameter("endDate", endDate); + query.setParameter("noteType", noteType); + notes.addAll(query.list()); + return notes; + + } + @Override + public Note getNoteByUuid(String uuid) { + return (Note)this.sessionFactory.getCurrentSession().createQuery("from Note note where note.uuid = :uuid").setParameter("uuid", uuid).uniqueResult(); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/NoteMapper.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/NoteMapper.java new file mode 100644 index 0000000000..52a59afc41 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/NoteMapper.java @@ -0,0 +1,34 @@ +package org.bahmni.module.bahmnicore.mapper; + +import org.bahmni.module.bahmnicore.contract.NoteRequestResponse; +import org.bahmni.module.bahmnicore.model.Note; +import org.bahmni.module.bahmnicore.service.NoteService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class NoteMapper { + + @Autowired + private NoteService noteService; + + public NoteRequestResponse mapResponse(Note note){ + NoteRequestResponse noteResponse = new NoteRequestResponse(); + noteResponse.setNoteId(note.getNoteId()); + noteResponse.setNoteDate(note.getNoteDate()); + noteResponse.setNoteText(note.getNoteText()); + noteResponse.setUuid(note.getUuid()); + noteResponse.setNoteTypeName(note.getNoteType().getName()); + return noteResponse; + } + + public Note mapRequest(NoteRequestResponse noteRequest){ + Note note = new Note(); + note.setNoteId(noteRequest.getNoteId()); + note.setNoteDate(noteRequest.getNoteDate()); + note.setNoteText(noteRequest.getNoteText()); + note.setUuid(noteRequest.getUuid()); + note.setNoteType(noteService.getNoteType(noteRequest.getNoteTypeName())); + return note; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/Note.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/Note.java new file mode 100644 index 0000000000..82ec99c8e2 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/Note.java @@ -0,0 +1,127 @@ +package org.bahmni.module.bahmnicore.model; + + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +import org.codehaus.jackson.annotate.JsonIgnore; +import org.openmrs.Auditable; +import org.openmrs.BaseOpenmrsData; +import org.openmrs.Patient; +import org.openmrs.User; + +public class Note extends BaseOpenmrsData implements Auditable, Serializable { + + private Integer noteId; + + private String noteText; + + private Date dateChanged; + + private Date dateCreated; + + private NoteType noteType; + + private Date noteDate; + + private Integer locationId; + + private User creator; + + private User changedBy; + + + public Note() { + } + + @Override + public void setId(Integer id) { + setNoteId(id); + } + + @Override + public Integer getId() { + return getNoteId(); + } + + public Date getDateChanged() { + return dateChanged; + } + + public void setDateChanged(Date dateChanged) { + this.dateChanged = dateChanged; + } + + @Override + public Date getDateCreated() { + return dateCreated; + } + + @Override + public void setDateCreated(Date dateCreated) { + this.dateCreated = dateCreated; + } + + public Integer getNoteId() { + return noteId; + } + + public void setNoteId(Integer noteId) { + this.noteId = noteId; + } + + public Integer getLocationId() { + return locationId; + } + + public void setLocationId(Integer locationId) { + this.locationId = locationId; + } + + public Date getNoteDate() { + return noteDate; + } + + public void setNoteDate(Date noteDate) { + this.noteDate = noteDate; + } + + public NoteType getNoteType() { + return noteType; + } + + public void setNoteType(NoteType noteType) { + this.noteType = noteType; + } + + public String getNoteText() { + return noteText; + } + + public void setNoteText(String noteText) { + this.noteText = noteText; + } + + @Override + @JsonIgnore + public User getCreator() { + return creator; + } + + @Override + public void setCreator(User creator) { + this.creator = creator; + } + + @Override + @JsonIgnore + public User getChangedBy() { + return changedBy; + } + + @Override + public void setChangedBy(User changedBy) { + this.changedBy = changedBy; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/NoteType.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/NoteType.java new file mode 100644 index 0000000000..ab4bfad380 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/NoteType.java @@ -0,0 +1,43 @@ +package org.bahmni.module.bahmnicore.model; + +import org.openmrs.BaseOpenmrsData; + +import java.io.Serializable; + +public class NoteType extends BaseOpenmrsData implements Serializable { + + private Integer noteTypeId; + + private String name; + + private String description; + public NoteType() { + } + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public Integer getNoteTypeId() { + return noteTypeId; + } + public void setNoteTypeId(Integer noteTypeId) { + this.noteTypeId = noteTypeId; + } + public Integer getId() { + return getNoteTypeId(); + } + + public void setId(Integer id) { + setNoteTypeId(id); + } +} + + diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/NoteService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/NoteService.java new file mode 100644 index 0000000000..b58d24cb5d --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/NoteService.java @@ -0,0 +1,47 @@ +package org.bahmni.module.bahmnicore.service; + + +import java.util.Date; +import java.util.List; + +import org.bahmni.module.bahmnicore.contract.NoteRequestResponse; +import org.bahmni.module.bahmnicore.model.Note; +import org.bahmni.module.bahmnicore.model.NoteType; +import org.openmrs.annotation.Authorized; +import org.openmrs.api.APIException; +import org.openmrs.util.PrivilegeConstants; +import org.springframework.transaction.annotation.Transactional; + + +public interface NoteService { + + @Transactional + @Authorized(PrivilegeConstants.GET_NOTE) + List getNotes(Date noteStartDate, Date noteEndDate, String noteType) throws Exception; + + @Transactional + Note createNote(Note note); + + @Transactional + Note updateNote(Integer id, NoteRequestResponse noteRequestResponse); + + @Transactional + @Authorized(PrivilegeConstants.DELETE_NOTE) + Note voidNote(Integer id, String reason); + + @Transactional + List createNotes(List notes); + + @Transactional + NoteType getNoteType(String name); + + @Transactional + @Authorized(PrivilegeConstants.GET_NOTE) + Note getNote(Date noteDate, String noteType); + + @Transactional + Note getNoteById(Integer id); + + @Transactional + Note getNoteByUuid(String uuid); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/NoteServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/NoteServiceImpl.java new file mode 100644 index 0000000000..d96f89114d --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/NoteServiceImpl.java @@ -0,0 +1,109 @@ +package org.bahmni.module.bahmnicore.service.impl; + + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.bahmni.module.bahmnicore.contract.NoteRequestResponse; +import org.bahmni.module.bahmnicore.dao.NoteDao; +import org.bahmni.module.bahmnicore.model.Note; +import org.bahmni.module.bahmnicore.model.NoteType; +import org.bahmni.module.bahmnicore.service.NoteService; +import org.openmrs.Provider; +import org.openmrs.User; +import org.openmrs.api.ProviderService; +import org.openmrs.api.UserService; +import org.openmrs.api.context.Context; +import org.springframework.transaction.annotation.Transactional; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +@Transactional +public class NoteServiceImpl implements NoteService, Serializable { + + private NoteDao noteDao; + + public void setNoteDao(NoteDao noteDao) { + this.noteDao = noteDao; + } + + private NoteDao getNoteDAO() { + return noteDao; + } + + private Log log = LogFactory.getLog(this.getClass()); + + public NoteServiceImpl() { + } + + public Note createNote(Note note) { + log.info("Create a note " + note); + noteDao.createNote(note); + return note; + } + + public Note getNote(Integer noteId) { + log.info("Get note " + noteId); + return noteDao.getNoteById(noteId); + } + + public Note updateNote(Integer id, NoteRequestResponse noteRequestResponse) { + Note note = noteDao.getNoteById(id); + Provider provider = Context.getService(ProviderService.class).getProviderByUuid(noteRequestResponse.getProviderUuid()); + User user = Context.getService(UserService.class).getUsersByPerson(provider.getPerson(), false).get(0); + if (note.getCreator().getUserId() == user.getUserId()) { + note.setNoteText(noteRequestResponse.getNoteText()); + log.info("Update note " + note); + return noteDao.updateNote(note); + } else { + Note newNote = new Note(); + newNote.setNoteDate(note.getNoteDate()); + newNote.setNoteText(noteRequestResponse.getNoteText()); + newNote.setNoteType(note.getNoteType()); + newNote = noteDao.createNote(newNote); + voidNote(id, "Updated to #" + newNote.getNoteId()); + log.info("Voided old note and created note " + newNote); + return newNote; + } + } + + public List getNotes(Date noteStartDate, Date noteEndDate, String noteType) { + return noteDao.getNotes(noteStartDate, noteEndDate, noteType); + } + + + public Note voidNote(Integer id, String reason) { + Note note = noteDao.getNoteById(id); + note.setVoided(true); + note.setVoidReason(reason); + log.debug("voiding note because " + reason); + return noteDao.voidNote(note); + } + + @Override + public List createNotes(List notes) { + return notes.stream().map(note -> noteDao.createNote(note)).collect(Collectors.toList()); + } + + @Override + public NoteType getNoteType(String name) { + return noteDao.getNoteType(name); + } + + @Override + public Note getNote(Date noteDate, String noteType) { + return noteDao.getNote(noteDate, noteType); + } + + @Override + public Note getNoteById(Integer noteId) { + return noteDao.getNoteById(noteId); + } + + @Override + public Note getNoteByUuid(String uuid) { + return noteDao.getNoteByUuid(uuid); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/validator/NoteValidator.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/validator/NoteValidator.java new file mode 100644 index 0000000000..ef4a6e1e93 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/validator/NoteValidator.java @@ -0,0 +1,42 @@ +package org.bahmni.module.bahmnicore.validator; + + +import org.bahmni.module.bahmnicore.contract.NoteRequestResponse; +import org.bahmni.module.bahmnicore.dao.NoteDao; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.validation.Errors; +import org.springframework.validation.ValidationUtils; +import org.springframework.validation.Validator; + +import static java.util.Objects.nonNull; + +@Component +public class NoteValidator implements Validator { + + @Autowired + private NoteDao noteDao; + + @Override + public boolean supports(Class c) { + return NoteRequestResponse.class.isAssignableFrom(c); + } + + @Override + public void validate(Object obj, Errors errors) { + NoteRequestResponse noteRequest = (NoteRequestResponse) obj; + if (noteRequest == null) { + errors.reject("error.general"); + } else { + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "noteTypeName", "Note.noteType.required"); + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "noteText", "Note.noteText.required"); + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "noteDate", "Note.noteDate.required"); + } + + if(nonNull(noteDao.getNote(noteRequest.getNoteDate(), noteRequest.getNoteTypeName()))) { + errors.reject("Note entry exist for noteType and noteDate"); + } + } + + +} diff --git a/bahmnicore-api/src/main/resources/NoteType.hbm.xml b/bahmnicore-api/src/main/resources/NoteType.hbm.xml new file mode 100644 index 0000000000..4712b2011d --- /dev/null +++ b/bahmnicore-api/src/main/resources/NoteType.hbm.xml @@ -0,0 +1,33 @@ + + + + + + + + + note_type_id_seq + + + + + + + + diff --git a/bahmnicore-api/src/main/resources/Notes.hbm.xml b/bahmnicore-api/src/main/resources/Notes.hbm.xml new file mode 100644 index 0000000000..d512195301 --- /dev/null +++ b/bahmnicore-api/src/main/resources/Notes.hbm.xml @@ -0,0 +1,44 @@ + + + + + + + + + note_id_seq + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/main/resources/moduleApplicationContext.xml b/bahmnicore-api/src/main/resources/moduleApplicationContext.xml index 78c1a50cd4..7129614967 100644 --- a/bahmnicore-api/src/main/resources/moduleApplicationContext.xml +++ b/bahmnicore-api/src/main/resources/moduleApplicationContext.xml @@ -228,4 +228,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.bahmni.module.bahmnicore.service.NoteService + + + + diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/NoteServiceImplIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/NoteServiceImplIT.java new file mode 100644 index 0000000000..532a7434fb --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/NoteServiceImplIT.java @@ -0,0 +1,123 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.BaseIntegrationTest; +import org.bahmni.module.bahmnicore.contract.drugorder.DrugOrderConfigResponse; +import org.bahmni.module.bahmnicore.model.Note; +import org.bahmni.module.bahmnicore.model.NoteType; +import org.bahmni.module.bahmnicore.service.NoteService; +import org.hibernate.HibernateException; +import org.hibernate.PropertyValueException; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.openmrs.DrugOrder; +import org.openmrs.api.APIException; +import org.openmrs.api.context.Context; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +import static org.junit.Assert.*; + +public class NoteServiceImplIT extends BaseIntegrationTest { + + @Before + public void setUp() throws Exception { + executeDataSet("notesData.xml"); + } + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void shouldCreateNewNoteOfSpecificNoteType() { + NoteService noteService = Context.getService(NoteService.class); + Note note = new Note(); + NoteType noteType = noteService.getNoteType("OT module"); + note.setNoteType(noteType); + note.setNoteText("note one"); + note.setNoteDate(new Date()); + noteService.createNote(note); + assertNotNull(note.getId()); + assertNotNull(note.getUuid()); + assertEquals(note.getNoteText(), "note one"); + assertEquals(note.getNoteType().getName(), "OT module"); + assertNotNull(note.getNoteDate()); + } + + @Test + public void shouldCreateNewNotesOfSpecificNoteType() { + NoteService noteService = Context.getService(NoteService.class); + NoteType noteType = noteService.getNoteType("OT module"); + Note note1 = new Note(); + note1.setNoteType(noteType); + note1.setNoteText("note one"); + note1.setNoteDate(new Date()); + + Note note2 = new Note(); + note2.setNoteType(noteType); + note2.setNoteText("Hello World Two"); + note2.setNoteDate(new Date()); + + Note noteObjectOne = noteService.createNote(note1); + Note noteObjectTwo = noteService.createNote(note2); + + assertNotNull(noteObjectOne); + assertEquals(noteObjectOne.getNoteText(), note1.getNoteText()); + assertEquals(noteObjectOne.getNoteType().getName(), note1.getNoteType().getName()); + assertNotNull(noteObjectOne.getNoteDate()); + + assertNotNull(noteObjectTwo); + assertEquals(noteObjectTwo.getNoteText(), note2.getNoteText()); + assertEquals(noteObjectTwo.getNoteType().getName(), note2.getNoteType().getName()); + assertNotNull(noteObjectTwo.getNoteDate()); + + } + + @Test + public void shouldGetNoteOfSpecificTypeAndDate() throws Exception { + NoteService noteService = Context.getService(NoteService.class); + NoteType noteType = new NoteType(); + noteType.setName("OT module"); + Note note = new Note(); + note.setNoteType(noteType); + DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + Date date = format.parse("2023-08-16 00:00:00.0"); + note.setNoteDate(date); + Note noteResponse = noteService.getNote(date,"OT module" ); + assertNotNull(noteResponse); + assertEquals(noteResponse.getNoteText(), "note one"); + assertEquals(noteResponse.getNoteType().getName(), "OT module"); + assertNotNull(noteResponse.getNoteDate()); + } + + + @Test + public void shouldThrowExceptionWhenNoteTypeIsEmpty() throws Exception { + NoteService noteService = Context.getService(NoteService.class); + Note note = new Note(); + note.setNoteText("Hello World"); + note.setNoteDate(new Date()); + expectedException.expect(HibernateException.class); + noteService.createNote(note); + } + + @Test + public void shouldExceptionWhenNoteDateIsEmpty() throws Exception { + NoteService noteService = Context.getService(NoteService.class); + Note note = new Note(); + note.setNoteText("Hello World"); + note.setNoteDate(new Date()); + expectedException.expect(HibernateException.class); + noteService.createNote(note); + + } + + +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/validator/NoteValidatorTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/validator/NoteValidatorTest.java new file mode 100644 index 0000000000..e81f7cb00e --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/validator/NoteValidatorTest.java @@ -0,0 +1,101 @@ +package org.bahmni.module.bahmnicore.validator; + +import org.bahmni.module.bahmnicore.contract.NoteRequestResponse; +import org.bahmni.module.bahmnicore.dao.NoteDao; +import org.bahmni.module.bahmnicore.model.Note; +import org.bahmni.module.bahmnicore.model.NoteType; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.springframework.validation.BeanPropertyBindingResult; +import org.springframework.validation.Errors; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.MockitoAnnotations.initMocks; + +public class NoteValidatorTest { + + @InjectMocks + private NoteValidator validator; + @Mock + private NoteDao noteDao; + + @Before + public void init() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void ensureNoteTypeIsNotNull() { + initMocks(this); + NoteRequestResponse noteRequest = new NoteRequestResponse(); + Errors noteRequestErrors = new BeanPropertyBindingResult(noteRequest, "noteRequest"); + noteRequest.setNoteTypeName(null); + noteRequest.setNoteText("Note Text"); + noteRequest.setNoteDate(new Date()); + Note note = new Note(); + note.setId(1); + Mockito.when(noteDao.getNote(any(Date.class), any(String.class))).thenReturn(note); + validator.validate(noteRequest, noteRequestErrors); + assertEquals(true, "Note.noteType.required".matches(noteRequestErrors.getAllErrors().get(0).getCode().toString())); + } + + @Test + public void ensureNoteDateIsNotNull() { + NoteRequestResponse noteRequest = new NoteRequestResponse(); + Errors noteRequestErrors = new BeanPropertyBindingResult(noteRequest, "noteRequest"); + noteRequest.setNoteTypeName("OT module"); + noteRequest.setNoteText("Note Text"); + noteRequest.setNoteDate(null); + Note note = new Note(); + note.setId(1); + Mockito.when(noteDao.getNote(any(Date.class), any(String.class))).thenReturn(note); + validator.validate(noteRequest, noteRequestErrors); + assertEquals(true, "Note.noteDate.required".matches(noteRequestErrors.getAllErrors().get(0).getCode().toString())); + } + + @Test + public void ensureNoteTextIsNotNull() { + NoteRequestResponse noteRequest = new NoteRequestResponse(); + Errors noteRequestErrors = new BeanPropertyBindingResult(noteRequest, "noteRequest"); + noteRequest.setNoteTypeName("OT module"); + noteRequest.setNoteDate(new Date()); + noteRequest.setNoteText(null); + Note note = new Note(); + note.setId(1); + Mockito.when(noteDao.getNote(any(Date.class), any(String.class))).thenReturn(note); + validator.validate(noteRequest, noteRequestErrors); + assertEquals(true, "Note.noteText.required".matches(noteRequestErrors.getAllErrors().get(0).getCode().toString())); + } + + @Test + public void ensureNoteDoesntExistForSameNoteDateAndNoteType() throws ParseException { + NoteRequestResponse noteRequest = new NoteRequestResponse(); + Errors noteRequestErrors = new BeanPropertyBindingResult(noteRequest, "noteRequest"); + DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + Date noteDate1 = format.parse("2023-08-16 00:00:00.0"); + noteRequest.setNoteTypeName("OT module"); + noteRequest.setNoteDate(noteDate1); + noteRequest.setNoteText("Some text"); + + Note note = new Note(); + NoteType noteType = new NoteType(); + Date existingNote = format.parse("2023-08-16 00:00:00.0"); + noteType.setName("OT module"); + note.setId(1); + note.setNoteDate(existingNote); + note.setNoteType(noteType); + Mockito.when(noteDao.getNote(any(Date.class), any(String.class))).thenReturn(note); + validator.validate(noteRequest, noteRequestErrors); + assertEquals(true, "Note entry exist for noteType and noteDate".matches(noteRequestErrors.getAllErrors().get(0).getCode().toString())); + } +} diff --git a/bahmnicore-api/src/test/resources/notesData.xml b/bahmnicore-api/src/test/resources/notesData.xml new file mode 100644 index 0000000000..35d6812658 --- /dev/null +++ b/bahmnicore-api/src/test/resources/notesData.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/bahmnicore-api/src/test/resources/test-hibernate.cfg.xml b/bahmnicore-api/src/test/resources/test-hibernate.cfg.xml index 96d722232c..f37c2985b0 100644 --- a/bahmnicore-api/src/test/resources/test-hibernate.cfg.xml +++ b/bahmnicore-api/src/test/resources/test-hibernate.cfg.xml @@ -15,5 +15,7 @@ + + diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniNotesController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniNotesController.java new file mode 100644 index 0000000000..cd079270cb --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniNotesController.java @@ -0,0 +1,89 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.bahmni.module.bahmnicore.contract.NoteRequestResponse; +import org.bahmni.module.bahmnicore.mapper.NoteMapper; +import org.bahmni.module.bahmnicore.model.Note; +import org.bahmni.module.bahmnicore.service.NoteService; +import org.bahmni.module.bahmnicore.validator.NoteValidator; +import org.openmrs.api.context.Context; +import org.openmrs.module.auditlog.util.DateUtil; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.validation.BeanPropertyBindingResult; +import org.springframework.validation.Errors; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/notes") +public class BahmniNotesController extends BaseRestController { + + private Log log = LogFactory.getLog(this.getClass()); + + @Autowired + private NoteMapper noteMapper; + + @Autowired + private NoteValidator noteValidator; + + @RequestMapping(method = RequestMethod.GET) + @ResponseBody + public List getNotes(@RequestParam(value = "noteStartDate") String noteStartDateString, @RequestParam(value = "noteEndDate", required = false) String noteEndDateString, + @RequestParam(value = "noteType") String noteType) throws Exception { + Date noteStartDate = DateUtil.convertToLocalDateFromUTC(noteStartDateString); + if (noteEndDateString != null) { + Date noteEndDate = DateUtil.convertToLocalDateFromUTC(noteEndDateString); + List notes = Context.getService(NoteService.class).getNotes(noteStartDate, noteEndDate, noteType); + return notes.stream().map(note -> noteMapper.mapResponse(note)).collect(Collectors.toList()); + } + + Note note = Context.getService(NoteService.class).getNote(noteStartDate, noteType); + List noteResponses = new ArrayList<>(); + if (note != null) { + noteResponses.add(noteMapper.mapResponse(note)); + } + return noteResponses; + } + + @RequestMapping(method = RequestMethod.POST) + @ResponseBody + public List save(@Valid @RequestBody List noteRequests) throws Exception { + List notes = new ArrayList<>(); + notes = noteRequests.stream().map(noteRequest -> { + Errors noteRequestErrors = new BeanPropertyBindingResult(noteRequest, "noteRequest"); + noteValidator.validate(noteRequest, noteRequestErrors); + if (!noteRequestErrors.getAllErrors().isEmpty()) { + throw new RuntimeException(noteRequestErrors.getAllErrors().get(0).toString()); + } + return noteMapper.mapRequest(noteRequest); + }).collect(Collectors.toList()); + List listOfNotes = Context.getService(NoteService.class).createNotes(notes); + return listOfNotes.stream().map(note -> noteMapper.mapResponse(note)).collect(Collectors.toList()); + } + + @RequestMapping(method = RequestMethod.POST, value = "/{id}") + @ResponseBody + public NoteRequestResponse update(@Valid @PathVariable("id") String id, @RequestBody NoteRequestResponse noteRequestResponse) { + Integer noteId = Integer.valueOf(id); + return noteMapper.mapResponse(Context.getService(NoteService.class).updateNote(noteId, noteRequestResponse)); + } + + @RequestMapping(method = RequestMethod.DELETE, value = "/{id}") + @ResponseBody + public NoteRequestResponse delete(@PathVariable("id") String id, @RequestParam(value = "reason", required = false) String reason ) { + Integer noteId = Integer.valueOf(id); + return noteMapper.mapResponse(Context.getService(NoteService.class).voidNote(noteId, reason)); + } + + +} diff --git a/bahmnicore-omod/src/main/resources/config.xml b/bahmnicore-omod/src/main/resources/config.xml index d33c63144f..0111d342a4 100644 --- a/bahmnicore-omod/src/main/resources/config.xml +++ b/bahmnicore-omod/src/main/resources/config.xml @@ -136,7 +136,9 @@ BahmniConfig.hbm.xml EntityMapping.hbm.xml EntityMappingType.hbm.xml - + Notes.hbm.xml + NoteType.hbm.xml + diff --git a/bahmnicore-omod/src/main/resources/liquibase.xml b/bahmnicore-omod/src/main/resources/liquibase.xml index 1589787665..682fff9f75 100644 --- a/bahmnicore-omod/src/main/resources/liquibase.xml +++ b/bahmnicore-omod/src/main/resources/liquibase.xml @@ -4556,7 +4556,101 @@ insert into order_type_class_map(order_type_id, concept_class_id) values(@radiology_order_type_id,@radiology_imaging); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select count(*) from note_type where name = 'OT module'; + + + Adding note type + + insert into note_type (name, description, uuid) values ('OT module', 'OT module', uuid()); + + From 1ae59c41ac362d97a4996f546c9668f8d71d1576 Mon Sep 17 00:00:00 2001 From: Parvathy Babu <102500787+parvathy00@users.noreply.github.com> Date: Wed, 15 May 2024 17:05:28 +0530 Subject: [PATCH 30/47] BAH-3745 | Add. Api To Fetch Order By Order Id (#262) * Parvathy | BAH-3745 | Add. Api To Fetch Order By Order Id * Parvathy | BAH-3745 | Add. Test Cases * Parvathy | BAH-3745 | Refactor. Fetch Drug Order By Uuid --- .../mapper/BahmniDrugOrderMapper.java | 66 ++++++++++--------- .../service/BahmniDrugOrderService.java | 2 + .../impl/BahmniDrugOrderServiceImpl.java | 7 ++ .../bahmnicore/dao/impl/OrderDaoImplIT.java | 7 +- .../controller/BahmniDrugOrderController.java | 17 +++-- .../BahmniDrugOrderControllerIT.java | 7 ++ .../mapper/BahmniDrugOrderMapperTest.java | 42 ++++++++++++ 7 files changed, 108 insertions(+), 40 deletions(-) diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/mapper/BahmniDrugOrderMapper.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/mapper/BahmniDrugOrderMapper.java index 6d63028ff6..e7ba05e633 100644 --- a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/mapper/BahmniDrugOrderMapper.java +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/mapper/BahmniDrugOrderMapper.java @@ -30,39 +30,10 @@ public List mapToResponse(List activeDrugOrders, Map discontinuedOrderMap, String locale) throws IOException { - OrderMapper1_12 drugOrderMapper = new OrderMapper1_12(); - List bahmniDrugOrders = new ArrayList<>(); for (DrugOrder openMRSDrugOrder : activeDrugOrders) { - BahmniDrugOrder bahmniDrugOrder = new BahmniDrugOrder(); - - bahmniDrugOrder.setDrugOrder(drugOrderMapper.mapDrugOrder(openMRSDrugOrder)); - if(locale != null) { - Locale tempLocale = new Locale(locale); - String localeSpecificName = ""; - if (openMRSDrugOrder != null) { - localeSpecificName = openMRSDrugOrder.getDrug().getFullName(tempLocale); - bahmniDrugOrder.getDrugOrder().getDrug().setName(localeSpecificName); - } - } - - if((locale != null) && (openMRSDrugOrder.getFrequency().getConcept() != null) && (openMRSDrugOrder.getFrequency().getConcept().getPreferredName(new Locale((locale))) != null)) { - bahmniDrugOrder.getDrugOrder().getDosingInstructions().setFrequency(openMRSDrugOrder.getFrequency().getConcept().getPreferredName(new Locale((locale))).getName()); - } - bahmniDrugOrder.setVisit(openMRSDrugOrder.getEncounter().getVisit()); - bahmniDrugOrder.setProvider(providerMapper.map(openMRSDrugOrder.getOrderer())); - if(openMRSDrugOrder.getDrug() != null){ - bahmniDrugOrder.setRetired(openMRSDrugOrder.getDrug().getRetired()); - } - bahmniDrugOrder.setEncounterUuid(openMRSDrugOrder.getEncounter().getUuid()); - - bahmniDrugOrder.setCreatorName(openMRSDrugOrder.getCreator().getPersonName().toString()); - if(discontinuedOrderMap.containsKey(openMRSDrugOrder.getOrderNumber())){ - bahmniDrugOrder.setOrderReasonText(discontinuedOrderMap.get(openMRSDrugOrder.getOrderNumber()).getOrderReasonNonCoded()); - bahmniDrugOrder.setOrderReasonConcept(conceptMapper.map(discontinuedOrderMap.get(openMRSDrugOrder.getOrderNumber()).getOrderReason())); - } - + BahmniDrugOrder bahmniDrugOrder = mapDrugOrderToBahmniDrugOrder(openMRSDrugOrder, locale, discontinuedOrderMap); bahmniDrugOrders.add(bahmniDrugOrder); } if(CollectionUtils.isNotEmpty(orderAttributeObs)){ @@ -71,9 +42,44 @@ public List mapToResponse(List activeDrugOrders, return bahmniDrugOrders; } + private BahmniDrugOrder mapDrugOrderToBahmniDrugOrder(DrugOrder openMRSDrugOrder, String locale, Map discontinuedOrderMap) { + OrderMapper1_12 drugOrderMapper = new OrderMapper1_12(); + BahmniDrugOrder bahmniDrugOrder = new BahmniDrugOrder(); + bahmniDrugOrder.setDrugOrder(drugOrderMapper.mapDrugOrder(openMRSDrugOrder)); + if(locale != null) { + Locale tempLocale = new Locale(locale); + String localeSpecificName = ""; + if (openMRSDrugOrder != null) { + localeSpecificName = openMRSDrugOrder.getDrug().getFullName(tempLocale); + bahmniDrugOrder.getDrugOrder().getDrug().setName(localeSpecificName); + } + } + + if((locale != null) && (openMRSDrugOrder.getFrequency().getConcept() != null) && (openMRSDrugOrder.getFrequency().getConcept().getPreferredName(new Locale((locale))) != null)) { + bahmniDrugOrder.getDrugOrder().getDosingInstructions().setFrequency(openMRSDrugOrder.getFrequency().getConcept().getPreferredName(new Locale((locale))).getName()); + } + bahmniDrugOrder.setVisit(openMRSDrugOrder.getEncounter().getVisit()); + bahmniDrugOrder.setProvider(providerMapper.map(openMRSDrugOrder.getOrderer())); + if(openMRSDrugOrder.getDrug() != null){ + bahmniDrugOrder.setRetired(openMRSDrugOrder.getDrug().getRetired()); + } + bahmniDrugOrder.setEncounterUuid(openMRSDrugOrder.getEncounter().getUuid()); + + bahmniDrugOrder.setCreatorName(openMRSDrugOrder.getCreator().getPersonName().toString()); + if(discontinuedOrderMap.containsKey(openMRSDrugOrder.getOrderNumber())){ + bahmniDrugOrder.setOrderReasonText(discontinuedOrderMap.get(openMRSDrugOrder.getOrderNumber()).getOrderReasonNonCoded()); + bahmniDrugOrder.setOrderReasonConcept(conceptMapper.map(discontinuedOrderMap.get(openMRSDrugOrder.getOrderNumber()).getOrderReason())); + } + return bahmniDrugOrder; + } + public void setMappers(BahmniProviderMapper bahmniProviderMapper, OrderAttributesMapper orderAttributesMapper, ConceptMapper conceptMapper){ providerMapper = bahmniProviderMapper; this.orderAttributesMapper = orderAttributesMapper; this.conceptMapper = conceptMapper; } + + public BahmniDrugOrder mapToResponse(DrugOrder drugOrder, Map discontinuedDrugOrderMap) { + return mapDrugOrderToBahmniDrugOrder(drugOrder, null, discontinuedDrugOrderMap); + } } diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniDrugOrderService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniDrugOrderService.java index 6d57f6a571..f483c45b88 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniDrugOrderService.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniDrugOrderService.java @@ -38,4 +38,6 @@ List getInactiveDrugOrders(String patientUuid, Set concepts, List getDrugOrders(String patientUuid, Boolean isActive, Set conceptsToFilter, Set conceptsToExclude, String patientProgramUuid) throws ParseException; + + DrugOrder getDrugOrderByOrderId(String orderId); } diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImpl.java index 2c9bb6faa8..e7631f8f1b 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImpl.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImpl.java @@ -141,6 +141,13 @@ public List getDrugOrders(String patientUuid, Boolean isActive, } } + @Override + public DrugOrder getDrugOrderByOrderId(String orderId) { + Order order = orderDao.getOrderByUuid(orderId); + List drugOrders = mapOrderToDrugOrder(Collections.singletonList(order)); + return drugOrders.get(0); + } + @Override public List getPrescribedDrugOrdersForConcepts(Patient patient, Boolean includeActiveVisit, List visits, List concepts, Date startDate, Date endDate) { if( concepts == null || concepts.isEmpty()){ diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/OrderDaoImplIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/OrderDaoImplIT.java index f71b1f691d..54fb23f79d 100644 --- a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/OrderDaoImplIT.java +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/OrderDaoImplIT.java @@ -20,12 +20,7 @@ import java.io.File; import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Date; -import java.util.HashSet; -import java.util.List; +import java.util.*; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertTrue; diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDrugOrderController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDrugOrderController.java index afc0306678..156f4b4d50 100644 --- a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDrugOrderController.java +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDrugOrderController.java @@ -3,6 +3,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.velocity.exception.ResourceNotFoundException; import org.bahmni.module.bahmnicore.service.BahmniDrugOrderService; import org.bahmni.module.bahmnicore.service.BahmniObsService; import org.bahmni.module.bahmnicore.util.BahmniDateUtil; @@ -17,10 +18,7 @@ import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.*; import java.io.IOException; import java.text.ParseException; @@ -129,6 +127,17 @@ public List getDrugOrderDetails(@RequestParam(value = "patientU return drugOrderService.getDrugOrders(patientUuid, isActive, drugConceptsToBeFiltered, drugConceptsToBeExcluded, patientProgramUuid); } + @RequestMapping(value = baseUrl + "/{orderId}", method = RequestMethod.GET) + @ResponseBody + public BahmniDrugOrder getDrugOrderByOrderId(@PathVariable String orderId) { + DrugOrder drugOrder = drugOrderService.getDrugOrderByOrderId(orderId); + Map discontinuedDrugOrderMap = drugOrderService.getDiscontinuedDrugOrders(Collections.singletonList(drugOrder)); + if (drugOrder == null) { + throw new ResourceNotFoundException("Drug order not found with orderId: " + orderId); + } + return bahmniDrugOrderMapper.mapToResponse(drugOrder, discontinuedDrugOrderMap); + } + Set getDrugConcepts(String drugConceptSetName){ if(drugConceptSetName == null) return null; Set drugConcepts = new HashSet<>(); diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDrugOrderControllerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDrugOrderControllerIT.java index 7160ce7ac3..be74f6f69b 100644 --- a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDrugOrderControllerIT.java +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDrugOrderControllerIT.java @@ -228,6 +228,13 @@ public void shouldReturnInactiveDrugOrderExceptForGivenConceptSet() throws Excep assertEquals("6d0ae116-ewrg-4629-9850-f15205e6bgoh", inactiveDrugOrders.get(0).getUuid()); } + @Test + public void shouldReturnDrugOrderByOrderId() throws Exception { + executeDataSet("prescribedAndActiveDrugOrdersForVisits.xml"); + BahmniDrugOrder drugOrder = bahmniDrugOrderController.getDrugOrderByOrderId("6d0ae116-707a-4629-9850-f15205e63ab0"); + assertEquals("6d0ae116-707a-4629-9850-f15205e63ab0", drugOrder.getUuid()); + } + private List getOrderUuids(List bahmniDrugOrders) { ArrayList orderUuids = new ArrayList<>(); for (BahmniDrugOrder drugOrder : bahmniDrugOrders) { diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniDrugOrderMapperTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniDrugOrderMapperTest.java index 8024e834b1..84d35ff3b8 100644 --- a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniDrugOrderMapperTest.java +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniDrugOrderMapperTest.java @@ -256,4 +256,46 @@ public void shouldFillDrugOrderReasonTextAndReasonConcept() throws Exception { assertEquals("AEID1234", mappedOrder.getOrderReasonText()); verify(providerMapper, times(1)).map(null); } + + @Test + public void shouldMapDrugOrderToResponse() throws Exception { + DrugOrderBuilder drugBuilder = new DrugOrderBuilder(); + Date visitDate; + Date dateActivated; + visitDate = dateActivated = new Date(); + Date dateScheduled = DateUtils.addDays(dateActivated, 2); + Date expireDate = DateUtils.addDays(dateActivated, 20); + + + Person person = new PersonBuilder().withUUID("puuid").build(); + Encounter encounter = new EncounterBuilder().build(); + Visit visit = new VisitBuilder().withPerson(person).withUUID("vuuid").withStartDatetime(visitDate).withEncounter( + encounter).build(); + + DrugOrder drugOrder = drugBuilder.withDrugName("Paracetamol 120mg/5ml 60ml") + .withDosingType(FlexibleDosingInstructions.class) + .withDrugForm("Capsule") + .withScheduledDate(dateScheduled) + .withDateActivated(dateActivated) + .withDurationUnits("Week") + .withDosingInstructions("{\"dose\": \"2.0\", \"doseUnits\": \"Tablet\"}") + .withVisit(visit) + .withDuration(18) + .withAutoExpireDate(expireDate) + .withCreator("testPersonName") + .build(); + + BahmniDrugOrder mappedDrugOrder = bahmniDrugOrderMapper.mapToResponse(drugOrder, new HashMap()); + + assertEquals("Paracetamol 120mg/5ml 60ml", mappedDrugOrder.getDrug().getName()); + assertEquals("Capsule", mappedDrugOrder.getDrug().getForm()); + assertEquals(dateScheduled, mappedDrugOrder.getEffectiveStartDate()); + assertEquals(expireDate, mappedDrugOrder.getEffectiveStopDate()); + assertEquals(18, mappedDrugOrder.getDuration(), 0); + assertEquals("Week", mappedDrugOrder.getDurationUnits()); + assertEquals("vuuid", mappedDrugOrder.getVisit().getUuid()); + assertEquals("{\"dose\": \"2.0\", \"doseUnits\": \"Tablet\"}", mappedDrugOrder.getDosingInstructions().getAdministrationInstructions()); + assertEquals(visitDate, mappedDrugOrder.getVisit().getStartDateTime()); + verify(providerMapper, times(1)).map(null); + } } From 8697e0557e8c56269b1eb19c5ecaf160a2ee0e04 Mon Sep 17 00:00:00 2001 From: MOHANKUMAR T <31698165+mohan-13@users.noreply.github.com> Date: Tue, 4 Jun 2024 15:49:18 +0530 Subject: [PATCH 31/47] BAH-3892 | Support atomfeed test events for concepts with class Test (#263) * BAH-3892 | Support atomfeed test events for concepts with class Test * BAH-3892 | Refactor. Support case-insensitive match for concept class names --- .../labconcepts/contract/LabTest.java | 6 +- .../labconcepts/mapper/ConceptExtension.java | 23 ++++++++ .../labconcepts/mapper/DepartmentMapper.java | 4 +- .../labconcepts/mapper/PanelMapper.java | 2 +- .../labconcepts/mapper/SampleMapper.java | 5 +- .../mapper/TestAndPanelMapper.java | 9 ++- .../labconcepts/model/event/LabTestEvent.java | 11 ++-- .../model/event/SaleableTypeEvent.java | 12 ++-- .../AllTestsPanelsConceptSetEventTest.java | 4 +- .../model/event/LabTestEventTest.java | 59 +++++++++++++------ .../contract/mapper/AllSamplesMapperTest.java | 2 +- .../mapper/AllTestsAndPanelsMapperTest.java | 6 +- .../contract/mapper/LabTestMapperTest.java | 2 +- .../web/contract/mapper/PanelMapperTest.java | 4 +- 14 files changed, 98 insertions(+), 51 deletions(-) diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/LabTest.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/LabTest.java index 2649702cf4..c71f37da25 100644 --- a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/LabTest.java +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/LabTest.java @@ -3,14 +3,18 @@ import org.openmrs.ConceptAnswer; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.List; public class LabTest extends Resource { private String description; private String resultType; private String testUnitOfMeasure; private Double sortOrder; - public static final String LAB_TEST_CONCEPT_CLASS = "LabTest"; + + public static final List LAB_TEST_CONCEPT_CLASSES = Arrays.asList("LabTest","Test"); + private Collection codedTestAnswer; diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptExtension.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptExtension.java index 0eada53a55..657d7f4a13 100644 --- a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptExtension.java +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptExtension.java @@ -102,11 +102,23 @@ private static boolean isFullySpecifiedName(ConceptName conceptName) { return ObjectUtils.equals(conceptName.getConceptNameType(), ConceptNameType.FULLY_SPECIFIED); } + private static boolean containsClassName(String conceptClassName, List classNames){ + for (String className : classNames) { + if (className.equalsIgnoreCase(conceptClassName)) { + return true; + } + } + return false; + } public static boolean isOfConceptClass(Concept concept, String conceptClassName) { return concept.getConceptClass() != null && concept.getConceptClass().getName() != null && concept.getConceptClass().getName().equals(conceptClassName); } + public static boolean isOfAnyConceptClass(Concept concept, List conceptClassNames) { + return concept.getConceptClass() != null && concept.getConceptClass().getName() != null && containsClassName(concept.getConceptClass().getName(),conceptClassNames); + } + public static boolean isOfConceptClassByUUID(Concept concept, String conceptClassUUID) { return concept.getConceptClass() != null && concept.getConceptClass().getUuid().equals(conceptClassUUID); } @@ -122,4 +134,15 @@ public static List getResourceReferencesOfConceptClass(List getResourceReferencesOfConceptClasses(List setMembers, List conceptClasses) { + ResourceReferenceMapper resourceReferenceMapper = new ResourceReferenceMapper(); + List resourceReferences = new ArrayList<>(); + for (Concept setMember : setMembers) { + if (isOfAnyConceptClass(setMember, conceptClasses)) { + resourceReferences.add(resourceReferenceMapper.map(setMember)); + } + } + return resourceReferences; + } + } diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/DepartmentMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/DepartmentMapper.java index 45159ca3ee..22fe234cf6 100644 --- a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/DepartmentMapper.java +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/DepartmentMapper.java @@ -4,7 +4,7 @@ import org.bahmni.module.referencedata.labconcepts.contract.LabTest; import org.openmrs.Concept; -import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.getResourceReferencesOfConceptClass; +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.getResourceReferencesOfConceptClasses; public class DepartmentMapper extends ResourceMapper { @@ -17,7 +17,7 @@ public Department map(Concept departmentConcept) { Department department = new Department(); department = mapResource(department, departmentConcept); department.setDescription(ConceptExtension.getDescriptionOrName(departmentConcept)); - department.setTests(getResourceReferencesOfConceptClass(departmentConcept.getSetMembers(), LabTest.LAB_TEST_CONCEPT_CLASS)); + department.setTests(getResourceReferencesOfConceptClasses(departmentConcept.getSetMembers(), LabTest.LAB_TEST_CONCEPT_CLASSES)); return department; } } diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/PanelMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/PanelMapper.java index 538e628e31..9555e65a52 100644 --- a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/PanelMapper.java +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/PanelMapper.java @@ -14,7 +14,7 @@ public PanelMapper() { public Panel map(Concept panelConcept) { Panel panel = new Panel(); panel = mapResource(panel, panelConcept); - panel.setTests(ConceptExtension.getResourceReferencesOfConceptClass(panelConcept.getSetMembers(), LabTest.LAB_TEST_CONCEPT_CLASS)); + panel.setTests(ConceptExtension.getResourceReferencesOfConceptClasses(panelConcept.getSetMembers(), LabTest.LAB_TEST_CONCEPT_CLASSES)); panel.setSortOrder(getSortWeight(panelConcept)); panel.setDescription(ConceptExtension.getDescriptionOrName(panelConcept)); return panel; diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/SampleMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/SampleMapper.java index 8a95d771c4..4dab4563c0 100644 --- a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/SampleMapper.java +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/SampleMapper.java @@ -8,6 +8,7 @@ import org.openmrs.api.context.Context; import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.getResourceReferencesOfConceptClass; +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.getResourceReferencesOfConceptClasses; public class SampleMapper extends ResourceMapper { public SampleMapper() { @@ -20,9 +21,9 @@ public Sample map(Concept sampleConcept) { sample = mapResource(sample, sampleConcept); sample.setShortName(sampleConcept.getShortestName(Context.getLocale(), false).getName()); sample.setSortOrder(getSortWeight(sampleConcept)); - sample.setTests(getResourceReferencesOfConceptClass(sampleConcept.getSetMembers(), LabTest.LAB_TEST_CONCEPT_CLASS)); + sample.setTests(getResourceReferencesOfConceptClasses(sampleConcept.getSetMembers(), LabTest.LAB_TEST_CONCEPT_CLASSES)); sample.setPanels(getResourceReferencesOfConceptClass(sampleConcept.getSetMembers(), Panel.LAB_SET_CONCEPT_CLASS)); return sample; } -} \ No newline at end of file +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/TestAndPanelMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/TestAndPanelMapper.java index b1ea11997b..5789fba58a 100644 --- a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/TestAndPanelMapper.java +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/TestAndPanelMapper.java @@ -6,9 +6,8 @@ import org.openmrs.Concept; import org.openmrs.ConceptClass; -import static org.bahmni.module.referencedata.labconcepts.contract.LabTest.LAB_TEST_CONCEPT_CLASS; -import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.isOfConceptClass; -import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.isOfConceptClassByUUID; +import static org.bahmni.module.referencedata.labconcepts.contract.LabTest.LAB_TEST_CONCEPT_CLASSES; +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.*; public class TestAndPanelMapper extends ResourceMapper { @@ -31,7 +30,7 @@ public TestsAndPanels map(Concept sampleConcept) { } private void addConcept(TestsAndPanels testsAndPanels, Concept concept) { - if (isOfConceptClass(concept, LAB_TEST_CONCEPT_CLASS)) { + if (isOfAnyConceptClass(concept, LAB_TEST_CONCEPT_CLASSES)) { LabTest test = labTestMapper.map(concept); testsAndPanels.addTest(test); } else if (isOfConceptClassByUUID(concept, ConceptClass.LABSET_UUID)) { @@ -39,4 +38,4 @@ private void addConcept(TestsAndPanels testsAndPanels, Concept concept) { testsAndPanels.addPanel(panel); } } -} \ No newline at end of file +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/LabTestEvent.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/LabTestEvent.java index 9aa4ea3120..06926f13d2 100644 --- a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/LabTestEvent.java +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/LabTestEvent.java @@ -10,8 +10,8 @@ import java.util.List; import java.util.UUID; -import static org.bahmni.module.referencedata.labconcepts.contract.LabTest.LAB_TEST_CONCEPT_CLASS; -import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.isOfConceptClass; +import static org.bahmni.module.referencedata.labconcepts.contract.LabTest.LAB_TEST_CONCEPT_CLASSES; +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.isOfAnyConceptClass; public class LabTestEvent extends ConceptOperationEvent { @@ -20,17 +20,16 @@ public LabTestEvent(String url, String category, String title) { } public boolean isResourceConcept(Concept concept) { - return isOfConceptClass(concept, LAB_TEST_CONCEPT_CLASS) || (getParentOfTypeLabTest(concept) != null); + return isOfAnyConceptClass(concept, LAB_TEST_CONCEPT_CLASSES) || (getParentOfTypeLabTest(concept) != null); } private Concept getParentOfTypeLabTest(Concept concept) { ConceptHelper conceptHelper = new ConceptHelper(Context.getConceptService()); List parentConcepts = conceptHelper.getParentConcepts(concept); for (Concept parentConcept : parentConcepts) { - if (isOfConceptClass(parentConcept, LAB_TEST_CONCEPT_CLASS)) { + if (isOfAnyConceptClass(parentConcept, LAB_TEST_CONCEPT_CLASSES)) { return parentConcept; } - ; } return null; } @@ -38,7 +37,7 @@ private Concept getParentOfTypeLabTest(Concept concept) { @Override public Event asAtomFeedEvent(Object[] arguments) throws URISyntaxException { Concept concept = (Concept) arguments[0]; - if (!isOfConceptClass(concept, LAB_TEST_CONCEPT_CLASS)) { + if (!isOfAnyConceptClass(concept, LAB_TEST_CONCEPT_CLASSES)) { concept = getParentOfTypeLabTest(concept); } String url = String.format(this.url, title, concept.getUuid()); diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SaleableTypeEvent.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SaleableTypeEvent.java index 18bf747ae8..0deaaef970 100644 --- a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SaleableTypeEvent.java +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SaleableTypeEvent.java @@ -9,15 +9,12 @@ import java.net.URI; import java.net.URISyntaxException; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.UUID; +import java.util.*; import static org.bahmni.module.referencedata.labconcepts.contract.AllSamples.ALL_SAMPLES; import static org.bahmni.module.referencedata.labconcepts.contract.AllTestsAndPanels.ALL_TESTS_AND_PANELS; import static org.bahmni.module.referencedata.labconcepts.contract.Department.DEPARTMENT_CONCEPT_CLASS; -import static org.bahmni.module.referencedata.labconcepts.contract.LabTest.LAB_TEST_CONCEPT_CLASS; +import static org.bahmni.module.referencedata.labconcepts.contract.LabTest.LAB_TEST_CONCEPT_CLASSES; import static org.bahmni.module.referencedata.labconcepts.contract.Panel.LAB_SET_CONCEPT_CLASS; import static org.bahmni.module.referencedata.labconcepts.contract.RadiologyTest.RADIOLOGY_TEST_CONCEPT_CLASS; import static org.bahmni.module.referencedata.labconcepts.contract.Sample.SAMPLE_CONCEPT_CLASS; @@ -31,7 +28,10 @@ public class SaleableTypeEvent implements ConceptServiceOperationEvent { private final String category; private List supportedOperations = Arrays.asList("saveConcept", "updateConcept", "retireConcept", "purgeConcept"); - private List unhandledClasses = Arrays.asList(LAB_TEST_CONCEPT_CLASS, LAB_SET_CONCEPT_CLASS, SAMPLE_CONCEPT_CLASS, DEPARTMENT_CONCEPT_CLASS, RADIOLOGY_TEST_CONCEPT_CLASS); + private List unhandledClasses = new ArrayList(){{ + addAll(Arrays.asList(LAB_SET_CONCEPT_CLASS, SAMPLE_CONCEPT_CLASS, DEPARTMENT_CONCEPT_CLASS, RADIOLOGY_TEST_CONCEPT_CLASS)); + addAll(LAB_TEST_CONCEPT_CLASSES); + }}; private List unhandledConcepsByName = Arrays.asList(ALL_SAMPLES, ALL_TESTS_AND_PANELS); public SaleableTypeEvent(String url, String category) { diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/AllTestsPanelsConceptSetEventTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/AllTestsPanelsConceptSetEventTest.java index 753f3f7cff..6ab6cfea55 100644 --- a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/AllTestsPanelsConceptSetEventTest.java +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/AllTestsPanelsConceptSetEventTest.java @@ -46,7 +46,7 @@ public void setUp() { PowerMockito.mockStatic(Context.class); when(Context.getLocale()).thenReturn(defaultLocale); when(Context.getConceptService()).thenReturn(conceptService); - testConcept = new ConceptBuilder().withClass(LabTest.LAB_TEST_CONCEPT_CLASS).build(); + testConcept = new ConceptBuilder().withClass(LabTest.LAB_TEST_CONCEPT_CLASSES.get(0)).build(); panelConcept = new ConceptBuilder().withClassUUID(ConceptClass.LABSET_UUID).build(); parentConcept = new ConceptBuilder().withName(AllTestsAndPanels.ALL_TESTS_AND_PANELS).withClass("ConvSet").withSetMember(testConcept).withSetMember(panelConcept).build(); } @@ -60,4 +60,4 @@ public void shouldCreateOneEventForAllTestsAndPanelsAndSetMembers() throws Excep assertEquals(ConceptServiceEventFactory.TESTS_AND_PANEL, event.getTitle()); assertEquals("lab", event.getCategory()); } -} \ No newline at end of file +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/LabTestEventTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/LabTestEventTest.java index dce35e3e2c..bd489ac4be 100644 --- a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/LabTestEventTest.java +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/LabTestEventTest.java @@ -34,8 +34,10 @@ @RunWith(PowerMockRunner.class) public class LabTestEventTest { public static final String TEST_CONCEPT_UUID = "aebc57b7-0683-464e-ac48-48b8838abdfc"; + public static final String LAB_TEST_CONCEPT_UUID = "9b11d2d1-c7ea-40f7-8616-be9bec4c6bb7"; - private Concept concept; + private Concept conceptWithLabTestClass; + private Concept conceptWithTestClass; @Mock private ConceptService conceptService; @@ -45,11 +47,13 @@ public class LabTestEventTest { public void setup() { MockitoAnnotations.initMocks(this); - concept = new ConceptBuilder().withClass(LabTest.LAB_TEST_CONCEPT_CLASS).withUUID(TEST_CONCEPT_UUID).build(); + conceptWithLabTestClass = new ConceptBuilder().withClass("LabTest").withUUID(LAB_TEST_CONCEPT_UUID).build(); + conceptWithTestClass = new ConceptBuilder().withClass("Test").withUUID(TEST_CONCEPT_UUID).build(); - parentConcept = new ConceptBuilder().withName(AllTestsAndPanels.ALL_TESTS_AND_PANELS).withSetMember(concept).build(); + parentConcept = new ConceptBuilder().withName(AllTestsAndPanels.ALL_TESTS_AND_PANELS).withSetMember(conceptWithLabTestClass).build(); + parentConcept.addSetMember(conceptWithTestClass); - List conceptSets = getConceptSets(parentConcept, concept); + List conceptSets = getConceptSets(parentConcept, conceptWithLabTestClass); when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(conceptSets); @@ -61,26 +65,43 @@ public void setup() { @Test - public void createEventForTestEvent() throws Exception { - Event event = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}).get(0); - Event anotherEvent = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}).get(0); - assertNotNull(event); - assertFalse(event.getUuid().equals(anotherEvent.getUuid())); - assertEquals(event.getTitle(), ConceptServiceEventFactory.TEST); - assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); + public void createEventForTestEventIfConceptClassIsLabTestOrTest() throws Exception { + Event eventForLabTestConceptClass = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{conceptWithLabTestClass}).get(0); + Event anotherEventForLabTestConceptClass = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{conceptWithLabTestClass}).get(0); + Event eventForTestConceptClass = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{conceptWithTestClass}).get(0); + Event anotherEventForTestConceptClass = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{conceptWithTestClass}).get(0); + assertNotNull(eventForLabTestConceptClass); + assertNotNull(eventForTestConceptClass); + assertFalse(eventForLabTestConceptClass.getUuid().equals(anotherEventForLabTestConceptClass.getUuid())); + assertEquals(eventForLabTestConceptClass.getTitle(), ConceptServiceEventFactory.TEST); + assertEquals(eventForLabTestConceptClass.getCategory(), ConceptServiceEventFactory.LAB); + assertFalse(eventForTestConceptClass.getUuid().equals(anotherEventForTestConceptClass.getUuid())); + assertEquals(eventForTestConceptClass.getTitle(), ConceptServiceEventFactory.TEST); + assertEquals(eventForTestConceptClass.getCategory(), ConceptServiceEventFactory.LAB); + } + + @Test + public void shouldCreateEventForCaseInsensitiveConceptClassMatches() throws Exception { + Concept conceptWithClassLabTest = new ConceptBuilder().withClass("LabTest").withUUID(LAB_TEST_CONCEPT_UUID).build(); + Concept conceptWithClasslabtest = new ConceptBuilder().withClass("labtest").withUUID("9b11d2d1-c7ea-40f7-8616-be9bec4c6b98").build(); + Event eventForLabTestConceptClass = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{conceptWithClassLabTest}).get(0); + Event eventForlabtestConceptClass = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{conceptWithClasslabtest}).get(0); + assertNotNull(eventForLabTestConceptClass); + assertNotNull(eventForlabtestConceptClass); + } @Test public void shouldNotCreateEventForTestEventIfThereIsDifferentConceptClass() throws Exception { - concept = new ConceptBuilder().withClassUUID("some").withClass("some").withUUID(TEST_CONCEPT_UUID).build(); - List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}); + conceptWithLabTestClass = new ConceptBuilder().withClassUUID("some").withClass("some").withUUID(TEST_CONCEPT_UUID).build(); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{conceptWithLabTestClass}); assertTrue(events.isEmpty()); } @Test public void shouldCreateEventForTestEventIfParentConceptIsMissing() throws Exception { when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(new ArrayList()); - List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{conceptWithLabTestClass}); Event event = events.get(0); assertNotNull(event); assertEquals(event.getTitle(), ConceptServiceEventFactory.TEST); @@ -90,9 +111,9 @@ public void shouldCreateEventForTestEventIfParentConceptIsMissing() throws Excep @Test public void shouldCreateEventForTestEventIfParentConceptIsWrong() throws Exception { - parentConcept = new ConceptBuilder().withName("Some wrong name").withSetMember(concept).build(); - when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(getConceptSets(parentConcept, concept)); - List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}); + parentConcept = new ConceptBuilder().withName("Some wrong name").withSetMember(conceptWithLabTestClass).build(); + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(getConceptSets(parentConcept, conceptWithLabTestClass)); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{conceptWithLabTestClass}); Event event = events.get(0); assertNotNull(event); assertEquals(event.getTitle(), ConceptServiceEventFactory.TEST); @@ -102,7 +123,7 @@ public void shouldCreateEventForTestEventIfParentConceptIsWrong() throws Excepti @Test public void createEventForTestWithParentConceptMissing() throws Exception { - Concept testConcept = new ConceptBuilder().withClass(LabTest.LAB_TEST_CONCEPT_CLASS).withUUID("testUUID").withClass("LabTest").build(); + Concept testConcept = new ConceptBuilder().withUUID("testUUID").withClass("LabTest").build(); List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{testConcept}); Event event = events.get(0); assertNotNull(event); @@ -110,4 +131,4 @@ public void createEventForTestWithParentConceptMissing() throws Exception { assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); } -} \ No newline at end of file +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AllSamplesMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AllSamplesMapperTest.java index 921dd8ca41..93b070b8bb 100644 --- a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AllSamplesMapperTest.java +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AllSamplesMapperTest.java @@ -56,7 +56,7 @@ public void setUp() throws Exception { Locale defaultLocale = new Locale("en", "GB"); PowerMockito.mockStatic(Context.class); when(Context.getLocale()).thenReturn(defaultLocale); - Concept testConcept = new ConceptBuilder().withUUID("Test UUID").withDateCreated(dateCreated).withClass(LabTest.LAB_TEST_CONCEPT_CLASS).withDescription("SomeDescription") + Concept testConcept = new ConceptBuilder().withUUID("Test UUID").withDateCreated(dateCreated).withClass(LabTest.LAB_TEST_CONCEPT_CLASSES.get(0)).withDescription("SomeDescription") .withDateChanged(dateChanged).withShortName("ShortName").withName("Test concept").withDataType(ConceptDatatype.NUMERIC).build(); sampleConcept = new ConceptBuilder().withUUID("Sample UUID").withDateCreated(dateCreated).withClass(Sample.SAMPLE_CONCEPT_CLASS). diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AllTestsAndPanelsMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AllTestsAndPanelsMapperTest.java index 4d743c0aeb..3335cfa7ce 100644 --- a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AllTestsAndPanelsMapperTest.java +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AllTestsAndPanelsMapperTest.java @@ -58,7 +58,7 @@ public void setUp() throws Exception { PowerMockito.mockStatic(Context.class); when(Context.getLocale()).thenReturn(defaultLocale); - testConcept = new ConceptBuilder().withUUID("Test UUID").withDateCreated(dateCreated).withClass(LabTest.LAB_TEST_CONCEPT_CLASS).withDescription("SomeDescription") + testConcept = new ConceptBuilder().withUUID("Test UUID").withDateCreated(dateCreated).withClass(LabTest.LAB_TEST_CONCEPT_CLASSES.get(0)).withDescription("SomeDescription") .withDateChanged(dateChanged).withShortName("ShortName").withName("Test concept").withDataType(ConceptDatatype.NUMERIC).build(); panelConcept = new ConceptBuilder().withUUID("Panel UUID").withDateCreated(dateCreated).withClassUUID(ConceptClass.LABSET_UUID).withDescription("SomeDescription") @@ -94,7 +94,7 @@ public void mapAllTestsAndPanelsFieldsFromConcept() throws Exception { @Test public void shouldNotMapTheTestOrPanelWhichIsRetired() throws Exception { - Concept testConcept = new ConceptBuilder().withUUID("Test UUID").withDateCreated(dateCreated).withClass(LabTest.LAB_TEST_CONCEPT_CLASS).withDescription("SomeDescription") + Concept testConcept = new ConceptBuilder().withUUID("Test UUID").withDateCreated(dateCreated).withClass(LabTest.LAB_TEST_CONCEPT_CLASSES.get(0)).withDescription("SomeDescription") .withDateChanged(dateChanged).withShortName("ShortName").withName("Test concept").withDataType(ConceptDatatype.NUMERIC).withRetired(true).build(); Concept panelConcept = new ConceptBuilder().withUUID("Panel UUID").withDateCreated(dateCreated).withClassUUID(ConceptClass.LABSET_UUID).withDescription("SomeDescription") .withSetMember(testConcept).withDateChanged(dateChanged).withShortName("ShortName").withName("Panel Name").withDataType(ConceptDatatype.NUMERIC).withRetired(true).build(); @@ -115,4 +115,4 @@ public void shouldNotMapTheTestOrPanelWhichIsRetired() throws Exception { Set panels = testsAndPanels.getPanels(); assertEquals(0, panels.size()); } -} \ No newline at end of file +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/LabTestMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/LabTestMapperTest.java index c559afd8f4..135e1b1805 100644 --- a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/LabTestMapperTest.java +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/LabTestMapperTest.java @@ -65,7 +65,7 @@ public void setUp() throws Exception { Locale defaultLocale = new Locale("en", "GB"); PowerMockito.mockStatic(Context.class); when(Context.getLocale()).thenReturn(defaultLocale); - testConcept = new ConceptBuilder().withUUID("Test UUID").withDateCreated(dateCreated).withClass(LabTest.LAB_TEST_CONCEPT_CLASS).withDescription("SomeDescription") + testConcept = new ConceptBuilder().withUUID("Test UUID").withDateCreated(dateCreated).withClass(LabTest.LAB_TEST_CONCEPT_CLASSES.get(0)).withDescription("SomeDescription") .withDateChanged(dateChanged).withShortName("ShortName").withName("Test Name Here").withDataType(ConceptDatatype.NUMERIC).build(); Concept testAndPanelsConcept = new ConceptBuilder().withUUID("Test and Panels UUID").withDateCreated(dateCreated).withClassUUID(ConceptClass.CONVSET_UUID) .withDateChanged(dateChanged).withShortName("ShortName").withName(AllTestsAndPanels.ALL_TESTS_AND_PANELS).withSetMember(testConcept).build(); diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/PanelMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/PanelMapperTest.java index d36951de14..37a9fc3aca 100644 --- a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/PanelMapperTest.java +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/PanelMapperTest.java @@ -63,7 +63,7 @@ public void setUp() throws Exception { Locale defaultLocale = new Locale("en", "GB"); PowerMockito.mockStatic(Context.class); when(Context.getLocale()).thenReturn(defaultLocale); - testConcept = new ConceptBuilder().withUUID("Test UUID").withDateCreated(dateCreated).withClass(LabTest.LAB_TEST_CONCEPT_CLASS).withDescription("SomeDescription") + testConcept = new ConceptBuilder().withUUID("Test UUID").withDateCreated(dateCreated).withClass(LabTest.LAB_TEST_CONCEPT_CLASSES.get(0)).withDescription("SomeDescription") .withDateChanged(dateChanged).withShortName("ShortName").withName("Panel Name Here").withDataType(ConceptDatatype.NUMERIC).build(); panelConcept = new ConceptBuilder().withUUID("Panel UUID").withDateCreated(dateCreated).withClassUUID(ConceptClass.LABSET_UUID).withDescription("SomeDescription") .withSetMember(testConcept).withDateChanged(dateChanged).withShortName("ShortName").withName("Panel Name Here").withDataType(ConceptDatatype.NUMERIC).build(); @@ -129,4 +129,4 @@ public void shouldSetNameIfDescriptionIsNull() throws Exception { Panel panelData = panelMapper.map(panelConceptWithoutDescription); assertEquals("Panel Name Here", panelData.getDescription()); } -} \ No newline at end of file +} From 925996e18ea2b34fe9c080c50e3b6d5ecfdd234e Mon Sep 17 00:00:00 2001 From: MOHANKUMAR T <31698165+mohan-13@users.noreply.github.com> Date: Tue, 4 Jun 2024 16:18:20 +0530 Subject: [PATCH 32/47] BAH-3893 | Enhancement to raise Radiology atomfeed events on save of concept with class Radiology/Imaging Procedure (#264) * BAH-3892 | Support atomfeed test events for concepts with class Test * BAH-3893 | Support atomfeed radiology events for concepts with class Radiology/Imaging Procedure --- .../labconcepts/contract/RadiologyTest.java | 5 ++++- .../labconcepts/model/event/RadiologyTestEvent.java | 6 +++--- .../labconcepts/model/event/SaleableTypeEvent.java | 5 +++-- .../model/event/RadiologyTestEventTest.java | 13 ++++++++++++- .../contract/mapper/RadiologyTestMapperTest.java | 4 ++-- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/RadiologyTest.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/RadiologyTest.java index bdbb789726..fba0a3c334 100644 --- a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/RadiologyTest.java +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/RadiologyTest.java @@ -1,6 +1,9 @@ package org.bahmni.module.referencedata.labconcepts.contract; +import java.util.Arrays; +import java.util.List; + public class RadiologyTest extends Resource { - public static final String RADIOLOGY_TEST_CONCEPT_CLASS = "Radiology"; + public static final List RADIOLOGY_TEST_CONCEPT_CLASSES = Arrays.asList("Radiology", "Radiology/Imaging Procedure"); public static final String RADIOLOGY_TEST_PARENT_CONCEPT_NAME = "Radiology"; } diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/RadiologyTestEvent.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/RadiologyTestEvent.java index 09230a6984..2f98ab8207 100644 --- a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/RadiologyTestEvent.java +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/RadiologyTestEvent.java @@ -2,8 +2,8 @@ import org.openmrs.Concept; -import static org.bahmni.module.referencedata.labconcepts.contract.RadiologyTest.RADIOLOGY_TEST_CONCEPT_CLASS; -import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.isOfConceptClass; +import static org.bahmni.module.referencedata.labconcepts.contract.RadiologyTest.RADIOLOGY_TEST_CONCEPT_CLASSES; +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.isOfAnyConceptClass; public class RadiologyTestEvent extends ConceptOperationEvent { @@ -14,7 +14,7 @@ public RadiologyTestEvent(String url, String category, String title) { @Override public boolean isResourceConcept(Concept concept) { - return isOfConceptClass(concept, RADIOLOGY_TEST_CONCEPT_CLASS); + return isOfAnyConceptClass(concept, RADIOLOGY_TEST_CONCEPT_CLASSES); } diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SaleableTypeEvent.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SaleableTypeEvent.java index 0deaaef970..6f884a6cd7 100644 --- a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SaleableTypeEvent.java +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SaleableTypeEvent.java @@ -16,7 +16,7 @@ import static org.bahmni.module.referencedata.labconcepts.contract.Department.DEPARTMENT_CONCEPT_CLASS; import static org.bahmni.module.referencedata.labconcepts.contract.LabTest.LAB_TEST_CONCEPT_CLASSES; import static org.bahmni.module.referencedata.labconcepts.contract.Panel.LAB_SET_CONCEPT_CLASS; -import static org.bahmni.module.referencedata.labconcepts.contract.RadiologyTest.RADIOLOGY_TEST_CONCEPT_CLASS; +import static org.bahmni.module.referencedata.labconcepts.contract.RadiologyTest.RADIOLOGY_TEST_CONCEPT_CLASSES; import static org.bahmni.module.referencedata.labconcepts.contract.Sample.SAMPLE_CONCEPT_CLASS; public class SaleableTypeEvent implements ConceptServiceOperationEvent { @@ -29,8 +29,9 @@ public class SaleableTypeEvent implements ConceptServiceOperationEvent { private List supportedOperations = Arrays.asList("saveConcept", "updateConcept", "retireConcept", "purgeConcept"); private List unhandledClasses = new ArrayList(){{ - addAll(Arrays.asList(LAB_SET_CONCEPT_CLASS, SAMPLE_CONCEPT_CLASS, DEPARTMENT_CONCEPT_CLASS, RADIOLOGY_TEST_CONCEPT_CLASS)); + addAll(Arrays.asList(LAB_SET_CONCEPT_CLASS, SAMPLE_CONCEPT_CLASS, DEPARTMENT_CONCEPT_CLASS)); addAll(LAB_TEST_CONCEPT_CLASSES); + addAll(RADIOLOGY_TEST_CONCEPT_CLASSES); }}; private List unhandledConcepsByName = Arrays.asList(ALL_SAMPLES, ALL_TESTS_AND_PANELS); diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/RadiologyTestEventTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/RadiologyTestEventTest.java index c72fc7e58c..5292c26af8 100644 --- a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/RadiologyTestEventTest.java +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/RadiologyTestEventTest.java @@ -70,6 +70,17 @@ public void createEventForSampleEvent() throws Exception { } + @Test + public void shouldCreateEventWhenClassIsRadiologyImagingProcedure() throws Exception{ + concept = new ConceptBuilder().withClass("Radiology/Imaging Procedure").withUUID(RADIOLOGY_TEST_CONCEPT_UUID).build(); + Event event = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}).get(0); + Event anotherEvent = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}).get(0); + assertNotNull(event); + assertFalse(event.getUuid().equals(anotherEvent.getUuid())); + assertEquals(event.getTitle(), ConceptServiceEventFactory.RADIOLOGY); + assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); + } + @Test public void shouldNotCreateEventForRadiologyEventIfThereIsDifferentConceptClass() throws Exception { concept = new ConceptBuilder().withClass("random").withClassUUID("some").withUUID(RADIOLOGY_TEST_CONCEPT_UUID).build(); @@ -109,4 +120,4 @@ public void createEventForRadiologyTestWithParentConceptMissing() throws Excepti assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); } -} \ No newline at end of file +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/RadiologyTestMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/RadiologyTestMapperTest.java index dd3085dc7f..404fe03d0a 100644 --- a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/RadiologyTestMapperTest.java +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/RadiologyTestMapperTest.java @@ -46,7 +46,7 @@ public void setUp() throws Exception { PowerMockito.mockStatic(Context.class); when(Context.getLocale()).thenReturn(defaultLocale); - radiologyConcept = new ConceptBuilder().withUUID("RadiologyUUID").withDateCreated(dateCreated).withClass(RadiologyTest.RADIOLOGY_TEST_CONCEPT_CLASS). + radiologyConcept = new ConceptBuilder().withUUID("RadiologyUUID").withDateCreated(dateCreated).withClass(RadiologyTest.RADIOLOGY_TEST_CONCEPT_CLASSES.get(0)). withDateChanged(dateChanged).withShortName("clavicle - right, 2 views (x-ray)").withName("Clavicle - Right, 2 views (X-ray)").build(); when(Context.getConceptService()).thenReturn(conceptService); @@ -62,4 +62,4 @@ public void mapNameOfRadiologyTestFromConcept() throws Exception { } -} \ No newline at end of file +} From 82ea8e8893010ce82dd0cf90df5653656fcb882c Mon Sep 17 00:00:00 2001 From: angshuman sarkar Date: Mon, 1 Jul 2024 02:09:26 +0000 Subject: [PATCH 33/47] BAH-3973 | optimizing query for patient list from ward (#265) --- .../dao/impl/BahmniConceptDaoImpl.java | 8 +- .../service/SqlSearchParamStore.java | 11 +++ .../service/impl/SqlSearchParamStoreImpl.java | 97 +++++++++++++++++++ .../service/impl/SqlSearchServiceImpl.java | 43 ++++++-- .../bahmnicore/util/SqlQueryHelper.java | 8 +- .../resources/moduleApplicationContext.xml | 5 + .../bahmnicore/util/SqlQueryHelperTest.java | 15 +++ .../src/main/resources/V1_99_WardsListSql.sql | 95 ++++++++++++++++++ .../src/main/resources/liquibase.xml | 4 + 9 files changed, 275 insertions(+), 11 deletions(-) create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/SqlSearchParamStore.java create mode 100644 bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/SqlSearchParamStoreImpl.java create mode 100644 bahmnicore-omod/src/main/resources/V1_99_WardsListSql.sql diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/BahmniConceptDaoImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/BahmniConceptDaoImpl.java index b119448b85..53ceb496b0 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/BahmniConceptDaoImpl.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/BahmniConceptDaoImpl.java @@ -1,8 +1,8 @@ package org.bahmni.module.bahmnicore.dao.impl; import org.bahmni.module.bahmnicore.dao.BahmniConceptDao; -import org.hibernate.Query; import org.hibernate.SessionFactory; +import org.hibernate.query.Query; import org.hibernate.type.StandardBasicTypes; import org.openmrs.Concept; import org.openmrs.ConceptAnswer; @@ -42,9 +42,9 @@ public Collection searchByQuestion(Concept questionConcept, Strin Query query = sessionFactory.getCurrentSession().createQuery( queryStringBuffer.toString()); - query.setEntity("questionConcept", questionConcept); + query.setParameter("questionConcept", questionConcept); for (int i = 0; i < queryArray.length; i++) { - query.setString("query"+ i, searchBothSidesOf(queryArray[i])); + query.setParameter("query"+ i, searchBothSidesOf(queryArray[i])); } return new HashSet<>(query.list()); @@ -57,7 +57,7 @@ public Concept getConceptByFullySpecifiedName(String fullySpecifiedConceptName) "from ConceptName as conceptName " + "where conceptName.conceptNameType ='FULLY_SPECIFIED' " + " and lower(conceptName.name)= lower(:fullySpecifiedName)") - .setString("fullySpecifiedName", fullySpecifiedConceptName) + .setParameter("fullySpecifiedName", fullySpecifiedConceptName) .list(); return concepts.size() > 0 ? concepts.get(0) : null; diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/SqlSearchParamStore.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/SqlSearchParamStore.java new file mode 100644 index 0000000000..b33663448d --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/SqlSearchParamStore.java @@ -0,0 +1,11 @@ +package org.bahmni.module.bahmnicore.service; + +import java.util.Map; + +public interface SqlSearchParamStore { + void initQueryParamStore(); + + boolean isInitialized(); + + Map getSearchableParameters(); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/SqlSearchParamStoreImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/SqlSearchParamStoreImpl.java new file mode 100644 index 0000000000..797b3c70ac --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/SqlSearchParamStoreImpl.java @@ -0,0 +1,97 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.service.SqlSearchParamStore; +import org.openmrs.Concept; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.ConceptNameType; +import org.openmrs.api.context.Context; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; + +public class SqlSearchParamStoreImpl implements SqlSearchParamStore { + public static final String BAHMNI_PRIMARY_IDENTIFIER_TYPE = "bahmni.primaryIdentifierType"; + public static final String ADT_NOTES_CONCEPT = "Adt Notes"; + public static final String VISIT_DIAGNOSES_CONCEPT = "Visit Diagnoses"; + public static final String CODED_DIAGNOSIS_CONCEPT = "Coded Diagnosis"; + public static final String NON_CODED_DIAGNOSIS_CONCEPT = "Non-coded Diagnosis"; + public static final String DIAGNOSIS_CERTAINTY_CONCEPT = "Diagnosis Certainty"; + public static final String DIAGNOSIS_ORDER_CONCEPT = "Diagnosis order"; + public static final String ADMISSION_ENCOUNTER_TYPE = "ADMISSION"; + public static final String DISPOSITION_CONCEPT = "Disposition"; + private AdministrationService administrationService; + private boolean initialized = false; + private Map parameters = new HashMap<>(); + + public void setAdministrationService(AdministrationService administrationService) { + this.administrationService = administrationService; + } + + private Map conceptNameFieldMap = new HashMap() {{ + put(ADT_NOTES_CONCEPT, "adt_notes_concept_id"); + put(VISIT_DIAGNOSES_CONCEPT, "visit_diagnoses_concept_id"); + put(CODED_DIAGNOSIS_CONCEPT, "coded_diagnosis_concept_id"); + put(NON_CODED_DIAGNOSIS_CONCEPT, "non_coded_diagnosis_concept_id"); + put(DIAGNOSIS_CERTAINTY_CONCEPT, "diagnosis_certainty_concept_id"); + put(DIAGNOSIS_ORDER_CONCEPT, "diagnosis_order_concept_id"); + put(DISPOSITION_CONCEPT, "disposition_concept_id"); + }}; + + @Override + public synchronized void initQueryParamStore() { + if (this.initialized) return; + parameters.clear(); + String primaryIdentifierProperty = administrationService.getGlobalProperty(BAHMNI_PRIMARY_IDENTIFIER_TYPE); + Optional.ofNullable(Context.getPatientService().getPatientIdentifierTypeByUuid(primaryIdentifierProperty)) + .ifPresent(identifierType -> parameters.put("patient_identifier_type_id", identifierType.getPatientIdentifierTypeId())); + Optional.ofNullable(Context.getEncounterService().getEncounterType(ADMISSION_ENCOUNTER_TYPE)) + .ifPresent(encounterType -> parameters.put("admission_encounter_type_id", encounterType.getEncounterTypeId())); + Context.getConceptService().getConceptsByName(ADT_NOTES_CONCEPT, Locale.ENGLISH, true) + .stream() + .findFirst() + .ifPresent(concept -> parameters.put(conceptNameFieldMap.get(ADT_NOTES_CONCEPT), concept.getConceptId())); + Context.getConceptService().getConceptsByName(DISPOSITION_CONCEPT, Locale.ENGLISH, true) + .stream() + .findFirst() + .ifPresent(concept -> parameters.put(conceptNameFieldMap.get(DISPOSITION_CONCEPT), concept.getConceptId())); + Optional visitDiagnosisConcept = Context.getConceptService().getConceptsByName(VISIT_DIAGNOSES_CONCEPT, Locale.ENGLISH, true).stream().findFirst(); + if (visitDiagnosisConcept.isPresent()) { + parameters.put(conceptNameFieldMap.get(VISIT_DIAGNOSES_CONCEPT), visitDiagnosisConcept.get().getConceptId()); + //noinspection DuplicatedCode + visitDiagnosisConcept.get().getSetMembers().stream().filter(member -> { + return matchMemberByName(member, CODED_DIAGNOSIS_CONCEPT); + }).findFirst().ifPresent(concept -> parameters.put(conceptNameFieldMap.get(CODED_DIAGNOSIS_CONCEPT), concept.getConceptId())); + + visitDiagnosisConcept.get().getSetMembers().stream().filter(member -> { + return matchMemberByName(member, NON_CODED_DIAGNOSIS_CONCEPT); + }).findFirst().ifPresent(concept -> parameters.put(conceptNameFieldMap.get(NON_CODED_DIAGNOSIS_CONCEPT), concept.getConceptId())); + //noinspection DuplicatedCode + visitDiagnosisConcept.get().getSetMembers().stream().filter(member -> { + return matchMemberByName(member, DIAGNOSIS_CERTAINTY_CONCEPT); + }).findFirst().ifPresent(concept -> parameters.put(conceptNameFieldMap.get(DIAGNOSIS_CERTAINTY_CONCEPT), concept.getConceptId())); + + visitDiagnosisConcept.get().getSetMembers().stream().filter(member -> { + return matchMemberByName(member, DIAGNOSIS_ORDER_CONCEPT); + }).findFirst().ifPresent(concept -> parameters.put(conceptNameFieldMap.get(DIAGNOSIS_ORDER_CONCEPT), concept.getConceptId())); + } + this.initialized = true; + } + + private boolean matchMemberByName(Concept member, String name) { + return member.getNames().stream().anyMatch(conceptName -> conceptName.getName().equals(name) + && conceptName.getConceptNameType().equals(ConceptNameType.FULLY_SPECIFIED) + && conceptName.getLocale().equals(Locale.ENGLISH)); + } + + @Override + public boolean isInitialized() { + return initialized; + } + + @Override + public Map getSearchableParameters() { + return this.parameters; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/SqlSearchServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/SqlSearchServiceImpl.java index 5e48a729fd..dbebda6a94 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/SqlSearchServiceImpl.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/SqlSearchServiceImpl.java @@ -1,11 +1,13 @@ package org.bahmni.module.bahmnicore.service.impl; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.bahmnicommons.api.visitlocation.BahmniVisitLocationServiceImpl; import org.bahmni.module.bahmnicore.service.RowMapper; import org.bahmni.module.bahmnicore.service.SqlSearchService; import org.bahmni.module.bahmnicore.util.SqlQueryHelper; import org.openmrs.api.AdministrationService; import org.openmrs.api.context.Context; -import org.bahmni.module.bahmnicommons.api.visitlocation.BahmniVisitLocationServiceImpl; import org.openmrs.module.webservices.rest.SimpleObject; import org.openmrs.util.DatabaseUpdater; @@ -19,21 +21,30 @@ public class SqlSearchServiceImpl implements SqlSearchService { private AdministrationService administrationService; + private SqlSearchParamStoreImpl searchParamStore; + + private static Logger logger = LogManager.getLogger(SqlSearchServiceImpl.class); public void setAdministrationService(AdministrationService administrationService) { this.administrationService = administrationService; } + public void setSearchParamStore(SqlSearchParamStoreImpl searchParamStore) { + this.searchParamStore = searchParamStore; + } + @Override public List search(String queryId, Map params) { Map updatedParams = conditionallyAddVisitLocation(params); + updatedParams.put("user_locale", new String[] { Context.getUserContext().getLocale().getLanguage() } ); + Map mergedParams = addQueryParamsFromStore(updatedParams); List results = new ArrayList<>(); SqlQueryHelper sqlQueryHelper = new SqlQueryHelper(); String query = getSql(queryId); + debugPrintQueryParams(queryId, mergedParams); try( Connection conn = DatabaseUpdater.getConnection(); - PreparedStatement statement = sqlQueryHelper.constructPreparedStatement(query,updatedParams,conn); - ResultSet resultSet = statement.executeQuery()) { - + PreparedStatement statement = sqlQueryHelper.constructPreparedStatement(query,mergedParams,conn); + ResultSet resultSet = statement.executeQuery()) { RowMapper rowMapper = new RowMapper(); while (resultSet.next()) { results.add(rowMapper.mapRow(resultSet)); @@ -44,6 +55,14 @@ public List search(String queryId, Map params) } } + private void debugPrintQueryParams(String queryId, Map mergedParams) { + logger.debug(String.format("Query Params for %s : %s", queryId, + mergedParams.entrySet().stream() + .map(entry -> entry.getKey()) + .reduce((s, e) -> s.concat(",").concat(e)) + .orElse(""))); + } + private String getSql(String queryId) { String query = administrationService.getGlobalProperty(queryId); if (query == null) throw new RuntimeException("No such query:" + queryId); @@ -55,9 +74,21 @@ private Map conditionallyAddVisitLocation(Map addQueryParamsFromStore(Map params) { + Map updatedParams = new HashMap<>(params); + if (!searchParamStore.isInitialized()) { + searchParamStore.initQueryParamStore(); } + Map searchableParameters = searchParamStore.getSearchableParameters(); + searchableParameters.entrySet().forEach(entry -> { + updatedParams.put(entry.getKey(), new String[] { entry.getValue().toString() } ); + }); return updatedParams; } } diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/SqlQueryHelper.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/SqlQueryHelper.java index 08bcbffdc6..6a7d7dfcad 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/SqlQueryHelper.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/SqlQueryHelper.java @@ -56,7 +56,13 @@ public PreparedStatement constructPreparedStatement(String queryString, Map + + + + + diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/SqlQueryHelperTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/SqlQueryHelperTest.java index c78e550722..4b0c217f41 100644 --- a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/SqlQueryHelperTest.java +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/SqlQueryHelperTest.java @@ -6,7 +6,9 @@ import org.mockito.MockitoAnnotations; import org.openmrs.api.AdministrationService; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.when; @@ -72,4 +74,17 @@ public void shouldEscapeSQLInjection() { assertEquals("admin\\'--", SqlQueryHelper.escapeSQL("admin'--", true, null)); assertEquals("admin\\'\\\\/*", SqlQueryHelper.escapeSQL("admin'/*", true, null)); } + + @Test + public void shouldDetectSameParams(){ + String queryString ="select * from location where name=${location_name} or location_id=${location_id} or location_id in (select l.location_id from location l where l.name=${location_name})"; + String expectQueryString = "select * from location where name=? or location_id=? or location_id in (select l.location_id from location l where l.name=?)"; + String result = sqlQueryHelper.transformIntoPreparedStatementFormat(queryString); + assertEquals(expectQueryString,result); + List paramNamesFromPlaceHolders = sqlQueryHelper.getParamNamesFromPlaceHolders(queryString); + assertEquals(3, paramNamesFromPlaceHolders.size()); + assertEquals("location_name", paramNamesFromPlaceHolders.get(0)); + assertEquals("location_id", paramNamesFromPlaceHolders.get(1)); + assertEquals("location_name", paramNamesFromPlaceHolders.get(2)); + } } diff --git a/bahmnicore-omod/src/main/resources/V1_99_WardsListSql.sql b/bahmnicore-omod/src/main/resources/V1_99_WardsListSql.sql new file mode 100644 index 0000000000..22e9b38fe1 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_99_WardsListSql.sql @@ -0,0 +1,95 @@ +DELETE FROM global_property where property = 'emrapi.sqlGet.wardsListDetails'; + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlGet.wardsListDetails', +"SELECT + DISTINCT b.bed_number AS Bed, + p.uuid AS 'Patient Uuid', + pi.identifier AS 'Id', + concat(pn.given_name, ' ', ifnull(pn.family_name,'')) AS 'Name', + p.gender AS 'Gender', + TIMESTAMPDIFF(YEAR, p.birthdate, CURDATE()) AS 'Age', + pa.county_district AS 'District', + pa.city_village AS 'Village', + cast(DATE_FORMAT(admissionEncounter.encounter_datetime, '%d %b %y %h:%i %p') AS CHAR) AS 'Admission Time', + adtNotesObs.value_text AS 'ADT Notes', + admissionVisit.uuid AS 'Visit Uuid', + concat(admProvName.given_name, ' ', ifnull(admProvName.family_name,'')) AS 'Admission By', + dispositionInfo.disp_provider_name AS 'Disposition By', + cast(DATE_FORMAT(dispositionInfo.disposition_date, '%d %b %y %h:%i %p') AS CHAR) AS 'Disposition Time', + patient_diagnosis.encounter_diagnosis as 'Diagnosis', + patient_diagnosis.diagnosis_by as 'Diagnosis Provider', + cast(DATE_FORMAT(patient_diagnosis.diagnosis_datetime, '%d %b %y %h:%i %p') AS CHAR) AS 'Diagnosis Datetime' +FROM bed_location_map blm +INNER JOIN bed b ON blm.bed_id = b.bed_id AND b.status = 'OCCUPIED' +INNER JOIN bed_patient_assignment_map bpam ON b.bed_id = bpam.bed_id AND bpam.date_stopped IS NULL +INNER JOIN person p ON bpam.patient_id=p.person_id +INNER JOIN person_name pn ON pn.person_id = p.person_id +INNER JOIN patient_identifier pi ON pi.patient_id = bpam.patient_id AND pi.identifier_type= ${patient_identifier_type_id} +INNER JOIN location bl ON blm.location_id=bl.location_id +LEFT OUTER JOIN person_address pa ON pa.person_id = p.person_id +LEFT OUTER JOIN ( + SELECT DISTINCT + do.person_id as patient_id, + concat(depn.given_name, ' ', ifnull(depn.family_name,'')) AS diagnosis_by, + MAX(do.obs_datetime) as diagnosis_datetime, + MAX(CASE WHEN do.concept_id = ${coded_diagnosis_concept_id} THEN dcn.name WHEN do.concept_id = ${non_coded_diagnosis_concept_id} THEN do.value_text END) as encounter_diagnosis + FROM obs do + INNER JOIN (SELECT + od.person_id AS patient_id, MAX(od.encounter_id) AS diagnosis_encounter_id + FROM bed_patient_assignment_map pam + INNER JOIN bed ab ON pam.bed_id=ab.bed_id AND ab.status = 'OCCUPIED' + INNER JOIN obs od ON pam.patient_id=od.person_id + INNER JOIN encounter de ON od.encounter_id = de.encounter_id + WHERE od.concept_id=${visit_diagnoses_concept_id} GROUP BY od.person_id + ) denc ON denc.patient_id = do.person_id AND do.encounter_id = denc.diagnosis_encounter_id + LEFT OUTER JOIN concept_name dcn ON do.value_coded = dcn.concept_id AND dcn.concept_name_type='FULLY_SPECIFIED' AND dcn.locale='en' + INNER JOIN encounter_provider dep ON dep.encounter_id = denc.diagnosis_encounter_id + INNER JOIN provider dp ON dp.provider_id = dep.provider_id + LEFT OUTER JOIN person_name depn ON depn.person_id = dp.person_id + GROUP BY patient_id, diagnosis_by +) patient_diagnosis ON patient_diagnosis.patient_id = bpam.patient_id +LEFT OUTER JOIN (SELECT + bpame.patient_id, + max(e.encounter_datetime) AS encounter_datetime, + max(e.visit_id) as visit_id, + max(e.encounter_id) AS encounter_id + FROM bed_patient_assignment_map bpame + INNER JOIN bed b ON bpame.bed_id=b.bed_id AND b.status = 'OCCUPIED' + INNER JOIN bed_location_map bm ON bm.bed_id=b.bed_id + INNER JOIN location loc ON bm.location_id=loc.location_id + INNER JOIN encounter e ON e.patient_id=bpame.patient_id + INNER JOIN encounter_type et ON e.encounter_type=et.encounter_type_id AND et.name='ADMISSION' + INNER JOIN visit av ON av.visit_id=e.visit_id + GROUP BY bpame.patient_id +) admissionEncounter ON admissionEncounter.patient_id=bpam.patient_id +LEFT OUTER JOIN visit admissionVisit ON admissionVisit.visit_id=admissionEncounter.visit_id +LEFT OUTER JOIN encounter_provider admEncProv ON admEncProv.encounter_id = admissionEncounter.encounter_id +LEFT OUTER JOIN provider admProv ON admProv.provider_id = admEncProv.provider_id +LEFT OUTER JOIN person_name admProvName ON admProvName.person_id = admProv.person_id +LEFT OUTER JOIN obs adtNotesObs ON adtNotesObs.encounter_id = admissionEncounter.encounter_id AND adtNotesObs.concept_id=${adt_notes_concept_id} +LEFT OUTER JOIN (SELECT + dpam.patient_id, + dispCn.name AS disposition, + lastDisp.obs_datetime AS disposition_date, + concat(dispn.given_name, ' ', ifnull(dispn.family_name,'')) AS disp_provider_name + FROM bed_patient_assignment_map dpam + INNER JOIN (SELECT + bpm.patient_id, MAX(dos.obs_id) AS obs_id + FROM bed_patient_assignment_map bpm + INNER JOIN bed b ON bpm.bed_id=b.bed_id AND b.status = 'OCCUPIED' + INNER JOIN obs dos ON dos.person_id=bpm.patient_id + WHERE dos.concept_id=${disposition_concept_id} + GROUP BY bpm.patient_id + ) maxObsId ON maxObsId.patient_id = dpam.patient_id + INNER JOIN obs lastDisp ON maxObsId.obs_id = lastDisp.obs_id AND lastDisp.voided = 0 + INNER JOIN concept_name dispCn ON lastDisp.value_coded = dispCn.concept_id AND dispCn.concept_name_type = 'FULLY_SPECIFIED' and dispCn.locale='en' + LEFT OUTER JOIN encounter_provider dispEp ON dispEp.encounter_id = lastDisp.encounter_id + LEFT OUTER JOIN provider dispProv ON dispProv.provider_id = dispEp.provider_id + LEFT OUTER JOIN person_name dispn ON dispn.person_id = dispProv.person_id + WHERE dpam.date_stopped IS NULL +) dispositionInfo ON dispositionInfo.patient_id = bpam.patient_id +WHERE bl.name = ${location_name} OR bl.parent_location in (SELECT location_id FROM location WHERE name = ${location_name} )", +'Sql query to get list of wards', +uuid() +); diff --git a/bahmnicore-omod/src/main/resources/liquibase.xml b/bahmnicore-omod/src/main/resources/liquibase.xml index 682fff9f75..0558ae4cc0 100644 --- a/bahmnicore-omod/src/main/resources/liquibase.xml +++ b/bahmnicore-omod/src/main/resources/liquibase.xml @@ -4678,5 +4678,9 @@ name = 'Stage' AND datatype = 'org.bahmni.module.bahmnicore.customdatatype.datatype.CodedConceptDatatype'; + + Update the wards list sql to optimize for MySQL 8 - Bahmni Standard 1.0 + + From 1909f3888e339b499f39329e969d764a21d93f83 Mon Sep 17 00:00:00 2001 From: MOHANKUMAR T <31698165+mohan-13@users.noreply.github.com> Date: Mon, 1 Jul 2024 09:18:27 +0530 Subject: [PATCH 34/47] Fix. Use upgraded runner version. macos-11 has been deprecated by Github Actions. https://github.blog/changelog/2024-05-20-actions-upcoming-changes-to-github-hosted-macos-runners/#macos-11-deprecation-and-removal --- .github/workflows/build_publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_publish.yml b/.github/workflows/build_publish.yml index 0d65180b02..38070da90f 100644 --- a/.github/workflows/build_publish.yml +++ b/.github/workflows/build_publish.yml @@ -7,7 +7,7 @@ on: jobs: build-publish-package: name: Build and Publish package - runs-on: macos-11 + runs-on: macos-14 steps: - uses: actions/checkout@v2 - name: Set up JDK 1.8 From 1555fbec857af62caec7ffa488c218f93a43c58c Mon Sep 17 00:00:00 2001 From: MOHANKUMAR T <31698165+mohan-13@users.noreply.github.com> Date: Fri, 12 Jul 2024 12:35:10 +0530 Subject: [PATCH 35/47] Upgraded runner version to macos-14 for Validate PR workflow --- .github/workflows/validate_pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/validate_pr.yml b/.github/workflows/validate_pr.yml index 9049223614..e63ea4ae86 100644 --- a/.github/workflows/validate_pr.yml +++ b/.github/workflows/validate_pr.yml @@ -6,7 +6,7 @@ on: jobs: build: name: Build - runs-on: macos-11 + runs-on: macos-14 steps: - uses: actions/checkout@v2 - name: Set up JDK 1.8 From 6359f3c770b722833bd57a96175d7ca1ae493a64 Mon Sep 17 00:00:00 2001 From: MOHANKUMAR T <31698165+mohan-13@users.noreply.github.com> Date: Fri, 12 Jul 2024 12:35:33 +0530 Subject: [PATCH 36/47] BAH-4026 | Raise Sample event when the concept class is Specimen (#267) --- .../labconcepts/contract/Sample.java | 5 +++-- .../labconcepts/mapper/AllSamplesMapper.java | 4 ++-- .../model/event/SaleableTypeEvent.java | 5 +++-- .../labconcepts/model/event/SampleEvent.java | 6 +++--- .../ConceptServiceEventInterceptorTest.java | 4 ++-- .../model/event/SampleEventTest.java | 18 +++++++++++++++++- .../contract/mapper/AllSamplesMapperTest.java | 12 +++++++++--- .../web/contract/mapper/LabTestMapperTest.java | 2 +- .../web/contract/mapper/PanelMapperTest.java | 2 +- .../web/contract/mapper/SampleMapperTest.java | 4 ++-- 10 files changed, 43 insertions(+), 19 deletions(-) diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Sample.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Sample.java index f2b5c8728b..84aeda70ed 100644 --- a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Sample.java +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Sample.java @@ -1,10 +1,11 @@ package org.bahmni.module.referencedata.labconcepts.contract; +import java.util.Arrays; import java.util.List; public class Sample extends Resource { private String shortName; - public static final String SAMPLE_CONCEPT_CLASS = "Sample"; + public static final List SAMPLE_CONCEPT_CLASSES = Arrays.asList("Sample", "Specimen"); private Double sortOrder; private List tests; private List panels; @@ -40,4 +41,4 @@ public Double getSortOrder() { public void setSortOrder(Double sortOrder) { this.sortOrder = sortOrder; } -} \ No newline at end of file +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/AllSamplesMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/AllSamplesMapper.java index d033492f03..29ff54aec6 100644 --- a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/AllSamplesMapper.java +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/AllSamplesMapper.java @@ -3,7 +3,7 @@ import org.bahmni.module.referencedata.labconcepts.contract.AllSamples; import org.openmrs.Concept; -import static org.bahmni.module.referencedata.labconcepts.contract.Sample.SAMPLE_CONCEPT_CLASS; +import static org.bahmni.module.referencedata.labconcepts.contract.Sample.SAMPLE_CONCEPT_CLASSES; public class AllSamplesMapper extends ResourceMapper { @@ -18,7 +18,7 @@ public AllSamples map(Concept allSamplesConcept) { allSamples.setDescription(ConceptExtension.getDescription(allSamplesConcept)); for (Concept setMember : allSamplesConcept.getSetMembers()) { - if (ConceptExtension.isOfConceptClass(setMember, SAMPLE_CONCEPT_CLASS)) { + if (ConceptExtension.isOfAnyConceptClass(setMember, SAMPLE_CONCEPT_CLASSES)) { SampleMapper sampleMapper = new SampleMapper(); allSamples.addSample(sampleMapper.map(setMember)); } diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SaleableTypeEvent.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SaleableTypeEvent.java index 6f884a6cd7..f71ea0a580 100644 --- a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SaleableTypeEvent.java +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SaleableTypeEvent.java @@ -17,7 +17,7 @@ import static org.bahmni.module.referencedata.labconcepts.contract.LabTest.LAB_TEST_CONCEPT_CLASSES; import static org.bahmni.module.referencedata.labconcepts.contract.Panel.LAB_SET_CONCEPT_CLASS; import static org.bahmni.module.referencedata.labconcepts.contract.RadiologyTest.RADIOLOGY_TEST_CONCEPT_CLASSES; -import static org.bahmni.module.referencedata.labconcepts.contract.Sample.SAMPLE_CONCEPT_CLASS; +import static org.bahmni.module.referencedata.labconcepts.contract.Sample.SAMPLE_CONCEPT_CLASSES; public class SaleableTypeEvent implements ConceptServiceOperationEvent { @@ -29,9 +29,10 @@ public class SaleableTypeEvent implements ConceptServiceOperationEvent { private List supportedOperations = Arrays.asList("saveConcept", "updateConcept", "retireConcept", "purgeConcept"); private List unhandledClasses = new ArrayList(){{ - addAll(Arrays.asList(LAB_SET_CONCEPT_CLASS, SAMPLE_CONCEPT_CLASS, DEPARTMENT_CONCEPT_CLASS)); + addAll(Arrays.asList(LAB_SET_CONCEPT_CLASS, DEPARTMENT_CONCEPT_CLASS)); addAll(LAB_TEST_CONCEPT_CLASSES); addAll(RADIOLOGY_TEST_CONCEPT_CLASSES); + addAll(SAMPLE_CONCEPT_CLASSES); }}; private List unhandledConcepsByName = Arrays.asList(ALL_SAMPLES, ALL_TESTS_AND_PANELS); diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SampleEvent.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SampleEvent.java index 1191423631..fdc69f74c8 100644 --- a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SampleEvent.java +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SampleEvent.java @@ -2,8 +2,8 @@ import org.openmrs.Concept; -import static org.bahmni.module.referencedata.labconcepts.contract.Sample.SAMPLE_CONCEPT_CLASS; -import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.isOfConceptClass; +import static org.bahmni.module.referencedata.labconcepts.contract.Sample.SAMPLE_CONCEPT_CLASSES; +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.isOfAnyConceptClass; public class SampleEvent extends ConceptOperationEvent { @@ -14,7 +14,7 @@ public SampleEvent(String url, String category, String title) { @Override public boolean isResourceConcept(Concept concept) { - return isOfConceptClass(concept, SAMPLE_CONCEPT_CLASS); + return isOfAnyConceptClass(concept, SAMPLE_CONCEPT_CLASSES); } diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/advice/ConceptServiceEventInterceptorTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/advice/ConceptServiceEventInterceptorTest.java index 346d7cb4e7..033defa11e 100644 --- a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/advice/ConceptServiceEventInterceptorTest.java +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/advice/ConceptServiceEventInterceptorTest.java @@ -55,7 +55,7 @@ public class ConceptServiceEventInterceptorTest { public void setup() { MockitoAnnotations.initMocks(this); - concept = new ConceptBuilder().withClass(Sample.SAMPLE_CONCEPT_CLASS).withUUID(SampleEventTest.SAMPLE_CONCEPT_UUID).build(); + concept = new ConceptBuilder().withClass(Sample.SAMPLE_CONCEPT_CLASSES.get(0)).withUUID(SampleEventTest.SAMPLE_CONCEPT_UUID).build(); Concept parentConcept = new ConceptBuilder().withName(AllSamples.ALL_SAMPLES).withSetMember(concept).build(); @@ -143,4 +143,4 @@ public void shouldSaveEventInTheSameTransactionAsTheTrigger() throws Throwable { assertEquals(AFTransactionWork.PropagationDefinition.PROPAGATION_REQUIRED, captor.getValue().getTxPropagationDefinition()); } -} \ No newline at end of file +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/SampleEventTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/SampleEventTest.java index 43e60125ad..ec2b778f71 100644 --- a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/SampleEventTest.java +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/SampleEventTest.java @@ -34,8 +34,12 @@ public class SampleEventTest { public static final String SAMPLE_CONCEPT_UUID = "aebc57b7-0683-464e-ac48-48b8838abdfc"; + public static final String SPECIMEN_CONCEPT_UUID = "aebc57b7-0683-464e-ac48-48b8838abdff"; + private Concept concept; + private Concept specimenConcept; + @Mock private ConceptService conceptService; private Concept parentConcept; @@ -46,6 +50,8 @@ public void setup() { concept = new ConceptBuilder().withClass("Sample").withUUID(SAMPLE_CONCEPT_UUID).build(); + specimenConcept = new ConceptBuilder().withClass("Specimen").withUUID(SPECIMEN_CONCEPT_UUID).build(); + parentConcept = new ConceptBuilder().withName(AllSamples.ALL_SAMPLES).withSetMember(concept).build(); List conceptSets = getConceptSets(parentConcept, concept); @@ -69,6 +75,16 @@ public void createEventForSampleEvent() throws Exception { assertEquals(event.getCategory(), "lab"); } + @Test + public void createSampleEventForSpecimenConcept() throws Exception { + Event event = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{specimenConcept}).get(0); + Event anotherEvent = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{specimenConcept}).get(0); + assertNotNull(event); + assertFalse(event.getUuid().equals(anotherEvent.getUuid())); + assertEquals(event.getTitle(), "sample"); + assertEquals(event.getCategory(), "lab"); + } + @Test public void shouldNotCreateEventForSampleEventIfThereIsDifferentConceptClass() throws Exception { concept = new ConceptBuilder().withClass("procedure").withClassUUID("some").withUUID(SAMPLE_CONCEPT_UUID).build(); @@ -106,4 +122,4 @@ public void createEventForSampleWithParentConceptMissing() throws Exception { assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); } -} \ No newline at end of file +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AllSamplesMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AllSamplesMapperTest.java index 93b070b8bb..053e3e5ff7 100644 --- a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AllSamplesMapperTest.java +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AllSamplesMapperTest.java @@ -36,6 +36,7 @@ public class AllSamplesMapperTest { private AllSamplesMapper allSamplesMapper; private SampleMapper sampleMapper; private Concept sampleConcept; + private Concept specimenConcept; private Date dateCreated; private Date dateChanged; private Concept labSampleConceptSet; @@ -59,12 +60,17 @@ public void setUp() throws Exception { Concept testConcept = new ConceptBuilder().withUUID("Test UUID").withDateCreated(dateCreated).withClass(LabTest.LAB_TEST_CONCEPT_CLASSES.get(0)).withDescription("SomeDescription") .withDateChanged(dateChanged).withShortName("ShortName").withName("Test concept").withDataType(ConceptDatatype.NUMERIC).build(); - sampleConcept = new ConceptBuilder().withUUID("Sample UUID").withDateCreated(dateCreated).withClass(Sample.SAMPLE_CONCEPT_CLASS). + sampleConcept = new ConceptBuilder().withUUID("Sample UUID").withDateCreated(dateCreated).withClass(Sample.SAMPLE_CONCEPT_CLASSES.get(0)). withDateChanged(dateChanged).withSetMember(testConcept).withShortName("ShortName").withName("SampleName").build(); + specimenConcept = new ConceptBuilder().withUUID("Specimen UUID").withDateCreated(dateCreated).withClass(Sample.SAMPLE_CONCEPT_CLASSES.get(1)). + withDateChanged(dateChanged).withSetMember(testConcept).withShortName("SpecimenShortName").withName("SpecimenName").build(); + labSampleConceptSet = new ConceptBuilder().withUUID("Lab Samples UUID").withDateCreated(dateCreated).withDateChanged(dateChanged) .withName(AllSamples.ALL_SAMPLES).withClassUUID(ConceptClass.LABSET_UUID).withShortName("Lab samples short name").withDescription("Lab samples Description") - .withSetMember(sampleConcept).build(); + .withSetMember(sampleConcept) + .withSetMember(specimenConcept) + .build(); when(Context.getConceptService()).thenReturn(conceptService); } @@ -80,7 +86,7 @@ public void mapAllSampleFieldsFromConcept() throws Exception { assertEquals(dateChanged, labSamplesData.getLastUpdated()); assertEquals("Lab samples Description", labSamplesData.getDescription()); List samples = labSamplesData.getSamples(); - assertEquals(1, samples.size()); + assertEquals(2, samples.size()); assertEquals(sampleData.getId(), samples.get(0).getId()); } diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/LabTestMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/LabTestMapperTest.java index 135e1b1805..fcf243d440 100644 --- a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/LabTestMapperTest.java +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/LabTestMapperTest.java @@ -69,7 +69,7 @@ public void setUp() throws Exception { .withDateChanged(dateChanged).withShortName("ShortName").withName("Test Name Here").withDataType(ConceptDatatype.NUMERIC).build(); Concept testAndPanelsConcept = new ConceptBuilder().withUUID("Test and Panels UUID").withDateCreated(dateCreated).withClassUUID(ConceptClass.CONVSET_UUID) .withDateChanged(dateChanged).withShortName("ShortName").withName(AllTestsAndPanels.ALL_TESTS_AND_PANELS).withSetMember(testConcept).build(); - Concept sampleConcept = new ConceptBuilder().withUUID("Sample UUID").withDateCreated(dateCreated).withClass(Sample.SAMPLE_CONCEPT_CLASS). + Concept sampleConcept = new ConceptBuilder().withUUID("Sample UUID").withDateCreated(dateCreated).withClass(Sample.SAMPLE_CONCEPT_CLASSES.get(0)). withDateChanged(dateChanged).withSetMember(testConcept).withShortName("ShortName").withName("SampleName").build(); Concept laboratoryConcept = new ConceptBuilder().withUUID("Laboratory UUID") .withName(AllSamples.ALL_SAMPLES).withClassUUID(ConceptClass.LABSET_UUID) diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/PanelMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/PanelMapperTest.java index 37a9fc3aca..843d8ef327 100644 --- a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/PanelMapperTest.java +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/PanelMapperTest.java @@ -69,7 +69,7 @@ public void setUp() throws Exception { .withSetMember(testConcept).withDateChanged(dateChanged).withShortName("ShortName").withName("Panel Name Here").withDataType(ConceptDatatype.NUMERIC).build(); Concept testAndPanelsConcept = new ConceptBuilder().withUUID("Test and Panels UUID").withDateCreated(dateCreated).withClassUUID(ConceptClass.CONVSET_UUID) .withDateChanged(dateChanged).withShortName("ShortName").withName(AllTestsAndPanels.ALL_TESTS_AND_PANELS).withSetMember(panelConcept).build(); - Concept sampleConcept = new ConceptBuilder().withUUID("Sample UUID").withDateCreated(dateCreated).withClass(Sample.SAMPLE_CONCEPT_CLASS). + Concept sampleConcept = new ConceptBuilder().withUUID("Sample UUID").withDateCreated(dateCreated).withClass(Sample.SAMPLE_CONCEPT_CLASSES.get(0)). withDateChanged(dateChanged).withSetMember(panelConcept).withShortName("ShortName").withName("SampleName").build(); Concept departmentConcept = new ConceptBuilder().withUUID("Department UUID").withDateCreated(dateCreated). withDateChanged(dateChanged).withClass("Department").withClassUUID(ConceptClass.CONVSET_UUID).withSetMember(panelConcept).withDescription("Some Description").withName("Department Name").build(); diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/SampleMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/SampleMapperTest.java index 429c5bbd7e..c26faf015e 100644 --- a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/SampleMapperTest.java +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/SampleMapperTest.java @@ -55,7 +55,7 @@ public void setUp() { when(Context.getLocale()).thenReturn(defaultLocale); sampleConcept = new ConceptBuilder().forSample().withShortName("ShortName").build(); allSamplesConcept = new ConceptBuilder().withUUID("Laboratory UUID") - .withName(AllSamples.ALL_SAMPLES).withClass(Sample.SAMPLE_CONCEPT_CLASS) + .withName(AllSamples.ALL_SAMPLES).withClass(Sample.SAMPLE_CONCEPT_CLASSES.get(0)) .withSetMember(sampleConcept).build(); ConceptSet conceptSet = createConceptSet(allSamplesConcept, sampleConcept); sortOrder = Double.valueOf(22); @@ -120,4 +120,4 @@ public void mapPanelsFromConceptSetMembers(){ assertEquals(1, sample.getPanels().size()); assertEquals("PanelName", sample.getPanels().get(0).getName()); } -} \ No newline at end of file +} From c53f6f706b29b49fda721db28ad35e40a6bc882e Mon Sep 17 00:00:00 2001 From: angshuman sarkar Date: Fri, 19 Jul 2024 07:25:35 +0000 Subject: [PATCH 37/47] BAH-4029 | adding better logs in cases of outside range values or invalid values for coded answers (#269) * BAH-4029 | Logging better logs in cases of outside range values or invalid values for coded answers * BAH-4029 | minor improvement - adding a gaurd clause to check if concept is numeric --- .../laborder/mapper/LabOrderResultMapper.java | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/mapper/LabOrderResultMapper.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/mapper/LabOrderResultMapper.java index 9113a523a2..44526a9f37 100644 --- a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/mapper/LabOrderResultMapper.java +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/mapper/LabOrderResultMapper.java @@ -4,6 +4,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openmrs.Concept; +import org.openmrs.ConceptNumeric; import org.openmrs.Obs; import org.openmrs.Order; import org.openmrs.api.APIException; @@ -14,6 +15,7 @@ import java.text.ParseException; import java.util.Date; +import java.util.Optional; import static org.apache.commons.lang3.StringUtils.isEmpty; import static org.apache.commons.lang3.StringUtils.isNotBlank; @@ -21,6 +23,7 @@ @Component public class LabOrderResultMapper { private static final Log log = LogFactory.getLog(LabOrderResultMapper.class); + private static final String EMPTY_STRING = ""; public static final String LAB_RESULT = "LAB_RESULT"; public static final String LAB_ABNORMAL = "LAB_ABNORMAL"; public static final String LAB_MINNORMAL = "LAB_MINNORMAL"; @@ -72,13 +75,14 @@ private Obs newResultObs(Order testOrder, Date obsDate, Concept concept, LabOrde obs.setConcept(concept); obs.setOrder(testOrder); obs.setObsDatetime(obsDate); + String accessionUuid = Optional.ofNullable(labOrderResult.getAccessionUuid()).orElseGet(() -> Optional.ofNullable(obs.getOrder()).map(Order::getAccessionNumber).orElse(EMPTY_STRING)); if (concept.getDatatype().getHl7Abbreviation().equals("CWE")) { String resultUuid = labOrderResult.getResultUuid(); Concept conceptAnswer = isEmpty(resultUuid) ? null : conceptService.getConceptByUuid(resultUuid); obs.setValueCoded(conceptAnswer); if (conceptAnswer == null) { - log.warn(String.format("Concept is not available in OpenMRS for ConceptUuid : [%s] , In Accession : [%s]" - , resultUuid,labOrderResult.getAccessionUuid())); + log.error(String.format("Concept [%s] does not not have coded answer with ConceptUuid [%s] in OpenMRS, In Accession [%s]", + obs.getConcept().getName(), resultUuid, accessionUuid)); return null; } return obs; @@ -88,9 +92,29 @@ private Obs newResultObs(Order testOrder, Date obsDate, Concept concept, LabOrde return null; } obs.setValueAsString(labOrderResult.getResult()); + checkResultRangesForAbsolutes(obs, accessionUuid); return obs; } + /** + * This method just logs error if the results are out of absolute ranges. This will be errored out (ValidationException) + * by openmrs by the {@link org.openmrs.validator.ObsValidator} during save + */ + private void checkResultRangesForAbsolutes(Obs obs, String accessionUuid) { + if (!obs.getConcept().isNumeric()) { + return; + } + if (obs.getValueNumeric() != null) { + ConceptNumeric cn = (ConceptNumeric) obs.getConcept(); + if (cn.getHiAbsolute() != null && cn.getHiAbsolute() < obs.getValueNumeric()) { + log.error(String.format("Test results for [%s] is beyond the absolute high range, in Accession [%s]", cn.getName(), accessionUuid)); + } + if (cn.getLowAbsolute() != null && cn.getLowAbsolute() > obs.getValueNumeric()) { + log.error(String.format("Test results for [%s] is beyond the absolute low range, in Accession [%s]", cn.getName(), accessionUuid)); + } + } + } + private Concept getConceptByName(String conceptName) { return conceptService.getConceptByName(conceptName); } From ffd25c0d3da8f212273eaee94eee5e8cb3de2137 Mon Sep 17 00:00:00 2001 From: MOHANKUMAR T <31698165+mohan-13@users.noreply.github.com> Date: Mon, 22 Jul 2024 15:12:05 +0530 Subject: [PATCH 38/47] BAH-4029 | Fix. Class Cast exception by using getConceptNumeric (#270) --- .../bahmniemrapi/laborder/mapper/LabOrderResultMapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/mapper/LabOrderResultMapper.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/mapper/LabOrderResultMapper.java index 44526a9f37..98683a29f4 100644 --- a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/mapper/LabOrderResultMapper.java +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/mapper/LabOrderResultMapper.java @@ -105,7 +105,7 @@ private void checkResultRangesForAbsolutes(Obs obs, String accessionUuid) { return; } if (obs.getValueNumeric() != null) { - ConceptNumeric cn = (ConceptNumeric) obs.getConcept(); + ConceptNumeric cn = conceptService.getConceptNumeric(obs.getConcept().getId()); if (cn.getHiAbsolute() != null && cn.getHiAbsolute() < obs.getValueNumeric()) { log.error(String.format("Test results for [%s] is beyond the absolute high range, in Accession [%s]", cn.getName(), accessionUuid)); } From 2a03cf968b082ea2e7f644c6d733d7185c5d0b46 Mon Sep 17 00:00:00 2001 From: MOHANKUMAR T <31698165+mohan-13@users.noreply.github.com> Date: Thu, 25 Jul 2024 19:28:37 +0530 Subject: [PATCH 39/47] BAH-4045 | Add. Privilege for getting program attribute types (#272) * BAH-4045 | Add. Privilege for getting program attribute types * BAH-4045 | Add. Assign Get Patient Program Attribute Types privilege to clinical app readonly role * Revert "BAH-4045 | Add. Assign Get Patient Program Attribute Types privilege to clinical app readonly role" - moved to config This reverts commit 124558a8a8793a0d900b8b8cef09d4de504bc43d. --- bahmnicore-omod/src/main/resources/config.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bahmnicore-omod/src/main/resources/config.xml b/bahmnicore-omod/src/main/resources/config.xml index 0111d342a4..cc89fb354f 100644 --- a/bahmnicore-omod/src/main/resources/config.xml +++ b/bahmnicore-omod/src/main/resources/config.xml @@ -98,6 +98,10 @@ app:lab-lite Will give access to Lab Lite app + + Get Patient Program Attribute Types + Ability to get program attribute types + org.openmrs.module.bahmniemrapi.encountertransaction.service.BahmniEncounterTransactionService From a6989747e5238d68bc0a90647902fb648a1ecdb1 Mon Sep 17 00:00:00 2001 From: Rahul Ramesh <121226043+rahu1ramesh@users.noreply.github.com> Date: Mon, 29 Jul 2024 17:22:46 +0530 Subject: [PATCH 40/47] BAH-3971 | Add. contextCookieExpirationTimeInMinutes Global Property (#273) --- bahmnicore-omod/src/main/resources/config.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bahmnicore-omod/src/main/resources/config.xml b/bahmnicore-omod/src/main/resources/config.xml index cc89fb354f..f993a01946 100644 --- a/bahmnicore-omod/src/main/resources/config.xml +++ b/bahmnicore-omod/src/main/resources/config.xml @@ -203,6 +203,11 @@ Boolean to enable sending sms when patient registers + + bahmni.contextCookieExpirationTimeInMinutes + 0 + Expiration time in minutes of the cookie that maintains the user's session context + org.openmrs.api.PatientService From 53fccf7220a8915612b9bc9ae21cbe00d2a10b61 Mon Sep 17 00:00:00 2001 From: MOHANKUMAR T <31698165+mohan-13@users.noreply.github.com> Date: Thu, 8 Aug 2024 08:55:28 +0530 Subject: [PATCH 41/47] BAH-4065 | Fix. Get Concept by FSN should return only unretired concepts (#274) --- .../bahmni/module/bahmnicore/dao/impl/BahmniConceptDaoImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/BahmniConceptDaoImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/BahmniConceptDaoImpl.java index 53ceb496b0..77ec81ff4b 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/BahmniConceptDaoImpl.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/BahmniConceptDaoImpl.java @@ -98,6 +98,7 @@ public List getConceptsByFullySpecifiedName(List conceptNames) .createQuery("select concept " + "from ConceptName as conceptName " + "where conceptName.conceptNameType ='FULLY_SPECIFIED' and conceptName.voided = false" + + " and conceptName.concept.retired = false" + " and lower(conceptName.name) in (:conceptNames)").setParameterList("conceptNames", lowerCaseConceptNames).list(); return concepts; } From dd48d7d6359835ae8c8b1604a2bb6d81adbe72e7 Mon Sep 17 00:00:00 2001 From: MOHANKUMAR T <31698165+mohan-13@users.noreply.github.com> Date: Tue, 27 Aug 2024 06:22:34 +0530 Subject: [PATCH 42/47] BAH-4090 | Refactor. Upgrade dependencies for release (#275) * BAH-4090 | Refactor. Upgrade dependencies for release * BAH-4090 | Fix. Mocks for AdministrationService --- .../impl/PatientDocumentServiceImplTest.java | 21 +++++++++++++++-- .../BahmniPatientProfileResourceTest.java | 2 +- pom.xml | 23 ++++++++++--------- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImplTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImplTest.java index 33dde79176..c1611333bb 100644 --- a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImplTest.java +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImplTest.java @@ -7,6 +7,7 @@ import org.bahmni.module.bahmnicore.model.VideoFormats; import org.bahmni.module.bahmnicore.properties.BahmniCoreProperties; import org.bahmni.module.bahmnicore.service.ThumbnailGenerator; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -15,10 +16,13 @@ import org.mockito.Matchers; import org.mockito.Mock; import org.openmrs.Patient; +import org.openmrs.api.context.UserContext; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.springframework.http.ResponseEntity; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.context.Context; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; @@ -39,9 +43,10 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.powermock.api.mockito.PowerMockito.verifyStatic; +import static org.mockito.MockitoAnnotations.initMocks; @RunWith(PowerMockRunner.class) -@PrepareForTest({BahmniCoreProperties.class, FileInputStream.class, FileUtils.class, ImageIO.class}) +@PrepareForTest({BahmniCoreProperties.class, FileInputStream.class, FileUtils.class, ImageIO.class, Context.class}) public class PatientDocumentServiceImplTest { private PatientDocumentServiceImpl patientDocumentService; @@ -54,6 +59,18 @@ public class PatientDocumentServiceImplTest { @Mock ThumbnailGenerator thumbnailGenerator; + @Mock + private AdministrationService administrationService; + + @Mock + private UserContext userContext; + + @Before + public void setUp() { + initMocks(this); + PowerMockito.mockStatic(Context.class); + when(Context.getAdministrationService()).thenReturn(administrationService); + } @Test public void shouldCreateRightDirectoryAccordingToPatientId() { @@ -176,7 +193,7 @@ public void shouldThrowExceptionWhenImageTypeOtherThanPngJpegGif() throws Except patientDocumentService = new PatientDocumentServiceImpl(); patientDocumentService.saveDocument(1, "Consultation", "otherfileContent", "bmp", "image", "file-name"); } - + @Test public void shouldCreateThumbnailForVideo() throws Exception { PowerMockito.mockStatic(BahmniCoreProperties.class); diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniPatientProfileResourceTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniPatientProfileResourceTest.java index 3370598943..2c3267b43f 100644 --- a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniPatientProfileResourceTest.java +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniPatientProfileResourceTest.java @@ -93,6 +93,7 @@ public void setUp() throws IOException { PowerMockito.when(Context.getService(RestService.class)).thenReturn(restService); PowerMockito.when(Context.getPersonService()).thenReturn(personService); PowerMockito.when(Context.getMessageSourceService()).thenReturn(messageSourceService); + PowerMockito.when(Context.getAdministrationService()).thenReturn(administrationService); PowerMockito.when(restService.getResourceBySupportedClass(Patient.class)).thenReturn(patientResource1_8); PowerMockito.when(patientResource1_8.getPatient(any(SimpleObject.class))).thenReturn(patient); PowerMockito.when(patientResource1_8.getPatientForUpdate(anyString(), any(SimpleObject.class))).thenReturn(patient); @@ -106,7 +107,6 @@ public void createPatient() throws Exception { when(identifierSourceServiceWrapper.generateIdentifierUsingIdentifierSourceUuid("dead-cafe", "")).thenReturn("BAH300010"); doReturn(delegate).when(bahmniPatientProfileResourceSpy, "mapForCreatePatient", propertiesToCreate); when(emrPatientProfileService.save(delegate)).thenReturn(delegate); - when(Context.getAdministrationService()).thenReturn(administrationService); when(Context.getPatientService()).thenReturn(patientService); Patient patient = mock(Patient.class); when(patient.getUuid()).thenReturn("patientUuid"); diff --git a/pom.xml b/pom.xml index 8f16b17f7a..28710b3601 100644 --- a/pom.xml +++ b/pom.xml @@ -46,30 +46,31 @@ UTF-8 2.5.12 - 2.39.0 + 2.44.0 5.2.14.RELEASE 1.10.1 - 2.14.2 - 1.23.0 + 2.17.0 + 1.26.0 1.3.0 0.2.15 - 1.35.0-SNAPSHOT - 1.5.0 + 1.36.0 + 1.6.0 2.6.3 1.18.20 - 4.7.0 - 1.13.0 + 4.10.0 + 1.16.0 1.1.0 1.3.0 1.3.0 1.0.0 - 0.94.4-SNAPSHOT + 1.0.0 4.0.1 2.17.1 1.4.0 - 2.13.0 + 2.14.0 1.6.2 - 1.1.0-SNAPSHOT + 1.1.0 + 1.2.0 4.13 @@ -579,7 +580,7 @@ org.bahmni.module communication-api - 1.2.0-SNAPSHOT + ${communicationVersion} jar provided From a50beb14d36efe46cf7cc4d2c44724d58edb6392 Mon Sep 17 00:00:00 2001 From: MOHANKUMAR T <31698165+mohan-13@users.noreply.github.com> Date: Tue, 27 Aug 2024 06:22:53 +0530 Subject: [PATCH 43/47] BAH-4090 | Add. Workflow torelease artifacts on push of a tag (#276) --- .github/workflows/build_publish.yml | 9 ++++-- .github/workflows/release_deploy.yml | 44 ++++++++++++++++++++++++++++ pom.xml | 7 +++++ 3 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/release_deploy.yml diff --git a/.github/workflows/build_publish.yml b/.github/workflows/build_publish.yml index 38070da90f..4a3166bd9e 100644 --- a/.github/workflows/build_publish.yml +++ b/.github/workflows/build_publish.yml @@ -32,8 +32,13 @@ jobs: run: | sudo gem install compass -v 1.0.3 - name: Build and deploy with Maven - run: ./mvnw --no-transfer-progress clean -U deploy + run: | + PROJECT_VERSION=$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout) + if [[ "$PROJECT_VERSION" == *"-SNAPSHOT" ]]; then + ./mvnw --no-transfer-progress clean -U deploy + else + echo "❌ The current push is for release. So skipping build." + fi env: NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }} NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} - diff --git a/.github/workflows/release_deploy.yml b/.github/workflows/release_deploy.yml new file mode 100644 index 0000000000..4388e95024 --- /dev/null +++ b/.github/workflows/release_deploy.yml @@ -0,0 +1,44 @@ +name: Build and Release package +on: + push: + tags: + - '[0-9]+.[0-9]+.[0-9]+' + +jobs: + build-release-package: + name: Build and Release package + runs-on: macos-14 + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + server-id: nexus-sonatype + server-username: NEXUS_USERNAME + server-password: NEXUS_PASSWORD + gpg-private-key: ${{ secrets.BAHMNI_INFRA_GPG_KEY }} + - name: Compare Git tag with Maven version + run: | + export GIT_TAG=${GITHUB_REF#refs/tags/} + PROJECT_VERSION=$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout) + if [ "$PROJECT_VERSION" != "$GIT_TAG" ]; then + echo "❌ The Git tag ($GIT_TAG) does not match the Maven version ($PROJECT_VERSION)." + exit 1 + else + echo "✅ The Git tag matches the Maven version." + fi + - name: Install Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '2.7' + bundler-cache: true + - name: Install compass + run: | + sudo gem install compass -v 1.0.3 + - name: Build and deploy with Maven + run: ./mvnw --no-transfer-progress clean -U deploy -DperformRelease=true + env: + NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }} + NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} + GPG_PASSPHRASE: ${{ secrets.BAHMNI_INFRA_GPG_PASSPHRASE }} diff --git a/pom.xml b/pom.xml index 28710b3601..fa9708e9c6 100644 --- a/pom.xml +++ b/pom.xml @@ -155,6 +155,13 @@ org.apache.maven.plugins maven-gpg-plugin 1.6 + + + + --pinentry-mode + loopback + + sign-artifacts From cafe093702412d63000d07ca0ce4f36331ed6c9d Mon Sep 17 00:00:00 2001 From: MOHANKUMAR T Date: Tue, 27 Aug 2024 06:28:08 +0530 Subject: [PATCH 44/47] BAH-4090 | Release of version 1.2.0 --- admin/pom.xml | 2 +- bahmni-emr-api/pom.xml | 2 +- bahmni-mapping/pom.xml | 2 +- bahmni-test-commons/pom.xml | 2 +- bahmnicore-api/pom.xml | 2 +- bahmnicore-omod/pom.xml | 2 +- bahmnicore-ui/pom.xml | 2 +- obs-relation/pom.xml | 2 +- openmrs-elis-atomfeed-client-omod/pom.xml | 2 +- pom.xml | 2 +- reference-data/api/pom.xml | 2 +- reference-data/omod/pom.xml | 2 +- reference-data/pom.xml | 2 +- vagrant-deploy/pom.xml | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/admin/pom.xml b/admin/pom.xml index 66185a5bf6..b9e548afd6 100644 --- a/admin/pom.xml +++ b/admin/pom.xml @@ -5,7 +5,7 @@ bahmni org.bahmni.module - 1.2.0-SNAPSHOT + 1.2.0 admin diff --git a/bahmni-emr-api/pom.xml b/bahmni-emr-api/pom.xml index 77df76dc48..f6e91820ea 100644 --- a/bahmni-emr-api/pom.xml +++ b/bahmni-emr-api/pom.xml @@ -5,7 +5,7 @@ bahmni org.bahmni.module - 1.2.0-SNAPSHOT + 1.2.0 4.0.0 diff --git a/bahmni-mapping/pom.xml b/bahmni-mapping/pom.xml index 0625d9428d..95767562f2 100644 --- a/bahmni-mapping/pom.xml +++ b/bahmni-mapping/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.2.0-SNAPSHOT + 1.2.0 bahmni-mapping jar diff --git a/bahmni-test-commons/pom.xml b/bahmni-test-commons/pom.xml index a65be4f4ae..0b3074dae7 100644 --- a/bahmni-test-commons/pom.xml +++ b/bahmni-test-commons/pom.xml @@ -14,7 +14,7 @@ bahmni org.bahmni.module - 1.2.0-SNAPSHOT + 1.2.0 diff --git a/bahmnicore-api/pom.xml b/bahmnicore-api/pom.xml index 4aaf0cf22a..108c4e0b8a 100644 --- a/bahmnicore-api/pom.xml +++ b/bahmnicore-api/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.2.0-SNAPSHOT + 1.2.0 bahmnicore-api jar diff --git a/bahmnicore-omod/pom.xml b/bahmnicore-omod/pom.xml index d987a02bc7..0616e1c797 100644 --- a/bahmnicore-omod/pom.xml +++ b/bahmnicore-omod/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.2.0-SNAPSHOT + 1.2.0 bahmnicore-omod jar diff --git a/bahmnicore-ui/pom.xml b/bahmnicore-ui/pom.xml index c43c0c1438..c7c66f3220 100644 --- a/bahmnicore-ui/pom.xml +++ b/bahmnicore-ui/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.2.0-SNAPSHOT + 1.2.0 bahmnicore-ui jar diff --git a/obs-relation/pom.xml b/obs-relation/pom.xml index 959203f92d..0568ff8871 100644 --- a/obs-relation/pom.xml +++ b/obs-relation/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.2.0-SNAPSHOT + 1.2.0 obs-relationship jar diff --git a/openmrs-elis-atomfeed-client-omod/pom.xml b/openmrs-elis-atomfeed-client-omod/pom.xml index bf1ac4e8b1..9dd0782864 100644 --- a/openmrs-elis-atomfeed-client-omod/pom.xml +++ b/openmrs-elis-atomfeed-client-omod/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.2.0-SNAPSHOT + 1.2.0 openelis-atomfeed-client-omod jar diff --git a/pom.xml b/pom.xml index fa9708e9c6..df2a60597e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.2.0-SNAPSHOT + 1.2.0 pom Bahmni EMR Core https://github.com/Bahmni/bahmni-core.git diff --git a/reference-data/api/pom.xml b/reference-data/api/pom.xml index dccf8ecc3e..342d95a7bc 100644 --- a/reference-data/api/pom.xml +++ b/reference-data/api/pom.xml @@ -5,7 +5,7 @@ reference-data org.bahmni.module - 1.2.0-SNAPSHOT + 1.2.0 4.0.0 diff --git a/reference-data/omod/pom.xml b/reference-data/omod/pom.xml index 3d7a3df678..4117f84ab7 100644 --- a/reference-data/omod/pom.xml +++ b/reference-data/omod/pom.xml @@ -5,7 +5,7 @@ reference-data org.bahmni.module - 1.2.0-SNAPSHOT + 1.2.0 4.0.0 diff --git a/reference-data/pom.xml b/reference-data/pom.xml index c7e84fd69c..0cf3eb9569 100644 --- a/reference-data/pom.xml +++ b/reference-data/pom.xml @@ -10,7 +10,7 @@ org.bahmni.module bahmni - 1.2.0-SNAPSHOT + 1.2.0 reference-data pom diff --git a/vagrant-deploy/pom.xml b/vagrant-deploy/pom.xml index 5b8d62805b..8d3ec28702 100644 --- a/vagrant-deploy/pom.xml +++ b/vagrant-deploy/pom.xml @@ -5,7 +5,7 @@ bahmni org.bahmni.module - 1.2.0-SNAPSHOT + 1.2.0 4.0.0 From a2a062a353c170c6d3f4a0e4e00b9c90ab8e5458 Mon Sep 17 00:00:00 2001 From: MOHANKUMAR T Date: Tue, 27 Aug 2024 06:47:33 +0530 Subject: [PATCH 45/47] BAH-4090 | Incrementing dev version to 1.3.0-SNAPSHOT --- admin/pom.xml | 2 +- bahmni-emr-api/pom.xml | 2 +- bahmni-mapping/pom.xml | 2 +- bahmni-test-commons/pom.xml | 2 +- bahmnicore-api/pom.xml | 2 +- bahmnicore-omod/pom.xml | 2 +- bahmnicore-ui/pom.xml | 2 +- obs-relation/pom.xml | 2 +- openmrs-elis-atomfeed-client-omod/pom.xml | 2 +- pom.xml | 2 +- reference-data/api/pom.xml | 2 +- reference-data/omod/pom.xml | 2 +- reference-data/pom.xml | 2 +- vagrant-deploy/pom.xml | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/admin/pom.xml b/admin/pom.xml index b9e548afd6..8a86e9db96 100644 --- a/admin/pom.xml +++ b/admin/pom.xml @@ -5,7 +5,7 @@ bahmni org.bahmni.module - 1.2.0 + 1.3.0-SNAPSHOT admin diff --git a/bahmni-emr-api/pom.xml b/bahmni-emr-api/pom.xml index f6e91820ea..07eff7dbf6 100644 --- a/bahmni-emr-api/pom.xml +++ b/bahmni-emr-api/pom.xml @@ -5,7 +5,7 @@ bahmni org.bahmni.module - 1.2.0 + 1.3.0-SNAPSHOT 4.0.0 diff --git a/bahmni-mapping/pom.xml b/bahmni-mapping/pom.xml index 95767562f2..c7941d8667 100644 --- a/bahmni-mapping/pom.xml +++ b/bahmni-mapping/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.2.0 + 1.3.0-SNAPSHOT bahmni-mapping jar diff --git a/bahmni-test-commons/pom.xml b/bahmni-test-commons/pom.xml index 0b3074dae7..2c161cd15e 100644 --- a/bahmni-test-commons/pom.xml +++ b/bahmni-test-commons/pom.xml @@ -14,7 +14,7 @@ bahmni org.bahmni.module - 1.2.0 + 1.3.0-SNAPSHOT diff --git a/bahmnicore-api/pom.xml b/bahmnicore-api/pom.xml index 108c4e0b8a..aa7524047d 100644 --- a/bahmnicore-api/pom.xml +++ b/bahmnicore-api/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.2.0 + 1.3.0-SNAPSHOT bahmnicore-api jar diff --git a/bahmnicore-omod/pom.xml b/bahmnicore-omod/pom.xml index 0616e1c797..2935d14827 100644 --- a/bahmnicore-omod/pom.xml +++ b/bahmnicore-omod/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.2.0 + 1.3.0-SNAPSHOT bahmnicore-omod jar diff --git a/bahmnicore-ui/pom.xml b/bahmnicore-ui/pom.xml index c7c66f3220..52d2201c8c 100644 --- a/bahmnicore-ui/pom.xml +++ b/bahmnicore-ui/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.2.0 + 1.3.0-SNAPSHOT bahmnicore-ui jar diff --git a/obs-relation/pom.xml b/obs-relation/pom.xml index 0568ff8871..fed6735be3 100644 --- a/obs-relation/pom.xml +++ b/obs-relation/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.2.0 + 1.3.0-SNAPSHOT obs-relationship jar diff --git a/openmrs-elis-atomfeed-client-omod/pom.xml b/openmrs-elis-atomfeed-client-omod/pom.xml index 9dd0782864..e723b2940c 100644 --- a/openmrs-elis-atomfeed-client-omod/pom.xml +++ b/openmrs-elis-atomfeed-client-omod/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.2.0 + 1.3.0-SNAPSHOT openelis-atomfeed-client-omod jar diff --git a/pom.xml b/pom.xml index df2a60597e..d9f290a2fd 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.bahmni.module bahmni - 1.2.0 + 1.3.0-SNAPSHOT pom Bahmni EMR Core https://github.com/Bahmni/bahmni-core.git diff --git a/reference-data/api/pom.xml b/reference-data/api/pom.xml index 342d95a7bc..915c9dc89d 100644 --- a/reference-data/api/pom.xml +++ b/reference-data/api/pom.xml @@ -5,7 +5,7 @@ reference-data org.bahmni.module - 1.2.0 + 1.3.0-SNAPSHOT 4.0.0 diff --git a/reference-data/omod/pom.xml b/reference-data/omod/pom.xml index 4117f84ab7..998505a743 100644 --- a/reference-data/omod/pom.xml +++ b/reference-data/omod/pom.xml @@ -5,7 +5,7 @@ reference-data org.bahmni.module - 1.2.0 + 1.3.0-SNAPSHOT 4.0.0 diff --git a/reference-data/pom.xml b/reference-data/pom.xml index 0cf3eb9569..bcfd6bcb01 100644 --- a/reference-data/pom.xml +++ b/reference-data/pom.xml @@ -10,7 +10,7 @@ org.bahmni.module bahmni - 1.2.0 + 1.3.0-SNAPSHOT reference-data pom diff --git a/vagrant-deploy/pom.xml b/vagrant-deploy/pom.xml index 8d3ec28702..bb7b72e0f7 100644 --- a/vagrant-deploy/pom.xml +++ b/vagrant-deploy/pom.xml @@ -5,7 +5,7 @@ bahmni org.bahmni.module - 1.2.0 + 1.3.0-SNAPSHOT 4.0.0 From b8a6bf3a84cd0800a40f72706f10cd2fb2086060 Mon Sep 17 00:00:00 2001 From: Kavitha S Date: Thu, 10 Oct 2024 09:14:52 +0530 Subject: [PATCH 46/47] fix test failures --- .../bahmnicore/service/impl/BahmniObsServiceImpl.java | 7 +++++-- .../org/bahmni/module/bahmnicore/util/MiscUtils.java | 5 +++-- .../service/impl/BahmniObsServiceImplTest.java | 5 ++++- .../bahmni/module/bahmnicore/util/MiscUtilsTest.java | 6 ++++-- .../web/v1_0/controller/BahmniOrderController.java | 7 +++++-- .../controls/BahmniObservationsController.java | 11 +++++++---- .../controller/BahmniObservationsControllerTest.java | 6 +++++- .../v1_0/controller/BahmniOrderControllerTest.java | 11 ++++++++--- 8 files changed, 41 insertions(+), 17 deletions(-) diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImpl.java index 5c9087d468..edc6736d66 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImpl.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImpl.java @@ -6,6 +6,7 @@ import org.bahmni.module.bahmnicore.dao.VisitDao; import org.bahmni.module.bahmnicore.dao.impl.ObsDaoImpl; import org.bahmni.module.bahmnicore.dao.impl.ObsDaoImpl.OrderBy; +import org.bahmni.module.bahmnicore.service.BahmniConceptService; import org.bahmni.module.bahmnicore.service.BahmniObsService; import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; import org.bahmni.module.bahmnicore.util.MiscUtils; @@ -37,9 +38,10 @@ public class BahmniObsServiceImpl implements BahmniObsService { private ConceptService conceptService; private BahmniProgramWorkflowService programWorkflowService; private ObsService obsService; + private BahmniConceptService bahmniConceptService; @Autowired - public BahmniObsServiceImpl(ObsDao obsDao, OMRSObsToBahmniObsMapper omrsObsToBahmniObsMapper, VisitService visitService, ConceptService conceptService, VisitDao visitDao, BahmniProgramWorkflowService programWorkflowService, ObsService obsService) { + public BahmniObsServiceImpl(ObsDao obsDao, OMRSObsToBahmniObsMapper omrsObsToBahmniObsMapper, VisitService visitService, ConceptService conceptService, VisitDao visitDao, BahmniProgramWorkflowService programWorkflowService, ObsService obsService, BahmniConceptService bahmniConceptService) { this.obsDao = obsDao; this.omrsObsToBahmniObsMapper = omrsObsToBahmniObsMapper; this.visitService = visitService; @@ -47,6 +49,7 @@ public BahmniObsServiceImpl(ObsDao obsDao, OMRSObsToBahmniObsMapper omrsObsToBah this.visitDao = visitDao; this.programWorkflowService = programWorkflowService; this.obsService = obsService; + this.bahmniConceptService = bahmniConceptService; } @Override @@ -220,7 +223,7 @@ public Collection getObservationForVisit(String visitUuid, Li List persons = new ArrayList<>(); persons.add(visit.getPatient()); List observations = obsDao.getObsForVisits(persons, new ArrayList<>(visit.getEncounters()), - MiscUtils.getConceptsForNames(conceptNames, conceptService), obsIgnoreList, filterOutOrders, order); + MiscUtils.getConceptsForNames(conceptNames, bahmniConceptService, conceptService), obsIgnoreList, filterOutOrders, order); observations = new ArrayList<>(getObsAtTopLevelAndApplyIgnoreList(observations, conceptNames, obsIgnoreList)); return omrsObsToBahmniObsMapper.map(observations, null); } diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/MiscUtils.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/MiscUtils.java index 73042231b6..8010a2b5b8 100644 --- a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/MiscUtils.java +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/MiscUtils.java @@ -1,6 +1,7 @@ package org.bahmni.module.bahmnicore.util; import org.apache.commons.collections.CollectionUtils; +import org.bahmni.module.bahmnicore.service.BahmniConceptService; import org.openmrs.Concept; import org.openmrs.ConceptName; import org.openmrs.api.ConceptService; @@ -15,12 +16,12 @@ import java.util.regex.Pattern; public class MiscUtils { - public static List getConceptsForNames(List conceptNames, ConceptService conceptService) { + public static List getConceptsForNames(List conceptNames, BahmniConceptService bahmniConceptService, ConceptService conceptService) { //Returning null for the sake of UTs if (CollectionUtils.isNotEmpty(conceptNames)) { List rootConcepts = new ArrayList<>(); for (String rootConceptName : conceptNames) { - Concept concept = conceptService.getConceptByName(rootConceptName); + Concept concept = bahmniConceptService.getConceptByFullySpecifiedName(rootConceptName); if (concept == null) { concept = getConceptInDefaultLocale(conceptService, rootConceptName); } diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImplTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImplTest.java index 4cb5f5e368..2f3ee4e6ee 100644 --- a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImplTest.java +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImplTest.java @@ -3,6 +3,7 @@ import org.bahmni.module.bahmnicore.dao.ObsDao; import org.bahmni.module.bahmnicore.dao.VisitDao; import org.bahmni.module.bahmnicore.dao.impl.ObsDaoImpl; +import org.bahmni.module.bahmnicore.service.BahmniConceptService; import org.bahmni.module.bahmnicore.service.BahmniObsService; import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; import org.bahmni.test.builder.ConceptBuilder; @@ -73,6 +74,8 @@ public class BahmniObsServiceImplTest { private ObsService obsService; @Mock private OMRSObsToBahmniObsMapper omrsObsToBahmniObsMapper; + @Mock + private BahmniConceptService bahmniConceptService; @Before public void setUp() { @@ -81,7 +84,7 @@ public void setUp() { mockStatic(LocaleUtility.class); when(LocaleUtility.getDefaultLocale()).thenReturn(Locale.ENGLISH); when(observationTypeMatcher.getObservationType(any(Obs.class))).thenReturn(ObservationTypeMatcher.ObservationType.OBSERVATION); - bahmniObsService = new BahmniObsServiceImpl(obsDao, omrsObsToBahmniObsMapper, visitService, conceptService, visitDao, bahmniProgramWorkflowService, obsService); + bahmniObsService = new BahmniObsServiceImpl(obsDao, omrsObsToBahmniObsMapper, visitService, conceptService, visitDao, bahmniProgramWorkflowService, obsService, bahmniConceptService); } @Test diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/MiscUtilsTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/MiscUtilsTest.java index 83b428a468..fca38ac54f 100644 --- a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/MiscUtilsTest.java +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/MiscUtilsTest.java @@ -1,5 +1,6 @@ package org.bahmni.module.bahmnicore.util; +import org.bahmni.module.bahmnicore.service.BahmniConceptService; import org.junit.Test; import org.openmrs.Concept; import org.openmrs.api.ConceptService; @@ -24,12 +25,13 @@ public class MiscUtilsTest { @Test public void shouldReturnConceptsWhenTheyAreAvailable() { ConceptService conceptService = mock(ConceptService.class); + BahmniConceptService bahmniconceptService = mock(BahmniConceptService.class); String nonExistantConceptName = "doesNotExist"; String sampleConceptName = "sampleConcept"; when(conceptService.getConceptByName(nonExistantConceptName)).thenReturn(null); Concept sampleConcept = new Concept(); - when(conceptService.getConceptByName(sampleConceptName)).thenReturn(sampleConcept); - Collection concepts = MiscUtils.getConceptsForNames(Arrays.asList(sampleConceptName, nonExistantConceptName), conceptService); + when(bahmniconceptService.getConceptByFullySpecifiedName(sampleConceptName)).thenReturn(sampleConcept); + Collection concepts = MiscUtils.getConceptsForNames(Arrays.asList(sampleConceptName, nonExistantConceptName), bahmniconceptService, conceptService); assertThat(concepts.size(), is(equalTo(1))); assertThat(concepts.iterator().next(), is(sampleConcept)); } diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniOrderController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniOrderController.java index e0025bc841..7a974496af 100644 --- a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniOrderController.java +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniOrderController.java @@ -1,5 +1,6 @@ package org.bahmni.module.bahmnicore.web.v1_0.controller; +import org.bahmni.module.bahmnicore.service.BahmniConceptService; import org.bahmni.module.bahmnicore.service.BahmniOrderService; import org.bahmni.module.bahmnicore.util.MiscUtils; import org.openmrs.Concept; @@ -22,11 +23,13 @@ public class BahmniOrderController extends BaseRestController { private ConceptService conceptService; private BahmniOrderService bahmniOrderService; + private BahmniConceptService bahmniConceptService; @Autowired - public BahmniOrderController(ConceptService conceptService, BahmniOrderService bahmniOrderService) { + public BahmniOrderController(ConceptService conceptService, BahmniOrderService bahmniOrderService, BahmniConceptService bahmniConceptService) { this.conceptService = conceptService; this.bahmniOrderService = bahmniOrderService; + this.bahmniConceptService = bahmniConceptService; } @@ -44,7 +47,7 @@ public List get(@RequestParam(value = "patientUuid", required = tru if (visitUuid != null) { - return bahmniOrderService.ordersForVisit(visitUuid, orderTypeUuid, rootConceptNames, MiscUtils.getConceptsForNames(obsIgnoreList, conceptService)); + return bahmniOrderService.ordersForVisit(visitUuid, orderTypeUuid, rootConceptNames, MiscUtils.getConceptsForNames(obsIgnoreList, bahmniConceptService, conceptService)); } List rootConcepts = getConcepts(rootConceptNames); diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniObservationsController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniObservationsController.java index b3ac3f1410..f4c565400b 100644 --- a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniObservationsController.java +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniObservationsController.java @@ -4,6 +4,7 @@ import org.apache.commons.lang3.ObjectUtils; import org.bahmni.module.bahmnicore.extensions.BahmniExtensions; import org.bahmni.module.bahmnicore.obs.ObservationsAdder; +import org.bahmni.module.bahmnicore.service.BahmniConceptService; import org.bahmni.module.bahmnicore.service.BahmniObsService; import org.bahmni.module.bahmnicore.util.MiscUtils; import org.bahmni.module.bahmnicore.web.v1_0.LocaleResolver; @@ -48,13 +49,15 @@ public class BahmniObservationsController extends BaseRestController { private ConceptService conceptService; private VisitService visitService; private BahmniExtensions bahmniExtensions; + private BahmniConceptService bahmniConceptService; @Autowired - public BahmniObservationsController(BahmniObsService bahmniObsService, ConceptService conceptService, VisitService visitService, BahmniExtensions bahmniExtensions) { + public BahmniObservationsController(BahmniObsService bahmniObsService, ConceptService conceptService, VisitService visitService, BahmniExtensions bahmniExtensions, BahmniConceptService bahmniConceptService) { this.bahmniObsService = bahmniObsService; this.conceptService = conceptService; this.visitService = visitService; this.bahmniExtensions = bahmniExtensions; + this.bahmniConceptService = bahmniConceptService; } @RequestMapping(method = RequestMethod.GET) @@ -105,12 +108,12 @@ public Collection get(@RequestParam(value = "visitUuid", requ Visit visit = visitService.getVisitByUuid(visitUuid); if (ObjectUtils.equals(scope, INITIAL)) { - return bahmniObsService.getInitialObsByVisit(visit, MiscUtils.getConceptsForNames(conceptNames, conceptService), obsIgnoreList, filterObsWithOrders); + return bahmniObsService.getInitialObsByVisit(visit, MiscUtils.getConceptsForNames(conceptNames, bahmniConceptService, conceptService), obsIgnoreList, filterObsWithOrders); } else if (ObjectUtils.equals(scope, LATEST)) { - return bahmniObsService.getLatestObsByVisit(visit, MiscUtils.getConceptsForNames(conceptNames, conceptService), obsIgnoreList, filterObsWithOrders); + return bahmniObsService.getLatestObsByVisit(visit, MiscUtils.getConceptsForNames(conceptNames, bahmniConceptService, conceptService), obsIgnoreList, filterObsWithOrders); } else { // Sending conceptName and obsIgnorelist, kinda contradicts, since we filter directly on concept names (not on root concept) - return bahmniObsService.getObservationForVisit(visitUuid, conceptNames, MiscUtils.getConceptsForNames(obsIgnoreList, conceptService), filterObsWithOrders, null); + return bahmniObsService.getObservationForVisit(visitUuid, conceptNames, MiscUtils.getConceptsForNames(obsIgnoreList, bahmniConceptService, conceptService), filterObsWithOrders, null); } } diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniObservationsControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniObservationsControllerTest.java index 3bf0c24cee..7d5511e262 100644 --- a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniObservationsControllerTest.java +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniObservationsControllerTest.java @@ -1,6 +1,7 @@ package org.bahmni.module.bahmnicore.web.v1_0.controller; import org.bahmni.module.bahmnicore.extensions.BahmniExtensions; +import org.bahmni.module.bahmnicore.service.BahmniConceptService; import org.bahmni.module.bahmnicore.service.BahmniObsService; import org.bahmni.module.bahmnicore.web.v1_0.controller.display.controls.BahmniObservationsController; import org.bahmni.test.builder.VisitBuilder; @@ -39,6 +40,8 @@ public class BahmniObservationsControllerTest { private VisitService visitService; @Mock private BahmniExtensions bahmniExtensions; + @Mock + private BahmniConceptService bahmniConceptService; private Visit visit; private Concept concept; @@ -49,9 +52,10 @@ public void setUp() throws Exception { MockitoAnnotations.initMocks(this); visit = new VisitBuilder().build(); concept = new Concept(); - bahmniObservationsController = new BahmniObservationsController(bahmniObsService, conceptService, visitService, bahmniExtensions); + bahmniObservationsController = new BahmniObservationsController(bahmniObsService, conceptService, visitService, bahmniExtensions, bahmniConceptService); when(visitService.getVisitByUuid("visitId")).thenReturn(visit); when(conceptService.getConceptByName("Weight")).thenReturn(concept); + when(bahmniConceptService.getConceptByFullySpecifiedName("Weight")).thenReturn(concept); } @Test diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniOrderControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniOrderControllerTest.java index 2ceca1e3a9..c164b876d1 100644 --- a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniOrderControllerTest.java +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniOrderControllerTest.java @@ -1,5 +1,6 @@ package org.bahmni.module.bahmnicore.web.v1_0.controller; +import org.bahmni.module.bahmnicore.service.BahmniConceptService; import org.bahmni.module.bahmnicore.service.BahmniOrderService; import org.junit.Before; import org.junit.Test; @@ -31,6 +32,9 @@ public class BahmniOrderControllerTest { @Mock private ConceptService conceptService; + @Mock + private BahmniConceptService bahmniConceptService; + private Patient patient; private Concept concept; @@ -41,6 +45,7 @@ public void setUp() throws Exception { patient = new Patient(); patient.setUuid("patientUuid"); when(conceptService.getConceptByName("Weight")).thenReturn(concept); + when(bahmniConceptService.getConceptByFullySpecifiedName("Weight")).thenReturn(concept); } @Test @@ -54,7 +59,7 @@ public void shouldReturnBahmniOrdersForOrderType() throws Exception { when(bahmniOrderService.ordersForOrderType("patientUuid", Arrays.asList(concept), null, null, "OrderTypeUuid", true, locationUuids)).thenReturn(Arrays.asList(bahmniOrder)); - BahmniOrderController bahmniOrderController = new BahmniOrderController(conceptService, bahmniOrderService); + BahmniOrderController bahmniOrderController = new BahmniOrderController(conceptService, bahmniOrderService, bahmniConceptService); List bahmniOrders = bahmniOrderController.get("patientUuid", Arrays.asList("Weight"),"OrderTypeUuid", null, null, null, null, true, locationUuids); verify(bahmniOrderService, never()).ordersForOrderUuid("patientUuid", Arrays.asList(concept), null, "someUuid"); @@ -71,7 +76,7 @@ public void shouldReturnBahmniOrdersForOrderUuid() throws Exception { bahmniOrder.setBahmniObservations(Arrays.asList(obs)); when(bahmniOrderService.ordersForOrderUuid("patientUuid", Arrays.asList(this.concept), null, "OrderUuid")).thenReturn(Arrays.asList(bahmniOrder)); - BahmniOrderController bahmniOrderController = new BahmniOrderController(conceptService, bahmniOrderService); + BahmniOrderController bahmniOrderController = new BahmniOrderController(conceptService, bahmniOrderService, bahmniConceptService); List bahmniOrders = bahmniOrderController.get("patientUuid", Arrays.asList("Weight"), null, null, "OrderUuid", 0, null, true, null); verify(bahmniOrderService, never()).ordersForOrderType("patientUuid", Arrays.asList(concept), null, null, "someUuid", true, null); @@ -87,7 +92,7 @@ public void shouldReturnBahmniOrdersForVisit() throws Exception { bahmniOrder.setBahmniObservations(Arrays.asList(obs)); when(bahmniOrderService.ordersForVisit("visitUuid", "orderTypeUuid", Arrays.asList("Weight"), Arrays.asList(concept))).thenReturn(Arrays.asList(bahmniOrder)); - BahmniOrderController bahmniOrderController = new BahmniOrderController(conceptService, bahmniOrderService); + BahmniOrderController bahmniOrderController = new BahmniOrderController(conceptService, bahmniOrderService, bahmniConceptService); List bahmniOrders = bahmniOrderController.get("patientUuid", Arrays.asList("Weight"), "orderTypeUuid", "visitUuid", null, null, Arrays.asList("Weight"), false, null); verify(bahmniOrderService, never()).ordersForOrderType("patientUuid", Arrays.asList(concept), null, null, "someUuid", true, null); From 9e6e50461bde18ffb54d42926263548fecf51b07 Mon Sep 17 00:00:00 2001 From: Kavitha S Date: Tue, 15 Oct 2024 11:40:47 +0530 Subject: [PATCH 47/47] add trivy ignore vulnerabilities --- .trivyignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.trivyignore b/.trivyignore index d44d219fb6..e8b6bfcf29 100644 --- a/.trivyignore +++ b/.trivyignore @@ -17,3 +17,6 @@ CVE-2023-20861 CVE-2023-20863 CVE-2016-1000027 CVE-2020-13956 +CVE-2024-22243 +CVE-2024-22259 +CVE-2024-22262