=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/analytics/AggregationType.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/analytics/AggregationType.java 2015-08-20 20:05:43 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/analytics/AggregationType.java 2015-08-21 01:47:02 +0000 @@ -43,6 +43,7 @@ MAX( "max" ), NONE( "none" ), DEFAULT( "default" ), + CUSTOM( "custom" ), // Internal types @@ -63,7 +64,7 @@ { return value; } - + public static AggregationType fromValue( String value ) { for ( AggregationType type : AggregationType.values() ) === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionType.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionType.java 2015-07-15 06:49:50 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/DimensionType.java 2015-08-21 01:47:02 +0000 @@ -36,6 +36,7 @@ DATA_X, PROGRAM_DATAELEMENT, PROGRAM_ATTRIBUTE, + PROGRAM_INDICATOR, DATA_COLLAPSED, CATEGORY_OPTION_COMBO, ATTRIBUTE_OPTION_COMBO, === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramIndicator.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramIndicator.java 2015-08-20 15:49:48 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramIndicator.java 2015-08-21 01:47:02 +0000 @@ -36,6 +36,7 @@ import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import org.hisp.dhis.analytics.AggregationType; import org.hisp.dhis.common.BaseIdentifiableObject; import org.hisp.dhis.common.BaseNameableObject; import org.hisp.dhis.common.DxfNamespaces; @@ -87,6 +88,8 @@ private String expression; private String filter; + + private AggregationType aggregationType; /** * Number of decimals to use for indicator value, null implies default. @@ -103,7 +106,6 @@ public ProgramIndicator() { - } // ------------------------------------------------------------------------- @@ -119,6 +121,14 @@ { return decimals != null && decimals >= 0; } + + /** + * Returns aggregation type, if not exists returns AVERAGE. + */ + public AggregationType getAggregationTypeFallback() + { + return aggregationType != null ? aggregationType : AggregationType.AVERAGE; + } // ------------------------------------------------------------------------- // Getters && Setters @@ -180,6 +190,19 @@ @JsonProperty @JsonView( { DetailedView.class, ExportView.class } ) @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public AggregationType getAggregationType() + { + return aggregationType; + } + + public void setAggregationType( AggregationType aggregationType ) + { + this.aggregationType = aggregationType; + } + + @JsonProperty + @JsonView( { DetailedView.class, ExportView.class } ) + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) public Integer getDecimals() { return decimals; === modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java' --- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java 2015-08-10 21:57:49 +0000 +++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java 2015-08-21 01:47:02 +0000 @@ -244,11 +244,6 @@ */ protected transient Map dataApprovalLevels = new HashMap<>(); - /** - * Filter expression. - */ - protected transient String filterExpression; - // ------------------------------------------------------------------------- // Constructors // ------------------------------------------------------------------------- @@ -287,7 +282,6 @@ params.dataPeriodType = this.dataPeriodType; params.skipPartitioning = this.skipPartitioning; params.dataApprovalLevels = new HashMap<>( this.dataApprovalLevels ); - params.filterExpression = this.filterExpression; return params; } @@ -1003,15 +997,7 @@ { return programStage != null; } - - /** - * Indicates whether this object has a filter expression. - */ - public boolean hasFilterExpression() - { - return filterExpression != null; - } - + // ------------------------------------------------------------------------- // Static methods // ------------------------------------------------------------------------- @@ -1483,16 +1469,6 @@ this.dataApprovalLevels = dataApprovalLevels; } - public String getFilterExpression() - { - return filterExpression; - } - - public void setFilterExpression( String filterExpression ) - { - this.filterExpression = filterExpression; - } - // ------------------------------------------------------------------------- // Get and set helpers for dimensions or filter // ------------------------------------------------------------------------- === modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/QueryPlanner.java' --- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/QueryPlanner.java 2015-07-10 15:56:26 +0000 +++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/QueryPlanner.java 2015-08-21 01:47:02 +0000 @@ -105,13 +105,6 @@ List groupByOrgUnitLevel( DataQueryParams params ); /** - * If program indicators appear as dimensions; groups the given query into - * sub queries based on the filter of the program indicators. Sets the - * program indicator filter on queries which contain program indicators. - */ - List groupByFilterExpression( DataQueryParams params ); - - /** * Groups the given query into sub queries based on its periods and which * partition it should be executed against. Sets the partition table name on * each query. Queries are grouped based on periods if appearing as a === 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 2015-08-18 11:56:04 +0000 +++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultAnalyticsService.java 2015-08-21 01:47:02 +0000 @@ -56,6 +56,7 @@ import static org.hisp.dhis.common.IdentifiableObjectUtils.getUids; import static org.hisp.dhis.common.NameableObjectUtils.asList; import static org.hisp.dhis.common.NameableObjectUtils.asTypedList; +import static org.hisp.dhis.commons.collection.ListUtils.sort; import static org.hisp.dhis.commons.util.TextUtils.splitSafe; import static org.hisp.dhis.organisationunit.OrganisationUnit.KEY_LEVEL; import static org.hisp.dhis.organisationunit.OrganisationUnit.KEY_ORGUNIT_GROUP; @@ -67,7 +68,6 @@ import static org.hisp.dhis.period.PeriodType.getPeriodTypeFromIsoString; import static org.hisp.dhis.reporttable.ReportTable.IRT2D; import static org.hisp.dhis.reporttable.ReportTable.addIfEmpty; -import static org.hisp.dhis.commons.collection.ListUtils.sort; import java.util.ArrayList; import java.util.Collection; @@ -101,7 +101,6 @@ import org.hisp.dhis.common.CombinationGenerator; import org.hisp.dhis.common.DataDimensionItem; import org.hisp.dhis.common.DataDimensionItem.DataDimensionItemType; -import org.hisp.dhis.common.comparator.IdentifiableObjectNameComparator; import org.hisp.dhis.common.DimensionType; import org.hisp.dhis.common.DimensionalObject; import org.hisp.dhis.common.DimensionalObjectUtils; @@ -115,6 +114,7 @@ import org.hisp.dhis.common.MapMap; import org.hisp.dhis.common.NameableObject; import org.hisp.dhis.common.NameableObjectUtils; +import org.hisp.dhis.common.comparator.IdentifiableObjectNameComparator; import org.hisp.dhis.commons.collection.ListUtils; import org.hisp.dhis.commons.collection.UniqueArrayList; import org.hisp.dhis.commons.util.DebugUtils; @@ -136,7 +136,6 @@ import org.hisp.dhis.period.RelativePeriodEnum; import org.hisp.dhis.period.RelativePeriods; import org.hisp.dhis.period.comparator.AscendingPeriodEndDateComparator; -import org.hisp.dhis.program.ProgramIndicator; import org.hisp.dhis.program.ProgramIndicatorService; import org.hisp.dhis.program.ProgramService; import org.hisp.dhis.program.ProgramStageService; @@ -255,9 +254,7 @@ addDataSetValues( params, grid ); - addProgramIndicatorValues( params, grid ); - - addProgramDataElementAttributeValues( params, grid ); + addProgramDataElementAttributeIndicatorValues( params, grid ); addDynamicDimensionValues( params, grid ); @@ -510,85 +507,19 @@ } /** - * Adds program indicator values to the given grid based on the given data query - * parameters. - * - * @param params the data query parameters. - * @param grid the grid. - */ - private void addProgramIndicatorValues( DataQueryParams params, Grid grid ) - { - if ( !params.getProgramIndicators().isEmpty() && !params.isSkipData() ) - { - // ----------------------------------------------------------------- - // Run queries with different filter expression separately - // ----------------------------------------------------------------- - - List queries = queryPlanner.groupByFilterExpression( params ); - - for ( DataQueryParams query : queries ) - { - DataQueryParams dataSourceParams = query.instance(); - dataSourceParams.retainDataDimension( DataDimensionItemType.PROGRAM_INDICATOR ); - - List indicators = asTypedList( dataSourceParams.getProgramIndicators() ); - - //TODO constants - - // ----------------------------------------------------------------- - // Get indicator values - // ----------------------------------------------------------------- - - List> dimensionItemPermutations = dataSourceParams.getDimensionItemPermutations(); - - Map> permutationOperandValueMap = getProgramPermutationOperandValueMap( dataSourceParams ); - - for ( ProgramIndicator indicator : indicators ) - { - for ( List dimensionItems : dimensionItemPermutations ) - { - String permKey = DimensionItem.asItemKey( dimensionItems ); - - Map valueMap = permutationOperandValueMap.get( permKey ); - - if ( valueMap == null ) - { - continue; - } - - Double value = programIndicatorService.getProgramIndicatorValue( indicator, valueMap ); - - if ( value != null ) - { - List row = new ArrayList<>( dimensionItems ); - - row.add( DX_INDEX, new DimensionItem( DATA_X_DIM_ID, indicator ) ); - - Double roundedValue = indicator.hasDecimals() ? MathUtils.getRounded( value, indicator.getDecimals() ) : MathUtils.getRounded( value ); - - grid.addRow(); - grid.addValues( DimensionItem.getItemIdentifiers( row ) ); - grid.addValue( dataSourceParams.isSkipRounding() ? value : roundedValue ); - } - } - } - } - } - } - - /** * Adds program data element values to the given grid based on the given data * query parameters. * * @param params the data query parameters. * @param grid the grid. */ - private void addProgramDataElementAttributeValues( DataQueryParams params, Grid grid ) + private void addProgramDataElementAttributeIndicatorValues( DataQueryParams params, Grid grid ) { - if ( !params.getAllProgramDataElementsAndAttributes().isEmpty() && !params.isSkipData() ) + if ( ( !params.getAllProgramDataElementsAndAttributes().isEmpty() || !params.getProgramIndicators().isEmpty() ) && !params.isSkipData() ) { DataQueryParams dataSourceParams = params.instance(); - dataSourceParams.retainDataDimensions( DataDimensionItemType.PROGRAM_DATA_ELEMENT, DataDimensionItemType.PROGRAM_ATTRIBUTE ); + dataSourceParams.retainDataDimensions( DataDimensionItemType.PROGRAM_DATA_ELEMENT, + DataDimensionItemType.PROGRAM_ATTRIBUTE, DataDimensionItemType.PROGRAM_INDICATOR ); EventQueryParams eventQueryParams = EventQueryParams.fromDataQueryParams( dataSourceParams ); @@ -1376,41 +1307,6 @@ } /** - * Returns a mapping of permutation keys and mappings of program data elements - * / program attributes and values based on the given query. - * - * @param params the data query parameters. - */ - private Map> getProgramPermutationOperandValueMap( DataQueryParams params ) - { - Map> permutationMap = new HashMap<>(); - - List programIndicators = asTypedList( params.getProgramIndicators() ); - List dataElements = asList( programIndicatorService.getDataElementsInIndicators( programIndicators ) ); - List attributes = asList( programIndicatorService.getAttributesInIndicators( programIndicators ) ); - List dataItems = ListUtils.union( dataElements, attributes ); - - if ( !dataElements.isEmpty() || !attributes.isEmpty() ) - { - DataQueryParams dataSourceParams = params.instance().removeDimension( DATA_X_DIM_ID ); - - dataSourceParams.getDimensions().add( DX_INDEX, new BaseDimensionalObject( - DATA_X_DIM_ID, DimensionType.DATA_X, dataItems ) ); - - EventQueryParams eventQueryParams = EventQueryParams.fromDataQueryParams( dataSourceParams ); - eventQueryParams.setSkipRounding( true ); - - Grid grid = eventAnalyticsService.getAggregatedEventData( eventQueryParams ); - - Map valueMap = grid.getAsMap( grid.getWidth() - 1, DIMENSION_SEP ); - - permutationMap.putAll( DataQueryParams.getPermutationProgramValueMap( valueMap ) ); - } - - return permutationMap; - } - - /** * Returns a mapping of dimension keys and aggregated values for the data * element totals part of the indicators in the given query. * === modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultQueryPlanner.java' --- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultQueryPlanner.java 2015-07-10 21:29:06 +0000 +++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultQueryPlanner.java 2015-08-21 01:47:02 +0000 @@ -72,7 +72,6 @@ import org.hisp.dhis.organisationunit.OrganisationUnitService; import org.hisp.dhis.period.Period; import org.hisp.dhis.period.PeriodType; -import org.hisp.dhis.program.ProgramIndicator; import org.hisp.dhis.program.ProgramIndicatorService; import org.hisp.dhis.setting.SystemSettingManager; import org.hisp.dhis.system.filter.AggregatableDataElementFilter; @@ -539,37 +538,6 @@ return queries; } - - @Override - public List groupByFilterExpression( DataQueryParams params ) - { - List queries = new ArrayList<>(); - - if ( !params.getProgramIndicators().isEmpty() ) - { - ListMap filterProgramIndicatorMap = getFilterProgramIndicatorMap( params.getProgramIndicators() ); - - for ( String filter : filterProgramIndicatorMap.keySet() ) - { - DataQueryParams query = params.instance(); - query.setProgramIndicators( filterProgramIndicatorMap.get( filter ) ); - query.setFilterExpression( programIndicatorService.getAnalyticsSQl( filter ) ); - queries.add( query ); - } - } - else - { - queries.add( params.instance() ); - return queries; - } - - if ( queries.size() > 1 ) - { - log.debug( "Split on filter expression: " + queries.size() ); - } - - return queries; - } private List groupByDataType( DataQueryParams params ) { @@ -776,26 +744,6 @@ } /** - * Creates a mapping between filter and program indicator for the given - * program indicators. - */ - private ListMap getFilterProgramIndicatorMap( List programIndicators ) - { - ListMap map = new ListMap<>(); - - for ( NameableObject programIndicator : programIndicators ) - { - ProgramIndicator indicator = (ProgramIndicator) programIndicator; - - String filter = indicator.getFilter(); - - map.putValue( filter, indicator ); - } - - return map; - } - - /** * Creates a mapping between data type and data element for the given data elements. */ private ListMap getDataTypeDataElementMap( List dataElements ) === modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/EventQueryParams.java' --- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/EventQueryParams.java 2015-08-20 20:05:43 +0000 +++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/EventQueryParams.java 2015-08-21 02:55:35 +0000 @@ -28,8 +28,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import static org.hisp.dhis.common.DimensionalObject.PERIOD_DIM_ID; import static org.hisp.dhis.common.DimensionalObject.DATA_X_DIM_ID; -import static org.hisp.dhis.common.DimensionalObject.PERIOD_DIM_ID; import java.util.ArrayList; import java.util.Date; @@ -52,6 +52,7 @@ import org.hisp.dhis.option.OptionSet; import org.hisp.dhis.organisationunit.OrganisationUnit; import org.hisp.dhis.period.Period; +import org.hisp.dhis.program.ProgramIndicator; import org.hisp.dhis.trackedentity.TrackedEntityAttribute; /** @@ -67,8 +68,12 @@ private List items = new ArrayList<>(); private List itemFilters = new ArrayList<>(); - + private DimensionalObject value; + + private List itemProgramIndicators = new ArrayList<>(); + + private ProgramIndicator programIndicator; private List asc = new ArrayList<>(); @@ -113,7 +118,6 @@ params.partitions = new Partitions( this.partitions ); params.periodType = this.periodType; - params.filterExpression = this.filterExpression; params.program = this.program; params.programStage = this.programStage; @@ -122,6 +126,8 @@ params.items = new ArrayList<>( this.items ); params.itemFilters = new ArrayList<>( this.itemFilters ); params.value = this.value; + params.itemProgramIndicators = new ArrayList<>( this.itemProgramIndicators ); + params.programIndicator = this.programIndicator; params.asc = new ArrayList<>( this.asc ); params.desc = new ArrayList<>( this.desc ); params.organisationUnitMode = this.organisationUnitMode; @@ -159,7 +165,7 @@ TrackedEntityAttribute element = (TrackedEntityAttribute) object; QueryItem item = new QueryItem( element, element.getLegendSet(), element.getValueType(), element.getAggregationType(), element.getOptionSet() ); params.getItems().add( item ); - } + } for ( NameableObject object : dataQueryParams.getFilterProgramDataElements() ) { @@ -175,6 +181,12 @@ params.getItemFilters().add( item ); } + for ( NameableObject object : dataQueryParams.getProgramIndicators() ) + { + ProgramIndicator programIndicator = (ProgramIndicator) object; + params.getItemProgramIndicators().add( programIndicator ); + } + params.setAggregateData( true ); params.removeDimension( DATA_X_DIM_ID ); @@ -311,6 +323,7 @@ public boolean isAggregationType( AggregationType aggregationType ) { AggregationType type = getAggregationTypeFallback(); + return type != null && type.equals( aggregationType ); } @@ -390,7 +403,12 @@ { return value != null; } - + + public boolean hasProgramIndicatorDimension() + { + return programIndicator != null; + } + /** * Indicates whether the program of this query requires registration of * tracked entity instances. @@ -419,6 +437,8 @@ "Items: " + items + ", " + "Item filters: " + itemFilters + ", " + "Value: " + value + ", " + + "Item program indicators: " + itemProgramIndicators + ", " + + "Program indicator: " + programIndicator + ", " + "Aggregation type: " + aggregationType + ", " + "Dimensions: " + dimensions + ", " + "Filters: " + filters + "]"; @@ -478,6 +498,26 @@ this.value = value; } + public List getItemProgramIndicators() + { + return itemProgramIndicators; + } + + public void setItemProgramIndicators( List itemProgramIndicators ) + { + this.itemProgramIndicators = itemProgramIndicators; + } + + public ProgramIndicator getProgramIndicator() + { + return programIndicator; + } + + public void setProgramIndicator( ProgramIndicator programIndicator ) + { + this.programIndicator = programIndicator; + } + public List getAsc() { return asc; === modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventQueryPlanner.java' --- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventQueryPlanner.java 2015-08-07 17:59:15 +0000 +++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/DefaultEventQueryPlanner.java 2015-08-21 02:55:35 +0000 @@ -51,6 +51,7 @@ import org.hisp.dhis.organisationunit.OrganisationUnit; import org.hisp.dhis.organisationunit.OrganisationUnitService; import org.hisp.dhis.period.Period; +import org.hisp.dhis.program.ProgramIndicator; import org.hisp.dhis.setting.SystemSettingManager; import org.springframework.beans.factory.annotation.Autowired; @@ -266,9 +267,19 @@ { EventQueryParams query = params.instance(); query.getItems().clear(); + query.getItemProgramIndicators().clear(); query.setValue( item.getItem() ); queries.add( query ); } + + for ( ProgramIndicator programIndicator : params.getItemProgramIndicators() ) + { + EventQueryParams query = params.instance(); + query.getItems().clear(); + query.getItemProgramIndicators().clear(); + query.setProgramIndicator( programIndicator ); + queries.add( query ); + } } else if ( params.isCollapseDataDimensions() && !params.getItems().isEmpty() ) { === modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/JdbcEventAnalyticsManager.java' --- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/JdbcEventAnalyticsManager.java 2015-08-20 20:05:43 +0000 +++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/JdbcEventAnalyticsManager.java 2015-08-21 02:55:35 +0000 @@ -56,8 +56,8 @@ import org.hisp.dhis.legend.Legend; import org.hisp.dhis.option.Option; import org.hisp.dhis.organisationunit.OrganisationUnit; +import org.hisp.dhis.program.ProgramIndicatorService; import org.hisp.dhis.system.util.MathUtils; -import org.hisp.dhis.system.util.ValidationUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.jdbc.core.JdbcTemplate; @@ -85,6 +85,9 @@ @Autowired private StatementBuilder statementBuilder; + @Autowired + private ProgramIndicatorService programIndicatorService; + // ------------------------------------------------------------------------- // EventAnalyticsManager implementation // ------------------------------------------------------------------------- @@ -158,7 +161,14 @@ if ( params.isAggregateData() ) { - grid.addValue( params.getValue().getUid() ); + if ( params.hasValueDimension() ) + { + grid.addValue( params.getValue().getUid() ); + } + else if ( params.hasProgramIndicatorDimension() ) + { + grid.addValue( params.getProgramIndicator().getUid() ); + } } else { @@ -176,7 +186,7 @@ grid.addValue( dimensionValue ); } - if ( params.hasValueDimension() ) + if ( params.hasValueDimension() || params.hasProgramIndicatorDimension() ) { double value = rowSet.getDouble( "value" ); grid.addValue( params.isSkipRounding() ? value : MathUtils.getRounded( value ) ); @@ -316,11 +326,21 @@ if ( params.hasValueDimension() ) // && isNumeric { - String column = statementBuilder.columnQuote( params.getValue().getUid() ); - String function = params.getAggregationTypeFallback().getValue(); - return function + "(" + column + ")"; + String expression = statementBuilder.columnQuote( params.getValue().getUid() ); + + return function + "(" + expression + ")"; + } + else if ( params.hasProgramIndicatorDimension() ) + { + String function = params.getProgramIndicator().getAggregationTypeFallback().getValue(); + + String expression = programIndicatorService.getAnalyticsSQl( params.getProgramIndicator().getExpression() ); + + return function + "(" + expression + ")"; + + //TODO check if expression is valid and safe SQL } else { @@ -483,9 +503,11 @@ // Filter expression // --------------------------------------------------------------------- - if ( params.hasFilterExpression() && ValidationUtils.expressionIsValidSQl( params.getFilterExpression() ) ) + if ( params.hasProgramIndicatorDimension() && params.getProgramIndicator().hasFilter() ) { - String sqlFilter = ExpressionUtils.asSql( params.getFilterExpression() ); + String filter = programIndicatorService.getAnalyticsSQl( params.getProgramIndicator().getFilter() ); + + String sqlFilter = ExpressionUtils.asSql( filter ); sql += "and (" + sqlFilter + ") "; } === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/i18n_global.properties' --- dhis-2/dhis-services/dhis-service-core/src/main/resources/i18n_global.properties 2015-08-18 20:08:20 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/resources/i18n_global.properties 2015-08-21 02:55:35 +0000 @@ -557,6 +557,7 @@ bool=Yes/No none=None yes_only = Yes Only +custom=Custom #-- User account --------------------------------------------------------------# === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/program/hibernate/ProgramIndicator.hbm.xml' --- dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/program/hibernate/ProgramIndicator.hbm.xml 2015-08-07 15:23:36 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/program/hibernate/ProgramIndicator.hbm.xml 2015-08-21 02:55:35 +0000 @@ -28,6 +28,13 @@ + + + org.hisp.dhis.analytics.AggregationType + 12 + + + === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programindicator/AddProgramIndicatorAction.java' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programindicator/AddProgramIndicatorAction.java 2015-08-07 15:23:36 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programindicator/AddProgramIndicatorAction.java 2015-08-21 02:55:35 +0000 @@ -32,6 +32,7 @@ import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; +import org.hisp.dhis.analytics.AggregationType; import org.hisp.dhis.program.Program; import org.hisp.dhis.program.ProgramIndicator; import org.hisp.dhis.program.ProgramIndicatorService; @@ -128,7 +129,14 @@ { this.filter = filter; } + + private String aggregationType; + public void setAggregationType( String aggregationType ) + { + this.aggregationType = aggregationType; + } + private Integer decimals; public void setDecimals( Integer decimals ) @@ -183,6 +191,7 @@ indicator.setValueType( StringUtils.trimToNull( valueType ) ); indicator.setExpression( StringUtils.trimToNull( expression ) ); indicator.setFilter( StringUtils.trimToNull( filter ) ); + indicator.setAggregationType( AggregationType.valueOf( aggregationType ) ); indicator.setDecimals( decimals ); indicator.setDisplayInForm( displayInForm ); indicator.setRootDate( StringUtils.trimToNull( rootDate ) ); === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programindicator/UpdateProgramIndicatorAction.java' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programindicator/UpdateProgramIndicatorAction.java 2015-08-07 15:23:36 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programindicator/UpdateProgramIndicatorAction.java 2015-08-21 02:55:35 +0000 @@ -32,6 +32,7 @@ import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; +import org.hisp.dhis.analytics.AggregationType; import org.hisp.dhis.program.ProgramIndicator; import org.hisp.dhis.program.ProgramIndicatorService; @@ -115,6 +116,13 @@ this.filter = filter; } + private String aggregationType; + + public void setAggregationType( String aggregationType ) + { + this.aggregationType = aggregationType; + } + private Integer decimals; public void setDecimals( Integer decimals ) @@ -174,6 +182,7 @@ indicator.setValueType( StringUtils.trimToNull( valueType ) ); indicator.setExpression( StringUtils.trimToNull( expression ) ); indicator.setFilter( StringUtils.trimToNull( filter ) ); + indicator.setAggregationType( AggregationType.valueOf( aggregationType ) ); indicator.setDecimals( decimals ); indicator.setDisplayInForm( displayInForm ); indicator.setRootDate( StringUtils.trimToNull( rootDate ) ); === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/addProgramIndicator.vm' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/addProgramIndicator.vm 2015-08-07 15:23:36 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/addProgramIndicator.vm 2015-08-21 02:55:35 +0000 @@ -63,6 +63,21 @@ + + + + + + + + + + + + + + + + +