← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 3693: Implemented support for number of days in indicator and validation rule formulas

 

------------------------------------------------------------
revno: 3693
committer: Lars Helge Overland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Fri 2011-05-20 18:00:10 +0200
message:
  Implemented support for number of days in indicator and validation rule formulas
added:
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/images/no_of_days.png
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/ExpressionService.java
  dhis-2/dhis-services/dhis-service-aggregationengine-default/src/main/java/org/hisp/dhis/aggregation/impl/indicator/IndicatorAggregation.java
  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/validation/DefaultValidationRuleService.java
  dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/expression/ExpressionServiceTest.java
  dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/indicator/DefaultIndicatorDataMart.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/resources/org/hisp/dhis/dd/i18n_module.properties
  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-validationrule/src/main/resources/org/hisp/dhis/validationrule/i18n_module.properties
  dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/expressionBuilderForm.vm


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== 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	2011-05-20 12:27:47 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/ExpressionService.java	2011-05-20 16:00:10 +0000
@@ -56,9 +56,10 @@
 
     final String NULL_REPLACEMENT = "0";
     final String SPACE = " ";
-    
-    final String FORMULA_EXPRESSION = "\\[\\d+?.*?\\]"; // [ - one or more digits - any characters - ]
-    final String DAYS_EXPRESSION = "\\[days\\]"; // [days]
+
+    final String FORMULA_EXPRESSION = "\\[.+?\\]";
+    final String OPERAND_EXPRESSION = "\\[\\d+?.*?\\]";
+    final String DAYS_EXPRESSION = "[days]";
     
     /**
      * Adds a new Expression to the database.
@@ -106,12 +107,13 @@
      * @param nullIfNoValues indicates whether null should be returned if no
      *        DataValues are registered for a DataElement in the expression.
      * @param aggregated indicates whether aggregated or raw data should be
-     *        used when evaluating the expression.
+     *        used when evaluating the expression.     *        
+     * @param days The number to be substituted with the days expression in the formula.
      * @return The value of the given Expression, or null
      *         if no values are registered for a given combination of 
      *         DataElement, Source, and Period.
      */
-    Double getExpressionValue( Expression expression, Period period, OrganisationUnit source, boolean nullIfNoValues, boolean aggregate );
+    Double getExpressionValue( Expression expression, Period period, OrganisationUnit source, boolean nullIfNoValues, boolean aggregate, Integer days );
     
     /**
      * Returns all DataElements included in the given expression string.
@@ -192,9 +194,10 @@
      *        DataValues are registered for a DataElement in the expression.
      * @param aggregated indicates whether aggregated or raw data should be
      *        used when evaluating the expression.
+     * @param days The number to be substituted with the days expression in the formula.
      * @return A numerical expression.
      */    
-    String generateExpression( String expression, Period period, OrganisationUnit source, boolean nullIfNoValues, boolean aggregated );
+    String generateExpression( String expression, Period period, OrganisationUnit source, boolean nullIfNoValues, boolean aggregated, Integer days );
 
     /**
      * Generates an expression where the Operand identifiers, consisting of 
@@ -204,6 +207,7 @@
      * 
      * @param formula The formula to parse.
      * @param valueMap The map containing data element identifiers and aggregated value.
+     * @param days The number to be substituted with the days expression in the formula.
      */
-    String generateExpression( String expression, Map<DataElementOperand, Double> valueMap );
+    String generateExpression( String expression, Map<DataElementOperand, Double> valueMap, Integer days );
 }

=== modified file 'dhis-2/dhis-services/dhis-service-aggregationengine-default/src/main/java/org/hisp/dhis/aggregation/impl/indicator/IndicatorAggregation.java'
--- dhis-2/dhis-services/dhis-service-aggregationengine-default/src/main/java/org/hisp/dhis/aggregation/impl/indicator/IndicatorAggregation.java	2011-05-20 13:27:02 +0000
+++ dhis-2/dhis-services/dhis-service-aggregationengine-default/src/main/java/org/hisp/dhis/aggregation/impl/indicator/IndicatorAggregation.java	2011-05-20 16:00:10 +0000
@@ -29,6 +29,7 @@
 
 import static org.hisp.dhis.system.util.MathUtils.INVALID;
 import static org.hisp.dhis.system.util.MathUtils.calculateExpression;
