/** * 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.api; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Map; import org.openmrs.Cohort; import org.openmrs.Encounter; import org.openmrs.EncounterRole; import org.openmrs.EncounterType; import org.openmrs.Form; import org.openmrs.Location; import org.openmrs.Patient; import org.openmrs.Provider; import org.openmrs.User; import org.openmrs.Visit; import org.openmrs.VisitType; import org.openmrs.annotation.Authorized; import org.openmrs.api.db.EncounterDAO; import org.openmrs.api.handler.EncounterVisitHandler; import org.openmrs.parameter.EncounterSearchCriteria; import org.openmrs.util.PrivilegeConstants; /** * Services for Encounters and Encounter Types * * @version 1.0 */ public interface EncounterService extends OpenmrsService { /** * Set the given <code>dao</code> on this encounter service. The dao will act as the conduit * through with all encounter calls get to the database * * @param dao */ public void setEncounterDAO(EncounterDAO dao); /** * Saves a new encounter or updates an existing encounter. If an existing encounter, this method * will automatically apply encounter.patient to all encounter.obs.patient * * @param encounter to be saved * @throws APIException * @should save encounter with basic details * @should update encounter successfully * @should cascade save to contained obs * @should cascade patient to orders in the encounter * @should cascade save to contained obs when encounter already exists * @should cascade encounter datetime to obs * @should only cascade the obsdatetimes to obs with different initial obsdatetimes * @should not overwrite creator if non null * @should not overwrite dateCreated if non null * @should not overwrite obs and orders creator or dateCreated * @should not assign encounter to visit if no handler is registered * @should not assign encounter to visit if the no assign handler is registered * @should assign encounter to visit if the assign to existing handler is registered * @should assign encounter to visit if the assign to existing or new handler is registered * @should cascade save encounter providers * @should cascade delete encounter providers * @should void and create new obs when saving encounter * @should fail if user is not supposed to edit encounters of type of given encounter */ @Authorized( { PrivilegeConstants.ADD_ENCOUNTERS, PrivilegeConstants.EDIT_ENCOUNTERS }) public Encounter saveEncounter(Encounter encounter) throws APIException; /** * Get encounter by internal identifier * * @param encounterId encounter id * @return encounter with given internal identifier * @throws APIException * @should throw error if given null parameter * @should fail if user is not allowed to view encounter by given id * @should return encounter if user is allowed to view it */ @Authorized( { PrivilegeConstants.GET_ENCOUNTERS }) public Encounter getEncounter(Integer encounterId) throws APIException; /** * Get Encounter by its UUID * * @param uuid * @return encounter or null * @should find object given valid uuid * @should return null if no object found with given uuid */ @Authorized( { PrivilegeConstants.GET_ENCOUNTERS }) public Encounter getEncounterByUuid(String uuid) throws APIException; /** * Get all encounters (not voided) for a patient, sorted by encounterDatetime ascending. * * @param patient * @return List<Encounter> encounters (not voided) for a patient. * @should not get voided encounters * @should throw error when given null parameter */ @Authorized( { PrivilegeConstants.GET_ENCOUNTERS }) public List<Encounter> getEncountersByPatient(Patient patient); /** * Get encounters for a patientId * * @param patientId * @return all encounters (not voided) for the given patient identifier * @throws APIException * @should not get voided encounters * @should throw error if given a null parameter */ @Authorized( { PrivilegeConstants.GET_ENCOUNTERS }) public List<Encounter> getEncountersByPatientId(Integer patientId) throws APIException; /** * Get encounters (not voided) for a patient identifier * * @param identifier * @return all encounters (not retired) for the given patient identifier * @throws APIException * @should not get voided encounters * @should throw error if given null parameter */ @Authorized( { PrivilegeConstants.GET_ENCOUNTERS }) public List<Encounter> getEncountersByPatientIdentifier(String identifier) throws APIException; /** * Get all encounters that match a variety of (nullable) criteria. Each extra value for a * parameter that is provided acts as an "and" and will reduce the number of results returned * * @param who the patient the encounter is for * @param loc the location this encounter took place * @param fromDate the minimum date (inclusive) this encounter took place * @param toDate the maximum date (exclusive) this encounter took place * @param enteredViaForms the form that entered this encounter must be in this list * @param encounterTypes the type of encounter must be in this list * @param providers the provider of this encounter must be in this list * @param visitTypes the visit types of this encounter must be in this list * @param visits the visits of this encounter must be in this list * @param includeVoided true/false to include the voided encounters or not * @return a list of encounters ordered by increasing encounterDatetime * @since 1.9 * @should get encounters by location * @should get encounters on or after date * @should get encounters on or up to a date * @should get encounters by form * @should get encounters by type * @should get encounters by provider * @should get encounters by visit type * @should get encounters by visit * @should exclude voided encounters * @should include voided encounters * * @deprecated As of 2.0, replaced by {@link #getEncounters(EncounterSearchCriteria)} */ @Deprecated @Authorized( { PrivilegeConstants.GET_ENCOUNTERS }) public List<Encounter> getEncounters(Patient who, Location loc, Date fromDate, Date toDate, Collection<Form> enteredViaForms, Collection<EncounterType> encounterTypes, Collection<Provider> providers, Collection<VisitType> visitTypes, Collection<Visit> visits, boolean includeVoided); /** * Get all encounters that match a variety of (nullable) criteria contained in the parameter object. * Each extra value for a parameter that is provided acts as an "and" and will reduce the number of results returned * * @param encounterSearchCriteria the object containing search parameters * @return a list of encounters ordered by increasing encounterDatetime * @since 1.12 * @should get encounters modified after specified date */ @Authorized( { PrivilegeConstants.GET_ENCOUNTERS }) public List<Encounter> getEncounters(EncounterSearchCriteria encounterSearchCriteria); /** * Voiding a encounter essentially removes it from circulation * * @param encounter Encounter object to void * @param reason String reason that it's being voided * @should void encounter and set attributes * @should cascade to obs * @should cascade to orders * @should throw error with null reason parameter * @should not void providers * @should fail if user is not supposed to edit encounters of type of given encounter */ @Authorized( { PrivilegeConstants.EDIT_ENCOUNTERS }) public Encounter voidEncounter(Encounter encounter, String reason); /** * Unvoid encounter record * * @param encounter Encounter to be revived * @should cascade unvoid to obs * @should cascade unvoid to orders * @should unvoid and unmark all attributes * @should fail if user is not supposed to edit encounters of type of given encounter */ @Authorized( { PrivilegeConstants.EDIT_ENCOUNTERS }) public Encounter unvoidEncounter(Encounter encounter) throws APIException; /** * Completely remove an encounter from database. For super users only. If dereferencing * encounters, use <code>voidEncounter(org.openmrs.Encounter)</code> * * @param encounter encounter object to be purged * @should purgeEncounter * @should fail if user is not supposed to edit encounters of type of given encounter */ @Authorized( { PrivilegeConstants.PURGE_ENCOUNTERS }) public void purgeEncounter(Encounter encounter) throws APIException; /** * Completely remove an encounter from database. For super users only. If dereferencing * encounters, use <code>voidEncounter(org.openmrs.Encounter)</code> * * @param encounter encounter object to be purged * @param cascade Purge any related observations as well? * @should cascade purge to obs and orders * @should fail if user is not supposed to edit encounters of type of given encounter */ @Authorized( { PrivilegeConstants.PURGE_ENCOUNTERS }) public void purgeEncounter(Encounter encounter, boolean cascade) throws APIException; /** * Save a new Encounter Type or update an existing Encounter Type. * * @param encounterType * @should save encounter type * @should not overwrite creator * @should not overwrite creator or date created * @should not overwrite date created * @should update an existing encounter type name * @should throw error when trying to save encounter type when encounter types are locked */ @Authorized( { PrivilegeConstants.MANAGE_ENCOUNTER_TYPES }) public EncounterType saveEncounterType(EncounterType encounterType) throws APIException; /** * Get encounterType by internal identifier * * @param encounterTypeId Integer * @return encounterType with given internal identifier * @throws APIException * @should throw error if given null parameter */ @Authorized( { PrivilegeConstants.GET_ENCOUNTER_TYPES }) public EncounterType getEncounterType(Integer encounterTypeId) throws APIException; /** * Get EncounterType by its UUID * * @param uuid * @return encounter type or null * @should find object given valid uuid * @should return null if no object found with given uuid */ @Authorized( { PrivilegeConstants.GET_ENCOUNTER_TYPES }) public EncounterType getEncounterTypeByUuid(String uuid) throws APIException; /** * Get encounterType by exact name * * @param name string to match to an Encounter.name * @return EncounterType that is not retired * @throws APIException * @should not get retired types * @should return null if only retired type found * @should not get by inexact name * @should return null with null name parameter */ @Authorized( { PrivilegeConstants.GET_ENCOUNTER_TYPES }) public EncounterType getEncounterType(String name) throws APIException; /** * Get all encounter types (including retired) * * @return encounter types list * @throws APIException * @should not return retired types */ @Authorized( { PrivilegeConstants.GET_ENCOUNTER_TYPES }) public List<EncounterType> getAllEncounterTypes() throws APIException; /** * Get all encounter types. If includeRetired is true, also get retired encounter types. * * @param includeRetired * @return encounter types list * @throws APIException * @should not return retired types * @should include retired types with true includeRetired parameter */ @Authorized( { PrivilegeConstants.GET_ENCOUNTER_TYPES }) public List<EncounterType> getAllEncounterTypes(boolean includeRetired) throws APIException; /** * Find Encounter Types with name matching the beginning of the search string. Search strings * are case insensitive so that "NaMe".equals("name") is true. Includes retired EncounterTypes. * * @param name of the encounter type to find * @return List<EncounterType> matching encounters * @throws APIException * @should return types by partial name match * @should return types by partial case insensitive match * @should include retired types in the results * @should not partial match name on internal substrings * @should return types ordered on name and nonretired first */ @Authorized( { PrivilegeConstants.GET_ENCOUNTER_TYPES }) public List<EncounterType> findEncounterTypes(String name) throws APIException; /** * Retire an EncounterType. This essentially marks the given encounter type as a non-current * type that shouldn't be used anymore. * * @param encounterType the encounter type to retire * @param reason required non-null purpose for retiring this encounter type * @throws APIException * @should retire type and set attributes * @should throw error if given null reason parameter * @should should throw error when trying to retire encounter type when encounter types are * locked */ @Authorized( { PrivilegeConstants.MANAGE_ENCOUNTER_TYPES }) public EncounterType retireEncounterType(EncounterType encounterType, String reason) throws APIException; /** * Unretire an EncounterType. This brings back the given encounter type and says that it can be * used again * * @param encounterType the encounter type to unretire * @throws APIException * @should unretire type and unmark attributes * @should should throw error when trying to unretire encounter type when encounter types are * locked */ @Authorized( { PrivilegeConstants.MANAGE_ENCOUNTER_TYPES }) public EncounterType unretireEncounterType(EncounterType encounterType) throws APIException; /** * Completely remove an encounter type from database. * * @param encounterType * @throws APIException * @should purge type * @should should throw error when trying to delete encounter type when encounter types are * locked */ @Authorized( { PrivilegeConstants.PURGE_ENCOUNTER_TYPES }) public void purgeEncounterType(EncounterType encounterType) throws APIException; /** * Search for encounters by patient name or patient identifier. * * @param query patient name or identifier * @return list of encounters for the given patient * @throws APIException * @see EncounterService#getEncountersByPatient(String, boolean) * @since 1.7 */ @Authorized( { PrivilegeConstants.GET_ENCOUNTERS }) public List<Encounter> getEncountersByPatient(String query) throws APIException; /** * Search for encounters by patient name or patient identifier. * * @param query patient name or identifier * @param includeVoided Specifies whether voided encounters should be included * @return list of encounters for the given patient * @throws APIException * @should get all unvoided encounters for the given patient name * @should get all unvoided encounters for the given patient identifier * @should throw error if given null parameter * @should include voided encounters in the returned list if includedVoided is true * @since 1.7 */ @Authorized( { PrivilegeConstants.GET_ENCOUNTERS }) public List<Encounter> getEncountersByPatient(String query, boolean includeVoided) throws APIException; /** * Search for encounters by patient name or patient identifier and returns a specific number of * them from the specified starting position. If start and length are not specified, then all * matches are returned * * @param query patient name or identifier * @param start beginning index for the batch * @param length number of encounters to return in the batch * @param includeVoided Specifies whether voided encounters should be included * @return list of encounters for the given patient based on batch settings * @throws APIException * @since 1.8 * @should get all the unique encounters that match the specified parameter values * @should not return voided encounters if includeVoided is set to true * @should return empty list for empty query */ @Authorized( { PrivilegeConstants.GET_ENCOUNTERS }) public List<Encounter> getEncounters(String query, Integer start, Integer length, boolean includeVoided) throws APIException; /** * Searches for encounters by patient id, provider identifier, location, encounter type, * provider, form or provider name. It returns a specific number of them from the specified * starting position. If start and length are not specified, then all matches are returned * * @param query provider identifier, location, encounter type, provider, form or provider name * @param patientId the patient id * @param start beginning index for the batch * @param length number of encounters to return in the batch * @param includeVoided Specifies whether voided encounters should be included * @return list of encounters for the given patient based on batch settings * @throws APIException * @since 1.10 * @should fetch encounters by patient id * @should include voided encounters if includeVoided is set to true * @should should match on provider identifier * @should match on the provider name * @should match on the location name * @should match on the provider person name * @should match on the encounter type name * @should match on the form name */ @Authorized( { PrivilegeConstants.GET_ENCOUNTERS }) public List<Encounter> getEncounters(String query, Integer patientId, Integer start, Integer length, boolean includeVoided) throws APIException; /** * Get all encounters for a cohort of patients * * @param patients Cohort of patients to search * @return Map of all encounters for specified patients. * @should get all encounters for a cohort of patients * @since 1.8 */ public Map<Integer, List<Encounter>> getAllEncounters(Cohort patients); /** * Return the number of encounters matching a patient name or patient identifier * * @param query patient name or identifier * @param includeVoided Specifies whether voided encounters should be included * @return the number of encounters matching the given search phrase * @since 1.8 * @should get the correct count of unique encounters */ @Authorized( { PrivilegeConstants.GET_ENCOUNTERS }) public Integer getCountOfEncounters(String query, boolean includeVoided); /** * Gets all encounters grouped within a given visit. * * @param visit the visit. * @param includeVoided whether voided encounters should be returned * @return list of encounters in the given visit. * @should get active encounters by visit * @should include voided encounters when includeVoided is true * @since 1.9 */ @Authorized( { PrivilegeConstants.GET_ENCOUNTERS }) List<Encounter> getEncountersByVisit(Visit visit, boolean includeVoided); /** * @return list of handlers for determining if an encounter should go into a visit. If none are * found, an empty list. * @see EncounterVisitHandler * @since 1.9 * @should return the no assignment handler * @should return the existing visit only assignment handler * @should return the existing or new visit assignment handler */ public List<EncounterVisitHandler> getEncounterVisitHandlers(); /** * Gets the active handler for assigning visits to encounters. * * @see EncounterVisitHandler * @since 1.9 * @return the active handler class. * @throws APIException thrown if something goes wrong during the retrieval of the handler. */ public EncounterVisitHandler getActiveEncounterVisitHandler() throws APIException; /** * Saves a new encounter role or updates an existing encounter role. * * @param encounterRole to be saved * @throws APIException * @return EncounterRole * @since 1.9 * @should save encounter role with basic details * @should update encounter role successfully */ @Authorized( { PrivilegeConstants.MANAGE_ENCOUNTER_ROLES }) public EncounterRole saveEncounterRole(EncounterRole encounterRole) throws APIException; /** * Gets an encounter role when and internal encounter role id is provided. * * @param encounterRoleId to be retrieved * @throws APIException * @return EncounterRole * @since 1.9 */ @Authorized( { PrivilegeConstants.GET_ENCOUNTER_ROLES }) public EncounterRole getEncounterRole(Integer encounterRoleId) throws APIException; /** * Completely remove an encounter role from database. For super users only. If dereferencing * encounter roles, use * <code>retireEncounterRole(org.openmrs.Encounter, java.lang.String)</code> * * @param encounterRole encounter role object to be purged * @since 1.9 * @should purge Encounter Role */ @Authorized( { PrivilegeConstants.PURGE_ENCOUNTER_ROLES }) public void purgeEncounterRole(EncounterRole encounterRole) throws APIException; /** * Get all encounter roles based on includeRetired flag * * @param includeRetired * @return List of all encounter roles * @since 1.9 * @should get all encounter roles based on include retired flag. */ @Authorized( { PrivilegeConstants.GET_ENCOUNTER_ROLES }) public List<EncounterRole> getAllEncounterRoles(boolean includeRetired); /** * Get EncounterRole by its UUID * * @param uuid * @return EncounterRole * @since 1.9 * @should find encounter role based on uuid */ @Authorized( { PrivilegeConstants.GET_ENCOUNTER_ROLES }) public EncounterRole getEncounterRoleByUuid(String uuid) throws APIException; /** * Get EncounterRole by name * * @param name * @return EncounterRole object by name * @since 1.10 * @should find an encounter role identified by its name */ @Authorized( { PrivilegeConstants.GET_ENCOUNTER_ROLES }) public EncounterRole getEncounterRoleByName(String name); /** * Retire an EncounterRole. This essentially marks the given encounter role as a non-current * type that shouldn't be used anymore. * * @param encounterRole the encounter role to retire * @param reason required non-null purpose for retiring this encounter role * @throws APIException * @since 1.9 * @should retire type and set attributes * @should throw error if given null reason parameter */ @Authorized( { PrivilegeConstants.MANAGE_ENCOUNTER_ROLES }) public EncounterRole retireEncounterRole(EncounterRole encounterRole, String reason) throws APIException; /** * Unretire an EncounterRole. This brings back the given encounter role and says that it can be * used again * * @param encounterType the encounter role to unretire * @throws APIException * @since 1.9 * @should unretire type and unmark attributes */ @Authorized( { PrivilegeConstants.MANAGE_ENCOUNTER_ROLES }) public EncounterRole unretireEncounterRole(EncounterRole encounterType) throws APIException; /** * Gets the unvoided encounters for the specified patient that are not assigned to any visit. * Note that this method will return a maximum of 100 encounters. * * @param patient the patient to match against * @return a list of {@link Encounter}s * @throws APIException * @should return the unvoided encounters not assigned to any visit * @since 1.9 */ @Authorized( { PrivilegeConstants.GET_ENCOUNTERS }) public List<Encounter> getEncountersNotAssignedToAnyVisit(Patient patient) throws APIException; /** * Gets encounters for the given patient. It populates results with empty encounters to include * visits that have no assigned encounters. * <p> * The empty encounters have only visit set. * * @param patient the patient to match * @param includeVoided if voided encounters or visits should be included * @param query filters results (defaults to return all results if <code>null</code>) * @param start index to start with (defaults to 0 if <code>null</code>) * @param length number of results to return (default to return all results if <code>null</code>) * @return encounters and empty encounters with only visit set * @throws APIException * @since 1.9 */ @Authorized( { PrivilegeConstants.GET_VISITS }) public List<Encounter> getEncountersByVisitsAndPatient(Patient patient, boolean includeVoided, String query, Integer start, Integer length) throws APIException; /** * Returns result count for * {@link #getEncountersByVisitsAndPatient(Patient, boolean, String, Integer, Integer)}. * * @param patient * @param includeVoided * @param query * @return number of results * @throws APIException * @since 1.9 */ @Authorized( { PrivilegeConstants.GET_VISITS }) public Integer getEncountersByVisitsAndPatientCount(Patient patient, boolean includeVoided, String query) throws APIException; /** * Filters out all encounters to which given user does not have access. If user is not specified * then implementations should treat authenticated user from context as given user by default * * @param encounters the list of encounters to be filtered * @param user the user instance to filter "visible" encounters for * @return list, that does not include encounters, which can not be shown to given user due to * permissions check * @should filter encounters if user is not allowed to see some encounters * @should not filter all encounters when the encounter type's view privilege column is null */ @Authorized( { PrivilegeConstants.GET_ENCOUNTERS }) public List<Encounter> filterEncountersByViewPermissions(List<Encounter> encounters, User user); /** * Determines whether given user is granted to view all encounter types or not * * @param subject the user whose permission to view all encounter types will be checked * @return true if user has access to view all types of encounters * @should return true if user is granted to view all encounters * @should return true when the encounter type's view privilege column is null */ public boolean canViewAllEncounterTypes(User subject); /** * Determines whether given user is granted to edit all encounter types or not * * @param subject the user whose permission to edit all encounter types will be checked * @return true if user has access to edit all types of encounters * @should return true if user is granted to edit all encounters * @should return true when the encounter type's edit privilege column is null */ public boolean canEditAllEncounterTypes(User subject); /** * Checks if passed in user can edit given encounter. If user is not specified, then * authenticated user will be taken by default * * @param encounter the encounter instance to be checked * @param subject the user, who requests edit access * @return true if user has privilege denoted by <em>editPrivilege</em> given on encounter type * @should return true if user can edit encounter * @should return false if user can not edit encounter * @should fail if encounter is null */ public boolean canEditEncounter(Encounter encounter, User subject); /** * Checks if passed in user can view given encounter. If user is not specified, then * authenticated user will be taken by default * * @param encounter the encounter instance to be checked * @param subject the user, who requests view access * @return true if user has privilege denoted by <em>viewPrivilege</em> given on encounter type * @should return true if user can view encounter * @should return false if user can not view encounter * @should fail if encounter is null */ public boolean canViewEncounter(Encounter encounter, User subject); /** * Check if the encounter types are locked, and if so, throw exception during manipulation of * encounter type * * @throws EncounterTypeLockedException */ public void checkIfEncounterTypesAreLocked() throws EncounterTypeLockedException; /** * Get EncounterRoles by name * * @param name * @return List of EncounterRole objects * @since 1.11 * @should find encounter roles based on their name */ @Authorized( { PrivilegeConstants.GET_ENCOUNTER_ROLES }) public List<EncounterRole> getEncounterRolesByName(String name); /** *Transfer encounter to another patient * * @param encounter * @param patient * @return transferred encounter * @since 1.12 * * @should transfer an encounter with observations but not orders to given patient * @should void given encounter * @should void given encounter visit if given encounter is the only encounter */ @Authorized( { PrivilegeConstants.EDIT_ENCOUNTERS }) public Encounter transferEncounter(Encounter encounter, Patient patient); }