/** * 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.impl; import static org.openmrs.util.DateUtil.truncateToSeconds; import java.util.Date; import java.util.List; import java.util.stream.Collectors; import org.openmrs.Cohort; import org.openmrs.CohortMembership; import org.openmrs.Patient; import org.openmrs.User; import org.openmrs.api.APIException; import org.openmrs.api.CohortService; import org.openmrs.api.context.Context; import org.openmrs.api.db.CohortDAO; import org.openmrs.util.OpenmrsUtil; import org.openmrs.util.PrivilegeConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.transaction.annotation.Transactional; /** * API functions related to Cohorts */ @Transactional public class CohortServiceImpl extends BaseOpenmrsService implements CohortService { protected final Logger log = LoggerFactory.getLogger(this.getClass()); private CohortDAO dao; /** * @see org.openmrs.api.CohortService#setCohortDAO(org.openmrs.api.db.CohortDAO) */ @Override public void setCohortDAO(CohortDAO dao) { this.dao = dao; } /** * @see org.openmrs.api.CohortService#saveCohort(org.openmrs.Cohort) */ @Override public Cohort saveCohort(Cohort cohort) throws APIException { if (cohort.getCohortId() == null) { Context.requirePrivilege(PrivilegeConstants.ADD_COHORTS); } else { Context.requirePrivilege(PrivilegeConstants.EDIT_COHORTS); } if (cohort.getName() == null) { throw new APIException("Cohort.save.nameRequired", (Object[]) null); } if (cohort.getDescription() == null) { throw new APIException("Cohort.save.descriptionRequired", (Object[]) null); } if (log.isInfoEnabled()) { log.info("Saving cohort " + cohort); } return dao.saveCohort(cohort); } /** * @see org.openmrs.api.CohortService#getCohort(java.lang.Integer) */ @Override @Transactional(readOnly = true) public Cohort getCohort(Integer id) { return dao.getCohort(id); } /** * @see org.openmrs.api.CohortService#voidCohort(org.openmrs.Cohort, java.lang.String) */ @Override public Cohort voidCohort(Cohort cohort, String reason) { // other setters done by the save handlers return Context.getCohortService().saveCohort(cohort); } /** * @see org.openmrs.api.CohortService#getCohortByUuid(java.lang.String) */ @Override @Transactional(readOnly = true) public Cohort getCohortByUuid(String uuid) { return dao.getCohortByUuid(uuid); } /** * @see org.openmrs.api.CohortService#getCohortMembershipByUuid(java.lang.String) */ @Override @Transactional(readOnly = true) public CohortMembership getCohortMembershipByUuid(String uuid) { return dao.getCohortMembershipByUuid(uuid); } /** * @see org.openmrs.api.CohortService#addPatientToCohort(org.openmrs.Cohort, * org.openmrs.Patient) */ @Override public Cohort addPatientToCohort(Cohort cohort, Patient patient) { if (!cohort.contains(patient.getPatientId())) { CohortMembership cohortMembership = new CohortMembership(patient.getPatientId()); cohort.addMembership(cohortMembership); Context.getCohortService().saveCohort(cohort); } return cohort; } /** * @see org.openmrs.api.CohortService#removePatientFromCohort(org.openmrs.Cohort, * org.openmrs.Patient) */ @Override public Cohort removePatientFromCohort(Cohort cohort, Patient patient) { List<CohortMembership> memberships = getCohortMemberships(patient.getPatientId(), null, false); List<CohortMembership> toVoid = memberships.stream() .filter(m -> m.getCohort().equals(cohort)) .collect(Collectors.toList()); for (CohortMembership membership : toVoid) { Context.getCohortService().voidCohortMembership(membership, "removePatientFromCohort"); } return cohort; } @Override @Transactional(readOnly = true) public List<Cohort> getCohortsContainingPatient(Patient patient) { return getCohortsContainingPatientId(patient.getPatientId()); } @Override @Transactional(readOnly = true) public List<Cohort> getCohortsContainingPatientId(Integer patientId) { return dao.getCohortsContainingPatientId(patientId, false, new Date()); } /** * @see org.openmrs.api.CohortService#getCohorts(java.lang.String) */ @Override @Transactional(readOnly = true) public List<Cohort> getCohorts(String nameFragment) throws APIException { return dao.getCohorts(nameFragment); } /** * @see org.openmrs.api.CohortService#getAllCohorts() */ @Override @Transactional(readOnly = true) public List<Cohort> getAllCohorts() throws APIException { return Context.getCohortService().getAllCohorts(false); } /** * @see org.openmrs.api.CohortService#getAllCohorts(boolean) */ @Override @Transactional(readOnly = true) public List<Cohort> getAllCohorts(boolean includeVoided) throws APIException { return dao.getAllCohorts(includeVoided); } /** * @see org.openmrs.api.CohortService#getCohortByName(java.lang.String) */ @Override @Transactional(readOnly = true) public Cohort getCohortByName(String name) throws APIException { return dao.getCohort(name); } /** * @see org.openmrs.api.CohortService#getCohort(java.lang.String) */ @Override @Transactional(readOnly = true) public Cohort getCohort(String name) throws APIException { return getCohortByName(name); } /** * @see org.openmrs.api.CohortService#purgeCohort(org.openmrs.Cohort) */ @Override public Cohort purgeCohort(Cohort cohort) throws APIException { return dao.deleteCohort(cohort); } /** * @see CohortService#purgeCohortMembership(CohortMembership) */ @Override public void purgeCohortMembership(CohortMembership cohortMembership) throws APIException { Cohort cohort = cohortMembership.getCohort(); boolean removed = cohort.removeMembership(cohortMembership); if (removed) { Context.getCohortService().saveCohort(cohort); } } /** * @see CohortService#voidCohortMembership(CohortMembership, String) */ @Override public CohortMembership voidCohortMembership(CohortMembership cohortMembership, String reason) { Context.getCohortService().saveCohort(cohortMembership.getCohort()); return cohortMembership; } /** * @see CohortService#endCohortMembership(CohortMembership, Date) */ @Override public CohortMembership endCohortMembership(CohortMembership cohortMembership, Date onDate) { cohortMembership.setEndDate(onDate == null ? new Date() : onDate); Context.getCohortService().saveCohort(cohortMembership.getCohort()); return cohortMembership; } /** * @see org.openmrs.api.CohortService#notifyPatientVoided(org.openmrs.Patient) */ @Override public void notifyPatientVoided(Patient patient) throws APIException { List<CohortMembership> memberships = Context.getCohortService() .getCohortMemberships(patient.getPatientId(), null, false); memberships.forEach(m -> { m.setVoided(patient.getVoided()); m.setDateVoided(patient.getDateVoided()); m.setVoidedBy(patient.getVoidedBy()); m.setVoidReason(patient.getVoidReason()); dao.saveCohortMembership(m); }); } /** * @see org.openmrs.api.CohortService#notifyPatientUnvoided(Patient, User, Date) */ @Override public void notifyPatientUnvoided(Patient patient, User originallyVoidedBy, Date originalDateVoided) throws APIException { List<CohortMembership> memberships = getCohortMemberships(patient.getPatientId(), null, true); List<CohortMembership> toUnvoid = memberships.stream().filter( m -> m.getVoided() && m.getVoidedBy().equals(originallyVoidedBy) && OpenmrsUtil.compare( truncateToSeconds(m.getDateVoided()), truncateToSeconds(originalDateVoided)) == 0) .collect(Collectors.toList()); for (CohortMembership member : toUnvoid) { member.setVoided(false); member.setDateVoided(null); member.setVoidedBy(null); member.setVoidReason(null); dao.saveCohortMembership(member); } } @Override public List<CohortMembership> getCohortMemberships(Integer patientId, Date activeOnDate, boolean includeVoided) { if (patientId == null) { throw new IllegalArgumentException("patientId is required"); } return dao.getCohortMemberships(patientId, activeOnDate, includeVoided); } }