+import static org.hisp.dhis.system.util.DateUtils.daysBetween;
 
 import java.util.Date;
 import java.util.HashMap;
@@ -91,11 +92,13 @@
     public Double getAggregatedIndicatorValue( Indicator indicator, Date startDate, Date endDate,
         OrganisationUnit organisationUnit )
     {
+        int days = daysBetween( startDate, endDate );
+        
         double numeratorValue = calculateExpression( generateExpression( indicator.getNumerator(), startDate,
-            endDate, organisationUnit ) );
+            endDate, organisationUnit, days ) );
         
         double denominatorValue = calculateExpression( generateExpression( indicator.getDenominator(),
-            startDate, endDate, organisationUnit ) );
+            startDate, endDate, organisationUnit, days ) );
         
         if ( numeratorValue == INVALID || denominatorValue == INVALID || denominatorValue == 0.0 )
         {
@@ -117,21 +120,21 @@
         OrganisationUnit organisationUnit )
     {
         return calculateExpression( generateExpression( indicator.getNumerator(), startDate,
-            endDate, organisationUnit ) );
+            endDate, organisationUnit, daysBetween( startDate, endDate ) ) );
     }
 
     public double getAggregatedDenominatorValue( Indicator indicator, Date startDate, Date endDate,
         OrganisationUnit organisationUnit )
     {
         return calculateExpression( generateExpression( indicator.getDenominator(),
-            startDate, endDate, organisationUnit ) );
+            startDate, endDate, organisationUnit, daysBetween( startDate, endDate ) ) );
     }
 
     // -------------------------------------------------------------------------
     // Supportive methods
     // -------------------------------------------------------------------------
     
-    private String generateExpression( String expression, Date startDate, Date endDate, OrganisationUnit organisationUnit )
+    private String generateExpression( String expression, Date startDate, Date endDate, OrganisationUnit organisationUnit, int days )
     {
         Set<DataElementOperand> operands = expressionService.getOperandsInExpression( expression );
         
@@ -145,6 +148,6 @@
             valueMap.put( operand, aggregationCache.getAggregatedDataValue( dataElement, optionCombo, startDate, endDate, organisationUnit ) );            
         }
         
-        return expressionService.generateExpression( expression, valueMap );
+        return expressionService.generateExpression( expression, valueMap, null );
     }
 }

=== 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	2011-05-20 12:27:47 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/expression/DefaultExpressionService.java	2011-05-20 16:00:10 +0000
@@ -72,7 +72,9 @@
     private static final Log log = LogFactory.getLog( DefaultExpressionService.class );
     
     private final Pattern FORMULA_PATTERN = Pattern.compile( FORMULA_EXPRESSION );
-
+    private final Pattern OPERAND_PATTERN = Pattern.compile( OPERAND_EXPRESSION );
+    private final String DAYS_DESCRIPTION = "[Number of days]";
+    
     // -------------------------------------------------------------------------
     // Dependencies
     // -------------------------------------------------------------------------
@@ -145,9 +147,9 @@
     // Business logic
     // -------------------------------------------------------------------------
 
-    public Double getExpressionValue( Expression expression, Period period, OrganisationUnit source, boolean nullIfNoValues, boolean aggregate )
+    public Double getExpressionValue( Expression expression, Period period, OrganisationUnit source, boolean nullIfNoValues, boolean aggregate, Integer days )
     {
-        final String expressionString = generateExpression( expression.getExpression(), period, source, nullIfNoValues, aggregate );
+        final String expressionString = generateExpression( expression.getExpression(), period, source, nullIfNoValues, aggregate, days );
 
         return expressionString != null ? calculateExpression( expressionString ) : null;
     }    
