=== 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-30 17:07:42 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElement.java 2015-08-30 18:24:11 +0000 @@ -338,6 +338,38 @@ Collections.sort( list, DataSetFrequencyComparator.INSTANCE ); return !list.isEmpty() ? list.get( 0 ) : null; } + + /** + * Returns the category combinations associated with the data sets of this + * data element. + */ + public Set getDataSetCategoryCombos() + { + Set categoryCombos = new HashSet<>(); + + for ( DataSet dataSet : dataSets ) + { + categoryCombos.add( dataSet.getCategoryCombo() ); + } + + return categoryCombos; + } + + /** + * Returns the category options combinations associated with the data sets of this + * data element. + */ + public Set getDataSetCategoryOptionCombos() + { + Set categoryOptionCombos = new HashSet<>(); + + for ( DataSet dataSet : dataSets ) + { + categoryOptionCombos.addAll( dataSet.getCategoryCombo().getOptionCombos() ); + } + + return categoryOptionCombos; + } /** * Returns the PeriodType of the DataElement, based on the PeriodType of the === 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-30 17:58:42 +0000 +++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/common/ImportOptions.java 2015-08-30 18:24:11 +0000 @@ -72,6 +72,8 @@ private Boolean strictCategoryOptionCombos; + private Boolean strictAttributeOptionCombos; + //-------------------------------------------------------------------------- // Constructors //-------------------------------------------------------------------------- @@ -106,6 +108,11 @@ return strictCategoryOptionCombos != null; } + public boolean hasStrictAttributeOptionCombos() + { + return strictAttributeOptionCombos != null; + } + //-------------------------------------------------------------------------- // Get methods //-------------------------------------------------------------------------- @@ -175,6 +182,11 @@ return strictCategoryOptionCombos; } + public Boolean getStrictAttributeOptionCombos() + { + return strictAttributeOptionCombos; + } + //-------------------------------------------------------------------------- // Set methods //-------------------------------------------------------------------------- @@ -251,6 +263,12 @@ return this; } + public ImportOptions setStrictAttributeOptionCombos( Boolean strictAttributeOptionCombos ) + { + this.strictAttributeOptionCombos = strictAttributeOptionCombos; + return this; + } + @Override public String toString() { @@ -265,6 +283,8 @@ add( "Skip existing check", skipExistingCheck ). add( "Sharing", sharing ). add( "Strict periods", strictPeriods ). - add( "Strict category option combos", strictCategoryOptionCombos ).toString(); + add( "Strict category option combos", strictCategoryOptionCombos ). + add( "Strict attr option combos", strictAttributeOptionCombos ). + 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-30 17:45:53 +0000 +++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/datavalueset/DefaultDataValueSetService.java 2015-08-30 18:24:11 +0000 @@ -580,6 +580,8 @@ (Boolean) systemSettingManager.getSystemSetting( KEY_DATA_IMPORT_STRICT_PERIODS, false ); boolean strictCategoryOptionCombos = importOptions.hasStrictCategoryOptionCombos() ? importOptions.getStrictCategoryOptionCombos() : (Boolean) systemSettingManager.getSystemSetting( KEY_DATA_IMPORT_STRICT_CATEGORY_OPTION_COMBOS, false ); + boolean strictAttrOptionCombos = importOptions.hasStrictAttributeOptionCombos() ? importOptions.getStrictAttributeOptionCombos() : + (Boolean) systemSettingManager.getSystemSetting( KEY_DATA_IMPORT_STRICT_ATTRIBUTE_OPTION_COMBOS, false ); //---------------------------------------------------------------------- // Create meta-data maps @@ -591,6 +593,7 @@ CachingMap periodMap = new CachingMap<>(); CachingMap> dataElementPeriodTypesMap = new CachingMap<>(); CachingMap> dataElementCategoryOptionComboMap = new CachingMap<>(); + CachingMap> dataElementAttrOptionComboMap = new CachingMap<>(); CachingMap orgUnitInHierarchyMap = new CachingMap<>(); //---------------------------------------------------------------------- @@ -711,6 +714,8 @@ // Validation // ----------------------------------------------------------------- + // TODO Use objects instead of data value references to handle outer objects + if ( dataElement == null ) { summary.getConflicts().add( new ImportConflict( dataValue.getDataElement(), "Data element not found or not acccessible" ) ); @@ -789,15 +794,23 @@ () -> dataElement.getPeriodTypes() ).contains( period.getPeriodType() ) ) { summary.getConflicts().add( new ImportConflict( dataValue.getPeriod(), - "Period type of period: " + dataValue.getPeriod() + " not valid for data element: " + dataValue.getDataElement() ) ); + "Period type of period: " + period.getIsoDate() + " not valid for data element: " + dataValue.getDataElement() ) ); continue; } if ( strictCategoryOptionCombos && !dataElementCategoryOptionComboMap.get( dataValue.getDataElement(), () -> dataElement.getCategoryCombo().getOptionCombos() ).contains( categoryOptionCombo ) ) { - summary.getConflicts().add( new ImportConflict( dataValue.getCategoryOptionCombo(), - "Category option combo: " + dataValue.getCategoryOptionCombo() + " must be part of category combo of data element: " + dataValue.getDataElement() ) ); + summary.getConflicts().add( new ImportConflict( categoryOptionCombo.getUid(), + "Category option combo: " + categoryOptionCombo.getUid() + " must be part of category combo of data element: " + dataElement.getUid() ) ); + continue; + } + + if ( strictAttrOptionCombos && !dataElementAttrOptionComboMap.get( dataValue.getDataElement(), + () -> dataElement.getDataSetCategoryOptionCombos() ).contains( attrOptionCombo ) ) + { + summary.getConflicts().add( new ImportConflict( attrOptionCombo.getUid(), + "Attribute option combo: " + attrOptionCombo.getUid() + " must be part of category combo of data sets of data element: " + dataElement.getUid() ) ); continue; } === 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-30 17:58:42 +0000 +++ dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/datavalueset/DataValueSetServiceTest.java 2015-08-30 18:24:11 +0000 @@ -148,6 +148,7 @@ deC = createDataElement( 'C', categoryComboDef ); deD = createDataElement( 'D', categoryComboDef ); dsA = createDataSet( 'A', new MonthlyPeriodType() ); + dsA.setCategoryCombo( categoryComboDef ); ouA = createOrganisationUnit( 'A' ); ouB = createOrganisationUnit( 'B' ); ouC = createOrganisationUnit( 'C' ); @@ -481,7 +482,7 @@ } @Test - public void testImportDataValuesWithNonStrictPeriods() + public void testImportDataValuesWithStrictPeriods() throws Exception { in = new ClassPathResource( "datavalueset/dataValueSetNonStrict.xml" ).getInputStream(); @@ -499,7 +500,7 @@ } @Test - public void testImportDataValuesWithNonStrictCategoryOptionCombos() + public void testImportDataValuesWithStrictCategoryOptionCombos() throws Exception { in = new ClassPathResource( "datavalueset/dataValueSetNonStrict.xml" ).getInputStream(); @@ -516,6 +517,24 @@ assertEquals( ImportStatus.SUCCESS, summary.getStatus() ); } + @Test + public void testImportDataValuesWithStrictAttributeOptionCombos() + throws Exception + { + in = new ClassPathResource( "datavalueset/dataValueSetNonStrict.xml" ).getInputStream(); + + ImportOptions options = new ImportOptions().setStrictAttributeOptionCombos( 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 17:45:53 +0000 +++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/datavalueset/dataValueSetNonStrict.xml 2015-08-30 18:24:11 +0000 @@ -1,5 +1,5 @@ - + \ No newline at end of file