/** * 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.web.controller.visit; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.Predicate; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openmrs.Encounter; import org.openmrs.Visit; import org.openmrs.VisitAttribute; import org.openmrs.VisitAttributeType; import org.openmrs.VisitType; import org.openmrs.api.APIException; import org.openmrs.api.context.Context; import org.openmrs.attribute.handler.AttributeHandler; import org.openmrs.validator.VisitValidator; import org.openmrs.web.WebConstants; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.util.StringUtils; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.support.SessionStatus; import org.springframework.web.context.request.WebRequest; /** * Controller class for creating, editing, deleting, restoring and purging a visit */ @Controller public class VisitFormController { private static final Log log = LogFactory.getLog(VisitFormController.class); private static final String VISIT_FORM_URL = "/admin/visits/visit"; private static final String VISIT_FORM = "/admin/visits/visitForm"; /** * Processes requests to display the form */ @RequestMapping(method = RequestMethod.GET, value = VISIT_FORM_URL) public String showForm() { return VISIT_FORM; } @ModelAttribute("visit") public Visit getVisit(@RequestParam(value = "visitId", required = false) Integer visitId, @RequestParam(value = "patientId", required = false) Integer patientId, ModelMap model) { Visit visit = null; if (visitId != null) visit = Context.getVisitService().getVisit(visitId); else { visit = new Visit(); if (patientId != null) visit.setPatient(Context.getPatientService().getPatient(patientId)); } return visit; } /** * Processes requests to save/update a visit * * @param request the {@link WebRequest} object * @param visit the visit object to save/update * @param status the {@link SessionStatus} * @param result the {@link BindingResult} object * @param model the {@link ModelMap} object * @return the url to forward/redirect to */ @RequestMapping(method = RequestMethod.POST, value = VISIT_FORM_URL) public String saveVisit(WebRequest request, @ModelAttribute("visit") Visit visit, BindingResult result, SessionStatus status, ModelMap model) { // manually handle the attribute parameters for (VisitAttributeType vat : (List<VisitAttributeType>) model.get("visitAttributeTypes")) { if (vat.getMaxOccurs() == null || vat.getMaxOccurs() != 1) throw new RuntimeException("For now only attributes with maxOccurs=1 are supported"); AttributeHandler<?> handler = Context.getAttributeService().getHandler(vat); List<Object> attributeValues = new ArrayList<Object>(); // look for parameters starting with attribute.${ vat.id } for (Iterator<String> iter = request.getParameterNames(); iter.hasNext();) { String paramName = iter.next(); if (paramName.startsWith("attribute." + vat.getId())) { String paramValue = request.getParameter(paramName); if (StringUtils.hasText(paramValue)) { Object realValue = handler.deserialize(paramValue); //handler.validate(realValue); VisitAttribute va = new VisitAttribute(); va.setAttributeType(vat); va.setSerializedValue(paramValue); visit.setAttribute(va); } else { for (VisitAttribute va : visit.getActiveAttributes(vat)) va.setVoided(true); } } } } new VisitValidator().validate(visit, result); if (!result.hasErrors()) { try { Context.getVisitService().saveVisit(visit); if (log.isDebugEnabled()) log.debug("Saved visit: " + visit.toString()); return "redirect:" + VISIT_FORM_URL + ".form?visitId=" + visit.getVisitId(); } catch (APIException e) { log.warn("Error while saving visit(s)", e); request.setAttribute(WebConstants.OPENMRS_ERROR_ATTR, "Visit.save.error", WebRequest.SCOPE_SESSION); } } return VISIT_FORM; } /** * Processes requests to void a visit * * @param request the {@link WebRequest} object * @param visit the visit object to void * @param voidReason the reason why the visit is getting void * @param status the {@link SessionStatus} * @param model the {@link ModelMap} object * @return the url to forward to */ @RequestMapping(method = RequestMethod.POST, value = "/admin/visits/voidVisit") public String voidVisit(WebRequest request, @ModelAttribute(value = "visit") Visit visit, @RequestParam(required = false, value = "voidReason") String voidReason, SessionStatus status, ModelMap model) { if (!StringUtils.hasText(voidReason)) voidReason = Context.getMessageSourceService().getMessage("general.default.voidReason"); try { Context.getVisitService().voidVisit(visit, voidReason); if (log.isDebugEnabled()) log.debug("Voided visit with id: " + visit.getId()); request.setAttribute(WebConstants.OPENMRS_MSG_ATTR, Context.getMessageSourceService().getMessage("Visit.voided"), WebRequest.SCOPE_SESSION); return "redirect:" + VISIT_FORM_URL + ".form?visitId=" + visit.getVisitId(); } catch (APIException e) { log.warn("Error occurred while attempting to void visit", e); request.setAttribute(WebConstants.OPENMRS_ERROR_ATTR, Context.getMessageSourceService().getMessage( "Visit.void.error"), WebRequest.SCOPE_SESSION); } return VISIT_FORM; } /** * Processes requests to unvoid a visit * * @param request the {@link WebRequest} object * @param visit the visit object to unvoid * @param status the {@link SessionStatus} * @param model the {@link ModelMap} object * @return the url to forward to */ @RequestMapping(method = RequestMethod.POST, value = "/admin/visits/unvoidVisit") public String unvoidVisit(WebRequest request, @ModelAttribute(value = "visit") Visit visit, SessionStatus status, ModelMap model) { try { Context.getVisitService().unvoidVisit(visit); if (log.isDebugEnabled()) log.debug("Unvoided visit with id: " + visit.getId()); request.setAttribute(WebConstants.OPENMRS_MSG_ATTR, Context.getMessageSourceService().getMessage( "Visit.unvoided"), WebRequest.SCOPE_SESSION); return "redirect:" + VISIT_FORM_URL + ".form?visitId=" + visit.getVisitId(); } catch (APIException e) { log.warn("Error occurred while attempting to unvoid visit", e); request.setAttribute(WebConstants.OPENMRS_ERROR_ATTR, Context.getMessageSourceService().getMessage( "Visit.unvoid.error"), WebRequest.SCOPE_SESSION); } return VISIT_FORM; } /** * Processes requests to purge a visit * * @param request the {@link WebRequest} object * @param visit the visit object to purge * @param status the {@link SessionStatus} * @param model the {@link ModelMap} object * @return the url to forward to */ @RequestMapping(method = RequestMethod.POST, value = "/admin/visits/purgeVisit") public String purgeVisit(WebRequest request, @ModelAttribute(value = "visit") Visit visit, SessionStatus status, ModelMap model) { try { Integer patientId = visit.getPatient().getPatientId(); Context.getVisitService().purgeVisit(visit); if (log.isDebugEnabled()) log.debug("Purged visit with id: " + visit.getId()); request.setAttribute(WebConstants.OPENMRS_MSG_ATTR, Context.getMessageSourceService().getMessage("Visit.purged"), WebRequest.SCOPE_SESSION); return "redirect:/patientDashboard.form?patientId=" + patientId; } catch (APIException e) { log.warn("Error occurred while attempting to purge visit", e); request.setAttribute(WebConstants.OPENMRS_ERROR_ATTR, Context.getMessageSourceService().getMessage( "Visit.purge.error"), WebRequest.SCOPE_SESSION); } return VISIT_FORM; } @ModelAttribute("visitTypes") public List<VisitType> getVisitTypes() throws Exception { return Context.getVisitService().getAllVisitTypes(); } @ModelAttribute("visitAttributeTypes") public List<VisitAttributeType> getVisitAttributeTypes() throws Exception { return Context.getVisitService().getAllVisitAttributeTypes(); } @ModelAttribute("visitEncounters") public List<Encounter> setEncounterDetails(@ModelAttribute("visit") Visit visit) { List<Encounter> visitEncounters = new ArrayList<Encounter>(); if (visit.getVisitId() != null) visitEncounters = Context.getEncounterService().getEncountersByVisit(visit); return visitEncounters; } @ModelAttribute("encountersToAdd") public List<Encounter> setEncounterDetailss(@ModelAttribute("visit") Visit visit) { List<Encounter> patientEncounters = new ArrayList<Encounter>(); if (visit.getPatient() != null && visit.getPatient().getPatientId() != null) patientEncounters = Context.getEncounterService().getEncountersByPatient(visit.getPatient()); //remove all encounters that are already associated to visits CollectionUtils.filter(patientEncounters, new Predicate() { @Override public boolean evaluate(Object object) { Encounter e = (Encounter) object; return e.getVisit() == null; } }); return patientEncounters; } }