org.openmrs.module.radiology.order.web.RadiologyOrderFormController.java Source code

Java tutorial

Introduction

Here is the source code for org.openmrs.module.radiology.order.web.RadiologyOrderFormController.java

Source

/**
 * 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.radiology.order.web;

import static org.openmrs.module.radiology.RadiologyPrivileges.ADD_RADIOLOGY_REPORTS;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.openmrs.Order;
import org.openmrs.Patient;
import org.openmrs.api.APIException;
import org.openmrs.api.context.Context;
import org.openmrs.module.radiology.Modality;
import org.openmrs.module.radiology.RadiologyProperties;
import org.openmrs.module.radiology.dicom.DicomWebViewer;
import org.openmrs.module.radiology.dicom.code.PerformedProcedureStepStatus;
import org.openmrs.module.radiology.dicom.code.ScheduledProcedureStepStatus;
import org.openmrs.module.radiology.order.RadiologyOrder;
import org.openmrs.module.radiology.order.RadiologyOrderService;
import org.openmrs.module.radiology.order.RadiologyOrderValidator;
import org.openmrs.module.radiology.report.RadiologyReport;
import org.openmrs.module.radiology.report.RadiologyReportService;
import org.openmrs.module.radiology.study.RadiologyStudy;
import org.openmrs.web.WebConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
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.servlet.ModelAndView;

/**
 * Controller for the form handling entry, display, discontinuation of {@code RadiologyOrder's}.
 */
@Controller
@RequestMapping(RadiologyOrderFormController.RADIOLOGY_ORDER_FORM_REQUEST_MAPPING)
public class RadiologyOrderFormController {

    public static final String RADIOLOGY_ORDER_FORM_REQUEST_MAPPING = "/module/radiology/radiologyOrder.form";

    static final String RADIOLOGY_ORDER_FORM_VIEW = "/module/radiology/orders/radiologyOrderForm";

    @Autowired
    private RadiologyOrderService radiologyOrderService;

    @Autowired
    private RadiologyReportService radiologyReportService;

    @Autowired
    private RadiologyProperties radiologyProperties;

    @Autowired
    private DicomWebViewer dicomWebViewer;

    @Autowired
    private RadiologyOrderValidator radiologyOrderValidator;

    @Autowired
    private DiscontinuationOrderRequestValidator discontinuationOrderRequestValidator;

    @InitBinder("discontinuationOrderRequest")
    protected void initBinderDiscontinuationOrderRequest(WebDataBinder webDataBinder) {
        webDataBinder.setValidator(discontinuationOrderRequestValidator);
    }

    /**
     * Handles requests for a new {@code RadiologyOrder}.
     * 
     * @return model and view containing new radiology order
     * @should populate model and view with new radiology order
     */
    @RequestMapping(method = RequestMethod.GET)
    protected ModelAndView getRadiologyOrderFormWithNewRadiologyOrder() {

        ModelAndView modelAndView = new ModelAndView(RADIOLOGY_ORDER_FORM_VIEW);
        modelAndView.addObject("order", new Order());
        modelAndView.addObject("radiologyReport", null);
        final RadiologyOrder radiologyOrder = new RadiologyOrder();
        radiologyOrder.setStudy(new RadiologyStudy());
        modelAndView.addObject("radiologyOrder", radiologyOrder);
        return modelAndView;
    }

    /**
     * Handles requests for a new {@code RadiologyOrder} for a specific patient.
     * 
     * @param patient the existing patient which should be associated with a new radiology order
     *        returned in the model and view
     * @return model and view containing new radiology order
     * @should populate model and view with new radiology order prefilled with given patient
     */
    @RequestMapping(method = RequestMethod.GET, params = "patientId")
    protected ModelAndView getRadiologyOrderFormWithNewRadiologyOrderAndPrefilledPatient(
            @RequestParam("patientId") Patient patient) {

        final ModelAndView modelAndView = getRadiologyOrderFormWithNewRadiologyOrder();
        Order order = (Order) modelAndView.getModel().get("radiologyOrder");
        order.setPatient(patient);
        modelAndView.addObject("patientId", patient.getPatientId());
        return modelAndView;
    }

