@Override
  public int addDataApprovalLevel(DataApprovalLevel level) {
    if (!prepareAddDataApproval(level)) {
      return -1;
    }

    return dataApprovalLevelStore.save(level);
  }
  @Override
  public Map<Integer, DataApprovalLevel> getDataApprovalLevelMap() {
    List<DataApprovalLevel> levels = dataApprovalLevelStore.getAllDataApprovalLevels();

    return Maps.uniqueIndex(
        levels,
        new Function<DataApprovalLevel, Integer>() {
          @Override
          public Integer apply(DataApprovalLevel level) {
            return level.getLevel();
          }
        });
  }
  @Override
  public Set<OrganisationUnitLevel> getOrganisationUnitApprovalLevels() {
    Set<OrganisationUnitLevel> orgUnitLevels = new HashSet<>();

    List<DataApprovalLevel> dataApprovalLevels = dataApprovalLevelStore.getAllDataApprovalLevels();

    for (DataApprovalLevel level : dataApprovalLevels) {
      OrganisationUnitLevel orgUnitLevel =
          organisationUnitService.getOrganisationUnitLevelByLevel(level.getOrgUnitLevel());

      if (orgUnitLevel != null) {
        orgUnitLevels.add(orgUnitLevel);
      }
    }

    return orgUnitLevels;
  }
  @Override
  public void deleteDataApprovalLevel(DataApprovalLevel dataApprovalLevel) {
    List<DataApprovalLevel> dataApprovalLevels = getAllDataApprovalLevels();

    int index = dataApprovalLevel.getLevel() - 1;

    if (index >= 0 && index < dataApprovalLevels.size()) {
      dataApprovalLevelStore.delete(dataApprovalLevel);

      dataApprovalLevels.remove(index);

      // Move up from here to end, to avoid duplicate level in database.

      for (int i = index; i < dataApprovalLevels.size(); i++) {
        update(dataApprovalLevels.get(i), i);
      }
    }
  }
  @Override
  public List<DataApprovalLevel> getAllDataApprovalLevels() {
    List<DataApprovalLevel> dataApprovalLevels = dataApprovalLevelStore.getAllDataApprovalLevels();

    for (DataApprovalLevel dataApprovalLevel : dataApprovalLevels) {
      int ouLevelNumber = dataApprovalLevel.getOrgUnitLevel();

      OrganisationUnitLevel ouLevel =
          organisationUnitService.getOrganisationUnitLevelByLevel(ouLevelNumber);

      String ouLevelName =
          ouLevel != null ? ouLevel.getName() : "Organisation unit level " + ouLevelNumber;

      dataApprovalLevel.setOrgUnitLevelName(ouLevelName);
    }

    return dataApprovalLevels;
  }
  /**
   * Updates a data approval level object by setting the level to correspond with the list index,
   * setting the updated date to now, and updating the object on disk.
   *
   * @param dataApprovalLevel data approval level to update
   * @param index index of the object (used to set the level.)
   */
  private void update(DataApprovalLevel dataApprovalLevel, int index) {
    dataApprovalLevel.setLevel(index + 1);

    dataApprovalLevelStore.update(dataApprovalLevel);
  }
  @Override
  public int addDataApprovalLevel(DataApprovalLevel approvalLevel, int level) {
    approvalLevel.setLevel(level);

    return dataApprovalLevelStore.save(approvalLevel);
  }
 @Override
 public List<DataApprovalLevel> getDataApprovalLevelsByOrgUnitLevel(int orgUnitLevel) {
   return dataApprovalLevelStore.getDataApprovalLevelsByOrgUnitLevel(orgUnitLevel);
 }
 @Override
 public DataApprovalLevel getDataApprovalLevelByName(String name) {
   return dataApprovalLevelStore.getByName(name);
 }
 @Override
 public DataApprovalLevel getDataApprovalLevel(String uid) {
   return dataApprovalLevelStore.getByUid(uid);
 }
 @Override
 public DataApprovalLevel getDataApprovalLevel(int id) {
   return dataApprovalLevelStore.get(id);
 }