=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitService.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitService.java 2014-09-28 19:17:21 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitService.java 2014-09-28 20:14:48 +0000 @@ -238,6 +238,18 @@ Collection getOrganisationUnitsWithChildren( String uid ); /** + * Returns an OrganisationUnit and all its children. + * + * @param id the id of the parent OrganisationUnit in the subtree. + * @param maxLevels the max number of levels to return relative to + * the given root, inclusive. + * @return a collection containing the OrganisationUnit with the given id + * and all its children, or an empty collection if no + * OrganisationUnits match. + */ + Collection getOrganisationUnitWithChildren( int id, Integer maxLevels ); + + /** * Returns the OrganisationUnits and all their children. * * @param uids the uids of the parent OrganisationUnits. === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/organisationunit/DefaultOrganisationUnitService.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/organisationunit/DefaultOrganisationUnitService.java 2014-09-28 19:17:21 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/organisationunit/DefaultOrganisationUnitService.java 2014-09-28 20:14:48 +0000 @@ -301,12 +301,22 @@ public Collection getOrganisationUnitWithChildren( int id ) { + return getOrganisationUnitWithChildren( id, null ); + } + + public Collection getOrganisationUnitWithChildren( int id, Integer maxLevels ) + { OrganisationUnit organisationUnit = getOrganisationUnit( id ); if ( organisationUnit == null ) { return Collections.emptySet(); } + + if ( maxLevels != null && maxLevels <= 0 ) + { + return Collections.emptySet(); + } List result = new ArrayList<>(); @@ -315,7 +325,9 @@ organisationUnit.setLevel( rootLevel ); result.add( organisationUnit ); - addOrganisationUnitChildren( organisationUnit, result, rootLevel ); + final Integer maxLevel = maxLevels != null ? ( rootLevel + maxLevels - 1 ) : null; + + addOrganisationUnitChildren( organisationUnit, result, rootLevel, maxLevel ); return result; } @@ -324,12 +336,17 @@ * Support method for getOrganisationUnitWithChildren(). Adds all * OrganisationUnit children to a result collection. */ - private void addOrganisationUnitChildren( OrganisationUnit parent, List result, int level ) + private void addOrganisationUnitChildren( OrganisationUnit parent, List result, int level, final Integer maxLevel ) { if ( parent.getChildren() != null && parent.getChildren().size() > 0 ) { level++; } + + if ( maxLevel != null && level > maxLevel ) + { + return; + } List childList = parent.getSortedChildren(); @@ -338,7 +355,7 @@ child.setLevel( level ); result.add( child ); - addOrganisationUnitChildren( child, result, level ); + addOrganisationUnitChildren( child, result, level, maxLevel ); } } === modified file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/organisationunit/OrganisationUnitServiceTest.java' --- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/organisationunit/OrganisationUnitServiceTest.java 2014-08-27 11:57:02 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/organisationunit/OrganisationUnitServiceTest.java 2014-09-28 20:14:48 +0000 @@ -151,6 +151,64 @@ } @Test + public void testGetOrganisationUnitWithChildrenMaxLevel() + { + OrganisationUnit unit1 = createOrganisationUnit( 'A' ); + OrganisationUnit unit2 = createOrganisationUnit( 'B', unit1 ); + OrganisationUnit unit3 = createOrganisationUnit( 'C', unit1 ); + OrganisationUnit unit4 = createOrganisationUnit( 'D', unit2 ); + OrganisationUnit unit5 = createOrganisationUnit( 'E', unit2 ); + OrganisationUnit unit6 = createOrganisationUnit( 'F', unit3 ); + OrganisationUnit unit7 = createOrganisationUnit( 'G', unit3 ); + + unit1.getChildren().add( unit2 ); + unit1.getChildren().add( unit3 ); + unit2.getChildren().add( unit4 ); + unit2.getChildren().add( unit5 ); + unit3.getChildren().add( unit6 ); + unit3.getChildren().add( unit7 ); + + int id1 = organisationUnitService.addOrganisationUnit( unit1 ); + int id2 = organisationUnitService.addOrganisationUnit( unit2 ); + organisationUnitService.addOrganisationUnit( unit3 ); + int id4 = organisationUnitService.addOrganisationUnit( unit4 ); + organisationUnitService.addOrganisationUnit( unit5 ); + organisationUnitService.addOrganisationUnit( unit6 ); + organisationUnitService.addOrganisationUnit( unit7 ); + + List actual = new ArrayList<>( organisationUnitService.getOrganisationUnitWithChildren( id1, 0 ) ); + assertEquals( 0, actual.size() ); + + actual = new ArrayList<>( organisationUnitService.getOrganisationUnitWithChildren( id1, 1 ) ); + assertEquals( 1, actual.size() ); + assertTrue( actual.contains( unit1 ) ); + + actual = new ArrayList<>( organisationUnitService.getOrganisationUnitWithChildren( id1, 2 ) ); + assertEquals( 3, actual.size() ); + assertTrue( actual.contains( unit1 ) ); + assertTrue( actual.contains( unit2 ) ); + assertTrue( actual.contains( unit3 ) ); + + actual = new ArrayList<>( organisationUnitService.getOrganisationUnitWithChildren( id1, 3 ) ); + assertEquals( 7, actual.size() ); + + actual = new ArrayList<>( organisationUnitService.getOrganisationUnitWithChildren( id1, 8 ) ); + assertEquals( 7, actual.size() ); + + actual = new ArrayList<>( organisationUnitService.getOrganisationUnitWithChildren( id2, 1 ) ); + assertEquals( 1, actual.size() ); + + actual = new ArrayList<>( organisationUnitService.getOrganisationUnitWithChildren( id2, 2 ) ); + assertEquals( 3, actual.size() ); + + actual = new ArrayList<>( organisationUnitService.getOrganisationUnitWithChildren( id4, 1 ) ); + assertEquals( 1, actual.size() ); + + actual = new ArrayList<>( organisationUnitService.getOrganisationUnitWithChildren( id4, 8 ) ); + assertEquals( 1, actual.size() ); + } + + @Test public void testGetOrganisationUnitWithChildrenWithCorrectLevel() throws Exception { === modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/commons/action/GetOrganisationUnitTreeAction.java' --- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/commons/action/GetOrganisationUnitTreeAction.java 2014-09-19 16:13:09 +0000 +++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/commons/action/GetOrganisationUnitTreeAction.java 2014-09-28 20:14:48 +0000 @@ -28,24 +28,23 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import com.opensymphony.xwork2.Action; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + import org.hisp.dhis.common.comparator.IdentifiableObjectNameComparator; import org.hisp.dhis.configuration.ConfigurationService; import org.hisp.dhis.organisationunit.OrganisationUnit; import org.hisp.dhis.organisationunit.OrganisationUnitLevel; import org.hisp.dhis.organisationunit.OrganisationUnitService; -import org.hisp.dhis.system.util.CollectionUtils; -import org.hisp.dhis.system.util.functional.Predicate; import org.hisp.dhis.user.CurrentUserService; import org.hisp.dhis.user.User; import org.hisp.dhis.version.Version; import org.hisp.dhis.version.VersionService; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.UUID; +import com.opensymphony.xwork2.Action; /** * @author mortenoh @@ -218,48 +217,15 @@ if ( !versionOnly && !rootOrganisationUnits.isEmpty() ) { + OrganisationUnitLevel offlineOrgUnitLevel = configurationService.getConfiguration().getOfflineOrganisationUnitLevel(); + + List orgUnitLevels = organisationUnitService.getOrganisationUnitLevels(); + + final Integer maxLevels = ( offlineOrgUnitLevel != null && !orgUnitLevels.isEmpty() ) ? offlineOrgUnitLevel.getLevel() : null; + for ( OrganisationUnit unit : userOrganisationUnits ) { - organisationUnits.addAll( organisationUnitService.getOrganisationUnitWithChildren( unit.getId() ) ); - } - - // only try OU-level filtering if there are any levels available - if ( !organisationUnitService.getOrganisationUnitLevels().isEmpty() ) - { - OrganisationUnitLevel offlineOrganisationUnitLevel = configurationService.getConfiguration().getOfflineOrganisationUnitLevel(); - - int size = organisationUnitService.getOrganisationUnitLevels().size(); - - if ( offlineOrganisationUnitLevel == null ) - { - offlineOrganisationUnitLevel = organisationUnitService.getOrganisationUnitLevelByLevel( size ); - } - - int minLevel = rootOrganisationUnits.get( 0 ).getLevel(); - int maxLevel = Integer.MAX_VALUE; - - if ( organisationUnitService.getOrganisationUnitLevelByLevel( size ) != null ) - { - maxLevel = organisationUnitService.getOrganisationUnitLevelByLevel( size ).getLevel(); - } - - int total = minLevel + offlineOrganisationUnitLevel.getLevel() - 1; - - if ( total > offlineOrganisationUnitLevel.getLevel() ) - { - total = maxLevel; - } - - final int finalTotal = total; - - CollectionUtils.filter( organisationUnits, new Predicate() - { - @Override - public boolean evaluate( OrganisationUnit organisationUnit ) - { - return organisationUnit.getLevel() <= finalTotal; - } - } ); + organisationUnits.addAll( organisationUnitService.getOrganisationUnitWithChildren( unit.getId(), maxLevels ) ); } }