Skip to content

Commit

Permalink
fix: No data returned for data element details/operands as filter [2.…
Browse files Browse the repository at this point in the history
…39-DHIS2-18182-backport] (#18795)

* fix: No data returned for data element details/operands as filter [2.42-DHIS2-18182]

* code cleaning

* code cleaning

* code cleaning

* post code review impl

* post code review impl

* java17 to java11
  • Loading branch information
d-bernat authored Oct 10, 2024
1 parent e9b1ede commit bf34635
Show file tree
Hide file tree
Showing 3 changed files with 243 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2135,6 +2135,12 @@ public List<DimensionalItemObject> getAllDataElements() {
return ImmutableList.copyOf(ListUtils.union(getDataElements(), getFilterDataElements()));
}

/** Returns all data element operands part of a dimension or filter. */
public List<DimensionalItemObject> getAllDataElementOperands() {
return ImmutableList.copyOf(
ListUtils.union(getDataElementOperands(), getFilterDataElementOperands()));
}

/** Returns all reporting rates part of a dimension or filter. */
public List<DimensionalItemObject> getAllReportingRates() {
return ImmutableList.copyOf(ListUtils.union(getReportingRates(), getFilterReportingRates()));
Expand Down Expand Up @@ -2361,6 +2367,13 @@ public List<DimensionalItemObject> getFilterDataElements() {
DataDimensionItemType.DATA_ELEMENT, getFilterOptions(DATA_X_DIM_ID)));
}

/** Returns all data element operands part of the data filter. */
public List<DimensionalItemObject> getFilterDataElementOperands() {
return ImmutableList.copyOf(
AnalyticsUtils.getByDataDimensionItemType(
DataDimensionItemType.DATA_ELEMENT_OPERAND, getFilterOptions(DATA_X_DIM_ID)));
}

