/** * 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.Set; import org.openmrs.Concept; import org.openmrs.Location; import org.openmrs.Patient; import org.openmrs.PatientIdentifier; import org.openmrs.PatientIdentifierType; import org.openmrs.Person; import org.openmrs.activelist.Allergy; import org.openmrs.activelist.Problem; import org.openmrs.annotation.Authorized; import org.openmrs.api.db.PatientDAO; import org.openmrs.patient.IdentifierValidator; import org.openmrs.util.PrivilegeConstants; import org.openmrs.validator.PatientIdentifierValidator; import org.springframework.transaction.annotation.Transactional; /** * Contains methods pertaining to Patients in the system Use:<br/> * * <pre> * * List<Patient> patients = Context.getPatientService().getAllPatients(); * </pre> * * @see org.openmrs.api.context.Context * @see org.openmrs.Patient */ @Transactional public interface PatientService extends OpenmrsService { /** * Sets the DAO for this service. This is done by DI and Spring. See the * applicationContext-service.xml definition file. * * @param dao DAO for this service */ public void setPatientDAO(PatientDAO dao); /** * @see #savePatient(Patient) * @deprecated replaced by #savePatient(Patient) */ @Deprecated @Authorized( { PrivilegeConstants.ADD_PATIENTS }) public Patient createPatient(Patient patient) throws APIException; /** * Saved the given <code>patient</code> to the database * * @param patient patient to be created or updated * @return patient who was created or updated * @throws APIException * @should create new patient from existing person plus user object * @should not throw a NonUniqueObjectException when called with a hand constructed patient * regression 1375 * @should fail when patient does not have any patient identifiers * @should update an existing patient * @should fail when patient does not have required patient identifiers * @should update the date changed and changed by on update of the person address */ @Authorized( { PrivilegeConstants.ADD_PATIENTS, PrivilegeConstants.EDIT_PATIENTS }) public Patient savePatient(Patient patient) throws APIException; /** * Get patient by internal identifier * * @param patientId internal patient identifier * @return patient with given internal identifier * @throws APIException * @should return null object if patient id doesnt exist * @should fetch patient with given patient id * @should return null when patient with given patient id does not exist */ @Authorized( { PrivilegeConstants.VIEW_PATIENTS }) @Transactional(readOnly = true) public Patient getPatient(Integer patientId) throws APIException; /** * Get patient by universally unique identifier. * * @param uuid universally unique identifier * @return the patient that matches the uuid * @throws APIException * @should fetch patient with given uuid * @should return null if patient not found with given uuid */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENTS }) public Patient getPatientByUuid(String uuid) throws APIException; /** * Get patient identifier by universally unique identifier. * * @param uuid universally unique identifier * @return the patient identifier that matches the uuid * @throws APIException * @should fetch patient identifier with given uuid * @should return null if patient identifier not found with given uuid */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENT_IDENTIFIERS }) public PatientIdentifier getPatientIdentifierByUuid(String uuid) throws APIException; /** * @see #savePatient(Patient) * @deprecated replaced by #savePatient(Patient) */ @Deprecated public Patient updatePatient(Patient patient) throws APIException; /** * Returns all non voided patients in the system * * @return non voided patients in the system * @see #getAllPatients(boolean) * @throws APIException * @should fetch all non voided patients */ @Authorized( { PrivilegeConstants.VIEW_PATIENTS }) @Transactional(readOnly = true) public List<Patient> getAllPatients() throws APIException; /** * Returns patients in the system * * @param includeVoided if false, will limit the search to non-voided patients * @return patients in the system * @throws APIException * @should fetch voided patients when given include voided is true * @should fetch non voided patients when given include voided is false */ @Authorized( { PrivilegeConstants.VIEW_PATIENTS }) @Transactional(readOnly = true) public List<Patient> getAllPatients(boolean includeVoided) throws APIException; /** * @deprecated use #getPatientByIdentifier(String) instead */ @Deprecated @Transactional(readOnly = true) public Patient identifierInUse(String identifier, PatientIdentifierType type, Patient ignorePatient); /** * @deprecated replaced by {@link #getPatients(String, String, List)} */ @Deprecated @Transactional(readOnly = true) public List<Patient> getPatientsByIdentifier(String identifier, boolean includeVoided) throws APIException; /** * Get patients based on given criteria The identifier is matched with the regex * <code>OpenmrsConstants.PATIENT_IDENTIFIER_REGEX</code> All parameters are optional and * nullable. If null, it is not included in the search. Will not return voided patients * * @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 * @param identifierTypes (optional) the PatientIdentifierTypes to restrict to * @param matchIdentifierExactly (required) if true, then the given <code>identifier</code> must * equal the id in the database. if false, then the identifier is 'searched' for by * using a regular expression * @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 when match identifier * exactly equals false * @should fetch all patients that exactly match given identifier when match identifier exactly * equals true * @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 */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENTS }) public List<Patient> getPatients(String name, String identifier, List<PatientIdentifierType> identifierTypes, boolean matchIdentifierExactly) throws APIException; /** * @deprecated replaced by a call to {@link #getPatients(String, String, List, boolean)} with * "false" as the last parameter */ @Deprecated @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENTS }) public List<Patient> getPatients(String name, String identifier, List<PatientIdentifierType> identifierTypes) throws APIException; /** * @deprecated replaced by getPatients( ... ) */ @Deprecated @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENTS }) public List<Patient> getPatientsByIdentifierPattern(String identifier, boolean includeVoided) throws APIException; /** * @deprecated replaced by {@link #getPatients(String, String, List)} */ @Deprecated @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENTS }) public List<Patient> getPatientsByName(String name) throws APIException; /** * @deprecated replaced by getPatients( ... ) */ @Deprecated @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENTS }) public List<Patient> getPatientsByName(String name, boolean includeVoided) throws APIException; /** * Void patient record (functionally delete patient from system) * * @param patient patient to be voided * @param reason reason for voiding patient * @return the voided patient * @should void given patient with given reason * @should void all patient identifiers associated with given patient * @should return voided patient with given reason * @should return null when patient is null */ @Authorized( { PrivilegeConstants.DELETE_PATIENTS }) public Patient voidPatient(Patient patient, String reason) throws APIException; /** * Unvoid patient record * * @param patient patient to be revived * @return the revived Patient * @should unvoid given patient * @should return unvoided patient */ @Authorized( { PrivilegeConstants.DELETE_PATIENTS }) public Patient unvoidPatient(Patient patient) throws APIException; /** * @see #purgePatient(Patient) * @deprecated replaced by {@link #purgePatient(Patient)} */ @Deprecated @Authorized( { PrivilegeConstants.PURGE_PATIENTS }) public void deletePatient(Patient patient) throws APIException; /** * Delete patient from database. This <b>should not be called</b> except for testing and * administration purposes. Use the void method instead. * * @param patient patient to be deleted * @throws APIException * @see #voidPatient(org.openmrs.Patient,java.lang.String) * @should delete patient from database */ @Authorized( { PrivilegeConstants.PURGE_PATIENTS }) public void purgePatient(Patient patient) throws APIException; /** * @deprecated replaced by {@link #getPatientIdentifiers(String, List, List, List, Boolean)} */ @Deprecated @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENT_IDENTIFIERS }) public List<PatientIdentifier> getPatientIdentifiers(PatientIdentifierType patientIdentifierType) throws APIException; /** * Get all patientIdentifiers that match all of the given criteria Voided identifiers are not * returned * * @param identifier the full identifier to match on * @param patientIdentifierTypes the type of identifiers to get * @param locations the locations of the identifiers to match * @param patients the patients containing these identifiers * @param isPreferred if true, limits to only preferred identifiers if false, only non * preferred. if null, ignores preferred status * @return PatientIdentifiers matching these criteria * @should return only non voided patients and patient identifiers * @throws APIException * @should fetch patient identifiers that exactly matches given identifier * @should fetch patient identifiers that partially matches given identifier * @should fetch patient identifiers that match given patient identifier types * @should fetch patient identifiers that match given locations * @should fetch patient identifiers that match given patients * @should fetch preferred patient identifiers when given is preferred equals true * @should fetch non preferred patient identifiers when given is preferred equals false * @should fetch preferred and non preferred patient identifiers when given is preferred is null */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENT_IDENTIFIERS }) public List<PatientIdentifier> getPatientIdentifiers(String identifier, List<PatientIdentifierType> patientIdentifierTypes, List<Location> locations, List<Patient> patients, Boolean isPreferred) throws APIException; /** * @deprecated replaced by {@link #getPatientIdentifiers(String, List, List, List, Boolean)} */ @Deprecated @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENT_IDENTIFIERS }) public List<PatientIdentifier> getPatientIdentifiers(String identifier, PatientIdentifierType pit) throws APIException; /** * Update patient identifier * * @param patientIdentifier identifier to be updated * @deprecated patient identifiers should not be updated directly; rather, after changing * patient identifiers, use {@link #savePatient(Patient)} to save changes to the * database * @throws APIException */ @Deprecated @Authorized( { PrivilegeConstants.EDIT_PATIENT_IDENTIFIERS }) public void updatePatientIdentifier(PatientIdentifier patientIdentifier) throws APIException; /** * Create or update a PatientIdentifierType * * @param patientIdentifierType PatientIdentifierType to create or update * @return the saved type * @throws APIException * @should create new patient identifier type * @should update existing patient identifier type */ @Authorized( { PrivilegeConstants.MANAGE_IDENTIFIER_TYPES }) public PatientIdentifierType savePatientIdentifierType(PatientIdentifierType patientIdentifierType) throws APIException; /** * @see #getAllPatientIdentifierTypes() * @deprecated replaced by {@link #getAllPatientIdentifierTypes()} */ @Deprecated @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_IDENTIFIER_TYPES }) public List<PatientIdentifierType> getPatientIdentifierTypes() throws APIException; /** * Get all patientIdentifier types * * @return patientIdentifier types list * @throws APIException * @should fetch all non retired patient identifier types */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_IDENTIFIER_TYPES }) public List<PatientIdentifierType> getAllPatientIdentifierTypes() throws APIException; /** * Get all patientIdentifier types * * @param includeRetired true/false whether retired types should be included * @return patientIdentifier types list * @throws APIException * @should fetch patient identifier types including retired when include retired is true * @should fetch patient identifier types excluding retired when include retired is false */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_IDENTIFIER_TYPES }) public List<PatientIdentifierType> getAllPatientIdentifierTypes(boolean includeRetired) throws APIException; /** * Get all patientIdentifier types that match the given criteria * * @param name name of the type to match on * @param format the string format to match on * @param required if true, limits to only identifiers marked as required if false, only non * required. if null, ignores required bit * @param hasCheckDigit if true, limits to only check digit'd identifiers if false, only non * checkdigit'd. if null, ignores checkDigit * @return patientIdentifier types list * @throws APIException * @should fetch patient identifier types that match given name with given format * @should fetch required patient identifier types when given required is true * @should fetch non required patient identifier types when given required is false * @should fetch any patient identifier types when given required is null * @should fetch patient identifier types with check digit when given has check digit is true * @should fetch patient identifier types without check digit when given has check digit is * false * @should fetch any patient identifier types when given has check digit is null */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_IDENTIFIER_TYPES }) public List<PatientIdentifierType> getPatientIdentifierTypes(String name, String format, Boolean required, Boolean hasCheckDigit) throws APIException; /** * Get patientIdentifierType by internal identifier * * @param patientIdentifierTypeId * @return patientIdentifierType with specified internal identifier * @throws APIException * @should fetch patient identifier with given patient identifier type id * @should return null when patient identifier identifier does not exist */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_IDENTIFIER_TYPES }) public PatientIdentifierType getPatientIdentifierType(Integer patientIdentifierTypeId) throws APIException; /** * Get patient identifierType by universally unique identifier * * @param patientIdentifierTypeId * @return patientIdentifierType with specified internal identifier * @throws APIException * @should fetch patient identifier type with given uuid * @should return null when patient identifier type with given uuid does not exist */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_IDENTIFIER_TYPES }) public PatientIdentifierType getPatientIdentifierTypeByUuid(String uuid) throws APIException; /** * @deprecated use {@link #getPatientIdentifierTypeByName(String)} */ @Deprecated @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_IDENTIFIER_TYPES }) public PatientIdentifierType getPatientIdentifierType(String name) throws APIException; /** * Get patientIdentifierType by exact name * * @param name * @return patientIdentifierType with given name * @throws APIException * @should fetch patient identifier type that exactly matches given name * @should not return patient identifier type that partially matches given name * @should return null when patient identifier type with given name does not exist */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_IDENTIFIER_TYPES }) public PatientIdentifierType getPatientIdentifierTypeByName(String name) throws APIException; /** * Retire a type of patient identifier * * @param patientIdentifierType type of patient identifier to be retired * @param reason the reason to retire this identifier type * @return the retired type * @throws APIException * @should retire patient identifier type with given reason * @should throw error when reason is empty */ @Authorized( { PrivilegeConstants.MANAGE_IDENTIFIER_TYPES }) public PatientIdentifierType retirePatientIdentifierType(PatientIdentifierType patientIdentifierType, String reason) throws APIException; /** * Unretire a type of patient identifier * * @param patientIdentifierType type of patient identifier to be unretired * @return the unretired type * @throws APIException * @should untire patient identifier type * @should return unretired patient identifier type */ @Authorized( { PrivilegeConstants.MANAGE_IDENTIFIER_TYPES }) public PatientIdentifierType unretirePatientIdentifierType(PatientIdentifierType patientIdentifierType) throws APIException; /** * Purge PatientIdentifierType (cannot be undone) * * @param patientIdentifierType PatientIdentifierType to purge from the database * @throws APIException * @should delete type from database * @should delete patient identifier type from database */ @Authorized( { PrivilegeConstants.PURGE_IDENTIFIER_TYPES }) public void purgePatientIdentifierType(PatientIdentifierType patientIdentifierType) throws APIException; /** * Convenience method to validate a patient identifier. Checks for things like blank * identifiers, invalid check digits, etc * * @param patientIdentifier identifier to be validated * @see #checkPatientIdentifiers(Patient) * @throws PatientIdentifierException if the identifier is invalid * @deprecated use {@link PatientIdentifierValidator#validateIdentifier(PatientIdentifier)} */ @Deprecated @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENT_IDENTIFIERS }) public void checkPatientIdentifier(PatientIdentifier patientIdentifier) throws PatientIdentifierException; /** * Convenience method to validate all identifiers for a given patient * * @param patient patient for which to validate identifiers * @see #checkPatientIdentifiers(Patient) * @throws PatientIdentifierException if one or more of the identifiers are invalid * @should validate when patient has all required and no duplicate and no blank patient * identifiers * @should ignore voided patient identifier * @should remove identifier and throw error when patient has blank patient identifier * @should throw error when patient has null patient identifiers * @should throw error when patient has empty patient identifiers * @should throw error when patient has identical identifiers * @should throw error when patient does not have one or more required identifiers * @should require one non voided patient identifier */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENT_IDENTIFIERS }) public void checkPatientIdentifiers(Patient patient) throws PatientIdentifierException; /** * @see #getPatients(String) * @deprecated use #getPatients(String) */ @Deprecated @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENTS }) public List<Patient> findPatients(String query, boolean includeVoided) throws APIException; /** * Generic search on patients based on the given string. Implementations can use this string to * search on name, identifier, etc Voided patients are not returned in search results * * @param query the string to search on * @return a list of matching Patients * @should force search string to be greater than minsearchcharacters global property * @should allow search string to be one according to minsearchcharacters global property * @should fetch patients with patient identifiers matching given query * @should fetch patients with any name matching given query * @should return empty list if given query length less than minimum search characters * @should not fail when minimum search characters is null * @should not fail when minimum search characters is invalid integer */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENTS }) public List<Patient> getPatients(String query) throws APIException; /** * Generic search on patients based on the given string and returns a specific number of them * from the specified starting position. Implementations can use this string to search on name, * identifier, etc Voided patients are not returned in search results If start is 0 and length * is not specified, then all matches are returned * * @param query the string to search on * @param start the starting index * @param length the number of patients to return * @return a list of matching Patients * @throws APIException * @since 1.8 */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENTS }) public List<Patient> getPatients(String query, Integer start, Integer length) throws APIException; /** * @see #getPatientByExample(Patient) * @deprecated use #getPatientByExample(Patient) */ @Deprecated @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENTS }) public Patient findPatient(Patient patientToMatch) throws APIException; /** * This method tries to find a patient in the database given the attributes on the given * <code>patientToMatch</code> object. Assumes there could be a PersonAttribute on this Patient * with PersonAttributeType.name = "Other Matching Information". This PersonAttribute has a * "value" that is just key value pairs in the form of key:value;nextkey:nextvalue; * * @param patientToMatch * @return null if no match found, a fresh patient object from the db if is found * @should fetch patient matching patient id of given patient * @should not fetch patient matching any other patient information * @should return null when no patient matches given patient to match */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENTS }) public Patient getPatientByExample(Patient patientToMatch) throws APIException; /** * @deprecated use {@link #getDuplicatePatientsByAttributes(List)} * @see #getDuplicatePatientsByAttributes(List) */ @Deprecated @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENTS }) public List<Patient> findDuplicatePatients(Set<String> attributes) throws APIException; /** * Search the database for patients that both share the given attributes. Each attribute that is * passed in must be identical to what is stored for at least one other patient for both * patients to be returned. * * @param attributes attributes on a Person or Patient object. similar to: [gender, givenName, * middleName, familyName] * @return list of patients that match other patients * @throws APIException * @should fetch patients that exactly match on all given attributes * @should not return patients that exactly match on some but not all given attributes */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENTS }) public List<Patient> getDuplicatePatientsByAttributes(List<String> attributes) throws APIException; /** * Convenience method to join two patients' information into one record. * <ol> * <li>Moves object (encounters/obs) pointing to <code>nonPreferred</code> to point at * <code>preferred</code></li> * <li>Copies data (gender/birthdate/names/ids/etc) from <code>nonPreferred</code> to * <code>preferred</code> IFF the data is missing or null in <code>preferred</code></li> * <li><code>notPreferred</code> is marked as voided</li> * </ol> * * @param preferred The Patient to merge to * @param notPreferred The Patient to merge from (and then void) * @throws APIException * @should not merge the same patient to itself * @should copy nonvoided names to preferred patient * @should copy nonvoided identifiers to preferred patient * @should copy nonvoided addresses to preferred patient * @should not copy over relationships that are only between the preferred and notpreferred * patient * @should not merge patient with itself * @should not create duplicate relationships * @should merge non voided encounters from non preferred to preferred patient * @should merge non duplicate patient identifiers from non preferred to preferred patient * @should merge non duplicate patient names from non preferred to preferred patient * @should merge non duplicate addresses from non preferred to preferred patient * @should merge non voided patient programs from non preferred to preferred patient * @should merge non voided relationships from non preferred to preferred patient * @should merge observations associated with encounters from non preferred to preferred patient * @should merge non voided person attributes from non preferred to preferred patient * @should merge other non voided observations from non preferred to preferred patient * @should merge other non voided orders from non preferred to preferred patient * @should merge non preferred death date when preferred death date is not null or empty * @should merge non preferred death cause when preferred death cause is not null or empty * @should void non preferred person object * @should change user records of non preferred person to preferred person * @should void non preferred patient * @should void all relationships for non preferred patient * @should not void relationships for same type and side with different relatives */ @Authorized( { PrivilegeConstants.EDIT_PATIENTS }) public void mergePatients(Patient preferred, Patient notPreferred) throws APIException; /** * Convenience method to join multiple patients' information into one record. * * @param preferred * @param notPreferred * @throws APIException * @should merge all non Preferred patients in the the notPreferred list to preferred patient */ public void mergePatients(Patient preferred, List<Patient> notPreferred) throws APIException; /** * Convenience method to establish that a patient has left the care center. This API call is * responsible for: 1) Closing workflow statuses 2) Terminating programs 3) Discontinuing orders * 4) Flagging patient table (if applicable) 5) Creating any relevant observations about the * patient TODO keep this in the PatientService? Or move to appropriate service? * * @param patient - the patient who has exited care * @param dateExited - the declared date/time of the patient's exit * @param reasonForExit - the concept that corresponds with why the patient has been declared as * exited * @throws APIException * @should save reason for exit observation for given patient * @should set death date and cause when given reason for exit equals death * @should discontinue all orders associated with given patient * @should terminate all program workflows associated with given paitent * @should throw error when given patient is null * @should throw error when given date exited is null * @should throw error when given reason for exist is null * @should be tested more thoroughly */ @Authorized( { PrivilegeConstants.EDIT_PATIENTS }) public void exitFromCare(Patient patient, Date dateExited, Concept reasonForExit) throws APIException; /** * Convenience method to establish that a patient has died. In addition to exiting the patient * from care (see above), this method will also set the appropriate patient characteristics to * indicate that they have died, when they died, etc. TODO Keep this in the PatientService? Or * move to appropriate service * * @param patient - the patient who has died * @param dateDied - the declared date/time of the patient's death * @param causeOfDeath - the concept that corresponds with the reason the patient died * @param otherReason - if the concept representing the reason is OTHER NON-CODED, and a * string-based "other" reason is supplied * @throws APIException * @should be tested more thoroughly */ @Authorized( { PrivilegeConstants.EDIT_PATIENTS }) public void processDeath(Patient patient, Date dateDied, Concept causeOfDeath, String otherReason) throws APIException; /** * Convenience method that saves the Obs that indicates when and why the patient died (including * any "other" reason there might be) TODO keep this in the PatientService? * * @param patient - the patient who has died * @param dateDied - the declared date/time of the patient's death * @param causeOfDeath - the concept that corresponds with the reason the patient died * @param otherReason - if the concept representing the reason is OTHER NON-CODED, and a * string-based "other" reason is supplied * @throws APIException * @should throw error when given patient is null * @should throw error when given death date is null * @should throw error when given cause is null is null * @should throw error when cause of death global property is not specified * @should throw error when patient already has more than one cause of death observations * @should modify existing cause of death observation * @should set death attributes as long as patient is not already dead * @should be tested more thoroughly */ @Authorized(value = { PrivilegeConstants.VIEW_PATIENTS, PrivilegeConstants.EDIT_OBS }, requireAll = true) public void saveCauseOfDeathObs(Patient patient, Date dateDied, Concept causeOfDeath, String otherReason) throws APIException; /** * Gets an identifier validator matching the given class. * * @param clazz identifierValidator which validator to get. * @should return patient identifier validator given class */ @Transactional(readOnly = true) public IdentifierValidator getIdentifierValidator(Class<IdentifierValidator> clazz); /** * @should return patient identifier validator given class name * @should treat empty strings like a null entry */ @Transactional(readOnly = true) public IdentifierValidator getIdentifierValidator(String pivClassName); /** * @return the default IdentifierValidator * @should return default patient identifier validator */ @Transactional(readOnly = true) public IdentifierValidator getDefaultIdentifierValidator(); /** * @return All registered PatientIdentifierValidators * @should return all registered patient identifier validators */ @Transactional(readOnly = true) public Collection<IdentifierValidator> getAllIdentifierValidators(); /** * Checks whether the given patient identifier is already assigned to a patient other than * patientIdentifier.patient * * @param patientIdentifier the patient identifier to look for in other patients * @return whether or not the identifier is in use by a patient other than * patientIdentifier.patient * @should return true when patientIdentifier contains a patient and another patient has this id * @should return false when patientIdentifier contains a patient and no other patient has this * id * @should return true when patientIdentifier does not contain a patient and a patient has this * id * @should return false when patientIdentifier does not contain a patient and no patient has * this id * @should ignore voided patientIdentifiers * @should ignore voided patients */ @Authorized(PrivilegeConstants.VIEW_PATIENTS) @Transactional(readOnly = true) public boolean isIdentifierInUseByAnotherPatient(PatientIdentifier patientIdentifier); /** * Returns a patient identifier that matches the given patientIndentifier id * * @param patientIdentifier the patientIdentifier id * @return the patientIdentifier matching the Id * @throws APIException * @should return the patientIdentifier with the given id */ @Authorized( { PrivilegeConstants.VIEW_PATIENT_IDENTIFIERS }) @Transactional(readOnly = true) public PatientIdentifier getPatientIdentifier(Integer patientIdentifierId) throws APIException; /** * Void patient identifier (functionally delete patient identifier from system) * * @param patient patientIdentifier to be voided * @param reason reason for voiding patient identifier * @return the voided patient identifier * @throws APIException * @should void given patient identifier with given reaso * @should throw an APIException if the reason is null * @should throw an APIException if the reason is an empty string * @should throw an APIException if the reason is a white space character */ @Authorized( { PrivilegeConstants.DELETE_PATIENT_IDENTIFIERS }) public PatientIdentifier voidPatientIdentifier(PatientIdentifier patientIdentifier, String reason) throws APIException; /** * Saved the given <code>patientIndentifier</code> to the database * * @param patientIndentifier patientIndentifier to be created or updated * @return patientIndentifier that was created or updated * @throws APIException * @should create new patientIndentifier * @should update an existing patient identifier * @should throw an APIException when a null argument is passed * @should throw an APIException when one of the required fields is null * @should throw an APIException if the patientIdentifier string is a white space * @should throw an APIException if the patientIdentifier string is an empty string */ @Authorized( { PrivilegeConstants.ADD_PATIENT_IDENTIFIERS, PrivilegeConstants.EDIT_PATIENT_IDENTIFIERS }) public PatientIdentifier savePatientIdentifier(PatientIdentifier patientIdentifier) throws APIException; /** * Purge PatientIdentifier (cannot be undone) * * @param patientIdentifier PatientIdentifier to purge from the database * @throws APIException * @should delete patient identifier from database */ @Authorized( { PrivilegeConstants.PURGE_PATIENT_IDENTIFIERS }) public void purgePatientIdentifier(PatientIdentifier patientIdentifier) throws APIException; /** * Get a list of the problems for the patient, sorted on sort_weight * * @param p the Person * @return sorted set based on the sort weight of the list items * @throws APIException * @should return empty list if no problems exist for this Patient */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PROBLEMS }) public List<Problem> getProblems(Person p) throws APIException; /** * Returns the Problem * * @param problemListId * @return the allergy * @throws APIException */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PROBLEMS }) public Problem getProblem(Integer problemListId) throws APIException; /** * Creates a ProblemListItem to the Patient's Problem Active List. Sets the start date to now, * if it is null. Sets the weight * * @param problem the Problem * @throws APIException * @should save the problem and set the weight for correct ordering */ @Authorized( { PrivilegeConstants.ADD_PROBLEMS, PrivilegeConstants.EDIT_PROBLEMS }) public void saveProblem(Problem problem) throws APIException; /** * Effectively removes the Problem from the Patient's Active List by setting the stop date to * now, if null. * * @param problem the Problem * @param reason the reason of removing the problem * @throws APIException * @should set the end date for the problem */ @Authorized( { PrivilegeConstants.EDIT_PROBLEMS }) public void removeProblem(Problem problem, String reason) throws APIException; /** * Used only in cases where the Problem was entered by error * * @param problem * @param reason * @throws APIException */ @Authorized( { PrivilegeConstants.DELETE_PROBLEMS }) public void voidProblem(Problem problem, String reason) throws APIException; /** * Returns a sorted set of Allergies, sorted on sort_weight * * @param p the Person * @return sorted set based on the sort weight of the list items * @throws APIException * @should return empty list if no allergies exist for the Patient */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_ALLERGIES }) public List<Allergy> getAllergies(Person p) throws APIException; /** * Returns the Allergy * * @param allergyListId * @return the allergy * @throws APIException */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_ALLERGIES }) public Allergy getAllergy(Integer allergyListId) throws APIException; /** * Creates an AllergyListItem to the Patient's Allergy Active List. Sets the start date to now, * if it is null. * * @param allergy the Allergy * @throws APIException * @should save the allergy */ @Authorized( { PrivilegeConstants.ADD_ALLERGIES, PrivilegeConstants.EDIT_ALLERGIES }) public void saveAllergy(Allergy allergy) throws APIException; /** * Resolving the allergy, effectively removes the Allergy from the Patient's Active List by * setting the stop date to now, if null. * * @param allergy the Allergy * @param reason the reason of remove * @throws APIException * @should set the end date for the allergy */ @Authorized( { PrivilegeConstants.EDIT_ALLERGIES }) public void removeAllergy(Allergy allergy, String reason) throws APIException; /** * Used only in cases where the Allergy was entered by error * * @param allergy * @param reason * @throws APIException */ @Authorized( { PrivilegeConstants.DELETE_ALLERGIES }) public void voidAllergy(Allergy allergy, String reason) throws APIException; /** * Return the number of unvoided patients with names or patient identifiers starting with or * equal to the specified text * * @param query the string to search on * @return the number of patients matching the given search phrase * @since 1.8 * @should return the right count when a patient has multiple matching person names */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENTS }) public Long getCountOfPatients(String query); /** * Get a limited size of patients from a given start index based on given criteria The * identifier is matched with the regex <code>OpenmrsConstants.PATIENT_IDENTIFIER_REGEX</code> * All parameters are optional and nullable. If null, it is not included in the search. Will not * return voided patients * * @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 * @param identifierTypes (optional) the PatientIdentifierTypes to restrict to * @param matchIdentifierExactly (required) if true, then the given <code>identifier</code> must * equal the id in the database. if false, then the identifier is 'searched' for by * using a regular expression * @param start the starting index * @param length the number of patients to return * @return patients that matched the given criteria (and are not voided) * @throws APIException * @since 1.8 */ @Transactional(readOnly = true) @Authorized( { PrivilegeConstants.VIEW_PATIENTS }) public List<Patient> getPatients(String name, String identifier, List<PatientIdentifierType> identifierTypes, boolean matchIdentifierExactly, Integer start, Integer length) throws APIException; }