=== 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-12-19 15:47:38 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElement.java 2014-12-22 21:47:45 +0000 @@ -361,6 +361,24 @@ } /** + * Indicates whether collecting data for future periods should be allowed for + * this data element. + * @return true if all the associated data sets allow future periods, false otherwise. + */ + public boolean isAllowFuturePeriods() + { + for ( DataSet dataSet : dataSets ) + { + if( dataSet != null && !dataSet.isAllowFuturePeriods() ) + { + return false; + } + } + + return true; + } + + /** * Returns the frequency order for the PeriodType of this DataElement. If no * PeriodType exists, 0 is returned. */ === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/Period.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/Period.java 2014-11-11 11:46:59 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/Period.java 2014-12-22 21:47:45 +0000 @@ -276,6 +276,15 @@ return true; } + /** + * Determines whether this is a future period in relation to the current time. + * @return true if this period ends in the future, false otherwise (the period has ended). + */ + public boolean isFuture() + { + return getEndDate().after( new Date() ); + } + // ------------------------------------------------------------------------- // hashCode, equals and toString // ------------------------------------------------------------------------- === 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-11-11 12:51:06 +0000 +++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/DataValueController.java 2014-12-22 21:47:45 +0000 @@ -33,6 +33,7 @@ import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo; import org.hisp.dhis.dataelement.DataElementCategoryService; import org.hisp.dhis.dataelement.DataElementService; +import org.hisp.dhis.dataset.DataSet; import org.hisp.dhis.dataset.DataSetService; import org.hisp.dhis.datavalue.DataValue; import org.hisp.dhis.datavalue.DataValueService; @@ -66,6 +67,10 @@ { public static final String RESOURCE_PATH = "/dataValues"; + // --------------------------------------------------------------------- + // Dependencies + // --------------------------------------------------------------------- + @Autowired private CurrentUserService currentUserService; @@ -87,6 +92,10 @@ @Autowired private InputUtils inputUtils; + // --------------------------------------------------------------------- + // POST + // --------------------------------------------------------------------- + @PreAuthorize( "hasRole('ALL') or hasRole('F_DATAVALUE_ADD')" ) @RequestMapping( method = RequestMethod.POST, produces = "text/plain" ) public void saveDataValue( @@ -177,6 +186,17 @@ } // --------------------------------------------------------------------- + // Future period constraint check + // --------------------------------------------------------------------- + + if ( period.isFuture() && !dataElement.isAllowFuturePeriods() ) + { + ContextUtils.conflictResponse( response, "Cannot save data value for future period. " + + "One or more data sets for data element " + de + " does not allow future periods." ); + return; + } + + // --------------------------------------------------------------------- // Locking validation // --------------------------------------------------------------------- @@ -240,6 +260,10 @@ } } + // --------------------------------------------------------------------- + // DELETE + // --------------------------------------------------------------------- + @PreAuthorize( "hasRole('ALL') or hasRole('F_DATAVALUE_DELETE')" ) @RequestMapping( method = RequestMethod.DELETE, produces = "text/plain" ) public void deleteDataValue( @@ -335,6 +359,10 @@ dataValueService.deleteDataValue( dataValue ); } + // --------------------------------------------------------------------- + // GET + // --------------------------------------------------------------------- + @RequestMapping( method = RequestMethod.GET ) public String getDataValue( @RequestParam String de,