Skip to content

Commit

Permalink
BAH-3266 | Siva Reddy | Fetching concepts from default locale if no c…
Browse files Browse the repository at this point in the history
…oncepts in requested locale (#235)

* BAH-3266 | Siva Reddy | Fetching concepts from default locale if no concepts in requested locale

* BAH-3266 | Review comments
  • Loading branch information
sivareddyp authored Nov 24, 2023
1 parent ab8c5d1 commit 62dab0f
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;

Expand Down Expand Up @@ -77,7 +79,7 @@ public List<Obs> getObsByPatientAndVisit(String patientUuid, List<String> 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 ");

Expand Down Expand Up @@ -106,13 +108,18 @@ public List<Obs> getObsByPatientAndVisit(String patientUuid, List<String> concep
query.append(" order by obs.obsDatetime desc ");
}

List<Locale> 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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -18,6 +21,9 @@ public static List<Concept> getConceptsForNames(List<String> conceptNames, Conce
List<Concept> 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);
}
Expand All @@ -26,6 +32,20 @@ public static List<Concept> getConceptsForNames(List<String> conceptNames, Conce
}
return new ArrayList<>();
}
private static Concept getConceptInDefaultLocale(ConceptService conceptService, String rootConceptName) {
if (LocaleUtility.getDefaultLocale().equals(Context.getLocale())) {
return null;
}
List<Concept> 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<BahmniObservation> bahmniObservations) {
for (BahmniObservation bahmniObservation : bahmniObservations) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -14,13 +16,16 @@
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;

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 {
Expand All @@ -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
* <strong>Should</strong> return concepts in the specified locale if specified.
* <strong>Should</strong> 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<Concept> conceptsByName = conceptService.getConceptsByName(conceptName);
List<Locale> localeList = getLocales(context);

List<ConceptSearchResult> conceptsSearchResult = conceptService.getConcepts(conceptName, localeList, false, null, null, null, null, null, 0, null);
List<Concept> conceptsByName = conceptsSearchResult.stream().map(conceptSearchResult -> conceptSearchResult.getConcept()).collect(Collectors.toList());

if (CollectionUtils.isEmpty(conceptsByName)) {
return new EmptySearchResult();
} else {
Expand All @@ -59,4 +76,27 @@ public PageableResult search(RequestContext context) throws ResponseException {
}
}

/**
* Returns list of unique locales based on the context.getParameter("locale") parameter
* <strong>Should</strong> 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<Locale> getLocales(RequestContext context) {
String locale = context.getParameter("locale");

List<Locale> 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;
}

}
Original file line number Diff line number Diff line change
@@ -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<ConceptSearchResult> 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<Locale> 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<Concept> searchResults = (NeedsPaging<Concept>) 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<Locale> localeList = new ArrayList<>();
localeList.add(LocaleUtility.getDefaultLocale());

verify(conceptService, times(1)).getConcepts("Nutritional Values", localeList, false, null, null, null, null, null, 0, null);
}
}

0 comments on commit 62dab0f

Please sign in to comment.