diff --git a/core/src/main/java/org/hisp/dhis/android/core/fileresource/internal/FileResourceDownloadCall.kt b/core/src/main/java/org/hisp/dhis/android/core/fileresource/internal/FileResourceDownloadCall.kt index 1b723a7ef4..911b9bbde5 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/fileresource/internal/FileResourceDownloadCall.kt +++ b/core/src/main/java/org/hisp/dhis/android/core/fileresource/internal/FileResourceDownloadCall.kt @@ -126,7 +126,7 @@ internal class FileResourceDownloadCall( values = dataValues, maxContentLength = params.maxContentLength, download = fileResourceNetworkHandlder::getFileFromDataValue, - getUid = { v -> v.value() }, + getUid = { v -> v.value.value() }, ) } } diff --git a/core/src/main/java/org/hisp/dhis/android/core/fileresource/internal/FileResourceDownloadCallHelper.kt b/core/src/main/java/org/hisp/dhis/android/core/fileresource/internal/FileResourceDownloadCallHelper.kt index bd45f63f94..c6b54f3b96 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/fileresource/internal/FileResourceDownloadCallHelper.kt +++ b/core/src/main/java/org/hisp/dhis/android/core/fileresource/internal/FileResourceDownloadCallHelper.kt @@ -27,9 +27,11 @@ */ package org.hisp.dhis.android.core.fileresource.internal +import org.hisp.dhis.android.core.arch.helpers.CollectionsHelper +import org.hisp.dhis.android.core.category.internal.CategoryOptionComboCategoryOptionLinkStore +import org.hisp.dhis.android.core.category.internal.CategoryOptionComboStore import org.hisp.dhis.android.core.dataelement.internal.DataElementStore import org.hisp.dhis.android.core.dataset.internal.DataSetElementStore -import org.hisp.dhis.android.core.datavalue.DataValue import org.hisp.dhis.android.core.datavalue.internal.DataValueStore import org.hisp.dhis.android.core.enrollment.internal.EnrollmentStore import org.hisp.dhis.android.core.event.internal.EventStore @@ -72,6 +74,8 @@ internal class FileResourceDownloadCallHelper( private val dataSetElementStore: DataSetElementStore, private val dataValueStore: DataValueStore, private val customIconStore: CustomIconStore, + private val categoryOptionComboStore: CategoryOptionComboStore, + private val categoryOptionComboCategoryOptionLinkStore: CategoryOptionComboCategoryOptionLinkStore, private val dhisVersionManager: DHISVersionManagerImpl, ) { @@ -225,7 +229,7 @@ internal class FileResourceDownloadCallHelper( suspend fun getMissingAggregatedDataValues( params: FileResourceDownloadParams, existingFileResources: List, - ): List { + ): List { val dataElementUidsWhereClause = WhereClauseBuilder() .appendInKeyEnumValues(DataElementTableInfo.Columns.VALUE_TYPE, params.valueTypes.map { it.valueType }) .appendKeyStringValue(DataElementTableInfo.Columns.DOMAIN_TYPE, "AGGREGATE") @@ -250,7 +254,28 @@ internal class FileResourceDownloadCallHelper( .appendNotInKeyStringValues(DataValueTableInfo.Columns.VALUE, existingFileResources) .build() - return dataValueStore.selectWhere(dataValuesWhereClause) + val dataValues = dataValueStore.selectWhere(dataValuesWhereClause) + val attributeOptionCombos = dataValues + .map { it.attributeOptionCombo() } + .distinct() + .associateWith { getAttributeOptionComboParams(it) } + + return dataValues.map { dataValue -> + val (categoryCombo, categoryOptions) = attributeOptionCombos.getValue(dataValue.attributeOptionCombo()) + MissingAggregatedDataValue(dataValue, categoryCombo, categoryOptions) + } + } + + private suspend fun getAttributeOptionComboParams(attributeOptionCombo: String): Pair { + val categoryCombo = categoryOptionComboStore.selectByUid(attributeOptionCombo)?.categoryCombo()?.uid() + + val categoryOptions = categoryOptionComboCategoryOptionLinkStore + .selectLinksForMasterUid(attributeOptionCombo) + .map { it.categoryOption() } + .takeIf { it.isNotEmpty() } + ?.let { CollectionsHelper.semicolonSeparatedCollectionValues(it) } + + return categoryCombo to categoryOptions } suspend fun getMissingCustomIcons( diff --git a/core/src/main/java/org/hisp/dhis/android/core/fileresource/internal/FileResourceNetworkHandler.kt b/core/src/main/java/org/hisp/dhis/android/core/fileresource/internal/FileResourceNetworkHandler.kt index 2f776ff4ba..1e771e86d3 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/fileresource/internal/FileResourceNetworkHandler.kt +++ b/core/src/main/java/org/hisp/dhis/android/core/fileresource/internal/FileResourceNetworkHandler.kt @@ -31,7 +31,6 @@ package org.hisp.dhis.android.core.fileresource.internal import io.ktor.client.request.forms.MultiPartFormDataContent import org.hisp.dhis.android.core.arch.api.payload.internal.Payload import org.hisp.dhis.android.core.arch.call.queries.internal.UidsQuery -import org.hisp.dhis.android.core.datavalue.DataValue import org.hisp.dhis.android.core.fileresource.FileResource import org.hisp.dhis.android.core.icon.CustomIcon import org.hisp.dhis.android.core.trackedentity.TrackedEntityDataValue @@ -68,5 +67,5 @@ internal interface FileResourceNetworkHandler { v: CustomIcon, ): ByteArray - suspend fun getFileFromDataValue(v: DataValue, dimension: String): ByteArray + suspend fun getFileFromDataValue(v: MissingAggregatedDataValue, dimension: String): ByteArray } diff --git a/core/src/main/java/org/hisp/dhis/android/core/fileresource/internal/MissingAggregatedDataValue.kt b/core/src/main/java/org/hisp/dhis/android/core/fileresource/internal/MissingAggregatedDataValue.kt new file mode 100644 index 0000000000..3dd401dc2e --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/fileresource/internal/MissingAggregatedDataValue.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2004-2023, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.fileresource.internal + +import org.hisp.dhis.android.core.datavalue.DataValue + +internal data class MissingAggregatedDataValue( + val value: DataValue, + val attributeCategoryCombo: String?, + val attributeCategoryOptions: String?, +) diff --git a/core/src/main/java/org/hisp/dhis/android/network/fileresource/FileResourceNetworkHandlerImpl.kt b/core/src/main/java/org/hisp/dhis/android/network/fileresource/FileResourceNetworkHandlerImpl.kt index f3fececbde..4894f0ef16 100644 --- a/core/src/main/java/org/hisp/dhis/android/network/fileresource/FileResourceNetworkHandlerImpl.kt +++ b/core/src/main/java/org/hisp/dhis/android/network/fileresource/FileResourceNetworkHandlerImpl.kt @@ -33,9 +33,9 @@ import org.hisp.dhis.android.core.arch.api.HttpServiceClient import org.hisp.dhis.android.core.arch.api.payload.internal.Payload import org.hisp.dhis.android.core.arch.call.queries.internal.UidsQuery import org.hisp.dhis.android.core.arch.helpers.FileResizerHelper.DimensionSize -import org.hisp.dhis.android.core.datavalue.DataValue import org.hisp.dhis.android.core.fileresource.FileResource import org.hisp.dhis.android.core.fileresource.internal.FileResourceNetworkHandler +import org.hisp.dhis.android.core.fileresource.internal.MissingAggregatedDataValue import org.hisp.dhis.android.core.fileresource.internal.MissingTrackerAttributeValue import org.hisp.dhis.android.core.icon.CustomIcon import org.hisp.dhis.android.core.systeminfo.DHISVersion @@ -146,12 +146,15 @@ internal class FileResourceNetworkHandlerImpl( return service.getCustomIcon(v.href()) } - override suspend fun getFileFromDataValue(v: DataValue, dimension: String): ByteArray { + override suspend fun getFileFromDataValue(v: MissingAggregatedDataValue, dimension: String): ByteArray { return service.getFileFromDataValue( - v.dataElement(), - v.period(), - v.organisationUnit(), - v.attributeOptionCombo(), + v.value.sourceDataSet(), + v.value.dataElement(), + v.value.period(), + v.value.organisationUnit(), + v.value.categoryOptionCombo(), + v.attributeCategoryCombo, + v.attributeCategoryOptions, dimension, ) } diff --git a/core/src/main/java/org/hisp/dhis/android/network/fileresource/FileResourceService.kt b/core/src/main/java/org/hisp/dhis/android/network/fileresource/FileResourceService.kt index 1a0af32b7c..00aa79c6f7 100644 --- a/core/src/main/java/org/hisp/dhis/android/network/fileresource/FileResourceService.kt +++ b/core/src/main/java/org/hisp/dhis/android/network/fileresource/FileResourceService.kt @@ -34,7 +34,7 @@ import org.hisp.dhis.android.core.fileresource.FileResource import org.hisp.dhis.android.network.common.fields.Fields import org.hisp.dhis.android.network.common.filters.Filter -@Suppress("TooManyFunctions") +@Suppress("TooManyFunctions", "LongParameterList") internal class FileResourceService(private val client: HttpServiceClient) { suspend fun uploadFile(filePart: MultiPartFormDataContent): FileResourceResponseDTO { @@ -161,19 +161,25 @@ internal class FileResourceService(private val client: HttpServiceClient) { } suspend fun getFileFromDataValue( + dataSet: String?, dataElement: String, period: String, organisationUnit: String, categoryOptionCombo: String, + attributeCategoryCombo: String?, + attributeCategoryOptions: String?, dimension: String, ): ByteArray { return client.get { url("$DATA_VALUES/files") parameters { + attribute("ds", dataSet) attribute("de", dataElement) attribute("pe", period) attribute("ou", organisationUnit) attribute("co", categoryOptionCombo) + attribute("cc", attributeCategoryCombo) + attribute("cp", attributeCategoryOptions) dimension.takeIf { it != DimensionSize.ORIGINAL_NAME }?.let { attribute("dimension", dimension) } } } diff --git a/core/src/test/java/org/hisp/dhis/android/core/fileresource/internal/FileResourceDownloadCallHelperShould.kt b/core/src/test/java/org/hisp/dhis/android/core/fileresource/internal/FileResourceDownloadCallHelperShould.kt index e789c211ce..07ba745598 100644 --- a/core/src/test/java/org/hisp/dhis/android/core/fileresource/internal/FileResourceDownloadCallHelperShould.kt +++ b/core/src/test/java/org/hisp/dhis/android/core/fileresource/internal/FileResourceDownloadCallHelperShould.kt @@ -29,6 +29,8 @@ package org.hisp.dhis.android.core.fileresource.internal import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest +import org.hisp.dhis.android.core.category.internal.CategoryOptionComboCategoryOptionLinkStore +import org.hisp.dhis.android.core.category.internal.CategoryOptionComboStore import org.hisp.dhis.android.core.common.ObjectWithUid import org.hisp.dhis.android.core.common.ValueType import org.hisp.dhis.android.core.dataelement.internal.DataElementStore @@ -70,6 +72,8 @@ internal class FileResourceDownloadCallHelperShould { private val dataSetElementStore: DataSetElementStore = mock() private val dataValueStore: DataValueStore = mock() private val customIconStore: CustomIconStore = mock() + private val categoryOptionComboStore: CategoryOptionComboStore = mock() + private val categoryOptionComboCategoryOptionLinkStore: CategoryOptionComboCategoryOptionLinkStore = mock() private val dhisVersionManager: DHISVersionManagerImpl = mock() private lateinit var helper: FileResourceDownloadCallHelper @@ -93,6 +97,8 @@ internal class FileResourceDownloadCallHelperShould { dataSetElementStore, dataValueStore, customIconStore, + categoryOptionComboStore, + categoryOptionComboCategoryOptionLinkStore, dhisVersionManager, ) }