=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElement.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElement.java 2014-07-15 18:31:16 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElement.java 2014-07-21 09:45:25 +0000 @@ -89,6 +89,7 @@ public static final String VALUE_TYPE_TRUE_ONLY = "trueOnly"; public static final String VALUE_TYPE_DATE = "date"; public static final String VALUE_TYPE_UNIT_INTERVAL = "unitInterval"; + public static final String VALUE_TYPE_PERCENTAGE = "percentage"; public static final String VALUE_TYPE_NUMBER = "number"; public static final String VALUE_TYPE_POSITIVE_INT = "posInt"; @@ -286,6 +287,27 @@ } /** + * Returns the detailed data element type. If value type is int, the number + * type is returned. If value type is string, the text type is returned. + * Otherwise the type is returned. + */ + public String getDetailedType() + { + if ( VALUE_TYPE_INT.equals( type ) ) + { + return numberType; + } + else if ( VALUE_TYPE_STRING.equals( type ) ) + { + return textType; + } + else + { + return type; + } + } + + /** * Returns whether aggregation should be skipped for this data element, based * on the setting of the data set which this data element is a members of, * if any. === 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 2014-07-06 17:12:17 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/resources/i18n_global.properties 2014-07-21 09:45:25 +0000 @@ -840,6 +840,7 @@ value_length_greater_than_max_length=Data value is greater than max length value_not_numeric=Data value is not numeric value_not_unit_interval=Data value is not a unit interval +value_not_percentage=Data value is not a percentage value_not_integer=Data value is not an integer value_not_positive_integer=Data value is not a positive integer value_not_negative_integer=Data value is not a negative integer === modified file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/MathUtils.java' --- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/MathUtils.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/MathUtils.java 2014-07-21 09:45:25 +0000 @@ -326,6 +326,25 @@ return dbl >= 0d && dbl <= 1d; } + + /** + * Returns true if the provided string argument is an integer in the inclusive + * range of 0 to 100. + * + * @param value the value. + * @return true if the provided string argument is a percentage. + */ + public static boolean isPercentage( String value ) + { + if ( !isInteger( value ) ) + { + return false; + } + + Integer integer = Integer.valueOf( value ); + + return integer >= 0 && integer <= 100; + } /** * Returns true if the provided string argument is to be considered an integer. === modified file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/ValidationUtils.java' --- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/ValidationUtils.java 2014-06-23 08:05:34 +0000 +++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/ValidationUtils.java 2014-07-21 09:45:25 +0000 @@ -247,6 +247,7 @@ *
  • value_length_greater_than_max_length
  • *
  • value_not_numeric
  • *
  • value_not_unit_interval
  • + *
  • value_not_percentage
  • *
  • value_not_integer
  • *
  • value_not_positive_integer
  • *
  • value_not_negative_integer
  • @@ -290,6 +291,11 @@ { return "value_not_unit_interval"; } + + if ( VALUE_TYPE_PERCENTAGE.equals( type ) && !MathUtils.isPercentage( value ) ) + { + return "value_not_percentage"; + } if ( VALUE_TYPE_INT.equals( type ) && !MathUtils.isInteger( value ) ) { === modified file 'dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/util/MathUtilsTest.java' --- dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/util/MathUtilsTest.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/util/MathUtilsTest.java 2014-07-21 09:45:25 +0000 @@ -187,6 +187,20 @@ } @Test + public void testIsPercentage() + { + assertTrue( MathUtils.isPercentage( "0" ) ); + assertTrue( MathUtils.isPercentage( "15" ) ); + assertTrue( MathUtils.isPercentage( "100" ) ); + + assertFalse( MathUtils.isPercentage( "abc" ) ); + assertFalse( MathUtils.isPercentage( "-1" ) ); + assertFalse( MathUtils.isPercentage( "12.5" ) ); + assertFalse( MathUtils.isPercentage( "17,8" ) ); + assertFalse( MathUtils.isPercentage( "101" ) ); + } + + @Test public void testIsInteger() { assertTrue( MathUtils.isInteger( "1" ) ); === modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/AccountController.java' --- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/AccountController.java 2014-07-18 14:41:57 +0000 +++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/AccountController.java 2014-07-21 09:45:25 +0000 @@ -28,11 +28,21 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.hisp.dhis.webapi.utils.ContextUtils; import org.hisp.dhis.configuration.ConfigurationService; import org.hisp.dhis.organisationunit.OrganisationUnit; import org.hisp.dhis.security.PasswordManager; @@ -45,6 +55,7 @@ import org.hisp.dhis.user.UserAuthorityGroup; import org.hisp.dhis.user.UserCredentials; import org.hisp.dhis.user.UserService; +import org.hisp.dhis.webapi.utils.ContextUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -58,19 +69,9 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.client.RestTemplate; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import java.io.IOException; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import com.fasterxml.jackson.databind.ObjectMapper; /** * @author Lars Helge Overland === modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/DataValueController.java' --- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/DataValueController.java 2014-07-10 15:06:47 +0000 +++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/DataValueController.java 2014-07-21 09:45:25 +0000 @@ -164,7 +164,7 @@ if ( valid != null ) { - ContextUtils.conflictResponse( response, "Invalid value: " + value + ", must match data element type: " + dataElement.getType() ); + ContextUtils.conflictResponse( response, "Invalid value: " + value + ", must match data element type: " + dataElement.getDetailedType() ); return; } === modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.validation.js' --- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.validation.js 2014-05-06 03:55:23 +0000 +++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.validation.js 2014-07-21 09:45:25 +0000 @@ -33,7 +33,7 @@ /** * Checks if the given value is valid zero. */ -dhis2.validation.isValidZeroNumber = function( value ) { +dhis2.validation.isValidZeroNumber = function(value) { var regex = /^0(\.0*)?$/; return regex.test(value); }; @@ -41,15 +41,22 @@ /** * Allow only integers or a single zero and no thousands separators. */ -dhis2.validation.isInt = function( value ) { +dhis2.validation.isInt = function(value) { var regex = /^(0|-?[1-9]\d*)$/; return regex.test(value); }; /** + * Allow only integers inclusive between 0 and 100. + */ +dhis2.validation.isPercentage = function(value) { + return dhis2.validation.isInt(value) && parseInt(value) >= 0 && parseInt(value) <= 100; +} + +/** * Allow only positive integers, not zero, no thousands separators. */ -dhis2.validation.isPositiveInt = function( value ) { +dhis2.validation.isPositiveInt = function(value) { var regex = /^[1-9]\d*$/; return regex.test(value); }; @@ -57,7 +64,7 @@ /** * Allow only zero or positive integers, no thousands separators. */ -dhis2.validation.isZeroOrPositiveInt = function( value ) { +dhis2.validation.isZeroOrPositiveInt = function(value) { var regex = /(^0$)|(^[1-9]\d*$)/; return regex.test(value); }; @@ -65,7 +72,7 @@ /** * Allow only negative integers, not zero and no thousands separators. */ -dhis2.validation.isNegativeInt = function( value ) { +dhis2.validation.isNegativeInt = function(value) { var regex = /^-[1-9]\d*$/; return regex.test(value); }; @@ -74,7 +81,7 @@ * Allow any real number,optionally with a sign, no thousands separators and a * single decimal point. */ -dhis2.validation.isNumber = function( value ) { +dhis2.validation.isNumber = function(value) { var regex = /^(-?0|-?[1-9]\d*)(\.\d+)?(E\d+)?$/; return regex.test(value); }; @@ -82,14 +89,14 @@ /** * Checks if the given value is a valid positive number. */ -dhis2.validation.isPositiveNumber = function( value ) { +dhis2.validation.isPositiveNumber = function(value) { return dhis2.validation.isNumber(value) && parseFloat(value) > 0; }; /** * Checks if the given value is a valid negative number. */ -dhis2.validation.isNegativeNumber = function( value ) { +dhis2.validation.isNegativeNumber = function(value) { return dhis2.validation.isNumber(value) && parseFloat(value) < 0; }; @@ -98,7 +105,7 @@ * interval, which implies that the value is numeric and inclusive between 0 * and 1. */ -dhis2.validation.isUnitInterval = function( value ) { +dhis2.validation.isUnitInterval = function(value) { if( !dhis2.validation.isNumber(value) ) { return false; } === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/org/hisp/dhis/de/i18n_module.properties' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/org/hisp/dhis/de/i18n_module.properties 2014-07-10 15:06:47 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/org/hisp/dhis/de/i18n_module.properties 2014-07-21 09:45:25 +0000 @@ -70,6 +70,7 @@ value_must_negative_integer=Value must be a negative integer value_must_zero_or_positive_integer=Value must be zero or a positive integer value_must_unit_interval=Value must be a unit interval (between 0 and 1) +value_must_percentage=Value must be a percentage (between 0 and 100) value_is_too_long=Value is too long field_unallowed_save_zero=This element does not permit 0 values. The original value will not be affected. datavalue_history=Data value history === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/entry.js' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/entry.js 2014-07-09 13:13:12 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/entry.js 2014-07-21 09:45:25 +0000 @@ -174,7 +174,7 @@ if ( value != '' ) { - if ( type == 'string' || type == 'int' || type == 'number' || type == 'unitInterval' || type == 'posInt' || type == 'negInt' || type == 'zeroPositiveInt' ) + if ( type == 'string' || type == 'int' || type == 'number' || type == 'posInt' || type == 'negInt' || type == 'zeroPositiveInt' || type == 'unitInterval' || type == 'percentage' ) { if ( value.length > 255 ) { @@ -188,10 +188,6 @@ { return alertField( fieldId, i18n_value_must_number + '\n\n' + dataElementName ); } - if ( type == 'unitInterval' && !dhis2.validation.isUnitInterval( value ) ) - { - return alertField( fieldId, i18n_value_must_unit_interval + '\n\n' + dataElementName ); - } if ( type == 'posInt' && !dhis2.validation.isPositiveInt( value ) ) { return alertField( fieldId, i18n_value_must_positive_integer + '\n\n' + dataElementName ); @@ -204,6 +200,14 @@ { return alertField( fieldId, i18n_value_must_zero_or_positive_integer + '\n\n' + dataElementName ); } + if ( type == 'unitInterval' && !dhis2.validation.isUnitInterval( value ) ) + { + return alertField( fieldId, i18n_value_must_unit_interval + '\n\n' + dataElementName ); + } + if ( type == 'percentage' && !dhis2.validation.isPercentage( value ) ) + { + return alertField( fieldId, i18n_value_must_percentage + '\n\n' + dataElementName ); + } if ( !existing && dhis2.validation.isValidZeroNumber( value ) ) { // If value = 0 and zero not significant for data element, skip === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/select.vm' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/select.vm 2014-06-02 15:29:13 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/select.vm 2014-07-21 09:45:25 +0000 @@ -14,6 +14,7 @@ var i18n_value_must_zero_or_positive_integer = '$encoder.jsEscape( $i18n.getString( "value_must_zero_or_positive_integer" ) , "'")'; var i18n_value_must_negative_integer = '$encoder.jsEscape( $i18n.getString( "value_must_negative_integer" ) , "'")'; var i18n_value_must_unit_interval = '$encoder.jsEscape( $i18n.getString( "value_must_unit_interval" ) , "'")'; +var i18n_value_must_percentage = '$encoder.jsEscape( $i18n.getString( "value_must_percentage" ) , "'")'; var i18n_field_unallowed_save_zero = '$encoder.jsEscape( $i18n.getString( "field_unallowed_save_zero" ) , "'")'; var i18n_saving_value_failed_status_code = '$encoder.jsEscape( $i18n.getString( "saving_value_failed_status_code" ) , "'")'; var i18n_saving_value_failed_dataset_is_locked = '$encoder.jsEscape( $i18n.getString( "saving_value_failed_dataset_is_locked" ) , "'")'; === 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 2014-07-15 18:31:16 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/resources/org/hisp/dhis/dd/i18n_module.properties 2014-07-21 09:45:25 +0000 @@ -24,6 +24,7 @@ data_element_category_combo=Data Element Category Combination select=Select unit_interval=Unit interval +percentage=Percentage data_element=Data Element data_element_group=Data Element Group data_element_groups=Data Element Groups === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/dataElementForm.vm' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/dataElementForm.vm 2014-07-15 18:31:16 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/webapp/dhis-web-maintenance-datadictionary/dataElementForm.vm 2014-07-21 09:45:25 +0000 @@ -102,11 +102,12 @@