/** * 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.xforms; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.commons.lang.StringUtils; import org.kxml2.kdom.Element; import org.openmrs.Patient; import org.openmrs.Person; import org.openmrs.Relationship; import org.openmrs.RelationshipType; import org.openmrs.api.APIException; import org.openmrs.api.PersonService; import org.openmrs.api.context.Context; public class RelativeSubmission { /** * Saves relationships which have been edited, added, or deleted. * * @param node the form root node. * @param patient the patient that the form has been submitted for. * @should create relationships * @should edit an editing relationship */ public static void submit(String xml, Patient patient) { Element patientNode = XformBuilder.getElement(XformBuilder.getDocument(xml).getRootElement(), XformBuilder.NODE_PATIENT); if (patientNode == null) return; if (XformBuilder.getElement(patientNode, RelativeBuilder.NODE_RELATIVE) == null) { return; //user deleted the relationships node XFRM-176 } PersonService ps = Context.getPersonService(); //we start by assuming all relationships are deleted until found in the submission. List<Relationship> deletedRelationships = ps.getRelationshipsByPerson(patient); List<Relationship> newRelationships = new ArrayList<Relationship>(); for (int i = 0; i < patientNode.getChildCount(); i++) { if (patientNode.getType(i) != Element.ELEMENT || !RelativeBuilder.NODE_RELATIVE.equals(patientNode.getElement(i).getName())) { continue; } Element relativeNode = patientNode.getElement(i); String relationshipUuid = relativeNode.getAttributeValue(null, XformBuilder.ATTRIBUTE_UUID); if (!("true()".equals(relativeNode.getAttributeValue(null, "new"))) && StringUtils.isNotBlank(relationshipUuid)) { updateRelationship(relationshipUuid, relativeNode, patient, deletedRelationships, ps); continue; } Relationship relationship = getRelationship(relativeNode, patient, ps); if (relationship != null) { newRelationships.add(relationship); } } for (Relationship reltnp : newRelationships) { ps.saveRelationship(reltnp); } for (Relationship reltnp : deletedRelationships) { ps.purgeRelationship(reltnp); } } private static Relationship getRelationship(Element relativeNode, Patient patient, PersonService ps) { Element personNode = XformBuilder.getElement(relativeNode, RelativeBuilder.BIND_PERSON); Element relationshipNode = XformBuilder.getElement(relativeNode, RelativeBuilder.NODE_RELATIONSHIP); String personUuid = XformBuilder.getTextValue(personNode); String relationshipStr = XformBuilder.getTextValue(relationshipNode); if (StringUtils.isBlank(personUuid) || StringUtils.isBlank(relationshipStr)) { if (StringUtils.isNotBlank(personUuid) || StringUtils.isNotBlank(relationshipStr)) { throw new APIException("Both person and relationship should be null or not null"); } return null; } String AorB = relationshipStr.substring(relationshipStr.length() - 1); String relationshipTypeId = relationshipStr.substring(0, relationshipStr.length() - 1); RelationshipType relationshipType = null; if (StringUtils.isNotBlank(relationshipTypeId)) relationshipType = ps.getRelationshipType(Integer.valueOf(relationshipTypeId)); if (relationshipType == null) throw new APIException("Cannot find relation type with id:" + relationshipType); boolean isPersonA = false; if (AorB != null && ("A".equalsIgnoreCase(AorB) || "B".equalsIgnoreCase(AorB))) { isPersonA = "A".equalsIgnoreCase(AorB); } else { throw new APIException("Cannot determine if the patient is A or B in the relationship:" + relationshipType.getName()); } Person otherPerson = ps.getPersonByUuid(personUuid); if (otherPerson == null) throw new APIException("Cannot determine if the relattive in the relationship:" + relationshipType.getName()); Person personA; Person personB; if (isPersonA) { personB = patient; personA = otherPerson; } else { personA = patient; personB = otherPerson; } Relationship relationship = new Relationship(); relationship.setRelationshipType(relationshipType); relationship.setPersonA(personA); relationship.setPersonB(personB); return relationship; } private static void updateRelationship(String uuid, Element relativeNode, Patient patient, List<Relationship> deletedRelationships, PersonService ps) { Relationship relationship = Context.getPersonService().getRelationshipByUuid(uuid); if (relationship == null) throw new APIException("Cannot find relationship with uuid: " + uuid); //relationship no longer considered deleted since it is found in the submission deletedRelationships.remove(relationship); Relationship editedRelationship = getRelationship(relativeNode, patient, ps); if (editedRelationship.getPersonA().getPersonId() == relationship.getPersonA().getPersonId() && editedRelationship.getPersonB().getPersonId() == relationship.getPersonB().getPersonId() && editedRelationship.getRelationshipType().getRelationshipTypeId() == relationship.getRelationshipType() .getRelationshipTypeId()) { //not changed. return; } relationship.setPersonA(editedRelationship.getPersonA()); relationship.setPersonB(editedRelationship.getPersonB()); relationship.setRelationshipType(editedRelationship.getRelationshipType()); relationship.setChangedBy(Context.getAuthenticatedUser()); relationship.setDateChanged(new Date()); ps.saveRelationship(relationship); } }