From ee6047f1869cb72f8f795ac7216fddbcbeba6b53 Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Thu, 20 Jun 2019 09:23:54 +0200 Subject: [PATCH 01/11] [ANDROSDK-856] Add test showing NPE on ProgramIndicatorEngine --- .../ProgramIndicatorEngineShould.java | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/core/src/test/java/org/hisp/dhis/android/core/utils/services/ProgramIndicatorEngineShould.java b/core/src/test/java/org/hisp/dhis/android/core/utils/services/ProgramIndicatorEngineShould.java index 48f00d10e5..849f5cdd19 100644 --- a/core/src/test/java/org/hisp/dhis/android/core/utils/services/ProgramIndicatorEngineShould.java +++ b/core/src/test/java/org/hisp/dhis/android/core/utils/services/ProgramIndicatorEngineShould.java @@ -222,7 +222,7 @@ public void setUp() throws Exception { } @Test - public void parse_static_value() throws Exception { + public void parse_static_value() { when(programIndicator.expression()).thenReturn("5 * 10"); String result = programIndicatorEngine.parseIndicatorExpression(enrollmentUid, null, @@ -232,7 +232,7 @@ public void parse_static_value() throws Exception { } @Test - public void parse_one_dataelement() throws Exception { + public void parse_one_dataelement() { when(programIndicator.expression()).thenReturn(de(programStageUid1, dataElementUid1)); when(value1.value()).thenReturn("3.5"); @@ -243,7 +243,7 @@ public void parse_one_dataelement() throws Exception { } @Test - public void parse_one_text_dataelement() throws Exception { + public void parse_one_text_dataelement() { when(programIndicator.expression()).thenReturn(de(programStageUid1, dataElementUid1)); when(value1.value()).thenReturn("text data-value"); @@ -254,7 +254,7 @@ public void parse_one_text_dataelement() throws Exception { } @Test - public void parse_operation_two_dataelements() throws Exception { + public void parse_operation_two_dataelements() { when(programIndicator.expression()).thenReturn( de(programStageUid1, dataElementUid1) + " + " + de(programStageUid1, dataElementUid2)); @@ -267,7 +267,7 @@ public void parse_operation_two_dataelements() throws Exception { } @Test - public void parse_operation_two_mixed_dataelements() throws Exception { + public void parse_operation_two_mixed_dataelements() { when(programIndicator.expression()).thenReturn( de(programStageUid1, dataElementUid1) + " + " + de(programStageUid1, dataElementUid2)); @@ -280,7 +280,7 @@ public void parse_operation_two_mixed_dataelements() throws Exception { } @Test - public void parse_operation_with_parenthesis() throws Exception { + public void parse_operation_with_parenthesis() { when(programIndicator.expression()).thenReturn( "(" + de(programStageUid1, dataElementUid1) + " + " + de(programStageUid1, dataElementUid2) + ") / " + de(programStageUid1, dataElementUid3)); @@ -295,7 +295,7 @@ public void parse_operation_with_parenthesis() throws Exception { } @Test - public void parse_dataelement_and_constant() throws Exception { + public void parse_dataelement_and_constant() { when(programIndicator.expression()).thenReturn( de(programStageUid1, dataElementUid1) + " + " + cons(constantUid1)); @@ -332,7 +332,7 @@ public void parse_incident_date_variable() throws Exception { } @Test - public void parse_enrollment_status_variable() throws Exception { + public void parse_enrollment_status_variable() { when(programIndicator.expression()).thenReturn(var("enrollment_status")); when(enrollment.status()).thenReturn(EnrollmentStatus.ACTIVE); @@ -367,7 +367,7 @@ public void parse_due_date_variable() throws Exception { } @Test - public void parse_event_count_variable() throws Exception { + public void parse_event_count_variable() { when(programIndicator.expression()).thenReturn(var("event_count")); String result = programIndicatorEngine.parseIndicatorExpression(enrollmentUid, eventUid1, programIndicatorUid); @@ -376,7 +376,7 @@ public void parse_event_count_variable() throws Exception { } @Test - public void parse_value_count_variable() throws Exception { + public void parse_value_count_variable() { when(programIndicator.expression()).thenReturn( "(" + de(programStageUid1, dataElementUid1) + " + " + de(programStageUid1, dataElementUid2) + ") / " + var("value_count")); @@ -452,7 +452,7 @@ public void ignore_values_from_non_existing_events() { } @Test - public void parse_operation_with_zero_values() throws Exception { + public void parse_operation_with_zero_values() { when(programIndicator.expression()).thenReturn( de(programStageUid2, dataElementUid2) + " * 10"); @@ -467,7 +467,7 @@ public void parse_operation_with_zero_values() throws Exception { } @Test - public void parse_last_aggregation_type() throws Exception { + public void parse_last_aggregation_type() { when(programIndicator.expression()).thenReturn( de(programStageUid2, dataElementUid4) + " * 10"); @@ -487,6 +487,20 @@ public void parse_last_aggregation_type() throws Exception { assertThat(lastResult).isEqualTo("4 * 10"); } + @Test + public void default_to_none_on_null_aggregation_type() { + when(programIndicator.expression()).thenReturn(de(programStageUid1, dataElementUid1)); + + when(value1.value()).thenReturn("10"); + + when(programIndicator.aggregationType()).thenReturn(null); + String sumResult = programIndicatorEngine.parseIndicatorExpression(enrollmentUid, null, + programIndicatorUid); + + assertThat(sumResult).isEqualTo("10"); + } + + // ------------------------------------------------------------------------- // Supportive methods // ------------------------------------------------------------------------- From 569f68ea4a4b087ca27e8a385851735b0f7ef499 Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Thu, 20 Jun 2019 09:30:10 +0200 Subject: [PATCH 02/11] [ANDROSDK-856] Handle empty AggregationType on ProgramIndicator --- .../org/hisp/dhis/android/core/program/ProgramIndicator.java | 5 +++-- .../android/core/utils/services/ProgramIndicatorEngine.java | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/hisp/dhis/android/core/program/ProgramIndicator.java b/core/src/main/java/org/hisp/dhis/android/core/program/ProgramIndicator.java index d73c2fa42e..425507d8dc 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/program/ProgramIndicator.java +++ b/core/src/main/java/org/hisp/dhis/android/core/program/ProgramIndicator.java @@ -49,7 +49,7 @@ import java.util.List; @AutoValue -@JsonDeserialize(builder = AutoValue_ProgramIndicator.Builder.class) +@JsonDeserialize(builder = $$AutoValue_ProgramIndicator.Builder.class) public abstract class ProgramIndicator extends BaseNameableObject implements Model { @Nullable @@ -94,7 +94,8 @@ public static ProgramIndicator create(Cursor cursor) { public abstract Builder toBuilder(); public static Builder builder() { - return new AutoValue_ProgramIndicator.Builder(); + return new $$AutoValue_ProgramIndicator.Builder() + .aggregationType(AggregationType.NONE); } @AutoValue.Builder diff --git a/core/src/main/java/org/hisp/dhis/android/core/utils/services/ProgramIndicatorEngine.java b/core/src/main/java/org/hisp/dhis/android/core/utils/services/ProgramIndicatorEngine.java index 867be96618..6d41c4f2a9 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/utils/services/ProgramIndicatorEngine.java +++ b/core/src/main/java/org/hisp/dhis/android/core/utils/services/ProgramIndicatorEngine.java @@ -353,8 +353,8 @@ private TrackedEntityDataValue evaluateDataElementInStage(String deId, if (candidates.isEmpty()) { return null; - } else if (aggregationType.equals(AggregationType.LAST) || - aggregationType.equals(AggregationType.LAST_AVERAGE_ORG_UNIT)) { + } else if (AggregationType.LAST.equals(aggregationType) || + AggregationType.LAST_AVERAGE_ORG_UNIT.equals(aggregationType)) { return candidates.get(candidates.size() - 1); } else { return candidates.get(0); From 24c572c02482d924643743b548344c6b13008f72 Mon Sep 17 00:00:00 2001 From: Luis Delgado Romera Date: Mon, 17 Jun 2019 13:38:50 +0200 Subject: [PATCH 03/11] [HOTBUGFIXING] [PERIOD-TIME-DEPENDENT-FIX] Fix time-dependent test --- .../dhis/android/core/period/PeriodMockIntegrationShould.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/period/PeriodMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/period/PeriodMockIntegrationShould.java index 6366de4ecc..b414f5faed 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/period/PeriodMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/period/PeriodMockIntegrationShould.java @@ -45,7 +45,7 @@ public class PeriodMockIntegrationShould extends BaseMockIntegrationTestFullDisp @Test public void get_period_passing_period_type_and_a_date() throws ParseException { Period period = d2.periodModule().periodHelper.getPeriod(PeriodType.BiWeekly, - BaseIdentifiableObject.DATE_FORMAT.parse("2018-12-24T12:24:25.319")); - assertThat(period.periodId(), is("2018BiW26")); + BaseIdentifiableObject.DATE_FORMAT.parse("2019-06-24T12:24:25.319")); + assertThat(period.periodId(), is("2019BiW13")); } } \ No newline at end of file From 36ef967cc6a2ecace7922769f32d981046a7e6df Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Fri, 21 Jun 2019 13:09:06 +0200 Subject: [PATCH 04/11] [ANDROSDK-855] Use only capture orgunits in TEI download --- ...kedEntityInstanceWithLimitCallFactory.java | 42 +++++++++++-------- .../user/UserOrganisationUnitLinkStore.java | 3 ++ .../UserOrganisationUnitLinkStoreImpl.java | 10 +++++ 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/core/src/main/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstanceWithLimitCallFactory.java b/core/src/main/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstanceWithLimitCallFactory.java index cbcecdfbe7..8dced64cff 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstanceWithLimitCallFactory.java +++ b/core/src/main/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstanceWithLimitCallFactory.java @@ -33,16 +33,17 @@ import org.hisp.dhis.android.core.arch.call.D2CallWithProgressImpl; import org.hisp.dhis.android.core.arch.call.D2Progress; import org.hisp.dhis.android.core.arch.call.D2ProgressManager; +import org.hisp.dhis.android.core.arch.db.WhereClauseBuilder; import org.hisp.dhis.android.core.arch.repositories.collection.ReadOnlyWithDownloadObjectRepository; import org.hisp.dhis.android.core.common.LinkModelStore; import org.hisp.dhis.android.core.data.api.OuMode; import org.hisp.dhis.android.core.organisationunit.OrganisationUnit; import org.hisp.dhis.android.core.organisationunit.OrganisationUnitProgramLink; +import org.hisp.dhis.android.core.organisationunit.OrganisationUnitProgramLinkTableInfo; import org.hisp.dhis.android.core.resource.Resource; import org.hisp.dhis.android.core.resource.ResourceHandler; import org.hisp.dhis.android.core.systeminfo.DHISVersionManager; import org.hisp.dhis.android.core.systeminfo.SystemInfo; -import org.hisp.dhis.android.core.user.UserOrganisationUnitLink; import org.hisp.dhis.android.core.user.UserOrganisationUnitLinkStore; import org.hisp.dhis.android.core.utils.services.ApiPagingEngine; import org.hisp.dhis.android.core.utils.services.Paging; @@ -165,35 +166,38 @@ private List getTeiQueryBuilders(boolean limitByOrgUnit, boole List builders = new ArrayList<>(); if (limitByOrgUnit) { + List captureOrgUnitUids = getCaptureOrgUnitUids(); if (limitByProgram) { - for (OrganisationUnitProgramLink link : organisationUnitProgramLinkStore.selectAll()) { + for (OrganisationUnitProgramLink link : + getOrganisationUnitProgramLinksByOrgunitUids(captureOrgUnitUids)) { builders.add(getTeiBuilderForOrgUnit(lastUpdated, link.organisationUnit()).program(link.program())); } } else { - for (String orgUnitUid: getOrgUnitUids()) { + for (String orgUnitUid : captureOrgUnitUids) { builders.add(getTeiBuilderForOrgUnit(lastUpdated, orgUnitUid)); } } } else { + List rootCaptureOrgUnitUids = getRootCaptureOrgUnitUids(); if (limitByProgram) { Set programs = new HashSet<>(); for (OrganisationUnitProgramLink link : organisationUnitProgramLinkStore.selectAll()) { programs.add(link.program()); } for (String program : programs) { - builders.add(getTeiBuilderForRoot(lastUpdated).program(program)); + builders.add(getTeiBuilderForRootOrgunits(lastUpdated, rootCaptureOrgUnitUids).program(program)); } } else { - builders.add(getTeiBuilderForRoot(lastUpdated)); + builders.add(getTeiBuilderForRootOrgunits(lastUpdated, rootCaptureOrgUnitUids)); } } return builders; } - private TeiQuery.Builder getTeiBuilderForRoot(String lastUpdated) { + private TeiQuery.Builder getTeiBuilderForRootOrgunits(String lastUpdated, List rootOrgunitUids) { return TeiQuery.builder() .lastUpdatedStartDate(lastUpdated) - .orgUnits(userOrganisationUnitLinkStore.queryRootCaptureOrganisationUnitUids()) + .orgUnits(rootOrgunitUids) .ouMode(OuMode.DESCENDANTS); } @@ -236,19 +240,21 @@ private List limitTeisForPage(List } } - private Set getOrgUnitUids() { - List userOrganisationUnitLinks = userOrganisationUnitLinkStore.selectAll(); - - Set organisationUnitUids = new HashSet<>(); + private List getRootCaptureOrgUnitUids() { + return userOrganisationUnitLinkStore.queryRootCaptureOrganisationUnitUids(); + } - for (UserOrganisationUnitLink userOrganisationUnitLink : userOrganisationUnitLinks) { - if (userOrganisationUnitLink.organisationUnitScope().equals( - OrganisationUnit.Scope.SCOPE_DATA_CAPTURE.name())) { - organisationUnitUids.add(userOrganisationUnitLink.organisationUnit()); - } - } + private List getCaptureOrgUnitUids() { + return userOrganisationUnitLinkStore + .queryOrganisationUnitUidsByScope(OrganisationUnit.Scope.SCOPE_DATA_CAPTURE); + } - return organisationUnitUids; + private List getOrganisationUnitProgramLinksByOrgunitUids(List uids) { + return organisationUnitProgramLinkStore.selectWhere( + new WhereClauseBuilder().appendInKeyStringValues( + OrganisationUnitProgramLinkTableInfo.Columns.ORGANISATION_UNIT, + uids + ).build()); } private Observable updateResource(D2ProgressManager progressManager, BooleanWrapper allOkay) { diff --git a/core/src/main/java/org/hisp/dhis/android/core/user/UserOrganisationUnitLinkStore.java b/core/src/main/java/org/hisp/dhis/android/core/user/UserOrganisationUnitLinkStore.java index 0834cec29d..b2e28252e1 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/user/UserOrganisationUnitLinkStore.java +++ b/core/src/main/java/org/hisp/dhis/android/core/user/UserOrganisationUnitLinkStore.java @@ -29,10 +29,13 @@ package org.hisp.dhis.android.core.user; import org.hisp.dhis.android.core.common.LinkModelStore; +import org.hisp.dhis.android.core.organisationunit.OrganisationUnit; import java.util.List; public interface UserOrganisationUnitLinkStore extends LinkModelStore { List queryRootCaptureOrganisationUnitUids() throws RuntimeException; + + List queryOrganisationUnitUidsByScope(OrganisationUnit.Scope scope); } \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/user/UserOrganisationUnitLinkStoreImpl.java b/core/src/main/java/org/hisp/dhis/android/core/user/UserOrganisationUnitLinkStoreImpl.java index fda0cdeddf..31d748f64b 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/user/UserOrganisationUnitLinkStoreImpl.java +++ b/core/src/main/java/org/hisp/dhis/android/core/user/UserOrganisationUnitLinkStoreImpl.java @@ -30,6 +30,7 @@ import android.database.sqlite.SQLiteStatement; +import org.hisp.dhis.android.core.arch.db.WhereClauseBuilder; import org.hisp.dhis.android.core.arch.db.binders.StatementBinder; import org.hisp.dhis.android.core.common.LinkModelStoreImpl; import org.hisp.dhis.android.core.common.SQLStatementBuilder; @@ -77,4 +78,13 @@ public List queryRootCaptureOrganisationUnitUids() throws RuntimeExcepti + Columns.ORGANISATION_UNIT_SCOPE + " = '" + OrganisationUnit.Scope.SCOPE_DATA_CAPTURE + "'"); } + + @Override + public List queryOrganisationUnitUidsByScope(OrganisationUnit.Scope scope) { + return selectStringColumnsWhereClause(Columns.ORGANISATION_UNIT, + new WhereClauseBuilder().appendKeyStringValue( + Columns.ORGANISATION_UNIT_SCOPE, + scope.name() + ).build()); + } } \ No newline at end of file From 512ae83503b6e93eb40fb146a530f9ce7b85cfbd Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Fri, 21 Jun 2019 19:32:09 +0200 Subject: [PATCH 05/11] [ANDROSDK-869] Create OrganisationUnitQuery --- .../OrganisationUnitCallFactory.java | 18 ++++-- .../OrganisationUnitQuery.java | 58 +++++++++++++++++++ 2 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitQuery.java diff --git a/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallFactory.java b/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallFactory.java index 5d9d6ff34a..f21d81f336 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallFactory.java +++ b/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallFactory.java @@ -136,16 +136,26 @@ private Set downloadSearchOrgunits(final User user, private Set downloadOrgunits(Set orguntis) throws D2Error { Set organisationUnits = new HashSet<>(); for (String uid : orguntis) { - organisationUnits.addAll(apiCallExecutor.executePayloadCall( - getOrganisationUnitAndDescendants(uid))); + OrganisationUnitQuery.Builder queryBuilder = OrganisationUnitQuery.builder().orgUnit(uid); + + List pageOrgunits; + OrganisationUnitQuery pageQuery; + do { + pageQuery = queryBuilder.build(); + pageOrgunits = apiCallExecutor.executePayloadCall(getOrganisationUnitAndDescendants(pageQuery)); + organisationUnits.addAll(pageOrgunits); + + queryBuilder.page(pageQuery.page() + 1); + } + while (pageOrgunits.size() == pageQuery.pageSize()); } return organisationUnits; } - private retrofit2.Call> getOrganisationUnitAndDescendants(@NonNull String uid) { + private retrofit2.Call> getOrganisationUnitAndDescendants(OrganisationUnitQuery query) { return organisationUnitService.getOrganisationUnitWithDescendants( - uid, OrganisationUnitFields.allFields, true, false); + query.orgUnit(), OrganisationUnitFields.allFields, true, false); } private Set getLinkedPrograms(Set capture, @NonNull Set programUids) { diff --git a/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitQuery.java b/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitQuery.java new file mode 100644 index 0000000000..80f655a11e --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitQuery.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2004-2019, 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.organisationunit; + +import androidx.annotation.Nullable; + +import com.google.auto.value.AutoValue; + +import org.hisp.dhis.android.core.common.BaseQuery; + +@AutoValue +abstract class OrganisationUnitQuery extends BaseQuery { + + private static int DEFAULT_PAGE_SIZE = 500; + + @Nullable + public abstract String orgUnit(); + + public static Builder builder() { + return new AutoValue_OrganisationUnitQuery.Builder() + .page(1) + .pageSize(DEFAULT_PAGE_SIZE) + .paging(true); + } + + @AutoValue.Builder + public abstract static class Builder extends BaseQuery.Builder { + public abstract Builder orgUnit(String orgUnit); + + public abstract OrganisationUnitQuery build(); + } +} From 555b2553686cd52af1fa1d8f0fd0b848650cd45a Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Fri, 21 Jun 2019 19:48:07 +0200 Subject: [PATCH 06/11] [ANDROSDK-869] Modify OrganisationUnitService --- .../OrganisationUnitCallFactory.java | 3 +- .../OrganisationUnitService.java | 29 +++++++++++++------ .../OrganisationUnitCallUnitShould.java | 12 ++++++-- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallFactory.java b/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallFactory.java index f21d81f336..da546826bc 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallFactory.java +++ b/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallFactory.java @@ -155,7 +155,8 @@ private Set downloadOrgunits(Set orguntis) throws D2Er private retrofit2.Call> getOrganisationUnitAndDescendants(OrganisationUnitQuery query) { return organisationUnitService.getOrganisationUnitWithDescendants( - query.orgUnit(), OrganisationUnitFields.allFields, true, false); + query.orgUnit(), OrganisationUnitFields.allFields, true, + query.paging(), query.pageSize(), query.page()); } private Set getLinkedPrograms(Set capture, @NonNull Set programUids) { diff --git a/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitService.java b/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitService.java index db87ba92ac..9acf683c81 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitService.java +++ b/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitService.java @@ -39,19 +39,30 @@ import retrofit2.http.Query; interface OrganisationUnitService { + String ORGANISATION_UNITS = "organisationUnits"; - @GET("organisationUnits/{uid}") + String UID = "uid"; + String FIELDS = "fields"; + String FILTER = "filter"; + String INCLUDE_DESCENDANTS = "includeDescendants"; + String PAGING = "paging"; + String PAGE = "page"; + String PAGE_SIZE = "pageSize"; + + @GET(ORGANISATION_UNITS + "/{uid}") Call> getOrganisationUnitWithDescendants( - @Path("uid") String organisationUnitUid, - @Query("fields") @Which Fields fields, - @Query("includeDescendants") Boolean descendants, - @Query("paging") Boolean paging + @Path(UID) String organisationUnitUid, + @Query(FIELDS) @Which Fields fields, + @Query(INCLUDE_DESCENDANTS) Boolean descendants, + @Query(PAGING) Boolean paging, + @Query(PAGE_SIZE) Integer pageSize, + @Query(PAGE) Integer page ); - @GET("organisationUnits") + @GET(ORGANISATION_UNITS) Call> getSearchOrganisationUnits( - @Query("fields") @Which Fields fields, - @Query("filter") @Where Filter filter, - @Query("paging") Boolean paging + @Query(FIELDS) @Which Fields fields, + @Query(FILTER) @Where Filter filter, + @Query(PAGING) Boolean paging ); } \ No newline at end of file diff --git a/core/src/test/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallUnitShould.java b/core/src/test/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallUnitShould.java index 34720ae5f2..665aba2847 100644 --- a/core/src/test/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallUnitShould.java +++ b/core/src/test/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallUnitShould.java @@ -94,6 +94,12 @@ public class OrganisationUnitCallUnitShould { @Captor private ArgumentCaptor pagingCaptor; + @Captor + private ArgumentCaptor pageCaptor; + + @Captor + private ArgumentCaptor pageSizeCaptor; + @Mock private OrganisationUnit organisationUnit; @@ -188,7 +194,8 @@ public void setUp() throws IOException { when(user.organisationUnits()).thenReturn(new ArrayList<>(organisationUnits)); when(organisationUnitService.getOrganisationUnitWithDescendants( - uidCaptor.capture(), fieldsCaptor.capture(), descendantsCaptor.capture(), pagingCaptor.capture() + uidCaptor.capture(), fieldsCaptor.capture(), descendantsCaptor.capture(), pagingCaptor.capture(), + pageSizeCaptor.capture(), pageCaptor.capture() )).thenReturn(retrofitCall); when(genericCallData.resourceHandler()).thenReturn(resourceHandler); @@ -208,7 +215,8 @@ public void invoke_server_with_correct_parameters() throws Exception { assertThat(uidCaptor.getValue()).isEqualTo(organisationUnit.uid()); assertThat(fieldsCaptor.getValue()).isEqualTo(OrganisationUnitFields.allFields); assertThat(descendantsCaptor.getValue()).isTrue(); - assertThat(pagingCaptor.getValue()).isFalse(); + assertThat(pagingCaptor.getValue()).isTrue(); + assertThat(pageCaptor.getValue()).isEqualTo(1); } @Test From 89a193b161ca9c890d9bbbd2253b4fd0f239625e Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Thu, 20 Jun 2019 09:07:48 +0200 Subject: [PATCH 07/11] [ANDROSDK-872] Add test showing the failure in ProgramIndicatorEngine --- .../ProgramIndicatorEngineIntegrationShould.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/utils/services/ProgramIndicatorEngineIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/utils/services/ProgramIndicatorEngineIntegrationShould.java index 600ab32dc0..1b5cb3530a 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/utils/services/ProgramIndicatorEngineIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/utils/services/ProgramIndicatorEngineIntegrationShould.java @@ -201,6 +201,20 @@ public void evaluate_addition_two_dataelement() { assertThat(result).isEqualTo("15"); } + @Test + public void evaluate_division_two_dataelement() { + createEnrollment(null, null); + createEvent(event1, programStage1, null); + insertTrackedEntityDataValue(event1, dataElement1, "3"); + insertTrackedEntityDataValue(event1, dataElement2, "5"); + + setProgramIndicatorExpressionAsAverage(de(programStage1,dataElement1) + " / " + de(programStage1,dataElement2)); + + String result = programIndicatorEngine.getProgramIndicatorValue(enrollmentUid, event1, programIndicatorUid); + + assertThat(result).isEqualTo("0.6"); + } + @Test public void evaluate_last_value_indicators_different_dates() { createEnrollment(null, null); From 6c73ad3fcd2f8d1e4de1e8ee279d7dd73ea22117 Mon Sep 17 00:00:00 2001 From: Abel Castro Date: Sun, 23 Jun 2019 17:14:03 +0200 Subject: [PATCH 08/11] [ANDROSDK-872] Modify ProgramIndicatorEngine to treat all numeric values as double by default --- .../services/ProgramIndicatorEngine.java | 26 ++++++++++++------- .../ProgramIndicatorEngineShould.java | 18 ++++++------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/org/hisp/dhis/android/core/utils/services/ProgramIndicatorEngine.java b/core/src/main/java/org/hisp/dhis/android/core/utils/services/ProgramIndicatorEngine.java index 6d41c4f2a9..017c902396 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/utils/services/ProgramIndicatorEngine.java +++ b/core/src/main/java/org/hisp/dhis/android/core/utils/services/ProgramIndicatorEngine.java @@ -362,18 +362,24 @@ private TrackedEntityDataValue evaluateDataElementInStage(String deId, } private String formatDataValue(TrackedEntityDataValue dataValue) { - if (dataElementStore.selectByUid(dataValue.dataElement()) - .valueType() == ValueType.BOOLEAN) { - if (dataValue.value().equals("true")) { - return "1"; - } else { - return "0"; + + DataElement dataElement = dataElementStore.selectByUid(dataValue.dataElement()); + + if (dataElement.valueType() == ValueType.BOOLEAN) { + return dataValue.value().equals("true") ? "1" : "0"; + } + + if (MathUtils.isNumeric(dataValue.value())) { + if (dataValue.value().endsWith(".")) { + return (dataValue.value() + "0"); + } + + if (!dataValue.value().contains(".")) { + return (dataValue.value() + ".0"); } - } else if (dataValue.value().endsWith(".")) { - return (dataValue.value() + "0"); - } else { - return dataValue.value(); } + + return dataValue.value(); } private static boolean isZeroOrPositive(String value) { diff --git a/core/src/test/java/org/hisp/dhis/android/core/utils/services/ProgramIndicatorEngineShould.java b/core/src/test/java/org/hisp/dhis/android/core/utils/services/ProgramIndicatorEngineShould.java index 849f5cdd19..1deaa29923 100644 --- a/core/src/test/java/org/hisp/dhis/android/core/utils/services/ProgramIndicatorEngineShould.java +++ b/core/src/test/java/org/hisp/dhis/android/core/utils/services/ProgramIndicatorEngineShould.java @@ -263,7 +263,7 @@ public void parse_operation_two_dataelements() { String result = programIndicatorEngine.parseIndicatorExpression(null, eventUid1, programIndicatorUid); - assertThat(result).isEqualTo("3.5 + 2"); + assertThat(result).isEqualTo("3.5 + 2.0"); } @Test @@ -291,7 +291,7 @@ public void parse_operation_with_parenthesis() { String result = programIndicatorEngine.parseIndicatorExpression(null, eventUid1, programIndicatorUid); - assertThat(result).isEqualTo("(2.5 + 2) / 1.5"); + assertThat(result).isEqualTo("(2.5 + 2.0) / 1.5"); } @Test @@ -386,7 +386,7 @@ public void parse_value_count_variable() { String result = programIndicatorEngine.parseIndicatorExpression(null, eventUid1, programIndicatorUid); - assertThat(result).isEqualTo("(3.5 + 2) / 2"); + assertThat(result).isEqualTo("(3.5 + 2.0) / 2"); } @Test @@ -426,9 +426,9 @@ public void parse_values_from_different_program_stage_instances() { String resultWithEvent2 = programIndicatorEngine.parseIndicatorExpression(enrollmentUid, eventUid2_1, programIndicatorUid); - assertThat(resultWithoutEvent).isEqualTo("3.5 + 2"); - assertThat(resultWithEvent1).isEqualTo("3.5 + 2"); - assertThat(resultWithEvent2).isEqualTo("3.5 + 2"); + assertThat(resultWithoutEvent).isEqualTo("3.5 + 2.0"); + assertThat(resultWithEvent1).isEqualTo("3.5 + 2.0"); + assertThat(resultWithEvent2).isEqualTo("3.5 + 2.0"); } @Test @@ -478,13 +478,13 @@ public void parse_last_aggregation_type() { String sumResult = programIndicatorEngine.parseIndicatorExpression(enrollmentUid, null, programIndicatorUid); - assertThat(sumResult).isEqualTo("2 * 10"); + assertThat(sumResult).isEqualTo("2.0 * 10"); when(programIndicator.aggregationType()).thenReturn(AggregationType.LAST); String lastResult = programIndicatorEngine.parseIndicatorExpression(enrollmentUid, null, programIndicatorUid); - assertThat(lastResult).isEqualTo("4 * 10"); + assertThat(lastResult).isEqualTo("4.0 * 10"); } @Test @@ -497,7 +497,7 @@ public void default_to_none_on_null_aggregation_type() { String sumResult = programIndicatorEngine.parseIndicatorExpression(enrollmentUid, null, programIndicatorUid); - assertThat(sumResult).isEqualTo("10"); + assertThat(sumResult).isEqualTo("10.0"); } From 288ebdeffa833db33c00116117e9b310513e2f2d Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Sun, 23 Jun 2019 18:44:07 +0200 Subject: [PATCH 09/11] [ANDROSDK-869] Use path instead of descendants --- .../dhis/android/core/data/api/Field.java | 4 ++++ .../core/data/api/SingleValueFilter.java | 4 ++++ .../OrganisationUnitCallFactory.java | 4 ++-- .../OrganisationUnitFields.java | 2 +- .../OrganisationUnitService.java | 8 +++----- .../OrganisationUnitCallUnitShould.java | 20 +++++++------------ 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/core/src/main/java/org/hisp/dhis/android/core/data/api/Field.java b/core/src/main/java/org/hisp/dhis/android/core/data/api/Field.java index 5bace41223..390e02450f 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/data/api/Field.java +++ b/core/src/main/java/org/hisp/dhis/android/core/data/api/Field.java @@ -47,6 +47,10 @@ public Filter gt(String value) { return SingleValueFilter.gt(this, value); } + public Filter like(String value) { + return SingleValueFilter.like(this, value); + } + public Filter in(Collection values) { return InFilter.create(this, values); } diff --git a/core/src/main/java/org/hisp/dhis/android/core/data/api/SingleValueFilter.java b/core/src/main/java/org/hisp/dhis/android/core/data/api/SingleValueFilter.java index 5e61bc0ca4..b0be3374c1 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/data/api/SingleValueFilter.java +++ b/core/src/main/java/org/hisp/dhis/android/core/data/api/SingleValueFilter.java @@ -58,6 +58,10 @@ public static Filter eq(@NonNull Field field, @Nullable Strin return create(field, "eq", value); } + public static Filter like(@NonNull Field field, @Nullable String value) { + return create(field, "like", value); + } + @Override public String generateString() { StringBuilder builder = new StringBuilder(); diff --git a/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallFactory.java b/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallFactory.java index da546826bc..fa3bc92504 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallFactory.java +++ b/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallFactory.java @@ -154,8 +154,8 @@ private Set downloadOrgunits(Set orguntis) throws D2Er } private retrofit2.Call> getOrganisationUnitAndDescendants(OrganisationUnitQuery query) { - return organisationUnitService.getOrganisationUnitWithDescendants( - query.orgUnit(), OrganisationUnitFields.allFields, true, + return organisationUnitService.getOrganisationUnits( + OrganisationUnitFields.allFields, OrganisationUnitFields.path.like(query.orgUnit()), query.paging(), query.pageSize(), query.page()); } diff --git a/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitFields.java b/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitFields.java index 543d3b1a26..42ac2f9f42 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitFields.java +++ b/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitFields.java @@ -48,7 +48,7 @@ public final class OrganisationUnitFields { static final Field uid = fh.uid(); private static final Field displayName = fh.displayName(); - private static final Field path = Field.create(PATH); + static final Field path = Field.create(PATH); private static final Field openingDate = Field.create(OPENING_DATE); private static final Field closedDate = Field.create(CLOSED_DATE); diff --git a/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitService.java b/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitService.java index 9acf683c81..48d9aabf8e 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitService.java +++ b/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitService.java @@ -44,16 +44,14 @@ interface OrganisationUnitService { String UID = "uid"; String FIELDS = "fields"; String FILTER = "filter"; - String INCLUDE_DESCENDANTS = "includeDescendants"; String PAGING = "paging"; String PAGE = "page"; String PAGE_SIZE = "pageSize"; - @GET(ORGANISATION_UNITS + "/{uid}") - Call> getOrganisationUnitWithDescendants( - @Path(UID) String organisationUnitUid, + @GET(ORGANISATION_UNITS) + Call> getOrganisationUnits( @Query(FIELDS) @Which Fields fields, - @Query(INCLUDE_DESCENDANTS) Boolean descendants, + @Query(FILTER) @Where Filter filter, @Query(PAGING) Boolean paging, @Query(PAGE_SIZE) Integer pageSize, @Query(PAGE) Integer page diff --git a/core/src/test/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallUnitShould.java b/core/src/test/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallUnitShould.java index 665aba2847..68f4a90eac 100644 --- a/core/src/test/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallUnitShould.java +++ b/core/src/test/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallUnitShould.java @@ -33,9 +33,9 @@ import org.hisp.dhis.android.core.common.Payload; import org.hisp.dhis.android.core.common.Transformer; import org.hisp.dhis.android.core.data.api.Fields; +import org.hisp.dhis.android.core.data.api.Filter; import org.hisp.dhis.android.core.data.database.DatabaseAdapter; import org.hisp.dhis.android.core.dataset.DataSet; -import org.hisp.dhis.android.core.maintenance.D2Error; import org.hisp.dhis.android.core.program.Program; import org.hisp.dhis.android.core.resource.Resource; import org.hisp.dhis.android.core.resource.ResourceHandler; @@ -59,8 +59,8 @@ import java.util.concurrent.Callable; import static org.assertj.core.api.Java6Assertions.assertThat; -import static org.mockito.Matchers.anyCollectionOf; import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyCollectionOf; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -82,14 +82,11 @@ public class OrganisationUnitCallUnitShould { private OrganisationUnitService organisationUnitService; //Captors for the organisationUnitService arguments: - @Captor - private ArgumentCaptor uidCaptor; - @Captor private ArgumentCaptor> fieldsCaptor; @Captor - private ArgumentCaptor descendantsCaptor; + private ArgumentCaptor> filtersCaptor; @Captor private ArgumentCaptor pagingCaptor; @@ -121,9 +118,6 @@ public class OrganisationUnitCallUnitShould { @Mock private GenericCallData genericCallData; - @Mock - private D2Error d2Error; - @Mock private OrganisationUnitHandler organisationUnitHandler; @@ -193,8 +187,8 @@ public void setUp() throws IOException { organisationUnits = Collections.singletonList(organisationUnit); when(user.organisationUnits()).thenReturn(new ArrayList<>(organisationUnits)); - when(organisationUnitService.getOrganisationUnitWithDescendants( - uidCaptor.capture(), fieldsCaptor.capture(), descendantsCaptor.capture(), pagingCaptor.capture(), + when(organisationUnitService.getOrganisationUnits( + fieldsCaptor.capture(), filtersCaptor.capture(), pagingCaptor.capture(), pageSizeCaptor.capture(), pageCaptor.capture() )).thenReturn(retrofitCall); @@ -212,9 +206,9 @@ public void invoke_server_with_correct_parameters() throws Exception { organisationUnitCall.call(); - assertThat(uidCaptor.getValue()).isEqualTo(organisationUnit.uid()); assertThat(fieldsCaptor.getValue()).isEqualTo(OrganisationUnitFields.allFields); - assertThat(descendantsCaptor.getValue()).isTrue(); + assertThat(filtersCaptor.getValue().operator()).isEqualTo("like"); + assertThat(filtersCaptor.getValue().field()).isEqualTo(OrganisationUnitFields.path); assertThat(pagingCaptor.getValue()).isTrue(); assertThat(pageCaptor.getValue()).isEqualTo(1); } From 21593134ea16361e6284157a127c829a01e9a7a3 Mon Sep 17 00:00:00 2001 From: Luis Delgado Romera Date: Mon, 24 Jun 2019 10:29:07 +0200 Subject: [PATCH 10/11] [ANDROSDK-873] Deal with ProgramRuleAction with empty ProgramRule --- .../maintenance/ForeignKeyCleanerShould.java | 5 ++- .../ProgramRuleWithUidColumnAdapter.java | 39 ------------------- .../core/program/ProgramRuleAction.java | 10 ++--- .../ProgramRuleActionEntityDIModule.java | 4 +- .../core/program/ProgramRuleActionFields.java | 1 - .../core/program/ProgramRuleHandler.java | 10 +++-- .../program/ProgramRuleActionSamples.java | 3 +- .../core/data/server/Dhis2MockServer.java | 2 +- .../resources/program/program_rules.json | 9 ----- .../program/ProgramRuleHandlerShould.java | 9 +++-- 10 files changed, 24 insertions(+), 68 deletions(-) delete mode 100644 core/src/main/java/org/hisp/dhis/android/core/data/database/ProgramRuleWithUidColumnAdapter.java diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/maintenance/ForeignKeyCleanerShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/maintenance/ForeignKeyCleanerShould.java index 46a2be6868..d4f15ec897 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/maintenance/ForeignKeyCleanerShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/maintenance/ForeignKeyCleanerShould.java @@ -39,7 +39,7 @@ import org.hisp.dhis.android.core.common.D2CallExecutor; import org.hisp.dhis.android.core.common.D2Factory; import org.hisp.dhis.android.core.common.IdentifiableObjectStore; -import org.hisp.dhis.android.core.utils.integration.real.BaseRealIntegrationTest; +import org.hisp.dhis.android.core.common.ObjectWithUid; import org.hisp.dhis.android.core.data.server.Dhis2MockServer; import org.hisp.dhis.android.core.program.Program; import org.hisp.dhis.android.core.program.ProgramRule; @@ -54,6 +54,7 @@ import org.hisp.dhis.android.core.user.UserCredentialsStoreImpl; import org.hisp.dhis.android.core.user.UserCredentialsTableInfo; import org.hisp.dhis.android.core.user.UserTableInfo; +import org.hisp.dhis.android.core.utils.integration.real.BaseRealIntegrationTest; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -199,7 +200,7 @@ public void cascade_deletion_on_foreign_key_error() throws Exception { .uid("action_uid") .name("name") .programRuleActionType(ProgramRuleActionType.ASSIGN) - .programRule(ProgramRule.builder().uid(PROGRAM_RULE_UID).build()) + .programRule(ObjectWithUid.create(PROGRAM_RULE_UID)) .build(); ProgramRuleActionStore.create(d2.databaseAdapter()).insert(programRuleAction); diff --git a/core/src/main/java/org/hisp/dhis/android/core/data/database/ProgramRuleWithUidColumnAdapter.java b/core/src/main/java/org/hisp/dhis/android/core/data/database/ProgramRuleWithUidColumnAdapter.java deleted file mode 100644 index 79fc66838e..0000000000 --- a/core/src/main/java/org/hisp/dhis/android/core/data/database/ProgramRuleWithUidColumnAdapter.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2004-2019, 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.data.database; - -import org.hisp.dhis.android.core.program.ProgramRule; - -public class ProgramRuleWithUidColumnAdapter extends IdentifiableObjectColumnAdapter { - - @Override - protected ProgramRule build(String uid) { - return ProgramRule.builder().uid(uid).build(); - } -} \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/program/ProgramRuleAction.java b/core/src/main/java/org/hisp/dhis/android/core/program/ProgramRuleAction.java index e5dcaf21a7..1860b363fa 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/program/ProgramRuleAction.java +++ b/core/src/main/java/org/hisp/dhis/android/core/program/ProgramRuleAction.java @@ -29,7 +29,6 @@ package org.hisp.dhis.android.core.program; import android.database.Cursor; -import androidx.annotation.Nullable; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @@ -43,13 +42,14 @@ import org.hisp.dhis.android.core.data.database.DataElementWithUidColumnAdapter; import org.hisp.dhis.android.core.data.database.ObjectWithUidColumnAdapter; import org.hisp.dhis.android.core.data.database.ProgramIndicatorWithUidColumnAdapter; -import org.hisp.dhis.android.core.data.database.ProgramRuleWithUidColumnAdapter; import org.hisp.dhis.android.core.data.database.ProgramStageSectionWithUidColumnAdapter; import org.hisp.dhis.android.core.data.database.ProgramStageWithUidColumnAdapter; import org.hisp.dhis.android.core.data.database.TrackedEntityAttributeWithUidColumnAdapter; import org.hisp.dhis.android.core.dataelement.DataElement; import org.hisp.dhis.android.core.trackedentity.TrackedEntityAttribute; +import androidx.annotation.Nullable; + @AutoValue @JsonDeserialize(builder = AutoValue_ProgramRuleAction.Builder.class) public abstract class ProgramRuleAction extends BaseIdentifiableObject implements Model { @@ -98,8 +98,8 @@ public abstract class ProgramRuleAction extends BaseIdentifiableObject implement @Nullable @JsonProperty() - @ColumnAdapter(ProgramRuleWithUidColumnAdapter.class) - public abstract ProgramRule programRule(); + @ColumnAdapter(ObjectWithUidColumnAdapter.class) + public abstract ObjectWithUid programRule(); @Nullable @JsonProperty() @@ -144,7 +144,7 @@ public abstract static class Builder extends BaseIdentifiableObject.Builder store(DatabaseAdapter database @Provides @Reusable - SyncHandler handler(IdentifiableObjectStore store) { + SyncHandlerWithTransformer handler(IdentifiableObjectStore store) { return new IdentifiableSyncHandlerImpl<>(store); } diff --git a/core/src/main/java/org/hisp/dhis/android/core/program/ProgramRuleActionFields.java b/core/src/main/java/org/hisp/dhis/android/core/program/ProgramRuleActionFields.java index 4cef9644c8..611ee7d330 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/program/ProgramRuleActionFields.java +++ b/core/src/main/java/org/hisp/dhis/android/core/program/ProgramRuleActionFields.java @@ -59,7 +59,6 @@ final class ProgramRuleActionFields { fh.field(PROGRAM_RULE_ACTION_TYPE), fh.nestedFieldWithUid(PROGRAM_STAGE), fh.nestedFieldWithUid(DATA_ELEMENT), - fh.nestedFieldWithUid(PROGRAM_RULE), fh.nestedFieldWithUid(OPTION), fh.nestedFieldWithUid(OPTION_GROUP) ).build(); diff --git a/core/src/main/java/org/hisp/dhis/android/core/program/ProgramRuleHandler.java b/core/src/main/java/org/hisp/dhis/android/core/program/ProgramRuleHandler.java index 15ddc5a926..2805e8ad67 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/program/ProgramRuleHandler.java +++ b/core/src/main/java/org/hisp/dhis/android/core/program/ProgramRuleHandler.java @@ -28,9 +28,10 @@ package org.hisp.dhis.android.core.program; import org.hisp.dhis.android.core.arch.handlers.IdentifiableSyncHandlerImpl; -import org.hisp.dhis.android.core.arch.handlers.SyncHandler; +import org.hisp.dhis.android.core.arch.handlers.SyncHandlerWithTransformer; import org.hisp.dhis.android.core.common.HandleAction; import org.hisp.dhis.android.core.common.IdentifiableObjectStore; +import org.hisp.dhis.android.core.common.ObjectWithUid; import org.hisp.dhis.android.core.common.OrphanCleaner; import javax.inject.Inject; @@ -39,12 +40,12 @@ @Reusable final class ProgramRuleHandler extends IdentifiableSyncHandlerImpl { - private final SyncHandler programRuleActionHandler; + private final SyncHandlerWithTransformer programRuleActionHandler; private final OrphanCleaner programRuleActionCleaner; @Inject ProgramRuleHandler(IdentifiableObjectStore programRuleStore, - SyncHandler programRuleActionHandler, + SyncHandlerWithTransformer programRuleActionHandler, OrphanCleaner programRuleActionCleaner) { super(programRuleStore); this.programRuleActionHandler = programRuleActionHandler; @@ -53,7 +54,8 @@ final class ProgramRuleHandler extends IdentifiableSyncHandlerImpl @Override protected void afterObjectHandled(ProgramRule programRule, HandleAction handleAction) { - programRuleActionHandler.handleMany(programRule.programRuleActions()); + programRuleActionHandler.handleMany(programRule.programRuleActions(), + pra -> pra.toBuilder().programRule(ObjectWithUid.create(programRule.uid())).build()); if (handleAction == HandleAction.Update) { programRuleActionCleaner.deleteOrphan(programRule, programRule.programRuleActions()); } diff --git a/core/src/sharedTest/java/org/hisp/dhis/android/core/data/program/ProgramRuleActionSamples.java b/core/src/sharedTest/java/org/hisp/dhis/android/core/data/program/ProgramRuleActionSamples.java index b269062ea7..c30cd792ce 100644 --- a/core/src/sharedTest/java/org/hisp/dhis/android/core/data/program/ProgramRuleActionSamples.java +++ b/core/src/sharedTest/java/org/hisp/dhis/android/core/data/program/ProgramRuleActionSamples.java @@ -31,7 +31,6 @@ import org.hisp.dhis.android.core.common.ObjectWithUid; import org.hisp.dhis.android.core.dataelement.DataElement; import org.hisp.dhis.android.core.program.ProgramIndicator; -import org.hisp.dhis.android.core.program.ProgramRule; import org.hisp.dhis.android.core.program.ProgramRuleAction; import org.hisp.dhis.android.core.program.ProgramRuleActionType; import org.hisp.dhis.android.core.program.ProgramStage; @@ -57,7 +56,7 @@ public static ProgramRuleAction getProgramRuleAction() { .programRuleActionType(ProgramRuleActionType.ASSIGN) .programStage(ProgramStage.builder().uid("ps").build()) .dataElement(DataElement.builder().uid("de").build()) - .programRule(ProgramRule.builder().uid("pr").build()) + .programRule(ObjectWithUid.create("pr")) .option(ObjectWithUid.create("option")) .optionGroup(ObjectWithUid.create("option_group")) .build(); diff --git a/core/src/sharedTest/java/org/hisp/dhis/android/core/data/server/Dhis2MockServer.java b/core/src/sharedTest/java/org/hisp/dhis/android/core/data/server/Dhis2MockServer.java index afc4b9d321..b7a8659493 100644 --- a/core/src/sharedTest/java/org/hisp/dhis/android/core/data/server/Dhis2MockServer.java +++ b/core/src/sharedTest/java/org/hisp/dhis/android/core/data/server/Dhis2MockServer.java @@ -153,7 +153,7 @@ public MockResponse dispatch(RecordedRequest request) { return createMockResponse(CATEGORY_COMBOS_JSON); } else if (path.startsWith("/api/categories?")) { return createMockResponse(CATEGORIES_JSON); - } else if (path.startsWith("/api/organisationUnits/")) { + } else if (path.startsWith("/api/organisationUnits?")) { return createMockResponse(ORGANISATION_UNITS_JSON); } else if (path.startsWith("/api/organisationUnitLevels?")) { return createMockResponse(ORGANISATION_UNIT_LEVELS_JSON); diff --git a/core/src/sharedTest/resources/program/program_rules.json b/core/src/sharedTest/resources/program/program_rules.json index 593d4408b3..075c241a64 100644 --- a/core/src/sharedTest/resources/program/program_rules.json +++ b/core/src/sharedTest/resources/program/program_rules.json @@ -19,9 +19,6 @@ "content": "The hemoglobin value cannot be above 99", "dataElement": { "id": "vANAXwtLwcT" - }, - "programRule": { - "id": "dahuKlP7jR2" } } ] @@ -62,9 +59,6 @@ "dataElement": { "id": "Ok9OQpitjQr" }, - "programRule": { - "id": "xOe5qCzRS0Y" - }, "option": { "id": "egT1YqFWsVk" }, @@ -95,9 +89,6 @@ "content": "Hemoglobin value lower than normal", "dataElement": { "id": "vANAXwtLwcT" - }, - "programRule": { - "id": "GC4gpdoSD4r" } } ] diff --git a/core/src/test/java/org/hisp/dhis/android/core/program/ProgramRuleHandlerShould.java b/core/src/test/java/org/hisp/dhis/android/core/program/ProgramRuleHandlerShould.java index 6d62d3d983..35c4343cd7 100644 --- a/core/src/test/java/org/hisp/dhis/android/core/program/ProgramRuleHandlerShould.java +++ b/core/src/test/java/org/hisp/dhis/android/core/program/ProgramRuleHandlerShould.java @@ -28,10 +28,11 @@ package org.hisp.dhis.android.core.program; import org.hisp.dhis.android.core.arch.handlers.IdentifiableSyncHandlerImpl; -import org.hisp.dhis.android.core.arch.handlers.SyncHandler; +import org.hisp.dhis.android.core.arch.handlers.SyncHandlerWithTransformer; import org.hisp.dhis.android.core.common.HandleAction; import org.hisp.dhis.android.core.common.IdentifiableObjectStore; import org.hisp.dhis.android.core.common.OrphanCleaner; +import org.hisp.dhis.android.core.common.Transformer; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -41,6 +42,8 @@ import java.util.List; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -51,7 +54,7 @@ public class ProgramRuleHandlerShould { private IdentifiableObjectStore programRuleStore; @Mock - private SyncHandler programRuleActionHandler; + private SyncHandlerWithTransformer programRuleActionHandler; @Mock private ProgramRule programRule; @@ -83,7 +86,7 @@ public void extend_identifiable_sync_handler_impl() { @Test public void call_program_rule_action_handler() { programRuleHandler.handle(programRule); - verify(programRuleActionHandler).handleMany(programRuleActions); + verify(programRuleActionHandler).handleMany(same(programRuleActions), any(Transformer.class)); } @Test From 947faf174aba0a7b349d759c55496f9f546f5267 Mon Sep 17 00:00:00 2001 From: Luis Delgado Romera Date: Mon, 24 Jun 2019 10:29:45 +0200 Subject: [PATCH 11/11] [ANDROSDK-873] Findbugs --- .../android/core/organisationunit/OrganisationUnitService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitService.java b/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitService.java index 48d9aabf8e..254950c0d3 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitService.java +++ b/core/src/main/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitService.java @@ -35,7 +35,6 @@ import retrofit2.Call; import retrofit2.http.GET; -import retrofit2.http.Path; import retrofit2.http.Query; interface OrganisationUnitService {