/**
* The contents of this file are subject to the OpenMRS Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://license.openmrs.org
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* Copyright (C) OpenMRS, LLC. All Rights Reserved.
*/
package org.openmrs.api;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.openmrs.Cohort;
import org.openmrs.Concept;
import org.openmrs.Drug;
import org.openmrs.DrugOrder;
import org.openmrs.Encounter;
import org.openmrs.EncounterType;
import org.openmrs.Form;
import org.openmrs.Location;
import org.openmrs.Obs;
import org.openmrs.Patient;
import org.openmrs.PatientIdentifier;
import org.openmrs.PatientIdentifierType;
import org.openmrs.PatientProgram;
import org.openmrs.PatientState;
import org.openmrs.Person;
import org.openmrs.PersonAttributeType;
import org.openmrs.Program;
import org.openmrs.ProgramWorkflow;
import org.openmrs.ProgramWorkflowState;
import org.openmrs.Relationship;
import org.openmrs.RelationshipType;
import org.openmrs.api.db.DAOException;
import org.openmrs.api.db.PatientSetDAO;
import org.springframework.transaction.annotation.Transactional;
@Transactional
public interface PatientSetService {
public void setPatientSetDAO(PatientSetDAO dao);
/**
* Export a set of patients to an XML
*
* @param ps The set you want to export as XML
* @return an XML representation of this patient-set, including patient characteristics, and
* observations
*/
@Transactional(readOnly = true)
public String exportXml(Cohort ps);
@Transactional(readOnly = true)
public String exportXml(Integer patientId);
@Transactional(readOnly = true)
public Cohort getAllPatients() throws DAOException;
@Transactional(readOnly = true)
public Cohort getPatientsByCharacteristics(String gender, Date minBirthdate, Date maxBirthdate) throws DAOException;
/**
* Get patients by specified gender, birthdate range, age range, and alive status (all optional)
*
* @param gender
* @param minBirthdate
* @param maxBirthdate
* @param minAge
* @param maxAge
* @param aliveOnly
* @param deadOnly
* @return Cohort with all matching patients
* @throws DAOException
* @should get all patients when no parameters given
* @should get patients of given gender
* @should get patients born before date
* @should get patients born after date
* @should get patients born between dates
* @should get patients who are alive
* @should get patients who are dead
*/
@Transactional(readOnly = true)
public Cohort getPatientsByCharacteristics(String gender, Date minBirthdate, Date maxBirthdate, Integer minAge,
Integer maxAge, Boolean aliveOnly, Boolean deadOnly) throws DAOException;
/**
* Get patients by specified gender, birthdate range, age range, and alive status (all optional)
*
* @param gender
* @param minBirthdate
* @param maxBirthdate
* @param minAge
* @param maxAge
* @param aliveOnly
* @param deadOnly
* @param effectiveDate
* @return Cohort with all matching patients
* @throws DAOException
* @should get all patients when no parameters given
* @should get patients of given gender
* @should get patients born before date
* @should get patients born after date
* @should get patients born between dates
* @should get patients who are alive
* @should get patients who are dead
* @should not get patients born after effectiveDate
*/
@Transactional(readOnly = true)
public Cohort getPatientsByCharacteristics(String gender, Date minBirthdate, Date maxBirthdate, Integer minAge,
Integer maxAge, Boolean aliveOnly, Boolean deadOnly, Date effectiveDate) throws DAOException;
@Transactional(readOnly = true)
public Cohort getPatientsHavingNumericObs(Integer conceptId, TimeModifier timeModifier,
PatientSetService.Modifier modifier, Number value, Date fromDate, Date toDate);
/**
* Searches for patients who have observations as described by the arguments to this method
*
* @param conceptId
* @param timeModifier
* @param modifier
* @param value
* @param fromDate
* @param toDate
* @return all patients with observations matching the arguments to this method
* @should get patients by concept and true boolean value
* @should get patients by concept and false boolean value
*/
@Transactional(readOnly = true)
public Cohort getPatientsHavingObs(Integer conceptId, TimeModifier timeModifier, Modifier modifier, Object value,
Date fromDate, Date toDate);
/**
* Searches for patients who have encounters as described by the arguments to this method
*
* @param encounterType
* @param location
* @param form
* @param fromDate
* @param toDate
* @param minCount
* @param maxCount
* @return all patients with encounters matching the arguments to this method
* @should get all patients with encounters when no parameters specified
*/
@Transactional(readOnly = true)
public Cohort getPatientsHavingEncounters(EncounterType encounterType, Location location, Form form, Date fromDate,
Date toDate, Integer minCount, Integer maxCount);
/**
* Gets patients who have encounters as described by the parameters specified (all optional)
*
* @param encounterTypeList
* @param location
* @param form
* @param fromDate
* @param toDate
* @param minCount
* @param maxCount
* @return Cohort with matching Patients
* @should get all patients with encounters when no parameters specified
* @should get patients with encounters of type
* @should get patients with encounters of multiple types
* @should get patients with encounters at location
* @should get patients with encounters from form
* @should get patients with encounters before date
* @should get patients with encounters after date
* @should get patients with encounters between dates
* @should get patients with at least n encounters
* @should get patients with at most n encounters
* @should get all patients with encounters when passed an empty encounterTypeList
*/
@Transactional(readOnly = true)
public Cohort getPatientsHavingEncounters(List<EncounterType> encounterTypeList, Location location, Form form,
Date fromDate, Date toDate, Integer minCount, Integer maxCount);
/**
* Gets patients who are enrolled in the given program or in the given state(s) at the specified
* time
*
* @param program
* @param stateList
* @param fromDate
* @param toDate
* @return Cohort with matching Patients
* @should get all patients in any program given null parameters
* @should get patients in program
* @should get patients in program from date
* @should get patients in program to date
* @should get patients in program between dates
* @should get patients in state
* @should get patients in states
* @should get patients in state from date
* @should get patients in state to date
* @should get patients in state between dates
*/
@Transactional(readOnly = true)
public Cohort getPatientsByProgramAndState(Program program, List<ProgramWorkflowState> stateList, Date fromDate,
Date toDate);
@Transactional(readOnly = true)
public Cohort getPatientsInProgram(Program program, Date fromDate, Date toDate);
@Transactional(readOnly = true)
public Cohort getPatientsHavingDateObs(Integer conceptId, Date startTime, Date endTime);
@Transactional(readOnly = true)
public Cohort getPatientsHavingTextObs(Concept concept, String value, TimeModifier timeModifier);
@Transactional(readOnly = true)
public Cohort getPatientsHavingTextObs(Integer conceptId, String value, TimeModifier timeModifier);
@Transactional(readOnly = true)
public Cohort getPatientsHavingLocation(Location loc);
@Transactional(readOnly = true)
public Cohort getPatientsHavingLocation(Location loc, PatientLocationMethod method);
@Transactional(readOnly = true)
public Cohort getPatientsHavingLocation(Integer locationId);
@Transactional(readOnly = true)
public Cohort getPatientsHavingLocation(Integer locationId, PatientLocationMethod method);
/**
* Returns a Cohort of patient who had drug orders for a set of drugs active on a certain date.
* Can also be used to find patient with no drug orders on that date.
*
* @param patientIds Collection of patientIds you're interested in. NULL means all patients.
* @param takingIds Collection of drugIds the patient is taking. (Or the empty set to mean
* "any drug" or NULL to mean "no drugs")
* @param onDate Which date to look at the patients' drug orders. (NULL defaults to now().)
*/
@Transactional(readOnly = true)
public Cohort getPatientsHavingDrugOrder(Collection<Integer> patientIds, Collection<Integer> takingIds, Date onDate);
/**
* Returns a Cohort of patient who had drug orders for a set of drugs active between a pair of
* dates. Can also be used to find patient with no drug orders on that date.
*
* @param patientIds Collection of patientIds you're interested in. NULL means all patients.
* @param drugIds Collection of drugIds the patient is taking. (Or the empty set to mean
* "any drug" or NULL to mean "no drugs")
* @param groupMethod whether to do NONE, ALL, or ANY of the list of specified ids.
* @param fromDate Beginning of date range to look at (NULL defaults to toDate if that isn't
* null, or now() if it is.)
* @param toDate End of date range to look at (NULL defaults to fromDate if that isn't null, or
* now() if it is.)
* @return Cohort with matching Patients
* @should get all patients with drug orders given null parameters
* @should get patients with no drug orders
* @should get patients with drug orders for drugs
* @should get patients with no drug orders for drugs
* @should get patients with drug orders from date
* @should get patients with drug orders to date
* @should get patients with drug order for drug between dates
*/
@Transactional(readOnly = true)
public Cohort getPatientsHavingDrugOrder(Collection<Integer> patientIds, Collection<Integer> drugIds,
GroupMethod groupMethod, Date fromDate, Date toDate);
/**
* @return A Cohort of patients who had drug order for particular drugs or generics, with start
* dates within a range, with end dates within a range, and a reason for
* discontinuation.
*/
@Transactional(readOnly = true)
public Cohort getPatientsHavingDrugOrder(List<Drug> drug, List<Concept> drugConcept, Date startDateFrom,
Date startDateTo, Date stopDateFrom, Date stopDateTo, Boolean discontinued, List<Concept> discontinuedReason);
/**
* At least one of attribute and value must be non-null
*
* @param attribute if not null, look for this attribute
* @param value if not null, look for this value
* @return Cohort of patients who have a person attribute (optionally) with attributeType of
* attribute and (optionally) value of value.
*/
@Transactional(readOnly = true)
public Cohort getPatientsHavingPersonAttribute(PersonAttributeType attribute, String value);
@Transactional(readOnly = true)
public Map<Integer, String> getShortPatientDescriptions(Collection<Integer> patientIds);
@Transactional(readOnly = true)
public Map<Integer, List<Obs>> getObservations(Cohort patients, Concept concept);
/**
* Date range is inclusive of both endpoints
*/
@Transactional(readOnly = true)
public Map<Integer, List<Obs>> getObservations(Cohort patients, Concept concept, Date fromDate, Date toDate);
/**
* TODO write something here
*
* @param patients
* @param c
* @return Map<patientId, List<Obs values>>
*/
@Transactional(readOnly = true)
public Map<Integer, List<List<Object>>> getObservationsValues(Cohort patients, Concept c);
/**
* @deprecated use {@link #getObservationsValues(Cohort, Concept, List, Integer, boolean)}
* instead
*/
@Deprecated
@Transactional(readOnly = true)
public Map<Integer, List<List<Object>>> getObservationsValues(Cohort patients, Concept c, List<String> attributes);
/**
* Returns a mapping from patient id to obs for concept <code>c</code>
* <p>
* The returned List< attribute value > is [obs value, attr value, attr value, attr value...]
* The returned List<List< attribute value >> represents the obs rows
*
* @param patients the cohort to restrict to. if null, then all patients are fetched
* @param c the concept to look for in obs.concept_id
* @param attributes list of attributes
* @param limit the number of patients to limit the results to. If null or less than zero,
* return all
* @param showMostRecentFirst if true, obs with the highest obsDatetime will be first in the
* List<List<Object>>
* @return <code>Map<patientId, List<List< attribute value >>></code>
*/
@Transactional(readOnly = true)
public Map<Integer, List<List<Object>>> getObservationsValues(Cohort patients, Concept c, List<String> attributes,
Integer limit, boolean showMostRecentFirst);
/**
* TODO write something here
*
* @param patients Cohort of patients to search
* @param encType the type of the encounter
* @return Map<Integer, Encounter> of patientId to encounters matching a specific type
*/
@Transactional(readOnly = true)
public Map<Integer, Encounter> getEncountersByType(Cohort patients, EncounterType encType);
/**
* TODO write something here
*
* @param patients Cohort of patients to search
* @param encTypes List<EncounterType> to include in the search
* @param attr <code>String</code> of attributes to get
* @return Map<Integer, Object> of encounter attributes
*/
public Map<Integer, Object> getEncounterAttrsByType(Cohort patients, List<EncounterType> encTypes, String attr);
/**
* TODO write something here
*
* @param patients Cohort of patients to search
* @param encType List<EncounterType> to include in the search
* @return Map<Integer, Encounter> of patientId to encounters matching a specific type
*/
@Transactional(readOnly = true)
public Map<Integer, Encounter> getEncountersByType(Cohort patients, List<EncounterType> encType);
/**
* This method returns a map of patients matched against their most recent encounters given a
* Cohort of patients, see {@link EncounterService#getAllEncounters(Cohort)} which gets a map of
* patient matched against lists of all their encounters.
*
* @see EncounterService#getAllEncounters(Cohort)
* @param patients Cohort of patients to search
* @return Map<Integer, Encounter> of all encounters for specified patients.
*/
@Transactional(readOnly = true)
public Map<Integer, Encounter> getEncounters(Cohort patients);
/**
* TODO write something here
*
* @param patients Cohort of patients to search
* @param encType
* @return Map<Integer, Encounter> of patientId to first encounters of specified patients, from
* a specific type
*/
@Transactional(readOnly = true)
public Map<Integer, Encounter> getFirstEncountersByType(Cohort patients, EncounterType encType);
/**
* TODO write something here
*
* @param patients Cohort of patients to search
* @param types List<EncounterType> to include in the search
* @return Map<Integer, Encounter> of patientId to first encounters of specified patients, from
* a specific list of types
*/
@Transactional(readOnly = true)
public Map<Integer, Encounter> getFirstEncountersByType(Cohort patients, List<EncounterType> types);
/**
* TODO write something here
*
* @param patients Cohort of patients to search
* @param encTypes List<EncounterType> to include in the search
* @param attr
* @return Map<Integer, Object> of patientId to first encounters properties
*/
@Transactional(readOnly = true)
public Map<Integer, Object> getFirstEncounterAttrsByType(Cohort patients, List<EncounterType> encTypes, String attr);
/**
* TODO write something here
*
* @param patients Cohort of patients to search
* @param className
* @param property
* @param returnAll
* @return Map<Integer, Object> of patientId to patient properties
*/
@Transactional(readOnly = true)
public Map<Integer, Object> getPatientAttributes(Cohort patients, String className, String property, boolean returnAll);
/**
* TODO write something here
*
* @param patients
* @param classNameDotProperty
* @param returnAll
* @return Map<Integer, Object> of patientId to patient properties
*/
@Transactional(readOnly = true)
public Map<Integer, Object> getPatientAttributes(Cohort patients, String classNameDotProperty, boolean returnAll);
/**
* @should return person attributes of type Location
* @param patients
* @param attributeName
* @param joinClass
* @param joinProperty
* @param outputColumn
* @param returnAll
* @return Map<Integer, Object> of patientId to person properties
*/
@Transactional(readOnly = true)
public Map<Integer, Object> getPersonAttributes(Cohort patients, String attributeName, String joinClass,
String joinProperty, String outputColumn, boolean returnAll);
/**
* TODO write something here
*
* @param patients Cohort of patients to look up
* @return Map<Integer,Map<String,Object>> with characteristics of specified patients
*/
@Transactional(readOnly = true)
public Map<Integer, Map<String, Object>> getCharacteristics(Cohort patients);
/**
* The PatientIdentifer object in the returned map now ONLY contains the identifier string, no
* other data is available
*
* @deprecated use method by same name that returns just the string instead of the whole object
*/
@Deprecated
@Transactional(readOnly = true)
public Map<Integer, PatientIdentifier> getPatientIdentifiersByType(Cohort patients, PatientIdentifierType type);
/**
* Gets a map of patient identifiers values by identifier type, indexed by patient primary key.
*
* @param patients Cohort of patients to look up
* @param type PatientIdentifierType to retrieve
* @return Map of patient identifiers (strings) for all patients in the specified cohort
*/
@Transactional(readOnly = true)
public Map<Integer, String> getPatientIdentifierStringsByType(Cohort patients, PatientIdentifierType type);
/**
* TODO write something here
*
* @param identifiers List of String patient identifiers
* @return Cohort of patients matching specified identifiers
*/
@Transactional(readOnly = true)
public Cohort convertPatientIdentifier(List<String> identifiers);
/**
* TODO write something here
*
* @param patientIds
* @return List of matching patients
*/
@Transactional(readOnly = true)
public List<Patient> getPatients(Collection<Integer> patientIds);
@Transactional(readOnly = true)
public Map<Integer, PatientState> getCurrentStates(Cohort ps, ProgramWorkflow wf);
@Transactional(readOnly = true)
public Map<Integer, PatientProgram> getCurrentPatientPrograms(Cohort ps, Program program);
/**
* Gets program enrollment data for the given cohort in the given program. The behavior is not
* specified if a patient is enrolled in the same program twice simultaneously.
*
* @param ps the cohort to get data for
* @param program the program to look for enrollments in
* @return a Map from patientId to PatientProgram
* @should get program enrollments for the given cohort
*/
@Transactional(readOnly = true)
public Map<Integer, PatientProgram> getPatientPrograms(Cohort ps, Program program);
@Transactional(readOnly = true)
public Map<Integer, List<Relationship>> getRelationships(Cohort ps, RelationshipType relType);
@Transactional(readOnly = true)
public Map<Integer, List<Person>> getRelatives(Cohort ps, RelationshipType relType, boolean forwards);
/**
* @return all active drug orders whose drug concept is in the given set (or all drugs if that's
* null)
*/
@Transactional(readOnly = true)
public Map<Integer, List<DrugOrder>> getCurrentDrugOrders(Cohort ps, Concept drugSet);
/**
* @return all active or finished drug orders whose drug concept is in the given set (or all
* drugs if that's null)
* @should return an empty list if cohort is empty
*/
@Transactional(readOnly = true)
public Map<Integer, List<DrugOrder>> getDrugOrders(Cohort ps, Concept drugSet);
/**
* Gets a list of encounters associated with the given form, filtered by the given patient set.
*
* @param patients Cohort of the patients to filter by (null will return all encounters for all
* patients)
* @param form List<Form> of the forms to filter by
*/
@Transactional(readOnly = true)
public List<Encounter> getEncountersByForm(Cohort patients, List<Form> form);
public enum Modifier {
LESS_THAN("<"), LESS_EQUAL("<="), EQUAL("="), GREATER_EQUAL(">="), GREATER_THAN(">");
public final String sqlRep;
Modifier(String sqlRep) {
this.sqlRep = sqlRep;
}
public String getSqlRepresentation() {
return sqlRep;
}
}
public enum TimeModifier {
ANY, NO, FIRST, LAST, MIN, MAX, AVG;
}
public enum BooleanOperator {
AND, OR, NOT;
}
// probably should combine this with TimeModifier
public enum GroupMethod {
ANY, ALL, NONE;
}
public enum PatientLocationMethod {
EARLIEST_ENCOUNTER, LATEST_ENCOUNTER, ANY_ENCOUNTER, PATIENT_HEALTH_CENTER
}
/**
* Equivalent to Cohort.subtract(PatientSetService.getAllPatients(), cohort) but may eventually
* perform faster by delegating to the database. (The current implementation has *not* been
* optimized.)
*
* @param cached
* @return
* @since 1.8
*/
public Cohort getInverseOfCohort(Cohort cohort);
/**
* @return number of unvoided patients in the database
* @since 1.8
*/
public Integer getCountOfPatients();
/**
* Get a batch of patients that are not voided in the database
*
* @param start the starting index
* @param size the number of patients to get in this batch
* @return a Cohort with patient ids
* @since 1.8
*/
public Cohort getPatients(Integer start, Integer size);
}