/**
  * Helper method that finds the corresponding providers for a collection of users
  *
  * @param users
  * @return a collection of providers, with 0-n for each item in users
  */
 private Collection<Provider> usersToProviders(Collection<User> users) {
   if (users == null) {
     return null;
   }
   ProviderService providerService = Context.getProviderService();
   Collection<Provider> ret = new HashSet<Provider>();
   for (User u : users) {
     ret.addAll(providerService.getProvidersByPerson(u.getPerson()));
   }
   return ret;
 }
 private Provider getProvider(User accountBelongingToUser) {
   Collection<Provider> candidates =
       providerService.getProvidersByPerson(accountBelongingToUser.getPerson(), false);
   if (candidates.size() == 0) {
     throw new IllegalStateException(
         "User " + accountBelongingToUser.getUsername() + " does not have a Provider account");
   } else if (candidates.size() > 1) {
     throw new IllegalStateException(
         "User " + accountBelongingToUser.getUsername() + " has more than one Provider account");
   } else {
     return candidates.iterator().next();
   }
 }
  /**
   * @see Encounter#setProvider(Person)
   * @verifies set existing provider for unknown role
   */
  @Test
  public void setProvider_shouldSetExistingProviderForUnknownRole() throws Exception {
    // given
    Encounter encounter = new Encounter();
    EncounterRole unknownRole = new EncounterRole();
    Person person = new Person();
    Provider provider = new Provider();
    provider.setPerson(person);
    List<Provider> providers = new ArrayList<Provider>();
    providers.add(provider);

    when(encounterService.getEncounterRoleByUuid(EncounterRole.UNKNOWN_ENCOUNTER_ROLE_UUID))
        .thenReturn(unknownRole);

    when(providerService.getProvidersByPerson(person)).thenReturn(providers);

    // when
    encounter.setProvider(person);

    // then
    assertEquals(1, encounter.getProvidersByRoles().size());
    assertEquals(1, encounter.getProvidersByRole(unknownRole).size());
    assertEquals(provider, encounter.getProvidersByRole(unknownRole).iterator().next());
  }
  /**
   * @see
   *     org.springframework.web.servlet.mvc.SimpleFormController#processFormSubmission(javax.servlet.http.HttpServletRequest,
   *     javax.servlet.http.HttpServletResponse, java.lang.Object,
   *     org.springframework.validation.BindException)
   */
  @Override
  protected ModelAndView processFormSubmission(
      HttpServletRequest request, HttpServletResponse reponse, Object obj, BindException errors)
      throws Exception {

    Encounter encounter = (Encounter) obj;

    try {
      if (Context.isAuthenticated()) {
        Context.addProxyPrivilege(PrivilegeConstants.VIEW_USERS);
        Context.addProxyPrivilege(PrivilegeConstants.VIEW_PATIENTS);

        if (encounter.getEncounterId() == null
            && StringUtils.hasText(request.getParameter("patientId"))) {
          encounter.setPatient(
              Context.getPatientService()
                  .getPatient(Integer.valueOf(request.getParameter("patientId"))));
        }
        if (encounter.isVoided()) {
          ValidationUtils.rejectIfEmptyOrWhitespace(errors, "voidReason", "error.null");
        }

        String[] providerIdsArray = ServletRequestUtils.getStringParameters(request, "providerIds");
        if (ArrayUtils.isEmpty(providerIdsArray)) {
          errors.reject("Encounter.provider.atleastOneProviderRequired");
        }

        String[] roleIdsArray =
            ServletRequestUtils.getStringParameters(request, "encounterRoleIds");

        ProviderService ps = Context.getProviderService();
        EncounterService es = Context.getEncounterService();
        if (providerIdsArray != null && roleIdsArray != null) {
          // list to store role provider mappings to be used below to detect removed providers
          List<String> unremovedRoleAndProviders = new ArrayList<String>();
          for (int i = 0; i < providerIdsArray.length; i++) {
            if (StringUtils.hasText(providerIdsArray[i]) && StringUtils.hasText(roleIdsArray[i])) {
              unremovedRoleAndProviders.add(roleIdsArray[i] + "-" + providerIdsArray[i]);
              Provider provider = ps.getProvider(Integer.valueOf(providerIdsArray[i]));
              EncounterRole encounterRole = es.getEncounterRole(Integer.valueOf(roleIdsArray[i]));
              // if this is an existing provider, don't create a new one to avoid losing existing
              // details like dateCreated, creator, uuid etc in the encounter_provider table
              if (encounter.getProvidersByRole(encounterRole).contains(provider)) {
                continue;
              }

              // this is a new provider
              encounter.addProvider(encounterRole, provider);
            }
          }
          // Get rid of the removed ones
          for (Map.Entry<EncounterRole, Set<Provider>> entry :
              encounter.getProvidersByRoles().entrySet()) {
            for (Provider p : entry.getValue()) {
              if (!unremovedRoleAndProviders.contains(
                  entry.getKey().getEncounterRoleId() + "-" + p.getProviderId())) {
                encounter.removeProvider(entry.getKey(), p);
              }
            }
          }
        }

        ValidationUtils.invokeValidator(new EncounterValidator(), encounter, errors);
      }
    } finally {
      Context.removeProxyPrivilege(PrivilegeConstants.VIEW_USERS);
      Context.removeProxyPrivilege(PrivilegeConstants.VIEW_PATIENTS);
    }

    return super.processFormSubmission(request, reponse, encounter, errors);
  }