@Test
  public void testPutFacilityUuid() throws Exception {
    OrganisationUnit organisationUnit = createOrganisationUnit('A');
    manager.save(organisationUnit);

    Facility facility = new OrganisationUnitToFacilityConverter().convert(organisationUnit);
    facility.setName("FacilityB");
    facility.setActive(false);

    MockHttpSession session = getSession("ALL");

    mvc.perform(
            put("/fred/v1/facilities/" + organisationUnit.getUuid())
                .content(objectMapper.writeValueAsString(facility))
                .session(session)
                .contentType(MediaType.APPLICATION_JSON))
        .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
        .andExpect(jsonPath("$.uuid", Matchers.notNullValue()))
        .andExpect(jsonPath("$.name").value("FacilityB"))
        .andExpect(jsonPath("$.active").value(false))
        .andExpect(jsonPath("$.createdAt", Matchers.notNullValue()))
        .andExpect(jsonPath("$.updatedAt", Matchers.notNullValue()))
        .andExpect(header().string("ETag", Matchers.notNullValue()))
        .andExpect(status().isOk());
  }
  @Override
  public String execute() throws Exception {
    Program program = programService.getProgram(programId);

    Collection<OrganisationUnit> orgunits = selectionTreeManager.getRootOrganisationUnits();

    program = programService.getProgram(programId);

    // ---------------------------------------------------------------------
    // Get orgunitIds
    // ---------------------------------------------------------------------

    Collection<Integer> orgunitIds = new HashSet<>();

    for (OrganisationUnit orgunit : orgunits) {
      if (facilityLB.equals("selected")) {
        orgunitIds.add(orgunit.getId());
      } else if (facilityLB.equals("childrenOnly")) {
        orgunitIds.addAll(
            organisationUnitService.getOrganisationUnitHierarchy().getChildren(orgunit.getId()));
        orgunitIds.remove(orgunit.getId());
      } else {
        orgunitIds.addAll(
            organisationUnitService.getOrganisationUnitHierarchy().getChildren(orgunit.getId()));
      }
    }

    if (orgunitIds.size() > 0) {
      grid =
          programStageInstanceService.getCompletenessProgramStageInstance(
              orgunitIds, program, startDate, endDate, i18n);
    }

    return (type == null) ? SUCCESS : type;
  }
  public Collection<ValidationResult> validate(
      Date startDate, Date endDate, Collection<OrganisationUnit> sources) {
    Map<String, Double> constantMap = constantService.getConstantMap();

    Collection<ValidationResult> validationViolations = new HashSet<ValidationResult>();

    Collection<Period> relevantPeriods = periodService.getPeriodsBetweenDates(startDate, endDate);

    for (OrganisationUnit source : sources) {
      Collection<ValidationRule> relevantRules =
          getRelevantValidationRules(source.getDataElementsInDataSets());

      Set<DataElement> dataElements =
          getDataElementsInValidationRules(relevantRules); // TODO move outside loop?

      if (relevantRules != null && relevantRules.size() > 0) {
        for (Period period : relevantPeriods) {
          validationViolations.addAll(
              validateInternal(
                  period,
                  source,
                  relevantRules,
                  dataElements,
                  constantMap,
                  validationViolations.size()));
        }
      }
    }

    return validationViolations;
  }
  public String execute() throws Exception {
    // ---------------------------------------------------------------------
    // Get parent
    // ---------------------------------------------------------------------

    OrganisationUnit newParent;

    if (newParentOrganisationUnitId != null) {
      newParent =
          organisationUnitService.getOrganisationUnit(newParentOrganisationUnitId.intValue());
    } else {
      newParent = selectionManager.getRootOrganisationUnitsParent();
    }

    // ---------------------------------------------------------------------
    // Update unit to move
    // ---------------------------------------------------------------------

    OrganisationUnit unitToMove =
        organisationUnitService.getOrganisationUnit(organisationUnitToMoveId.intValue());

    unitToMove.setParent(newParent);

    organisationUnitService.updateOrganisationUnit(unitToMove);

    organisationUnitService.addOrganisationUnitHierarchy(new Date());

    return SUCCESS;
  }
  public Collection<ValidationResult> validate(
      Date startDate,
      Date endDate,
      Collection<OrganisationUnit> sources,
      ValidationRuleGroup group) {
    Map<String, Double> constantMap = constantService.getConstantMap();

    Collection<ValidationResult> validationViolations = new HashSet<ValidationResult>();

    Collection<Period> relevantPeriods = periodService.getPeriodsBetweenDates(startDate, endDate);

    for (OrganisationUnit source : sources) {
      Collection<ValidationRule> relevantRules =
          getRelevantValidationRules(source.getDataElementsInDataSets());
      relevantRules.retainAll(group.getMembers());

      Set<DataElement> dataElements = getDataElementsInValidationRules(relevantRules);

      if (!relevantRules.isEmpty()) {
        for (Period period : relevantPeriods) {
          validationViolations.addAll(
              validateInternal(
                  period,
                  source,
                  relevantRules,
                  dataElements,
                  constantMap,
                  validationViolations.size()));
        }
      }
    }

    return validationViolations;
  }
  public void postObject(
      HttpServletResponse response, HttpServletRequest request, Message message) {
    List<User> users = new ArrayList<User>(message.getUsers());
    message.getUsers().clear();

    for (OrganisationUnit ou : message.getOrganisationUnits()) {
      OrganisationUnit organisationUnit = organisationUnitService.getOrganisationUnit(ou.getUid());

      if (organisationUnit == null) {
        ContextUtils.conflictResponse(response, "Organisation Unit does not exist: " + ou.getUid());
        return;
      }

      message.getUsers().addAll(organisationUnit.getUsers());
    }

    for (User u : users) {
      User user = userService.getUser(u.getUid());

      if (user == null) {
        ContextUtils.conflictResponse(response, "User does not exist: " + u.getUid());
        return;
      }

      message.getUsers().add(user);
    }

    for (UserGroup ug : message.getUserGroups()) {
      UserGroup userGroup = userGroupService.getUserGroup(ug.getUid());

      if (userGroup == null) {
        ContextUtils.conflictResponse(response, "User Group does not exist: " + ug.getUid());
        return;
      }

      message.getUsers().addAll(userGroup.getMembers());
    }

    if (message.getUsers().isEmpty()) {
      ContextUtils.conflictResponse(response, "No recipients selected.");
      return;
    }

    String metaData =
        MessageService.META_USER_AGENT + request.getHeader(ContextUtils.HEADER_USER_AGENT);

    int id =
        messageService.sendMessage(
            message.getSubject(), message.getText(), metaData, message.getUsers());

    MessageConversation conversation = messageService.getMessageConversation(id);

    ContextUtils.createdResponse(
        response,
        "Message conversation created",
        MessageConversationController.RESOURCE_PATH + "/" + conversation.getUid());
  }
  private String getHierarchyOrgunit(OrganisationUnit orgunit) {
    String hierarchyOrgunit = orgunit.getName();

    while (orgunit.getParent() != null) {
      hierarchyOrgunit = orgunit.getParent().getName() + " / " + hierarchyOrgunit;

      orgunit = orgunit.getParent();
    }

    return hierarchyOrgunit;
  }
  @Test
  public void testDeleteFacilityUuid() throws Exception {
    OrganisationUnit organisationUnit = createOrganisationUnit('A');
    manager.save(organisationUnit);

    MockHttpSession session = getSession("ALL");

    mvc.perform(delete("/fred/v1/facilities/" + organisationUnit.getUuid()).session(session))
        .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
        .andExpect(status().isOk());
  }
  private Collection<OrganisationUnit> getHierarchy() {
    Collection<OrganisationUnit> hierarchy = new ArrayList<OrganisationUnit>();

    Collection<OrganisationUnit> roots = organisationUnitService.getRootOrganisationUnits();

    for (OrganisationUnit root : roots) {
      hierarchy.addAll(organisationUnitService.getOrganisationUnitWithChildren(root.getId()));
    }

    return hierarchy;
  }
  protected String getUniquenessStatement(Object object) {
    OrganisationUnit unit = (OrganisationUnit) object;

    Map<String, String> fieldMap = new HashMap<String, String>();

    fieldMap.put("name", unit.getName());
    fieldMap.put("shortname", unit.getShortName());
    fieldMap.put("code", unit.getOrganisationUnitCode());

    return statementBuilder.getValueStatement(tableName, "organisationunitid", fieldMap, false);
  }
  @Override
  public void setRootOrganisationUnitsParent(OrganisationUnit rootUnitsParent) {
    if (rootUnitsParent == null) {
      throw new IllegalArgumentException("Root OrganisationUnits parent cannot be null");
    }

    OrganisationUnit reloadedRootUnitsParent = reloadOrganisationUnit(rootUnitsParent);

    saveToSession(SESSION_KEY_ROOT_ORG_UNITS, reloadedRootUnitsParent.getChildren());

    clearSelectedOrganisationUnits();
  }
  /**
   * Finds the lowest number (highest level) organisaiton unit level from the organisations assigned
   * to the current user.
   */
  private int getCurrentUsersLowestNumberOrgUnitLevel() {
    int level = APPROVAL_LEVEL_UNAPPROVED;

    Set<OrganisationUnit> userOrgUnits = currentUserService.getCurrentUser().getOrganisationUnits();

    for (OrganisationUnit orgUnit : userOrgUnits) {
      if (orgUnit.getLevel() < level) {
        level = orgUnit.getLevel();
      }
    }
    return level;
  }
  protected String getUpdateSqlStatement(Object object) {
    OrganisationUnit unit = (OrganisationUnit) object;

    statementBuilder.setIdentifierColumnName("organisationunitid");
    statementBuilder.setIdentifierColumnValue(unit.getId());

    addColumns();

    addValues(object);

    return statementBuilder.getUpdateStatement(tableName);
  }
  public String execute() {
    relationshipTypes =
        new ArrayList<RelationshipType>(relationshipTypeService.getAllRelationshipTypes());

    identifierTypes = patientIdentifierTypeService.getAllPatientIdentifierTypes();

    attributes = patientAttributeService.getAllPatientAttributes();

    OrganisationUnit organisationUnit = selectionManager.getSelectedOrganisationUnit();
    healthWorkers = organisationUnit.getUsers();

    return SUCCESS;
  }
  @Test
  public void testPutFacilityWithoutRequiredPropertiesUuid() throws Exception {
    OrganisationUnit organisationUnit = createOrganisationUnit('A');
    manager.save(organisationUnit);

    MockHttpSession session = getSession("ALL");

    mvc.perform(
            put("/fred/v1/facilities/" + organisationUnit.getUuid())
                .content("{}")
                .session(session)
                .contentType(MediaType.APPLICATION_JSON))
        .andExpect(status().isUnprocessableEntity());
  }
  @Test
  public void testPutInvalidJsonUuid() throws Exception {
    OrganisationUnit organisationUnit = createOrganisationUnit('A');
    manager.save(organisationUnit);

    MockHttpSession session = getSession("ALL");

    mvc.perform(
            put("/fred/v1/facilities/" + organisationUnit.getUuid())
                .content("INVALID JSON")
                .session(session)
                .contentType(MediaType.APPLICATION_JSON))
        .andExpect(status().isBadRequest());
  }
  @Override
  public OrganisationUnit getRootOrganisationUnitsParent() {
    Collection<OrganisationUnit> rootUnits = getCollectionFromSession(SESSION_KEY_ROOT_ORG_UNITS);

    if (rootUnits == null || rootUnits.isEmpty()) {
      return null;
    }

    OrganisationUnit randomRootUnit = rootUnits.iterator().next();

    OrganisationUnit reloadedRootUnit = reloadOrganisationUnit(randomRootUnit);

    return reloadedRootUnit.getParent();
  }
  @Test
  public void testGetFacilityVerifyPresenceOfETag() throws Exception {
    OrganisationUnit organisationUnit = createOrganisationUnit('A');
    manager.save(organisationUnit);

    MockHttpSession session = getSession("ALL");

    mvc.perform(
            get("/fred/v1/facilities/" + organisationUnit.getUid())
                .session(session)
                .accept(MediaType.APPLICATION_JSON))
        .andExpect(header().string("ETag", Matchers.notNullValue()))
        .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
        .andExpect(status().isOk());
  }
  @Override
  public DataApprovalLevel getLowestDataApprovalLevel(
      OrganisationUnit orgUnit, DataElementCategoryOptionCombo attributeOptionCombo) {
    Set<CategoryOptionGroupSet> cogSets = null;

    if (attributeOptionCombo != null
        && attributeOptionCombo != categoryService.getDefaultDataElementCategoryOptionCombo()) {
      cogSets = new HashSet<>();

      for (DataElementCategoryOption option : attributeOptionCombo.getCategoryOptions()) {
        if (option.getGroupSets() != null) {
          cogSets.addAll(option.getGroupSets());
        }
      }
    }

    int orgUnitLevel = orgUnit.getLevel();

    List<DataApprovalLevel> approvalLevels = getDataApprovalLevelsByOrgUnitLevel(orgUnitLevel);

    for (DataApprovalLevel level : Lists.reverse(approvalLevels)) {
      if (level.getCategoryOptionGroupSet() == null) {
        if (cogSets == null) {
          return level;
        }
      } else if (cogSets != null && cogSets.contains(level.getCategoryOptionGroupSet())) {
        return level;
      }
    }

    return null;
  }
  /**
   * Determines whether a user can access an organisation unit, based on the organisation units to
   * which the user has been assigned.
   *
   * @param user user to test
   * @param source organisation unit to which the user may have access
   * @return whether the user has acceess to the organisation unit
   */
  private boolean canUserAccessSource(User user, OrganisationUnit source) {
    for (OrganisationUnit o : user.getOrganisationUnits()) {
      if (source == o || source.getAncestors().contains(o)) {
        return true;
      }
    }

    return false;
  }
  // TODO: this should fail, need to figure out which code to return
  @Test
  public void testPutChangeUuidShouldFail() throws Exception {
    OrganisationUnit organisationUnit = createOrganisationUnit('A');
    organisationUnit.setUuid("ddccbbaa-bbaa-bbaa-bbaa-ffeeddccbbaa");
    manager.save(organisationUnit);

    Facility facility = new OrganisationUnitToFacilityConverter().convert(organisationUnit);
    facility.setUuid("aabbccdd-aabb-aabb-aabb-aabbccddeeff");

    MockHttpSession session = getSession("ALL");

    mvc.perform(
            put("/fred/v1/facilities/" + organisationUnit.getUuid())
                .content(objectMapper.writeValueAsString(facility))
                .session(session)
                .contentType(MediaType.APPLICATION_JSON))
        .andExpect(status().isOk());
  }
  @Test
  public void testPutInvalidUuidShouldFail() throws Exception {
    OrganisationUnit organisationUnit = createOrganisationUnit('A');
    manager.save(organisationUnit);

    Facility facility = new OrganisationUnitToFacilityConverter().convert(organisationUnit);
    facility.setUuid("DUMMY_UUID");

    MockHttpSession session = getSession("ALL");

    mvc.perform(
            put("/fred/v1/facilities/" + organisationUnit.getUuid())
                .content(objectMapper.writeValueAsString(facility))
                .session(session)
                .contentType(MediaType.APPLICATION_JSON))
        .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
        .andExpect(status().isPreconditionFailed());
  }
  // -------------------------------------------------------------------------
  // Action implementation
  // -------------------------------------------------------------------------
  public String execute() throws Exception {
    statementManager.initialise();

    Program selProgram = programService.getProgram(programList);

    OrganisationUnit selOrgUnit = organisationUnitService.getOrganisationUnit(ouIDTB);

    System.out.println(
        "NBITS Report_"
            + selOrgUnit.getName()
            + "_"
            + selProgram.getName()
            + "_StartTime: "
            + new Date());

    List<OrganisationUnit> orgUnitList =
        new ArrayList<OrganisationUnit>(
            organisationUnitService.getOrganisationUnitWithChildren(ouIDTB));

    List<OrganisationUnit> programOrgUnits =
        new ArrayList<OrganisationUnit>(selProgram.getOrganisationUnits());

    orgUnitList.retainAll(programOrgUnits);

    Date sDate = format.parseDate(startDate);

    Date eDate = format.parseDate(endDate);

    System.out.println("Start Date" + sDate + "-----" + "End Date: " + eDate);
    generateReport(selProgram, orgUnitList, sDate, eDate);

    System.out.println(
        "NBITS Report_"
            + selOrgUnit.getName()
            + "_"
            + selProgram.getName()
            + "_EndTime: "
            + new Date());

    statementManager.destroy();

    return SUCCESS;
  }
  public void write(XMLWriter writer, ExportParams params) {
    Collection<OrganisationUnitGroup> groups = params.getOrganisationUnitGroups();

    for (OrganisationUnitGroup group : groups) {
      if (group.getMembers() != null) {
        for (OrganisationUnit unit : group.getMembers()) {
          if (params.getOrganisationUnits().contains(unit)) {
            writer.openElement(ELEMENT_NAME);

            writer.writeElement(FIELD_GROUP_ID, String.valueOf(group.getId()));
            writer.writeElement(FIELD_UNIT_ID, String.valueOf(unit.getId()));
            writer.writeElement(FIELD_LAST_USER, new String());
            writer.writeElement(FIELD_LAST_UPDATED, new String());

            writer.closeElement(ELEMENT_NAME);
          }
        }
      }
    }
  }
  @Test
  public void testGetFacilityUuid() throws Exception {
    OrganisationUnit organisationUnit = createOrganisationUnit('A');
    manager.save(organisationUnit);

    MockHttpSession session = getSession("ALL");

    mvc.perform(
            get("/fred/v1/facilities/" + organisationUnit.getUuid())
                .session(session)
                .accept(MediaType.APPLICATION_JSON))
        .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
        .andExpect(jsonPath("$.uuid", Matchers.notNullValue()))
        .andExpect(jsonPath("$.name").value("OrgUnitA"))
        .andExpect(jsonPath("$.active").value(true))
        .andExpect(jsonPath("$.createdAt", Matchers.notNullValue()))
        .andExpect(jsonPath("$.updatedAt", Matchers.notNullValue()))
        .andExpect(header().string("ETag", Matchers.notNullValue()))
        .andExpect(status().isOk());
  }
  private List<DataSet> getDataSetsForCurrentUser(int id) {
    OrganisationUnit organisationUnit = organisationUnitService.getOrganisationUnit(id);

    if (organisationUnit == null) {
      return new ArrayList<DataSet>();
    }

    List<DataSet> dataSets = new ArrayList<DataSet>();

    if (organisationUnit.getDataSets() != null) {
      dataSets.addAll(organisationUnit.getDataSets());
    }

    UserCredentials userCredentials = currentUserService.getCurrentUser().getUserCredentials();

    if (!userCredentials.isSuper()) {
      dataSets.retainAll(userCredentials.getAllDataSets());
    }

    return dataSets;
  }
  private Grid generateGrid() {
    final Grid orgUnitGrid = new ListGrid().setTitle("Organisation unit search result");

    orgUnitGrid.addHeader(new GridHeader("Code", false, true));
    orgUnitGrid.addHeader(new GridHeader("Name", false, true));

    for (OrganisationUnitGroupSet groupSet : groupSets) {
      orgUnitGrid.addHeader(new GridHeader(groupSet.getName(), false, true));
    }

    for (OrganisationUnit unit : organisationUnits) {
      orgUnitGrid.addRow();

      orgUnitGrid.addValue(unit.getCode());
      orgUnitGrid.addValue(unit.getName());

      for (OrganisationUnitGroupSet groupSet : groupSets) {
        orgUnitGrid.addValue(unit.getGroupNameInGroupSet(groupSet));
      }
    }

    return orgUnitGrid;
  }
  public void write(Document document, ExportParams params) {
    I18n i18n = params.getI18n();
    I18nFormat format = params.getFormat();

    PDFUtils.printObjectFrontPage(
        document, params.getOrganisationUnits(), i18n, format, "organisation_unit_hierarchy");

    if (params.getOrganisationUnits() != null && params.getOrganisationUnits().size() > 0) {
      Collection<OrganisationUnit> hierarchy = getHierarchy();

      PdfPTable table = getPdfPTable(false, 0.100f);

      for (OrganisationUnit unit : hierarchy) {
        String indent = getIndent(unit.getLevel());

        table.addCell(getTextCell(indent + unit.getName()));
      }

      addTableToDocument(document, table);

      moveToNewPage(document);
    }
  }
  private Collection<OrganisationUnit> getUnitsInTree(
      Collection<OrganisationUnit> rootUnits, Collection<OrganisationUnit> selectedUnits) {
    Collection<OrganisationUnit> unitsInTree = new ArrayList<>();

    for (OrganisationUnit selectedUnit : selectedUnits) {
      if (rootUnits.contains(selectedUnit)) {
        unitsInTree.add(selectedUnit);
        continue;
      }

      OrganisationUnit parent = selectedUnit.getParent();

      while (parent != null) {
        if (rootUnits.contains(parent)) {
          unitsInTree.add(selectedUnit);
        }

        parent = parent.getParent();
      }
    }

    return unitsInTree;
  }
  public void handleRow(Object object) {
    OrganisationUnit unit = (OrganisationUnit) object;

    NameMappingUtil.addOrganisationUnitMapping(unit.getId(), unit.getName());

    unit.setUuid(UUIdUtils.getUUId());

    if (unit.getOrganisationUnitCode() != null
        && unit.getOrganisationUnitCode().trim().length() == 0) {
      unit.setOrganisationUnitCode(null);
    }

    read(unit, OrganisationUnit.class, GroupMemberType.NONE, params);
  }