/**
   * @see RadiologyObsFormController#saveObs(HttpServletRequest, HttpServletResponse, String,
   *     RadiologyOrder, Obs Obs, BindingResult)
   */
  @Test
  @Verifies(
      value = "should edit obs with edit reason and complex concept",
      method =
          "saveObs(HttpServletRequest, HttpServletResponse, String, RadiologyOrder, Obs Obs, BindingResult)")
  public void saveObs_ShouldEditObsWithEditReasonAndComplexConcept() {

    MockHttpSession mockSession = new MockHttpSession();
    mockRequest.addParameter("saveObs", "saveObs");
    mockRequest.setSession(mockSession);

    when(obsErrors.hasErrors()).thenReturn(false);
    ConceptComplex concept = new ConceptComplex();
    ConceptDatatype cdt = new ConceptDatatype();
    cdt.setHl7Abbreviation("ED");
    concept.setDatatype(cdt);
    mockObs.setConcept(concept);

    ModelAndView modelAndView =
        radiologyObsFormController.saveObs(
            mockRequest, null, "Test Edit Reason", mockRadiologyOrder, mockObs, obsErrors);

    assertNotNull(mockSession.getAttribute(WebConstants.OPENMRS_MSG_ATTR));
    assertThat((String) mockSession.getAttribute(WebConstants.OPENMRS_MSG_ATTR), is("Obs.saved"));
    assertThat(
        modelAndView.getViewName(),
        is(
            "redirect:"
                + RADIOLOGY_OBS_FORM_URL
                + "orderId="
                + mockRadiologyOrder.getId()
                + "&obsId="
                + mockObs.getId()));
  }
  /**
   * @see RadiologyObsFormController#saveObs(HttpServletRequest, HttpServletResponse, String,
   *     RadiologyOrder, Obs Obs, BindingResult)
   */
  @Test
  @Verifies(
      value = "should return redirecting model and view for not authenticated user",
      method =
          "saveObs(HttpServletRequest, HttpServletResponse, String, RadiologyOrder, Obs Obs, BindingResult)")
  public void saveObs_shouldReturnRedirectingModelAndViewForNotAuthenticatedUser() {

    MockHttpSession mockSession = new MockHttpSession();
    mockRequest.addParameter("saveObs", "saveObs");
    mockRequest.setSession(mockSession);

    when(Context.getAuthenticatedUser()).thenReturn(null);

    ModelAndView modelAndView =
        radiologyObsFormController.saveObs(
            mockRequest, null, "Test Edit Reason", mockRadiologyOrder, mockObs, obsErrors);

    assertThat(
        modelAndView.getViewName(),
        is(
            "redirect:"
                + RADIOLOGY_OBS_FORM_URL
                + "orderId="
                + mockRadiologyOrder.getId()
                + "&obsId="
                + mockObs.getId()));
  }
  /**
   * @see RadiologyObsFormController#voidObs(HttpServletRequest, HttpServletResponse, Order, Obs,
   *     String, String, Obs, BindingResult)
   */
  @Test
  @Verifies(
      value =
          "should void obs for given request, response, orderId, obsId, voidObs, voidReason, and obs",
      method =
          "voidObs(HttpServletRequest, HttpServletResponse, Order, Obs, String, String, Obs, BindingResult)")
  public void voidObs_ShouldVoidObsForGivenRequestResponseOrderIdObsIdVoidObsVoidReasonAndObs() {

    MockHttpSession mockSession = new MockHttpSession();
    mockRequest.addParameter("voidObs", "voidObs");
    mockRequest.setSession(mockSession);

    when(obsErrors.hasErrors()).thenReturn(false);

    ModelAndView modelAndView =
        radiologyObsFormController.voidObs(
            mockRequest, null, mockRadiologyOrder, mockObs, "Test Void Reason");

    assertNotNull(mockSession.getAttribute(WebConstants.OPENMRS_MSG_ATTR));
    assertThat(
        (String) mockSession.getAttribute(WebConstants.OPENMRS_MSG_ATTR),
        is("Obs.voidedSuccessfully"));
    assertThat(
        (String) modelAndView.getViewName(),
        is(
            "redirect:"
                + RADIOLOGY_OBS_FORM_URL
                + "orderId="
                + mockRadiologyOrder.getId()
                + "&obsId="
                + mockObs.getId()));
  }
  /**
   * @see RadiologyObsFormController#unvoidObs(HttpServletRequest, HttpServletResponse, Obs, String)
   */
  @Test
  @Verifies(
      value = "should unvoid voided obs for given request, response and obs",
      method = "unvoidObs(HttpServletRequest, HttpServletResponse, Obs, String)")
  public void unvoidObs_shouldUnvoidVoidedObsForGivenRequestResponseAndObs() {

    MockHttpSession mockSession = new MockHttpSession();
    mockRequest.addParameter("unvoidObs", "unvoidObs");
    mockRequest.setSession(mockSession);
    when(obsErrors.hasErrors()).thenReturn(false);

    mockObs.setVoided(true);

    ModelAndView modelAndView = radiologyObsFormController.unvoidObs(mockRequest, null, mockObs);
    assertThat(
        modelAndView.getViewName(),
        is(
            "redirect:"
                + RADIOLOGY_OBS_FORM_URL
                + "orderId="
                + mockRadiologyOrder.getId()
                + "&obsId="
                + mockObs.getId()));
    assertThat(
        (String) mockSession.getAttribute(WebConstants.OPENMRS_MSG_ATTR),
        is("Obs.unvoidedSuccessfully"));
  }
  /**
   * Void given obs corresponding to given http servlet request, http servlet response,
   * radiologyOrder, obs, voidReason
   *
   * @param request the http servlet request with all parameters
   * @param response the http servlet response
   * @param radiologyOrder the corresponding radiology order
   * @param obs the obs
   * @param voidReason the reason the obs was voided for
   * @return ModelAndView for radiology obs form
   * @should void obs for given request, response, radiologyOrder, obs, and voidReason
   * @should not void obs with empty voiding reason
   * @should not void obs with voiding reason null
   */
  @RequestMapping(
      value = "/module/radiology/radiologyObs.form",
      method = RequestMethod.POST,
      params = "voidObs")
  protected ModelAndView voidObs(
      HttpServletRequest request,
      HttpServletResponse response,
      @RequestParam(value = "orderId", required = true) RadiologyOrder radiologyOrder,
      @RequestParam(value = "obsId", required = true) Obs obs,
      @RequestParam(value = "voidReason", required = true) String voidReason) {

    HttpSession httpSession = request.getSession();
    if (voidReason == null || voidReason.isEmpty()) {
      httpSession.setAttribute(WebConstants.OPENMRS_ERROR_ATTR, "Obs.void.reason.empty");
      return populateModelAndView(radiologyOrder, obs);
    }

    obsService.voidObs(obs, voidReason);
    httpSession.setAttribute(WebConstants.OPENMRS_MSG_ATTR, "Obs.voidedSuccessfully");
    return new ModelAndView(
        "redirect:"
            + RADIOLOGY_OBS_FORM_URL
            + "orderId="
            + radiologyOrder.getId()
            + "&obsId="
            + obs.getId());
  }
  public static Set<Set<Obs>> generateObsGroupFromSearchResults() {
    Set<Set<Obs>> obsGroups = new HashSet<Set<Obs>>();

    SearchAPI searchAPI = SearchAPI.getInstance();
    List<ChartListItem> searchResultsList = searchAPI.getResults();
    for (ChartListItem item :
        searchResultsList) { // for each item in results we classify it by its obsGroup, and add all
                             // of the group.
      if (item != null && item instanceof ObsItem && ((ObsItem) item).getObsId() != null) {
        int itemObsId = ((ObsItem) item).getObsId();
        Obs obsGrp = Context.getObsService().getObs(itemObsId).getObsGroup();
        if (obsGrp != null) {
          int groupId = obsGrp.getId();
          Set<Obs> obsGroup = obsGrp.getGroupMembers();
          boolean found = false; // if found == true then we don't need to add the group.
          for (Set<Obs> grp : obsGroups) {
            Obs ob = new Obs(-1);
            if (grp.iterator().hasNext()) {
              ob = grp.iterator().next();
            }
            if (ob.getObsGroup() != null && ob.getObsGroup().getId() != null) {
              if (ob.getObsGroup().getId() == groupId) {
                found = true;
              }
            }
          }
          if (!found) {
            obsGroups.add(obsGroup);
          }
        }
      }
    }
    return obsGroups;
  }
  private void updateInitialDiagnosis(
      Obs diagnosisObs,
      BahmniDiagnosisRequest bahmniDiagnosis,
      Concept bahmniInitialDiagnosisConcept) {
    Obs obs = findOrCreateObs(diagnosisObs, bahmniInitialDiagnosisConcept);
    String initialDiagnosisUuid =
        bahmniDiagnosis.getPreviousObs() == null && obs.getId() == null
            ? diagnosisObs.getUuid()
            : bahmniDiagnosis.getFirstDiagnosis().getExistingObs();

    obs.setValueText(initialDiagnosisUuid);
    addToObsGroup(diagnosisObs, obs);
  }
  /**
   * Unvoid given obs corresponding to given http servlet request, http servlet response and obs
   *
   * @param request the http servlet request with all parameters
   * @param response the http servlet response
   * @param obs obs which should be unvoided
   * @return ModelAndView for radiology order list
   * @should unvoid voided obs for given request, response and obs
   */
  @RequestMapping(
      value = "/module/radiology/radiologyObs.form",
      method = RequestMethod.POST,
      params = "unvoidObs")
  protected ModelAndView unvoidObs(
      HttpServletRequest request,
      HttpServletResponse response,
      @RequestParam(value = "obsId", required = true) Obs obs) {

    HttpSession httpSession = request.getSession();
    obsService.unvoidObs(obs);
    httpSession.setAttribute(WebConstants.OPENMRS_MSG_ATTR, "Obs.unvoidedSuccessfully");
    return new ModelAndView(
        "redirect:"
            + RADIOLOGY_OBS_FORM_URL
            + "orderId="
            + obs.getOrder().getId()
            + "&obsId="
            + obs.getId());
  }
  /**
   * @see RadiologyObsFormController#saveObs(HttpServletRequest, HttpServletResponse, String,
   *     RadiologyOrder, Obs Obs, BindingResult)
   */
  @Test
  @Verifies(
      value =
          "should edit obs with edit reason concept not complex and request which is an instance of multihttpserveletrequest",
      method =
          "saveObs(HttpServletRequest, HttpServletResponse, String, RadiologyOrder, Obs Obs, BindingResult)")
  public void
      saveObs_ShouldEditObsWithEditReasonConceptNotComplexAndRequestWhichIsAnInstanceOfMultiHTTPServletRequest() {

    MockHttpSession mockSession = new MockHttpSession();
    MockMultipartHttpServletRequest mockRequest = new MockMultipartHttpServletRequest();
    mockRequest.addParameter("saveObs", "saveObs");
    mockRequest.setSession(mockSession);

    when(obsErrors.hasErrors()).thenReturn(false);
    ;
    mockObs.setConcept(new Concept());
    final String fileName = "test.txt";
    final byte[] content = "Hello World".getBytes();
    MockMultipartFile mockMultipartFile =
        new MockMultipartFile("complexDataFile", fileName, "text/plain", content);

    mockRequest.addFile(mockMultipartFile);

    ModelAndView modelAndView =
        radiologyObsFormController.saveObs(
            mockRequest, null, "Test Edit Reason", mockRadiologyOrder, mockObs, obsErrors);

    assertNotNull(mockSession.getAttribute(WebConstants.OPENMRS_MSG_ATTR));
    assertThat((String) mockSession.getAttribute(WebConstants.OPENMRS_MSG_ATTR), is("Obs.saved"));
    assertThat(
        modelAndView.getViewName(),
        is(
            "redirect:"
                + RADIOLOGY_OBS_FORM_URL
                + "orderId="
                + mockRadiologyOrder.getId()
                + "&obsId="
                + mockObs.getId()));
  }
 @Override
 public Integer getId() {
   return obs.getId();
 }
 @Override
 public int compare(Obs o1, Obs o2) {
   return o1.getId().compareTo(o2.getId());
 }
  /**
   * Save obs corresponding to given http servlet request, http servlet response, radiologyOrder,
   * obs, obs, obsErrors
   *
   * @param request the http servlet request with all parameters
   * @param response the http servlet response
   * @param radiologyOrder the corresponding radiology order
   * @param obs the obs
   * @param obsErrors the result of the parameter binding
   * @return ModelAndView populated with obs matching the given criteria
   * @should save obs with given parameters
   * @should return populated model and view if binding errors occur
   * @should return populated model and view if edit reason is empty and obs id not null
   * @should return populated model and view if edit reason is null and obs id not null
   * @should return redirecting model and view for not authenticated user
   * @should edit obs with edit reason and complex concept
   * @should edit obs with edit reason, complex concept and request which is an instance of
   *     multihttpserveletrequest
   * @should edit obs with edit reason concept not complex and request which is an instance of
   *     multihttpserveletrequest
   * @should populate model and view with obs occuring thrown APIException
   */
  @RequestMapping(
      value = "/module/radiology/radiologyObs.form",
      method = RequestMethod.POST,
      params = "saveObs")
  ModelAndView saveObs(
      HttpServletRequest request,
      HttpServletResponse response,
      @RequestParam(value = "editReason", required = false) String editReason,
      @RequestParam(value = "orderId", required = true) RadiologyOrder radiologyOrder,
      @ModelAttribute("obs") Obs obs,
      BindingResult obsErrors) {

    HttpSession httpSession = request.getSession();

    new ObsValidator().validate(obs, obsErrors);

    if (obsErrors.hasErrors()) {
      return populateModelAndView(radiologyOrder, obs);
    }
    if (Context.isAuthenticated()) {

      try {
        // if the user is just editing the obs
        if (obs.getObsId() != null && (editReason == null || editReason.isEmpty())) {
          obsErrors.reject("editReason", "Obs.edit.reason.empty");

          return populateModelAndView(radiologyOrder, obs);
        }

        if (obs.getConcept().isComplex()) {
          if (request instanceof MultipartHttpServletRequest) {
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            MultipartFile complexDataFile = multipartRequest.getFile("complexDataFile");
            if (complexDataFile != null && !complexDataFile.isEmpty()) {
              InputStream complexDataInputStream = complexDataFile.getInputStream();

              ComplexData complexData =
                  new ComplexData(complexDataFile.getOriginalFilename(), complexDataInputStream);

              obs.setComplexData(complexData);

              // the handler on the obs.concept is called
              // with
              // the given complex data
              obsService.saveObs(obs, editReason);
              updateReadingPhysician(radiologyOrder.getStudy());
              complexDataInputStream.close();
            }
          }
        } else {
          obsService.saveObs(obs, editReason);
          updateReadingPhysician(radiologyOrder.getStudy());
        }
        httpSession.setAttribute(WebConstants.OPENMRS_MSG_ATTR, "Obs.saved");
      } catch (APIException e) {
        httpSession.setAttribute(WebConstants.OPENMRS_ERROR_ATTR, e.getMessage());
        return populateModelAndView(radiologyOrder, obs);
      } catch (IOException e) {
        return populateModelAndView(radiologyOrder, obs);
      }
    }
    return new ModelAndView(
        "redirect:"
            + RADIOLOGY_OBS_FORM_URL
            + "orderId="
            + obs.getOrder().getId()
            + "&obsId="
            + obs.getId());
  }