    /**
     * Handles requests for getting existing {@code RadiologyOrder's}.
     * 
     * @param order the order of an existing radiology order which should be returned
     * @return model and view containing radiology order
     * @should populate model and view with existing radiology order if given order id matches a
     *         radiology order and no dicom viewer url if order is not completed
     * @should populate model and view with existing radiology order if given order id matches a
     *         radiology order and dicom viewer url if order completed
     * @should populate model and view with existing order if given order id only matches an order
     *         and not a radiology order
     */
    @RequestMapping(method = RequestMethod.GET, params = "orderId")
    protected ModelAndView getRadiologyOrderFormWithExistingRadiologyOrder(@RequestParam("orderId") Order order) {

        final ModelAndView modelAndView = new ModelAndView(RADIOLOGY_ORDER_FORM_VIEW);
        modelAndView.addObject("order", order);
        modelAndView.addObject("discontinuationOrderRequest", new DiscontinuationOrderRequest());

        if (order instanceof RadiologyOrder) {
            final RadiologyOrder radiologyOrder = (RadiologyOrder) order;
            modelAndView.addObject("radiologyOrder", radiologyOrder);
            if (radiologyOrder.isCompleted()) {
                modelAndView.addObject("dicomViewerUrl",
                        dicomWebViewer.getDicomViewerUrl(radiologyOrder.getStudy()));
            }
        }

        if (Context.getAuthenticatedUser().hasPrivilege(ADD_RADIOLOGY_REPORTS)) {
            radiologyReportNeedsToBeCreated(modelAndView, order);
        }

        return modelAndView;
    }

    /**
     * Handles requests for saving a new {@code RadiologyOrder}.
     *
     * @param request the http servlet request issued to save the radiology order
     * @param radiologyOrder the radiology order to be saved
     * @param resultRadiologyOrder the binding result for given radiology order
     * @return the model and view for the radiology order form containing binding result errors if given radiology order is
     *         not valid
     * @should save given radiology order if valid and set http session attribute openmrs message to order saved and redirect
     *         to the new radiology order
     * @should not save given radiology order if it is not valid and not redirect
     */
    @RequestMapping(method = RequestMethod.POST, params = "saveRadiologyOrder")
    protected ModelAndView saveRadiologyOrder(HttpServletRequest request,
            @ModelAttribute RadiologyOrder radiologyOrder, BindingResult resultRadiologyOrder) {

        final ModelAndView modelAndView = new ModelAndView(RADIOLOGY_ORDER_FORM_VIEW);

        radiologyOrderValidator.validate(radiologyOrder, resultRadiologyOrder);
        if (resultRadiologyOrder.hasErrors()) {
            modelAndView.addObject("order", (Order) radiologyOrder);
            modelAndView.addObject("radiologyOrder", radiologyOrder);
            return modelAndView;
        }

        radiologyOrderService.placeRadiologyOrder(radiologyOrder);

        request.getSession().setAttribute(WebConstants.OPENMRS_MSG_ATTR, "Order.saved");
        modelAndView.setViewName(
                "redirect:" + RADIOLOGY_ORDER_FORM_REQUEST_MAPPING + "?orderId=" + radiologyOrder.getOrderId());
        return modelAndView;
    }

    /**
     * Handles requests to discontinue a {@code RadiologyOrder}.
     * 
     * @param request the http servlet request issued to discontinue the radiology order
     * @param radiologyOrderToDiscontinue the radiology order to discontinue
     * @param discontinuationOrderRequest the discontinuation order request containing provider and reason
     * @param resultDiscontinuationOrderRequest the binding result for given discontinuation order request
     * @return the model and view populated with discontinuation order
     * @throws Exception
     * @should discontinue non discontinued radiology order and redirect to discontinuation order
     * @should not discontinue given radiology order and not redirect if discontinuation order request is not valid
     * @should not redirect and set session attribute with openmrs error if api exception is thrown by discontinue radiology
     *         order
     */
    @RequestMapping(method = RequestMethod.POST, params = "discontinueOrder")
    protected ModelAndView discontinueRadiologyOrder(HttpServletRequest request,
            @RequestParam("orderId") RadiologyOrder radiologyOrderToDiscontinue,
            @Valid @ModelAttribute DiscontinuationOrderRequest discontinuationOrderRequest,
            BindingResult resultDiscontinuationOrderRequest) throws Exception {

        final ModelAndView modelAndView = new ModelAndView(RADIOLOGY_ORDER_FORM_VIEW);

        try {
            if (resultDiscontinuationOrderRequest.hasErrors()) {
                modelAndView.addObject("order", radiologyOrderToDiscontinue);
                modelAndView.addObject("radiologyOrder",
                        radiologyOrderService.getRadiologyOrder(radiologyOrderToDiscontinue.getOrderId()));
                return modelAndView;
            }
            Order discontinuationOrder = radiologyOrderService.discontinueRadiologyOrder(
                    radiologyOrderToDiscontinue, discontinuationOrderRequest.getOrderer(),
                    discontinuationOrderRequest.getReasonNonCoded());

            request.getSession().setAttribute(WebConstants.OPENMRS_MSG_ATTR, "Order.discontinuedSuccessfully");
            modelAndView.setViewName("redirect:" + RADIOLOGY_ORDER_FORM_REQUEST_MAPPING + "?orderId="
                    + discontinuationOrder.getOrderId());
        } catch (APIException apiException) {
            request.getSession().setAttribute(WebConstants.OPENMRS_ERROR_ATTR, apiException.getMessage());
        }

        modelAndView.addObject("order", radiologyOrderToDiscontinue);
        modelAndView.addObject("radiologyOrder",
                radiologyOrderService.getRadiologyOrder(radiologyOrderToDiscontinue.getOrderId()));
        return modelAndView;
    }

