Skip to content

Commit

Permalink
Merge pull request #498 from opensrp/issue/support/30-duplicate-zeir-ids
Browse files Browse the repository at this point in the history
  • Loading branch information
ekigamba authored Dec 6, 2022
2 parents 92876a4 + 810c06c commit ffadf4e
Show file tree
Hide file tree
Showing 11 changed files with 159 additions and 20 deletions.
21 changes: 12 additions & 9 deletions opensrp-giz-malawi/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ android {
applicationId "org.smartregister.giz"
minSdkVersion androidMinSdkVersion
targetSdkVersion androidTargetSdkVersion
versionCode 45
versionName "0.4.5"
versionCode 46
versionName "0.4.6"
multiDexEnabled true
buildConfigField "long", "MAX_SERVER_TIME_DIFFERENCE", "1800000l"
buildConfigField "boolean", "TIME_CHECK", "false"
Expand Down Expand Up @@ -115,7 +115,7 @@ android {
buildConfigField "int", "OPENMRS_UNIQUE_ID_BATCH_SIZE", '100'
buildConfigField "int", "OPENMRS_UNIQUE_ID_SOURCE", '2'
buildConfigField "int", "VACCINE_SYNC_TIME", '0'
buildConfigField "int", "DATABASE_VERSION", '19'
buildConfigField "int", "DATABASE_VERSION", '20'
buildConfigField "int", "URL_VERSION", '1'
buildConfigField "long", "MAX_SERVER_TIME_DIFFERENCE", "1800000l"
buildConfigField "boolean", "TIME_CHECK", "true"
Expand Down Expand Up @@ -144,7 +144,7 @@ android {
buildConfigField "int", "OPENMRS_UNIQUE_ID_BATCH_SIZE", '10'
buildConfigField "int", "OPENMRS_UNIQUE_ID_SOURCE", '2'
buildConfigField "int", "VACCINE_SYNC_TIME", '0'
buildConfigField "int", "DATABASE_VERSION", '19'
buildConfigField "int", "DATABASE_VERSION", '20'
buildConfigField "int", "URL_VERSION", '1'
buildConfigField "long", "MAX_SERVER_TIME_DIFFERENCE", "1800000l"
buildConfigField "boolean", "TIME_CHECK", "true"
Expand Down Expand Up @@ -172,7 +172,7 @@ android {
buildConfigField "int", "OPENMRS_UNIQUE_ID_BATCH_SIZE", '100'
buildConfigField "int", "OPENMRS_UNIQUE_ID_SOURCE", '2'
buildConfigField "int", "VACCINE_SYNC_TIME", '0'
buildConfigField "int", "DATABASE_VERSION", '19'
buildConfigField "int", "DATABASE_VERSION", '20'
buildConfigField "int", "URL_VERSION", '1'
buildConfigField "long", "MAX_SERVER_TIME_DIFFERENCE", "1800000l"
buildConfigField "boolean", "TIME_CHECK", "true"
Expand All @@ -196,7 +196,7 @@ android {
buildConfigField "int", "OPENMRS_UNIQUE_ID_BATCH_SIZE", '100'
buildConfigField "int", "OPENMRS_UNIQUE_ID_SOURCE", '2'
buildConfigField "int", "VACCINE_SYNC_TIME", '0'
buildConfigField "int", "DATABASE_VERSION", '19'
buildConfigField "int", "DATABASE_VERSION", '20'
buildConfigField "int", "URL_VERSION", '1'
buildConfigField "long", "MAX_SERVER_TIME_DIFFERENCE", "1800000l"
buildConfigField "boolean", "TIME_CHECK", "true"
Expand Down Expand Up @@ -259,7 +259,7 @@ dependencies {
// exclude group: 'com.github.lecho', module: 'hellocharts-library'
}

implementation('org.smartregister:opensrp-client-child:0.7.3-ALPHA3-SNAPSHOT@aar') {
implementation('org.smartregister:opensrp-client-child:0.10.1-SNAPSHOT@aar') {
transitive = true
exclude group: 'id.zelory', module: 'compressor'
exclude group: 'org.smartregister', module: 'opensrp-client-core'
Expand Down Expand Up @@ -291,7 +291,7 @@ dependencies {
exclude group: 'io.ona.rdt-capture', module: 'lib'
}

api('org.smartregister:opensrp-client-core:4.3.23-SNAPSHOT@aar') {
api('org.smartregister:opensrp-client-core:5.0.9-SNAPSHOT@aar') {
transitive = true
exclude group: 'id.zelory', module: 'compressor'
exclude group: 'com.github.bmelnychuk', module: 'atv'
Expand Down Expand Up @@ -325,7 +325,7 @@ dependencies {
exclude group: 'com.android.support', module: 'appcompat-v7'
}

api('org.smartregister:opensrp-client-immunization:4.0.0-SNAPSHOT@aar') {
api('org.smartregister:opensrp-client-immunization:4.0.6-SNAPSHOT@aar') {
transitive = true
exclude group: 'id.zelory', module: 'compressor'
exclude group: 'org.smartregister', module: 'opensrp-client-core'
Expand Down Expand Up @@ -402,6 +402,9 @@ dependencies {
implementation group: 'org.yaml', name: 'snakeyaml', version: '1.24'
implementation group: 'io.fabric.sdk.android', name: 'fabric', version: '1.4.8'

implementation "androidx.multidex:multidex:2.0.1"
testImplementation "androidx.work:work-testing:2.7.1"


def robolectricVersion = '4.1'
testImplementation("org.robolectric:robolectric:$robolectricVersion") {
Expand Down
Binary file modified opensrp-giz-malawi/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ public boolean onOptionsItemSelected(MenuItem item) {
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data == null)
if (data == null || data.getStringExtra(JsonFormConstants.JSON_FORM_KEY.JSON) == null)
return;
try {
String jsonString = data.getStringExtra(JsonFormConstants.JSON_FORM_KEY.JSON);
Expand Down Expand Up @@ -248,5 +248,10 @@ protected String getReportDeceasedMetadata() {
}
return "";
}

@Override
public void updateViews() {
// Do nothing
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.multidex.MultiDex;

import com.crashlytics.android.Crashlytics;
import com.crashlytics.android.core.CrashlyticsCore;
Expand Down Expand Up @@ -187,6 +188,12 @@ public void initializeCrashLyticsTree() {
}
}

@Override
protected void attachBaseContext(android.content.Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}

private static String[] getFtsTables() {
return new String[]{OpdDbConstants.KEY.TABLE, "ec_mother_details", DBConstants.RegisterTable.CHILD_DETAILS, MaternityDbConstants.Table.MATERNITY_REGISTRATION_DETAILS};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,8 @@ protected static Map<String, List<Vaccine>> fetchAllVaccines() {
cursor.getString(cursor.getColumnIndex(VaccineRepository.EVENT_ID)),
cursor.getString(cursor.getColumnIndex(VaccineRepository.FORMSUBMISSION_ID)),
cursor.getInt(cursor.getColumnIndex(VaccineRepository.OUT_OF_AREA)),
createdAt
// cursor.getInt(cursor.getColumnIndex(VaccineRepository.IS_VOIDED))
createdAt,
cursor.getInt(cursor.getColumnIndex(VaccineRepository.IS_VOIDED))
);

vaccine.setTeam(cursor.getString(cursor.getColumnIndex(VaccineRepository.TEAM)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.smartregister.growthmonitoring.job.ZScoreRefreshIntentServiceJob;
import org.smartregister.immunization.job.RecurringServiceJob;
import org.smartregister.immunization.job.VaccineServiceJob;
import org.smartregister.job.DuplicateZeirIdsCleanerWorker;
import org.smartregister.job.ImageUploadServiceJob;
import org.smartregister.job.PullUniqueIdsServiceJob;
import org.smartregister.job.SyncServiceJob;
Expand All @@ -24,7 +25,6 @@ public LoginInteractor(BaseLoginContract.Presenter loginPresenter) {

@Override
protected void scheduleJobsPeriodically() {

VaccineServiceJob
.scheduleJob(VaccineServiceJob.TAG, TimeUnit.MINUTES.toMinutes(BuildConfig.DATA_SYNC_DURATION_MINUTES),
getFlexValue(BuildConfig.DATA_SYNC_DURATION_MINUTES));
Expand Down Expand Up @@ -69,5 +69,13 @@ protected void scheduleJobsImmediately() {
PullUniqueIdsServiceJob.scheduleJobImmediately(PullUniqueIdsServiceJob.TAG); //need these asap!
ZScoreRefreshIntentServiceJob.scheduleJobImmediately(ZScoreRefreshIntentServiceJob.TAG);
ImageUploadServiceJob.scheduleJobImmediately(ImageUploadServiceJob.TAG);

/*
This job will not be duplicated but is added here since scheduleJobsPeriodically is only called
after a remote login and therefore might be run too late. scheduleJobsImmediately is called
after both remote login and local login
*/
String[] eventTypes = new String[]{"Opd Registration", "PNC Registration", "ANC Registration", "Maternity Registration"};
DuplicateZeirIdsCleanerWorker.schedulePeriodically(this.getApplicationContext(), 15, eventTypes);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.smartregister.anc.library.repository.PreviousContactRepository;
import org.smartregister.child.util.ChildDbMigrations;
import org.smartregister.child.util.Utils;
import org.smartregister.child.util.VaccineOverdueCountRepositoryHelper;
import org.smartregister.configurableviews.repository.ConfigurableViewsRepository;
import org.smartregister.domain.db.Column;
import org.smartregister.giz.BuildConfig;
Expand All @@ -25,6 +26,7 @@
import org.smartregister.immunization.job.VaccineSchedulesUpdateJob;
import org.smartregister.immunization.repository.RecurringServiceRecordRepository;
import org.smartregister.immunization.repository.RecurringServiceTypeRepository;
import org.smartregister.immunization.repository.VaccineOverdueCountRepository;
import org.smartregister.immunization.repository.VaccineRepository;
import org.smartregister.immunization.util.IMDatabaseUtils;
import org.smartregister.maternity.repository.MaternityChildRepository;
Expand Down Expand Up @@ -214,6 +216,11 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
case 19:
databaseUpgradeToResetIndicators(db);
break;

case 20:
upgradeToVersion20(db);
break;

default:
break;
}
Expand Down Expand Up @@ -566,4 +573,43 @@ protected void dumpHIA2IndicatorsCSV(SQLiteDatabase db) {
.hIA2IndicatorsRepository();
hIA2IndicatorsRepository.save(db, csvData);
}

private void upgradeToVersion20(SQLiteDatabase db) {
try {
// Add vaccine overdue table and migration vaccines
db.execSQL(VaccineOverdueCountRepository.CREATE_TABLE_SQL);
db.execSQL(VaccineOverdueCountRepositoryHelper.MIGRATE_VACCINES_QUERY);

addOutreachColumn(db);
addDateRemovedColumnChildDetailsTable(db);
} catch (Exception e) {
Timber.e(e);
}
}

private void addOutreachColumn(SQLiteDatabase db) {
try {
String UPDATE_VACCINES_TABLE_ADD_OUTREACH = "ALTER TABLE " + VaccineRepository.VACCINE_TABLE_NAME + " ADD COLUMN outreach INTEGER;";
db.execSQL(UPDATE_VACCINES_TABLE_ADD_OUTREACH);
db.execSQL(HeightRepository.UPDATE_TABLE_ADD_CHILD_LOCATION_ID_COL);
db.execSQL(HeightRepository.UPDATE_TABLE_ADD_TEAM_COL);
db.execSQL(HeightRepository.UPDATE_TABLE_ADD_TEAM_ID_COL);
db.execSQL(HeightRepository.UPDATE_TABLE_ADD_EVENT_ID_COL);
db.execSQL(HeightRepository.UPDATE_TABLE_ADD_FORMSUBMISSION_ID_COL);
db.execSQL(HeightRepository.ALTER_ADD_Z_SCORE_COLUMN);
db.execSQL(HeightRepository.UPDATE_TABLE_ADD_OUT_OF_AREA_COL);
db.execSQL(HeightRepository.ALTER_ADD_CREATED_AT_COLUMN);
} catch (Exception e) {
Timber.e(e);
}
}

private void addDateRemovedColumnChildDetailsTable(SQLiteDatabase database) {
try {
String UPDATE_CHILD_DETAILS_TABLE_ADD_DATE_REMOVED = "ALTER TABLE ec_child_details ADD COLUMN date_removed VARCHAR;";
database.execSQL(UPDATE_CHILD_DETAILS_TABLE_ADD_DATE_REMOVED);
} catch (Exception e) {
Timber.e(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,31 +83,31 @@ public void testFetchAllVaccinesReturnsVaccineList() throws ParseException {
VaccineRepository.DATE, VaccineRepository.ANMID, VaccineRepository.LOCATION_ID,
VaccineRepository.SYNC_STATUS, VaccineRepository.HIA2_STATUS, VaccineRepository.UPDATED_AT_COLUMN,
VaccineRepository.EVENT_ID, VaccineRepository.FORMSUBMISSION_ID, VaccineRepository.OUT_OF_AREA,
VaccineRepository.TEAM, VaccineRepository.TEAM_ID, VaccineRepository.CHILD_LOCATION_ID
VaccineRepository.TEAM, VaccineRepository.TEAM_ID, VaccineRepository.CHILD_LOCATION_ID, VaccineRepository.IS_VOIDED
});
matrixCursor.addRow(new Object[]{
"2021-02-20 22:22:34", 1, "839e53i354-ba27-46b1-b5c2-2bab06fd77e2",
"giz", "bcg", 1,
"1567112400000", "meso", "402ecf03-af72-4c93-b099-e1ce327d815b",
"Synced", "hia_2", "1584692554019",
"23147a8f-d301-43a1-876e-93f30088e2d7", "d3e94182-a7c8-457a-a5a5-40354bfb37e4", 0,
"Team A", "team_1", "4d30ecac-536b-4a90-b712-8613d3768717"
"Team A", "team_1", "4d30ecac-536b-4a90-b712-8613d3768717", 0
});
matrixCursor.addRow(new Object[]{
"2021-02-20 22:22:34", 1, "839e53i354-ba27-46b1-b5c2-2bab06fd77e2",
"giz", "opv_0", 0,
"1567112400000", "meso", "402ecf03-af72-4c93-b099-e1ce327d815b",
"Synced", "hia_2", "1584692554019",
"23147a8f-d301-43a1-876e-93f30088e2d7", "d3e94182-a7c8-457a-a5a5-40354bfb37e4", 0,
"Team A", "team_1", "4d30ecac-536b-4a90-b712-8613d3768717"
"Team A", "team_1", "4d30ecac-536b-4a90-b712-8613d3768717", 0
});
matrixCursor.addRow(new Object[]{
"2021-02-20 22:22:34", 1, "89839e53i354-483d-48c2-baec-929b862f3ac1",
"giz", "opv_0", 0,
"1567112400000", "meso", "402ecf03-af72-4c93-b099-e1ce327d815b",
"Synced", "hia_2", "1584692554019",
"23147a8f-d301-43a1-876e-93f30088e2d7", "d3e94182-a7c8-457a-a5a5-40354bfb37e4", 0,
"Team A", "team_1", "4d30ecac-536b-4a90-b712-8613d3768717"
"Team A", "team_1", "4d30ecac-536b-4a90-b712-8613d3768717", 0
});
doReturn(matrixCursor).when(database).rawQuery(Mockito.any(), Mockito.any());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,30 @@

import static org.junit.Assert.assertEquals;

import android.content.Context;
import android.util.Log;

import androidx.work.Configuration;
import androidx.work.WorkInfo;
import androidx.work.WorkManager;
import androidx.work.impl.utils.SynchronousExecutor;
import androidx.work.testing.WorkManagerTestInitHelper;

import com.google.common.util.concurrent.ListenableFuture;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.robolectric.RuntimeEnvironment;
import org.smartregister.giz.BaseRobolectricTest;
import org.smartregister.giz.shadow.ShadowBaseJob;
import org.smartregister.growthmonitoring.job.HeightIntentServiceJob;
import org.smartregister.growthmonitoring.job.WeightIntentServiceJob;
import org.smartregister.growthmonitoring.job.ZScoreRefreshIntentServiceJob;
import org.smartregister.immunization.job.RecurringServiceJob;
import org.smartregister.immunization.job.VaccineServiceJob;
import org.smartregister.job.DuplicateZeirIdsCleanerWorker;
import org.smartregister.job.ImageUploadServiceJob;
import org.smartregister.job.PullUniqueIdsServiceJob;
import org.smartregister.job.SyncServiceJob;
Expand All @@ -21,6 +34,8 @@

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutionException;

/**
* Created by Ephraim Kigamba - [email protected] on 05-03-2020.
Expand All @@ -31,7 +46,8 @@ public class LoginInteractorTest extends BaseRobolectricTest {

@Before
public void setUp() throws Exception {
loginInteractor = new LoginInteractor(Mockito.mock(BaseLoginContract.Presenter.class));
loginInteractor = Mockito.spy(new LoginInteractor(Mockito.mock(BaseLoginContract.Presenter.class)));
Mockito.doReturn((Context) RuntimeEnvironment.application).when(loginInteractor).getApplicationContext();
}

@Test
Expand All @@ -53,7 +69,9 @@ public void scheduleJobsPeriodically() {
}

@Test
public void scheduleJobsImmediatelyShouldCallEachJobToScheduleImmediateExecution() {
public void scheduleJobsImmediatelyShouldCallEachJobToScheduleImmediateExecution() throws ExecutionException, InterruptedException {
initializeWorkManager();

loginInteractor.scheduleJobsImmediately();

Assert.assertTrue(ShadowBaseJob.getShadowHelper().isCalled(ShadowBaseJob.scheduleJobImmediatelyMN));
Expand All @@ -65,5 +83,22 @@ public void scheduleJobsImmediatelyShouldCallEachJobToScheduleImmediateExecution
assertEquals(ZScoreRefreshIntentServiceJob.TAG, methodCalls.get(3).get(0));
assertEquals(ImageUploadServiceJob.TAG, methodCalls.get(4).get(0));
ShadowBaseJob.getShadowHelper().getMethodCalls().clear();

ListenableFuture<List<WorkInfo>> listenableFuture = WorkManager.getInstance(RuntimeEnvironment.application)
.getWorkInfosForUniqueWork(DuplicateZeirIdsCleanerWorker.TAG);

assertEquals(1, listenableFuture.get().size());
}


private void initializeWorkManager() {
Configuration config = new Configuration.Builder()
.setMinimumLoggingLevel(Log.DEBUG)
.setExecutor(new SynchronousExecutor())
.build();

// Initialize WorkManager for instrumentation tests.
WorkManagerTestInitHelper.initializeTestWorkManager(
RuntimeEnvironment.application, config);
}
}
Loading

0 comments on commit ffadf4e

Please sign in to comment.