@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; }
/** * Finds the right index at which to insert a new data approval level. Returns -1 if the new data * approval level is a duplicate. * * @param dataApprovalLevels list of all levels. * @param newLevel new level to find the insertion point for. * @return index where the new approval level should be inserted, or -1 if the new level is a * duplicate. */ private int getInsertIndex( List<DataApprovalLevel> dataApprovalLevels, DataApprovalLevel newLevel) { int i = dataApprovalLevels.size() - 1; while (i >= 0) { DataApprovalLevel test = dataApprovalLevels.get(i); int orgLevelDifference = newLevel.getOrgUnitLevel() - test.getOrgUnitLevel(); if (orgLevelDifference > 0) { break; } if (orgLevelDifference == 0) { if (newLevel.levelEquals(test)) { return -1; } if (test.getCategoryOptionGroupSet() == null) { break; } } i--; } return i + 1; }
@Override public boolean canDataApprovalLevelMoveUp(int level) { List<DataApprovalLevel> dataApprovalLevels = getAllDataApprovalLevels(); int index = level - 1; if (index <= 0 || index >= dataApprovalLevels.size()) { return false; } DataApprovalLevel test = dataApprovalLevels.get(index); DataApprovalLevel previous = dataApprovalLevels.get(index - 1); return test.getOrgUnitLevel() == previous.getOrgUnitLevel() && previous.getCategoryOptionGroupSet() != null; }
@Override public boolean canDataApprovalLevelMoveDown(int level) { List<DataApprovalLevel> dataApprovalLevels = getAllDataApprovalLevels(); int index = level - 1; if (index < 0 || index + 1 >= dataApprovalLevels.size()) { return false; } DataApprovalLevel test = dataApprovalLevels.get(index); DataApprovalLevel next = dataApprovalLevels.get(index + 1); return test.getOrgUnitLevel() == next.getOrgUnitLevel() && test.getCategoryOptionGroupSet() != null; }
/** * Get the approval level for a user for a given organisation unit. It is assumed that the user * has access to the organisation unit (must be checked elsewhere, it is not checked here.) If the * organisation unit is above all approval levels, returns null (no approval levels apply.) * * <p>If users are restricted to viewing approved data only, users may see data from lower levels * *only* if it is approved *below* this approval level (higher number approval level). Or, if * this method returns the lowest (highest number) approval level, users may see unapproved data. * * <p>If users have approve/unapprove authority (checked elsewhere, not here), the returned level * is the level at which users may approve/unapprove. If users have authority to approve at lower * levels, they may approve at levels below the returned level. * * <p>If users have accept/unaccept authority (checked elsewhere, not here), users may * accept/unaccept at the level just *below* this level. * * @param orgUnit organisation unit to test. * @param user the user. * @param approvalLevels app data approval levels. * @return approval level for user. */ private DataApprovalLevel getUserApprovalLevel( OrganisationUnit orgUnit, User user, List<DataApprovalLevel> approvalLevels) { int userOrgUnitLevel = orgUnit.getLevel(); DataApprovalLevel userLevel = null; for (DataApprovalLevel level : approvalLevels) { if (level.getOrgUnitLevel() >= userOrgUnitLevel && securityService.canRead(level) && canReadCOGS(user, level.getCategoryOptionGroupSet())) { userLevel = level; break; } } return userLevel; }
@Override public List<DataApprovalLevel> getUserDataApprovalLevels() { UserCredentials userCredentials = currentUserService.getCurrentUser().getUserCredentials(); boolean mayApprove = userCredentials.isAuthorized(DataApproval.AUTH_APPROVE); boolean mayApproveAtLowerLevels = userCredentials.isAuthorized(DataApproval.AUTH_APPROVE_LOWER_LEVELS); boolean mayAcceptAtLowerLevels = userCredentials.isAuthorized(DataApproval.AUTH_ACCEPT_LOWER_LEVELS); if (!mayApprove && !mayApproveAtLowerLevels && !mayAcceptAtLowerLevels) { return new ArrayList<>(); } int lowestNumberOrgUnitLevel = getCurrentUsersLowestNumberOrgUnitLevel(); boolean canSeeAllDimensions = CollectionUtils.isEmpty(userService.getCoDimensionConstraints(userCredentials)) && CollectionUtils.isEmpty(userService.getCogDimensionConstraints(userCredentials)); List<DataApprovalLevel> approvalLevels = getAllDataApprovalLevels(); List<DataApprovalLevel> userDataApprovalLevels = new ArrayList<>(); boolean addLevel = false; for (DataApprovalLevel approvalLevel : approvalLevels) { if (!addLevel && approvalLevel.getOrgUnitLevel() >= lowestNumberOrgUnitLevel) { CategoryOptionGroupSet cogs = approvalLevel.getCategoryOptionGroupSet(); addLevel = securityService.canRead(approvalLevel) && cogs == null ? canSeeAllDimensions : (securityService.canRead(cogs) && !CollectionUtils.isEmpty(categoryService.getCategoryOptionGroups(cogs))); } if (addLevel) { userDataApprovalLevels.add(approvalLevel); } } return userDataApprovalLevels; }