    /**
     * Convenient method to check if a {@code RadiologyReport} needs to be created for a {@code RadiologyOrder}.
     *
     * @param modelAndView the model and view to which an object indicating if a report needs to be created is added
     * @param order the order to be checked for the need of a radiology report
     * @return true if a radiology report needs to be created and false otherwise
     * @should return false if order is not a radiology order
     * @should return false if radiology order is not completed
     * @should return false if radiology order is completed but has a claimed report
     * @should return false if radiology order is completed but has a completed report
     * @should return true if radiology order is completed and has no claimed report
     */
    private boolean radiologyReportNeedsToBeCreated(ModelAndView modelAndView, Order order) {

        final RadiologyOrder radiologyOrder;
        if (order instanceof RadiologyOrder) {
            radiologyOrder = (RadiologyOrder) order;
        } else {
            modelAndView.addObject("radiologyReportNeedsToBeCreated", false);
            return false;
        }

        if (radiologyOrder.isNotCompleted()) {
            modelAndView.addObject("radiologyReportNeedsToBeCreated", false);
            return false;
        }

        final RadiologyReport radiologyReport = radiologyReportService
                .getActiveRadiologyReportByRadiologyOrder(radiologyOrder);
        if (radiologyReport == null) {
            modelAndView.addObject("radiologyReportNeedsToBeCreated", true);
            return true;
        } else {
            modelAndView.addObject("radiologyReportNeedsToBeCreated", false);
            modelAndView.addObject("radiologyReport", radiologyReport);
            return false;
        }
    }

    @ModelAttribute("modalities")
    private Map<String, String> getModalityList() {

        final Map<String, String> modalities = new HashMap<String, String>();

        for (final Modality modality : Modality.values()) {
            modalities.put(modality.name(), modality.getFullName());
        }

        return modalities;
    }

    @ModelAttribute("urgencies")
    private List<String> getUrgenciesList() {

        final List<String> urgencies = new LinkedList<String>();

        for (final Order.Urgency urgency : Order.Urgency.values()) {
            urgencies.add(urgency.name());
        }

        return urgencies;
    }

    @ModelAttribute("scheduledProcedureStepStatuses")
    private Map<String, String> getScheduledProcedureStepStatusList() {

        final Map<String, String> scheduledProcedureStepStatuses = new LinkedHashMap<String, String>();
        scheduledProcedureStepStatuses.put("", "Select");

        for (final ScheduledProcedureStepStatus scheduledProcedureStepStatus : ScheduledProcedureStepStatus
                .values()) {
            scheduledProcedureStepStatuses.put(scheduledProcedureStepStatus.name(),
                    scheduledProcedureStepStatus.name());
        }

        return scheduledProcedureStepStatuses;
    }

    @ModelAttribute("performedStatuses")
    private Map<String, String> getPerformedStatusList() {

        final Map<String, String> performedStatuses = new HashMap<String, String>();
        performedStatuses.put("", "Select");

        for (final PerformedProcedureStepStatus performedStatus : PerformedProcedureStepStatus.values()) {
            performedStatuses.put(performedStatus.name(), performedStatus.name());
        }

        return performedStatuses;
    }

    /**
     * Gets the Name of the ConceptClasses that should be filtered
     *
     * @return Name of ConceptClasses
     */
    @ModelAttribute("radiologyConceptClassNames")
    private String getRadiologyConceptClassNames() {
        return radiologyProperties.getRadiologyConceptClassNames();
    }
}