/** Returns all reporting rates part of the data filter. */
public List<DimensionalItemObject> getFilterReportingRates() {
return ImmutableList.copyOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ public void addReportingRates(DataQueryParams params, Grid grid) {
*/
@Transactional(readOnly = true)
public void addDataElementOperandValues(DataQueryParams params, Grid grid) {
if (!params.getDataElementOperands().isEmpty() && !params.isSkipData()) {
if (!params.getAllDataElementOperands().isEmpty() && !params.isSkipData()) {
DataQueryParams dataSourceParams =
newBuilder(params).retainDataDimension(DATA_ELEMENT_OPERAND).build();

Expand Down Expand Up @@ -729,7 +729,7 @@ private Map<String, Double> getAggregatedCompletenessTargetMap(DataQueryParams p
* @param totalType the operand {@link TotalType}.
*/
private void addDataElementOperandValues(DataQueryParams params, Grid grid, TotalType totalType) {
List<DataElementOperand> operands = asTypedList(params.getDataElementOperands());
List<DataElementOperand> operands = asTypedList(params.getAllDataElementOperands());
operands =
operands.stream()
.filter(o -> totalType.equals(o.getTotalType()))
Expand All @@ -739,45 +739,242 @@ private void addDataElementOperandValues(DataQueryParams params, Grid grid, Tota
return;
}

DataQueryParams operandParams = getOperandDataQueryParams(params, operands, totalType);

Map<String, Object> aggregatedDataMap = getAggregatedDataValueMapObjectTyped(operandParams);

aggregatedDataMap = convertDxToOperand(aggregatedDataMap, totalType);

for (Map.Entry<String, Object> entry : aggregatedDataMap.entrySet()) {
Object value = getRoundedValueObject(operandParams, entry.getValue());

grid.addRow().addValues(entry.getKey().split(DIMENSION_SEP)).addValue(value);

if (params.isIncludeNumDen()) {
grid.addNullValues(NUMERATOR_DENOMINATOR_PROPERTIES_COUNT);
}
}
}

/**
* Delivers a DataQueryParams instance for DataElementOperands. The dimension and filter operands
* are added to the query parameters.
*
* @param params the {@link DataQueryParams}.
* @param operands the collection of {@link DataElementOperand}.
* @param totalType the {@link TotalType}.
* @return mapped DataQueryParams
*/
private DataQueryParams getOperandDataQueryParams(
DataQueryParams params, List<DataElementOperand> operands, TotalType totalType) {

List<DimensionalItemObject> dataElements = newArrayList(getDataElements(operands));
List<DimensionalItemObject> categoryOptionCombos =
newArrayList(getCategoryOptionCombos(operands));
List<DimensionalItemObject> attributeOptionCombos =
newArrayList(getAttributeOptionCombos(operands));

// TODO Check if data was dim or filter
DataQueryParams.Builder builder = newBuilder(params).removeDimension(DATA_X_DIM_ID);

DataQueryParams.Builder builder =
newBuilder(params)
.removeDimension(DATA_X_DIM_ID)
.addDimension(new BaseDimensionalObject(DATA_X_DIM_ID, DATA_X, dataElements));
addDataElementDimensionToDataQueryParamBuilder(builder, params, dataElements);
addDataElementFilterToDataQueryParamBuilder(builder, params, dataElements);

if (totalType.isCategoryOptionCombo()) {
builder.addDimension(
new BaseDimensionalObject(
CATEGORYOPTIONCOMBO_DIM_ID, CATEGORY_OPTION_COMBO, categoryOptionCombos));
addCategoryOptionComboDimensionToDataQueryParamBuilder(builder, params, categoryOptionCombos);
addCategoryOptionComboFilterToDataQueryParamBuilder(builder, params, categoryOptionCombos);
}

if (totalType.isAttributeOptionCombo()) {
addAttributeOptionComboDimensionToDataQueryParamBuilder(
builder, params, attributeOptionCombos);
addAttributeOptionComboFilterToDataQueryParamBuilder(builder, params, attributeOptionCombos);
}

return builder.build();
}

/**
* Add CategoryOptionCombo dimension to DataQueryParam builder.
*
* @param builder the {@link DataQueryParams.Builder}.
* @param params the {@link DataQueryParams}.
* @param categoryOptionCombos the collection of the {@link DimensionalItemObject}.
*/
private void addCategoryOptionComboDimensionToDataQueryParamBuilder(
DataQueryParams.Builder builder,
DataQueryParams params,
List<DimensionalItemObject> categoryOptionCombos) {
List<DimensionalItemObject> dimensionCategoryOptionCombos =
categoryOptionCombos.stream()
.filter(
coc ->
params.getDataElementOperands().stream()
.filter(deo -> ((DataElementOperand) deo).getCategoryOptionCombo() != null)
.anyMatch(
deo ->
((DataElementOperand) deo)
.getCategoryOptionCombo()
.getUid()
.equals(coc.getUid())))
.collect(toList());

if (!dimensionCategoryOptionCombos.isEmpty()) {
builder.addDimension(
new BaseDimensionalObject(
ATTRIBUTEOPTIONCOMBO_DIM_ID, ATTRIBUTE_OPTION_COMBO, attributeOptionCombos));
CATEGORYOPTIONCOMBO_DIM_ID, CATEGORY_OPTION_COMBO, dimensionCategoryOptionCombos));
}
}

DataQueryParams operandParams = builder.build();

Map<String, Object> aggregatedDataMap = getAggregatedDataValueMapObjectTyped(operandParams);
/**
* Add CategoryOptionCombo filter to DataQueryParam builder.
*
* @param builder the {@link DataQueryParams.Builder}.
* @param params the {@link DataQueryParams}.
* @param categoryOptionCombos the collection of the {@link DimensionalItemObject}.
*/
private void addCategoryOptionComboFilterToDataQueryParamBuilder(
DataQueryParams.Builder builder,
DataQueryParams params,
List<DimensionalItemObject> categoryOptionCombos) {
List<DimensionalItemObject> filterCategoryOptionCombos =
categoryOptionCombos.stream()
.filter(
coc ->
params.getFilterDataElementOperands().stream()
.filter(deo -> ((DataElementOperand) deo).getCategoryOptionCombo() != null)
.anyMatch(
deo ->
((DataElementOperand) deo)
.getCategoryOptionCombo()
.getUid()
.equals(coc.getUid())))
.collect(toList());

if (!filterCategoryOptionCombos.isEmpty()) {
builder.addFilter(
new BaseDimensionalObject(
CATEGORYOPTIONCOMBO_DIM_ID, CATEGORY_OPTION_COMBO, filterCategoryOptionCombos));
}
}

aggregatedDataMap = convertDxToOperand(aggregatedDataMap, totalType);
/**
* Add AttributeOptionCombo dimension to DataQueryParam builder.
*
* @param builder the {@link DataQueryParams.Builder}.
* @param params the {@link DataQueryParams}.
* @param attributeOptionCombos the collection of the {@link DimensionalItemObject}.
*/
private void addAttributeOptionComboDimensionToDataQueryParamBuilder(
DataQueryParams.Builder builder,
DataQueryParams params,
List<DimensionalItemObject> attributeOptionCombos) {
List<DimensionalItemObject> dimensionAttributeOptionCombos =
attributeOptionCombos.stream()
.filter(
aoc ->
params.getDataElementOperands().stream()
.filter(deo -> ((DataElementOperand) deo).getAttributeOptionCombo() != null)
.anyMatch(
deo ->
((DataElementOperand) deo)
.getAttributeOptionCombo()
.getUid()
.equals(aoc.getUid())))
.collect(toList());

if (!dimensionAttributeOptionCombos.isEmpty()) {
builder.addDimension(
new BaseDimensionalObject(
ATTRIBUTEOPTIONCOMBO_DIM_ID, ATTRIBUTE_OPTION_COMBO, dimensionAttributeOptionCombos));
}
}

for (Map.Entry<String, Object> entry : aggregatedDataMap.entrySet()) {
Object value = getRoundedValueObject(operandParams, entry.getValue());
/**
* Add AttributeOptionCombo filter to DataQueryParam builder.
*
* @param builder the {@link DataQueryParams.Builder}.
* @param params the {@link DataQueryParams}.
* @param attributeOptionCombos the collection of the {@link DimensionalItemObject}.
*/
private void addAttributeOptionComboFilterToDataQueryParamBuilder(
DataQueryParams.Builder builder,
DataQueryParams params,
List<DimensionalItemObject> attributeOptionCombos) {
List<DimensionalItemObject> filterAttributeOptionCombos =
attributeOptionCombos.stream()
.filter(
aoc ->
params.getFilterDataElementOperands().stream()
.filter(deo -> ((DataElementOperand) deo).getAttributeOptionCombo() != null)
.anyMatch(
deo ->
((DataElementOperand) deo)
.getAttributeOptionCombo()
.getUid()
.equals(aoc.getUid())))
.collect(toList());

if (!filterAttributeOptionCombos.isEmpty()) {
builder.addFilter(
new BaseDimensionalObject(
ATTRIBUTEOPTIONCOMBO_DIM_ID, ATTRIBUTE_OPTION_COMBO, filterAttributeOptionCombos));
}
}

grid.addRow().addValues(entry.getKey().split(DIMENSION_SEP)).addValue(value);
/**
* Add DataElement dimension to DataQueryParam builder.
*
* @param builder the {@link DataQueryParams.Builder}.
* @param params the {@link DataQueryParams}.
* @param dataElements the collection of the {@link DimensionalItemObject}.
*/
private void addDataElementDimensionToDataQueryParamBuilder(
DataQueryParams.Builder builder,
DataQueryParams params,
List<DimensionalItemObject> dataElements) {

List<DimensionalItemObject> dimensionDataElements =
dataElements.stream()
.filter(
de ->
params.getDataElementOperands().stream()
.anyMatch(
deo ->
((DataElementOperand) deo)
.getDataElement()
.getUid()
.equals(de.getUid())))
.collect(toList());
if (!dimensionDataElements.isEmpty()) {
builder.addDimension(new BaseDimensionalObject(DATA_X_DIM_ID, DATA_X, dimensionDataElements));
}
}

if (params.isIncludeNumDen()) {
grid.addNullValues(NUMERATOR_DENOMINATOR_PROPERTIES_COUNT);
}
/**
* Add DataElement filter to DataQueryParam builder.
*
* @param builder the {@link DataQueryParams.Builder}.
* @param params the {@link DataQueryParams}.
* @param dataElements the collection of the {@link DimensionalItemObject}.
*/
private void addDataElementFilterToDataQueryParamBuilder(
DataQueryParams.Builder builder,
DataQueryParams params,
List<DimensionalItemObject> dataElements) {
List<DimensionalItemObject> filterDataElements =
dataElements.stream()
.filter(
de ->
params.getFilterDataElementOperands().stream()
.anyMatch(
deo ->
((DataElementOperand) deo)
.getDataElement()
.getUid()
.equals(de.getUid())))
.collect(toList());
if (!filterDataElements.isEmpty()) {
builder.addFilter(new BaseDimensionalObject(DATA_X_DIM_ID, DATA_X, filterDataElements));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,13 +338,23 @@ public static <T> Map<String, T> convertDxToOperand(
Map<String, T> valueMap, TotalType totalType) {
Map<String, T> map = Maps.newHashMap();

final int upperBoundaryMarginOfDimensionalObjectItems = 1;
final int upperBoundaryOfDimensionalObjectItems =
totalType.getPropertyCount() + upperBoundaryMarginOfDimensionalObjectItems;

for (Entry<String, T> entry : valueMap.entrySet()) {
List<String> items =
Lists.newArrayList(entry.getKey().split(DimensionalObject.DIMENSION_SEP));

if (items.size() < upperBoundaryOfDimensionalObjectItems) {
map.put(entry.getKey(), entry.getValue());
continue;
}

List<String> operands =
Lists.newArrayList(items.subList(0, totalType.getPropertyCount() + 1));
Lists.newArrayList(items.subList(0, upperBoundaryOfDimensionalObjectItems));
List<String> dimensions =
Lists.newArrayList(items.subList(totalType.getPropertyCount() + 1, items.size()));
Lists.newArrayList(items.subList(upperBoundaryOfDimensionalObjectItems, items.size()));

// Add wild card in place of category option combination

Expand Down

0 comments on commit bf34635

Please sign in to comment.