From 3cca5c15c2b20c3dbcdff7b764d16922c1feee6e Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Mon, 17 May 2021 12:46:36 +0200 Subject: [PATCH 01/32] [ANDROSDK-1372] Add failing test --- ...ectionRepositoryMockIntegrationShould.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/core/src/androidTest/java/org/hisp/dhis/android/testapp/trackedentity/search/TrackedEntityInstanceQueryCollectionRepositoryMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/testapp/trackedentity/search/TrackedEntityInstanceQueryCollectionRepositoryMockIntegrationShould.java index c9f6fa2e9f..ae649153d0 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/testapp/trackedentity/search/TrackedEntityInstanceQueryCollectionRepositoryMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/testapp/trackedentity/search/TrackedEntityInstanceQueryCollectionRepositoryMockIntegrationShould.java @@ -28,6 +28,7 @@ package org.hisp.dhis.android.testapp.trackedentity.search; +import org.hisp.dhis.android.core.arch.helpers.DateUtils; import org.hisp.dhis.android.core.trackedentity.TrackedEntityInstance; import org.hisp.dhis.android.core.trackedentity.search.TrackedEntityInstanceQueryRepositoryScope; import org.hisp.dhis.android.core.utils.integration.mock.BaseMockIntegrationTestFullDispatcher; @@ -35,6 +36,8 @@ import org.junit.Test; import org.junit.runner.RunWith; +import java.text.ParseException; +import java.util.Date; import java.util.List; import static com.google.common.truth.Truth.assertThat; @@ -63,6 +66,34 @@ public void find_uids_by_program() { assertThat(trackedEntityInstanceUids.size()).isEqualTo(2); } + @Test + public void find_by_enrollment_date() throws ParseException { + Date refDate = DateUtils.DATE_FORMAT.parse("2017-01-20T00:00:00.000"); + + List trackedEntityInstances = + d2.trackedEntityModule().trackedEntityInstanceQuery() + .byProgram().eq("lxAQ7Zs9VYR") + .byProgramDate().afterOrEqual(refDate) + .byProgramDate().beforeOrEqual(refDate) + .blockingGet(); + + assertThat(trackedEntityInstances.size()).isEqualTo(1); + } + + @Test + public void find_by_event_date() throws ParseException { + Date refDate = DateUtils.DATE_FORMAT.parse("2017-01-20T00:00:00.000"); + + List trackedEntityInstances = + d2.trackedEntityModule().trackedEntityInstanceQuery() + .byProgram().eq("lxAQ7Zs9VYR") + .byEventDate().afterOrEqual(refDate) + .byEventDate().beforeOrEqual(refDate) + .blockingGet(); + + assertThat(trackedEntityInstances.size()).isEqualTo(1); + } + @Test public void get_scope() { TrackedEntityInstanceQueryRepositoryScope scope = From ce9b11085a18db7851ed4c038c0c206a01c5e8a3 Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Mon, 17 May 2021 12:58:58 +0200 Subject: [PATCH 02/32] [ANDROSDK-1372] Fix date comparison in query search repository --- ...lectionRepositoryMockIntegrationShould.java | 4 ++-- .../TrackedEntityInstanceLocalQueryHelper.kt | 18 ++++++++---------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/core/src/androidTest/java/org/hisp/dhis/android/testapp/trackedentity/search/TrackedEntityInstanceQueryCollectionRepositoryMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/testapp/trackedentity/search/TrackedEntityInstanceQueryCollectionRepositoryMockIntegrationShould.java index ae649153d0..32ba61a2dc 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/testapp/trackedentity/search/TrackedEntityInstanceQueryCollectionRepositoryMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/testapp/trackedentity/search/TrackedEntityInstanceQueryCollectionRepositoryMockIntegrationShould.java @@ -68,7 +68,7 @@ public void find_uids_by_program() { @Test public void find_by_enrollment_date() throws ParseException { - Date refDate = DateUtils.DATE_FORMAT.parse("2017-01-20T00:00:00.000"); + Date refDate = DateUtils.DATE_FORMAT.parse("2018-01-10T00:00:00.000"); List trackedEntityInstances = d2.trackedEntityModule().trackedEntityInstanceQuery() @@ -82,7 +82,7 @@ public void find_by_enrollment_date() throws ParseException { @Test public void find_by_event_date() throws ParseException { - Date refDate = DateUtils.DATE_FORMAT.parse("2017-01-20T00:00:00.000"); + Date refDate = DateUtils.DATE_FORMAT.parse("2015-05-01T00:00:00.000"); List trackedEntityInstances = d2.trackedEntityModule().trackedEntityInstanceQuery() diff --git a/core/src/main/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceLocalQueryHelper.kt b/core/src/main/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceLocalQueryHelper.kt index 5342f13d5c..e1352537fb 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceLocalQueryHelper.kt +++ b/core/src/main/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceLocalQueryHelper.kt @@ -163,18 +163,16 @@ internal class TrackedEntityInstanceLocalQueryHelper @Inject constructor( where.appendKeyStringValue(dot(enrollmentAlias, program), escapeQuotes(scope.program())) } if (scope.programDate() != null) { + val enrollmentDateStr = "date(${dot(enrollmentAlias, enrollmentDate)})" + dateFilterPeriodHelper.getStartDate(scope.programDate()!!)?.let { startDate -> - where.appendKeyGreaterOrEqStringValue( - dot(enrollmentAlias, enrollmentDate), - DateUtils.SIMPLE_DATE_FORMAT.format(startDate) - ) + val startDateStr = DateUtils.SIMPLE_DATE_FORMAT.format(startDate) + where.appendKeyGreaterOrEqStringValue(enrollmentDateStr, startDateStr) } dateFilterPeriodHelper.getEndDate(scope.programDate()!!)?.let { endDate -> - where.appendKeyLessThanOrEqStringValue( - dot(enrollmentAlias, enrollmentDate), - DateUtils.SIMPLE_DATE_FORMAT.format(endDate) - ) + val endDateStr = DateUtils.SIMPLE_DATE_FORMAT.format(endDate) + where.appendKeyLessThanOrEqStringValue(enrollmentDateStr, endDateStr) } } if (scope.enrollmentStatus() != null) { @@ -369,11 +367,11 @@ internal class TrackedEntityInstanceLocalQueryHelper @Inject constructor( if (eventFilter.eventDate() != null) { dateFilterPeriodHelper.getStartDate(eventFilter.eventDate()!!)?.let { startDate -> val dateStr = DateUtils.SIMPLE_DATE_FORMAT.format(startDate) - where.appendKeyGreaterOrEqStringValue(dot(eventAlias, refDate), dateStr) + where.appendKeyGreaterOrEqStringValue("date(${dot(eventAlias, refDate)})", dateStr) } dateFilterPeriodHelper.getEndDate(eventFilter.eventDate()!!)?.let { endDate -> val dateStr = DateUtils.SIMPLE_DATE_FORMAT.format(endDate) - where.appendKeyLessThanOrEqStringValue(dot(eventAlias, refDate), dateStr) + where.appendKeyLessThanOrEqStringValue("date(${dot(eventAlias, refDate)})", dateStr) } } } From 29a71618acb72e1a19437ee47c9e7e968763fc91 Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Thu, 20 May 2021 13:47:04 +0200 Subject: [PATCH 03/32] [ANDROSDK-1373] Filter OVERDUE/SCHEDULE events by eventStatus --- .../search/TrackedEntityInstanceLocalQueryHelper.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceLocalQueryHelper.kt b/core/src/main/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceLocalQueryHelper.kt index 5342f13d5c..49e3d5338b 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceLocalQueryHelper.kt +++ b/core/src/main/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceLocalQueryHelper.kt @@ -334,7 +334,10 @@ internal class TrackedEntityInstanceLocalQueryHelper @Inject constructor( EventStatus.SCHEDULE -> { appendEventDates(statusWhere, eventFilter, EventTableInfo.Columns.DUE_DATE) statusWhere.appendIsNullValue(EventTableInfo.Columns.EVENT_DATE) - statusWhere.appendIsNotNullValue(dot(eventAlias, EventTableInfo.Columns.STATUS)) + statusWhere.appendInKeyEnumValues( + dot(eventAlias, EventTableInfo.Columns.STATUS), + listOf(EventStatus.SCHEDULE, EventStatus.OVERDUE) + ) statusWhere.appendKeyGreaterOrEqStringValue( dot(eventAlias, EventTableInfo.Columns.DUE_DATE), nowStr ) @@ -342,7 +345,10 @@ internal class TrackedEntityInstanceLocalQueryHelper @Inject constructor( EventStatus.OVERDUE -> { appendEventDates(statusWhere, eventFilter, EventTableInfo.Columns.DUE_DATE) statusWhere.appendIsNullValue(EventTableInfo.Columns.EVENT_DATE) - statusWhere.appendIsNotNullValue(dot(eventAlias, EventTableInfo.Columns.STATUS)) + statusWhere.appendInKeyEnumValues( + dot(eventAlias, EventTableInfo.Columns.STATUS), + listOf(EventStatus.SCHEDULE, EventStatus.OVERDUE) + ) statusWhere.appendKeyLessThanStringValue( dot(eventAlias, EventTableInfo.Columns.DUE_DATE), nowStr ) From 4355bd1a3bd6593924e270be22f68fddfe7d8672 Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Thu, 20 May 2021 15:13:33 +0200 Subject: [PATCH 04/32] [ANDROSDK-1372] Apply date function to other date fields --- .../search/TrackedEntityInstanceLocalQueryHelper.kt | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceLocalQueryHelper.kt b/core/src/main/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceLocalQueryHelper.kt index e1352537fb..8adf38d68a 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceLocalQueryHelper.kt +++ b/core/src/main/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceLocalQueryHelper.kt @@ -334,7 +334,7 @@ internal class TrackedEntityInstanceLocalQueryHelper @Inject constructor( statusWhere.appendIsNullValue(EventTableInfo.Columns.EVENT_DATE) statusWhere.appendIsNotNullValue(dot(eventAlias, EventTableInfo.Columns.STATUS)) statusWhere.appendKeyGreaterOrEqStringValue( - dot(eventAlias, EventTableInfo.Columns.DUE_DATE), nowStr + "date(${dot(eventAlias, EventTableInfo.Columns.DUE_DATE)})", nowStr ) } EventStatus.OVERDUE -> { @@ -342,7 +342,7 @@ internal class TrackedEntityInstanceLocalQueryHelper @Inject constructor( statusWhere.appendIsNullValue(EventTableInfo.Columns.EVENT_DATE) statusWhere.appendIsNotNullValue(dot(eventAlias, EventTableInfo.Columns.STATUS)) statusWhere.appendKeyLessThanStringValue( - dot(eventAlias, EventTableInfo.Columns.DUE_DATE), nowStr + "date(${dot(eventAlias, EventTableInfo.Columns.DUE_DATE)})", nowStr ) } EventStatus.SKIPPED -> { @@ -365,13 +365,14 @@ internal class TrackedEntityInstanceLocalQueryHelper @Inject constructor( refDate: String ) { if (eventFilter.eventDate() != null) { + val refDateStr = "date(${dot(eventAlias, refDate)})" dateFilterPeriodHelper.getStartDate(eventFilter.eventDate()!!)?.let { startDate -> - val dateStr = DateUtils.SIMPLE_DATE_FORMAT.format(startDate) - where.appendKeyGreaterOrEqStringValue("date(${dot(eventAlias, refDate)})", dateStr) + val startDateStr = DateUtils.SIMPLE_DATE_FORMAT.format(startDate) + where.appendKeyGreaterOrEqStringValue(refDateStr, startDateStr) } dateFilterPeriodHelper.getEndDate(eventFilter.eventDate()!!)?.let { endDate -> - val dateStr = DateUtils.SIMPLE_DATE_FORMAT.format(endDate) - where.appendKeyLessThanOrEqStringValue("date(${dot(eventAlias, refDate)})", dateStr) + val endDateStr = DateUtils.SIMPLE_DATE_FORMAT.format(endDate) + where.appendKeyLessThanOrEqStringValue(refDateStr, endDateStr) } } } From b6b23fb1fe274a336cc921e42a1a7eff7285c198 Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Thu, 20 May 2021 16:01:49 +0200 Subject: [PATCH 05/32] [ANDROSDK-1372] Apply simpleDate format in eventRepository and enrollmentRepository --- ...ectionRepositoryMockIntegrationShould.java | 4 +- ...ectionRepositoryMockIntegrationShould.java | 16 +++- .../internal/BaseAbstractFilterConnector.java | 2 +- ...rConnector.java => DateFilterConnector.kt} | 73 +++++++-------- .../internal/DateTimeFilterConnector.kt | 39 ++++++++ .../internal/FilterConnectorFactory.java | 6 +- .../internal/SimpleDateFilterConnector.kt | 39 ++++++++ .../EnrollmentCollectionRepository.java | 4 +- .../core/event/EventCollectionRepository.java | 6 +- ...ueryHelper.java => InPeriodQueryHelper.kt} | 44 ++++------ .../internal/InPeriodQueryHelperShould.java | 70 --------------- .../internal/InPeriodQueryHelperShould.kt | 88 +++++++++++++++++++ 12 files changed, 241 insertions(+), 150 deletions(-) rename core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/{DateFilterConnector.java => DateFilterConnector.kt} (77%) create mode 100644 core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/DateTimeFilterConnector.kt create mode 100644 core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/SimpleDateFilterConnector.kt rename core/src/main/java/org/hisp/dhis/android/core/period/internal/{InPeriodQueryHelper.java => InPeriodQueryHelper.kt} (61%) delete mode 100644 core/src/test/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelperShould.java create mode 100644 core/src/test/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelperShould.kt diff --git a/core/src/androidTest/java/org/hisp/dhis/android/testapp/enrollment/EnrollmentCollectionRepositoryMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/testapp/enrollment/EnrollmentCollectionRepositoryMockIntegrationShould.java index 057724e4ae..84db5f7422 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/testapp/enrollment/EnrollmentCollectionRepositoryMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/testapp/enrollment/EnrollmentCollectionRepositoryMockIntegrationShould.java @@ -138,7 +138,7 @@ public void filter_by_program() { @Test public void filter_by_enrollment_date() throws ParseException { - Date created = BaseIdentifiableObject.DATE_FORMAT.parse("2018-01-10T00:00:00.000"); + Date created = BaseIdentifiableObject.DATE_FORMAT.parse("2018-01-10T13:45:00.000"); List enrollments = d2.enrollmentModule().enrollments() .byEnrollmentDate().eq(created) .blockingGet(); @@ -147,7 +147,7 @@ public void filter_by_enrollment_date() throws ParseException { @Test public void filter_by_incident_date() throws ParseException { - Date lastUpdated = BaseIdentifiableObject.DATE_FORMAT.parse("2019-01-10T00:00:00.000"); + Date lastUpdated = BaseIdentifiableObject.DATE_FORMAT.parse("2019-01-10T12:23:00.000"); List enrollments = d2.enrollmentModule().enrollments() .byIncidentDate().eq(lastUpdated) .blockingGet(); diff --git a/core/src/androidTest/java/org/hisp/dhis/android/testapp/event/EventCollectionRepositoryMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/testapp/event/EventCollectionRepositoryMockIntegrationShould.java index 8fc8db8b4a..0d47b07ff9 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/testapp/event/EventCollectionRepositoryMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/testapp/event/EventCollectionRepositoryMockIntegrationShould.java @@ -36,12 +36,14 @@ import org.hisp.dhis.android.core.event.EventCreateProjection; import org.hisp.dhis.android.core.event.EventStatus; import org.hisp.dhis.android.core.maintenance.D2Error; +import org.hisp.dhis.android.core.period.Period; import org.hisp.dhis.android.core.utils.integration.mock.BaseMockIntegrationTestFullDispatcher; import org.hisp.dhis.android.core.utils.runner.D2JunitRunner; import org.junit.Test; import org.junit.runner.RunWith; import java.text.ParseException; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -181,9 +183,14 @@ public void filter_by_organization_unit() { @Test public void filter_by_event_date() throws ParseException { + List periods = new ArrayList<>(); + periods.add(Period.builder() + .startDate(BaseNameableObject.DATE_FORMAT.parse("2017-02-27T00:00:00.000")) + .endDate(BaseNameableObject.DATE_FORMAT.parse("2017-02-27T00:00:00.000")) + .build()); List events = d2.eventModule().events() - .byEventDate().eq(BaseNameableObject.DATE_FORMAT.parse("2017-02-27T00:00:00.000")) + .byEventDate().inPeriods(periods) .blockingGet(); assertThat(events.size()).isEqualTo(1); @@ -193,7 +200,7 @@ public void filter_by_event_date() throws ParseException { public void filter_by_complete_date() throws ParseException { List events = d2.eventModule().events() - .byCompleteDate().eq(BaseNameableObject.DATE_FORMAT.parse("2016-02-27T00:00:00.000")) + .byCompleteDate().eq(BaseNameableObject.DATE_FORMAT.parse("2016-02-27T14:34:00.000")) .blockingGet(); assertThat(events.size()).isEqualTo(1); @@ -203,10 +210,11 @@ public void filter_by_complete_date() throws ParseException { public void filter_by_due_date() throws ParseException { List events = d2.eventModule().events() - .byDueDate().eq(BaseNameableObject.DATE_FORMAT.parse("2017-01-28T00:00:00.000")) + .byDueDate() + .afterOrEqual(BaseNameableObject.DATE_FORMAT.parse("2017-01-28T12:35:00.000")) .blockingGet(); - assertThat(events.size()).isEqualTo(1); + assertThat(events.size()).isEqualTo(2); } @Test diff --git a/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/BaseAbstractFilterConnector.java b/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/BaseAbstractFilterConnector.java index 4953c53eed..c89787637e 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/BaseAbstractFilterConnector.java +++ b/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/BaseAbstractFilterConnector.java @@ -36,7 +36,7 @@ import java.util.Arrays; import java.util.Collection; -abstract class BaseAbstractFilterConnector extends AbstractFilterConnector { +public abstract class BaseAbstractFilterConnector extends AbstractFilterConnector { BaseAbstractFilterConnector(BaseRepositoryFactory repositoryFactory, RepositoryScope scope, diff --git a/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/DateFilterConnector.java b/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/DateFilterConnector.kt similarity index 77% rename from core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/DateFilterConnector.java rename to core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/DateFilterConnector.kt index 23eb7c4c72..1f1ef51593 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/DateFilterConnector.java +++ b/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/DateFilterConnector.kt @@ -25,31 +25,24 @@ * (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.arch.repositories.filters.internal -package org.hisp.dhis.android.core.arch.repositories.filters.internal; +import org.hisp.dhis.android.core.arch.dateformat.internal.SafeDateFormat +import org.hisp.dhis.android.core.arch.repositories.collection.BaseRepository +import org.hisp.dhis.android.core.arch.repositories.collection.internal.BaseRepositoryFactory +import org.hisp.dhis.android.core.arch.repositories.scope.RepositoryScope +import org.hisp.dhis.android.core.arch.repositories.scope.internal.FilterItemOperator +import org.hisp.dhis.android.core.period.DatePeriod +import org.hisp.dhis.android.core.period.Period +import org.hisp.dhis.android.core.period.internal.InPeriodQueryHelper +import java.util.* -import androidx.annotation.NonNull; - -import org.hisp.dhis.android.core.arch.helpers.DateUtils; -import org.hisp.dhis.android.core.arch.repositories.collection.BaseRepository; -import org.hisp.dhis.android.core.arch.repositories.collection.internal.BaseRepositoryFactory; -import org.hisp.dhis.android.core.arch.repositories.scope.RepositoryScope; -import org.hisp.dhis.android.core.arch.repositories.scope.internal.FilterItemOperator; -import org.hisp.dhis.android.core.period.DatePeriod; -import org.hisp.dhis.android.core.period.Period; -import org.hisp.dhis.android.core.period.internal.InPeriodQueryHelper; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -public final class DateFilterConnector extends BaseAbstractFilterConnector { - - DateFilterConnector(BaseRepositoryFactory repositoryFactory, - RepositoryScope scope, - String key) { - super(repositoryFactory, scope, key); - } +abstract class DateFilterConnector internal constructor( + repositoryFactory: BaseRepositoryFactory, + scope: RepositoryScope, + key: String, + val formatter: SafeDateFormat +) : BaseAbstractFilterConnector(repositoryFactory, scope, key) { /** * Returns a new repository whose scope is the one of the current repository plus the new filter being applied. @@ -57,8 +50,8 @@ public final class DateFilterConnector extends BaseAbs * @param value value to compare with the target field * @return the new repository */ - public R before(Date value) { - return newWithWrappedScope(FilterItemOperator.LT, value); + fun before(value: Date): R { + return newWithWrappedScope(FilterItemOperator.LT, value) } /** @@ -67,8 +60,8 @@ public R before(Date value) { * @param value value to compare with the target field * @return the new repository */ - public R beforeOrEqual(Date value) { - return newWithWrappedScope(FilterItemOperator.LE, value); + fun beforeOrEqual(value: Date): R { + return newWithWrappedScope(FilterItemOperator.LE, value) } /** @@ -77,8 +70,8 @@ public R beforeOrEqual(Date value) { * @param value value to compare with the target field * @return the new repository */ - public R after(Date value) { - return newWithWrappedScope(FilterItemOperator.GT, value); + fun after(value: Date): R { + return newWithWrappedScope(FilterItemOperator.GT, value) } /** @@ -87,8 +80,8 @@ public R after(Date value) { * @param value value to compare with the target field * @return the new repository */ - public R afterOrEqual(Date value) { - return newWithWrappedScope(FilterItemOperator.GE, value); + fun afterOrEqual(value: Date): R { + return newWithWrappedScope(FilterItemOperator.GE, value) } /** @@ -98,8 +91,8 @@ public R afterOrEqual(Date value) { * @param datePeriods date periods to compare with the target field * @return the new repository */ - public R inDatePeriods(@NonNull List datePeriods) { - return newWithWrappedScope(InPeriodQueryHelper.buildInPeriodsQuery(key, datePeriods)); + fun inDatePeriods(datePeriods: List): R { + return newWithWrappedScope(InPeriodQueryHelper.buildInPeriodsQuery(key, datePeriods, formatter)) } /** @@ -109,15 +102,15 @@ public R inDatePeriods(@NonNull List datePeriods) { * @param periods periods to compare with the target field * @return the new repository */ - public R inPeriods(@NonNull List periods) { - List datePeriods = new ArrayList<>(); - for (Period period : periods) { - datePeriods.add(DatePeriod.builder().startDate(period.startDate()).endDate(period.endDate()).build()); + fun inPeriods(periods: List): R { + val datePeriods: MutableList = ArrayList() + for (period in periods) { + datePeriods.add(DatePeriod.builder().startDate(period.startDate()).endDate(period.endDate()).build()) } - return inDatePeriods(datePeriods); + return inDatePeriods(datePeriods) } - protected String wrapValue(Date value) { - return "'" + DateUtils.DATE_FORMAT.format(value) + "'"; + override fun wrapValue(value: Date): String { + return "'${formatter.format(value)}'" } } \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/DateTimeFilterConnector.kt b/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/DateTimeFilterConnector.kt new file mode 100644 index 0000000000..789b63d45a --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/DateTimeFilterConnector.kt @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2004-2021, 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.arch.repositories.filters.internal + +import org.hisp.dhis.android.core.arch.helpers.DateUtils +import org.hisp.dhis.android.core.arch.repositories.collection.BaseRepository +import org.hisp.dhis.android.core.arch.repositories.collection.internal.BaseRepositoryFactory +import org.hisp.dhis.android.core.arch.repositories.scope.RepositoryScope + +class DateTimeFilterConnector internal constructor( + repositoryFactory: BaseRepositoryFactory, + scope: RepositoryScope, + key: String +) : DateFilterConnector(repositoryFactory, scope, key, DateUtils.DATE_FORMAT) \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/FilterConnectorFactory.java b/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/FilterConnectorFactory.java index 66e27afd13..190b7e7dfe 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/FilterConnectorFactory.java +++ b/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/FilterConnectorFactory.java @@ -55,7 +55,11 @@ public BaseStringFilterConnector baseString(String key) { } public DateFilterConnector date(String key) { - return new DateFilterConnector<>(repositoryFactory, scope, key); + return new DateTimeFilterConnector<>(repositoryFactory, scope, key); + } + + public DateFilterConnector simpleDate(String key) { + return new SimpleDateFilterConnector<>(repositoryFactory, scope, key); } public BooleanFilterConnector bool(String key) { diff --git a/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/SimpleDateFilterConnector.kt b/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/SimpleDateFilterConnector.kt new file mode 100644 index 0000000000..34f5c3e569 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/SimpleDateFilterConnector.kt @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2004-2021, 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.arch.repositories.filters.internal + +import org.hisp.dhis.android.core.arch.helpers.DateUtils +import org.hisp.dhis.android.core.arch.repositories.collection.BaseRepository +import org.hisp.dhis.android.core.arch.repositories.collection.internal.BaseRepositoryFactory +import org.hisp.dhis.android.core.arch.repositories.scope.RepositoryScope + +class SimpleDateFilterConnector internal constructor( + repositoryFactory: BaseRepositoryFactory, + scope: RepositoryScope, + key: String +) : DateFilterConnector(repositoryFactory, scope, "date(${key})", DateUtils.SIMPLE_DATE_FORMAT) \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/enrollment/EnrollmentCollectionRepository.java b/core/src/main/java/org/hisp/dhis/android/core/enrollment/EnrollmentCollectionRepository.java index 87a5ca8514..666221b5cf 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/enrollment/EnrollmentCollectionRepository.java +++ b/core/src/main/java/org/hisp/dhis/android/core/enrollment/EnrollmentCollectionRepository.java @@ -107,11 +107,11 @@ public StringFilterConnector byProgram() { } public DateFilterConnector byEnrollmentDate() { - return cf.date(Columns.ENROLLMENT_DATE); + return cf.simpleDate(Columns.ENROLLMENT_DATE); } public DateFilterConnector byIncidentDate() { - return cf.date(Columns.INCIDENT_DATE); + return cf.simpleDate(Columns.INCIDENT_DATE); } public BooleanFilterConnector byFollowUp() { diff --git a/core/src/main/java/org/hisp/dhis/android/core/event/EventCollectionRepository.java b/core/src/main/java/org/hisp/dhis/android/core/event/EventCollectionRepository.java index d48199161c..e1cd072580 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/event/EventCollectionRepository.java +++ b/core/src/main/java/org/hisp/dhis/android/core/event/EventCollectionRepository.java @@ -156,15 +156,15 @@ public StringFilterConnector byOrganisationUnitUid() } public DateFilterConnector byEventDate() { - return cf.date(Columns.EVENT_DATE); + return cf.simpleDate(Columns.EVENT_DATE); } public DateFilterConnector byCompleteDate() { - return cf.date(Columns.COMPLETE_DATE); + return cf.simpleDate(Columns.COMPLETE_DATE); } public DateFilterConnector byDueDate() { - return cf.date(Columns.DUE_DATE); + return cf.simpleDate(Columns.DUE_DATE); } public EnumFilterConnector byState() { diff --git a/core/src/main/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelper.java b/core/src/main/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelper.kt similarity index 61% rename from core/src/main/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelper.java rename to core/src/main/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelper.kt index 242d215ffb..096e815890 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelper.java +++ b/core/src/main/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelper.kt @@ -25,40 +25,30 @@ * (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.period.internal -package org.hisp.dhis.android.core.period.internal; +import org.hisp.dhis.android.core.arch.dateformat.internal.SafeDateFormat +import org.hisp.dhis.android.core.arch.db.querybuilders.internal.WhereClauseBuilder +import org.hisp.dhis.android.core.period.DatePeriod -import org.hisp.dhis.android.core.arch.db.querybuilders.internal.WhereClauseBuilder; -import org.hisp.dhis.android.core.common.BaseIdentifiableObject; -import org.hisp.dhis.android.core.period.DatePeriod; +internal object InPeriodQueryHelper { -import java.util.List; - -public final class InPeriodQueryHelper { - - private InPeriodQueryHelper(){ - } - - public static String buildInPeriodsQuery(String key, List datePeriods) { - WhereClauseBuilder builder = new WhereClauseBuilder(); - for (int i = 0; i < datePeriods.size(); i++) { - builder.appendComplexQuery(buildWhereClause(key, datePeriods, i)); - - if (i != datePeriods.size() - 1) { + fun buildInPeriodsQuery(key: String, datePeriods: List, formatter: SafeDateFormat): String { + val builder = WhereClauseBuilder() + datePeriods.forEachIndexed { index, datePeriod -> + builder.appendComplexQuery(buildWhereClause(key, datePeriod, formatter)) + if (index != datePeriods.size - 1) { builder - .appendOperator(" OR "); + .appendOperator(" OR ") } } - - return builder.build(); + return builder.build() } - private static String buildWhereClause(String key, List datePeriods, int i) { - return new WhereClauseBuilder() - .appendKeyGreaterOrEqStringValue(key, - BaseIdentifiableObject.DATE_FORMAT.format(datePeriods.get(i).startDate())) - .appendKeyLessThanOrEqStringValue(key, - BaseIdentifiableObject.DATE_FORMAT.format(datePeriods.get(i).endDate())) - .build(); + private fun buildWhereClause(key: String, datePeriod: DatePeriod, formatter: SafeDateFormat): String { + return WhereClauseBuilder() + .appendKeyGreaterOrEqStringValue(key, formatter.format(datePeriod.startDate())) + .appendKeyLessThanOrEqStringValue(key, formatter.format(datePeriod.endDate())) + .build() } } \ No newline at end of file diff --git a/core/src/test/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelperShould.java b/core/src/test/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelperShould.java deleted file mode 100644 index bd9541895e..0000000000 --- a/core/src/test/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelperShould.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2004-2021, 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.period.internal; - -import com.google.common.collect.Lists; - -import org.hisp.dhis.android.core.common.BaseIdentifiableObject; -import org.hisp.dhis.android.core.period.DatePeriod; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.util.Date; -import java.util.List; - -import static com.google.common.truth.Truth.assertThat; - -@RunWith(JUnit4.class) -public class InPeriodQueryHelperShould { - - @Test - public void generate_one_requested_period() throws Exception { - - Date date1 = BaseIdentifiableObject.DATE_FORMAT.parse("2001-12-24T12:24:25.203"); - Date date2 = BaseIdentifiableObject.DATE_FORMAT.parse("2002-12-24T12:24:25.203"); - Date date3 = BaseIdentifiableObject.DATE_FORMAT.parse("2003-12-24T12:24:25.203"); - Date date4 = BaseIdentifiableObject.DATE_FORMAT.parse("2004-12-24T12:24:25.203"); - Date date5 = BaseIdentifiableObject.DATE_FORMAT.parse("2005-12-24T12:24:25.203"); - Date date6 = BaseIdentifiableObject.DATE_FORMAT.parse("2006-12-24T12:24:25.203"); - - List datePeriods = Lists.newArrayList( - DatePeriod.create(date1, date2), - DatePeriod.create(date3, date4), - DatePeriod.create(date5, date6)); - - String inPeriodQuery = InPeriodQueryHelper.buildInPeriodsQuery("COL1", datePeriods); - - assertThat(inPeriodQuery).isEqualTo( - "(COL1 >= '2001-12-24T12:24:25.203' AND COL1 <= '2002-12-24T12:24:25.203') OR " + - "(COL1 >= '2003-12-24T12:24:25.203' AND COL1 <= '2004-12-24T12:24:25.203') OR " + - "(COL1 >= '2005-12-24T12:24:25.203' AND COL1 <= '2006-12-24T12:24:25.203')" - ); - } -} \ No newline at end of file diff --git a/core/src/test/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelperShould.kt b/core/src/test/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelperShould.kt new file mode 100644 index 0000000000..478276cbb2 --- /dev/null +++ b/core/src/test/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelperShould.kt @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2004-2021, 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.period.internal + +import com.google.common.truth.Truth +import org.hisp.dhis.android.core.arch.helpers.DateUtils +import org.hisp.dhis.android.core.period.DatePeriod +import org.hisp.dhis.android.core.period.internal.InPeriodQueryHelper.buildInPeriodsQuery +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +@RunWith(JUnit4::class) +class InPeriodQueryHelperShould { + + @Test + @Throws(Exception::class) + fun generate_one_requested_period() { + val formatter = DateUtils.DATE_FORMAT + + val date1 = formatter.parse("2001-12-24T12:24:25.203") + val date2 = formatter.parse("2002-12-24T12:24:25.203") + val date3 = formatter.parse("2003-12-24T12:24:25.203") + val date4 = formatter.parse("2004-12-24T12:24:25.203") + val date5 = formatter.parse("2005-12-24T12:24:25.203") + val date6 = formatter.parse("2006-12-24T12:24:25.203") + + val datePeriods: List = listOf( + DatePeriod.create(date1, date2), + DatePeriod.create(date3, date4), + DatePeriod.create(date5, date6) + ) + + val inPeriodQuery = buildInPeriodsQuery("COL1", datePeriods, formatter) + Truth.assertThat(inPeriodQuery).isEqualTo( + "(COL1 >= '2001-12-24T12:24:25.203' AND COL1 <= '2002-12-24T12:24:25.203') OR " + + "(COL1 >= '2003-12-24T12:24:25.203' AND COL1 <= '2004-12-24T12:24:25.203') OR " + + "(COL1 >= '2005-12-24T12:24:25.203' AND COL1 <= '2006-12-24T12:24:25.203')" + ) + } + + @Test + @Throws(Exception::class) + fun generate_one_requested_period_simple_date() { + val formatter = DateUtils.SIMPLE_DATE_FORMAT + + val date1 = formatter.parse("2001-12-24T12:24:25.203") + val date2 = formatter.parse("2002-12-24T12:24:25.203") + val date3 = formatter.parse("2003-12-24T12:24:25.203") + val date4 = formatter.parse("2004-12-24T12:24:25.203") + + val datePeriods: List = listOf( + DatePeriod.create(date1, date2), + DatePeriod.create(date3, date4) + ) + + val inPeriodQuery = buildInPeriodsQuery("date(COL1)", datePeriods, formatter) + Truth.assertThat(inPeriodQuery).isEqualTo( + "(date(COL1) >= '2001-12-24' AND date(COL1) <= '2002-12-24') OR " + + "(date(COL1) >= '2003-12-24' AND date(COL1) <= '2004-12-24')" + ) + } +} \ No newline at end of file From 541191fc447dbaad58ab84564e0257e6d0eb05e7 Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Thu, 20 May 2021 16:06:20 +0200 Subject: [PATCH 06/32] [ANDROSDK-1372] Ktlint --- .../repositories/filters/internal/DateFilterConnector.kt | 4 ++-- .../filters/internal/DateTimeFilterConnector.kt | 2 +- .../filters/internal/SimpleDateFilterConnector.kt | 2 +- .../android/core/period/internal/InPeriodQueryHelper.kt | 2 +- .../core/period/internal/InPeriodQueryHelperShould.kt | 8 ++++---- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/DateFilterConnector.kt b/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/DateFilterConnector.kt index 1f1ef51593..2f07ea29e0 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/DateFilterConnector.kt +++ b/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/DateFilterConnector.kt @@ -27,6 +27,7 @@ */ package org.hisp.dhis.android.core.arch.repositories.filters.internal +import java.util.* import org.hisp.dhis.android.core.arch.dateformat.internal.SafeDateFormat import org.hisp.dhis.android.core.arch.repositories.collection.BaseRepository import org.hisp.dhis.android.core.arch.repositories.collection.internal.BaseRepositoryFactory @@ -35,7 +36,6 @@ import org.hisp.dhis.android.core.arch.repositories.scope.internal.FilterItemOpe import org.hisp.dhis.android.core.period.DatePeriod import org.hisp.dhis.android.core.period.Period import org.hisp.dhis.android.core.period.internal.InPeriodQueryHelper -import java.util.* abstract class DateFilterConnector internal constructor( repositoryFactory: BaseRepositoryFactory, @@ -113,4 +113,4 @@ abstract class DateFilterConnector internal constructor( override fun wrapValue(value: Date): String { return "'${formatter.format(value)}'" } -} \ No newline at end of file +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/DateTimeFilterConnector.kt b/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/DateTimeFilterConnector.kt index 789b63d45a..a495ed034f 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/DateTimeFilterConnector.kt +++ b/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/DateTimeFilterConnector.kt @@ -36,4 +36,4 @@ class DateTimeFilterConnector internal constructor( repositoryFactory: BaseRepositoryFactory, scope: RepositoryScope, key: String -) : DateFilterConnector(repositoryFactory, scope, key, DateUtils.DATE_FORMAT) \ No newline at end of file +) : DateFilterConnector(repositoryFactory, scope, key, DateUtils.DATE_FORMAT) diff --git a/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/SimpleDateFilterConnector.kt b/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/SimpleDateFilterConnector.kt index 34f5c3e569..67e2049d47 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/SimpleDateFilterConnector.kt +++ b/core/src/main/java/org/hisp/dhis/android/core/arch/repositories/filters/internal/SimpleDateFilterConnector.kt @@ -36,4 +36,4 @@ class SimpleDateFilterConnector internal constructor( repositoryFactory: BaseRepositoryFactory, scope: RepositoryScope, key: String -) : DateFilterConnector(repositoryFactory, scope, "date(${key})", DateUtils.SIMPLE_DATE_FORMAT) \ No newline at end of file +) : DateFilterConnector(repositoryFactory, scope, "date($key)", DateUtils.SIMPLE_DATE_FORMAT) diff --git a/core/src/main/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelper.kt b/core/src/main/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelper.kt index 096e815890..a929c44765 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelper.kt +++ b/core/src/main/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelper.kt @@ -51,4 +51,4 @@ internal object InPeriodQueryHelper { .appendKeyLessThanOrEqStringValue(key, formatter.format(datePeriod.endDate())) .build() } -} \ No newline at end of file +} diff --git a/core/src/test/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelperShould.kt b/core/src/test/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelperShould.kt index 478276cbb2..1f56e92383 100644 --- a/core/src/test/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelperShould.kt +++ b/core/src/test/java/org/hisp/dhis/android/core/period/internal/InPeriodQueryHelperShould.kt @@ -59,8 +59,8 @@ class InPeriodQueryHelperShould { val inPeriodQuery = buildInPeriodsQuery("COL1", datePeriods, formatter) Truth.assertThat(inPeriodQuery).isEqualTo( "(COL1 >= '2001-12-24T12:24:25.203' AND COL1 <= '2002-12-24T12:24:25.203') OR " + - "(COL1 >= '2003-12-24T12:24:25.203' AND COL1 <= '2004-12-24T12:24:25.203') OR " + - "(COL1 >= '2005-12-24T12:24:25.203' AND COL1 <= '2006-12-24T12:24:25.203')" + "(COL1 >= '2003-12-24T12:24:25.203' AND COL1 <= '2004-12-24T12:24:25.203') OR " + + "(COL1 >= '2005-12-24T12:24:25.203' AND COL1 <= '2006-12-24T12:24:25.203')" ) } @@ -82,7 +82,7 @@ class InPeriodQueryHelperShould { val inPeriodQuery = buildInPeriodsQuery("date(COL1)", datePeriods, formatter) Truth.assertThat(inPeriodQuery).isEqualTo( "(date(COL1) >= '2001-12-24' AND date(COL1) <= '2002-12-24') OR " + - "(date(COL1) >= '2003-12-24' AND date(COL1) <= '2004-12-24')" + "(date(COL1) >= '2003-12-24' AND date(COL1) <= '2004-12-24')" ) } -} \ No newline at end of file +} From ad5fb15085b6ace14ccdf3c2c2bbda1ad684f428 Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Fri, 21 May 2021 13:48:47 +0200 Subject: [PATCH 07/32] [ANDROSDK-1373] Relax condition to consider an event as ACTIVE --- .../search/TrackedEntityInstanceLocalQueryHelper.kt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceLocalQueryHelper.kt b/core/src/main/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceLocalQueryHelper.kt index 49e3d5338b..050ae237fc 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceLocalQueryHelper.kt +++ b/core/src/main/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceLocalQueryHelper.kt @@ -327,9 +327,16 @@ internal class TrackedEntityInstanceLocalQueryHelper @Inject constructor( for (eventStatus in statusList) { val statusWhere = WhereClauseBuilder() when (eventStatus) { - EventStatus.ACTIVE, EventStatus.COMPLETED, EventStatus.VISITED -> { - statusWhere.appendKeyStringValue(dot(eventAlias, EventTableInfo.Columns.STATUS), eventStatus) + EventStatus.ACTIVE -> { appendEventDates(statusWhere, eventFilter, EventTableInfo.Columns.EVENT_DATE) + statusWhere.appendInKeyEnumValues( + dot(eventAlias, EventTableInfo.Columns.STATUS), + listOf(EventStatus.ACTIVE, EventStatus.SCHEDULE, EventStatus.OVERDUE) + ) + } + EventStatus.COMPLETED, EventStatus.VISITED -> { + appendEventDates(statusWhere, eventFilter, EventTableInfo.Columns.EVENT_DATE) + statusWhere.appendKeyStringValue(dot(eventAlias, EventTableInfo.Columns.STATUS), eventStatus) } EventStatus.SCHEDULE -> { appendEventDates(statusWhere, eventFilter, EventTableInfo.Columns.DUE_DATE) From 375d0db6fd7fd5e78116561f605b47bcf1027b2f Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Fri, 21 May 2021 14:21:14 +0200 Subject: [PATCH 08/32] [ANDROSDK-1372] Fix unit test --- .../search/TrackedEntityInstanceLocalQueryHelperShould.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/test/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceLocalQueryHelperShould.java b/core/src/test/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceLocalQueryHelperShould.java index fa44e80412..4ba92ce1f0 100644 --- a/core/src/test/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceLocalQueryHelperShould.java +++ b/core/src/test/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceLocalQueryHelperShould.java @@ -100,8 +100,8 @@ public void build_sql_query_with_enrollment_date() throws ParseException { .build(); String sqlQuery = localQueryHelper.getSqlQuery(scope, Collections.emptySet(), 50); - assertThat(sqlQuery).contains("enrollmentDate >= '2019-04-15'"); - assertThat(sqlQuery).contains("enrollmentDate <= '2019-05-19'"); + assertThat(sqlQuery).contains("date(en.enrollmentDate) >= '2019-04-15'"); + assertThat(sqlQuery).contains("date(en.enrollmentDate) <= '2019-05-19'"); } @Test From b102f3835c1f4fa1ac6d01e03b4bbc7e99282c99 Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Tue, 25 May 2021 14:23:15 +0200 Subject: [PATCH 09/32] [ANDROSDK-1375] Create VTeiCount variable --- .../variable/ProgramVariableItem.java | 2 + .../internal/variable/VTeiCount.java | 45 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 core/src/main/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/variable/VTeiCount.java diff --git a/core/src/main/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/variable/ProgramVariableItem.java b/core/src/main/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/variable/ProgramVariableItem.java index 8a45c62f5b..83a9b6e485 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/variable/ProgramVariableItem.java +++ b/core/src/main/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/variable/ProgramVariableItem.java @@ -46,6 +46,7 @@ import static org.hisp.dhis.parser.expression.antlr.ExpressionParser.V_EVENT_COUNT; import static org.hisp.dhis.parser.expression.antlr.ExpressionParser.V_EVENT_DATE; import static org.hisp.dhis.parser.expression.antlr.ExpressionParser.V_INCIDENT_DATE; +import static org.hisp.dhis.parser.expression.antlr.ExpressionParser.V_TEI_COUNT; import static org.hisp.dhis.parser.expression.antlr.ExpressionParser.V_VALUE_COUNT; import static org.hisp.dhis.parser.expression.antlr.ExpressionParser.V_ZERO_POS_VALUE_COUNT; @@ -63,6 +64,7 @@ public class ProgramVariableItem extends ProgramExpressionItem { .put(V_CREATION_DATE, new VCreationDate()) .put(V_COMPLETED_DATE, new VCompletedDate()) + .put(V_TEI_COUNT, new VTeiCount()) .put(V_ENROLLMENT_STATUS, new VEnrollmentStatus()) .put(V_ENROLLMENT_COUNT, new VEnrollmentCount()) diff --git a/core/src/main/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/variable/VTeiCount.java b/core/src/main/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/variable/VTeiCount.java new file mode 100644 index 0000000000..abab205989 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/variable/VTeiCount.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2004-2021, 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.program.programindicatorengine.internal.variable; + +import org.hisp.dhis.android.core.parser.internal.expression.CommonExpressionVisitor; +import org.hisp.dhis.android.core.parser.internal.expression.ExpressionItem; +import org.hisp.dhis.parser.expression.antlr.ExpressionParser; + +public class VTeiCount + implements ExpressionItem { + + @Override + public Object evaluate(ExpressionParser.ExprContext ctx, CommonExpressionVisitor visitor) { + + int count = visitor.getProgramIndicatorContext().enrollment() == null ? 0 : 1; + + return String.valueOf(count); + } +} From 334e3a55a6b79558f686ce31341cfca07c9ec614 Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Tue, 25 May 2021 14:27:19 +0200 Subject: [PATCH 10/32] [ANDROSDK-1375] Add unit test --- .../internal/ProgramIndicatorExecutorShould.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/src/test/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/ProgramIndicatorExecutorShould.kt b/core/src/test/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/ProgramIndicatorExecutorShould.kt index e460bc2a26..5361dfdf05 100644 --- a/core/src/test/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/ProgramIndicatorExecutorShould.kt +++ b/core/src/test/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/ProgramIndicatorExecutorShould.kt @@ -363,6 +363,15 @@ class ProgramIndicatorExecutorShould { assertThat(result).isEqualTo("5.3") } + @Test + @Throws(ParseException::class) + fun evaluate_tei_count() { + setExpression(`var`("tei_count")) + + val result = programIndicatorExecutor.getProgramIndicatorValue(programIndicator.expression()) + assertThat(result).isEqualTo("1") + } + // ------------------------------------------------------------------------- // Supportive methods // ------------------------------------------------------------------------- From d88a65e824c4524d28b2d3000803f1070eb3b434 Mon Sep 17 00:00:00 2001 From: Marcos Campos Date: Fri, 21 May 2021 14:05:53 +0200 Subject: [PATCH 11/32] [androsdk-1315] Improve test to generate periods in this year for BiWeekly periods --- .../BiWeeklyPeriodGeneratorShould.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/core/src/test/java/org/hisp/dhis/android/core/period/internal/BiWeeklyPeriodGeneratorShould.java b/core/src/test/java/org/hisp/dhis/android/core/period/internal/BiWeeklyPeriodGeneratorShould.java index 14e873c3d4..608025ba7f 100644 --- a/core/src/test/java/org/hisp/dhis/android/core/period/internal/BiWeeklyPeriodGeneratorShould.java +++ b/core/src/test/java/org/hisp/dhis/android/core/period/internal/BiWeeklyPeriodGeneratorShould.java @@ -133,18 +133,28 @@ public void generate_period_id_with_offset() throws ParseException { } @Test - public void generate_periods_in_this_year() { + public void generate_periods_in_this_year() throws ParseException { calendar.set(2020, 7, 29); PeriodGenerator generator = new BiWeeklyPeriodGenerator(calendar); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); List periods = generator.generatePeriodsInYear(0); - // TODO Related to https://jira.dhis2.org/browse/ANDROSDK-1315 - /* assertThat(periods.size()).isEqualTo(27); assertThat(periods.get(0).periodId()).isEqualTo("2020BiW1"); assertThat(periods.get(26).periodId()).isEqualTo("2020BiW27"); - */ + + assertThat(periods.get(26).startDate()).isEqualTo(format.parse("2020-12-28")); + assertThat(periods.get(26).endDate()).isEqualTo(format.parse("2021-1-10")); + + calendar.set(2021, 4, 15); + generator = new BiWeeklyPeriodGenerator(calendar); + + periods = generator.generatePeriodsInYear(0); + + assertThat(periods.get(0).periodId()).isEqualTo("2021BiW1"); + assertThat(periods.get(0).startDate()).isEqualTo(format.parse("2021-1-4")); + assertThat(periods.get(0).endDate()).isEqualTo(format.parse("2021-1-17")); } @Test From ffd17a3f89c6746a94e684daf1e03bbd3764814d Mon Sep 17 00:00:00 2001 From: Marcos Campos Date: Mon, 24 May 2021 16:54:35 +0200 Subject: [PATCH 12/32] [androsdk-1315] Move calendar to start of the pariod after generating each period --- .../period/internal/AbstractPeriodGenerator.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/hisp/dhis/android/core/period/internal/AbstractPeriodGenerator.java b/core/src/main/java/org/hisp/dhis/android/core/period/internal/AbstractPeriodGenerator.java index a18bac2622..a4ba5f853d 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/period/internal/AbstractPeriodGenerator.java +++ b/core/src/main/java/org/hisp/dhis/android/core/period/internal/AbstractPeriodGenerator.java @@ -91,10 +91,7 @@ public final List generatePeriods(int start, int end) throws RuntimeExce public final Period generatePeriod(Date date, int periodOffset) { this.calendar = (Calendar) initialCalendar.clone(); - calendar.setTime(date); - setCalendarToStartTimeOfADay(calendar); - moveToStartOfCurrentPeriod(); - this.movePeriods(periodOffset); + moveToStartOfThePeriodOfADayWithOffset(date, periodOffset); Date startDate = calendar.getTime(); String periodId = generateId(); @@ -102,6 +99,8 @@ public final Period generatePeriod(Date date, int periodOffset) { calendar.add(Calendar.MILLISECOND, -1); Date endDate = calendar.getTime(); + moveToStartOfThePeriodOfADayWithOffset(date, periodOffset); + return Period.builder() .periodType(periodType) .startDate(startDate) @@ -137,6 +136,13 @@ public List generatePeriodsInYear(int yearOffset) { return periods; } + private void moveToStartOfThePeriodOfADayWithOffset(Date date, int periodOffset) { + this.calendar.setTime(date); + setCalendarToStartTimeOfADay(calendar); + moveToStartOfCurrentPeriod(); + this.movePeriods(periodOffset); + } + static void setCalendarToStartTimeOfADay(Calendar calendar) { calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); From ab143cd0378a5211d4ac1d223e10dd4622db93cb Mon Sep 17 00:00:00 2001 From: Marcos Campos Date: Mon, 24 May 2021 16:55:17 +0200 Subject: [PATCH 13/32] [androsdk-1315] Improve generate_periods_in_year test --- .../core/period/internal/BiWeeklyPeriodGeneratorShould.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/core/src/test/java/org/hisp/dhis/android/core/period/internal/BiWeeklyPeriodGeneratorShould.java b/core/src/test/java/org/hisp/dhis/android/core/period/internal/BiWeeklyPeriodGeneratorShould.java index 608025ba7f..18da8f5f89 100644 --- a/core/src/test/java/org/hisp/dhis/android/core/period/internal/BiWeeklyPeriodGeneratorShould.java +++ b/core/src/test/java/org/hisp/dhis/android/core/period/internal/BiWeeklyPeriodGeneratorShould.java @@ -143,18 +143,15 @@ public void generate_periods_in_this_year() throws ParseException { assertThat(periods.size()).isEqualTo(27); assertThat(periods.get(0).periodId()).isEqualTo("2020BiW1"); assertThat(periods.get(26).periodId()).isEqualTo("2020BiW27"); - assertThat(periods.get(26).startDate()).isEqualTo(format.parse("2020-12-28")); - assertThat(periods.get(26).endDate()).isEqualTo(format.parse("2021-1-10")); calendar.set(2021, 4, 15); generator = new BiWeeklyPeriodGenerator(calendar); - periods = generator.generatePeriodsInYear(0); + assertThat(periods.size()).isEqualTo(26); assertThat(periods.get(0).periodId()).isEqualTo("2021BiW1"); assertThat(periods.get(0).startDate()).isEqualTo(format.parse("2021-1-4")); - assertThat(periods.get(0).endDate()).isEqualTo(format.parse("2021-1-17")); } @Test From 9468f702a189d06712a88b2688a7043f398498fa Mon Sep 17 00:00:00 2001 From: Marcos Campos Date: Mon, 31 May 2021 16:06:45 +0200 Subject: [PATCH 14/32] [androsdk-1315] Fix generatePeriods method --- .../internal/AbstractPeriodGenerator.java | 17 +++-------------- .../internal/BiWeeklyPeriodGeneratorShould.java | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/org/hisp/dhis/android/core/period/internal/AbstractPeriodGenerator.java b/core/src/main/java/org/hisp/dhis/android/core/period/internal/AbstractPeriodGenerator.java index a4ba5f853d..7615fca9aa 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/period/internal/AbstractPeriodGenerator.java +++ b/core/src/main/java/org/hisp/dhis/android/core/period/internal/AbstractPeriodGenerator.java @@ -67,22 +67,11 @@ public final List generatePeriods(int start, int end) throws RuntimeExce movePeriods(start); for (int i = 0; i < end - start; i++) { - Date startDate = calendar.getTime(); - String periodId = generateId(); - - this.movePeriods(1); - calendar.add(Calendar.MILLISECOND, -1); - Date endDate = calendar.getTime(); - - Period period = Period.builder() - .periodType(periodType) - .startDate(startDate) - .periodId(periodId) - .endDate(endDate) - .build(); + Period period = generatePeriod(calendar.getTime(), 0); periods.add(period); - calendar.add(Calendar.MILLISECOND, 1); + calendar.setTime(period.startDate()); + this.movePeriods(1); } return periods; } diff --git a/core/src/test/java/org/hisp/dhis/android/core/period/internal/BiWeeklyPeriodGeneratorShould.java b/core/src/test/java/org/hisp/dhis/android/core/period/internal/BiWeeklyPeriodGeneratorShould.java index 18da8f5f89..a5e8122b05 100644 --- a/core/src/test/java/org/hisp/dhis/android/core/period/internal/BiWeeklyPeriodGeneratorShould.java +++ b/core/src/test/java/org/hisp/dhis/android/core/period/internal/BiWeeklyPeriodGeneratorShould.java @@ -39,6 +39,7 @@ import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.List; +import java.util.stream.Collectors; import static com.google.common.truth.Truth.assertThat; @@ -76,6 +77,20 @@ public void generate_bi_weekly_periods() { assertThat(generatedPeriods).isEqualTo(Lists.newArrayList(period1, period2)); } + @Test + public void generate_all_bi_weekly_periods() { + calendar.set(2021, 2, 25); + + List generatedPeriods = new BiWeeklyPeriodGenerator(calendar).generatePeriods( + PeriodType.BiWeekly.getDefaultStartPeriods(), + PeriodType.BiWeekly.getDefaultEndPeriods()); + + List periodIds = generatedPeriods.stream().map(period -> period.periodId()).collect(Collectors.toList()); + + assertThat(periodIds.contains("2020BiW27")).isTrue(); + assertThat(generatedPeriods.size()).isEqualTo(13); + } + @Test public void generate_bi_weekly_periods_for_changing_year() { calendar.set(2016,11,31); From b208bfa5c63d4dad2a4804528bfbfeade6b6a88d Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Mon, 31 May 2021 16:33:16 +0200 Subject: [PATCH 15/32] [ANDROSDK-1381] Pick most recent data value in repeatable stage --- .../internal/dataitem/ProgramItemStageElement.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/core/src/main/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/dataitem/ProgramItemStageElement.java b/core/src/main/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/dataitem/ProgramItemStageElement.java index 80720c16f5..0eb9dccc9c 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/dataitem/ProgramItemStageElement.java +++ b/core/src/main/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/dataitem/ProgramItemStageElement.java @@ -28,7 +28,6 @@ package org.hisp.dhis.android.core.program.programindicatorengine.internal.dataitem; -import org.hisp.dhis.android.core.common.AggregationType; import org.hisp.dhis.android.core.dataelement.DataElement; import org.hisp.dhis.android.core.event.Event; import org.hisp.dhis.android.core.parser.internal.expression.CommonExpressionVisitor; @@ -55,15 +54,8 @@ public Object evaluate(ExpressionParser.ExprContext ctx, CommonExpressionVisitor if (eventList != null) { List candidates = getCandidates(eventList, dataElementId); - AggregationType aggregationType = visitor.getProgramIndicatorContext().programIndicator().aggregationType(); - if (!candidates.isEmpty()) { - if (AggregationType.LAST.equals(aggregationType) || - AggregationType.LAST_AVERAGE_ORG_UNIT.equals(aggregationType)) { - value = candidates.get(candidates.size() - 1).value(); - } else { - value = candidates.get(0).value(); - } + value = candidates.get(candidates.size() - 1).value(); } } From 980e6d8da7dad11f564bec07a8540c7075e281fe Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Mon, 31 May 2021 16:33:33 +0200 Subject: [PATCH 16/32] [ANDROSDK-1381] Add integregation test --- ...ProgramIndicatorEngineIntegrationShould.kt | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/program/programindicatorengine/ProgramIndicatorEngineIntegrationShould.kt b/core/src/androidTest/java/org/hisp/dhis/android/core/program/programindicatorengine/ProgramIndicatorEngineIntegrationShould.kt index 1b431cf492..0b85265799 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/program/programindicatorengine/ProgramIndicatorEngineIntegrationShould.kt +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/program/programindicatorengine/ProgramIndicatorEngineIntegrationShould.kt @@ -141,7 +141,7 @@ class ProgramIndicatorEngineIntegrationShould : BaseMockIntegrationTestEmptyDisp createEnrollment() createTrackerEvent(eventUid = event1, programStageUid = programStage1, eventDate = Date()) insertTrackedEntityDataValue(event1, dataElement1, "4") - setProgramIndicatorExpressionAsAvg(de(programStage1, dataElement1)) + setProgramIndicatorExpression(de(programStage1, dataElement1)) val result = programIndicatorEngine!!.getEnrollmentProgramIndicatorValue(enrollmentUid, programIndicatorUid) assertThat(result).isEqualTo("4") } @@ -151,7 +151,7 @@ class ProgramIndicatorEngineIntegrationShould : BaseMockIntegrationTestEmptyDisp createEnrollment() createTrackerEvent(eventUid = event1, programStageUid = programStage1, eventDate = Date()) insertTrackedEntityDataValue(event1, dataElement1, "text data-value") - setProgramIndicatorExpressionAsAvg(de(programStage1, dataElement1)) + setProgramIndicatorExpression(de(programStage1, dataElement1)) val result = programIndicatorEngine!!.getEnrollmentProgramIndicatorValue(enrollmentUid, programIndicatorUid) assertThat(result).isEqualTo("text data-value") } @@ -162,7 +162,7 @@ class ProgramIndicatorEngineIntegrationShould : BaseMockIntegrationTestEmptyDisp createTrackerEvent(eventUid = event1, programStageUid = programStage1) insertTrackedEntityDataValue(event1, dataElement1, "5") insertTrackedEntityDataValue(event1, dataElement2, "3") - setProgramIndicatorExpressionAsAvg("${de(programStage1, dataElement1)} * ${de(programStage1, dataElement2)}") + setProgramIndicatorExpression("${de(programStage1, dataElement1)} * ${de(programStage1, dataElement2)}") val result = programIndicatorEngine!!.getEnrollmentProgramIndicatorValue(enrollmentUid, programIndicatorUid) assertThat(result).isEqualTo("15") } @@ -173,13 +173,13 @@ class ProgramIndicatorEngineIntegrationShould : BaseMockIntegrationTestEmptyDisp createTrackerEvent(eventUid = event1, programStageUid = programStage1) insertTrackedEntityDataValue(event1, dataElement1, "3") insertTrackedEntityDataValue(event1, dataElement2, "5") - setProgramIndicatorExpressionAsAvg("${de(programStage1, dataElement1)} / ${de(programStage1, dataElement2)}") + setProgramIndicatorExpression("${de(programStage1, dataElement1)} / ${de(programStage1, dataElement2)}") val result = programIndicatorEngine!!.getEnrollmentProgramIndicatorValue(enrollmentUid, programIndicatorUid) assertThat(result).isEqualTo("0.6") } @Test - fun evaluate_last_value_indicators_different_dates() { + fun evaluate_last_value_in_repeatable_stages() { createEnrollment() createTrackerEvent( eventUid = event1, programStageUid = programStage1, @@ -196,7 +196,7 @@ class ProgramIndicatorEngineIntegrationShould : BaseMockIntegrationTestEmptyDisp insertTrackedEntityDataValue(event1, dataElement1, "1") insertTrackedEntityDataValue(event2, dataElement1, "2") // Expected as last value insertTrackedEntityDataValue(event3, dataElement1, "3") - setProgramIndicatorExpressionAsLast(de(programStage1, dataElement1)) + setProgramIndicatorExpression(de(programStage1, dataElement1)) val result = programIndicatorEngine!!.getEnrollmentProgramIndicatorValue(enrollmentUid, programIndicatorUid) assertThat(result).isEqualTo("2") } @@ -220,7 +220,7 @@ class ProgramIndicatorEngineIntegrationShould : BaseMockIntegrationTestEmptyDisp insertTrackedEntityDataValue(event1, dataElement1, "1") insertTrackedEntityDataValue(event2, dataElement1, "2") // Expected as last value insertTrackedEntityDataValue(event3, dataElement1, "3") - setProgramIndicatorExpressionAsLast(de(programStage1, dataElement1)) + setProgramIndicatorExpression(de(programStage1, dataElement1)) val result = programIndicatorEngine!!.getEnrollmentProgramIndicatorValue(enrollmentUid, programIndicatorUid) assertThat(result).isEqualTo("2") } @@ -233,7 +233,7 @@ class ProgramIndicatorEngineIntegrationShould : BaseMockIntegrationTestEmptyDisp insertTrackedEntityDataValue(event1, dataElement1, "5") insertTrackedEntityDataValue(event2, dataElement2, "1.5") insertTrackedEntityAttributeValue(attribute1, "2") - setProgramIndicatorExpressionAsAvg( + setProgramIndicatorExpression( "(${de(programStage1, dataElement1)} + ${de(programStage2, dataElement2)})" + " / ${att(attribute1)}" ) @@ -254,7 +254,7 @@ class ProgramIndicatorEngineIntegrationShould : BaseMockIntegrationTestEmptyDisp createTrackerEvent(event1, programStage1) createTrackerEvent(event2, programStage2) createTrackerEvent(event3, programStage2, deleted = true) - setProgramIndicatorExpressionAsAvg(`var`("event_count")) + setProgramIndicatorExpression(`var`("event_count")) val result = programIndicatorEngine!!.getEnrollmentProgramIndicatorValue( enrollmentUid, programIndicatorUid @@ -268,7 +268,7 @@ class ProgramIndicatorEngineIntegrationShould : BaseMockIntegrationTestEmptyDisp createTrackerEvent(event1, programStage1) insertTrackedEntityDataValue(event1, dataElement1, "4.8") insertTrackedEntityDataValue(event1, dataElement2, "3") - setProgramIndicatorExpressionAsAvg( + setProgramIndicatorExpression( "d2:round(${de(programStage1, dataElement1)}) * ${de(programStage1, dataElement2)}" ) val result = programIndicatorEngine!!.getEnrollmentProgramIndicatorValue(enrollmentUid, programIndicatorUid) @@ -281,7 +281,7 @@ class ProgramIndicatorEngineIntegrationShould : BaseMockIntegrationTestEmptyDisp val enrollmentDate = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS").parse("2018-05-05T00:00:00.000") val incidentDate = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS").parse("2018-05-21T00:00:00.000") createEnrollment(enrollmentDate, incidentDate) - setProgramIndicatorExpressionAsAvg("d2:daysBetween(V{enrollment_date}, V{incident_date})") + setProgramIndicatorExpression("d2:daysBetween(V{enrollment_date}, V{incident_date})") val result = programIndicatorEngine!!.getEnrollmentProgramIndicatorValue(enrollmentUid, programIndicatorUid) assertThat(result).isEqualTo("16") } @@ -291,7 +291,7 @@ class ProgramIndicatorEngineIntegrationShould : BaseMockIntegrationTestEmptyDisp createSingleEvent(eventUid = event1, programStageUid = programStage1) insertTrackedEntityDataValue(event1, dataElement1, "3.0") insertTrackedEntityDataValue(event1, dataElement2, "4.0") - setProgramIndicatorExpressionAsLast("${de(programStage1, dataElement1)} + ${de(programStage1, dataElement2)}") + setProgramIndicatorExpression("${de(programStage1, dataElement1)} + ${de(programStage1, dataElement2)}") val result = programIndicatorEngine!!.getEventProgramIndicatorValue(event1, programIndicatorUid) assertThat(result).isEqualTo("7") } @@ -350,14 +350,10 @@ class ProgramIndicatorEngineIntegrationShould : BaseMockIntegrationTestEmptyDisp ) } - private fun setProgramIndicatorExpressionAsAvg(expression: String) { + private fun setProgramIndicatorExpression(expression: String) { insertProgramIndicator(expression, AggregationType.AVERAGE) } - private fun setProgramIndicatorExpressionAsLast(expression: String) { - insertProgramIndicator(expression, AggregationType.LAST) - } - private fun insertProgramIndicator(expression: String, aggregationType: AggregationType) { val programIndicator = ProgramIndicator.builder().uid(programIndicatorUid) .program(ObjectWithUid.create(programUid)).expression(expression).aggregationType(aggregationType).build() From e0eea92a4ae1f7de663dab9caa12fa18a289df8b Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Tue, 1 Jun 2021 12:20:53 +0200 Subject: [PATCH 17/32] [ANDROSDK-1381] Adapt unit tests --- .../internal/ProgramIndicatorExecutorShould.kt | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/core/src/test/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/ProgramIndicatorExecutorShould.kt b/core/src/test/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/ProgramIndicatorExecutorShould.kt index 5361dfdf05..1aad986fec 100644 --- a/core/src/test/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/ProgramIndicatorExecutorShould.kt +++ b/core/src/test/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/ProgramIndicatorExecutorShould.kt @@ -31,9 +31,7 @@ import com.google.common.truth.Truth.assertThat import com.nhaarman.mockitokotlin2.doReturn import com.nhaarman.mockitokotlin2.mock import com.nhaarman.mockitokotlin2.whenever -import java.text.ParseException import org.hisp.dhis.android.core.arch.db.stores.internal.IdentifiableObjectStore -import org.hisp.dhis.android.core.common.AggregationType import org.hisp.dhis.android.core.common.BaseIdentifiableObject import org.hisp.dhis.android.core.common.ValueType import org.hisp.dhis.android.core.constant.Constant @@ -49,6 +47,7 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.junit.MockitoJUnitRunner +import java.text.ParseException @RunWith(MockitoJUnitRunner::class) class ProgramIndicatorExecutorShould { @@ -157,14 +156,8 @@ class ProgramIndicatorExecutorShould { fun evaluate_data_elements_in_stage() { val expression = "${de(programStage1, dataElementUid1)} + ${de(programStage2, dataElementUid2)}" whenever(dataValue1.value()) doReturn "4.5" - whenever(dataValue2_1.value()) doReturn "0.8" whenever(dataValue2_2.value()) doReturn "20.6" - whenever(programIndicator.aggregationType()) doReturn AggregationType.NONE - val resultNone = programIndicatorExecutor.getProgramIndicatorValue(expression) - assertThat(resultNone).isEqualTo("5.3") - - whenever(programIndicator.aggregationType()) doReturn AggregationType.LAST val resultLast = programIndicatorExecutor.getProgramIndicatorValue(expression) assertThat(resultLast).isEqualTo("25.1") } @@ -176,7 +169,7 @@ class ProgramIndicatorExecutorShould { `var`("value_count") ) whenever(dataValue1.value()) doReturn "4.5" - whenever(dataValue2_1.value()) doReturn "1.9" + whenever(dataValue2_2.value()) doReturn "1.9" val resultNone = programIndicatorExecutor.getProgramIndicatorValue(programIndicator.expression()) assertThat(resultNone).isEqualTo("3.2") @@ -189,7 +182,7 @@ class ProgramIndicatorExecutorShould { `var`("zero_pos_value_count") ) whenever(dataValue1.value()) doReturn "7.5" - whenever(dataValue2_1.value()) doReturn "-1.5" + whenever(dataValue2_2.value()) doReturn "-1.5" val resultNone = programIndicatorExecutor.getProgramIndicatorValue(programIndicator.expression()) assertThat(resultNone).isEqualTo("6") From 1ef892b22886dbbb03e4a660411682763ccf8344 Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Tue, 1 Jun 2021 12:42:30 +0200 Subject: [PATCH 18/32] [ANDROSDK-1381] Ktlint --- .../internal/ProgramIndicatorExecutorShould.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/test/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/ProgramIndicatorExecutorShould.kt b/core/src/test/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/ProgramIndicatorExecutorShould.kt index 1aad986fec..e2634b1931 100644 --- a/core/src/test/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/ProgramIndicatorExecutorShould.kt +++ b/core/src/test/java/org/hisp/dhis/android/core/program/programindicatorengine/internal/ProgramIndicatorExecutorShould.kt @@ -31,6 +31,7 @@ import com.google.common.truth.Truth.assertThat import com.nhaarman.mockitokotlin2.doReturn import com.nhaarman.mockitokotlin2.mock import com.nhaarman.mockitokotlin2.whenever +import java.text.ParseException import org.hisp.dhis.android.core.arch.db.stores.internal.IdentifiableObjectStore import org.hisp.dhis.android.core.common.BaseIdentifiableObject import org.hisp.dhis.android.core.common.ValueType @@ -47,7 +48,6 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.junit.MockitoJUnitRunner -import java.text.ParseException @RunWith(MockitoJUnitRunner::class) class ProgramIndicatorExecutorShould { From 0cf1ccdff4c4bfcff05210dad892d1ce29b3cdc6 Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Tue, 1 Jun 2021 13:14:39 +0200 Subject: [PATCH 19/32] [ANDROSDK-1315] Add failing test --- .../BiWeeklyPeriodGeneratorShould.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/core/src/test/java/org/hisp/dhis/android/core/period/internal/BiWeeklyPeriodGeneratorShould.java b/core/src/test/java/org/hisp/dhis/android/core/period/internal/BiWeeklyPeriodGeneratorShould.java index a5e8122b05..ae8449d312 100644 --- a/core/src/test/java/org/hisp/dhis/android/core/period/internal/BiWeeklyPeriodGeneratorShould.java +++ b/core/src/test/java/org/hisp/dhis/android/core/period/internal/BiWeeklyPeriodGeneratorShould.java @@ -29,6 +29,8 @@ import com.google.common.collect.Lists; +import org.hisp.dhis.android.core.arch.dateformat.internal.SafeDateFormat; +import org.hisp.dhis.android.core.arch.helpers.DateUtils; import org.hisp.dhis.android.core.period.Period; import org.hisp.dhis.android.core.period.PeriodType; import org.junit.Test; @@ -48,6 +50,8 @@ public class BiWeeklyPeriodGeneratorShould { protected final Calendar calendar; + private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + public BiWeeklyPeriodGeneratorShould() { this.calendar = Calendar.getInstance(); } @@ -147,6 +151,26 @@ public void generate_period_id_with_offset() throws ParseException { assertThat("2019BiW25").isEqualTo(biWeeklyGenerator.generatePeriod(dateFormatter.parse("2020-01-02"), -2).periodId()); } + @Test + public void generate_last_periods_in_53_weeks_year() { + calendar.set(2021, 0, 18); + SafeDateFormat dateFormat = DateUtils.SIMPLE_DATE_FORMAT; + + PeriodGenerator biWeeklyGenerator = new BiWeeklyPeriodGenerator(calendar); + List periods = biWeeklyGenerator.generatePeriods(-3, 0); + + Period first2021 = periods.get(periods.size() - 1); + Period last2020 = periods.get(periods.size() - 2); + + assertThat(first2021.periodId()).isEqualTo("2021BiW1"); + assertThat(dateFormat.format(first2021.startDate())).isEqualTo("2021-01-04"); + assertThat(dateFormat.format(first2021.endDate())).isEqualTo("2021-01-17"); + + assertThat(last2020.periodId()).isEqualTo("2020BiW27"); + assertThat(dateFormat.format(last2020.startDate())).isEqualTo("2020-12-28T"); + assertThat(dateFormat.format(last2020.endDate())).isEqualTo("2021-12-03T"); + } + @Test public void generate_periods_in_this_year() throws ParseException { calendar.set(2020, 7, 29); From ff7ab5de594bfc017fdf13e8e92ce92212ae6b1b Mon Sep 17 00:00:00 2001 From: andresmr Date: Mon, 31 May 2021 15:14:07 +0200 Subject: [PATCH 20/32] [ANDROSDK-1380] Rename .java to .kt --- .../{DataValueImportHandler.java => DataValueImportHandler.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/{DataValueImportHandler.java => DataValueImportHandler.kt} (100%) diff --git a/core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/DataValueImportHandler.java b/core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/DataValueImportHandler.kt similarity index 100% rename from core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/DataValueImportHandler.java rename to core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/DataValueImportHandler.kt From 573bacb6791c14a7e64d59a470fbee3def6d1948 Mon Sep 17 00:00:00 2001 From: andresmr Date: Mon, 31 May 2021 15:14:07 +0200 Subject: [PATCH 21/32] [ANDROSDK-1380] Refactor to KotlinDataValueImportHandler.kt --- .../internal/DataValueImportHandler.kt | 148 ++++++++---------- 1 file changed, 68 insertions(+), 80 deletions(-) diff --git a/core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/DataValueImportHandler.kt b/core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/DataValueImportHandler.kt index b0aa1e3ed2..43318c6629 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/DataValueImportHandler.kt +++ b/core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/DataValueImportHandler.kt @@ -25,116 +25,104 @@ * (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.datavalue.internal; - -import androidx.annotation.NonNull; - -import org.hisp.dhis.android.core.common.State; -import org.hisp.dhis.android.core.datavalue.DataValue; -import org.hisp.dhis.android.core.imports.ImportStatus; -import org.hisp.dhis.android.core.imports.internal.DataValueImportSummary; -import org.hisp.dhis.android.core.imports.internal.ImportConflict; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.inject.Inject; - -import dagger.Reusable; +package org.hisp.dhis.android.core.datavalue.internal + +import dagger.Reusable +import org.hisp.dhis.android.core.common.State +import org.hisp.dhis.android.core.datavalue.DataValue +import org.hisp.dhis.android.core.imports.ImportStatus +import org.hisp.dhis.android.core.imports.internal.DataValueImportSummary +import org.hisp.dhis.android.core.imports.internal.ImportConflict +import java.util.ArrayList +import java.util.HashSet +import java.util.regex.Pattern +import javax.inject.Inject @Reusable -final class DataValueImportHandler { - - private final DataValueStore dataValueStore; - - @Inject - DataValueImportHandler(DataValueStore dataValueStore) { - this.dataValueStore = dataValueStore; - } - - void handleImportSummary(@NonNull DataValueSet dataValueSet, - @NonNull DataValueImportSummary dataValueImportSummary) { - if (dataValueImportSummary == null || dataValueSet == null) { - return; +internal class DataValueImportHandler @Inject constructor( + private val dataValueStore: DataValueStore +) { + + fun handleImportSummary( + dataValueSet: DataValueSet, + dataValueImportSummary: DataValueImportSummary + ) { + val state = when (dataValueImportSummary.importStatus()) { + ImportStatus.ERROR -> State.ERROR + ImportStatus.WARNING -> State.WARNING + else -> State.SYNCED } - State state = (dataValueImportSummary.importStatus() == ImportStatus.ERROR) ? State.ERROR : - (dataValueImportSummary.importStatus() == ImportStatus.WARNING) ? State.WARNING : State.SYNCED; - if (state == State.WARNING) { - handleDataValueWarnings(dataValueSet, dataValueImportSummary); + handleDataValueWarnings(dataValueSet, dataValueImportSummary) } else { - setStateToDataValues(state, dataValueSet.getDataValues()); + setStateToDataValues(state, dataValueSet.dataValues) } } - private void handleDataValueWarnings(DataValueSet dataValueSet, DataValueImportSummary dataValueImportSummary) { - if (dataValueImportSummary.importConflicts() == null) { - setStateToDataValues(State.WARNING, dataValueSet.getDataValues()); - } else { - Set dataValueConflicts = new HashSet<>(); - boolean setStateOnlyForConflicts = Boolean.TRUE; - for (ImportConflict importConflict : dataValueImportSummary.importConflicts()) { - List dataValues = getDataValues(importConflict, dataValueSet.getDataValues()); + private fun handleDataValueWarnings( + dataValueSet: DataValueSet, + dataValueImportSummary: DataValueImportSummary + ) { + dataValueImportSummary.importConflicts()?.let { conflicts -> + val dataValueConflicts: MutableSet = HashSet() + var setStateOnlyForConflicts = true + conflicts.forEach { importConflict -> + val dataValues = getDataValues(importConflict, dataValueSet.dataValues) if (dataValues.isEmpty()) { - setStateOnlyForConflicts = Boolean.FALSE; + setStateOnlyForConflicts = false } - dataValueConflicts.addAll(dataValues); + dataValueConflicts.addAll(dataValues) } - setDataValueStates(dataValueSet, dataValueConflicts, setStateOnlyForConflicts); - } + setDataValueStates(dataValueSet, dataValueConflicts, setStateOnlyForConflicts) + } ?: setStateToDataValues(State.WARNING, dataValueSet.dataValues) } - private void setDataValueStates(DataValueSet dataValueSet, - Set dataValueConflicts, - boolean setStateOnlyForConflicts) { + private fun setDataValueStates( + dataValueSet: DataValueSet, + dataValueConflicts: Set, + setStateOnlyForConflicts: Boolean + ) { if (setStateOnlyForConflicts) { - Iterator i = dataValueSet.getDataValues().iterator(); - while (i.hasNext()) { - if (dataValueConflicts.contains(i.next())) { - i.remove(); - } + val syncedValues = dataValueSet.dataValues.filter { dataValue -> + !dataValueConflicts.contains(dataValue) } - setStateToDataValues(State.WARNING, dataValueConflicts); + setStateToDataValues(State.WARNING, dataValueConflicts) + setStateToDataValues(State.SYNCED, syncedValues) + } else { + setStateToDataValues(State.WARNING, dataValueSet.dataValues) } - setStateToDataValues(State.SYNCED, dataValueSet.getDataValues()); } - private List getDataValues(ImportConflict importConflict, Collection dataValues) - throws IllegalArgumentException { - String patternStr = "(?<=:\\s)[a-zA-Z0-9]{11}"; - Pattern pattern = Pattern.compile(patternStr); - Matcher matcher = pattern.matcher(importConflict.value()); + private fun getDataValues( + importConflict: ImportConflict, + dataValues: Collection + ): List { + val patternStr = "(?<=:\\s)[a-zA-Z0-9]{11}" + val pattern = Pattern.compile(patternStr) + val matcher = pattern.matcher(importConflict.value()) - List foundDataValues = new ArrayList<>(); + val foundDataValues: MutableList = ArrayList() if (matcher.find()) { - String value = importConflict.object(); - String dataElementUid = matcher.group(0); - for (DataValue dataValue : dataValues) { - if (dataValue.value().equals(value) && dataValue.dataElement().equals(dataElementUid)) { - foundDataValues.add(dataValue); + val value = importConflict.`object`() + val dataElementUid = matcher.group(0) + for (dataValue in dataValues) { + if (dataValue.value() == value && dataValue.dataElement() == dataElementUid) { + foundDataValues.add(dataValue) } } } - - return foundDataValues; + return foundDataValues } - private void setStateToDataValues(State state, Collection dataValues) { - for (DataValue dataValue : dataValues) { + private fun setStateToDataValues(state: State, dataValues: Collection) { + for (dataValue in dataValues) { if (dataValueStore.isDataValueBeingUpload(dataValue)) { if (state == State.SYNCED && dataValueStore.isDeleted(dataValue)) { - dataValueStore.deleteWhere(dataValue); + dataValueStore.deleteWhere(dataValue) } else { - dataValueStore.setState(dataValue, state); + dataValueStore.setState(dataValue, state) } } } From 35ba90e7ab225d30e448bda84e85763969d9c9c8 Mon Sep 17 00:00:00 2001 From: andresmr Date: Mon, 31 May 2021 17:18:05 +0200 Subject: [PATCH 22/32] [ANDROSDK-1380] Get values for each conflict or null to stop loop --- .../internal/DataValueImportHandler.kt | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/DataValueImportHandler.kt b/core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/DataValueImportHandler.kt index 43318c6629..8a74297bf4 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/DataValueImportHandler.kt +++ b/core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/DataValueImportHandler.kt @@ -64,34 +64,36 @@ internal class DataValueImportHandler @Inject constructor( dataValueSet: DataValueSet, dataValueImportSummary: DataValueImportSummary ) { - dataValueImportSummary.importConflicts()?.let { conflicts -> - val dataValueConflicts: MutableSet = HashSet() - var setStateOnlyForConflicts = true - conflicts.forEach { importConflict -> - val dataValues = getDataValues(importConflict, dataValueSet.dataValues) + getValuesWithConflicts(dataValueSet, dataValueImportSummary)?.let { dataValueConflicts -> + setDataValueStates(dataValueSet, dataValueConflicts) + } ?: setStateToDataValues(State.WARNING, dataValueSet.dataValues) + } + + private fun getValuesWithConflicts( + dataValueSet: DataValueSet, + dataValueImportSummary: DataValueImportSummary + ) = dataValueImportSummary.importConflicts()?.let { conflicts -> + val dataValueConflicts: MutableSet = HashSet() + conflicts.forEach { importConflict -> + getDataValues(importConflict, dataValueSet.dataValues).let { dataValues -> if (dataValues.isEmpty()) { - setStateOnlyForConflicts = false + return null } dataValueConflicts.addAll(dataValues) } - setDataValueStates(dataValueSet, dataValueConflicts, setStateOnlyForConflicts) - } ?: setStateToDataValues(State.WARNING, dataValueSet.dataValues) + } + dataValueConflicts } private fun setDataValueStates( dataValueSet: DataValueSet, - dataValueConflicts: Set, - setStateOnlyForConflicts: Boolean + dataValueConflicts: Set ) { - if (setStateOnlyForConflicts) { - val syncedValues = dataValueSet.dataValues.filter { dataValue -> - !dataValueConflicts.contains(dataValue) - } - setStateToDataValues(State.WARNING, dataValueConflicts) - setStateToDataValues(State.SYNCED, syncedValues) - } else { - setStateToDataValues(State.WARNING, dataValueSet.dataValues) + val syncedValues = dataValueSet.dataValues.filter { dataValue -> + !dataValueConflicts.contains(dataValue) } + setStateToDataValues(State.WARNING, dataValueConflicts) + setStateToDataValues(State.SYNCED, syncedValues) } private fun getDataValues( From 39102cd24805f8e977bca4e749dd6bafe50b6b35 Mon Sep 17 00:00:00 2001 From: andresmr Date: Tue, 1 Jun 2021 14:29:28 +0200 Subject: [PATCH 23/32] [ANDROSDK-1380] Create DataValuePostCallMockIntegrationShould.kt test --- .../DataValuePostCallMockIntegrationShould.kt | 76 +++++++++++++++++++ .../internal/DataValueImportHandler.kt | 8 +- .../datavalueset/data_value_set_success.json | 40 ++++++++++ .../datavalueset/data_value_set_warning.json | 45 +++++++++++ 4 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/internal/DataValuePostCallMockIntegrationShould.kt create mode 100644 core/src/sharedTest/resources/datavalueset/data_value_set_success.json create mode 100644 core/src/sharedTest/resources/datavalueset/data_value_set_warning.json diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/internal/DataValuePostCallMockIntegrationShould.kt b/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/internal/DataValuePostCallMockIntegrationShould.kt new file mode 100644 index 0000000000..9c5679f80e --- /dev/null +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/internal/DataValuePostCallMockIntegrationShould.kt @@ -0,0 +1,76 @@ +package org.hisp.dhis.android.core.datavalue.internal + +import com.google.common.truth.Truth.assertThat +import org.hisp.dhis.android.core.common.State +import org.hisp.dhis.android.core.maintenance.D2Error +import org.hisp.dhis.android.core.utils.integration.mock.BaseMockIntegrationTestMetadataEnqueable +import org.hisp.dhis.android.core.utils.runner.D2JunitRunner +import org.junit.After +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(D2JunitRunner::class) +class DataValuePostCallMockIntegrationShould : BaseMockIntegrationTestMetadataEnqueable() { + + @After + @Throws(D2Error::class) + fun tearDown() { + d2.wipeModule().wipeData() + } + + @Test + fun post_dataValues_success() { + dhis2MockServer.enqueueMockResponse("datavalueset/data_value_set_success.json") + + provideCorrectDataValues() + + d2.dataValueModule().dataValues().blockingUpload() + val warnings = d2.dataValueModule().dataValues().byState().eq(State.SYNCED).blockingGet() + assertThat(warnings.size).isEqualTo(2) + } + + @Test + fun post_dataValues_warning() { + dhis2MockServer.enqueueMockResponse("datavalueset/data_value_set_warning.json") + + provideWarningDataValues() + + d2.dataValueModule().dataValues().blockingUpload() + val warnings = d2.dataValueModule().dataValues().byState().eq(State.WARNING).blockingGet() + assertThat(warnings.size).isEqualTo(1) + } + + private fun provideCorrectDataValues() { + d2.dataValueModule().dataValues().value( + "20191021", + "DiszpKrYNg8", + "Ok9OQpitjQr", + "DwrQJzeChWp", + "DwrQJzeChWp" + ).blockingSet("30") + d2.dataValueModule().dataValues().value( + "20191021", + "DiszpKrYNg8", + "vANAXwtLwcT", + "bRowv6yZOF2", + "bRowv6yZOF2" + ).blockingSet("40") + } + + private fun provideWarningDataValues() { + d2.dataValueModule().dataValues().value( + "20191021", + "DiszpKrYNg8", + "Ok9OQpitjQr", + "DwrQJzeChWp", + "DwrQJzeChWp" + ).blockingSet("30") + d2.dataValueModule().dataValues().value( + "20191021", + "DiszpKrYNg8", + "vANAXwtLwcT", + "bRowv6yZOF2", + "bRowv6yZOF2" + ).blockingSet("40L") + } +} diff --git a/core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/DataValueImportHandler.kt b/core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/DataValueImportHandler.kt index 8a74297bf4..a93e7d9fe4 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/DataValueImportHandler.kt +++ b/core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/DataValueImportHandler.kt @@ -44,9 +44,13 @@ internal class DataValueImportHandler @Inject constructor( ) { fun handleImportSummary( - dataValueSet: DataValueSet, - dataValueImportSummary: DataValueImportSummary + dataValueSet: DataValueSet?, + dataValueImportSummary: DataValueImportSummary? ) { + if (dataValueSet == null || dataValueImportSummary == null) { + return + } + val state = when (dataValueImportSummary.importStatus()) { ImportStatus.ERROR -> State.ERROR ImportStatus.WARNING -> State.WARNING diff --git a/core/src/sharedTest/resources/datavalueset/data_value_set_success.json b/core/src/sharedTest/resources/datavalueset/data_value_set_success.json new file mode 100644 index 0000000000..a36d88db9e --- /dev/null +++ b/core/src/sharedTest/resources/datavalueset/data_value_set_success.json @@ -0,0 +1,40 @@ +{ + "responseType": "ImportSummary", + "status": "SUCCESS", + "importOptions": { + "idSchemes": {}, + "dryRun": false, + "async": false, + "importStrategy": "CREATE_AND_UPDATE", + "mergeMode": "REPLACE", + "reportMode": "FULL", + "skipExistingCheck": false, + "sharing": false, + "skipNotifications": false, + "skipAudit": false, + "datasetAllowsPeriods": false, + "strictPeriods": false, + "strictDataElements": false, + "strictCategoryOptionCombos": false, + "strictAttributeOptionCombos": false, + "strictOrganisationUnits": false, + "requireCategoryOptionCombo": false, + "requireAttributeOptionCombo": false, + "skipPatternValidation": false, + "ignoreEmptyCollection": false, + "force": false, + "firstRowIsHeader": true, + "skipLastUpdated": false, + "mergeDataValues": false, + "skipCache": false + }, + "description": "Import process completed successfully", + "importCount": { + "imported": 0, + "updated": 3, + "ignored": 0, + "deleted": 0 + }, + "conflicts": [], + "dataSetComplete": "false" +} \ No newline at end of file diff --git a/core/src/sharedTest/resources/datavalueset/data_value_set_warning.json b/core/src/sharedTest/resources/datavalueset/data_value_set_warning.json new file mode 100644 index 0000000000..dabfdd390a --- /dev/null +++ b/core/src/sharedTest/resources/datavalueset/data_value_set_warning.json @@ -0,0 +1,45 @@ +{ + "responseType": "ImportSummary", + "status": "WARNING", + "importOptions": { + "idSchemes": {}, + "dryRun": false, + "async": false, + "importStrategy": "CREATE_AND_UPDATE", + "mergeMode": "REPLACE", + "reportMode": "FULL", + "skipExistingCheck": false, + "sharing": false, + "skipNotifications": false, + "skipAudit": false, + "datasetAllowsPeriods": false, + "strictPeriods": false, + "strictDataElements": false, + "strictCategoryOptionCombos": false, + "strictAttributeOptionCombos": false, + "strictOrganisationUnits": false, + "requireCategoryOptionCombo": false, + "requireAttributeOptionCombo": false, + "skipPatternValidation": false, + "ignoreEmptyCollection": false, + "force": false, + "firstRowIsHeader": true, + "skipLastUpdated": false, + "mergeDataValues": false, + "skipCache": false + }, + "description": "Import process completed successfully", + "importCount": { + "imported": 0, + "updated": 0, + "ignored": 1, + "deleted": 0 + }, + "conflicts": [ + { + "object": "40L", + "value": "El valor de dato no es un entero, must match data element type: vANAXwtLwcT" + } + ], + "dataSetComplete": "false" +} \ No newline at end of file From 2d13eba345cd0b4db5a1b77d4152f3422774b4df Mon Sep 17 00:00:00 2001 From: andresmr Date: Tue, 1 Jun 2021 16:46:52 +0200 Subject: [PATCH 24/32] [ANDROSDK-1380] Klint format --- .../datavalue/internal/DataValueImportHandler.kt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/DataValueImportHandler.kt b/core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/DataValueImportHandler.kt index a93e7d9fe4..3be37abbba 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/DataValueImportHandler.kt +++ b/core/src/main/java/org/hisp/dhis/android/core/datavalue/internal/DataValueImportHandler.kt @@ -28,15 +28,15 @@ package org.hisp.dhis.android.core.datavalue.internal import dagger.Reusable +import java.util.ArrayList +import java.util.HashSet +import java.util.regex.Pattern +import javax.inject.Inject import org.hisp.dhis.android.core.common.State import org.hisp.dhis.android.core.datavalue.DataValue import org.hisp.dhis.android.core.imports.ImportStatus import org.hisp.dhis.android.core.imports.internal.DataValueImportSummary import org.hisp.dhis.android.core.imports.internal.ImportConflict -import java.util.ArrayList -import java.util.HashSet -import java.util.regex.Pattern -import javax.inject.Inject @Reusable internal class DataValueImportHandler @Inject constructor( @@ -47,7 +47,7 @@ internal class DataValueImportHandler @Inject constructor( dataValueSet: DataValueSet?, dataValueImportSummary: DataValueImportSummary? ) { - if (dataValueSet == null || dataValueImportSummary == null) { + if (dataValueSet == null || dataValueImportSummary == null) { return } @@ -76,9 +76,9 @@ internal class DataValueImportHandler @Inject constructor( private fun getValuesWithConflicts( dataValueSet: DataValueSet, dataValueImportSummary: DataValueImportSummary - ) = dataValueImportSummary.importConflicts()?.let { conflicts -> + ): Set? { val dataValueConflicts: MutableSet = HashSet() - conflicts.forEach { importConflict -> + dataValueImportSummary.importConflicts()?.forEach { importConflict -> getDataValues(importConflict, dataValueSet.dataValues).let { dataValues -> if (dataValues.isEmpty()) { return null @@ -86,7 +86,7 @@ internal class DataValueImportHandler @Inject constructor( dataValueConflicts.addAll(dataValues) } } - dataValueConflicts + return dataValueConflicts } private fun setDataValueStates( From 9d400f143de2f287ba821e32536021ad1dbb34d6 Mon Sep 17 00:00:00 2001 From: andresmr Date: Wed, 2 Jun 2021 17:58:01 +0200 Subject: [PATCH 25/32] [ANDROSDK-1380] Add test for non recognised warning --- .../DataValuePostCallMockIntegrationShould.kt | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/internal/DataValuePostCallMockIntegrationShould.kt b/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/internal/DataValuePostCallMockIntegrationShould.kt index 9c5679f80e..bad0bd18ba 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/internal/DataValuePostCallMockIntegrationShould.kt +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/internal/DataValuePostCallMockIntegrationShould.kt @@ -20,57 +20,60 @@ class DataValuePostCallMockIntegrationShould : BaseMockIntegrationTestMetadataEn @Test fun post_dataValues_success() { + // Given user sets correct data values dhis2MockServer.enqueueMockResponse("datavalueset/data_value_set_success.json") + provideDataValues("30", "40") - provideCorrectDataValues() - + // When user sync data in order to upload the data values d2.dataValueModule().dataValues().blockingUpload() + + // Then all data set should be properly synced val warnings = d2.dataValueModule().dataValues().byState().eq(State.SYNCED).blockingGet() assertThat(warnings.size).isEqualTo(2) } @Test fun post_dataValues_warning() { + // Given user sets one unsupported type of data value dhis2MockServer.enqueueMockResponse("datavalueset/data_value_set_warning.json") + provideDataValues("30", "40L") - provideWarningDataValues() - + // When user sync data in order to upload the data values d2.dataValueModule().dataValues().blockingUpload() + + // Then one data set should marked as WARNING val warnings = d2.dataValueModule().dataValues().byState().eq(State.WARNING).blockingGet() assertThat(warnings.size).isEqualTo(1) } - private fun provideCorrectDataValues() { - d2.dataValueModule().dataValues().value( - "20191021", - "DiszpKrYNg8", - "Ok9OQpitjQr", - "DwrQJzeChWp", - "DwrQJzeChWp" - ).blockingSet("30") - d2.dataValueModule().dataValues().value( - "20191021", - "DiszpKrYNg8", - "vANAXwtLwcT", - "bRowv6yZOF2", - "bRowv6yZOF2" - ).blockingSet("40") + @Test + fun post_dataValues_undetermined_warning() { + // Given user sets one undetermined data value + dhis2MockServer.enqueueMockResponse("datavalueset/data_value_set_warning.json") + provideDataValues("40", "50L") + + // When user sync data in order to upload the data values + d2.dataValueModule().dataValues().blockingUpload() + + // Then all data values should be marked as WARNING + val warnings = d2.dataValueModule().dataValues().byState().eq(State.WARNING).blockingGet() + assertThat(warnings.size).isEqualTo(2) } - private fun provideWarningDataValues() { + private fun provideDataValues(value1: String, value2: String) { d2.dataValueModule().dataValues().value( "20191021", "DiszpKrYNg8", "Ok9OQpitjQr", "DwrQJzeChWp", "DwrQJzeChWp" - ).blockingSet("30") + ).blockingSet(value1) d2.dataValueModule().dataValues().value( "20191021", "DiszpKrYNg8", "vANAXwtLwcT", "bRowv6yZOF2", "bRowv6yZOF2" - ).blockingSet("40L") + ).blockingSet(value2) } } From 3586e26ccebe56d161c8ade058d9c5756890cc0a Mon Sep 17 00:00:00 2001 From: Marcos Campos Date: Fri, 4 Jun 2021 11:19:15 +0200 Subject: [PATCH 26/32] [androsdk-1315] Fix BiWeekly generation for last periods in the year --- .../internal/AbstractPeriodGenerator.java | 19 +++++++++++++-- .../BiWeeklyPeriodGeneratorShould.java | 24 +++++++++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/hisp/dhis/android/core/period/internal/AbstractPeriodGenerator.java b/core/src/main/java/org/hisp/dhis/android/core/period/internal/AbstractPeriodGenerator.java index 7615fca9aa..fb09de539c 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/period/internal/AbstractPeriodGenerator.java +++ b/core/src/main/java/org/hisp/dhis/android/core/period/internal/AbstractPeriodGenerator.java @@ -64,14 +64,14 @@ public final List generatePeriods(int start, int end) throws RuntimeExce List periods = new ArrayList<>(); setCalendarToStartTimeOfADay(calendar); moveToStartOfCurrentPeriod(); - movePeriods(start); + moveToTheFirstPeriod(start); for (int i = 0; i < end - start; i++) { Period period = generatePeriod(calendar.getTime(), 0); periods.add(period); calendar.setTime(period.startDate()); - this.movePeriods(1); + movePeriods(1); } return periods; } @@ -125,6 +125,21 @@ public List generatePeriodsInYear(int yearOffset) { return periods; } + private void moveToTheFirstPeriod(int start) { + int periods = 0; + while (periods < Math.abs(start)) { + Period period = generatePeriod(calendar.getTime(), 0); + if (start > 0) { + calendar.setTime(period.startDate()); + movePeriods(1); + } else { + calendar.setTime(period.startDate()); + calendar.add(Calendar.MILLISECOND, -1); + } + periods++; + } + } + private void moveToStartOfThePeriodOfADayWithOffset(Date date, int periodOffset) { this.calendar.setTime(date); setCalendarToStartTimeOfADay(calendar); diff --git a/core/src/test/java/org/hisp/dhis/android/core/period/internal/BiWeeklyPeriodGeneratorShould.java b/core/src/test/java/org/hisp/dhis/android/core/period/internal/BiWeeklyPeriodGeneratorShould.java index ae8449d312..0c3ad616d3 100644 --- a/core/src/test/java/org/hisp/dhis/android/core/period/internal/BiWeeklyPeriodGeneratorShould.java +++ b/core/src/test/java/org/hisp/dhis/android/core/period/internal/BiWeeklyPeriodGeneratorShould.java @@ -167,8 +167,28 @@ public void generate_last_periods_in_53_weeks_year() { assertThat(dateFormat.format(first2021.endDate())).isEqualTo("2021-01-17"); assertThat(last2020.periodId()).isEqualTo("2020BiW27"); - assertThat(dateFormat.format(last2020.startDate())).isEqualTo("2020-12-28T"); - assertThat(dateFormat.format(last2020.endDate())).isEqualTo("2021-12-03T"); + assertThat(dateFormat.format(last2020.startDate())).isEqualTo("2020-12-28"); + assertThat(dateFormat.format(last2020.endDate())).isEqualTo("2021-01-10"); + } + + @Test + public void generate_last_periods_in_53_weeks_year_starting_past_year() { + calendar.set(2020, 11, 2); + SafeDateFormat dateFormat = DateUtils.SIMPLE_DATE_FORMAT; + + PeriodGenerator biWeeklyGenerator = new BiWeeklyPeriodGenerator(calendar); + List periods = biWeeklyGenerator.generatePeriods(1, 5); + + Period first2021 = periods.get(periods.size() - 2); + Period last2020 = periods.get(periods.size() - 3); + + assertThat(first2021.periodId()).isEqualTo("2021BiW1"); + assertThat(dateFormat.format(first2021.startDate())).isEqualTo("2021-01-04"); + assertThat(dateFormat.format(first2021.endDate())).isEqualTo("2021-01-17"); + + assertThat(last2020.periodId()).isEqualTo("2020BiW27"); + assertThat(dateFormat.format(last2020.startDate())).isEqualTo("2020-12-28"); + assertThat(dateFormat.format(last2020.endDate())).isEqualTo("2021-01-10"); } @Test From 95e7197c99e801b71078c426f9f3337e0814b229 Mon Sep 17 00:00:00 2001 From: Marcos Campos Date: Thu, 20 May 2021 16:11:03 +0200 Subject: [PATCH 27/32] [ANDROSDK-1357-2] [androsdk-1357] Add dueDateLabel to program stage --- .../android/core/program/ProgramStage.java | 6 +++ .../core/program/ProgramStageTableInfo.java | 2 + .../program/internal/ProgramStageFields.java | 1 + .../program/internal/ProgramStageStore.java | 45 ++++++++++--------- 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/core/src/main/java/org/hisp/dhis/android/core/program/ProgramStage.java b/core/src/main/java/org/hisp/dhis/android/core/program/ProgramStage.java index eafee35d3b..6e19424baf 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/program/ProgramStage.java +++ b/core/src/main/java/org/hisp/dhis/android/core/program/ProgramStage.java @@ -79,6 +79,10 @@ public abstract class ProgramStage extends BaseIdentifiableObject @JsonProperty() public abstract String executionDateLabel(); + @Nullable + @JsonProperty() + public abstract String dueDateLabel(); + @Nullable @JsonProperty() public abstract Boolean allowGenerateNextVisit(); @@ -210,6 +214,8 @@ public static abstract class Builder extends BaseIdentifiableObject.Builderfield(Columns.DESCRIPTION), fh.field(Columns.DISPLAY_DESCRIPTION), fh.field(Columns.EXECUTION_DATE_LABEL), + fh.field(Columns.DUE_DATE_LABEL), fh.field(Columns.ALLOW_GENERATE_NEXT_VISIT), fh.field(Columns.VALID_COMPLETE_ONLY), fh.field(Columns.REPORT_DATE_TO_USE), diff --git a/core/src/main/java/org/hisp/dhis/android/core/program/internal/ProgramStageStore.java b/core/src/main/java/org/hisp/dhis/android/core/program/internal/ProgramStageStore.java index 456347b57c..7ca63a8db2 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/program/internal/ProgramStageStore.java +++ b/core/src/main/java/org/hisp/dhis/android/core/program/internal/ProgramStageStore.java @@ -28,6 +28,8 @@ package org.hisp.dhis.android.core.program.internal; +import androidx.annotation.NonNull; + import org.hisp.dhis.android.core.arch.db.access.DatabaseAdapter; import org.hisp.dhis.android.core.arch.db.stores.binders.internal.IdentifiableWithStyleStatementBinder; import org.hisp.dhis.android.core.arch.db.stores.binders.internal.StatementBinder; @@ -39,8 +41,6 @@ import org.hisp.dhis.android.core.program.ProgramStage; import org.hisp.dhis.android.core.program.ProgramStageTableInfo; -import androidx.annotation.NonNull; - public final class ProgramStageStore { private static StatementBinder BINDER = new IdentifiableWithStyleStatementBinder() { @@ -51,26 +51,27 @@ public void bindToStatement(@NonNull ProgramStage o, @NonNull StatementWrapper w w.bind(9, o.description()); w.bind(10, o.displayDescription()); w.bind(11, o.executionDateLabel()); - w.bind(12, o.allowGenerateNextVisit()); - w.bind(13, o.validCompleteOnly()); - w.bind(14, o.reportDateToUse()); - w.bind(15, o.openAfterEnrollment()); - w.bind(16, o.repeatable()); - w.bind(17, o.formType().name()); - w.bind(18, o.displayGenerateEventBox()); - w.bind(19, o.generatedByEnrollmentDate()); - w.bind(20, o.autoGenerateEvent()); - w.bind(21, o.sortOrder()); - w.bind(22, o.hideDueDate()); - w.bind(23, o.blockEntryForm()); - w.bind(24, o.minDaysFromStart()); - w.bind(25, o.standardInterval()); - w.bind(26, UidsHelper.getUidOrNull(o.program())); - w.bind(27, o.periodType()); - w.bind(28, o.access().data().write()); - w.bind(29, o.remindCompleted()); - w.bind(30, o.featureType()); - w.bind(31, o.enableUserAssignment()); + w.bind(12, o.dueDateLabel()); + w.bind(13, o.allowGenerateNextVisit()); + w.bind(14, o.validCompleteOnly()); + w.bind(15, o.reportDateToUse()); + w.bind(16, o.openAfterEnrollment()); + w.bind(17, o.repeatable()); + w.bind(18, o.formType().name()); + w.bind(19, o.displayGenerateEventBox()); + w.bind(20, o.generatedByEnrollmentDate()); + w.bind(21, o.autoGenerateEvent()); + w.bind(22, o.sortOrder()); + w.bind(23, o.hideDueDate()); + w.bind(24, o.blockEntryForm()); + w.bind(25, o.minDaysFromStart()); + w.bind(26, o.standardInterval()); + w.bind(27, UidsHelper.getUidOrNull(o.program())); + w.bind(28, o.periodType()); + w.bind(29, o.access().data().write()); + w.bind(30, o.remindCompleted()); + w.bind(31, o.featureType()); + w.bind(32, o.enableUserAssignment()); } }; From 0e394d5cf17a49cba58754bbc5f350f0dfbdb5b3 Mon Sep 17 00:00:00 2001 From: Marcos Campos Date: Thu, 20 May 2021 16:11:21 +0200 Subject: [PATCH 28/32] [ANDROSDK-1357-2] [androsdk-1357] Add dueDateLabel to table and migrations --- core/src/main/assets/migrations/99.sql | 2 ++ core/src/main/assets/snapshots/{98.sql => 99.sql} | 2 +- .../core/arch/db/access/internal/BaseDatabaseOpenHelper.java | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 core/src/main/assets/migrations/99.sql rename core/src/main/assets/snapshots/{98.sql => 99.sql} (99%) diff --git a/core/src/main/assets/migrations/99.sql b/core/src/main/assets/migrations/99.sql new file mode 100644 index 0000000000..da734f947f --- /dev/null +++ b/core/src/main/assets/migrations/99.sql @@ -0,0 +1,2 @@ +# Adds column ProgramStage.dueDateLabel +ALTER TABLE ProgramStage ADD COLUMN dueDateLabel TEXT; \ No newline at end of file diff --git a/core/src/main/assets/snapshots/98.sql b/core/src/main/assets/snapshots/99.sql similarity index 99% rename from core/src/main/assets/snapshots/98.sql rename to core/src/main/assets/snapshots/99.sql index 8f1b137ed6..9cfc3749d5 100644 --- a/core/src/main/assets/snapshots/98.sql +++ b/core/src/main/assets/snapshots/99.sql @@ -66,7 +66,7 @@ CREATE TABLE TrackerImportConflict (_id INTEGER PRIMARY KEY AUTOINCREMENT, confl CREATE TABLE DataSetOrganisationUnitLink (_id INTEGER PRIMARY KEY AUTOINCREMENT, dataSet TEXT NOT NULL, organisationUnit TEXT NOT NULL, FOREIGN KEY (dataSet) REFERENCES DataSet (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (organisationUnit, dataSet)); CREATE TABLE UserOrganisationUnit (_id INTEGER PRIMARY KEY AUTOINCREMENT, user TEXT NOT NULL, organisationUnit TEXT NOT NULL, organisationUnitScope TEXT NOT NULL, root INTEGER, FOREIGN KEY (user) REFERENCES User (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (organisationUnitScope, user, organisationUnit)); CREATE TABLE RelationshipType (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, fromToName TEXT, toFromName TEXT, bidirectional INTEGER, accessDataWrite INTEGER ); -CREATE TABLE ProgramStage (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, executionDateLabel TEXT, allowGenerateNextVisit INTEGER, validCompleteOnly INTEGER, reportDateToUse TEXT, openAfterEnrollment INTEGER, repeatable INTEGER, formType TEXT, displayGenerateEventBox INTEGER, generatedByEnrollmentDate INTEGER, autoGenerateEvent INTEGER, sortOrder INTEGER, hideDueDate INTEGER, blockEntryForm INTEGER, minDaysFromStart INTEGER, standardInterval INTEGER, program TEXT NOT NULL, periodType TEXT, accessDataWrite INTEGER, remindCompleted INTEGER, description TEXT, displayDescription TEXT, featureType TEXT, color TEXT, icon TEXT, enableUserAssignment INTEGER, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE ProgramStage (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, executionDateLabel TEXT, allowGenerateNextVisit INTEGER, validCompleteOnly INTEGER, reportDateToUse TEXT, openAfterEnrollment INTEGER, repeatable INTEGER, formType TEXT, displayGenerateEventBox INTEGER, generatedByEnrollmentDate INTEGER, autoGenerateEvent INTEGER, sortOrder INTEGER, hideDueDate INTEGER, blockEntryForm INTEGER, minDaysFromStart INTEGER, standardInterval INTEGER, program TEXT NOT NULL, periodType TEXT, accessDataWrite INTEGER, remindCompleted INTEGER, description TEXT, displayDescription TEXT, featureType TEXT, color TEXT, icon TEXT, enableUserAssignment INTEGER, dueDateLabel TEXT, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); CREATE TABLE Program (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, shortName TEXT, displayShortName TEXT, description TEXT, displayDescription TEXT, version INTEGER, onlyEnrollOnce INTEGER, enrollmentDateLabel TEXT, displayIncidentDate INTEGER, incidentDateLabel TEXT, registration INTEGER, selectEnrollmentDatesInFuture INTEGER, dataEntryMethod INTEGER, ignoreOverdueEvents INTEGER, selectIncidentDatesInFuture INTEGER, useFirstStageDuringRegistration INTEGER, displayFrontPageList INTEGER, programType TEXT, relatedProgram TEXT, trackedEntityType TEXT, categoryCombo TEXT, accessDataWrite INTEGER, expiryDays INTEGER, completeEventsExpiryDays INTEGER, expiryPeriodType TEXT, minAttributesRequiredToSearch INTEGER, maxTeiCountToReturn INTEGER, featureType TEXT, accessLevel TEXT, color TEXT, icon TEXT, FOREIGN KEY (trackedEntityType) REFERENCES TrackedEntityType (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (categoryCombo) REFERENCES CategoryCombo (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); CREATE TABLE TrackedEntityInstance (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, created TEXT, lastUpdated TEXT, createdAtClient TEXT, lastUpdatedAtClient TEXT, organisationUnit TEXT, trackedEntityType TEXT, geometryType TEXT, geometryCoordinates TEXT, state TEXT, deleted INTEGER, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityType) REFERENCES TrackedEntityType (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); CREATE TABLE Enrollment (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, created TEXT, lastUpdated TEXT, createdAtClient TEXT, lastUpdatedAtClient TEXT, organisationUnit TEXT NOT NULL, program TEXT NOT NULL, enrollmentDate TEXT, incidentDate TEXT, followup INTEGER, status TEXT, trackedEntityInstance TEXT NOT NULL, state TEXT, geometryType TEXT, geometryCoordinates TEXT, deleted INTEGER, completedDate TEXT, FOREIGN KEY (organisationUnit) REFERENCES OrganisationUnit (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (program) REFERENCES Program (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY (trackedEntityInstance) REFERENCES TrackedEntityInstance (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); diff --git a/core/src/main/java/org/hisp/dhis/android/core/arch/db/access/internal/BaseDatabaseOpenHelper.java b/core/src/main/java/org/hisp/dhis/android/core/arch/db/access/internal/BaseDatabaseOpenHelper.java index dd448decb7..1dfd2092f1 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/arch/db/access/internal/BaseDatabaseOpenHelper.java +++ b/core/src/main/java/org/hisp/dhis/android/core/arch/db/access/internal/BaseDatabaseOpenHelper.java @@ -36,7 +36,7 @@ class BaseDatabaseOpenHelper { - static final int VERSION = 98; + static final int VERSION = 99; private final AssetManager assetManager; private final int targetVersion; From 46af939e89700779489dd04093674b6e24935b04 Mon Sep 17 00:00:00 2001 From: Marcos Campos Date: Thu, 20 May 2021 16:11:36 +0200 Subject: [PATCH 29/32] [ANDROSDK-1357-2] [androsdk-1357] Add dueDateLabel to ProgramStageCollectionRepository --- .../core/program/ProgramStageCollectionRepository.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/main/java/org/hisp/dhis/android/core/program/ProgramStageCollectionRepository.java b/core/src/main/java/org/hisp/dhis/android/core/program/ProgramStageCollectionRepository.java index e998add379..2d90929040 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/program/ProgramStageCollectionRepository.java +++ b/core/src/main/java/org/hisp/dhis/android/core/program/ProgramStageCollectionRepository.java @@ -73,6 +73,10 @@ public StringFilterConnector byExecutionDateLa return cf.string(Columns.EXECUTION_DATE_LABEL); } + public StringFilterConnector byDueDateLabel() { + return cf.string(Columns.DUE_DATE_LABEL); + } + public BooleanFilterConnector byAllowGenerateNextVisit() { return cf.bool(Columns.ALLOW_GENERATE_NEXT_VISIT); } From 98343430038231ce201d55fd6705cd457f3625e6 Mon Sep 17 00:00:00 2001 From: Marcos Campos Date: Thu, 20 May 2021 16:12:43 +0200 Subject: [PATCH 30/32] [ANDROSDK-1357-2] [androsdk-1357] Add dueDateLabel to tests --- .../android/core/program/CreateProgramStageUtils.java | 2 ++ ...tageCollectionRepositoryMockIntegrationShould.java | 11 +++++++++++ .../core/data/program/ProgramStageSamples.java | 1 + .../sharedTest/resources/program/program_stage.json | 1 + .../sharedTest/resources/program/program_stages.json | 2 ++ .../dhis/android/core/program/ProgramStageShould.java | 1 + 6 files changed, 18 insertions(+) diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/program/CreateProgramStageUtils.java b/core/src/androidTest/java/org/hisp/dhis/android/core/program/CreateProgramStageUtils.java index fe5c1a2ab5..f0218c238b 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/program/CreateProgramStageUtils.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/program/CreateProgramStageUtils.java @@ -40,6 +40,7 @@ public class CreateProgramStageUtils { private static final String DISPLAY_NAME = "test_display_name"; private static final String EXECUTION_DATE_LABEL = "test_executionDateLabel"; + private static final String DUE_DATE_LABEL = "test_dueDateLabel"; private static final Integer ALLOW_GENERATE_NEXT_VISIT = 0; private static final Integer VALID_COMPLETE_ONLY = 0; private static final String REPORT_DATE_TO_USE = "test_reportDateToUse"; @@ -69,6 +70,7 @@ public static ContentValues create(long id, String uid, String programId) { programStage.put(IdentifiableColumns.CREATED, DATE); programStage.put(IdentifiableColumns.LAST_UPDATED, DATE); programStage.put(ProgramStageTableInfo.Columns.EXECUTION_DATE_LABEL, EXECUTION_DATE_LABEL); + programStage.put(ProgramStageTableInfo.Columns.DUE_DATE_LABEL, DUE_DATE_LABEL); programStage.put(ProgramStageTableInfo.Columns.ALLOW_GENERATE_NEXT_VISIT, ALLOW_GENERATE_NEXT_VISIT); programStage.put(ProgramStageTableInfo.Columns.VALID_COMPLETE_ONLY, VALID_COMPLETE_ONLY); programStage.put(ProgramStageTableInfo.Columns.REPORT_DATE_TO_USE, REPORT_DATE_TO_USE); diff --git a/core/src/androidTest/java/org/hisp/dhis/android/testapp/program/ProgramStageCollectionRepositoryMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/testapp/program/ProgramStageCollectionRepositoryMockIntegrationShould.java index 4e479feae5..49717af923 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/testapp/program/ProgramStageCollectionRepositoryMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/testapp/program/ProgramStageCollectionRepositoryMockIntegrationShould.java @@ -87,6 +87,17 @@ public void filter_by_execution_date_label() { assertThat(programStages.size()).isEqualTo(1); } + @Test + public void filter_by_due_date_label() { + List programStages = + d2.programModule().programStages() + .byDueDateLabel() + .eq("Due date") + .blockingGet(); + + assertThat(programStages.size()).isEqualTo(1); + } + @Test public void filter_by_allow_generate_next_visit() { List programStages = diff --git a/core/src/sharedTest/java/org/hisp/dhis/android/core/data/program/ProgramStageSamples.java b/core/src/sharedTest/java/org/hisp/dhis/android/core/data/program/ProgramStageSamples.java index b112f51a00..51b31e2bca 100644 --- a/core/src/sharedTest/java/org/hisp/dhis/android/core/data/program/ProgramStageSamples.java +++ b/core/src/sharedTest/java/org/hisp/dhis/android/core/data/program/ProgramStageSamples.java @@ -51,6 +51,7 @@ public static ProgramStage getProgramStage() { .description("description") .displayDescription("display_description") .executionDateLabel("execution_date_label") + .dueDateLabel("due_date_label") .allowGenerateNextVisit(Boolean.FALSE) .validCompleteOnly(Boolean.TRUE) .reportDateToUse("report_date_to_use") diff --git a/core/src/sharedTest/resources/program/program_stage.json b/core/src/sharedTest/resources/program/program_stage.json index b04ea17db7..8a1f35a98b 100644 --- a/core/src/sharedTest/resources/program/program_stage.json +++ b/core/src/sharedTest/resources/program/program_stage.json @@ -17,6 +17,7 @@ "enableUserAssignment": "true", "captureCoordinates": true, "formType": "DEFAULT", + "dueDateLabel": "Due date", "remindCompleted": false, "displayGenerateEventBox": false, "generatedByEnrollmentDate": false, diff --git a/core/src/sharedTest/resources/program/program_stages.json b/core/src/sharedTest/resources/program/program_stages.json index 36604f64f0..d0a3c3eb27 100644 --- a/core/src/sharedTest/resources/program/program_stages.json +++ b/core/src/sharedTest/resources/program/program_stages.json @@ -9,6 +9,7 @@ "displayDescription": "Display Description", "allowGenerateNextVisit": false, "executionDateLabel": "Visit date", + "dueDateLabel": "Due date", "validCompleteOnly": true, "displayName": "Antenatal care visit - Program rules demo", "openAfterEnrollment": false, @@ -193,6 +194,7 @@ "name": "Child care visit - demo", "allowGenerateNextVisit": true, "executionDateLabel": "Visit date 2", + "dueDateLabel": "Due date 2", "validCompleteOnly": false, "displayName": "Antenatal care visit - Program rules demo", "openAfterEnrollment": true, diff --git a/core/src/test/java/org/hisp/dhis/android/core/program/ProgramStageShould.java b/core/src/test/java/org/hisp/dhis/android/core/program/ProgramStageShould.java index 1412fc990c..dbd77a57d5 100644 --- a/core/src/test/java/org/hisp/dhis/android/core/program/ProgramStageShould.java +++ b/core/src/test/java/org/hisp/dhis/android/core/program/ProgramStageShould.java @@ -70,6 +70,7 @@ public void map_from_json_string() throws IOException, ParseException { assertThat(programStage.captureCoordinates()).isTrue(); assertThat(programStage.displayGenerateEventBox()).isFalse(); assertThat(programStage.executionDateLabel()).isNull(); + assertThat(programStage.dueDateLabel()).isEqualTo("Due date"); assertThat(programStage.formType()).isEqualTo(FormType.DEFAULT); assertThat(programStage.generatedByEnrollmentDate()).isFalse(); assertThat(programStage.hideDueDate()).isFalse(); From 51116e357bb4e3e584a19f63d6f5f73649020ad0 Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Mon, 7 Jun 2021 15:13:44 +0200 Subject: [PATCH 31/32] [MASTER-DEV] [RELEASE-1.4.1] Version 1.4.1 --- core/build.gradle | 4 ++-- core/gradle.properties | 4 ++-- docs/content/developer/getting-started.md | 2 +- docs/dhis2_android_sdk_developer_guide_INDEX.md | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/build.gradle b/core/build.gradle index 6bb079b2a0..4e6ad95fd3 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -43,8 +43,8 @@ ext { buildToolsVersion: "29.0.3", minSdkVersion : 19, targetSdkVersion : 29, - versionCode : 240, - versionName : "1.4.0" + versionCode : 241, + versionName : "1.4.1" ] libraries = [ diff --git a/core/gradle.properties b/core/gradle.properties index 888c4b4e0e..339527049f 100644 --- a/core/gradle.properties +++ b/core/gradle.properties @@ -29,8 +29,8 @@ # Properties which are consumed by plugins/gradle-mvn-push.gradle plugin. # They are used for publishing artifact to snapshot repository. -VERSION_NAME=1.4.0 -VERSION_CODE=240 +VERSION_NAME=1.4.1 +VERSION_CODE=241 GROUP=org.hisp.dhis diff --git a/docs/content/developer/getting-started.md b/docs/content/developer/getting-started.md index 68534a3711..59be23b9fe 100644 --- a/docs/content/developer/getting-started.md +++ b/docs/content/developer/getting-started.md @@ -6,7 +6,7 @@ Include dependency in build.gradle. ```gradle dependencies { - implementation "org.hisp.dhis:android-core:1.4.0" + implementation "org.hisp.dhis:android-core:1.4.1" ... } ``` diff --git a/docs/dhis2_android_sdk_developer_guide_INDEX.md b/docs/dhis2_android_sdk_developer_guide_INDEX.md index 82f40e822e..770554bf77 100644 --- a/docs/dhis2_android_sdk_developer_guide_INDEX.md +++ b/docs/dhis2_android_sdk_developer_guide_INDEX.md @@ -3,11 +3,11 @@ title: 'DHIS 2 Android SDK Developer Guide' author: 'DHIS 2' date: year: 2021 -month: April +month: June keywords: [DHIS2, Android] commit: version: master -applicable_txt: 'Applicable to version 1.4.0' +applicable_txt: 'Applicable to version 1.4.1' --- From aa392abc2c0c917d657d8a67db0559e0fcfca569 Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Wed, 9 Jun 2021 15:59:18 +0200 Subject: [PATCH 32/32] fix: [ANDROSDK-1391] Download token using IO scheduler --- .../android/core/user/openid/OpenIDConnectHandlerImpl.kt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/hisp/dhis/android/core/user/openid/OpenIDConnectHandlerImpl.kt b/core/src/main/java/org/hisp/dhis/android/core/user/openid/OpenIDConnectHandlerImpl.kt index 267cc4fa87..afdff166eb 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/user/openid/OpenIDConnectHandlerImpl.kt +++ b/core/src/main/java/org/hisp/dhis/android/core/user/openid/OpenIDConnectHandlerImpl.kt @@ -33,6 +33,7 @@ import android.content.Intent import dagger.Reusable import io.reactivex.Observable import io.reactivex.Single +import io.reactivex.schedulers.Schedulers import javax.inject.Inject import net.openid.appauth.* import org.hisp.dhis.android.core.user.User @@ -71,9 +72,11 @@ internal class OpenIDConnectHandlerImpl @Inject constructor( Single.error(ex) } else { val response = AuthorizationResponse.fromIntent(intent)!! - downloadToken(response.createTokenExchangeRequest()).map { - logInCall.blockingLogInOpenIDConnect(serverUrl, it) - } + downloadToken(response.createTokenExchangeRequest()) + .observeOn(Schedulers.io()) + .map { + logInCall.blockingLogInOpenIDConnect(serverUrl, it) + } } } else { Single.error(RuntimeException("Unexpected intent or request code"))