diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..45d85f8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +.classpath +.project +.settings/* +target/* +api/.classpath +api/.project +api/.settings/* +api/target/* +omod/.classpath +omod/.project +omod/.settings/* +omod/target/* +/.settings + + diff --git a/README.md b/README.md index 7f9417a..bff4fee 100644 --- a/README.md +++ b/README.md @@ -1 +1,9 @@ -# openmrs-module-patientsearchcriteria \ No newline at end of file +![alt text](https://camo.githubusercontent.com/93680c923c12178e9fa6b523b1bbb644d32f4039/68747470733a2f2f74616c6b2e6f70656e6d72732e6f72672f75706c6f6164732f64656661756c742f6f726967696e616c2f32582f662f663165633537396230333938636230346338306135346335366461323139623234343066653234392e6a7067) + +Patient Search Criteria Module +========================== + +Description +----------- +This module provides the different patient search criteria which are used in core apps module + diff --git a/api/.gitignore b/api/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/api/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/api/pom.xml b/api/pom.xml new file mode 100644 index 0000000..83e3bb4 --- /dev/null +++ b/api/pom.xml @@ -0,0 +1,37 @@ + + 4.0.0 + + org.openmrs.module + patientsearch + 1.0.0-SNAPSHOT + + + patientsearch-api + jar + PatientSearchCriteria API + API project for PatientSearchCriteria + + + + jitpack.io + https://jitpack.io + + + + + + com.github.Reyano132.openmrs-core + openmrs-api + 0112f622 + provided + + + com.github.Reyano132.openmrs-core + openmrs-api + 0112f622 + test-jar + provided + + + diff --git a/api/src/main/java/org/openmrs/module/patientsearch/PatientSearchCriteriaActivator.java b/api/src/main/java/org/openmrs/module/patientsearch/PatientSearchCriteriaActivator.java new file mode 100644 index 0000000..56e33cc --- /dev/null +++ b/api/src/main/java/org/openmrs/module/patientsearch/PatientSearchCriteriaActivator.java @@ -0,0 +1,37 @@ +/** + * 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.openmrs.module.patientsearch; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openmrs.module.BaseModuleActivator; + +/** + * This class contains the logic that is run every time this module is either started or shutdown + */ +public class PatientSearchCriteriaActivator extends BaseModuleActivator { + + private Log log = LogFactory.getLog(this.getClass()); + + /** + * @see #started() + */ + public void started() { + log.info("Started PatientSearchCriteria"); + } + + /** + * @see #shutdown() + */ + public void shutdown() { + log.info("Shutdown PatientSearchCriteria"); + } + +} diff --git a/api/src/main/java/org/openmrs/module/patientsearch/PatientSearchCriteriaConfig.java b/api/src/main/java/org/openmrs/module/patientsearch/PatientSearchCriteriaConfig.java new file mode 100644 index 0000000..68514ce --- /dev/null +++ b/api/src/main/java/org/openmrs/module/patientsearch/PatientSearchCriteriaConfig.java @@ -0,0 +1,21 @@ +/** + * 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.openmrs.module.patientsearch; + +import org.springframework.stereotype.Component; + +/** + * Contains module's config. + */ +@Component("patientsearch.PatientSearchCriteriaConfig") +public class PatientSearchCriteriaConfig { + + public final static String MODULE_PRIVILEGE = "PatientSearchCriteria Privilege"; +} diff --git a/api/src/main/java/org/openmrs/module/patientsearch/api/PatientSearchCriteriaService.java b/api/src/main/java/org/openmrs/module/patientsearch/api/PatientSearchCriteriaService.java new file mode 100644 index 0000000..922967f --- /dev/null +++ b/api/src/main/java/org/openmrs/module/patientsearch/api/PatientSearchCriteriaService.java @@ -0,0 +1,71 @@ +/** + * 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.openmrs.module.patientsearch.api; + +import java.util.Date; +import java.util.List; + +import org.openmrs.Patient; +import org.openmrs.PatientIdentifierType; +import org.openmrs.annotation.Authorized; +import org.openmrs.api.APIException; +import org.openmrs.api.PatientService; +import org.openmrs.util.PrivilegeConstants; + +/** + * This provide patient search criteria service. It helps to retrieve patient with different fields + * such as gender, birthdate, age. + */ +public interface PatientSearchCriteriaService extends PatientService { + + /** + * Return the list of patient which has required name or identifier or gender or birthdate or + * age. + * + * @param name (optional) this is a slight break from the norm, patients with a partial match on + * this name will be returned + * @param identifier (optional) only patients with a matching identifier are returned. This + * however applies only if name argument is null. Otherwise, its + * ignored. + * @param identifierTypes (optional) the PatientIdentifierTypes to restrict to + * @param matchIdentifierExactly (required) if true, then the given identifier must + * equal the id in the database. if false, then the identifier is 'searched' for by + * using a regular expression + * @param gender(optional) : if user want to search patient by gender or filter the search + * result by gender. value of gender parameter is either "M" or "F". + * @param to(optional) : user wants to search patients having age between some range, at that + * time this paramater represent the upper boundary of range. + * @param from(optional):user wants to search patients having age between some range, at that + * time this paramater represent the lower boundary of range. + * @param birthdate(optional) : User can search patient by birthdate. + * @return patients that matched the given criteria (and are not voided) + * @throws APIException + * @should fetch all patients that partially match given name + * @should fetch all patients that partially match given identifier if name + * argument is null + * @should fetch all patients that partially match given identifier when match identifier + * exactly equals false and if name argument is null + * @should fetch all patients that exactly match given identifier when match identifier exactly + * equals true and if name argument is null + * @should fetch all patients that match given identifier types + * @should not return duplicates + * @should not return voided patients + * @should return empty list when no match is found + * @should search familyName2 with name + * @should support simple regex + * @should support pattern using last digit as check digit + * @should return empty list if name and identifier is empty + * @should support all the search criteria + */ + @Authorized({ PrivilegeConstants.GET_PATIENTS }) + public List getPatients(String name, String identifier, List identifierTypes, + boolean matchIdentifierExactly, String gender, Integer from, Integer to, Date birthdate) throws APIException; + +} diff --git a/api/src/main/java/org/openmrs/module/patientsearch/api/dao/PatientSearchCriteriaDAO.java b/api/src/main/java/org/openmrs/module/patientsearch/api/dao/PatientSearchCriteriaDAO.java new file mode 100644 index 0000000..fa2aef4 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/patientsearch/api/dao/PatientSearchCriteriaDAO.java @@ -0,0 +1,117 @@ +/** + * 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.openmrs.module.patientsearch.api.dao; + +import java.util.Date; +import java.util.List; + +import org.openmrs.Patient; +import org.openmrs.api.db.DAOException; +import org.openmrs.api.db.PatientDAO; + +/** + * methods to search patients with different fields + */ +public interface PatientSearchCriteriaDAO extends PatientDAO { + + /** + * @param query : name or identifier of patients + * @param gender : gender of patients + * @param length : maximum number of patients should return + * @return : list of patients who follow the query regex and having required gender + * @throws DAOException + */ + public List getPatientsByNameOrIdAndGender(String query, String gender, Integer start, Integer length, + Boolean includeVoided) throws DAOException; + + /** + * @return : list of patient having required gender + * @throws DAOException + */ + public List getPatientsByGender(String gender, Integer start, Integer length, Boolean includeVoided) + throws DAOException; + + /** + * @param from: lower boundary of range of age + * @param to : upper boundary of range of age + * @return list of patients, who's age is in between the required range + * @throws DAOException + */ + public List getPatientsByRangeOfAge(Date from, Date to, Integer start, Integer length, Boolean includeVoided) + throws DAOException; + + /** + * @param birthdate : birthdate of patient + * @return list of patient/s , who's birthdate is similar to required birthdate + * @throws DAOException + */ + public List getPatientsByBirthdate(Date birthdate, Integer start, Integer length, Boolean includeVoided) + throws DAOException; + + /** + * @param query : name or identifier of patient/s. + * @param gender : gender of patient + * @param from : lower boundary of range of age + * @param to : upper boundary of range of age + * @return list of patients who follow the query regex and having required gender and having age + * in required range + * @throws DAOException + */ + public List getPatientsByNameOrIdAndGenderAndRangeOfAge(String query, String gender, Date from, Date to, + Integer start, Integer length, Boolean includeVoided) throws DAOException; + + /** + * @param query : name or identifier of patient/s + * @param gender : gender of patient + * @param birthdate : birthdate of patient + * @return list of patients who follow the query regex and having required gender and having + * required birthdate + * @throws DAOException + */ + public List getPatientsByNameOrIdAndGenderAndBirthdate(String query, String gender, Date birthdate, + Integer start, Integer length, Boolean includeVoided) throws DAOException; + + /** + * @param from: lower boundary of range of age + * @param to : upper boundary of range of age + * @return list of patients who follow the query regex and having age in required range + * @throws DAOException + */ + public List getPatientsByNameOrIdAndRangeOfAge(String query, Date from, Date to, Integer start, Integer length, + Boolean includeVoided) throws DAOException; + + /** + * @param birthdate: birthdate of patient + * @return list of patients who follow the query regex and having birthdate as required. + * @throws DAOException + */ + public List getPatientsByNameOrIdAndBirthdate(String query, Date birthdate, Integer start, Integer length, + Boolean includeVoided) throws DAOException; + + /** + * @param gender : gender of patients + * @param birthdate: birthdate of patient + * @return list of patients which have required birthdate and gender + * @throws DAOException + */ + public List getPatientsByGenderAndBirthdate(String gender, Date birthdate, Integer start, Integer length, + Boolean includeVoided) throws DAOException; + + /** + * @param gender : gender of patients + * @param from: lower boundary of range of age + * @param to : upper boundary of range of age + * @return list of patients which have required gender and age in required range. + * @throws DAOException + */ + public List getPatientsByGenderAndAge(String gender, Date from, Date to, Integer start, Integer length, + Boolean includeVoided) throws DAOException; + +} diff --git a/api/src/main/java/org/openmrs/module/patientsearch/api/dao/hibernate/HibernatePatientSearchCriteriaDAO.java b/api/src/main/java/org/openmrs/module/patientsearch/api/dao/hibernate/HibernatePatientSearchCriteriaDAO.java new file mode 100644 index 0000000..0053148 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/patientsearch/api/dao/hibernate/HibernatePatientSearchCriteriaDAO.java @@ -0,0 +1,243 @@ +/** + * 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.openmrs.module.patientsearch.api.dao.hibernate; + +import java.util.ArrayList; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.StringUtils; +import org.hibernate.SessionFactory; +import org.openmrs.Patient; +import org.openmrs.PatientIdentifier; +import org.openmrs.PatientIdentifierType; +import org.openmrs.Person; +import org.openmrs.api.context.Context; +import org.openmrs.api.db.DAOException; +import org.openmrs.api.db.hibernate.HibernatePatientDAO; +import org.openmrs.api.db.hibernate.HibernatePersonDAO; +import org.openmrs.api.db.hibernate.search.LuceneQuery; +import org.openmrs.collection.ListPart; +import org.openmrs.module.patientsearch.api.dao.PatientSearchCriteriaDAO; +import org.openmrs.util.OpenmrsConstants; + +/** + * With help of Hibernate API , implement the methods of PatientSearchCriteriaDAO + * + * @see org.openmrs.module.patientcriteria.api.dao.PatientSearchCriteriaDao + */ + +public class HibernatePatientSearchCriteriaDAO extends HibernatePatientDAO implements PatientSearchCriteriaDAO { + + private SessionFactory sessionFactory; + + public void setSessionFactory(SessionFactory sessionFactory) { + super.setSessionFactory(sessionFactory); + this.sessionFactory = sessionFactory; + } + + @Override + public List getPatientsByGender(String gender, Integer start, Integer length, Boolean includeVoided) + throws DAOException { + + PatientLuceneQuery patientLuceneQuery = new PatientLuceneQuery(sessionFactory); + LuceneQuery genderQuery = patientLuceneQuery.getPatinetWithGender(gender, includeVoided); + return getPatientsWithLuceneQuery(genderQuery, start, length); + } + + @Override + public List getPatientsByRangeOfAge(Date from, Date to, Integer start, Integer length, Boolean includeVoided) + throws DAOException { + + PatientLuceneQuery personLuceneQuery = new PatientLuceneQuery(sessionFactory); + LuceneQuery ageQuery = personLuceneQuery.getPatinetWithAgeRange(from, to, includeVoided); + return getPatientsWithLuceneQuery(ageQuery, start, length); + } + + @Override + public List getPatientsByBirthdate(Date birthdate, Integer start, Integer length, Boolean includeVoided) + throws DAOException { + + PatientLuceneQuery personLuceneQuery = new PatientLuceneQuery(sessionFactory); + LuceneQuery birthdateQuery = personLuceneQuery.getPatinetWithBirthdate(birthdate, includeVoided); + return getPatientsWithLuceneQuery(birthdateQuery, start, length); + } + + @Override + public List getPatientsByNameOrIdAndGender(String query, String gender, Integer start, Integer length, Boolean includeVoided) + throws DAOException { + return findPatients(query, includeVoided, start, length).stream().filter(patient -> patient.getGender().equals(gender)).collect(Collectors.toList()); + } + + @Override + public List getPatientsByNameOrIdAndRangeOfAge(String query, Date from, Date to, Integer start, Integer length, + Boolean includeVoided) throws DAOException { + + PatientLuceneQuery patientLuceneQuery=new PatientLuceneQuery(sessionFactory); + LuceneQuery ageQuery=patientLuceneQuery.getPatinetWithAgeRange(from, to, includeVoided); + List temp=getPatientsWithLuceneQuery(ageQuery,start,length); + return findPatients(query, includeVoided, start, length).stream().filter(patient -> temp.contains(patient)).collect(Collectors.toList()); + } + + @Override + public List getPatientsByNameOrIdAndBirthdate(String query,Date birthdate, Integer start, Integer length, + Boolean includeVoided) throws DAOException { + + PatientLuceneQuery patientLuceneQuery=new PatientLuceneQuery(sessionFactory); + LuceneQuery birthdateQuery=patientLuceneQuery.getPatinetWithBirthdate(birthdate, includeVoided); + List temp=getPatientsWithLuceneQuery(birthdateQuery,start,length); + return findPatients(query, includeVoided, start, length).stream().filter(patient -> temp.contains(patient)).collect(Collectors.toList()); + } + + @Override + public List getPatientsByNameOrIdAndGenderAndRangeOfAge(String query, String gender, Date from, Date to, Integer start, Integer length, + Boolean includeVoided) throws DAOException { + return getPatientsByNameOrIdAndRangeOfAge(query, from, to, start, length, includeVoided).stream().filter(patient -> patient.getGender().equals(gender)).collect(Collectors.toList()); + } + + @Override + public List getPatientsByNameOrIdAndGenderAndBirthdate(String query, String gender, Date birthdate, Integer start, Integer length, + Boolean includeVoided) throws DAOException { + return getPatientsByNameOrIdAndBirthdate(query, birthdate, start, length, includeVoided).stream().filter(patient -> patient.getGender().equals(gender)).collect(Collectors.toList()); + } + + @Override + public List getPatientsByGenderAndBirthdate(String gender, Date birthdate, Integer start, Integer length, + Boolean includeVoided) throws DAOException { + return getPatientsByBirthdate(birthdate, start, length, includeVoided).stream().filter(patient -> patient.getGender().equals(gender)).collect(Collectors.toList()); + } + + @Override + public List getPatientsByGenderAndAge(String gender, Date from, Date to, Integer start, Integer length, + Boolean includeVoided) throws DAOException { + return getPatientsByRangeOfAge(from, to, start, length, includeVoided).stream().filter(patient -> patient.getGender().equals(gender)).collect(Collectors.toList()); + } + + private List getPatientsWithLuceneQuery(LuceneQuery query, Integer start, Integer length){ + Integer tmpStart = start; + if (tmpStart == null) { + tmpStart = 0; + } + Integer maxLength = HibernatePersonDAO.getMaximumSearchResults(); + Integer tmpLength = length; + if (tmpLength == null || tmpLength > maxLength) { + tmpLength = maxLength; + } + + List patients = new LinkedList<>(); + + long querySize = query.resultSize(); + if (querySize > tmpStart) { + ListPart tempPatients = query.listPartProjection(tmpStart, tmpLength, "personId"); + tempPatients.getList().forEach(patient -> patients.add(getPatient((Integer) patient[0]))); + } + + return patients; + + + } + + //Below methods will be removed at time of merging with openmrs core. + + @SuppressWarnings("unused") + private LuceneQuery getPatientIdentifierLuceneQuery(String query, + List identifierTypes, boolean matchExactly) { + LuceneQuery patientIdentifierLuceneQuery = getPatientIdentifierLuceneQuery(query, matchExactly); + for (PatientIdentifierType identifierType : identifierTypes) { + patientIdentifierLuceneQuery.include("identifierType.patientIdentifierTypeId", identifierType.getId()); + } + patientIdentifierLuceneQuery.include("patient.isPatient", true); + patientIdentifierLuceneQuery.skipSame("patient.personId"); + + return patientIdentifierLuceneQuery; + } + + private LuceneQuery getPatientIdentifierLuceneQuery(String paramQuery, boolean matchExactly) { + String query = removeIdentifierPadding(paramQuery); + List tokens = tokenizeIdentifierQuery(query); + query = StringUtils.join(tokens, " OR "); + List fields = new ArrayList<>(); + fields.add("identifierPhrase"); + fields.add("identifierType"); + String matchMode = Context.getAdministrationService() + .getGlobalProperty(OpenmrsConstants.GLOBAL_PROPERTY_PATIENT_IDENTIFIER_SEARCH_MATCH_MODE); + if (matchExactly) { + fields.add("identifierExact"); + } + else if (OpenmrsConstants.GLOBAL_PROPERTY_PATIENT_SEARCH_MATCH_START.equals(matchMode)) { + fields.add("identifierStart"); + } + else { + fields.add("identifierAnywhere"); + } + return LuceneQuery.newQuery(PatientIdentifier.class, sessionFactory.getCurrentSession(), query, fields); + + } private LuceneQuery getPatientIdentifierLuceneQuery(String query, boolean includeVoided, + boolean matchExactly) { + LuceneQuery luceneQuery = getPatientIdentifierLuceneQuery(query, matchExactly); + if (!includeVoided) { + luceneQuery.include("voided", false); + luceneQuery.include("patient.voided", false); + } + + luceneQuery.include("patient.isPatient", true); + luceneQuery.skipSame("patient.personId"); + + return luceneQuery; + } + + private String removeIdentifierPadding(String query) { + String regex = Context.getAdministrationService().getGlobalProperty( + OpenmrsConstants.GLOBAL_PROPERTY_PATIENT_IDENTIFIER_REGEX, ""); + if (Pattern.matches("^\\^.{1}\\*.*$", regex)) { + String padding = regex.substring(regex.indexOf("^") + 1, regex.indexOf("*")); + Pattern pattern = Pattern.compile("^" + padding + "+"); + query = pattern.matcher(query).replaceFirst(""); + } + return query; + } + + private List tokenizeIdentifierQuery(String query) { + List searchPatterns = new ArrayList<>(); + + String patternSearch = Context.getAdministrationService().getGlobalProperty( + OpenmrsConstants.GLOBAL_PROPERTY_PATIENT_IDENTIFIER_SEARCH_PATTERN, ""); + + if (StringUtils.isBlank(patternSearch)) { + searchPatterns.add(query); + } else { + // split the pattern before replacing in case the user searched on a comma + // replace the @SEARCH@, etc in all elements + for (String pattern : patternSearch.split(",")) { + searchPatterns.add(replaceSearchString(pattern, query)); + } + } + return searchPatterns; + } + + private String replaceSearchString(String regex, String identifierSearched) { + String returnString = regex.replaceAll("@SEARCH@", identifierSearched); + if (identifierSearched.length() > 1) { + // for 2 or more character searches, we allow regex to use last character as check digit + returnString = returnString.replaceAll("@SEARCH-1@", + identifierSearched.substring(0, identifierSearched.length() - 1)); + returnString = returnString.replaceAll("@CHECKDIGIT@", + identifierSearched.substring(identifierSearched.length() - 1)); + } else { + returnString = returnString.replaceAll("@SEARCH-1@", ""); + returnString = returnString.replaceAll("@CHECKDIGIT@", ""); + } + return returnString; + } + +} diff --git a/api/src/main/java/org/openmrs/module/patientsearch/api/dao/hibernate/PatientLuceneQuery.java b/api/src/main/java/org/openmrs/module/patientsearch/api/dao/hibernate/PatientLuceneQuery.java new file mode 100644 index 0000000..1cae32b --- /dev/null +++ b/api/src/main/java/org/openmrs/module/patientsearch/api/dao/hibernate/PatientLuceneQuery.java @@ -0,0 +1,144 @@ +/** + * 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.openmrs.module.patientsearch.api.dao.hibernate; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.hibernate.SessionFactory; +import org.openmrs.Person; +import org.openmrs.api.db.hibernate.search.LuceneQuery; +import org.openmrs.module.patientsearch.api.dao.hibernate.search.DateLuceneQuery; + +/* + + Provides the lucene query for the patient search criteria + + */ +public class PatientLuceneQuery { + + SessionFactory sessionFactory; + + public PatientLuceneQuery(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + //returns the lucene query for searching patients with gender + public LuceneQuery getPatinetWithGender(String query) { + return findPatientWithGender(query, true, null); + } + + public LuceneQuery getPatinetWithGender(String query, boolean includeVoided) { + return findPatientWithGender(query, includeVoided, null); + } + + public LuceneQuery getPatinetWithGender(String query, LuceneQuery skipSame) { + return findPatientWithGender(query, true, skipSame); + } + + public LuceneQuery getPatinetWithGender(String query, boolean includeVoided, LuceneQuery skipSame) { + return findPatientWithGender(query, includeVoided, skipSame); + } + + private LuceneQuery findPatientWithGender(String query,boolean includeVoided,LuceneQuery skipSame){ + List fields=new ArrayList<>(); + fields.add("gender"); + + LuceneQuery luceneQuery = LuceneQuery + .newQuery(Person.class, sessionFactory.getCurrentSession(), query, fields); + if (!includeVoided) { + luceneQuery.include("voided", false); + } + + if (skipSame != null) { + luceneQuery.skipSame("personId", skipSame); + } else { + luceneQuery.skipSame("personId"); + } + luceneQuery.include("isPatient", true); + + return luceneQuery; + + } + + //returns the lucene query for searching patients with birthdate + public LuceneQuery getPatinetWithBirthdate(Date query) { + return findPatientWithBirthdate(query, true, null); + } + + public LuceneQuery getPatinetWithBirthdate(Date query, boolean includeVoided) { + return findPatientWithBirthdate(query, includeVoided, null); + } + + public LuceneQuery getPatinetWithBirthdate(Date query, LuceneQuery skipSame) { + return findPatientWithBirthdate(query, true, skipSame); + } + + public LuceneQuery getPatinetWithBirthdate(Date query, boolean includeVoided, LuceneQuery skipSame) { + return findPatientWithBirthdate(query, includeVoided, skipSame); + } + + private LuceneQuery findPatientWithBirthdate(Date query, boolean includeVoided, LuceneQuery skipSame) { + String field = "birthdate"; + + DateLuceneQuery luceneQuery = DateLuceneQuery.newQuery(Person.class, sessionFactory.getCurrentSession(), + query, field); + if (!includeVoided) { + luceneQuery.include("voided", false); + } + + if (skipSame != null) { + luceneQuery.skipSame("personId", skipSame); + } else { + luceneQuery.skipSame("personId"); + } + luceneQuery.include("isPatient", true); + return luceneQuery; + + } + + //returns the lucene query for searching patients with range of age + public LuceneQuery getPatinetWithAgeRange(Date from, Date to) { + return findPatientWithAgeRange(from, to, true, null); + } + + public LuceneQuery getPatinetWithAgeRange(Date from, Date to, boolean includeVoided) { + return findPatientWithAgeRange(from, to, includeVoided, null); + } + + public LuceneQuery getPatinetWithAgeRange(Date from, Date to, LuceneQuery skipSame) { + return findPatientWithAgeRange(from, to, true, skipSame); + } + + public LuceneQuery getPatinetWithAgeRange(Date from, Date to, boolean includeVoided, LuceneQuery skipSame) { + return findPatientWithAgeRange(from, to, includeVoided, skipSame); + } + + private LuceneQuery findPatientWithAgeRange(Date from, Date to, boolean includeVoided, LuceneQuery skipSame) { + String field = "birthdate"; + + DateLuceneQuery luceneQuery = DateLuceneQuery.newQuery(Person.class, sessionFactory.getCurrentSession(), + from, to, field); + if (!includeVoided) { + luceneQuery.include("voided", false); + } + + if (skipSame != null) { + luceneQuery.skipSame("personId", skipSame); + } else { + luceneQuery.skipSame("personId"); + } + luceneQuery.include("isPatient", true); + return luceneQuery; + + } + +} diff --git a/api/src/main/java/org/openmrs/module/patientsearch/api/dao/hibernate/search/DateLuceneQuery.java b/api/src/main/java/org/openmrs/module/patientsearch/api/dao/hibernate/search/DateLuceneQuery.java new file mode 100644 index 0000000..d2b8e21 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/patientsearch/api/dao/hibernate/search/DateLuceneQuery.java @@ -0,0 +1,75 @@ +/** + * 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.openmrs.module.patientsearch.api.dao.hibernate.search; + +import java.util.Date; + +import org.apache.lucene.search.MatchAllDocsQuery; +import org.apache.lucene.search.Query; +import org.hibernate.Session; +import org.hibernate.search.query.dsl.QueryBuilder; +import org.openmrs.api.db.hibernate.search.LuceneQuery; + +/* + * Lucene query for date fomate + */ +public class DateLuceneQuery extends LuceneQuery { + + public static DateLuceneQuery newQuery(final Class type, final Session session, final Date query, + final String field) { + return new DateLuceneQuery( + type, session) { + + @Override + protected Query prepareQuery() { + if (query == null) { + return new MatchAllDocsQuery(); + } + + QueryBuilder queryBuilder = getFullTextSession().getSearchFactory().buildQueryBuilder().forEntity(type) + .get(); + return queryBuilder.range().onField(field).from(query.getTime()).to(query.getTime() + 86400000) + .createQuery(); + + } + }; + } + + public static DateLuceneQuery newQuery(final Class type, final Session session, final Date from, + final Date to, final String field) { + return new DateLuceneQuery( + type, session) { + + @Override + protected Query prepareQuery() { + if (from == null || to == null) { + return new MatchAllDocsQuery(); + } + + QueryBuilder queryBuilder = getFullTextSession().getSearchFactory().buildQueryBuilder().forEntity(type) + .get(); + return queryBuilder.range().onField(field).from(to.getTime()).to(from.getTime()).createQuery(); + + } + }; + } + + public DateLuceneQuery(Class type, Session session) { + super(type, session); + // TODO Auto-generated constructor stub + } + + @Override + protected Query prepareQuery() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/api/src/main/java/org/openmrs/module/patientsearch/api/impl/PatientSearchCriteriaServiceImpl.java b/api/src/main/java/org/openmrs/module/patientsearch/api/impl/PatientSearchCriteriaServiceImpl.java new file mode 100644 index 0000000..8a576bc --- /dev/null +++ b/api/src/main/java/org/openmrs/module/patientsearch/api/impl/PatientSearchCriteriaServiceImpl.java @@ -0,0 +1,108 @@ +/** + * 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.openmrs.module.patientsearch.api.impl; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.List; + +import org.openmrs.Patient; +import org.openmrs.PatientIdentifierType; +import org.openmrs.api.APIException; +import org.openmrs.api.impl.PatientServiceImpl; +import org.openmrs.module.patientsearch.api.PatientSearchCriteriaService; +import org.openmrs.module.patientsearch.api.dao.PatientSearchCriteriaDAO; +import org.springframework.transaction.annotation.Transactional; + +/** + * All the methods of PatientSearchCriteriaService implemented here + * + * @see org.openmrs.module.patientcriteria.api.PatientSearchCriteriaService + **/ + +@Transactional +public class PatientSearchCriteriaServiceImpl extends PatientServiceImpl implements PatientSearchCriteriaService { + + PatientSearchCriteriaDAO dao; + + public void setDao(PatientSearchCriteriaDAO dao) { + this.dao = dao; + } + + @Override + public List getPatients(String name, String identifier, List identifierTypes, + boolean matchIdentifierExactly, String gender, Integer from, Integer to, Date birthdate) throws APIException { + if (identifierTypes == null) { + Date fromDate = null; + Date toDate = null; + + if (to != null && from != null) { + Calendar today = Calendar.getInstance(); + fromDate = new GregorianCalendar(today.get(Calendar.YEAR) - from, 0, 1).getTime(); + toDate = new GregorianCalendar(today.get(Calendar.YEAR) - to, 11, 31).getTime(); + } + + if (gender == null && to == null && from == null && birthdate == null) { + return dao.getPatients(name != null ? name : identifier, 0, null); + } + + else if (gender != null && to == null && from == null && birthdate == null) { + if (name == null && identifier == null) { + return dao.getPatientsByGender(gender, 0, null, false); + } + return dao.getPatientsByNameOrIdAndGender(name != null ? name : identifier, gender, 0, null, false); + } + + else if (name == null && identifier == null && gender == null && to != null && from != null && birthdate == null) { + return dao.getPatientsByRangeOfAge(fromDate, toDate, 0, null, false); + } + + else if (name == null && identifier == null && gender == null && to == null && from == null && birthdate != null) { + return dao.getPatientsByBirthdate(birthdate, 0, null, false); + } + + else { + return getPatientsBySeachCriteria(name, identifier, identifierTypes, gender, fromDate, toDate, birthdate); + } + + } else { + return dao.getPatients(name != null ? name : identifier, identifierTypes, matchIdentifierExactly, 0, null); + } + + } + + private List getPatientsBySeachCriteria(String name, String identifier, + List identifierTypes, String gender, Date from, Date to, Date birthdate) { + if (name == null && identifier == null) { + if (birthdate == null) { + return dao.getPatientsByGenderAndAge(gender, from, to, 0, null, false); + } else { + return dao.getPatientsByGenderAndBirthdate(gender, birthdate, 0, null, false); + } + } + if (gender == null) { + if (birthdate == null) { + return dao.getPatientsByNameOrIdAndRangeOfAge(name != null ? name : identifier, from, to, 0, null, false); + } else { + return dao.getPatientsByNameOrIdAndBirthdate(name != null ? name : identifier, birthdate, 0, null, false); + } + } + + if (birthdate == null) { + return dao.getPatientsByNameOrIdAndGenderAndRangeOfAge(name != null ? name : identifier, gender, from, to, 0, + null, false); + } else { + return dao.getPatientsByNameOrIdAndGenderAndBirthdate(name != null ? name : identifier, gender, birthdate, 0, + null, false); + } + } + +} diff --git a/api/src/main/resources/liquibase.xml b/api/src/main/resources/liquibase.xml new file mode 100644 index 0000000..e625012 --- /dev/null +++ b/api/src/main/resources/liquibase.xml @@ -0,0 +1,39 @@ + + + + + + + + + + \ No newline at end of file diff --git a/api/src/main/resources/messages.properties b/api/src/main/resources/messages.properties new file mode 100644 index 0000000..60f06fd --- /dev/null +++ b/api/src/main/resources/messages.properties @@ -0,0 +1 @@ +patientsearch.title=PatientSearchCriteria diff --git a/api/src/main/resources/messages_es.properties b/api/src/main/resources/messages_es.properties new file mode 100644 index 0000000..60f06fd --- /dev/null +++ b/api/src/main/resources/messages_es.properties @@ -0,0 +1 @@ +patientsearch.title=PatientSearchCriteria diff --git a/api/src/main/resources/messages_fr.properties b/api/src/main/resources/messages_fr.properties new file mode 100644 index 0000000..60f06fd --- /dev/null +++ b/api/src/main/resources/messages_fr.properties @@ -0,0 +1 @@ +patientsearch.title=PatientSearchCriteria diff --git a/api/src/main/resources/moduleApplicationContext.xml b/api/src/main/resources/moduleApplicationContext.xml new file mode 100644 index 0000000..5c5ac54 --- /dev/null +++ b/api/src/main/resources/moduleApplicationContext.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.openmrs.module.patientsearch.api.PatientSearchCriteriaService + + + + + diff --git a/api/src/test/java/org/openmrs/module/patientsearch/api/PatientSearchCriteriaServiceTest.java b/api/src/test/java/org/openmrs/module/patientsearch/api/PatientSearchCriteriaServiceTest.java new file mode 100644 index 0000000..e08bf26 --- /dev/null +++ b/api/src/test/java/org/openmrs/module/patientsearch/api/PatientSearchCriteriaServiceTest.java @@ -0,0 +1,126 @@ +/** + * 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.openmrs.module.patientsearch.api; + +import java.sql.SQLException; +import java.util.GregorianCalendar; +import java.util.List; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Patient; +import org.openmrs.module.patientsearch.api.PatientSearchCriteriaService; +import org.openmrs.test.BaseModuleContextSensitiveTest; +import org.openmrs.test.SkipBaseSetup; +import org.springframework.beans.factory.annotation.Autowired; + +public class PatientSearchCriteriaServiceTest extends BaseModuleContextSensitiveTest { + + private final static String PATIENTS_XML = "org/openmrs/module/patientsearch/api/include/PatientSearchCriteriaServiceTest-patients.xml"; + + @Autowired + private PatientSearchCriteriaService patientservice; + + @Before + public void runBeforeEachTest() { + try { + initializeInMemoryDatabase(); + } + catch (SQLException e) { + e.printStackTrace(); + } + executeDataSet(PATIENTS_XML); + updateSearchIndex(); + authenticate(); + } + + @Test + @SkipBaseSetup + public void getPatientsByGender() { + List patients = patientservice.getPatients(null, null, null, true, "F", null, null, null); + Assert.assertEquals(1, patients.size()); + Assert.assertEquals("F", patients.get(0).getGender()); + } + + @Test + public void getPatientByBirthdate() { + GregorianCalendar birthdate = new GregorianCalendar(2014, 7, 28); + List patients = patientservice.getPatients(null, null, null, false, null, null, null, birthdate.getTime()); + Assert.assertEquals(2, patients.size()); + } + + @Test + public void getPatientByAgeRange() { + List patients = patientservice.getPatients(null, null, null, false, null, 3, 10, null); + Assert.assertEquals(3, patients.size()); + } + + @Test + public void getPatientByGenderAndBirthdate() { + GregorianCalendar birthdate = new GregorianCalendar(2014, 7, 28); + List patients = patientservice.getPatients(null, null, null, false, "M", null, null, birthdate.getTime()); + Assert.assertEquals(1, patients.size()); + Assert.assertEquals("M", patients.get(0).getGender()); + } + + @Test + public void getPatientByGenderAndAgeRange() { + List patients = patientservice.getPatients(null, null, null, false, "F", 3, 10, null); + Assert.assertEquals(1, patients.size()); + Assert.assertEquals("F", patients.get(0).getGender()); + + } + + @Test + public void getPatientByNameAndGender() { + List patients = patientservice.getPatients("Frank", null, null, true, "M", null, null, null); + Assert.assertEquals(3, patients.size()); + } + + @Test + public void getPatientByPatientIdentifierAndGender() { + List patients = patientservice.getPatients(null, "82-82-82", null, true, null, null, null, null); + Assert.assertEquals(1, patients.size()); + Assert.assertEquals(82, patients.get(0).getId().longValue()); + Assert.assertEquals("M", patients.get(0).getGender()); + } + + @Test + public void getPatientByNameAndBirthdate() { + GregorianCalendar birthdate = new GregorianCalendar(2014, 7, 28); + List patients = patientservice + .getPatients("Adam", null, null, false, null, null, null, birthdate.getTime()); + Assert.assertEquals(1, patients.size()); + } + + @Test + public void getPatientByNameAndAgeRange() { + List patients = patientservice.getPatients("Frank", null, null, false, null, 3, 10, null); + Assert.assertEquals(3, patients.size()); + } + + @Test + public void getPatientByNameAndGenderAndBirthdate() { + GregorianCalendar birthdate = new GregorianCalendar(2014, 7, 28); + List patients = patientservice + .getPatients("Frank", null, null, false, "F", null, null, birthdate.getTime()); + Assert.assertEquals(1, patients.size()); + Assert.assertEquals("Frank", patients.get(0).getMiddleName()); + } + + @Test + public void getPatientByNameAndGenderAndAgeRange() { + List patients = patientservice.getPatients("Frank", null, null, false, "F", 3, 10, null); + Assert.assertEquals(1, patients.size()); + Assert.assertEquals("Frank", patients.get(0).getMiddleName()); + } + +} diff --git a/api/src/test/java/org/openmrs/module/patientsearch/api/dao/PatientSearchCriteriaDAOTest.java b/api/src/test/java/org/openmrs/module/patientsearch/api/dao/PatientSearchCriteriaDAOTest.java new file mode 100644 index 0000000..0c9bed6 --- /dev/null +++ b/api/src/test/java/org/openmrs/module/patientsearch/api/dao/PatientSearchCriteriaDAOTest.java @@ -0,0 +1,272 @@ +/** + * 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.openmrs.module.patientsearch.api.dao; + +import java.sql.SQLException; +import java.util.GregorianCalendar; +import java.util.List; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Patient; +import org.openmrs.module.patientsearch.api.dao.PatientSearchCriteriaDAO; +import org.openmrs.test.BaseModuleContextSensitiveTest; +import org.openmrs.test.SkipBaseSetup; +import org.springframework.beans.factory.annotation.Autowired; + +public class PatientSearchCriteriaDAOTest extends BaseModuleContextSensitiveTest { + + private final static String PATIENTS_XML = "org/openmrs/module/patientsearch/api/dao/include/PatientSearchCriteriaDAOTest-patients.xml"; + + @Autowired + private PatientSearchCriteriaDAO dao; + + @Before + public void runBeforeEachTest() { + try { + initializeInMemoryDatabase(); + } + catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + executeDataSet(PATIENTS_XML); + + updateSearchIndex(); + authenticate(); + } + + /** + * @see PatientSearchCriteriaDAO#getPatients(String, Integer, Integer, Boolean) + */ + @Test + @SkipBaseSetup + public void getPatients_shouldReturnListOfPatientsWithRequriedGender() { + List patients = dao.getPatientsByGender("M", 0, 11, false); + Assert.assertEquals(3, patients.size()); + Assert.assertEquals("M", patients.get(0).getGender()); + Assert.assertEquals("M", patients.get(1).getGender()); + Assert.assertEquals("M", patients.get(2).getGender()); + } + + /** + * @see PatientSearchCriteriaDAO#getPatients(java.util.Date, Integer, Integer, Boolean) + */ + @Test + public void getPatient_shouldReturnListOfPatientsWithRequriedBirthdate() { + GregorianCalendar birthdate = new GregorianCalendar(2014, 7, 28); + List patients = dao.getPatientsByBirthdate(birthdate.getTime(), 0, 11, false); + Assert.assertEquals(2, patients.size()); + } + + /** + * @see PatientSearchCriteriaDAO#getPatients(java.util.Date, java.util.Date, Integer, Integer, + * Boolean) + */ + @Test + public void getPatient_shouldReturnListOfPatientsWithRequriedAge() { + GregorianCalendar to = new GregorianCalendar(2013, 7, 28); + GregorianCalendar from = new GregorianCalendar(2015, 7, 28); + List patients = dao.getPatientsByRangeOfAge(from.getTime(), to.getTime(), 0, 11, false); + Assert.assertEquals(3, patients.size()); + } + + /** + * @see PatientSearchCriteriaDAO#getPatients(String, String, Integer, Integer, Boolean) + */ + @Test + public void getPatients_shouldReturnListOfPatientsWithRequriedGivenNameAndGender() { + List patients = dao.getPatientsByNameOrIdAndGender("Bethany", "F", 0, 11, false); + Assert.assertEquals(1, patients.size()); + Assert.assertEquals("Bethany", patients.get(0).getGivenName()); + Assert.assertEquals("F", patients.get(0).getGender()); + } + + /** + * @see PatientSearchCriteriaDAO#getPatients(String, java.util.Date, Integer, Integer, Boolean) + */ + @Test + public void getPatients_shouldReturnListOfPatientsWithRequriedGivenNameAndBirthdate() { + GregorianCalendar birthdate = new GregorianCalendar(2014, 7, 28); + List patients = dao.getPatientsByNameOrIdAndBirthdate("Bethany", birthdate.getTime(), 0, 11, false); + Assert.assertEquals(1, patients.size()); + Assert.assertEquals("Bethany", patients.get(0).getGivenName()); + } + + /** + * @see PatientSearchCriteriaDAO#getPatients(String, java.util.Date, java.util.Date, Integer, + * Integer, Boolean) + */ + @Test + public void getPatients_shouldReturnListOfPatientsWithRequriedGivenNameAndAgeRange() { + GregorianCalendar to = new GregorianCalendar(2013, 7, 28); + GregorianCalendar from = new GregorianCalendar(2015, 7, 28); + List patients = dao.getPatientsByNameOrIdAndRangeOfAge("Bethany", from.getTime(), to.getTime(), 0, 11, + false); + Assert.assertEquals(1, patients.size()); + Assert.assertEquals("Bethany", patients.get(0).getGivenName()); + } + + /** + * @see PatientSearchCriteriaDAO#getPatients(String, String, java.util.Date, Integer, Integer, + * Boolean) + */ + @Test + public void getPatients_shouldReturnListOfPatientsWithRequriedGivenNameAndBirthdaterAndGender() { + GregorianCalendar birthdate = new GregorianCalendar(2014, 7, 28); + List patients = dao.getPatientsByNameOrIdAndGenderAndBirthdate("Adam", "M", birthdate.getTime(), 0, 11, + false); + Assert.assertEquals(1, patients.size()); + Assert.assertEquals("Adam", patients.get(0).getGivenName()); + } + + /** + * @see PatientSearchCriteriaDAO#getPatients(String, String, java.util.Date, java.util.Date, + * Integer, Integer, Boolean) + */ + @Test + public void getPatients_shouldReturnListOfPatientsWithRequriedGivenNameAndAgeRangeAndGender() { + GregorianCalendar to = new GregorianCalendar(2013, 7, 28); + GregorianCalendar from = new GregorianCalendar(2015, 7, 28); + List patients = dao.getPatientsByNameOrIdAndGenderAndRangeOfAge("Adam", "M", from.getTime(), to.getTime(), + 0, 11, false); + Assert.assertEquals(1, patients.size()); + Assert.assertEquals("Adam", patients.get(0).getGivenName()); + } + + /** + * @see PatientSearchCriteriaDAO#getPatients(String, String, Integer, Integer, Boolean) + */ + @Test + public void getPatients_shouldReturnListOfPatientsWithRequriedMiddleNameAndGender() { + List patients = dao.getPatientsByNameOrIdAndGender("Benedict", "M", 0, 11, false); + Assert.assertEquals(1, patients.size()); + Assert.assertEquals("Benedict", patients.get(0).getMiddleName()); + Assert.assertEquals("M", patients.get(0).getGender()); + } + + /** + * @see PatientSearchCriteriaDAO#getPatients(String, java.util.Date, Integer, Integer, Boolean) + */ + @Test + public void getPatients_shouldReturnListOfPatientsWithRequriedMiddleNameAndBirthdate() { + GregorianCalendar birthdate = new GregorianCalendar(2014, 7, 28); + List patients = dao.getPatientsByNameOrIdAndBirthdate("Benedict", birthdate.getTime(), 0, 11, false); + Assert.assertEquals(1, patients.size()); + Assert.assertEquals("Benedict", patients.get(0).getMiddleName()); + } + + /** + * @see PatientSearchCriteriaDAO#getPatients(String, java.util.Date, java.util.Date, Integer, + * Integer, Boolean) + */ + @Test + public void getPatients_shouldReturnListOfPatientsWithRequriedMiddleNameAndAgeRange() { + GregorianCalendar to = new GregorianCalendar(2014, 7, 28); + GregorianCalendar from = new GregorianCalendar(2015, 7, 28); + List patients = dao.getPatientsByNameOrIdAndRangeOfAge("Benedict", from.getTime(), to.getTime(), 0, 11, + false); + Assert.assertEquals(1, patients.size()); + Assert.assertEquals("Benedict", patients.get(0).getMiddleName()); + } + + /** + * @see PatientSearchCriteriaDAO#getPatients(String, String, java.util.Date, Integer, Integer, + * Boolean) + */ + @Test + public void getPatients_shouldReturnListOfPatientsWithRequriedMiddleNameAndBirthdaterAndGender() { + GregorianCalendar birthdate = new GregorianCalendar(2014, 7, 28); + List patients = dao.getPatientsByNameOrIdAndGenderAndBirthdate("Frank", "F", birthdate.getTime(), 0, 11, + false); + Assert.assertEquals(1, patients.size()); + Assert.assertEquals("Frank", patients.get(0).getMiddleName()); + } + + /** + * @see PatientSearchCriteriaDAO#getPatients(String, String, java.util.Date, java.util.Date, + * Integer, Integer, Boolean) + */ + @Test + public void getPatients_shouldReturnListOfPatientsWithRequriedMiddleNameAndAgeRangeAndGender() { + GregorianCalendar to = new GregorianCalendar(2013, 7, 28); + GregorianCalendar from = new GregorianCalendar(2015, 7, 28); + List patients = dao.getPatientsByNameOrIdAndGenderAndRangeOfAge("Frank", "F", from.getTime(), to.getTime(), + 0, 11, false); + Assert.assertEquals(1, patients.size()); + Assert.assertEquals("Frank", patients.get(0).getMiddleName()); + } + + /** + * @see PatientSearchCriteriaDAO#getPatients(String, String, Integer, Integer, Boolean) + */ + @Test + public void getPatients_shouldReturnListOfPatientsWithRequriedfamilyNameAndGender() { + List patients = dao.getPatientsByNameOrIdAndGender("Franklin", "M", 0, 11, false); + Assert.assertEquals(2, patients.size()); + Assert.assertEquals("Franklin", patients.get(0).getFamilyName()); + Assert.assertEquals("Franklin", patients.get(1).getFamilyName()); + Assert.assertEquals("M", patients.get(0).getGender()); + Assert.assertEquals("M", patients.get(1).getGender()); + } + + /** + * @see PatientSearchCriteriaDAO#getPatients(String, java.util.Date, Integer, Integer, Boolean) + */ + @Test + public void getPatients_shouldReturnListOfPatientsWithRequriedfamilyNameAndBirthdate() { + GregorianCalendar birthdate = new GregorianCalendar(2014, 7, 28); + List patients = dao.getPatientsByNameOrIdAndBirthdate("Franklin", birthdate.getTime(), 0, 11, false); + Assert.assertEquals(1, patients.size()); + Assert.assertEquals("Adam", patients.get(0).getGivenName()); + } + + /** + * @see PatientSearchCriteriaDAO#getPatients(String, java.util.Date, java.util.Date, Integer, + * Integer, Boolean) + */ + @Test + public void getPatients_shouldReturnListOfPatientsWithRequriedfamilyNameAndAgeRange() { + GregorianCalendar to = new GregorianCalendar(2013, 7, 28); + GregorianCalendar from = new GregorianCalendar(2015, 7, 28); + List patients = dao.getPatientsByNameOrIdAndRangeOfAge("Franklin", from.getTime(), to.getTime(), 0, 11, + false); + Assert.assertEquals(1, patients.size()); + Assert.assertEquals("Adam", patients.get(0).getGivenName()); + } + + /** + * @see PatientSearchCriteriaDAO#getPatients(String, String, java.util.Date, Integer, Integer, + * Boolean) + */ + @Test + public void getPatients_shouldReturnListOfPatientsWithRequriedfamilyNameAndBirthdaterAndGender() { + GregorianCalendar birthdate = new GregorianCalendar(2014, 7, 28); + List patients = dao.getPatientsByNameOrIdAndGenderAndBirthdate("Franklin", "M", birthdate.getTime(), 0, 11, + false); + Assert.assertEquals(1, patients.size()); + Assert.assertEquals("Adam", patients.get(0).getGivenName()); + } + + /** + * @see PatientSearchCriteriaDAO#getPatients(String, String, java.util.Date, java.util.Date, + * Integer, Integer, Boolean) + */ + @Test + public void getPatients_shouldReturnListOfPatientsWithRequriedfamilyNameAndAgeRangeAndGender() { + GregorianCalendar to = new GregorianCalendar(2013, 7, 28); + GregorianCalendar from = new GregorianCalendar(2015, 7, 28); + List patients = dao.getPatientsByNameOrIdAndGenderAndRangeOfAge("Franklin", "M", from.getTime(), + to.getTime(), 0, 11, false); + Assert.assertEquals(1, patients.size()); + Assert.assertEquals("Adam", patients.get(0).getGivenName()); + } +} diff --git a/api/src/test/resources/org/openmrs/module/patientsearch/api/dao/include/PatientSearchCriteriaDAOTest-patients.xml b/api/src/test/resources/org/openmrs/module/patientsearch/api/dao/include/PatientSearchCriteriaDAOTest-patients.xml new file mode 100644 index 0000000..41bb193 --- /dev/null +++ b/api/src/test/resources/org/openmrs/module/patientsearch/api/dao/include/PatientSearchCriteriaDAOTest-patients.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/api/src/test/resources/org/openmrs/module/patientsearch/api/include/PatientSearchCriteriaServiceTest-patients.xml b/api/src/test/resources/org/openmrs/module/patientsearch/api/include/PatientSearchCriteriaServiceTest-patients.xml new file mode 100644 index 0000000..3f8df7b --- /dev/null +++ b/api/src/test/resources/org/openmrs/module/patientsearch/api/include/PatientSearchCriteriaServiceTest-patients.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/omod/.gitignore b/omod/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/omod/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/omod/pom.xml b/omod/pom.xml new file mode 100644 index 0000000..a72d97f --- /dev/null +++ b/omod/pom.xml @@ -0,0 +1,100 @@ + + 4.0.0 + + org.openmrs.module + patientsearch + 1.0.0-SNAPSHOT + + + patientsearch-omod + jar + PatientSearchCriteria OMOD + Omod submodule for PatientSearchCriteria + + + + jitpack.io + https://jitpack.io + + + + + + org.openmrs.module + patientsearch-api + 1.0.0-SNAPSHOT + + + org.openmrs.web + openmrs-web + provided + + + org.openmrs.web + openmrs-web + provided + tests + + + + org.openmrs.module + webservices.rest-omod + 2.25.0 + provided + + + + org.openmrs.module + webservices.rest-omod-1.8 + 2.25.0 + provided + + + + org.openmrs.module + webservices.rest-omod-common + 2.25.0 + test-jar + test + + + + javax.servlet + javax.servlet-api + 3.0.1 + test + + + + com.github.Reyano132.openmrs-core + openmrs-api + 0112f622 + provided + + + com.github.Reyano132.openmrs-core + openmrs-api + 0112f622 + test-jar + provided + + + + + + ${project.parent.artifactId}-${project.parent.version} + + + + org.openmrs.maven.plugins + maven-openmrs-plugin + + + org.apache.maven.plugins + maven-dependency-plugin + + + + + diff --git a/omod/src/main/java/org/openmrs/module/patientsearch/extension/html/AdminList.java b/omod/src/main/java/org/openmrs/module/patientsearch/extension/html/AdminList.java new file mode 100644 index 0000000..75efdc8 --- /dev/null +++ b/omod/src/main/java/org/openmrs/module/patientsearch/extension/html/AdminList.java @@ -0,0 +1,50 @@ +/** + * 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.openmrs.module.patientsearch.extension.html; + +import java.util.HashMap; +import java.util.Map; + +import org.openmrs.module.Extension; + +/** + * This class defines the links that will appear on the administration page under the + * "patientsearch.title" heading. This extension is enabled by defining (uncommenting) it in the + * config.xml file. + */ +public class AdminList extends Extension { + + /** + * @see org.openmrs.module.web.extension.AdministrationSectionExt#getMediaType() + */ + public Extension.MEDIA_TYPE getMediaType() { + return Extension.MEDIA_TYPE.html; + } + + /** + * @see org.openmrs.module.web.extension.AdministrationSectionExt#getTitle() + */ + public String getTitle() { + return "patientsearch.title"; + } + + /** + * @see org.openmrs.module.web.extension.AdministrationSectionExt#getLinks() + */ + public Map getLinks() { + + Map map = new HashMap(); + + map.put("module/patientsearch/patientsearch.form", "patientsearch.title"); + + return map; + } + +} diff --git a/omod/src/main/java/org/openmrs/module/patientsearch/web/controller/PatientSearchCriteriaController.java b/omod/src/main/java/org/openmrs/module/patientsearch/web/controller/PatientSearchCriteriaController.java new file mode 100644 index 0000000..1fe4279 --- /dev/null +++ b/omod/src/main/java/org/openmrs/module/patientsearch/web/controller/PatientSearchCriteriaController.java @@ -0,0 +1,37 @@ +/** + * 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.openmrs.module.patientsearch.web.controller; + +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceController; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * This class configured as controller using annotation and mapped with the URL of + * 'module/${rootArtifactid}/${rootArtifactid}Link.form'. + */ +//@Controller("${rootrootArtifactid}.PatientSearchCriteriaController") +//@RequestMapping(value = "module/${rootArtifactid}/${rootArtifactid}.form") +@Controller +@RequestMapping("/rest/" + RestConstants.VERSION_1 + PatientSearchCriteriaController.PATIENTSEARCH_REST_NAMESPACE) +public class PatientSearchCriteriaController extends MainResourceController { + + public static final String PATIENTSEARCH_REST_NAMESPACE = "/patientsearch"; + + /** + * @see org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController#getNamespace() + */ + @Override + public String getNamespace() { + return RestConstants.VERSION_1 + PATIENTSEARCH_REST_NAMESPACE; + } + +} diff --git a/omod/src/main/java/org/openmrs/module/patientsearch/web/resources/PatientSearchCriteriaResource.java b/omod/src/main/java/org/openmrs/module/patientsearch/web/resources/PatientSearchCriteriaResource.java new file mode 100644 index 0000000..00aa14b --- /dev/null +++ b/omod/src/main/java/org/openmrs/module/patientsearch/web/resources/PatientSearchCriteriaResource.java @@ -0,0 +1,16 @@ +package org.openmrs.module.patientsearch.web.resources; + +import org.openmrs.Patient; +import org.openmrs.module.patientsearch.web.controller.PatientSearchCriteriaController; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.annotation.Resource; +import org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs1_8.PatientResource1_8; + +@Resource(name = RestConstants.VERSION_1 + PatientSearchCriteriaController.PATIENTSEARCH_REST_NAMESPACE + "/patient", supportedClass = Patient.class, supportedOpenmrsVersions = { + "1.8.*", "1.9.*", "1.10.*, 1.11.*", "1.12.*", "2.0.*", "2.1.*", "2.2.*", "2.3.*" }) +public class PatientSearchCriteriaResource extends PatientResource1_8 { + + public PatientSearchCriteriaResource() { + } + +} diff --git a/omod/src/main/java/org/openmrs/module/patientsearch/web/search/PatientSearchHandler.java b/omod/src/main/java/org/openmrs/module/patientsearch/web/search/PatientSearchHandler.java new file mode 100644 index 0000000..a039f9e --- /dev/null +++ b/omod/src/main/java/org/openmrs/module/patientsearch/web/search/PatientSearchHandler.java @@ -0,0 +1,67 @@ +package org.openmrs.module.patientsearch.web.search; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import org.openmrs.Patient; +import org.openmrs.api.context.Context; +import org.openmrs.module.patientsearch.api.PatientSearchCriteriaService; +import org.openmrs.module.patientsearch.web.controller.PatientSearchCriteriaController; +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; +import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; +import org.openmrs.module.webservices.rest.web.resource.api.SearchHandler; +import org.openmrs.module.webservices.rest.web.resource.api.SearchQuery; +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.springframework.stereotype.Component; + +@Component +public class PatientSearchHandler implements SearchHandler { + + private final SearchConfig searchConfig = new SearchConfig("patientBySearchCriteria", RestConstants.VERSION_1 + + PatientSearchCriteriaController.PATIENTSEARCH_REST_NAMESPACE + "/patient", Arrays.asList("1.8.*", "1.9.*", + "1.10.*, 1.11.*", "1.12.*", "2.0.*", "2.1.*", "2.2.*", "2.3.*"), Arrays.asList(new SearchQuery.Builder( + "Allows you to find Patients by name or id").withRequiredParameters("q").build(), new SearchQuery.Builder( + "Allow you to find Patients by gender").withRequiredParameters("gender").build(), new SearchQuery.Builder( + "Allow you to find Patients by birthdate").withRequiredParameters("birthdate").build(), new SearchQuery.Builder( + "Allow you to find Patients by range of age").withRequiredParameters("to", "from").build(), + new SearchQuery.Builder("Allow you to find Patients by name or id and gender").withRequiredParameters("q", "gender") + .build(), new SearchQuery.Builder("Allow you to find Patients by name or id and birthdate") + .withRequiredParameters("q", "birthdate").build(), new SearchQuery.Builder( + "Allow you to find Patients by name or id and range of age").withRequiredParameters("q", "to", "from") + .build(), new SearchQuery.Builder("Allow you to find Patients by name or id and gender and birthdate") + .withRequiredParameters("q", "gender", "birthdate").build(), + new SearchQuery.Builder("Allow you to find Patients by name or id and gender and range of age") + .withRequiredParameters("q", "gender", "to", "from").build(), new SearchQuery.Builder( + "Allow you to find Patients by gender and range of age").withRequiredParameters("gender", "to", "from") + .build(), new SearchQuery.Builder("Allow you to find Patients by birthdate and gender") + .withRequiredParameters("gender", "birthdate").build())); + + @Override + public SearchConfig getSearchConfig() { + return this.searchConfig; + } + + @Override + public PageableResult search(RequestContext context) throws ResponseException { + String q = context.getParameter("q"); + String gender = context.getParameter("gender"); + String toString = context.getParameter("to"); + String fromString = context.getParameter("from"); + String birthdateString = context.getParameter("birthdate"); + Integer to = (toString == null) ? null : Integer.parseInt(toString); + Integer from = (fromString == null) ? null : Integer.parseInt(fromString); + Date birthdate = (birthdateString == null) ? null : new Date(Long.valueOf(birthdateString)); + List patients = Context.getService(PatientSearchCriteriaService.class).getPatients(null, q, null, true, + gender, from, to, birthdate); + if (patients != null && patients.size() > 0) { + return new NeedsPaging(patients, context); + } + return new EmptySearchResult(); + } + +} diff --git a/omod/src/main/resources/config.xml b/omod/src/main/resources/config.xml new file mode 100644 index 0000000..d6ecaf6 --- /dev/null +++ b/omod/src/main/resources/config.xml @@ -0,0 +1,109 @@ + + + + + + ${project.parent.artifactId} + ${project.parent.name} + ${project.parent.version} + org.openmrs.module.patientsearch + Rushikesh Chaudhari + + ${project.parent.description} + + + org.openmrs.module.patientsearch.PatientSearchCriteriaActivator + + + + + 2.2.0 + + + org.openmrs.module.webservices.rest + + + + org.openmrs.admin.list + org.openmrs.module.patientsearch.extension.html.AdminList + + + + org.openmrs.module.legacyui + + + + + + + + + + + + + + + + + + + + + + en + messages.properties + + + fr + messages_fr.properties + + + es + messages_es.properties + + + + + diff --git a/omod/src/main/resources/webModuleApplicationContext.xml b/omod/src/main/resources/webModuleApplicationContext.xml new file mode 100644 index 0000000..387ea86 --- /dev/null +++ b/omod/src/main/resources/webModuleApplicationContext.xml @@ -0,0 +1,24 @@ + + + + + diff --git a/omod/src/test/java/org/openmrs/module/patientsearch/AdminListExtensionTest.java b/omod/src/test/java/org/openmrs/module/patientsearch/AdminListExtensionTest.java new file mode 100644 index 0000000..8ea79f0 --- /dev/null +++ b/omod/src/test/java/org/openmrs/module/patientsearch/AdminListExtensionTest.java @@ -0,0 +1,48 @@ +/** + * 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.openmrs.module.patientsearch; + +import java.util.Map; + +import org.junit.Test; +import org.openmrs.module.Extension; +import org.openmrs.module.patientsearch.extension.html.AdminList; +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + +/** + * This test validates the AdminList extension class + */ +public class AdminListExtensionTest { + + /** + * Get the links for the extension class + */ + @Test + public void testValidatesLinks() { + AdminList ext = new AdminList(); + + Map links = ext.getLinks(); + + assertThat(links, is(notNullValue())); + assertThat(links.size(), is(not(0))); + } + + /** + * Check the media type of this extension class + */ + @Test + public void testMediaTypeIsHtml() { + AdminList ext = new AdminList(); + + assertThat(ext.getMediaType(), is(Extension.MEDIA_TYPE.html)); + } + +} diff --git a/omod/src/test/java/org/openmrs/module/patientsearch/web/search/PatientSearchHandlerTest.java b/omod/src/test/java/org/openmrs/module/patientsearch/web/search/PatientSearchHandlerTest.java new file mode 100644 index 0000000..477fe6e --- /dev/null +++ b/omod/src/test/java/org/openmrs/module/patientsearch/web/search/PatientSearchHandlerTest.java @@ -0,0 +1,219 @@ +package org.openmrs.module.patientsearch.web.search; + +import java.util.GregorianCalendar; +import java.util.List; + +import org.apache.commons.beanutils.PropertyUtils; +import org.junit.Assert; +import org.junit.Test; +import org.openmrs.api.context.Context; +import org.openmrs.module.patientsearch.api.PatientSearchCriteriaService; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; +import org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.web.bind.annotation.RequestMethod; + +public class PatientSearchHandlerTest extends MainResourceControllerTest { + + private final static String PATIENT_UUID = "da7f524f-27ce-4bb2-86d6-6d1d05312bd5"; + + /** + * @see MainResourceControllerTest#getURI() + */ + @Override + public String getURI() { + return "patientsearch/patient"; + } + + /** + * @return + * @see MainResourceControllerTest#getAllCount() + */ + @Override + public long getAllCount() { + return Context.getService(PatientSearchCriteriaService.class).getAllPatients(false).size(); + } + + /** + * @see MainResourceControllerTest#getUuid() + */ + @Override + public String getUuid() { + return PATIENT_UUID; + } + + @Override + @Test(expected = ResourceDoesNotSupportOperationException.class) + public void shouldGetAll() throws Exception { + super.shouldGetAll(); + } + + @Test + @SuppressWarnings("unchecked") + public void getSearchConfig_shouldReturnPatientByIdentifier() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("q", "7TU-8"); + + SimpleObject result = deserialize(handle(req)); + List hits = (List) result.get("results"); + Assert.assertEquals(Context.getPatientService().getPatient(8).getUuid(), + PropertyUtils.getProperty(hits.get(0), "uuid")); + } + + @Test + @SuppressWarnings("unchecked") + public void getPatientByName() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("q", "Horatio"); + SimpleObject result = deserialize(handle(req)); + List hits = (List) result.get("results"); + Assert.assertEquals(1, hits.size()); + Assert.assertEquals(Context.getPatientService().getPatient(2).getUuid(), + PropertyUtils.getProperty(hits.get(0), "uuid")); + } + + @Test + @SuppressWarnings("unchecked") + public void getPatientByFewInitialsOfName() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("q", "Hor"); + SimpleObject result = deserialize(handle(req)); + List hits = (List) result.get("results"); + Assert.assertEquals(1, hits.size()); + Assert.assertEquals(Context.getPatientService().getPatient(2).getUuid(), + PropertyUtils.getProperty(hits.get(0), "uuid")); + } + + @Test + @SuppressWarnings("unchecked") + public void getPatientByNameAndGender() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("q", "Horatio"); + req.addParameter("gender", "M"); + SimpleObject result = deserialize(handle(req)); + List hits = (List) result.get("results"); + Assert.assertEquals(1, hits.size()); + Assert.assertEquals(Context.getPatientService().getPatient(2).getUuid(), + PropertyUtils.getProperty(hits.get(0), "uuid")); + + } + + @Test + @SuppressWarnings("unchecked") + public void getPatientByBirthdate() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + GregorianCalendar birthdate = new GregorianCalendar(1975, 3, 8); + req.addParameter("birthdate", String.valueOf(birthdate.getTime().getTime())); + SimpleObject result = deserialize(handle(req)); + List hits = (List) result.get("results"); + Assert.assertEquals(1, hits.size()); + Assert.assertEquals(Context.getPatientService().getPatient(2).getUuid(), + PropertyUtils.getProperty(hits.get(0), "uuid")); + } + + @Test + @SuppressWarnings("unchecked") + public void getPatientByRangeOfAge() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("from", String.valueOf(40)); + req.addParameter("to", String.valueOf(50)); + SimpleObject result = deserialize(handle(req)); + List hits = (List) result.get("results"); + Assert.assertEquals(3, hits.size()); + Assert.assertEquals(Context.getPatientService().getPatient(2).getUuid(), + PropertyUtils.getProperty(hits.get(0), "uuid")); + Assert.assertEquals(Context.getPatientService().getPatient(6).getUuid(), + PropertyUtils.getProperty(hits.get(1), "uuid")); + Assert.assertEquals(Context.getPatientService().getPatient(7).getUuid(), + PropertyUtils.getProperty(hits.get(2), "uuid")); + + } + + @Test + @SuppressWarnings("unchecked") + public void getPatientByNameAndBirthdate() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + GregorianCalendar birthdate = new GregorianCalendar(1975, 3, 8); + req.addParameter("birthdate", String.valueOf(birthdate.getTime().getTime())); + req.addParameter("q", "Horatio"); + SimpleObject result = deserialize(handle(req)); + List hits = (List) result.get("results"); + Assert.assertEquals(1, hits.size()); + Assert.assertEquals(Context.getPatientService().getPatient(2).getUuid(), + PropertyUtils.getProperty(hits.get(0), "uuid")); + } + + @Test + @SuppressWarnings("unchecked") + public void getPatientByGenderAndRangeOfAge() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("from", String.valueOf(40)); + req.addParameter("to", String.valueOf(50)); + req.addParameter("gender", "F"); + SimpleObject result = deserialize(handle(req)); + List hits = (List) result.get("results"); + Assert.assertEquals(1, hits.size()); + Assert.assertEquals(Context.getPatientService().getPatient(7).getUuid(), + PropertyUtils.getProperty(hits.get(0), "uuid")); + } + + @Test + @SuppressWarnings("unchecked") + public void getPatientByNameAndRangeOfAge() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("from", String.valueOf(40)); + req.addParameter("to", String.valueOf(50)); + req.addParameter("q", "Collet"); + SimpleObject result = deserialize(handle(req)); + List hits = (List) result.get("results"); + Assert.assertEquals(1, hits.size()); + Assert.assertEquals(Context.getPatientService().getPatient(7).getUuid(), + PropertyUtils.getProperty(hits.get(0), "uuid")); + } + + @Test + @SuppressWarnings("unchecked") + public void getPatientByGenderAndBirthdate() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + GregorianCalendar birthdate = new GregorianCalendar(1975, 3, 8); + req.addParameter("birthdate", String.valueOf(birthdate.getTime().getTime())); + req.addParameter("gender", "M"); + SimpleObject result = deserialize(handle(req)); + List hits = (List) result.get("results"); + Assert.assertEquals(1, hits.size()); + Assert.assertEquals(Context.getPatientService().getPatient(2).getUuid(), + PropertyUtils.getProperty(hits.get(0), "uuid")); + } + + @Test + @SuppressWarnings("unchecked") + public void getPatientByNameAndGenderAndRangeOfAge() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("from", String.valueOf(40)); + req.addParameter("to", String.valueOf(50)); + req.addParameter("gender", "F"); + req.addParameter("q", "Collet"); + SimpleObject result = deserialize(handle(req)); + List hits = (List) result.get("results"); + Assert.assertEquals(1, hits.size()); + Assert.assertEquals(Context.getPatientService().getPatient(7).getUuid(), + PropertyUtils.getProperty(hits.get(0), "uuid")); + } + + @Test + @SuppressWarnings("unchecked") + public void getPatientByNameAndGenderAndBirthdate() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + GregorianCalendar birthdate = new GregorianCalendar(1975, 3, 8); + req.addParameter("birthdate", String.valueOf(birthdate.getTime().getTime())); + req.addParameter("gender", "M"); + req.addParameter("q", "Horatio"); + SimpleObject result = deserialize(handle(req)); + List hits = (List) result.get("results"); + Assert.assertEquals(1, hits.size()); + Assert.assertEquals(Context.getPatientService().getPatient(2).getUuid(), + PropertyUtils.getProperty(hits.get(0), "uuid")); + } + +} diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..c961bb5 --- /dev/null +++ b/pom.xml @@ -0,0 +1,74 @@ + + 4.0.0 + + + org.openmrs.maven.parents + maven-parent-openmrs-module + 1.1.1 + + + org.openmrs.module + patientsearch + 1.0.0-SNAPSHOT + pom + PatientSearchCriteria + Temporary module for patient search + + https://wiki.openmrs.org/x/FQ4z + + + scm:git:git@github.com:openmrs/openmrs-module-patientsearch.git + scm:git:git@github.com:openmrs/openmrs-module-patientsearch.git + https://github.com/openmrs/openmrs-module-patientsearch/ + + + + api + omod + + + + + openmrs-repo + OpenMRS Nexus Repository + http://mavenrepo.openmrs.org/nexus/content/repositories/public + + + central + Maven Repository Switchboard + default + http://repo1.maven.org/maven2 + + + + + openmrs-repo + OpenMRS Nexus Repository + http://mavenrepo.openmrs.org/nexus/content/repositories/public + + false + + + + + + 2.2.0 + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + + +