=== 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 2015-08-31 04:36:39 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElement.java 2015-08-31 08:31:30 +0000 @@ -28,13 +28,15 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; -import com.google.common.collect.Sets; +import static org.hisp.dhis.dataset.DataSet.NO_EXPIRY; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + import org.hisp.dhis.analytics.AggregationType; import org.hisp.dhis.attribute.AttributeValue; import org.hisp.dhis.common.BaseDimensionalObject; @@ -49,6 +51,7 @@ import org.hisp.dhis.dataset.DataSet; import org.hisp.dhis.dataset.comparator.DataSetFrequencyComparator; import org.hisp.dhis.option.OptionSet; +import org.hisp.dhis.organisationunit.OrganisationUnit; import org.hisp.dhis.period.PeriodType; import org.hisp.dhis.period.YearlyPeriodType; import org.hisp.dhis.schema.PropertyType; @@ -56,14 +59,13 @@ import org.hisp.dhis.schema.annotation.PropertyRange; import org.hisp.dhis.util.ObjectUtils; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import static org.hisp.dhis.dataset.DataSet.NO_EXPIRY; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonView; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import com.google.common.collect.Sets; /** * A DataElement is a definition (meta-information about) of the entities that @@ -377,6 +379,23 @@ } /** + * Indicates whether the data sets of this data element is associated with + * the given organisation unit. + */ + public boolean hasDataSetOrganisationUnit( OrganisationUnit unit ) + { + for ( DataSet dataSet : dataSets ) + { + if ( dataSet.getSources().contains( unit ) ) + { + return true; + } + } + + return false; + } + + /** * Returns the PeriodType of the DataElement, based on the PeriodType of the * DataSet which the DataElement is associated with. If this data element has * multiple data sets, the data set with the highest collection frequency is === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/setting/SystemSettingManager.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/setting/SystemSettingManager.java 2015-08-30 17:07:42 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/setting/SystemSettingManager.java 2015-08-31 08:31:30 +0000 @@ -110,6 +110,7 @@ final String KEY_DATA_IMPORT_STRICT_PERIODS = "keyDataImportStrictPeriods"; final String KEY_DATA_IMPORT_STRICT_CATEGORY_OPTION_COMBOS = "keyDataImportStrictCategoryOptionCombos"; + final String KEY_DATA_IMPORT_STRICT_ORGANISATION_UNITS = "keyDataImportStrictOrganisationUnits"; final String KEY_DATA_IMPORT_STRICT_ATTRIBUTE_OPTION_COMBOS = "keyDataImportStrictAttributeOptionCombos"; final String KEY_DATA_IMPORT_REQUIRE_CATEGORY_OPTION_COMBO = "keyDataImportRequireCategoryOptionCombo"; final String KEY_DATA_IMPORT_REQUIRE_ATTRIBUTE_OPTION_COMBO = "keyDataImportRequireAttributeOptionCombo"; === modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/common/ImportOptions.java' --- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/common/ImportOptions.java 2015-08-31 07:39:12 +0000 +++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/common/ImportOptions.java 2015-08-31 08:31:30 +0000 @@ -74,6 +74,8 @@ private boolean strictAttributeOptionCombos; + private boolean strictOrganisationUnits; + private boolean requireCategoryOptionCombo; private boolean requireAttributeOptionCombo; @@ -176,6 +178,11 @@ return strictAttributeOptionCombos; } + public boolean isStrictOrganisationUnits() + { + return strictOrganisationUnits; + } + public boolean isRequireCategoryOptionCombo() { return requireCategoryOptionCombo; @@ -268,6 +275,12 @@ return this; } + public ImportOptions setStrictOrganisationUnits( boolean strictOrganisationUnits ) + { + this.strictOrganisationUnits = strictOrganisationUnits; + return this; + } + public ImportOptions setRequireCategoryOptionCombo( boolean requireCategoryOptionCombo ) { this.requireCategoryOptionCombo = requireCategoryOptionCombo; @@ -296,6 +309,7 @@ add( "Strict periods", strictPeriods ). add( "Strict category option combos", strictCategoryOptionCombos ). add( "Strict attr option combos", strictAttributeOptionCombos ). + add( "Strict org units", strictCategoryOptionCombos ). add( "Require category option combo", requireCategoryOptionCombo ). add( "Require attribute option combo", requireAttributeOptionCombo ). toString(); === modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/datavalueset/DefaultDataValueSetService.java' --- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/datavalueset/DefaultDataValueSetService.java 2015-08-31 07:39:12 +0000 +++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/datavalueset/DefaultDataValueSetService.java 2015-08-31 08:31:30 +0000 @@ -51,6 +51,7 @@ import org.amplecode.quick.BatchHandler; import org.amplecode.quick.BatchHandlerFactory; import org.amplecode.staxwax.factory.XMLFactory; +import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hisp.dhis.common.DxfNamespaces; @@ -569,16 +570,15 @@ log.info( "Scheme: " + idScheme + ", data element scheme: " + dataElementIdScheme + ", org unit scheme: " + orgUnitIdScheme ); - boolean dryRun = dataValueSet.getDryRun() != null ? dataValueSet.getDryRun() : importOptions.isDryRun(); - ImportStrategy strategy = dataValueSet.getStrategy() != null ? ImportStrategy.valueOf( dataValueSet.getStrategy() ) : importOptions.getImportStrategy(); - boolean skipExistingCheck = importOptions.isSkipExistingCheck(); - + boolean dryRun = dataValueSet.getDryRun() != null ? dataValueSet.getDryRun() : importOptions.isDryRun(); + boolean skipExistingCheck = importOptions.isSkipExistingCheck(); boolean strictPeriods = importOptions.isStrictPeriods() || (Boolean) systemSettingManager.getSystemSetting( KEY_DATA_IMPORT_STRICT_PERIODS, false ); boolean strictCategoryOptionCombos = importOptions.isStrictCategoryOptionCombos() || (Boolean) systemSettingManager.getSystemSetting( KEY_DATA_IMPORT_STRICT_CATEGORY_OPTION_COMBOS, false ); boolean strictAttrOptionCombos = importOptions.isStrictAttributeOptionCombos() || (Boolean) systemSettingManager.getSystemSetting( KEY_DATA_IMPORT_STRICT_ATTRIBUTE_OPTION_COMBOS, false ); + boolean strictOrgUnits = importOptions.isStrictOrganisationUnits() || (Boolean) systemSettingManager.getSystemSetting( KEY_DATA_IMPORT_STRICT_ORGANISATION_UNITS, false ); boolean requireCategoryOptionCombo = importOptions.isRequireCategoryOptionCombo() || (Boolean) systemSettingManager.getSystemSetting( KEY_DATA_IMPORT_REQUIRE_CATEGORY_OPTION_COMBO, false ); boolean requireAttrOptionCombo = importOptions.isRequireAttributeOptionCombo() || (Boolean) systemSettingManager.getSystemSetting( KEY_DATA_IMPORT_REQUIRE_ATTRIBUTE_OPTION_COMBO, false ); @@ -593,6 +593,7 @@ CachingMap> dataElementPeriodTypesMap = new CachingMap<>(); CachingMap> dataElementCategoryOptionComboMap = new CachingMap<>(); CachingMap> dataElementAttrOptionComboMap = new CachingMap<>(); + CachingMap dataElementOrgUnitMap = new CachingMap<>(); CachingMap orgUnitInHierarchyMap = new CachingMap<>(); //---------------------------------------------------------------------- @@ -805,7 +806,7 @@ } } - if ( strictPeriods && !dataElementPeriodTypesMap.get( dataValue.getDataElement(), + if ( strictPeriods && !dataElementPeriodTypesMap.get( dataElement.getUid(), () -> dataElement.getPeriodTypes() ).contains( period.getPeriodType() ) ) { summary.getConflicts().add( new ImportConflict( dataValue.getPeriod(), @@ -813,7 +814,7 @@ continue; } - if ( strictCategoryOptionCombos && !dataElementCategoryOptionComboMap.get( dataValue.getDataElement(), + if ( strictCategoryOptionCombos && !dataElementCategoryOptionComboMap.get( dataElement.getUid(), () -> dataElement.getCategoryCombo().getOptionCombos() ).contains( categoryOptionCombo ) ) { summary.getConflicts().add( new ImportConflict( categoryOptionCombo.getUid(), @@ -821,7 +822,7 @@ continue; } - if ( strictAttrOptionCombos && !dataElementAttrOptionComboMap.get( dataValue.getDataElement(), + if ( strictAttrOptionCombos && !dataElementAttrOptionComboMap.get( dataElement.getUid(), () -> dataElement.getDataSetCategoryOptionCombos() ).contains( attrOptionCombo ) ) { summary.getConflicts().add( new ImportConflict( attrOptionCombo.getUid(), @@ -829,6 +830,14 @@ continue; } + if ( strictOrgUnits && BooleanUtils.isFalse( dataElementOrgUnitMap.get( dataElement.getUid() + orgUnit.getUid(), + () -> dataElement.hasDataSetOrganisationUnit( orgUnit ) ) ) ) + { + summary.getConflicts().add( new ImportConflict( orgUnit.getUid(), + "Data element: " + dataElement.getUid() + " must be assigned through data sets to organisation unit: " + orgUnit.getUid() ) ); + continue; + } + internalValue.setDataElement( dataElement ); internalValue.setPeriod( period ); internalValue.setSource( orgUnit ); === modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/datavalueset/DataValueSetServiceTest.java' --- dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/datavalueset/DataValueSetServiceTest.java 2015-08-31 07:39:12 +0000 +++ dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/datavalueset/DataValueSetServiceTest.java 2015-08-31 08:31:30 +0000 @@ -193,10 +193,14 @@ dsA.addDataElement( deC ); dsA.addDataElement( deD ); - dataSetService.addDataSet( dsA ); organisationUnitService.addOrganisationUnit( ouA ); organisationUnitService.addOrganisationUnit( ouB ); organisationUnitService.addOrganisationUnit( ouC ); + + dsA.addOrganisationUnit( ouA ); + dsA.addOrganisationUnit( ouC ); + + dataSetService.addDataSet( dsA ); periodService.addPeriod( peA ); periodService.addPeriod( peB ); @@ -571,6 +575,24 @@ assertEquals( ImportStatus.SUCCESS, summary.getStatus() ); } + @Test + public void testImportDataValuesWithStrictOrganisationUnits() + throws Exception + { + in = new ClassPathResource( "datavalueset/dataValueSetNonStrict.xml" ).getInputStream(); + + ImportOptions options = new ImportOptions().setStrictOrganisationUnits( true ); + + ImportSummary summary = dataValueSetService.saveDataValueSet( in, options ); + + assertEquals( summary.getConflicts().toString(), 1, summary.getConflicts().size() ); + assertEquals( 2, summary.getImportCount().getImported() ); + assertEquals( 0, summary.getImportCount().getUpdated() ); + assertEquals( 0, summary.getImportCount().getDeleted() ); + assertEquals( 1, summary.getImportCount().getIgnored() ); + assertEquals( ImportStatus.SUCCESS, summary.getStatus() ); + } + // ------------------------------------------------------------------------- // Supportive methods // ------------------------------------------------------------------------- === modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/datavalueset/dataValueSetNonStrict.xml' --- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/datavalueset/dataValueSetNonStrict.xml 2015-08-30 18:24:11 +0000 +++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/datavalueset/dataValueSetNonStrict.xml 2015-08-31 08:31:30 +0000 @@ -1,5 +1,5 @@ - - - - + + + + \ No newline at end of file