=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/chart/Chart.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/chart/Chart.java 2013-05-29 13:05:35 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/chart/Chart.java 2013-07-04 15:41:57 +0000 @@ -114,6 +114,8 @@ private transient List relativePeriods = new ArrayList(); private transient User user; + + private transient List organisationUnitsAtLevel = new ArrayList(); // ------------------------------------------------------------------------- // Constructors @@ -132,11 +134,13 @@ // Init // ------------------------------------------------------------------------- - public void init( User user, Date date, OrganisationUnit organisationUnit, I18nFormat format ) + @Override + public void init( User user, Date date, OrganisationUnit organisationUnit, List organisationUnitsAtLevel, I18nFormat format ) { this.user = user; this.relativePeriodDate = date; this.relativeOrganisationUnit = organisationUnit; + this.organisationUnitsAtLevel = organisationUnitsAtLevel; this.format = format; } @@ -146,14 +150,14 @@ public List series() { - DimensionalObject object = getDimensionalObject( series, relativePeriodDate, user, true, format ); + DimensionalObject object = getDimensionalObject( series, relativePeriodDate, user, true, organisationUnitsAtLevel, format ); return object != null ? object.getItems() : null; } public List category() { - DimensionalObject object = getDimensionalObject( category, relativePeriodDate, user, true, format ); + DimensionalObject object = getDimensionalObject( category, relativePeriodDate, user, true, organisationUnitsAtLevel, format ); return object != null ? object.getItems() : null; } @@ -164,7 +168,7 @@ for ( String filter : filterDimensions ) { - DimensionalObject object = getDimensionalObject( filter, relativePeriodDate, user, true, format ); + DimensionalObject object = getDimensionalObject( filter, relativePeriodDate, user, true, organisationUnitsAtLevel, format ); if ( object != null ) { === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseAnalyticalObject.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseAnalyticalObject.java 2013-06-25 17:43:37 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseAnalyticalObject.java 2013-07-04 15:41:57 +0000 @@ -38,6 +38,7 @@ import static org.hisp.dhis.common.DimensionalObject.DIMENSION_SEP; import static org.hisp.dhis.organisationunit.OrganisationUnit.KEY_USER_ORGUNIT; import static org.hisp.dhis.organisationunit.OrganisationUnit.KEY_USER_ORGUNIT_CHILDREN; +import static org.hisp.dhis.organisationunit.OrganisationUnit.KEY_LEVEL; import java.util.ArrayList; import java.util.Arrays; @@ -84,11 +85,15 @@ * This class contains associations to dimensional meta-data. Should typically * be sub-classed by analytical objects like tables, maps and charts. * + * Implementation note: Objects currently managing this class are AnalyticsService, + * DefaultDimensionService and the getDimensionalObject and getDimensionalObjectList + * methods of this class. + * * @author Lars Helge Overland */ public abstract class BaseAnalyticalObject extends BaseIdentifiableObject -{ +{ // ------------------------------------------------------------------------- // Persisted properties // ------------------------------------------------------------------------- @@ -126,6 +131,8 @@ protected boolean userOrganisationUnitChildren; + protected Integer organisationUnitLevel; + protected boolean rewindRelativePeriods; // ------------------------------------------------------------------------- @@ -156,6 +163,8 @@ // Logic // ------------------------------------------------------------------------- + public abstract void init( User user, Date date, OrganisationUnit organisationUnit, List organisationUnitsAtLevel, I18nFormat format ); + public abstract void populateAnalyticalProperties(); public boolean hasUserOrgUnit() @@ -198,7 +207,7 @@ * @param format the I18nFormat. * @return a DimensionalObject. */ - protected DimensionalObject getDimensionalObject( String dimension, Date date, User user, boolean dynamicNames, I18nFormat format ) + protected DimensionalObject getDimensionalObject( String dimension, Date date, User user, boolean dynamicNames, List organisationUnitsAtLevel, I18nFormat format ) { List items = new ArrayList(); @@ -250,6 +259,11 @@ items.addAll( user.getOrganisationUnit().getSortedChildren() ); } + if ( organisationUnitLevel != null && organisationUnitsAtLevel != null ) + { + items.addAll( organisationUnitsAtLevel ); + } + type = DimensionType.ORGANISATIONUNIT; } else if ( CATEGORYOPTIONCOMBO_DIM_ID.equals( dimension ) ) @@ -383,6 +397,16 @@ ouList.add( new BaseNameableObject( KEY_USER_ORGUNIT_CHILDREN, KEY_USER_ORGUNIT_CHILDREN, KEY_USER_ORGUNIT_CHILDREN ) ); } + if ( organisationUnitLevel != null ) + { + for ( OrganisationUnit unit : organisationUnits ) + { + String id = KEY_LEVEL + organisationUnitLevel + DimensionalObject.DIMENSION_SEP + unit.getUid(); + + ouList.add( new BaseNameableObject( id, id, id ) ); + } + } + objects.add( new BaseDimensionalObject( dimension, DimensionType.ORGANISATIONUNIT, ouList ) ); } else if ( CATEGORYOPTIONCOMBO_DIM_ID.equals( dimension ) ) @@ -546,7 +570,8 @@ categoryDimensions.addAll( object.getCategoryDimensions() ); userOrganisationUnit = object.isUserOrganisationUnit(); - userOrganisationUnitChildren = object.isUserOrganisationUnitChildren(); + userOrganisationUnitChildren = object.isUserOrganisationUnitChildren(); + organisationUnitLevel = object.getOrganisationUnitLevel(); } } @@ -725,6 +750,19 @@ @JsonProperty @JsonView( {DetailedView.class, ExportView.class} ) @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0) + public Integer getOrganisationUnitLevel() + { + return organisationUnitLevel; + } + + public void setOrganisationUnitLevel( Integer organisationUnitLevel ) + { + this.organisationUnitLevel = organisationUnitLevel; + } + + @JsonProperty + @JsonView( {DetailedView.class, ExportView.class} ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0) public boolean isRewindRelativePeriods() { return rewindRelativePeriods; === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseDimensionalObject.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseDimensionalObject.java 2013-05-24 10:04:42 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/BaseDimensionalObject.java 2013-07-04 15:41:57 +0000 @@ -74,6 +74,12 @@ this.uid = dimension; } + public BaseDimensionalObject( String dimension, List items ) + { + this.uid = dimension; + this.items = new ArrayList( items ); + } + public BaseDimensionalObject( String dimension, DimensionType type, List items ) { this.uid = dimension; === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionalObjectUtils.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionalObjectUtils.java 2013-06-05 12:45:22 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionalObjectUtils.java 2013-07-04 15:41:57 +0000 @@ -124,4 +124,46 @@ return map; } + + /** + * Retrieves the level from a level parameter string, which is on the format + * LEVEL-- . + */ + public static int getLevelFromLevelParam( String param ) + { + if ( param == null ) + { + return 0; + } + + String[] split = param.split( "-" ); + + if ( split.length > 1 ) // TODO check if valid integer + { + return Integer.parseInt( split[1] ); + } + + return 0; + } + + /** + * Retrieves the boundary dimension item from a level parameter string, which + * is on the format LEVEL-- . + */ + public static String getBoundaryFromLevelParam( String param ) + { + if ( param == null ) + { + return null; + } + + String[] split = param.split( "-" ); + + if ( split.length > 2 && split[2] != null ) + { + return split[2]; + } + + return null; + } } === 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 2013-05-20 06:54:42 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitService.java 2013-07-04 15:41:57 +0000 @@ -282,6 +282,18 @@ Collection getOrganisationUnitsAtLevel( int level, OrganisationUnit parent ); /** + * Returns all OrganisationUnits which are children of the given units and are + * at the given hierarchical level. The root OrganisationUnits are at level 1. + * + * @param level the hierarchical level. + * @param parent the parent units. + * @return all OrganisationUnits which are children of the given units and are + * at the given hierarchical level. + * @throws IllegalArgumentException if the level is illegal. + */ + Collection getOrganisationUnitsAtLevel( int level, Collection parents ); + + /** * Returns the number of levels in the OrganisationUnit hierarchy. * * @return the number of hierarchical levels. === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/reporttable/ReportTable.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/reporttable/ReportTable.java 2013-06-05 20:11:33 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/reporttable/ReportTable.java 2013-07-04 15:41:57 +0000 @@ -299,7 +299,8 @@ // Init // ------------------------------------------------------------------------- - public void init( User user, Date date, OrganisationUnit organisationUnit, I18nFormat format ) + @Override + public void init( User user, Date date, OrganisationUnit organisationUnit, List organisationUnitsAtLevel, I18nFormat format ) { verify( ( periods != null && !periods.isEmpty() ) || hasRelativePeriods(), "Must contain periods or relative periods" ); @@ -336,14 +337,14 @@ // Populate grid - this.populateGridColumnsAndRows( date, user, format ); + this.populateGridColumnsAndRows( date, user, organisationUnitsAtLevel, format ); } // ------------------------------------------------------------------------- // Public methods // ------------------------------------------------------------------------- - public void populateGridColumnsAndRows( Date date, User user, I18nFormat format ) + public void populateGridColumnsAndRows( Date date, User user, List organisationUnitsAtLevel, I18nFormat format ) { List tableColumns = new ArrayList(); List tableRows = new ArrayList(); @@ -351,17 +352,17 @@ for ( String dimension : columnDimensions ) { - tableColumns.add( getDimensionalObject( dimension, date, user, false, format ).getItems().toArray( IRT ) ); + tableColumns.add( getDimensionalObject( dimension, date, user, false, organisationUnitsAtLevel, format ).getItems().toArray( IRT ) ); } for ( String dimension : rowDimensions ) { - tableRows.add( getDimensionalObject( dimension, date, user, true, format ).getItems().toArray( IRT ) ); + tableRows.add( getDimensionalObject( dimension, date, user, true, organisationUnitsAtLevel, format ).getItems().toArray( IRT ) ); } for ( String filter : filterDimensions ) { - filterItems.addAll( getDimensionalObject( filter, date, user, true, format ).getItems() ); + filterItems.addAll( getDimensionalObject( filter, date, user, true, organisationUnitsAtLevel, format ).getItems() ); } gridColumns = new CombinationGenerator( tableColumns.toArray( IRT2D ) ).getCombinations(); === modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java' --- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java 2013-06-06 08:48:20 +0000 +++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java 2013-07-04 15:41:57 +0000 @@ -169,12 +169,17 @@ @Autowired private ConstantService constantService; - + + @Autowired + private DataElementOperandService operandService; + @Autowired private CurrentUserService currentUserService; - - @Autowired - private DataElementOperandService operandService; + + public void setCurrentUserService( CurrentUserService currentUserService ) + { + this.currentUserService = currentUserService; // Testing purposes + } // ------------------------------------------------------------------------- // Implementation @@ -808,6 +813,7 @@ else if ( ou != null && ou.startsWith( KEY_LEVEL ) ) { int level = DataQueryParams.getLevelFromLevelParam( ou ); + String boundaryId = DataQueryParams.getBoundaryFromLevelParam( ou ); OrganisationUnit boundary = null; === modified file 'dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/data/AnalyticsServiceTest.java' --- dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/data/AnalyticsServiceTest.java 2013-05-29 18:35:32 +0000 +++ dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/data/AnalyticsServiceTest.java 2013-07-04 15:41:57 +0000 @@ -41,12 +41,15 @@ import org.hisp.dhis.common.DimensionalObject; import org.hisp.dhis.dataelement.DataElement; import org.hisp.dhis.dataelement.DataElementService; +import org.hisp.dhis.mock.MockCurrentUserService; import org.hisp.dhis.organisationunit.OrganisationUnit; import org.hisp.dhis.organisationunit.OrganisationUnitGroup; import org.hisp.dhis.organisationunit.OrganisationUnitGroupService; import org.hisp.dhis.organisationunit.OrganisationUnitGroupSet; import org.hisp.dhis.organisationunit.OrganisationUnitService; import org.hisp.dhis.period.PeriodType; +import org.hisp.dhis.user.CurrentUserService; +import org.hisp.dhis.user.User; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -72,7 +75,7 @@ private OrganisationUnitGroup ouGroupC; private OrganisationUnitGroupSet ouGroupSetA; - + @Autowired private AnalyticsService analyticsService; @@ -104,6 +107,11 @@ ouD = createOrganisationUnit( 'D' ); ouE = createOrganisationUnit( 'E' ); + ouB.updateParent( ouA ); + ouC.updateParent( ouA ); + ouD.updateParent( ouB ); + ouE.updateParent( ouB ); + organisationUnitService.addOrganisationUnit( ouA ); organisationUnitService.addOrganisationUnit( ouB ); organisationUnitService.addOrganisationUnit( ouC ); @@ -131,6 +139,17 @@ ouGroupSetA.getOrganisationUnitGroups().add( ouGroupC ); organisationUnitGroupService.updateOrganisationUnitGroupSet( ouGroupSetA ); + + // --------------------------------------------------------------------- + // Mock injection + // --------------------------------------------------------------------- + + User user = createUser( 'A' ); + user.addOrganisationUnit( ouA ); + + CurrentUserService currentUserService = new MockCurrentUserService( user ); + + setDependency( analyticsService, "currentUserService", currentUserService ); } @Test @@ -166,6 +185,53 @@ assertEquals( 4, params.getDataElements().size() ); assertEquals( 1, params.getFilterOrganisationUnits().size() ); } + + @Test + public void testGetFromUrlRelativePeriods() + { + Set dimensionParams = new HashSet(); + dimensionParams.add( "dx:" + deA.getUid() + ";" + deB.getUid() + ";" + deC.getUid() + ";" + deD.getUid() ); + dimensionParams.add( "pe:LAST_12_MONTHS" ); + + Set filterParams = new HashSet(); + filterParams.add( "ou:" + ouA.getUid() + ";" + ouB.getUid() ); + + DataQueryParams params = analyticsService.getFromUrl( dimensionParams, filterParams, null, null, false, null ); + + assertEquals( 4, params.getDataElements().size() ); + assertEquals( 12, params.getPeriods().size() ); + assertEquals( 2, params.getFilterOrganisationUnits().size() ); + } + + @Test + public void testGetFromUrlUserOrgUnit() + { + Set dimensionParams = new HashSet(); + dimensionParams.add( "ou:" + OrganisationUnit.KEY_USER_ORGUNIT ); + dimensionParams.add( "dx:" + deA.getUid() + ";" + deB.getUid() ); + dimensionParams.add( "pe:2011;2012" ); + + DataQueryParams params = analyticsService.getFromUrl( dimensionParams, null, null, null, false, null ); + + assertEquals( 1, params.getOrganisationUnits().size() ); + assertEquals( 2, params.getDataElements().size() ); + assertEquals( 2, params.getPeriods().size() ); + } + + @Test + public void testGetFromUrlOrgUnitLevel() + { + Set dimensionParams = new HashSet(); + dimensionParams.add( "ou:LEVEL-2-" + ouA.getUid() ); + dimensionParams.add( "dx:" + deA.getUid() + ";" + deB.getUid() ); + dimensionParams.add( "pe:2011;2012" ); + + DataQueryParams params = analyticsService.getFromUrl( dimensionParams, null, null, null, false, null ); + + assertEquals( 2, params.getOrganisationUnits().size() ); + assertEquals( 2, params.getDataElements().size() ); + assertEquals( 2, params.getPeriods().size() ); + } @Test( expected = IllegalQueryException.class ) public void testGetFromUrlNoDx() === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultDimensionService.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultDimensionService.java 2013-05-23 13:38:20 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultDimensionService.java 2013-07-04 15:41:57 +0000 @@ -37,6 +37,7 @@ import static org.hisp.dhis.common.DimensionType.ORGANISATIONUNIT_GROUPSET; import static org.hisp.dhis.common.DimensionType.PERIOD; import static org.hisp.dhis.common.IdentifiableObjectUtils.getUids; +import static org.hisp.dhis.organisationunit.OrganisationUnit.KEY_LEVEL; import static org.hisp.dhis.organisationunit.OrganisationUnit.KEY_USER_ORGUNIT; import static org.hisp.dhis.organisationunit.OrganisationUnit.KEY_USER_ORGUNIT_CHILDREN; @@ -286,6 +287,20 @@ { object.setUserOrganisationUnitChildren( true ); } + else if ( ou != null && ou.startsWith( KEY_LEVEL ) ) + { + int level = DimensionalObjectUtils.getLevelFromLevelParam( ou ); + + String boundary = DimensionalObjectUtils.getBoundaryFromLevelParam( ou ); + + OrganisationUnit unit = identifiableObjectManager.get( OrganisationUnit.class, boundary ); + + if ( level > 0 && unit != null ) + { + object.setOrganisationUnitLevel( level ); + ous.add( unit ); + } + } else { OrganisationUnit unit = identifiableObjectManager.get( OrganisationUnit.class, ou ); === 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 2013-05-24 18:29:35 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/organisationunit/DefaultOrganisationUnitService.java 2013-07-04 15:41:57 +0000 @@ -405,6 +405,18 @@ return result; } + public Collection getOrganisationUnitsAtLevel( int level, Collection parents ) + { + Set result = new HashSet(); + + for ( OrganisationUnit parent : parents ) + { + result.addAll( getOrganisationUnitsAtLevel( level, parent ) ); + } + + return result; + } + /** * Support method for getOrganisationUnitsAtLevel(). Adds all children at a * given targetLevel to a result collection. The parent's children are at === added file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/common/DimensionServiceTest.java' --- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/common/DimensionServiceTest.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/common/DimensionServiceTest.java 2013-07-04 15:41:57 +0000 @@ -0,0 +1,235 @@ +package org.hisp.dhis.common; + +/* + * Copyright (c) 2004-2005, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import static org.hisp.dhis.organisationunit.OrganisationUnit.KEY_LEVEL; +import static org.hisp.dhis.organisationunit.OrganisationUnit.KEY_USER_ORGUNIT; +import static org.hisp.dhis.period.RelativePeriodEnum.LAST_12_MONTHS; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; + +import org.hisp.dhis.DhisSpringTest; +import org.hisp.dhis.dataelement.DataElement; +import org.hisp.dhis.dataelement.DataElementService; +import org.hisp.dhis.organisationunit.OrganisationUnit; +import org.hisp.dhis.organisationunit.OrganisationUnitGroup; +import org.hisp.dhis.organisationunit.OrganisationUnitGroupService; +import org.hisp.dhis.organisationunit.OrganisationUnitGroupSet; +import org.hisp.dhis.organisationunit.OrganisationUnitService; +import org.hisp.dhis.period.Period; +import org.hisp.dhis.reporttable.ReportTable; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * @author Lars Helge Overland + */ +public class DimensionServiceTest + extends DhisSpringTest +{ + private DataElement deA; + private DataElement deB; + + private Period peA; + private Period peB; + + private BaseNameableObject peLast12Months; + + private OrganisationUnit ouA; + private OrganisationUnit ouB; + private OrganisationUnit ouC; + private OrganisationUnit ouD; + private OrganisationUnit ouE; + + private BaseNameableObject ouUser; + private BaseNameableObject ouLevel2; + + private OrganisationUnitGroup ouGroupA; + private OrganisationUnitGroup ouGroupB; + private OrganisationUnitGroup ouGroupC; + + private OrganisationUnitGroupSet ouGroupSetA; + + @Autowired + private DataElementService dataElementService; + + @Autowired + private OrganisationUnitService organisationUnitService; + + @Autowired + private OrganisationUnitGroupService organisationUnitGroupService; + + @Autowired + private DimensionService dimensionService; + + @Override + public void setUpTest() + { + deA = createDataElement( 'A' ); + deB = createDataElement( 'B' ); + + dataElementService.addDataElement( deA ); + dataElementService.addDataElement( deB ); + + peA = createPeriod( "201201" ); + peB = createPeriod( "201202" ); + peLast12Months = new BaseNameableObject( LAST_12_MONTHS.toString(), LAST_12_MONTHS.toString(), LAST_12_MONTHS.toString() ); + + peA.setUid( "201201" ); + peB.setUid( "201202" ); + + ouA = createOrganisationUnit( 'A' ); + ouB = createOrganisationUnit( 'B' ); + ouC = createOrganisationUnit( 'C' ); + ouD = createOrganisationUnit( 'D' ); + ouE = createOrganisationUnit( 'E' ); + + ouB.updateParent( ouA ); + ouC.updateParent( ouA ); + ouD.updateParent( ouB ); + ouE.updateParent( ouB ); + + organisationUnitService.addOrganisationUnit( ouA ); + organisationUnitService.addOrganisationUnit( ouB ); + organisationUnitService.addOrganisationUnit( ouC ); + organisationUnitService.addOrganisationUnit( ouD ); + organisationUnitService.addOrganisationUnit( ouE ); + + String level2 = KEY_LEVEL + 2 + DimensionalObject.DIMENSION_SEP + ouA.getUid(); + + ouUser = new BaseNameableObject( KEY_USER_ORGUNIT, KEY_USER_ORGUNIT, KEY_USER_ORGUNIT ); + ouLevel2 = new BaseNameableObject( level2, level2, level2 ); + + ouGroupSetA = createOrganisationUnitGroupSet( 'A' ); + + organisationUnitGroupService.addOrganisationUnitGroupSet( ouGroupSetA ); + + ouGroupA = createOrganisationUnitGroup( 'A' ); + ouGroupB = createOrganisationUnitGroup( 'B' ); + ouGroupC = createOrganisationUnitGroup( 'C' ); + + ouGroupA.setGroupSet( ouGroupSetA ); + ouGroupB.setGroupSet( ouGroupSetA ); + ouGroupC.setGroupSet( ouGroupSetA ); + + organisationUnitGroupService.addOrganisationUnitGroup( ouGroupA ); + organisationUnitGroupService.addOrganisationUnitGroup( ouGroupB ); + organisationUnitGroupService.addOrganisationUnitGroup( ouGroupC ); + + ouGroupSetA.getOrganisationUnitGroups().add( ouGroupA ); + ouGroupSetA.getOrganisationUnitGroups().add( ouGroupB ); + ouGroupSetA.getOrganisationUnitGroups().add( ouGroupC ); + + organisationUnitGroupService.updateOrganisationUnitGroupSet( ouGroupSetA ); + } + + @Test + public void testMergeAnalyticalObject() + { + ReportTable reportTable = new ReportTable(); + + reportTable.getColumns().add( new BaseDimensionalObject( DimensionalObject.DATAELEMENT_DIM_ID, Arrays.asList( deA, deB ) ) ); + reportTable.getRows().add( new BaseDimensionalObject( DimensionalObject.ORGUNIT_DIM_ID, Arrays.asList( ouA, ouB, ouC, ouD, ouE ) ) ); + reportTable.getFilters().add( new BaseDimensionalObject( DimensionalObject.PERIOD_DIM_ID, Arrays.asList( peA, peB ) ) ); + + dimensionService.mergeAnalyticalObject( reportTable ); + + assertEquals( 2, reportTable.getDataElements().size() ); + assertEquals( 2, reportTable.getPeriods().size() ); + assertEquals( 5, reportTable.getOrganisationUnits().size() ); + } + + @Test + public void testMergeAnalyticalObjectUserOrgUnit() + { + ReportTable reportTable = new ReportTable(); + + reportTable.getColumns().add( new BaseDimensionalObject( DimensionalObject.DATAELEMENT_DIM_ID, Arrays.asList( deA, deB ) ) ); + reportTable.getRows().add( new BaseDimensionalObject( DimensionalObject.ORGUNIT_DIM_ID, Arrays.asList( ouUser ) ) ); + reportTable.getFilters().add( new BaseDimensionalObject( DimensionalObject.PERIOD_DIM_ID, Arrays.asList( peA ) ) ); + + dimensionService.mergeAnalyticalObject( reportTable ); + + assertEquals( 2, reportTable.getDataElements().size() ); + assertEquals( 1, reportTable.getPeriods().size() ); + assertEquals( 0, reportTable.getOrganisationUnits().size() ); + assertTrue( reportTable.isUserOrganisationUnit() ); + } + + @Test + public void testMergeAnalyticalObjectOrgUnitLevel() + { + ReportTable reportTable = new ReportTable(); + + reportTable.getColumns().add( new BaseDimensionalObject( DimensionalObject.DATAELEMENT_DIM_ID, Arrays.asList( deA, deB ) ) ); + reportTable.getRows().add( new BaseDimensionalObject( DimensionalObject.ORGUNIT_DIM_ID, Arrays.asList( ouLevel2 ) ) ); + reportTable.getFilters().add( new BaseDimensionalObject( DimensionalObject.PERIOD_DIM_ID, Arrays.asList( peA ) ) ); + + dimensionService.mergeAnalyticalObject( reportTable ); + + assertEquals( 2, reportTable.getDataElements().size() ); + assertEquals( 1, reportTable.getPeriods().size() ); + assertEquals( 1, reportTable.getOrganisationUnits().size() ); + assertEquals( Integer.valueOf( 2 ), reportTable.getOrganisationUnitLevel() ); + } + + @Test + public void testMergeAnalyticalObjectRelativePeriods() + { + ReportTable reportTable = new ReportTable(); + + reportTable.getColumns().add( new BaseDimensionalObject( DimensionalObject.DATAELEMENT_DIM_ID, Arrays.asList( deA, deB ) ) ); + reportTable.getRows().add( new BaseDimensionalObject( DimensionalObject.ORGUNIT_DIM_ID, Arrays.asList( ouA, ouB, ouC, ouD, ouE ) ) ); + reportTable.getFilters().add( new BaseDimensionalObject( DimensionalObject.PERIOD_DIM_ID, Arrays.asList( peLast12Months ) ) ); + + dimensionService.mergeAnalyticalObject( reportTable ); + + assertEquals( 2, reportTable.getDataElements().size() ); + assertEquals( 0, reportTable.getPeriods().size() ); + assertTrue( reportTable.getRelatives().isLast12Months() ); + assertEquals( 5, reportTable.getOrganisationUnits().size() ); + } + + @Test + public void testMergeAnalyticalObjectOrgUnitGroupSet() + { + ReportTable reportTable = new ReportTable(); + + reportTable.getColumns().add( new BaseDimensionalObject( DimensionalObject.DATAELEMENT_DIM_ID, Arrays.asList( deA, deB ) ) ); + reportTable.getRows().add( ouGroupSetA ); + reportTable.getFilters().add( new BaseDimensionalObject( DimensionalObject.PERIOD_DIM_ID, Arrays.asList( peA, peB ) ) ); + + dimensionService.mergeAnalyticalObject( reportTable ); + + assertEquals( 2, reportTable.getDataElements().size() ); + assertEquals( 2, reportTable.getPeriods().size() ); + assertEquals( 3, reportTable.getOrganisationUnitGroups().size() ); + } +} === modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/chart/impl/DefaultChartService.java' --- dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/chart/impl/DefaultChartService.java 2013-06-13 13:49:46 +0000 +++ dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/chart/impl/DefaultChartService.java 2013-07-04 15:41:57 +0000 @@ -68,6 +68,7 @@ import org.hisp.dhis.minmax.MinMaxDataElement; import org.hisp.dhis.minmax.MinMaxDataElementService; import org.hisp.dhis.organisationunit.OrganisationUnit; +import org.hisp.dhis.organisationunit.OrganisationUnitService; import org.hisp.dhis.period.Period; import org.hisp.dhis.period.PeriodService; import org.hisp.dhis.period.RelativePeriods; @@ -161,6 +162,13 @@ this.currentUserService = currentUserService; } + private OrganisationUnitService organisationUnitService; + + public void setOrganisationUnitService( OrganisationUnitService organisationUnitService ) + { + this.organisationUnitService = organisationUnitService; + } + private AnalyticsService analyticsService; public void setAnalyticsService( AnalyticsService analyticsService ) @@ -196,8 +204,15 @@ { organisationUnit = user.getOrganisationUnit(); } - - chart.init( user, date, organisationUnit, format ); + + List atLevel = new ArrayList(); + + if ( chart.getOrganisationUnitLevel() != null && chart.getOrganisationUnits() != null ) + { + atLevel.addAll( organisationUnitService.getOrganisationUnitsAtLevel( chart.getOrganisationUnitLevel(), chart.getOrganisationUnits() ) ); + } + + chart.init( user, date, organisationUnit, atLevel, format ); return getJFreeChart( chart ); } === modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/reporttable/impl/DefaultReportTableService.java' --- dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/reporttable/impl/DefaultReportTableService.java 2013-05-23 11:45:52 +0000 +++ dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/reporttable/impl/DefaultReportTableService.java 2013-07-04 15:41:57 +0000 @@ -27,6 +27,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; @@ -109,8 +110,15 @@ ReportTable reportTable = getReportTable( uid ); OrganisationUnit organisationUnit = organisationUnitService.getOrganisationUnit( organisationUnitUid ); - - reportTable.init( currentUserService.getCurrentUser(), reportingPeriod, organisationUnit, format ); + + List atLevel = new ArrayList(); + + if ( reportTable.getOrganisationUnitLevel() != null && reportTable.getOrganisationUnits() != null ) + { + atLevel.addAll( organisationUnitService.getOrganisationUnitsAtLevel( reportTable.getOrganisationUnitLevel(), reportTable.getOrganisationUnits() ) ); + } + + reportTable.init( currentUserService.getCurrentUser(), reportingPeriod, organisationUnit, atLevel, format ); Map valueMap = analyticsService.getAggregatedDataValueMapping( reportTable, format ); === modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/resources/META-INF/dhis/beans.xml' --- dhis-2/dhis-services/dhis-service-reporting/src/main/resources/META-INF/dhis/beans.xml 2013-05-24 12:17:30 +0000 +++ dhis-2/dhis-services/dhis-service-reporting/src/main/resources/META-INF/dhis/beans.xml 2013-07-04 15:41:57 +0000 @@ -51,6 +51,7 @@ + === modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/chart/hibernate/Chart.hbm.xml' --- dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/chart/hibernate/Chart.hbm.xml 2013-05-14 10:30:17 +0000 +++ dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/chart/hibernate/Chart.hbm.xml 2013-07-04 15:41:57 +0000 @@ -136,6 +136,8 @@ + + === modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/reporttable/hibernate/ReportTable.hbm.xml' --- dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/reporttable/hibernate/ReportTable.hbm.xml 2013-06-06 07:31:24 +0000 +++ dhis-2/dhis-services/dhis-service-reporting/src/main/resources/org/hisp/dhis/reporttable/hibernate/ReportTable.hbm.xml 2013-07-04 15:41:57 +0000 @@ -143,6 +143,8 @@ + + === modified file 'dhis-2/dhis-services/dhis-service-reporting/src/test/java/org/hisp/dhis/reporttable/ReportTableTest.java' --- dhis-2/dhis-services/dhis-service-reporting/src/test/java/org/hisp/dhis/reporttable/ReportTableTest.java 2013-05-22 13:14:47 +0000 +++ dhis-2/dhis-services/dhis-service-reporting/src/test/java/org/hisp/dhis/reporttable/ReportTableTest.java 2013-07-04 15:41:57 +0000 @@ -261,7 +261,7 @@ new ArrayList(), indicators, new ArrayList(), periods, units, true, true, false, relatives, null, "january_2000" ); - reportTable.init( null, null, null, i18nFormat ); + reportTable.init( null, null, null, null, i18nFormat ); List columnDims = reportTable.getColumnDimensions(); List rowDims = reportTable.getRowDimensions(); @@ -313,7 +313,7 @@ new ArrayList(), indicators, new ArrayList(), periods, units, false, false, true, relatives, null, "january_2000" ); - reportTable.init( null, null, null, i18nFormat ); + reportTable.init( null, null, null, null, i18nFormat ); List columnDims = reportTable.getColumnDimensions(); List rowDims = reportTable.getRowDimensions(); @@ -363,7 +363,7 @@ new ArrayList(), indicators, new ArrayList(), periods, units, true, false, true, relatives, null, "january_2000" ); - reportTable.init( null, null, null, i18nFormat ); + reportTable.init( null, null, null, null, i18nFormat ); List columnDims = reportTable.getColumnDimensions(); List rowDims = reportTable.getRowDimensions(); @@ -413,7 +413,7 @@ new ArrayList(), indicators, new ArrayList(), periods, units, true, true, true, relatives, null, "january_2000" ); - reportTable.init( null, null, null, i18nFormat ); + reportTable.init( null, null, null, null, i18nFormat ); List columnDims = reportTable.getColumnDimensions(); List rowDims = reportTable.getRowDimensions(); @@ -443,7 +443,7 @@ new ArrayList(), indicators, new ArrayList(), periods, units, false, false, false, relatives, null, "january_2000" ); - reportTable.init( null, null, null, i18nFormat ); + reportTable.init( null, null, null, null, i18nFormat ); List columnDims = reportTable.getColumnDimensions(); List rowDims = reportTable.getRowDimensions(); @@ -473,7 +473,7 @@ dataElements, new ArrayList(), new ArrayList(), periods, units, true, true, false, relatives, null, "january_2000" ); - reportTable.init( null, null, null, i18nFormat ); + reportTable.init( null, null, null, null, i18nFormat ); List columnDims = reportTable.getColumnDimensions(); List rowDims = reportTable.getRowDimensions(); @@ -513,7 +513,7 @@ dataElements, new ArrayList(), new ArrayList(), periods, units, false, false, true, relatives, null, "january_2000" ); - reportTable.init( null, null, null, i18nFormat ); + reportTable.init( null, null, null, null, i18nFormat ); List columnDims = reportTable.getColumnDimensions(); List rowDims = reportTable.getRowDimensions(); @@ -551,7 +551,7 @@ dataElements, new ArrayList(), new ArrayList(), periods, units, true, false, true, relatives, null, "january_2000" ); - reportTable.init( null, null, null, i18nFormat ); + reportTable.init( null, null, null, null, i18nFormat ); List columnDims = reportTable.getColumnDimensions(); List rowDims = reportTable.getRowDimensions(); @@ -591,7 +591,7 @@ new ArrayList(), new ArrayList(), dataSets, periods, units, true, true, false, relatives, null, "january_2000" ); - reportTable.init( null, null, null, i18nFormat ); + reportTable.init( null, null, null, null, i18nFormat ); List columnDims = reportTable.getColumnDimensions(); List rowDims = reportTable.getRowDimensions(); @@ -631,7 +631,7 @@ new ArrayList(), new ArrayList(), dataSets, periods, units, false, false, true, relatives, null, "january_2000" ); - reportTable.init( null, null, null, i18nFormat ); + reportTable.init( null, null, null, null, i18nFormat ); List columnDims = reportTable.getColumnDimensions(); List rowDims = reportTable.getRowDimensions(); @@ -669,7 +669,7 @@ new ArrayList(), new ArrayList(), dataSets, periods, units, true, false, true, relatives, null, "january_2000" ); - reportTable.init( null, null, null, i18nFormat ); + reportTable.init( null, null, null, null, i18nFormat ); List columnDims = reportTable.getColumnDimensions(); List rowDims = reportTable.getRowDimensions();