=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/Expression.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/Expression.java 2014-08-27 09:20:22 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/Expression.java 2014-08-28 12:01:44 +0000 @@ -96,10 +96,10 @@ private String description; /** - * Indicates whether the expression should evaluate to null if there are - * missing data values in the expression. + * Indicates whether the expression should evaluate to null if all or any + * data values are missing in the expression. */ - private boolean nullIfBlank; + private MissingValueStrategy missingValueStrategy; /** * A reference to the DataElements in the Expression. @@ -267,7 +267,7 @@ } @JsonProperty - @JsonView( { DetailedView.class, ExportView.class } ) + @JsonView({ DetailedView.class, ExportView.class }) @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) public String getDescription() { @@ -282,15 +282,15 @@ @JsonProperty @JsonView({ DetailedView.class, ExportView.class }) @JacksonXmlProperty(namespace = DxfNamespaces.DXF_2_0) - public boolean isNullIfBlank() + public MissingValueStrategy getMissingValueStrategy() { - return nullIfBlank; + return missingValueStrategy; } - public void setNullIfBlank( boolean nullIfBlank ) + public void setMissingValueStrategy( MissingValueStrategy missingValueStrategy ) { - this.nullIfBlank = nullIfBlank; - } + this.missingValueStrategy = missingValueStrategy; + } @JsonIgnore public String getExplodedExpression() @@ -309,7 +309,7 @@ expression = other.getExpression() == null ? expression : other.getExpression(); description = other.getDescription() == null ? description : other.getDescription(); - nullIfBlank = other.isNullIfBlank(); + missingValueStrategy = other.getMissingValueStrategy() == null ? missingValueStrategy : other.getMissingValueStrategy(); dataElementsInExpression = other.getDataElementsInExpression() == null ? dataElementsInExpression : new HashSet<>( other.getDataElementsInExpression() ); === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/ExpressionService.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/ExpressionService.java 2014-08-05 22:30:52 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/ExpressionService.java 2014-08-28 12:01:44 +0000 @@ -350,10 +350,13 @@ * @param constantMap the mapping between the constant uid and value to use * in the calculation. * @param orgUnitCountMap the mapping between organisation unit group uid and - * count of org units to use in the calculation. + * count of organisation units to use in the calculation. * @param days the number of days to use in the calculation. + * @param missingValueStrategy the strategy to use when data values are missing + * when calculating the expression. Strategy defaults to NEVER_SKIP if null. */ - String generateExpression( String expression, Map valueMap, Map constantMap, Map orgUnitCountMap, Integer days, boolean nullIfNoValues ); + String generateExpression( String expression, Map valueMap, + Map constantMap, Map orgUnitCountMap, Integer days, MissingValueStrategy missingValueStrategy ); /** * Returns all Operands included in the formulas for the given collection of === added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/MissingValueStrategy.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/MissingValueStrategy.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/MissingValueStrategy.java 2014-08-28 12:01:44 +0000 @@ -0,0 +1,61 @@ +package org.hisp.dhis.expression; + +/* + * Copyright (c) 2004-2014, 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 HISP project 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. + */ + +/** + * @author Lars Helge Overland + */ +public enum MissingValueStrategy +{ + SKIP_IF_ANY_VALUE_MISSING( "skip_if_any_value_missing" ), + SKIP_IF_ALL_VALUES_MISSING( "skip_if_all_values_missing" ), + NEVER_SKIP( "never_skip" ); + + private final String value; + + private MissingValueStrategy( String value ) + { + this.value = value; + } + + public String getValue() + { + return value; + } + + public static MissingValueStrategy safeValueOf( String value ) + { + return value != null ? MissingValueStrategy.valueOf( value ) : null; + } + + public static MissingValueStrategy safeValueOf( String value, MissingValueStrategy defaultValue ) + { + return value != null ? MissingValueStrategy.valueOf( value ) : defaultValue; + } +} === modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/DefaultAnalyticsTableService.java' --- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/DefaultAnalyticsTableService.java 2014-08-25 11:42:12 +0000 +++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/DefaultAnalyticsTableService.java 2014-08-28 12:01:44 +0000 @@ -97,7 +97,9 @@ public void update( Integer lastYears, TaskId taskId ) { - Clock clock = new Clock().startClock().logTime( "Starting update, no of processes: " + getProcessNo() ); + int processNo = getProcessNo(); + + Clock clock = new Clock().startClock().logTime( "Starting update, no of processes: " + processNo ); String validState = tableManager.validState(); @@ -111,7 +113,7 @@ clock.logTime( "Partition tables: " + tables + ", last years: " + lastYears ); - notifier.notify( taskId, "Creating analytics tables" ); + notifier.notify( taskId, "Creating analytics tables, last years: " + lastYears + ", processes: " + processNo ); createTables( tables ); === added file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/MissingValueStrategyUserType.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/MissingValueStrategyUserType.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/MissingValueStrategyUserType.java 2014-08-28 12:01:44 +0000 @@ -0,0 +1,44 @@ +package org.hisp.dhis.common; + +/* + * Copyright (c) 2004-2014, 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 HISP project 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 org.hisp.dhis.expression.MissingValueStrategy; +import org.hisp.dhis.hibernate.EnumUserType; + +/** + * @author Lars Helge Overland + */ +public class MissingValueStrategyUserType + extends EnumUserType +{ + public MissingValueStrategyUserType() + { + super( MissingValueStrategy.class ); + } +} === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/expression/DefaultExpressionService.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/expression/DefaultExpressionService.java 2014-08-15 07:40:20 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/expression/DefaultExpressionService.java 2014-08-28 12:01:44 +0000 @@ -35,6 +35,7 @@ import static org.hisp.dhis.expression.Expression.SEPARATOR; import static org.hisp.dhis.system.util.MathUtils.calculateExpression; import static org.hisp.dhis.system.util.MathUtils.isEqual; +import static org.hisp.dhis.expression.MissingValueStrategy.*; import java.util.Collection; import java.util.HashSet; @@ -164,7 +165,8 @@ return null; } - final String denominatorExpression = generateExpression( indicator.getExplodedDenominatorFallback(), valueMap, constantMap, orgUnitCountMap, days, false ); + final String denominatorExpression = generateExpression( indicator.getExplodedDenominatorFallback(), + valueMap, constantMap, orgUnitCountMap, days, NEVER_SKIP ); if ( denominatorExpression == null ) { @@ -175,7 +177,8 @@ if ( !isEqual( denominatorValue, 0d ) ) { - final String numeratorExpression = generateExpression( indicator.getExplodedNumeratorFallback(), valueMap, constantMap, orgUnitCountMap, days, false ); + final String numeratorExpression = generateExpression( indicator.getExplodedNumeratorFallback(), + valueMap, constantMap, orgUnitCountMap, days, NEVER_SKIP ); if ( numeratorExpression == null ) { @@ -197,21 +200,14 @@ public Double getExpressionValue( Expression expression, Map valueMap, Map constantMap, Map orgUnitCountMap, Integer days ) { - final String expressionString = generateExpression( expression.getExplodedExpressionFallback(), valueMap, constantMap, - orgUnitCountMap, days, expression.isNullIfBlank() ); - - Double result = expressionString != null ? calculateExpression( expressionString ) : null; - - log.debug( "Expression: " + expression.getExplodedExpressionFallback() + ", generated: " + expressionString + ", result: " + result ); - - return result; + return getExpressionValue( expression, valueMap, constantMap, orgUnitCountMap, days, null ); } public Double getExpressionValue( Expression expression, Map valueMap, Map constantMap, Map orgUnitCountMap, Integer days, Set incompleteValues ) { - final String expressionString = generateExpression( expression.getExplodedExpressionFallback(), valueMap, constantMap, orgUnitCountMap, days, - expression.isNullIfBlank(), incompleteValues ); + String expressionString = generateExpression( expression.getExplodedExpressionFallback(), valueMap, constantMap, + orgUnitCountMap, days, expression.getMissingValueStrategy(), incompleteValues ); Double result = expressionString != null ? calculateExpression( expressionString ) : null; @@ -823,19 +819,21 @@ @Transactional public String generateExpression( String expression, Map valueMap, - Map constantMap, Map orgUnitCountMap, Integer days, boolean nullIfNoValues ) + Map constantMap, Map orgUnitCountMap, Integer days, MissingValueStrategy missingValueStrategy ) { - return generateExpression( expression, valueMap, constantMap, orgUnitCountMap, days, nullIfNoValues, null ); + return generateExpression( expression, valueMap, constantMap, orgUnitCountMap, days, missingValueStrategy, null ); } private String generateExpression( String expression, Map valueMap, - Map constantMap, Map orgUnitCountMap, Integer days, boolean nullIfNoValues, Set incompleteValues ) + Map constantMap, Map orgUnitCountMap, Integer days, MissingValueStrategy missingValueStrategy, Set incompleteValues ) { if ( expression == null || expression.isEmpty() ) { return null; } + missingValueStrategy = missingValueStrategy == null ? NEVER_SKIP : missingValueStrategy; + // --------------------------------------------------------------------- // Operands // --------------------------------------------------------------------- @@ -843,22 +841,39 @@ StringBuffer sb = new StringBuffer(); Matcher matcher = OPERAND_PATTERN.matcher( expression ); + int matchCount = 0; + int valueCount = 0; + while ( matcher.find() ) { + matchCount++; + DataElementOperand operand = DataElementOperand.getOperand( matcher.group() ); final Double value = valueMap.get( operand ); - if ( nullIfNoValues && ( value == null || ( incompleteValues != null && incompleteValues.contains( operand ) ) ) ) + boolean missingValue = value == null || ( incompleteValues != null && incompleteValues.contains( operand ) ); + + if ( missingValue && SKIP_IF_ANY_VALUE_MISSING.equals( missingValueStrategy ) ) { return null; } + + if ( !missingValue ) + { + valueCount++; + } String replacement = value != null ? String.valueOf( value ) : NULL_REPLACEMENT; matcher.appendReplacement( sb, replacement ); } + if ( SKIP_IF_ALL_VALUES_MISSING.equals( missingValueStrategy ) && matchCount > 0 && valueCount == 0 ) + { + return null; + } + expression = appendTail( matcher, sb ); // --------------------------------------------------------------------- === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableAlteror.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableAlteror.java 2014-08-26 10:51:19 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableAlteror.java 2014-08-28 12:01:44 +0000 @@ -722,6 +722,10 @@ // validation rule group, new column alertbyorgunits executeSql( "UPDATE validationrulegroup SET alertbyorgunits=false WHERE alertbyorgunits IS NULL" ); + + executeSql( "update expression set missingvaluestrategy = 'SKIP_IF_ANY_VALUE_MISSING' where nullifblank = true or nullifblank is null" ); + executeSql( "update expression set missingvaluestrategy = 'NEVER_SKIP' where nullifblank = false" ); + executeSql( "alter table expression alter column missingvaluestrategy set not null" ); upgradeDataValuesWithAttributeOptionCombo(); upgradeCompleteDataSetRegistrationsWithAttributeOptionCombo(); === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/expression/hibernate/Expression.hbm.xml' --- dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/expression/hibernate/Expression.hbm.xml 2014-08-26 10:51:19 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/expression/hibernate/Expression.hbm.xml 2014-08-28 12:01:44 +0000 @@ -16,7 +16,7 @@ - + === modified file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/expression/ExpressionServiceTest.java' --- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/expression/ExpressionServiceTest.java 2014-08-26 10:51:19 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/expression/ExpressionServiceTest.java 2014-08-28 12:01:44 +0000 @@ -358,10 +358,10 @@ Map orgUnitCountMap = new HashMap<>(); orgUnitCountMap.put( groupA.getUid(), groupA.getMembers().size() ); - assertEquals( "12.0+34.0", expressionService.generateExpression( expressionA, valueMap, constantMap, null, null, false ) ); - assertEquals( "12.0+5", expressionService.generateExpression( expressionD, valueMap, constantMap, null, 5, false ) ); - assertEquals( "12.0*2.0", expressionService.generateExpression( expressionE, valueMap, constantMap, null, null, false ) ); - assertEquals( "12.0*3", expressionService.generateExpression( expressionH, valueMap, constantMap, orgUnitCountMap, null, false ) ); + assertEquals( "12.0+34.0", expressionService.generateExpression( expressionA, valueMap, constantMap, null, null, null ) ); + assertEquals( "12.0+5", expressionService.generateExpression( expressionD, valueMap, constantMap, null, 5, null ) ); + assertEquals( "12.0*2.0", expressionService.generateExpression( expressionE, valueMap, constantMap, null, null, null ) ); + assertEquals( "12.0*3", expressionService.generateExpression( expressionH, valueMap, constantMap, orgUnitCountMap, null, null ) ); } @Test @@ -371,9 +371,9 @@ Map constantMap = new HashMap<>(); - assertNull( expressionService.generateExpression( expressionA, valueMap, constantMap, null, null, true ) ); - assertNull( expressionService.generateExpression( expressionD, valueMap, constantMap, null, 5, true ) ); - assertNotNull( expressionService.generateExpression( expressionE, valueMap, constantMap, null, null, false ) ); + assertNull( expressionService.generateExpression( expressionA, valueMap, constantMap, null, null, MissingValueStrategy.SKIP_IF_ANY_VALUE_MISSING ) ); + assertNull( expressionService.generateExpression( expressionD, valueMap, constantMap, null, 5, MissingValueStrategy.SKIP_IF_ANY_VALUE_MISSING ) ); + assertNotNull( expressionService.generateExpression( expressionE, valueMap, constantMap, null, null, MissingValueStrategy.NEVER_SKIP ) ); } @Test === modified file 'dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/indicator/DefaultIndicatorDataMart.java' --- dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/indicator/DefaultIndicatorDataMart.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/indicator/DefaultIndicatorDataMart.java 2014-08-28 12:01:44 +0000 @@ -164,11 +164,11 @@ { for ( final Indicator indicator : indicators ) { - final double denominatorValue = calculateExpression( expressionService.generateExpression( indicator.getExplodedDenominator(), valueMap, constantMap, null, days, false ) ); + final double denominatorValue = calculateExpression( expressionService.generateExpression( indicator.getExplodedDenominator(), valueMap, constantMap, null, days, null ) ); if ( !isEqual( denominatorValue, 0d ) ) { - final double numeratorValue = calculateExpression( expressionService.generateExpression( indicator.getExplodedNumerator(), valueMap, constantMap, null, days, false ) ); + final double numeratorValue = calculateExpression( expressionService.generateExpression( indicator.getExplodedNumerator(), valueMap, constantMap, null, days, null ) ); if ( !( omitZeroNumerator && isEqual( numeratorValue, 0d ) ) ) { === modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/csv/DefaultCsvImportService.java' --- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/csv/DefaultCsvImportService.java 2014-08-26 10:51:19 +0000 +++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/csv/DefaultCsvImportService.java 2014-08-28 12:01:44 +0000 @@ -50,6 +50,7 @@ import org.hisp.dhis.dxf2.metadata.MetaData; import org.hisp.dhis.expression.Expression; import org.hisp.dhis.expression.ExpressionService; +import org.hisp.dhis.expression.MissingValueStrategy; import org.hisp.dhis.expression.Operator; import org.hisp.dhis.option.Option; import org.hisp.dhis.option.OptionSet; @@ -259,15 +260,13 @@ leftSide.setExpression( getSafe( values, 9, null, 255 ) ); leftSide.setDescription( getSafe( values, 10, null, 255 ) ); - leftSide.setNullIfBlank( Boolean.valueOf( getSafe( values, 11, Boolean.FALSE.toString(), 5 ) ) ); + leftSide.setMissingValueStrategy( MissingValueStrategy.safeValueOf( getSafe( values, 11, MissingValueStrategy.NEVER_SKIP.toString(), 50 ) ) ); leftSide.setDataElementsInExpression( expressionService.getDataElementsInExpression( leftSide.getExpression() ) ); - leftSide.setNullIfBlank( true ); rightSide.setExpression( getSafe( values, 12, null, 255 ) ); rightSide.setDescription( getSafe( values, 13, null, 255 ) ); - rightSide.setNullIfBlank( Boolean.valueOf( getSafe( values, 14, Boolean.FALSE.toString(), 5 ) ) ); + rightSide.setMissingValueStrategy( MissingValueStrategy.safeValueOf( getSafe( values, 14, MissingValueStrategy.NEVER_SKIP.toString(), 50 ) ) ); rightSide.setDataElementsInExpression( expressionService.getDataElementsInExpression( rightSide.getExpression() ) ); - rightSide.setNullIfBlank( true ); object.setLeftSide( leftSide ); object.setRightSide( rightSide ); === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/indicatorExpressionBuilderForm.vm' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/indicatorExpressionBuilderForm.vm 2014-07-26 18:27:49 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/indicatorExpressionBuilderForm.vm 2014-08-28 12:01:44 +0000 @@ -37,15 +37,15 @@ $i18n.getString( "organisation_unit_counts" ) - +
$i18n.getString( "tip" ): $i18n.getString( "use" ) abs(x) sin(x) cos(x) tan(x) ln(x) log(x) sqrt(x) mod(x,y)
- + - + === modified file 'dhis-2/dhis-web/dhis-web-validationrule/src/main/java/org/hisp/dhis/validationrule/action/AddValidationRuleAction.java' --- dhis-2/dhis-web/dhis-web-validationrule/src/main/java/org/hisp/dhis/validationrule/action/AddValidationRuleAction.java 2014-08-26 10:51:19 +0000 +++ dhis-2/dhis-web/dhis-web-validationrule/src/main/java/org/hisp/dhis/validationrule/action/AddValidationRuleAction.java 2014-08-28 12:01:44 +0000 @@ -28,6 +28,9 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import static org.hisp.dhis.expression.MissingValueStrategy.SKIP_IF_ANY_VALUE_MISSING; +import static org.hisp.dhis.expression.MissingValueStrategy.safeValueOf; + import org.hisp.dhis.expression.Expression; import org.hisp.dhis.expression.ExpressionService; import org.hisp.dhis.expression.Operator; @@ -133,11 +136,11 @@ this.leftSideDescription = leftSideDescription; } - private boolean leftSideNullIfBlank; + private String leftSideMissingValueStrategy; - public void setLeftSideNullIfBlank( boolean leftSideNullIfBlank ) + public void setLeftSideMissingValueStrategy( String leftSideMissingValueStrategy ) { - this.leftSideNullIfBlank = leftSideNullIfBlank; + this.leftSideMissingValueStrategy = leftSideMissingValueStrategy; } private String rightSideExpression; @@ -154,11 +157,11 @@ this.rightSideDescription = rightSideDescription; } - private boolean rightSideNullIfBlank; + private String rightSideMissingValueStrategy; - public void setRightSideNullIfBlank( boolean rightSideNullIfBlank ) + public void setRightSideMissingValueStrategy( String rightSideMissingValueStrategy ) { - this.rightSideNullIfBlank = rightSideNullIfBlank; + this.rightSideMissingValueStrategy = rightSideMissingValueStrategy; } private Integer organisationUnitLevel; @@ -213,14 +216,14 @@ leftSide.setExpression( leftSideExpression ); leftSide.setDescription( leftSideDescription ); - leftSide.setNullIfBlank( leftSideNullIfBlank ); + leftSide.setMissingValueStrategy( safeValueOf( leftSideMissingValueStrategy, SKIP_IF_ANY_VALUE_MISSING ) ); leftSide.setDataElementsInExpression( expressionService.getDataElementsInExpression( leftSideExpression ) ); Expression rightSide = new Expression(); rightSide.setExpression( rightSideExpression ); rightSide.setDescription( rightSideDescription ); - rightSide.setNullIfBlank( rightSideNullIfBlank ); + rightSide.setMissingValueStrategy( safeValueOf( rightSideMissingValueStrategy, SKIP_IF_ANY_VALUE_MISSING ) ); rightSide.setDataElementsInExpression( expressionService.getDataElementsInExpression( rightSideExpression ) ); ValidationRule validationRule = new ValidationRule(); === modified file 'dhis-2/dhis-web/dhis-web-validationrule/src/main/java/org/hisp/dhis/validationrule/action/UpdateValidationRuleAction.java' --- dhis-2/dhis-web/dhis-web-validationrule/src/main/java/org/hisp/dhis/validationrule/action/UpdateValidationRuleAction.java 2014-08-26 10:51:19 +0000 +++ dhis-2/dhis-web/dhis-web-validationrule/src/main/java/org/hisp/dhis/validationrule/action/UpdateValidationRuleAction.java 2014-08-28 12:01:44 +0000 @@ -28,6 +28,9 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import static org.hisp.dhis.expression.MissingValueStrategy.SKIP_IF_ANY_VALUE_MISSING; +import static org.hisp.dhis.expression.MissingValueStrategy.safeValueOf; + import org.hisp.dhis.expression.ExpressionService; import org.hisp.dhis.expression.Operator; import org.hisp.dhis.period.PeriodService; @@ -40,8 +43,6 @@ /** * @author Margrethe Store * @author Lars Helge Overland - * @version $Id: UpdateValidationRuleAction.java 3868 2007-11-08 15:11:12Z - * larshelg $ */ public class UpdateValidationRuleAction implements Action @@ -138,11 +139,11 @@ this.leftSideDescription = leftSideDescription; } - private boolean leftSideNullIfBlank; + private String leftSideMissingValueStrategy; - public void setLeftSideNullIfBlank( boolean leftSideNullIfBlank ) + public void setLeftSideMissingValueStrategy( String leftSideMissingValueStrategy ) { - this.leftSideNullIfBlank = leftSideNullIfBlank; + this.leftSideMissingValueStrategy = leftSideMissingValueStrategy; } private String rightSideExpression; @@ -159,11 +160,11 @@ this.rightSideDescription = rightSideDescription; } - private boolean rightSideNullIfBlank; + private String rightSideMissingValueStrategy; - public void setRightSideNullIfBlank( boolean rightSideNullIfBlank ) + public void setRightSideMissingValueStrategy( String rightSideMissingValueStrategy ) { - this.rightSideNullIfBlank = rightSideNullIfBlank; + this.rightSideMissingValueStrategy = rightSideMissingValueStrategy; } private Integer organisationUnitLevel; @@ -225,12 +226,12 @@ validationRule.getLeftSide().setExpression( leftSideExpression ); validationRule.getLeftSide().setDescription( leftSideDescription ); - validationRule.getLeftSide().setNullIfBlank( leftSideNullIfBlank ); + validationRule.getLeftSide().setMissingValueStrategy( safeValueOf( leftSideMissingValueStrategy, SKIP_IF_ANY_VALUE_MISSING ) ); validationRule.getLeftSide().setDataElementsInExpression( expressionService.getDataElementsInExpression( leftSideExpression ) ); validationRule.getRightSide().setExpression( rightSideExpression ); validationRule.getRightSide().setDescription( rightSideDescription ); - validationRule.getRightSide().setNullIfBlank( rightSideNullIfBlank ); + validationRule.getRightSide().setMissingValueStrategy( safeValueOf( rightSideMissingValueStrategy, SKIP_IF_ANY_VALUE_MISSING ) ); validationRule.getRightSide().setDataElementsInExpression( expressionService.getDataElementsInExpression( rightSideExpression ) ); validationRule.setOrganisationUnitLevel( organisationUnitLevel ); === modified file 'dhis-2/dhis-web/dhis-web-validationrule/src/main/resources/org/hisp/dhis/validationrule/i18n_module.properties' --- dhis-2/dhis-web/dhis-web-validationrule/src/main/resources/org/hisp/dhis/validationrule/i18n_module.properties 2014-05-18 00:49:40 +0000 +++ dhis-2/dhis-web/dhis-web-validationrule/src/main/resources/org/hisp/dhis/validationrule/i18n_module.properties 2014-08-28 12:01:44 +0000 @@ -153,4 +153,7 @@ number_of_user_groups_to_alert=Number of user groups to alert send_alerts=Send alerts visible_when_rule_is_violated=visible when rule is violated -instruction=Instruction \ No newline at end of file +instruction=Instruction +skip_if_any_value_is_missing=Skip if any value is missing +skip_if_all_values_are_missing=Skip if all values are missing +never_skip=Never skip === modified file 'dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/addValidationRuleForm.vm' --- dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/addValidationRuleForm.vm 2014-03-04 00:22:37 +0000 +++ dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/addValidationRuleForm.vm 2014-08-28 12:01:44 +0000 @@ -97,13 +97,13 @@ - + - + === modified file 'dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/expressionBuilderForm.vm' --- dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/expressionBuilderForm.vm 2014-07-26 18:27:49 +0000 +++ dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/expressionBuilderForm.vm 2014-08-28 12:01:44 +0000 @@ -19,16 +19,20 @@ $i18n.getString( "description" ) - $i18n.getString( "constants" ) + $i18n.getString( "constants" ) - +
-   -
$encoder.htmlEncode( $i18n.getString( "tip" ) ): $encoder.htmlEncode( $i18n.getString( "use" ) ) abs(x) ln(x) log(x) sqrt(x) mod(x,y)
+ +
+ +
+ + - - + + === modified file 'dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/javascript/expression.js' --- dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/javascript/expression.js 2013-10-13 18:58:45 +0000 +++ dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/javascript/expression.js 2014-08-28 12:01:44 +0000 @@ -63,7 +63,6 @@ { addOptionById( "dataElementId", "[" + objects[i].operandId + "]", objects[i].operandName ); } - } ); } @@ -125,26 +124,6 @@ } ); } -function validateExpressionReceived( xmlObject ) -{ - var type = xmlObject.getAttribute( 'type' ); - var message = xmlObject.firstChild.nodeValue; - - if ( type == "success" ) - { - var description = byId( "expDescription" ).value; - var expression = byId( "expression" ).value; - var textualDescription = byId( "textualExpression" ).innerHTML; - var side = byId( "side" ).value; - saveExpression( side, description, expression, textualDescription ); - disable( 'periodTypeName' ); - } - else if ( type == "error" ) - { - byId( "textualExpression" ).innerHTML = message; - } -} - function saveExpression( side, description, expression, textualDescription ) { if ( side == "left" ) === modified file 'dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/javascript/expressionBuilder.js' --- dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/javascript/expressionBuilder.js 2014-07-26 18:27:49 +0000 +++ dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/javascript/expressionBuilder.js 2014-08-28 12:01:44 +0000 @@ -9,7 +9,7 @@ minWidth: 840, minHeight: 560, width: 840, - height: 630, + height: 655, title: "Expression" }); @@ -24,11 +24,13 @@ function editLeftExpression() { left = true; + var strategy = $( '#leftSideMissingValueStrategy' ).val(); + strategy = ( strategy ) ? strategy : 'SKIP_IF_ANY_VALUE_MISSING'; $( '#expression' ).val( $( '#leftSideExpression' ).val() ); $( '#description' ).val( $( '#leftSideDescription' ).val() ); $( '#formulaText' ).text( $( '#leftSideTextualExpression' ).val() ); - $( '#nullIfBlank' ).attr( 'checked', ( $( '#leftSideNullIfBlank' ).val() == 'true' || $( '#leftSideNullIfBlank' ).val() == '' ) ); + $( 'input[name="missingValueStrategy"][value="' + strategy + '"]' ).prop( 'checked', true ); dialog.dialog("open"); } @@ -36,11 +38,13 @@ function editRightExpression() { left = false; + var strategy = $( '#rightSideMissingValueStrategy' ).val(); + strategy = ( strategy ) ? strategy : 'SKIP_IF_ANY_VALUE_MISSING'; $( '#expression' ).val( $( '#rightSideExpression' ).val() ); $( '#description' ).val( $( '#rightSideDescription' ).val() ); $( '#formulaText' ).text( $( '#rightSideTextualExpression' ).val() ); - $( '#nullIfBlank' ).attr( 'checked', ( $( '#rightSideNullIfBlank' ).val() == 'true' || $( '#rightSideNullIfBlank' ).val() == '' ) ); + $( 'input[name="missingValueStrategy"][value="' + strategy + '"]' ).prop( 'checked', true ); dialog.dialog("open"); } @@ -116,8 +120,10 @@ function insertExpression() { - var expression = $( '#expression' ).val(); - var description = $( '#description' ).val(); + var expression = $( '#expression' ).val(), + description = $( '#description' ).val(), + formulaText = $( '#formulaText' ).text(), + missingValueStrategy = $( 'input[name="missingValueStrategy"]:checked' ).val(); jQuery.postJSON( '../dhis-web-commons-ajax-json/getExpressionText.action', { @@ -127,23 +133,23 @@ { if ( json.response == 'error' ) { - markInvalid( 'expression-container textarea[id=expression]' , json.message ); + markInvalid( 'expression-container textarea[id=expression]', json.message ); } else { if ( left ) { $( '#leftSideExpression' ).val( expression ); - $( '#leftSideDescription' ).val( description ); - $( '#leftSideTextualExpression' ).val( $( '#formulaText' ).text() ); - $( '#leftSideNullIfBlank' ).val( $( '#nullIfBlank' ).is( ':checked' ) ); + $( '#leftSideDescription' ).val( description ); + $( '#leftSideTextualExpression' ).val( formulaText ); + $( '#leftSideMissingValueStrategy' ).val( missingValueStrategy ); } else { $( '#rightSideExpression' ).val( expression ); - $( '#rightSideDescription' ).val( description ); - $( '#rightSideTextualExpression' ).val( $( '#formulaText' ).text() ); - $( '#rightSideNullIfBlank' ).val( $( '#nullIfBlank' ).is( ':checked' ) ); + $( '#rightSideDescription' ).val( description ); + $( '#rightSideTextualExpression' ).val( formulaText ); + $( '#rightSideMissingValueStrategy' ).val( missingValueStrategy ); } dialog.dialog( "close" ); === modified file 'dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/updateValidationRuleForm.vm' --- dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/updateValidationRuleForm.vm 2014-07-26 19:04:03 +0000 +++ dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/updateValidationRuleForm.vm 2014-08-28 12:01:44 +0000 @@ -105,13 +105,13 @@ - + - +