Skip to content

Commit

Permalink
FM2-421: Fix Immunization requirements
Browse files Browse the repository at this point in the history
  • Loading branch information
ibacher committed Aug 2, 2021
1 parent ccfbefa commit ccce482
Show file tree
Hide file tree
Showing 39 changed files with 431 additions and 148 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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.Reference;
import org.openmrs.Location;

public interface LocationReferenceTranslator extends OpenmrsFhirTranslator<Location, Reference> {

/**
* Maps an {@link Location} to a FHIR reference
*
* @param location the location to translate
* @return the corresponding FHIR reference
*/
@Override
Reference toFhirResource(@Nonnull Location location);

/**
* Maps a FHIR reference to a {@link Location}
*
* @param locationReference the location reference to translate
* @return the corresponding location
*/
@Override
Location toOpenmrsType(@Nonnull Reference locationReference);
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.openmrs.module.fhir2.api.translators.ConceptTranslator;
import org.openmrs.module.fhir2.api.translators.EncounterReferenceTranslator;
import org.openmrs.module.fhir2.api.translators.ImmunizationTranslator;
import org.openmrs.module.fhir2.api.translators.LocationReferenceTranslator;
import org.openmrs.module.fhir2.api.translators.ObservationValueTranslator;
import org.openmrs.module.fhir2.api.translators.PatientReferenceTranslator;
import org.openmrs.module.fhir2.api.translators.PractitionerReferenceTranslator;
Expand Down Expand Up @@ -99,6 +100,9 @@ public class ImmunizationTranslatorImpl implements ImmunizationTranslator {
@Autowired
private ConceptTranslator conceptTranslator;

@Autowired
private LocationReferenceTranslator locationReferenceTranslator;

@Autowired
private PractitionerReferenceTranslator<Provider> practitionerReferenceTranslator;

Expand Down Expand Up @@ -163,6 +167,12 @@ public Obs toOpenmrsType(@Nonnull Obs openmrsImmunization, @Nonnull Immunization
}

Location location = visit.getLocation();
if (fhirImmunization.hasLocation()) {
Location recordedLocation = locationReferenceTranslator.toOpenmrsType(fhirImmunization.getLocation());
if (recordedLocation != null) {
location = recordedLocation;
}
}

if (!patient.equals(visit.getPatient())) {
throw createImmunizationRequestValidationError(
Expand All @@ -177,11 +187,12 @@ public Obs toOpenmrsType(@Nonnull Obs openmrsImmunization, @Nonnull Immunization
.max(Comparator.comparing(Encounter::getEncounterDatetime));

final Provider encounterProvider = provider;
final Location finalLocation = location;
Encounter encounter = existingEncounter.orElseGet(() -> {
final EncounterRole encounterRole = helper.getAdministeringEncounterRole();
final Encounter newEncounter = new Encounter();
newEncounter.setVisit(visit);
newEncounter.setLocation(location);
newEncounter.setLocation(finalLocation);
newEncounter.setEncounterType(encounterType);
newEncounter.setPatient(patient);
if (encounterProvider != null) {
Expand All @@ -202,7 +213,7 @@ public Obs toOpenmrsType(@Nonnull Obs openmrsImmunization, @Nonnull Immunization
openmrsImmunization.setEncounter(encounter);
openmrsImmunization.getGroupMembers().forEach(obs -> {
obs.setPerson(patient);
obs.setLocation(location);
obs.setLocation(finalLocation);
obs.setEncounter(encounter);
});

Expand Down Expand Up @@ -235,6 +246,10 @@ public Obs toOpenmrsType(@Nonnull Obs openmrsImmunization, @Nonnull Immunization
}
}

if (!fhirImmunization.hasOccurrenceDateTimeType() || !fhirImmunization.getOccurrenceDateTimeType().hasValue()) {
throw createImmunizationRequestValidationError("An Immunization must have a valid occurrenceDateTime value");
}

{
Obs obs = members.get(CIEL_1410);
if (obs == null) {
Expand Down Expand Up @@ -282,6 +297,8 @@ public Obs toOpenmrsType(@Nonnull Obs openmrsImmunization, @Nonnull Immunization
}
}
}
} else {
openmrsImmunization.removeGroupMember(members.get(CIEL_1418));
}

if (fhirImmunization.hasManufacturer() && fhirImmunization.getManufacturer().hasDisplay()) {
Expand All @@ -303,6 +320,8 @@ public Obs toOpenmrsType(@Nonnull Obs openmrsImmunization, @Nonnull Immunization
}
}
}
} else {
openmrsImmunization.removeGroupMember(members.get(CIEL_1419));
}

if (fhirImmunization.hasLotNumber()) {
Expand All @@ -324,6 +343,8 @@ public Obs toOpenmrsType(@Nonnull Obs openmrsImmunization, @Nonnull Immunization
}
}
}
} else {
openmrsImmunization.removeGroupMember(members.get(CIEL_1420));
}

if (fhirImmunization.hasExpirationDate()) {
Expand All @@ -345,6 +366,8 @@ public Obs toOpenmrsType(@Nonnull Obs openmrsImmunization, @Nonnull Immunization
}
}
}
} else {
openmrsImmunization.removeGroupMember(members.get(CIEL_165907));
}

return openmrsImmunization;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* 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 javax.annotation.Nonnull;

import lombok.AccessLevel;
import lombok.Setter;
import org.hl7.fhir.r4.model.Reference;
import org.openmrs.Location;
import org.openmrs.module.fhir2.FhirConstants;
import org.openmrs.module.fhir2.api.dao.FhirLocationDao;
import org.openmrs.module.fhir2.api.translators.LocationReferenceTranslator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Setter(AccessLevel.PACKAGE)
public class LocationReferenceTranslatorImpl extends BaseReferenceHandlingTranslator implements LocationReferenceTranslator {

@Autowired
private FhirLocationDao locationDao;

@Override
public Reference toFhirResource(@Nonnull Location location) {
if (location == null || location.getRetired()) {
return null;
}

return createLocationReference(location);
}

@Override
public Location toOpenmrsType(@Nonnull Reference locationReference) {
if (locationReference == null || !locationReference.hasReference()) {
return null;
}

if (getReferenceType(locationReference).map(ref -> !ref.equals(FhirConstants.LOCATION)).orElse(true)) {
throw new IllegalArgumentException(
"Reference must be to a Location not a " + getReferenceType(locationReference).orElse(""));
}

return getReferenceId(locationReference).map(uuid -> locationDao.get(uuid)).orElse(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public void shouldCreateNewGroupAsXML() throws Exception {
}

// create group
MockHttpServletResponse response = post("/Group").accept(FhirMediaTypes.XML).xmlContext(xmlGroup).go();
MockHttpServletResponse response = post("/Group").accept(FhirMediaTypes.XML).xmlContent(xmlGroup).go();

// verify created correctly
assertThat(response, isCreated());
Expand Down Expand Up @@ -268,7 +268,7 @@ public void shouldUpdateExistingGroupAsXML() throws Exception {
}

//Update
response = put("/Group/" + COHORT_UUID).xmlContext(xmlGroup).accept(FhirMediaTypes.XML).go();
response = put("/Group/" + COHORT_UUID).xmlContent(xmlGroup).accept(FhirMediaTypes.XML).go();

assertThat(response, isOk());
assertThat(response.getContentType(), is(FhirMediaTypes.XML.toString()));
Expand Down Expand Up @@ -302,7 +302,7 @@ public void shouldReturnBadRequestWhenDocumentIdDoesNotMatchGroupIdAsXML() throw
group.setId(BAD_COHORT_UUID);

// send the update to the server
response = put("/Group/" + COHORT_UUID).xmlContext(toXML(group)).accept(FhirMediaTypes.XML).go();
response = put("/Group/" + COHORT_UUID).xmlContent(toXML(group)).accept(FhirMediaTypes.XML).go();

assertThat(response, isBadRequest());
assertThat(response.getContentType(), is(FhirMediaTypes.XML.toString()));
Expand All @@ -324,7 +324,7 @@ public void shouldReturnNotFoundWhenUpdatingNonExistentGroupAsXML() throws Excep
group.setId(BAD_COHORT_UUID);

// send the update to the server
response = put("/Group/" + BAD_COHORT_UUID).xmlContext(toXML(group)).accept(FhirMediaTypes.XML).go();
response = put("/Group/" + BAD_COHORT_UUID).xmlContent(toXML(group)).accept(FhirMediaTypes.XML).go();

assertThat(response, isNotFound());
assertThat(response.getContentType(), is(FhirMediaTypes.XML.toString()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ public void shouldCreateNewObservationAsXML() throws Exception {
}

// create obs
MockHttpServletResponse response = post("/Observation").accept(FhirMediaTypes.XML).xmlContext(xmlObs).go();
MockHttpServletResponse response = post("/Observation").accept(FhirMediaTypes.XML).xmlContent(xmlObs).go();

// verify created correctly
assertThat(response, isCreated());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ public void shouldCreateNewGroupAsXML() throws Exception {
}

// create group
MockHttpServletResponse response = post("/Group").accept(FhirMediaTypes.XML).xmlContext(xmlGroup).go();
MockHttpServletResponse response = post("/Group").accept(FhirMediaTypes.XML).xmlContent(xmlGroup).go();

// verify created correctly
assertThat(response, isCreated());
Expand Down Expand Up @@ -293,7 +293,7 @@ public void shouldUpdateExistingGroupAsXML() throws Exception {
}

//Update
response = put("/Group/" + GROUP_UUID).xmlContext(xmlGroup).accept(FhirMediaTypes.XML).go();
response = put("/Group/" + GROUP_UUID).xmlContent(xmlGroup).accept(FhirMediaTypes.XML).go();

assertThat(response, isOk());
assertThat(response.getContentType(), is(FhirMediaTypes.XML.toString()));
Expand Down Expand Up @@ -331,7 +331,7 @@ public void shouldReturnBadRequestWhenDocumentIdDoesNotMatchGroupIdAsXML() throw
group.setId(BAD_GROUP_UUID);

// send the update to the server
response = put("/Group/" + GROUP_UUID).xmlContext(toXML(group)).accept(FhirMediaTypes.XML).go();
response = put("/Group/" + GROUP_UUID).xmlContent(toXML(group)).accept(FhirMediaTypes.XML).go();

assertThat(response, isBadRequest());
assertThat(response.getContentType(), is(FhirMediaTypes.XML.toString()));
Expand All @@ -353,7 +353,7 @@ public void shouldReturnNotFoundWhenUpdatingNonExistentGroupAsXML() throws Excep
group.setId(BAD_GROUP_UUID);

// send the update to the server
response = put("/Group/" + BAD_GROUP_UUID).xmlContext(toXML(group)).accept(FhirMediaTypes.XML).go();
response = put("/Group/" + BAD_GROUP_UUID).xmlContent(toXML(group)).accept(FhirMediaTypes.XML).go();

assertThat(response, isNotFound());
assertThat(response.getContentType(), is(FhirMediaTypes.XML.toString()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ public void shouldCreateNewObservationAsXML() throws Exception {
}

// create obs
MockHttpServletResponse response = post("/Observation").accept(FhirMediaTypes.XML).xmlContext(xmlObs).go();
MockHttpServletResponse response = post("/Observation").accept(FhirMediaTypes.XML).xmlContent(xmlObs).go();

// verify created correctly
assertThat(response, isCreated());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ public void shouldCreateNewConditionAsXML() throws Exception {
assertThat(xmlCondition, notNullValue());
}

MockHttpServletResponse response = post("/Condition").accept(FhirMediaTypes.XML).xmlContext(xmlCondition).go();
MockHttpServletResponse response = post("/Condition").accept(FhirMediaTypes.XML).xmlContent(xmlCondition).go();

assertThat(response, isCreated());
assertThat(response.getHeader("Location"), containsString("/Condition/"));
Expand Down Expand Up @@ -338,7 +338,7 @@ public void shouldUpdateExistingConditionAsXML() throws Exception {

condition.setVerificationStatus(Condition.ConditionVerificationStatus.PROVISIONAL);

response = put("/Condition/" + CONDITION_UUID).xmlContext(toXML(condition)).accept(FhirMediaTypes.XML).go();
response = put("/Condition/" + CONDITION_UUID).xmlContent(toXML(condition)).accept(FhirMediaTypes.XML).go();

assertThat(response, isOk());
assertThat(response.getContentType(), is(FhirMediaTypes.XML.toString()));
Expand Down Expand Up @@ -373,7 +373,7 @@ public void shouldReturnBadRequestWhenDocumentIdDoesNotMatchConditionIdAsXML() t

condition.setId(WRONG_CONDITION_UUID);

response = put("/Condition/" + CONDITION_UUID).xmlContext(toXML(condition)).accept(FhirMediaTypes.XML).go();
response = put("/Condition/" + CONDITION_UUID).xmlContent(toXML(condition)).accept(FhirMediaTypes.XML).go();

assertThat(response, isBadRequest());
assertThat(response.getContentType(), is(FhirMediaTypes.XML.toString()));
Expand All @@ -397,7 +397,7 @@ public void shouldReturnNotFoundWhenUpdatingNonExistentConditionAsXML() throws E

condition.setId(WRONG_CONDITION_UUID);

response = put("/Condition/" + WRONG_CONDITION_UUID).xmlContext(toXML(condition)).accept(FhirMediaTypes.XML).go();
response = put("/Condition/" + WRONG_CONDITION_UUID).xmlContent(toXML(condition)).accept(FhirMediaTypes.XML).go();

assertThat(response, isNotFound());
assertThat(response.getContentType(), is(FhirMediaTypes.XML.toString()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ public void shouldCreateNewConditionAsXML() throws Exception {
assertThat(xmlCondition, notNullValue());
}

MockHttpServletResponse response = post("/Condition").accept(FhirMediaTypes.XML).xmlContext(xmlCondition).go();
MockHttpServletResponse response = post("/Condition").accept(FhirMediaTypes.XML).xmlContent(xmlCondition).go();

assertThat(response, isCreated());
assertThat(response.getHeader("Location"), containsString("/Condition/"));
Expand Down Expand Up @@ -336,7 +336,7 @@ public void shouldUpdateExistingConditionAsXML() throws Exception {

condition.getVerificationStatus().getCodingFirstRep().setCode("provisional");

response = put("/Condition/" + CONDITION_UUID).xmlContext(toXML(condition)).accept(FhirMediaTypes.XML).go();
response = put("/Condition/" + CONDITION_UUID).xmlContent(toXML(condition)).accept(FhirMediaTypes.XML).go();

assertThat(response, isOk());
assertThat(response.getContentType(), is(FhirMediaTypes.XML.toString()));
Expand Down Expand Up @@ -371,7 +371,7 @@ public void shouldReturnBadRequestWhenDocumentIdDoesNotMatchConditionIdAsXML() t

condition.setId(WRONG_CONDITION_UUID);

response = put("/Condition/" + CONDITION_UUID).xmlContext(toXML(condition)).accept(FhirMediaTypes.XML).go();
response = put("/Condition/" + CONDITION_UUID).xmlContent(toXML(condition)).accept(FhirMediaTypes.XML).go();

assertThat(response, isBadRequest());
assertThat(response.getContentType(), is(FhirMediaTypes.XML.toString()));
Expand All @@ -395,7 +395,7 @@ public void shouldReturnNotFoundWhenUpdatingNonExistentConditionAsXML() throws E

condition.setId(WRONG_CONDITION_UUID);

response = put("/Condition/" + WRONG_CONDITION_UUID).xmlContext(toXML(condition)).accept(FhirMediaTypes.XML).go();
response = put("/Condition/" + WRONG_CONDITION_UUID).xmlContent(toXML(condition)).accept(FhirMediaTypes.XML).go();

assertThat(response, isNotFound());
assertThat(response.getContentType(), is(FhirMediaTypes.XML.toString()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ public FhirRequestBuilder jsonContent(@Nonnull String json) {
return this;
}

public FhirRequestBuilder xmlContext(@Nonnull String xml) {
public FhirRequestBuilder xmlContent(@Nonnull String xml) {
request.addHeader(CONTENT_TYPE, FhirMediaTypes.XML.toString());
request.setContent(xml.getBytes(StandardCharsets.UTF_8));
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public void shouldCreateNewAllergyAsXML() throws Exception {
}

// create allergy
MockHttpServletResponse response = post("/AllergyIntolerance").accept(FhirMediaTypes.XML).xmlContext(jsonAllergy)
MockHttpServletResponse response = post("/AllergyIntolerance").accept(FhirMediaTypes.XML).xmlContent(jsonAllergy)
.go();

// verify created correctly
Expand Down Expand Up @@ -300,7 +300,7 @@ public void shouldUpdateExistingAllergyAsXML() throws Exception {
allergy.getCategory().set(0, category);

// send the update to the server
response = put("/AllergyIntolerance/" + ALLERGY_UUID).xmlContext(toXML(allergy)).accept(FhirMediaTypes.XML).go();
response = put("/AllergyIntolerance/" + ALLERGY_UUID).xmlContent(toXML(allergy)).accept(FhirMediaTypes.XML).go();

assertThat(response, isOk());
assertThat(response.getContentType(), is(FhirMediaTypes.XML.toString()));
Expand Down Expand Up @@ -331,7 +331,7 @@ public void shouldReturnBadRequestWhenDocumentIdDoesNotMatchAllergyIdAsXML() thr
allergy.setId(UNKNOWN_ALLERGY_UUID);

// send the update to the server
response = put("/AllergyIntolerance/" + ALLERGY_UUID).xmlContext(toXML(allergy)).accept(FhirMediaTypes.XML).go();
response = put("/AllergyIntolerance/" + ALLERGY_UUID).xmlContent(toXML(allergy)).accept(FhirMediaTypes.XML).go();

assertThat(response, isBadRequest());
assertThat(response.getContentType(), is(FhirMediaTypes.XML.toString()));
Expand All @@ -353,7 +353,7 @@ public void shouldReturnNotFoundWhenUpdatingNonExistentAllergyAsXML() throws Exc
allergy.setId(UNKNOWN_ALLERGY_UUID);

// send the update to the server
response = put("/AllergyIntolerance/" + UNKNOWN_ALLERGY_UUID).xmlContext(toXML(allergy)).accept(FhirMediaTypes.XML)
response = put("/AllergyIntolerance/" + UNKNOWN_ALLERGY_UUID).xmlContent(toXML(allergy)).accept(FhirMediaTypes.XML)
.go();

assertThat(response, isNotFound());
Expand Down

0 comments on commit ccce482

Please sign in to comment.