From 79e139143b7707c4931b128c103d6cb543c9253b Mon Sep 17 00:00:00 2001 From: Michael Seaton Date: Wed, 4 Sep 2024 22:52:09 -0400 Subject: [PATCH] EA-201 - Add additional method to AccountService to find accounts by name --- .../emrapi/account/AccountSearchCriteria.java | 13 ++++ .../module/emrapi/account/AccountService.java | 5 ++ .../emrapi/account/AccountServiceImpl.java | 59 +++++++++++++------ .../main/resources/hql/provider_search.hql | 20 +++++++ api/src/main/resources/hql/user_search.hql | 22 +++++++ .../resources/moduleApplicationContext.xml | 1 + .../emrapi/account/AccountComponentTest.java | 36 +++++++++++ api/src/test/resources/baseTestDataset.xml | 9 +++ 8 files changed, 148 insertions(+), 17 deletions(-) create mode 100644 api/src/main/java/org/openmrs/module/emrapi/account/AccountSearchCriteria.java create mode 100644 api/src/main/resources/hql/provider_search.hql create mode 100644 api/src/main/resources/hql/user_search.hql diff --git a/api/src/main/java/org/openmrs/module/emrapi/account/AccountSearchCriteria.java b/api/src/main/java/org/openmrs/module/emrapi/account/AccountSearchCriteria.java new file mode 100644 index 000000000..81d9611aa --- /dev/null +++ b/api/src/main/java/org/openmrs/module/emrapi/account/AccountSearchCriteria.java @@ -0,0 +1,13 @@ +package org.openmrs.module.emrapi.account; + +import lombok.Data; + +/** + * Represents criteria for searching for Accounts + */ +@Data +public class AccountSearchCriteria { + + private String nameOrIdentifier; + +} diff --git a/api/src/main/java/org/openmrs/module/emrapi/account/AccountService.java b/api/src/main/java/org/openmrs/module/emrapi/account/AccountService.java index 1969d19b0..4d4800e8a 100644 --- a/api/src/main/java/org/openmrs/module/emrapi/account/AccountService.java +++ b/api/src/main/java/org/openmrs/module/emrapi/account/AccountService.java @@ -14,6 +14,11 @@ public interface AccountService { */ List getAllAccounts(); + /** + * @should get all unique accounts that match the given criteria + */ + List getAccounts(AccountSearchCriteria criteria); + /** * Save the account details to the database * diff --git a/api/src/main/java/org/openmrs/module/emrapi/account/AccountServiceImpl.java b/api/src/main/java/org/openmrs/module/emrapi/account/AccountServiceImpl.java index 9c7769a2a..10c960a3f 100644 --- a/api/src/main/java/org/openmrs/module/emrapi/account/AccountServiceImpl.java +++ b/api/src/main/java/org/openmrs/module/emrapi/account/AccountServiceImpl.java @@ -1,5 +1,7 @@ package org.openmrs.module.emrapi.account; +import org.apache.commons.lang.BooleanUtils; +import org.apache.commons.lang.StringUtils; import org.openmrs.Person; import org.openmrs.Privilege; import org.openmrs.Provider; @@ -12,10 +14,12 @@ import org.openmrs.api.impl.BaseOpenmrsService; import org.openmrs.module.emrapi.EmrApiConstants; import org.openmrs.module.emrapi.EmrApiProperties; +import org.openmrs.module.emrapi.db.EmrApiDAO; import org.openmrs.module.emrapi.domainwrapper.DomainWrapperFactory; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -33,6 +37,8 @@ public class AccountServiceImpl extends BaseOpenmrsService implements AccountSer private EmrApiProperties emrApiProperties; + private EmrApiDAO emrApiDAO; + /** * @param userService the userService to set */ @@ -62,47 +68,66 @@ public void setEmrApiProperties(EmrApiProperties emrApiProperties) { this.emrApiProperties = emrApiProperties; } + public void setEmrApiDAO(EmrApiDAO emrApiDAO) { + this.emrApiDAO = emrApiDAO; + } + /** * @see org.openmrs.module.emrapi.account.AccountService#getAllAccounts() */ @Override @Transactional(readOnly = true) public List getAllAccounts() { + return getAccounts(new AccountSearchCriteria()); + } - Map byPerson = new LinkedHashMap(); + @Override + public List getAccounts(AccountSearchCriteria criteria) { + Map byPerson = new LinkedHashMap<>(); + List users; + List providers; + if (StringUtils.isNotBlank(criteria.getNameOrIdentifier())) { + Map searchParams = new HashMap<>(); + searchParams.put("search", "%" + criteria.getNameOrIdentifier() + "%"); + users = emrApiDAO.executeHqlFromResource("hql/user_search.hql", searchParams, User.class); + providers = emrApiDAO.executeHqlFromResource("hql/provider_search.hql", searchParams, Provider.class); + } + else { + users = userService.getAllUsers(); + providers = providerService.getAllProviders(); + } - for (User user : userService.getAllUsers()) { + for (User user : users) { //exclude daemon user - if (EmrApiConstants.DAEMON_USER_UUID.equals(user.getUuid())) + if (EmrApiConstants.DAEMON_USER_UUID.equals(user.getUuid())) { continue; - - if (!user.getPerson().isPersonVoided()) { - byPerson.put(user.getPerson(), domainWrapperFactory.newAccountDomainWrapper(user.getPerson())); + } + Person person = user.getPerson(); + if (BooleanUtils.isNotTrue(person.getPersonVoided())) { + byPerson.put(person, domainWrapperFactory.newAccountDomainWrapper(person)); } } - for (Provider provider : providerService.getAllProviders()) { + for (Provider provider : providers) { // skip the baked-in unknown provider if (provider.equals(emrApiProperties.getUnknownProvider())) { continue; } - if (provider.getPerson() == null) - throw new APIException("Providers not associated to a person are not supported"); + Person person = provider.getPerson(); - AccountDomainWrapper account = byPerson.get(provider.getPerson()); - if (account == null && !provider.getPerson().isPersonVoided()) { - byPerson.put(provider.getPerson(), domainWrapperFactory.newAccountDomainWrapper(provider.getPerson())); + if (person == null) { + throw new APIException("Providers not associated to a person are not supported"); } - } - List accounts = new ArrayList(); - for (AccountDomainWrapper account : byPerson.values()) { - accounts.add(account); + AccountDomainWrapper account = byPerson.get(person); + if (account == null && BooleanUtils.isNotTrue(person.getPersonVoided())) { + byPerson.put(person, domainWrapperFactory.newAccountDomainWrapper(person)); + } } - return accounts; + return new ArrayList<>(byPerson.values()); } /** diff --git a/api/src/main/resources/hql/provider_search.hql b/api/src/main/resources/hql/provider_search.hql new file mode 100644 index 000000000..cebd781f4 --- /dev/null +++ b/api/src/main/resources/hql/provider_search.hql @@ -0,0 +1,20 @@ +select + pr +from + Provider as pr +left join pr.person as p +left join p.names as pn +where (p.voided is null or p.voided = false) + and (pn.voided is null or pn.voided = false) + and ( + :search is null or + pr.identifier like :search or + pn.prefix like :search or + pn.givenName like :search or + pn.middleName like :search or + pn.familyNamePrefix like :search or + pn.familyName like :search or + pn.familyName2 like :search or + pn.familyNameSuffix like :search or + pn.degree like :search + ) diff --git a/api/src/main/resources/hql/user_search.hql b/api/src/main/resources/hql/user_search.hql new file mode 100644 index 000000000..3ca1d2ad6 --- /dev/null +++ b/api/src/main/resources/hql/user_search.hql @@ -0,0 +1,22 @@ +select + u +from + User as u +left join u.person as p +left join p.names as pn +where (p.voided is null or p.voided = false) + and (pn.voided is null or pn.voided = false) + and ( + :search is null or + u.username like :search or + u.systemId like :search or + u.email like :search or + pn.prefix like :search or + pn.givenName like :search or + pn.middleName like :search or + pn.familyNamePrefix like :search or + pn.familyName like :search or + pn.familyName2 like :search or + pn.familyNameSuffix like :search or + pn.degree like :search + ) diff --git a/api/src/main/resources/moduleApplicationContext.xml b/api/src/main/resources/moduleApplicationContext.xml index 835c0e076..553ae3e3f 100644 --- a/api/src/main/resources/moduleApplicationContext.xml +++ b/api/src/main/resources/moduleApplicationContext.xml @@ -15,6 +15,7 @@ + diff --git a/api/src/test/java/org/openmrs/module/emrapi/account/AccountComponentTest.java b/api/src/test/java/org/openmrs/module/emrapi/account/AccountComponentTest.java index cc1fc05ce..18869602a 100644 --- a/api/src/test/java/org/openmrs/module/emrapi/account/AccountComponentTest.java +++ b/api/src/test/java/org/openmrs/module/emrapi/account/AccountComponentTest.java @@ -35,6 +35,9 @@ import java.util.Locale; import java.util.Set; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + public class AccountComponentTest extends EmrApiContextSensitiveTest { @Autowired @@ -51,6 +54,7 @@ public class AccountComponentTest extends EmrApiContextSensitiveTest { @Before public void beforeAllTests() throws Exception { + executeDataSet("baseTestDataset.xml"); executeDataSet("accountComponentTestDataset.xml"); } @@ -248,4 +252,36 @@ public void shouldHandlePersonWithoutUser() { } + /** + * @see AccountService#getAccounts(AccountSearchCriteria) () + */ + @Test + public void shouldGetAccountsThatMatchSearchCriteria() throws Exception { + // user 501: username = bruno, systemId = 2-6, retired = true, person=501, provider 1001, identifier = 123, retired = false + // user 502: username = butch, systemId = 3-4, retired = false, person=502 + // provider 1, person=1, identifier = Test, retired = false + // provider 5000, person=5000, name = John Smith, set as unknown provider + // provider 5001, person=5001, name = Mary Smith, no user + + // Should include all accounts except for the unknown provider + AccountSearchCriteria criteria = new AccountSearchCriteria(); + List allAccounts = accountService.getAccounts(criteria); + assertThat(allAccounts.size(), equalTo(4)); + + criteria.setNameOrIdentifier("bruno"); + allAccounts = accountService.getAccounts(criteria); + assertThat(allAccounts.size(), equalTo(1)); + + criteria.setNameOrIdentifier("Smith"); + allAccounts = accountService.getAccounts(criteria); + assertThat(allAccounts.size(), equalTo(1)); + + criteria.setNameOrIdentifier("3"); + allAccounts = accountService.getAccounts(criteria); + assertThat(allAccounts.size(), equalTo(2)); + + criteria.setNameOrIdentifier("Bob"); + allAccounts = accountService.getAccounts(criteria); + assertThat(allAccounts.size(), equalTo(0)); + } } diff --git a/api/src/test/resources/baseTestDataset.xml b/api/src/test/resources/baseTestDataset.xml index 5178d0e73..ef12e0b55 100644 --- a/api/src/test/resources/baseTestDataset.xml +++ b/api/src/test/resources/baseTestDataset.xml @@ -20,10 +20,19 @@ retired = "false" /> + + + + + + + +