@@ -160,7 +162,7 @@
         {
             dataElementsInExpression = new HashSet<DataElement>();
 
-            final Matcher matcher = FORMULA_PATTERN.matcher( expression );
+            final Matcher matcher = OPERAND_PATTERN.matcher( expression );
             
             while ( matcher.find() )
             {
@@ -182,7 +184,7 @@
         
         if ( expression != null )
         {
-            final Matcher matcher = FORMULA_PATTERN.matcher( expression );
+            final Matcher matcher = OPERAND_PATTERN.matcher( expression );
 
             while ( matcher.find() )
             {
@@ -227,7 +229,7 @@
         {
             operandsInExpression = new HashSet<DataElementOperand>();
 
-            final Matcher matcher = FORMULA_PATTERN.matcher( expression );
+            final Matcher matcher = OPERAND_PATTERN.matcher( expression );
 
             while ( matcher.find() )
             {
@@ -253,25 +255,30 @@
         {
             DataElementOperand operand = null;
             
-            try
-            {
-                operand = DataElementOperand.getOperand( matcher.group() );
-            }
-            catch ( NumberFormatException ex )
-            {
-                return ID_NOT_NUMERIC;
-            }
-
-            if ( !dataElementService.dataElementExists( operand.getDataElementId()  ) )
-            {
-                return DATAELEMENT_DOES_NOT_EXIST;
-            }
-
-            if ( !operand.isTotal() && !dataElementService.dataElementCategoryOptionComboExists( operand.getOptionComboId() ) )
-            {
-                return CATEGORYOPTIONCOMBO_DOES_NOT_EXIST;
-            }
-
+            String match = matcher.group();
+            
+            if ( !DAYS_EXPRESSION.equals( match ) )
+            {
+                try
+                {
+                    operand = DataElementOperand.getOperand( match );
+                }
+                catch ( NumberFormatException ex )
+                {
+                    return ID_NOT_NUMERIC;
+                }
+    
+                if ( !dataElementService.dataElementExists( operand.getDataElementId()  ) )
+                {
+                    return DATAELEMENT_DOES_NOT_EXIST;
+                }
+    
+                if ( !operand.isTotal() && !dataElementService.dataElementCategoryOptionComboExists( operand.getOptionComboId() ) )
+                {
+                    return CATEGORYOPTIONCOMBO_DOES_NOT_EXIST;
+                }
+            }
+            
             // -----------------------------------------------------------------
             // Replacing the operand with 1.1 in order to later be able to verify
             // that the formula is mathematically valid
@@ -304,25 +311,32 @@
             {
                 String match = matcher.group();
                 
-                final DataElementOperand operand = DataElementOperand.getOperand( match );
-                
-                final DataElement dataElement = dataElementService.getDataElement( operand.getDataElementId() );
-                final DataElementCategoryOptionCombo categoryOptionCombo = 
-                    categoryService.getDataElementCategoryOptionCombo( operand.getOptionComboId() );
-
-                if ( dataElement == null )
-                {
-                    throw new IllegalArgumentException( "Identifier does not reference a data element: "
-                        + operand.getDataElementId() );
-                }
-
-                if ( !operand.isTotal() && categoryOptionCombo == null )
-                {
-                    throw new IllegalArgumentException( "Identifier does not reference a category option combo: "
-                        + operand.getOptionComboId() );
-                }
-
-                match = DataElementOperand.getPrettyName( dataElement, categoryOptionCombo );
+                if ( DAYS_EXPRESSION.equals( match ) )
+                {
+                    match = DAYS_DESCRIPTION;
+                }
+                else
+                {
+                    final DataElementOperand operand = DataElementOperand.getOperand( match );
+                    
+                    final DataElement dataElement = dataElementService.getDataElement( operand.getDataElementId() );
+                    final DataElementCategoryOptionCombo categoryOptionCombo = 
+                        categoryService.getDataElementCategoryOptionCombo( operand.getOptionComboId() );
+    
+                    if ( dataElement == null )
+                    {
+                        throw new IllegalArgumentException( "Identifier does not reference a data element: "
+                            + operand.getDataElementId() );
+                    }
+    
+                    if ( !operand.isTotal() && categoryOptionCombo == null )
+                    {
+                        throw new IllegalArgumentException( "Identifier does not reference a category option combo: "
+                            + operand.getOptionComboId() );
+                    }
+    
+                    match = DataElementOperand.getPrettyName( dataElement, categoryOptionCombo );
+                }
                 
                 matcher.appendReplacement( buffer, match );
             }
@@ -339,7 +353,7 @@
         
         if ( expression != null )
         {
-            final Matcher matcher = FORMULA_PATTERN.matcher( expression );
+            final Matcher matcher = OPERAND_PATTERN.matcher( expression );
             
             buffer = new StringBuffer();
             
@@ -372,7 +386,7 @@
         return buffer != null ? buffer.toString() : null;
     }
     
-    public String generateExpression( String expression, Period period, OrganisationUnit source, boolean nullIfNoValues, boolean aggregated )
+    public String generateExpression( String expression, Period period, OrganisationUnit source, boolean nullIfNoValues, boolean aggregated, Integer days )
     {
         StringBuffer buffer = null;
         
@@ -386,27 +400,34 @@
             {
                 String match = matcher.group();
 
-                final DataElementOperand operand = DataElementOperand.getOperand( match );
-                
-                String value = null;
-              
-                if ( aggregated )
-                {
-                    Double aggregatedValue = aggregatedDataValueService.getAggregatedDataValue( operand.getDataElementId(), operand.getOptionComboId(), period.getId(), source.getId() );
-
-                    value = aggregatedValue != null ? String.valueOf( aggregatedValue ) : null;
-                }
-                else
-                {
-                    value = dataValueService.getValue( operand.getDataElementId(), period.getId(), source.getId(), operand.getOptionComboId() );
-                }
-                
-                if ( value == null && nullIfNoValues )
-                {
-                    return null;
-                }
-                
-                match = ( value == null ) ? NULL_REPLACEMENT : value;
+                if ( DAYS_EXPRESSION.equals( match ) ) // Days
+                {
+                    match = days != null ? String.valueOf( days ) : NULL_REPLACEMENT;
+                }
+                else // Operand
+                {
+                    final DataElementOperand operand = DataElementOperand.getOperand( match );
+                    
+                    String value = null;
+                  
+                    if ( aggregated )
+                    {
+                        Double aggregatedValue = aggregatedDataValueService.getAggregatedDataValue( operand.getDataElementId(), operand.getOptionComboId(), period.getId(), source.getId() );
+    
+                        value = aggregatedValue != null ? String.valueOf( aggregatedValue ) : null;
+                    }
+                    else
+                    {
+                        value = dataValueService.getValue( operand.getDataElementId(), period.getId(), source.getId(), operand.getOptionComboId() );
+                    }
+                    
+                    if ( value == null && nullIfNoValues )
+                    {
+                        return null;
+                    }
+                    
+                    match = ( value == null ) ? NULL_REPLACEMENT : value;
+                }
                 
                 matcher.appendReplacement( buffer, match );
             }
@@ -417,7 +438,7 @@
         return buffer != null ? buffer.toString() : null;
     }
     
-    public String generateExpression( String expression, Map<DataElementOperand, Double> valueMap )
+    public String generateExpression( String expression, Map<DataElementOperand, Double> valueMap, Integer days )
     {   
         StringBuffer buffer = null;
         
@@ -431,11 +452,18 @@
             {
                 String match = matcher.group();
                 
-                final DataElementOperand operand = DataElementOperand.getOperand( match );
-                
-                Double aggregatedValue = valueMap.get( operand );
-                
-                match = ( aggregatedValue == null ) ? NULL_REPLACEMENT : String.valueOf( aggregatedValue );
+                if ( DAYS_EXPRESSION.equals( match ) ) // Days
+                {
+                    match = days != null ? String.valueOf( days ) : NULL_REPLACEMENT;
+                }
+                else // Operand
+                {
+                    final DataElementOperand operand = DataElementOperand.getOperand( match );
+                    
+                    Double aggregatedValue = valueMap.get( operand );
+                    
+                    match = ( aggregatedValue == null ) ? NULL_REPLACEMENT : String.valueOf( aggregatedValue );
+                }
                 
                 matcher.appendReplacement( buffer, match );
             }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/validation/DefaultValidationRuleService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/validation/DefaultValidationRuleService.java	2011-04-22 21:04:14 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/validation/DefaultValidationRuleService.java	2011-05-20 16:00:10 +0000
@@ -302,8 +302,8 @@
             {
                 if ( validationRule.getPeriodType() != null && validationRule.getPeriodType().equals( period.getPeriodType() ) )
                 {
-                    leftSide = expressionService.getExpressionValue( validationRule.getLeftSide(), period, source, true, aggregate );
-                    rightSide = expressionService.getExpressionValue( validationRule.getRightSide(), period, source, true, aggregate );
+                    leftSide = expressionService.getExpressionValue( validationRule.getLeftSide(), period, source, true, aggregate, null );
+                    rightSide = expressionService.getExpressionValue( validationRule.getRightSide(), period, source, true, aggregate, null );
         
                     if ( leftSide != null && rightSide != null )
                     {

=== 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	2011-05-20 12:27:47 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/expression/ExpressionServiceTest.java	2011-05-20 16:00:10 +0000
@@ -32,6 +32,7 @@
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
 import static org.hisp.dhis.expression.Expression.SEPARATOR;
+import static org.hisp.dhis.expression.ExpressionService.DAYS_EXPRESSION;
 
 import java.util.Collection;
 import java.util.HashMap;
@@ -94,6 +95,7 @@
     private String expressionA;
     private String expressionB;
     private String expressionC;
+    private String expressionD;
     
     private String descriptionA;
     private String descriptionB;
@@ -170,6 +172,7 @@
         expressionA = "[" + dataElementIdA + SEPARATOR + categoryOptionComboId + "]+[" + dataElementIdB + SEPARATOR + categoryOptionComboId + "]";
         expressionB = "[" + dataElementIdC + SEPARATOR + categoryOptionComboId + "]-[" + dataElementIdD + SEPARATOR + categoryOptionComboId + "]";
         expressionC = "[" + dataElementIdA + SEPARATOR + categoryOptionComboId + "]+[" + dataElementIdE + "]-10";
+        expressionD = "[" + dataElementIdA + SEPARATOR + categoryOptionComboId + "]+" + DAYS_EXPRESSION;
         
         descriptionA = "Expression A";
         descriptionB = "Expression B";
@@ -223,13 +226,13 @@
     {
         Expression expression = new Expression( expressionA, descriptionA, dataElements );
         
-        Double value = expressionService.getExpressionValue( expression, period, source, false, false );
+        Double value = expressionService.getExpressionValue( expression, period, source, false, false, null );
         
         assertEquals( value, 15.0 );
         
         expression = new Expression( expressionB, descriptionB, dataElements );
 
-        value = expressionService.getExpressionValue( expression, period, source, false, false );
+        value = expressionService.getExpressionValue( expression, period, source, false, false, null );
         
         assertEquals( 0.0, value );
     }
@@ -314,13 +317,9 @@
     @Test
     public void testGenerateExpression()
     {
-        String expression = expressionService.generateExpression( expressionA, period, source, false, false );
-        
-        assertEquals( "10+5", expression );
-        
-        expression = expressionService.generateExpression( expressionB, period, source, false, false );
-        
-        assertEquals( "0-0", expression );
+        assertEquals( "10+5", expressionService.generateExpression( expressionA, period, source, false, false, null ) );
+        assertEquals( "0-0", expressionService.generateExpression( expressionB, period, source, false, false, null ) );
+        assertEquals( "10+7", expressionService.generateExpression( expressionD, period, source, false, false, 7 ) );
     }
     
     @Test
@@ -330,7 +329,8 @@
         valueMap.put( new DataElementOperand( dataElementIdA, categoryOptionComboId ), new Double( 12 ) );
         valueMap.put( new DataElementOperand( dataElementIdB, categoryOptionComboId ), new Double( 34 ) );
         
-        assertEquals( "12.0+34.0", expressionService.generateExpression( expressionA, valueMap ) );        
+        assertEquals( "12.0+34.0", expressionService.generateExpression( expressionA, valueMap, null ) );        
+        assertEquals( "12.0+5", expressionService.generateExpression( expressionD, valueMap, 5 ) );
     }
     
     // -------------------------------------------------------------------------

=== 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	2011-05-20 13:27:02 +0000
+++ dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/indicator/DefaultIndicatorDataMart.java	2011-05-20 16:00:10 +0000
@@ -30,6 +30,7 @@
 import static org.hisp.dhis.options.SystemSettingManager.KEY_OMIT_INDICATORS_ZERO_NUMERATOR_DATAMART;
 import static org.hisp.dhis.system.util.MathUtils.calculateExpression;
 import static org.hisp.dhis.system.util.MathUtils.getRounded;
+import static org.hisp.dhis.system.util.DateUtils.daysBetween;
 
 import java.util.Collection;
 import java.util.HashMap;
@@ -147,6 +148,8 @@
         
         for ( final Period period : periods )
         {
+            int days = daysBetween( period.getStartDate(), period.getEndDate() );
+            
             final PeriodType periodType = period.getPeriodType();
             
             final Collection<DataElementOperand> sumOperands = sumIntAggregator.filterOperands( operands, periodType );
@@ -167,8 +170,8 @@
                 
                 for ( final Indicator indicator : indicators )
                 {
-                    final double numeratorValue = calculateExpression( expressionService.generateExpression( indicator.getExplodedNumerator(), valueMap ) );                    
-                    final double denominatorValue = calculateExpression( expressionService.generateExpression( indicator.getExplodedDenominator(), valueMap ) );
+                    final double numeratorValue = calculateExpression( expressionService.generateExpression( indicator.getExplodedNumerator(), valueMap, days ) );                    
+                    final double denominatorValue = calculateExpression( expressionService.generateExpression( indicator.getExplodedDenominator(), valueMap, days ) );
 
                     // ---------------------------------------------------------
                     // AggregatedIndicatorValue

=== added file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/images/no_of_days.png'
Binary files dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/images/no_of_days.png	1970-01-01 00:00:00 +0000 and dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/images/no_of_days.png	2011-05-20 16:00:10 +0000 differ
=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/resources/org/hisp/dhis/dd/i18n_module.properties'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/resources/org/hisp/dhis/dd/i18n_module.properties	2011-05-13 01:26:31 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/resources/org/hisp/dhis/dd/i18n_module.properties	2011-05-20 16:00:10 +0000
@@ -133,6 +133,7 @@
 divide											= Devide
 plus											= Plus
 minus											= Minus
+no_of_days										= Number of days
 data_dictionary_intro							= Please select an item from the menu.
 calculated										= Calculated
 saved											= Saved

=== 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	2011-05-13 05:39:55 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/indicatorExpressionBuilderForm.vm	2011-05-20 16:00:10 +0000
@@ -87,7 +87,7 @@
 		}
 	}
 	
-	function insertText( inputAreaName, inputText, radioGroupName )
+	function insertText( inputAreaName, inputText )
 	{
 		insertTextCommon( inputAreaName, inputText );	
 
@@ -180,12 +180,13 @@
 	<tr>
 		<td valign="top">
 		<textarea id="expression" name="expression" style="width:250px; height:150px" wrap="virtual" onchange="cleanExpression()" class="{validate:{required:true}}"></textarea><br/>
-		<a href="javascript:insertText( 'expression', '(', 'aggregationOperator' )"><img src="../images/left_parent.png" alt="$i18n.getString( 'left_brackets' )"/></a>
-		<a href="javascript:insertText( 'expression', ')', 'aggregationOperator' )"><img src="../images/right_parent.png" alt="$i18n.getString( 'right_brackets' )"/></a>
-		<a href="javascript:insertText( 'expression', '*', 'aggregationOperator' )"><img src="../images/multiply.png" alt="$i18n.getString( 'multiply' )"/></a>
-		<a href="javascript:insertText( 'expression', '/', 'aggregationOperator' )"><img src="../images/divide.png" alt="$i18n.getString( 'divide' )"/></a>
-		<a href="javascript:insertText( 'expression', '+', 'aggregationOperator' )"><img src="../images/plus.png" alt="$i18n.getString( 'plus' )"/></a>
-		<a href="javascript:insertText( 'expression', '-', 'aggregationOperator' )"><img src="../images/minus.png" alt="$i18n.getString( 'minus' )"/></a>
+		<a href="javascript:insertText( 'expression', '(' )"><img src="../images/left_parent.png" title="$i18n.getString( 'left_brackets' )"/></a>
+		<a href="javascript:insertText( 'expression', ')' )"><img src="../images/right_parent.png" title="$i18n.getString( 'right_brackets' )"/></a>
+		<a href="javascript:insertText( 'expression', '*' )"><img src="../images/multiply.png" title="$i18n.getString( 'multiply' )"/></a>
+		<a href="javascript:insertText( 'expression', '/' )"><img src="../images/divide.png" title="$i18n.getString( 'divide' )"/></a>
+		<a href="javascript:insertText( 'expression', '+' )"><img src="../images/plus.png" title="$i18n.getString( 'plus' )"/></a>
+		<a href="javascript:insertText( 'expression', '-' )"><img src="../images/minus.png" title="$i18n.getString( 'minus' )"/></a>
+		<a href="javascript:insertText( 'expression', '[days]' )"><img src="../images/no_of_days.png" title="$i18n.getString( 'no_of_days' )"/></a>
 		</td>
 		<td></td>
 		<td valign="top">
@@ -193,7 +194,7 @@
 			<input type="text" id="filter" name="filter" style="width:400px">
 			<input type="button" value="$i18n.getString( 'filter' )" onclick="getOperandsPage()" style="width:60px"><br/>
 
-			<select id="dataElementId" name="dataElementId" size="7" style="width:510px" ondblclick="insertText( 'expression', this.value, 'aggregationOperator' )">
+			<select id="dataElementId" name="dataElementId" size="7" style="width:510px" ondblclick="insertText( 'expression', this.value )">
 			</select>
 		</td>
 	</tr>

=== 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	2011-05-11 15:51:15 +0000
+++ dhis-2/dhis-web/dhis-web-validationrule/src/main/resources/org/hisp/dhis/validationrule/i18n_module.properties	2011-05-20 16:00:10 +0000
@@ -16,6 +16,7 @@
 divide= Divide
 plus= Plus
 minus= Minus
+no_of_days = Number of days
 specify_left_side	= Please specify the left side
 specify_right_side	= Please specify the right side
 specify_operator	= Please specify an operator

=== 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	2011-03-18 14:58:26 +0000
+++ dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/expressionBuilderForm.vm	2011-05-20 16:00:10 +0000
@@ -142,12 +142,13 @@
 	<tr>
 		<td valign="top">
 		<textarea id="expression" name="expression" style="width:250px; height:150px" wrap="virtual" onchange="getExpressionText()" class="{validate:{required:true}}"></textarea><br/>
-		<a href="javascript:insertText( 'expression', '(', 'aggregationOperator' )"><img src="../images/left_parent.png" alt="$i18n.getString( 'left_brackets' )"/></a>
-		<a href="javascript:insertText( 'expression', ')', 'aggregationOperator' )"><img src="../images/right_parent.png" alt="$i18n.getString( 'right_brackets' )"/></a>
-		<a href="javascript:insertText( 'expression', '*', 'aggregationOperator' )"><img src="../images/multiply.png" alt="$i18n.getString( 'multiply' )"/></a>
-		<a href="javascript:insertText( 'expression', '/', 'aggregationOperator' )"><img src="../images/divide.png" alt="$i18n.getString( 'divide' )"/></a>
-		<a href="javascript:insertText( 'expression', '+', 'aggregationOperator' )"><img src="../images/plus.png" alt="$i18n.getString( 'plus' )"/></a>
-		<a href="javascript:insertText( 'expression', '-', 'aggregationOperator' )"><img src="../images/minus.png" alt="$i18n.getString( 'minus' )"/></a>
+		<a href="javascript:insertText( 'expression', '(' )"><img src="../images/left_parent.png" alt="$i18n.getString( 'left_brackets' )"/></a>
+		<a href="javascript:insertText( 'expression', ')' )"><img src="../images/right_parent.png" alt="$i18n.getString( 'right_brackets' )"/></a>
+		<a href="javascript:insertText( 'expression', '*' )"><img src="../images/multiply.png" alt="$i18n.getString( 'multiply' )"/></a>
+		<a href="javascript:insertText( 'expression', '/' )"><img src="../images/divide.png" alt="$i18n.getString( 'divide' )"/></a>
+		<a href="javascript:insertText( 'expression', '+' )"><img src="../images/plus.png" alt="$i18n.getString( 'plus' )"/></a>
+		<a href="javascript:insertText( 'expression', '-' )"><img src="../images/minus.png" alt="$i18n.getString( 'minus' )"/></a>
+		<a href="javascript:insertText( 'expression', '[days]' )"><img src="../images/no_of_days.png" title="$i18n.getString( 'no_of_days' )"/></a>
 		</td>
 		<td></td>
 		<td valign="top">