Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FM2-608: Add EpisodeOfCare FHIR2 Module with Mapping of Patient Program #536

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.fhir2.api;

import javax.annotation.Nonnull;

import org.hl7.fhir.r4.model.EpisodeOfCare;

public interface FhirEpisodeOfCareService extends FhirService<EpisodeOfCare> {

@Override
EpisodeOfCare get(@Nonnull String uuid);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.fhir2.api.dao;

import javax.annotation.Nonnull;

import org.openmrs.PatientProgram;
import org.openmrs.annotation.Authorized;
import org.openmrs.util.PrivilegeConstants;

public interface FhirEpisodeOfCareDao extends FhirDao<PatientProgram> {

@Override
@Authorized(PrivilegeConstants.GET_PATIENT_PROGRAMS)
PatientProgram get(@Nonnull String uuid);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.fhir2.api.dao.impl;

import lombok.AccessLevel;
import lombok.Setter;
import org.openmrs.PatientProgram;
import org.openmrs.module.fhir2.api.dao.FhirEpisodeOfCareDao;
import org.springframework.stereotype.Component;

@Component
@Setter(AccessLevel.PACKAGE)
public class FhirEpisodeOfCareDaoImpl extends BaseFhirDao<PatientProgram> implements FhirEpisodeOfCareDao {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.fhir2.api.impl;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import org.hl7.fhir.r4.model.EpisodeOfCare;
import org.openmrs.PatientProgram;
import org.openmrs.module.fhir2.api.FhirEpisodeOfCareService;
import org.openmrs.module.fhir2.api.dao.FhirEpisodeOfCareDao;
import org.openmrs.module.fhir2.api.translators.EpisodeOfCareTranslator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Component
@Transactional
@Setter(AccessLevel.PACKAGE)
@Getter(AccessLevel.PROTECTED)
public class FhirEpisodeOfCareServiceImpl extends BaseFhirService<EpisodeOfCare, PatientProgram> implements FhirEpisodeOfCareService {

@Autowired
private FhirEpisodeOfCareDao dao;

@Autowired
private EpisodeOfCareTranslator translator;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.fhir2.api.translators;

import javax.annotation.Nonnull;

import org.hl7.fhir.r4.model.EpisodeOfCare;
import org.openmrs.PatientProgram;

public interface EpisodeOfCareTranslator extends OpenmrsFhirUpdatableTranslator<PatientProgram, EpisodeOfCare> {

/**
* Maps a {@link org.openmrs.PatientProgram} to a {@link EpisodeOfCare}
*
* @param patientProgram the PatientProgram to translate
* @return the corresponding FHIR EpisodeOfCare
*/
@Override
EpisodeOfCare toFhirResource(@Nonnull PatientProgram patientProgram);

/**
* Maps a {@link EpisodeOfCare} to a {@link org.openmrs.PatientProgram}
*
* @param episodeOfCare the FHIR EpisodeOfCare to map
* @return the corresponding OpenMRS PatientProgram
*/
@Override
PatientProgram toOpenmrsType(@Nonnull EpisodeOfCare episodeOfCare);

/**
* Maps a {@link EpisodeOfCare} to an existing {@link org.openmrs.PatientProgram}
*
* @param patientProgram the PatientProgram to update
* @param episodeOfCare the FHIR EpisodeOfCare to map
* @return the updated OpenMRS PatientProgram
*/
@Override
PatientProgram toOpenmrsType(@Nonnull PatientProgram patientProgram, @Nonnull EpisodeOfCare episodeOfCare);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.fhir2.api.translators.impl;

import static org.apache.commons.lang3.Validate.notNull;

import javax.annotation.Nonnull;

import java.util.Collections;
import java.util.List;

import lombok.AccessLevel;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.EpisodeOfCare;
import org.hl7.fhir.r4.model.Period;
import org.openmrs.PatientProgram;
import org.openmrs.module.fhir2.api.translators.ConceptTranslator;
import org.openmrs.module.fhir2.api.translators.EpisodeOfCareTranslator;
import org.openmrs.module.fhir2.api.translators.PatientReferenceTranslator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@Setter(AccessLevel.PACKAGE)
public class EpisodeOfCareTranslatorImpl implements EpisodeOfCareTranslator {

@Autowired
private PatientReferenceTranslator patientReferenceTranslator;

@Autowired
private ConceptTranslator conceptTranslator;

@Override
public EpisodeOfCare toFhirResource(@Nonnull PatientProgram patientProgram) {
notNull(patientProgram, "The Openmrs PatientProgram object should not be null");

EpisodeOfCare episodeOfCare = new EpisodeOfCare();

episodeOfCare.setId(patientProgram.getUuid());
episodeOfCare.setPeriod(getPeriod(patientProgram));
episodeOfCare.setPatient(patientReferenceTranslator.toFhirResource(patientProgram.getPatient()));
episodeOfCare.setType(getType(patientProgram));

episodeOfCare.setStatus(getStatus(patientProgram));

return episodeOfCare;
}

@Override
public PatientProgram toOpenmrsType(@Nonnull EpisodeOfCare episodeOfCare) {
notNull(episodeOfCare, "The EpisodeOfCare object should not be null");
return this.toOpenmrsType(new PatientProgram(), episodeOfCare);

Check warning on line 62 in api/src/main/java/org/openmrs/module/fhir2/api/translators/impl/EpisodeOfCareTranslatorImpl.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/openmrs/module/fhir2/api/translators/impl/EpisodeOfCareTranslatorImpl.java#L62

Added line #L62 was not covered by tests
}

@Override
public PatientProgram toOpenmrsType(@Nonnull PatientProgram patientProgram, @Nonnull EpisodeOfCare episodeOfCare) {
throw new UnsupportedOperationException("Translation from FHIR resource EpisodeOfCare to OpenMRS object PatientProgram is not supported.");
}

private List<CodeableConcept> getType(PatientProgram patientProgram) {
if (patientProgram.getProgram() == null) {
return Collections.emptyList();
}

CodeableConcept codeableConcept = conceptTranslator.toFhirResource(patientProgram.getProgram().getConcept());
if (codeableConcept == null) {
return Collections.emptyList();
}
return Collections.singletonList(codeableConcept);
}

private EpisodeOfCare.EpisodeOfCareStatus getStatus(PatientProgram patientProgram) {
if (patientProgram.getActive()) {
return EpisodeOfCare.EpisodeOfCareStatus.ACTIVE;
} else {
return EpisodeOfCare.EpisodeOfCareStatus.FINISHED;
}
}

private Period getPeriod(PatientProgram program) {
Period period = new Period();

period.setStart(program.getDateEnrolled());
period.setEnd(program.getDateCompleted());

return period;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.fhir2.providers.r3;

import static lombok.AccessLevel.PACKAGE;

import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import lombok.Setter;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.dstu3.model.EpisodeOfCare;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.openmrs.module.fhir2.api.FhirEpisodeOfCareService;
import org.openmrs.module.fhir2.api.annotations.R3Provider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component("episodeOfCareFhirR3ResourceProvider")
@R3Provider
@Setter(PACKAGE)
public class EpisodeOfCareFhirResourceProvider implements IResourceProvider {

@Autowired
private FhirEpisodeOfCareService episodeOfCareService;

@Override
public Class<? extends IBaseResource> getResourceType() {
return EpisodeOfCare.class;
}

@Read
public EpisodeOfCare getEpisodeOfCareById(@IdParam IdType id) {
org.hl7.fhir.r4.model.EpisodeOfCare episodeOfCare = episodeOfCareService.get(id.getIdPart());
if (episodeOfCare == null) {
throw new ResourceNotFoundException("Could not find EpisodeOfCare with Id " + id.getIdPart());
}
return (EpisodeOfCare) VersionConvertorFactory_30_40.convertResource(episodeOfCare);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.fhir2.providers.r4;

import static lombok.AccessLevel.PACKAGE;

import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import lombok.Setter;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.EpisodeOfCare;
import org.hl7.fhir.r4.model.IdType;
import org.openmrs.module.fhir2.api.FhirEpisodeOfCareService;
import org.openmrs.module.fhir2.api.annotations.R4Provider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component("episodeOfCareFhirR4ResourceProvider")
@R4Provider
@Setter(PACKAGE)
public class EpisodeOfCareFhirResourceProvider implements IResourceProvider {

@Autowired
private FhirEpisodeOfCareService episodeOfCareService;

@Override
public Class<? extends IBaseResource> getResourceType() {
return EpisodeOfCare.class;
}

@Read
public EpisodeOfCare getEpisodeOfCareById(@IdParam IdType id) {
EpisodeOfCare episodeOfCare = episodeOfCareService.get(id.getIdPart());
if (episodeOfCare == null) {
throw new ResourceNotFoundException("Could not find EpisodeOfCare with Id " + id.getIdPart());
}
return episodeOfCare;
}
}