diff --git a/gradle.properties b/gradle.properties index 0787731d6..8d4c6d3cd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -VERSION_NAME=4.2.13-gs.1-SNAPSHOT +VERSION_NAME=4.2.13-gs.2-SNAPSHOT VERSION_CODE=1 GROUP=org.smartregister POM_SETTING_DESCRIPTION=OpenSRP Client Core Application diff --git a/opensrp-app/build.gradle b/opensrp-app/build.gradle index 1b9f44e5c..19b9f4d77 100644 --- a/opensrp-app/build.gradle +++ b/opensrp-app/build.gradle @@ -89,8 +89,8 @@ android { //applicationId "org.smartregister" minSdkVersion androidMinSdkVersion targetSdkVersion androidTargetSdkVersion - versionCode Integer.parseInt(project.VERSION_CODE) - versionName project.VERSION_NAME + /*versionCode Integer.parseInt(project.VERSION_CODE) + versionName project.VERSION_NAME*/ testInstrumentationRunner "android.test.InstrumentationTestRunner" buildConfigField "long", "BUILD_TIMESTAMP", System.currentTimeMillis() + "L" buildConfigField "int", "DB_ENCRYPTION_VERSION", '1' @@ -230,7 +230,7 @@ dependencies { transitive = true } - implementation 'org.smartregister:opensrp-plan-evaluator:1.3.1-SNAPSHOT' + implementation 'org.smartregister:opensrp-plan-evaluator:1.4.0-SNAPSHOT' implementation 'xerces:xercesImpl:2.12.0' @@ -312,4 +312,4 @@ coveralls { sourceDirs = ["$project.projectDir/src/main/java"] } -apply from: '../maven.gradle' \ No newline at end of file +//apply from: '../maven.gradle' \ No newline at end of file diff --git a/opensrp-app/src/main/java/org/smartregister/AllConstants.java b/opensrp-app/src/main/java/org/smartregister/AllConstants.java index 8ae63d979..9f3a797e7 100644 --- a/opensrp-app/src/main/java/org/smartregister/AllConstants.java +++ b/opensrp-app/src/main/java/org/smartregister/AllConstants.java @@ -28,6 +28,7 @@ public class AllConstants { public static final String FAMILY = "Family"; public static final String RELATIONSHIPS = "relationships"; public static final String TASK_IDENTIFIER = "taskIdentifier"; + public static final String PRACTITIONER_IDENTIFIER = "practitionerIdentifier"; // Maximum time difference between server and client time in milliseconds diff --git a/opensrp-app/src/main/java/org/smartregister/Context.java b/opensrp-app/src/main/java/org/smartregister/Context.java index f5b91566a..e9edee3c0 100755 --- a/opensrp-app/src/main/java/org/smartregister/Context.java +++ b/opensrp-app/src/main/java/org/smartregister/Context.java @@ -43,6 +43,7 @@ import org.smartregister.repository.ManifestRepository; import org.smartregister.repository.MotherRepository; import org.smartregister.repository.PlanDefinitionRepository; +import org.smartregister.repository.PractitionerRepository; import org.smartregister.repository.ReportRepository; import org.smartregister.repository.ServiceProvidedRepository; import org.smartregister.repository.SettingsRepository; @@ -227,6 +228,7 @@ public class Context { private AppProperties appProperties; private LocationTagRepository locationTagRepository; private ManifestRepository manifestRepository; + private PractitionerRepository practitionerRepository; private ClientFormRepository clientFormRepository; private ClientRelationshipRepository clientRelationshipRepository; @@ -1245,6 +1247,13 @@ public ClientFormRepository getClientFormRepository() { return clientFormRepository; } + public PractitionerRepository getPractitionerRepository() { + if (practitionerRepository == null) { + practitionerRepository = new PractitionerRepository(); + } + return practitionerRepository; + } + public ClientRelationshipRepository getClientRelationshipRepository() { if (clientRelationshipRepository == null) { clientRelationshipRepository = new ClientRelationshipRepository(); diff --git a/opensrp-app/src/main/java/org/smartregister/configuration/BottomNavigationOptions.java b/opensrp-app/src/main/java/org/smartregister/configuration/BottomNavigationOptions.java new file mode 100644 index 000000000..4d25bef70 --- /dev/null +++ b/opensrp-app/src/main/java/org/smartregister/configuration/BottomNavigationOptions.java @@ -0,0 +1,10 @@ +package org.smartregister.configuration; + +public interface BottomNavigationOptions { + + public int getBottomNavigationLayoutId(); + + public BottomNavigationOptionsModel getBottomNavigationOptionsModel(); + + public int checkedItemId(); +} diff --git a/opensrp-app/src/main/java/org/smartregister/configuration/BottomNavigationOptionsModel.java b/opensrp-app/src/main/java/org/smartregister/configuration/BottomNavigationOptionsModel.java new file mode 100644 index 000000000..5a784bb61 --- /dev/null +++ b/opensrp-app/src/main/java/org/smartregister/configuration/BottomNavigationOptionsModel.java @@ -0,0 +1,11 @@ +package org.smartregister.configuration; + +import android.app.Activity; +import android.view.MenuItem; + +import androidx.annotation.NonNull; + +public interface BottomNavigationOptionsModel { + + void onBottomOptionSelection(Activity activity, @NonNull MenuItem menuItem); +} diff --git a/opensrp-app/src/main/java/org/smartregister/configuration/ConfigurableNavigationOptions.java b/opensrp-app/src/main/java/org/smartregister/configuration/ConfigurableNavigationOptions.java new file mode 100644 index 000000000..42b8473b0 --- /dev/null +++ b/opensrp-app/src/main/java/org/smartregister/configuration/ConfigurableNavigationOptions.java @@ -0,0 +1,9 @@ +package org.smartregister.configuration; + +public interface ConfigurableNavigationOptions { + + public ToolbarOptions getToolbarOptions(); + + public BottomNavigationOptions getBottomNavigationOptions(); + +} diff --git a/opensrp-app/src/main/java/org/smartregister/configuration/ModuleConfiguration.java b/opensrp-app/src/main/java/org/smartregister/configuration/ModuleConfiguration.java index 54b716387..6657230f5 100644 --- a/opensrp-app/src/main/java/org/smartregister/configuration/ModuleConfiguration.java +++ b/opensrp-app/src/main/java/org/smartregister/configuration/ModuleConfiguration.java @@ -83,8 +83,8 @@ public String getRegisterTitle() { return builder.registerTitle; } - public Class getToolbarOptions() { - return builder.toolbarOptions; + public Class getNavigationOptions() { + return builder.navigationOptions; } public int getMaxCheckInDurationInMinutes() { @@ -127,7 +127,7 @@ public static class Builder { @NonNull private Class jsonFormActivity; - private Class toolbarOptions; + private Class navigationOptions; private boolean isBottomNavigationEnabled; @@ -163,8 +163,8 @@ public Builder setModuleMetadata(@NonNull ModuleMetadata moduleMetadata) { return this; } - public Builder setToolbarOptions(@Nullable Class toolbarOptions) { - this.toolbarOptions = toolbarOptions; + public Builder setNavigationOptions(@Nullable Class navigationOptions) { + this.navigationOptions = navigationOptions; return this; } diff --git a/opensrp-app/src/main/java/org/smartregister/configuration/ToolbarOptions.java b/opensrp-app/src/main/java/org/smartregister/configuration/ToolbarOptions.java index ff4385b70..d8471c424 100644 --- a/opensrp-app/src/main/java/org/smartregister/configuration/ToolbarOptions.java +++ b/opensrp-app/src/main/java/org/smartregister/configuration/ToolbarOptions.java @@ -2,16 +2,27 @@ import org.smartregister.view.dialog.DialogOptionModel; +import java.util.ArrayList; +import java.util.List; + public interface ToolbarOptions { public int getLogoResourceId(); + default int getToolBarColor() { + return 0; + } + public int getFabTextStringResource(); public boolean isFabEnabled(); public boolean isNewToolbarEnabled(); + default List getHiddenToolOptions() { + return new ArrayList<>(); + } + public DialogOptionModel getDialogOptionModel(); } diff --git a/opensrp-app/src/main/java/org/smartregister/job/SyncPractitionersByIdAndRoleJob.java b/opensrp-app/src/main/java/org/smartregister/job/SyncPractitionersByIdAndRoleJob.java new file mode 100644 index 000000000..6f5bea030 --- /dev/null +++ b/opensrp-app/src/main/java/org/smartregister/job/SyncPractitionersByIdAndRoleJob.java @@ -0,0 +1,21 @@ +package org.smartregister.job; + +import android.content.Intent; + +import androidx.annotation.NonNull; + +import org.smartregister.AllConstants; +import org.smartregister.sync.intent.SyncChwPractitionersByIdAndRoleIntentService; + +public class SyncPractitionersByIdAndRoleJob extends BaseJob { + + public static final String TAG = "SyncPractitionersByIdAndRoleJob"; + + @NonNull + @Override + protected Result onRunJob(@NonNull Params params) { + Intent intent = new Intent(getApplicationContext(), SyncChwPractitionersByIdAndRoleIntentService.class); + getApplicationContext().startService(intent); + return params != null && params.getExtras().getBoolean(AllConstants.INTENT_KEY.TO_RESCHEDULE, false) ? Result.RESCHEDULE : Result.SUCCESS; + } +} diff --git a/opensrp-app/src/main/java/org/smartregister/listener/BottomNavigationListener.java b/opensrp-app/src/main/java/org/smartregister/listener/BottomNavigationListener.java index 842f4f0d2..75be6c185 100644 --- a/opensrp-app/src/main/java/org/smartregister/listener/BottomNavigationListener.java +++ b/opensrp-app/src/main/java/org/smartregister/listener/BottomNavigationListener.java @@ -1,15 +1,17 @@ package org.smartregister.listener; import android.app.Activity; +import android.view.MenuItem; + import androidx.annotation.NonNull; + import com.google.android.material.bottomnavigation.BottomNavigationView; -import android.view.MenuItem; import org.smartregister.R; import org.smartregister.view.activity.BaseRegisterActivity; public class BottomNavigationListener implements BottomNavigationView.OnNavigationItemSelectedListener { - private Activity context; + protected Activity context; public BottomNavigationListener(Activity context) { this.context = context; diff --git a/opensrp-app/src/main/java/org/smartregister/listener/ConfigurableBottomNavigationListener.java b/opensrp-app/src/main/java/org/smartregister/listener/ConfigurableBottomNavigationListener.java new file mode 100644 index 000000000..dfe8bfb6d --- /dev/null +++ b/opensrp-app/src/main/java/org/smartregister/listener/ConfigurableBottomNavigationListener.java @@ -0,0 +1,25 @@ +package org.smartregister.listener; + +import android.app.Activity; +import android.view.MenuItem; + +import androidx.annotation.NonNull; + +import org.smartregister.configuration.BottomNavigationOptionsModel; + +public class ConfigurableBottomNavigationListener extends BottomNavigationListener { + + private BottomNavigationOptionsModel bottomNavigationOptionsModel; + + public ConfigurableBottomNavigationListener(Activity context, BottomNavigationOptionsModel model) { + super(context); + this.bottomNavigationOptionsModel = model; + } + + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) { + bottomNavigationOptionsModel.onBottomOptionSelection(context, menuItem); + return true; + } + +} diff --git a/opensrp-app/src/main/java/org/smartregister/login/task/RemoteLoginTask.java b/opensrp-app/src/main/java/org/smartregister/login/task/RemoteLoginTask.java index df45bee1b..b65378f58 100644 --- a/opensrp-app/src/main/java/org/smartregister/login/task/RemoteLoginTask.java +++ b/opensrp-app/src/main/java/org/smartregister/login/task/RemoteLoginTask.java @@ -21,6 +21,8 @@ import org.smartregister.account.AccountHelper; import org.smartregister.account.AccountResponse; import org.smartregister.domain.LoginResponse; +import org.smartregister.domain.Practitioner; +import org.smartregister.domain.PractitionerRole; import org.smartregister.domain.jsonmapping.User; import org.smartregister.event.Listener; import org.smartregister.sync.helper.SyncSettingsServiceHelper; @@ -140,6 +142,11 @@ protected LoginResponse doInBackground(Void... params) { } } + + // Save the registered ANM + getOpenSRPContext().allSharedPreferences().updateANMUserName(mUsername); + + fetchUserRole(); } else { if (response.getAccountError() != null && response.getAccountError().getError() != null) { return LoginResponse.valueOf(response.getAccountError().getError().toUpperCase(Locale.ENGLISH)); @@ -162,6 +169,37 @@ protected LoginResponse doInBackground(Void... params) { return loginResponse; } + protected void fetchUserRole() { + Practitioner[] practitioners = getOpenSRPContext().httpAgent().fetchPractitioners(); + PractitionerRole[] practitionerRoles = getOpenSRPContext().httpAgent().fetchPractitionerRoles(); + + if (practitioners == null) { + return; + } + + Practitioner loggedInPractitioner = null; + for (Practitioner practitioner : practitioners) { + if (practitioner != null && mUsername.equals(practitioner.getUsername())) { + loggedInPractitioner = practitioner; + } + } + + if (loggedInPractitioner != null && practitionerRoles != null) { + + PractitionerRole loggedInPractitionerRole = null; + for (PractitionerRole practitionerRole : practitionerRoles) { + if (loggedInPractitioner.getIdentifier().equals(practitionerRole.getPractitionerIdentifier())) { + loggedInPractitionerRole = practitionerRole; + } + } + + if (loggedInPractitionerRole != null) { + getOpenSRPContext().allSharedPreferences().setUserPractitionerRole(loggedInPractitionerRole.getCode().getText()); + getOpenSRPContext().allSharedPreferences().setUserPractitionerIdentifier(loggedInPractitionerRole.getPractitionerIdentifier()); + } + } + } + @Override protected void onProgressUpdate(Integer... messageIdentifier) { mLoginView.updateProgressMessage(getOpenSRPContext().applicationContext().getString(messageIdentifier[0])); diff --git a/opensrp-app/src/main/java/org/smartregister/repository/AllSharedPreferences.java b/opensrp-app/src/main/java/org/smartregister/repository/AllSharedPreferences.java index 2b083f3bb..e96c18fdb 100644 --- a/opensrp-app/src/main/java/org/smartregister/repository/AllSharedPreferences.java +++ b/opensrp-app/src/main/java/org/smartregister/repository/AllSharedPreferences.java @@ -2,8 +2,8 @@ import android.content.SharedPreferences; -import androidx.annotation.Nullable; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import org.apache.commons.lang3.StringUtils; import org.smartregister.AllConstants; @@ -33,6 +33,8 @@ public class AllSharedPreferences { public static final String FORMS_VERSION = "FORMS_VERSION"; private static final String ENCRYPTED_PASSPHRASE_KEY = "ENCRYPTED_PASSPHRASE_KEY"; private static final String DB_ENCRYPTION_VERSION = "DB_ENCRYPTION_VERSION"; + private static final String USER_PRACTITIONER_ROLE = "USER_PRACTITIONER_ROLE"; + private static final String USER_PRACTITIONER_IDENTIFIER = "USER_PRACTITIONER_IDENTIFIER"; private SharedPreferences preferences; public AllSharedPreferences(SharedPreferences preferences) { @@ -385,5 +387,24 @@ public int getDBEncryptionVersion() { public void setDBEncryptionVersion(int encryptionVersion) { preferences.edit().putInt(DB_ENCRYPTION_VERSION, encryptionVersion).commit(); } + + @Nullable + public String getUserPractitionerRole() { + return preferences.getString(USER_PRACTITIONER_ROLE, null); + } + + @Nullable + public String getUserPractitionerIdentifier() { + return preferences.getString(USER_PRACTITIONER_IDENTIFIER, null); + } + + public void setUserPractitionerRole(String practitionerRole) { + preferences.edit().putString(USER_PRACTITIONER_ROLE, practitionerRole).commit(); + } + + public void setUserPractitionerIdentifier(String identifier) { + preferences.edit().putString(USER_PRACTITIONER_IDENTIFIER, identifier).commit(); + + } } diff --git a/opensrp-app/src/main/java/org/smartregister/repository/PractitionerRepository.java b/opensrp-app/src/main/java/org/smartregister/repository/PractitionerRepository.java new file mode 100644 index 000000000..01447cfff --- /dev/null +++ b/opensrp-app/src/main/java/org/smartregister/repository/PractitionerRepository.java @@ -0,0 +1,89 @@ +package org.smartregister.repository; + +import android.content.ContentValues; + +import androidx.annotation.NonNull; + +import net.sqlcipher.Cursor; +import net.sqlcipher.database.SQLiteDatabase; + +import org.smartregister.domain.Practitioner; + +import java.util.ArrayList; +import java.util.List; + +import timber.log.Timber; + +public class PractitionerRepository extends BaseRepository { + + protected static final String ID = "id"; + protected static final String IDENTIFIER = "identifier"; + protected static final String IS_ACTIVE = "is_active"; + protected static final String NAME = "name"; + protected static final String USER_ID = "user_id"; + protected static final String USERNAME = "username"; + + private static final String PRACTITIONER_TABLE = "practitioner"; + + private static final String CREATE_PRACTITIONER_TABLE = + "CREATE TABLE IF NOT EXISTS " + PRACTITIONER_TABLE + " (" + + ID + " VARCHAR NOT NULL PRIMARY KEY," + + IDENTIFIER + " VARCHAR NOT NULL," + + IS_ACTIVE + " INTEGER NOT NULL," + + NAME + " VARCHAR NOT NULL," + + USER_ID + " VARCHAR NOT NULL," + + USERNAME + " VARCHAR NOT NULL)"; + + public static void createTable(SQLiteDatabase database) { + database.execSQL(CREATE_PRACTITIONER_TABLE); + } + + public void addOrUpdate(Practitioner practitioner) { + ContentValues contentValues = new ContentValues(); + contentValues.put(ID, practitioner.getIdentifier()); + contentValues.put(IDENTIFIER, practitioner.getIdentifier()); + contentValues.put(IS_ACTIVE, practitioner.getActive()); + contentValues.put(NAME, practitioner.getName()); + contentValues.put(USER_ID, practitioner.getUserId()); + contentValues.put(USERNAME, practitioner.getUsername()); + getWritableDatabase().replace(PRACTITIONER_TABLE, null, contentValues); + + } + + protected Practitioner readCursor(@NonNull Cursor cursor) { + Practitioner practitioner = new Practitioner(); + practitioner.setIdentifier(cursor.getString(cursor.getColumnIndex(IDENTIFIER))); + practitioner.setName(cursor.getString(cursor.getColumnIndex(NAME))); + practitioner.setActive(cursor.getInt(cursor.getColumnIndex(IS_ACTIVE)) > 0); + practitioner.setUserId(cursor.getString(cursor.getColumnIndex(USER_ID))); + practitioner.setUsername(cursor.getString(cursor.getColumnIndex(USERNAME))); + + return practitioner; + } + + + public List getAllPractitioners() { + List practitionerList = new ArrayList<>(); + try (Cursor cursor = getReadableDatabase().rawQuery("SELECT * FROM " + PRACTITIONER_TABLE, + null)) { + while (cursor.moveToNext()) { + practitionerList.add(readCursor(cursor)); + } + } + return practitionerList; + } + + public Practitioner getPractitionerByIdentifier(String identifier) { + Practitioner practitioner = null; + try (Cursor cursor = getReadableDatabase().rawQuery("SELECT * FROM " + PRACTITIONER_TABLE + + " WHERE " + IDENTIFIER + " =?", new String[]{identifier})) { + while (cursor.moveToNext()) { + practitioner = readCursor(cursor); + } + } catch (Exception e) { + Timber.e(e); + } + return practitioner; + } + +} diff --git a/opensrp-app/src/main/java/org/smartregister/repository/TaskRepository.java b/opensrp-app/src/main/java/org/smartregister/repository/TaskRepository.java index 45213771c..1eb466ab7 100644 --- a/opensrp-app/src/main/java/org/smartregister/repository/TaskRepository.java +++ b/opensrp-app/src/main/java/org/smartregister/repository/TaskRepository.java @@ -718,6 +718,7 @@ public int getUnsyncedCreatedTasksAndTaskStatusCount() { return unsyncedRecordsCount; } + @NonNull public Set getTasksByJurisdictionAndPlan(@NonNull String jurisdictionId, String planIdentifier) { String query = "SELECT * FROM " + TASK_TABLE + " WHERE " + GROUP_ID + " = ? AND " + PLAN_ID + " = ?"; diff --git a/opensrp-app/src/main/java/org/smartregister/repository/dao/TaskDaoImpl.java b/opensrp-app/src/main/java/org/smartregister/repository/dao/TaskDaoImpl.java index 4cb9d61b1..e3b24f067 100644 --- a/opensrp-app/src/main/java/org/smartregister/repository/dao/TaskDaoImpl.java +++ b/opensrp-app/src/main/java/org/smartregister/repository/dao/TaskDaoImpl.java @@ -92,7 +92,7 @@ public org.smartregister.domain.Task updateTask(org.smartregister.domain.Task ta @Override public List findTasksByJurisdiction(String jurisdiction,String planIdentifier) { - return getTasksByJurisdictionAndPlan(jurisdiction,planIdentifier) + return getTasksByJurisdictionAndPlan(jurisdiction, planIdentifier) .stream() .map(TaskConverter::convertTasktoFihrResource) .collect(Collectors.toList()); diff --git a/opensrp-app/src/main/java/org/smartregister/service/HTTPAgent.java b/opensrp-app/src/main/java/org/smartregister/service/HTTPAgent.java index cec29ee99..799f8a443 100644 --- a/opensrp-app/src/main/java/org/smartregister/service/HTTPAgent.java +++ b/opensrp-app/src/main/java/org/smartregister/service/HTTPAgent.java @@ -27,6 +27,8 @@ import org.smartregister.compression.GZIPCompression; import org.smartregister.domain.DownloadStatus; import org.smartregister.domain.LoginResponse; +import org.smartregister.domain.Practitioner; +import org.smartregister.domain.PractitionerRole; import org.smartregister.domain.ProfileImage; import org.smartregister.domain.Response; import org.smartregister.domain.ResponseErrorStatus; @@ -36,6 +38,7 @@ import org.smartregister.security.SecurityHelper; import org.smartregister.ssl.OpensrpSSLHelper; import org.smartregister.util.Utils; +import org.smartregister.view.contract.IView; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -61,7 +64,9 @@ import java.net.URL; import java.net.URLConnection; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import javax.net.ssl.HttpsURLConnection; @@ -107,6 +112,8 @@ public class HTTPAgent { private Gson gson; private static final String DETAILS_URL = "/user-details?anm-id="; + private static final String PRACTITIONER_ROLE_URL = "/rest/practitionerRole"; + private static final String PRACTITIONER_URL = "/rest/practitioner"; public HTTPAgent(Context context, AllSharedPreferences @@ -1022,6 +1029,88 @@ public AccountConfiguration fetchOAuthConfiguration() { return null; } + private void initializeAdapter(Set iviews) { + Set mySet = new HashSet<>(); + + initializeAdapter(mySet); + } + + public Practitioner[] fetchPractitioners() { + + String baseUrl = configuration.dristhiBaseURL(); + + if (baseUrl.endsWith("/")) { + baseUrl = baseUrl.substring(0, baseUrl.length() - 1); + } + + baseUrl = baseUrl + PRACTITIONER_URL; + + HttpURLConnection urlConnection = null; + + InputStream inputStream = null; + try { + + urlConnection = initializeHttp(baseUrl, true); + + int statusCode = urlConnection.getResponseCode(); + if (statusCode == HttpStatus.SC_OK) { + + inputStream = urlConnection.getInputStream(); + + String responseString = IOUtils.toString(inputStream); + + return gson.fromJson(responseString, Practitioner[].class); + } + + } catch (IOException | URISyntaxException e) { + Timber.e(e); + } finally { + + closeConnection(urlConnection); + closeIOStream(inputStream); + + } + return null; + } + + public PractitionerRole[] fetchPractitionerRoles() { + + String baseUrl = configuration.dristhiBaseURL(); + + if (baseUrl.endsWith("/")) { + baseUrl = baseUrl.substring(0, baseUrl.length() - 1); + } + + baseUrl = baseUrl + PRACTITIONER_ROLE_URL; + + HttpURLConnection urlConnection = null; + + InputStream inputStream = null; + try { + + urlConnection = initializeHttp(baseUrl, true); + + int statusCode = urlConnection.getResponseCode(); + if (statusCode == HttpStatus.SC_OK) { + + inputStream = urlConnection.getInputStream(); + + String responseString = IOUtils.toString(inputStream); + + return gson.fromJson(responseString, PractitionerRole[].class); + } + + } catch (IOException | URISyntaxException e) { + Timber.e(e); + } finally { + + closeConnection(urlConnection); + closeIOStream(inputStream); + + } + return null; + } + private void closeConnection(HttpURLConnection urlConnection) { if (urlConnection != null) { try { diff --git a/opensrp-app/src/main/java/org/smartregister/sync/helper/PractitionerSyncHelper.java b/opensrp-app/src/main/java/org/smartregister/sync/helper/PractitionerSyncHelper.java new file mode 100644 index 000000000..6a90dc2f3 --- /dev/null +++ b/opensrp-app/src/main/java/org/smartregister/sync/helper/PractitionerSyncHelper.java @@ -0,0 +1,96 @@ +package org.smartregister.sync.helper; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import org.json.JSONException; +import org.smartregister.CoreLibrary; +import org.smartregister.domain.Practitioner; +import org.smartregister.domain.Response; +import org.smartregister.exception.NoHttpResponseException; +import org.smartregister.repository.AllSharedPreferences; +import org.smartregister.repository.PractitionerRepository; +import org.smartregister.service.HTTPAgent; + +import java.text.MessageFormat; +import java.util.List; + +import timber.log.Timber; + +/** + * Created by Allan Onchuru on 20/03/2021 + */ + +public class PractitionerSyncHelper { + + private final PractitionerRepository practitionerRepository; + private HTTPAgent httpAgent; + private Gson gson; + protected static PractitionerSyncHelper instance; + private final AllSharedPreferences allSharedPreferences; + private static final String PRACTITIONER_URL = "/rest/practitioner"; + private static final String PRACTITIONERS_BY_ID_AND_ROLE_URL = PRACTITIONER_URL + "/report-to"; + private static final String PRACTITIONER_IDENTIFIER = "practitionerIdentifier"; + private static final String PRACTITIONER_ROLE_CODE = "code"; + + + public static PractitionerSyncHelper getInstance() { + if (instance == null) { + instance = new PractitionerSyncHelper(CoreLibrary.getInstance().context().getPractitionerRepository()); + } + return instance; + } + + private PractitionerSyncHelper(PractitionerRepository practitionerRepository) { + this.practitionerRepository = practitionerRepository; + this.allSharedPreferences = CoreLibrary.getInstance().context().allSharedPreferences(); + this.httpAgent = CoreLibrary.getInstance().context().getHttpAgent(); + this.gson = new Gson(); + } + + + public void syncChwPractitionersByIdAndRoleFromServer() { + String practitionerIdentifier = allSharedPreferences.getUserPractitionerIdentifier(); + String code = "Community Health Worker"; + try { + String response = syncPractitioners(practitionerIdentifier, code); + List practitioners = gson.fromJson(response, new TypeToken>() { + }.getType()); + for (Practitioner practitioner : practitioners) { + practitionerRepository.addOrUpdate(practitioner); + } + } catch (Exception ex) { + Timber.e(ex); + } + } + + private String syncPractitioners(String practitionerIdentifier, String code) throws JSONException, NoHttpResponseException { + if (httpAgent == null) { + throw new IllegalArgumentException(PRACTITIONERS_BY_ID_AND_ROLE_URL + " HTTPAgent agent is null"); + } + + String baseUrl = getFormattedBaseUrl(); + + Response resp = httpAgent.fetch( + MessageFormat.format("{0}{1}{2}", + baseUrl, PRACTITIONERS_BY_ID_AND_ROLE_URL, + "?" + PRACTITIONER_IDENTIFIER + "=" + practitionerIdentifier + + "&" + PRACTITIONER_ROLE_CODE + "=" + code)); + + if (resp.isFailure()) { + throw new NoHttpResponseException(PRACTITIONERS_BY_ID_AND_ROLE_URL + " not data returned"); + } + + return resp.payload().toString(); + } + + public String getFormattedBaseUrl() { + String baseUrl = CoreLibrary.getInstance().context().configuration().dristhiBaseURL(); + String endString = "/"; + if (baseUrl.endsWith(endString)) { + baseUrl = baseUrl.substring(0, baseUrl.lastIndexOf(endString)); + } + return baseUrl; + } + +} diff --git a/opensrp-app/src/main/java/org/smartregister/sync/intent/SyncChwPractitionersByIdAndRoleIntentService.java b/opensrp-app/src/main/java/org/smartregister/sync/intent/SyncChwPractitionersByIdAndRoleIntentService.java new file mode 100644 index 000000000..78e828f14 --- /dev/null +++ b/opensrp-app/src/main/java/org/smartregister/sync/intent/SyncChwPractitionersByIdAndRoleIntentService.java @@ -0,0 +1,29 @@ +package org.smartregister.sync.intent; + +import android.content.Intent; + +import org.smartregister.sync.helper.PractitionerSyncHelper; + +import timber.log.Timber; + +public class SyncChwPractitionersByIdAndRoleIntentService extends BaseSyncIntentService { + + private static final String TAG = SyncChwPractitionersByIdAndRoleIntentService.class.getCanonicalName(); + + public SyncChwPractitionersByIdAndRoleIntentService() { + super(TAG); + } + + @Override + protected void onHandleIntent(Intent intent) { + super.onHandleIntent(intent); + + PractitionerSyncHelper practitionerSyncHelper = PractitionerSyncHelper.getInstance(); + + try { + practitionerSyncHelper.syncChwPractitionersByIdAndRoleFromServer(); + } catch (Exception ex) { + Timber.e(ex); + } + } +} diff --git a/opensrp-app/src/main/java/org/smartregister/view/activity/BaseConfigurableRegisterActivity.java b/opensrp-app/src/main/java/org/smartregister/view/activity/BaseConfigurableRegisterActivity.java index cb0ffc350..fffa10ad1 100644 --- a/opensrp-app/src/main/java/org/smartregister/view/activity/BaseConfigurableRegisterActivity.java +++ b/opensrp-app/src/main/java/org/smartregister/view/activity/BaseConfigurableRegisterActivity.java @@ -18,8 +18,13 @@ import org.smartregister.R; import org.smartregister.client.utils.domain.Form; import org.smartregister.commonregistry.CommonPersonObjectClient; +import org.smartregister.configuration.BottomNavigationOptions; +import org.smartregister.configuration.ConfigurableNavigationOptions; import org.smartregister.configuration.ModuleConfiguration; import org.smartregister.configuration.ModuleMetadata; +import org.smartregister.helper.BottomNavigationHelper; +import org.smartregister.listener.ConfigurableBottomNavigationListener; +import org.smartregister.util.ConfigurationInstancesHelper; import org.smartregister.util.JsonFormUtils; import org.smartregister.util.Utils; import org.smartregister.view.contract.BaseRegisterContract; @@ -46,12 +51,13 @@ public class BaseConfigurableRegisterActivity extends BaseRegisterActivity { protected String moduleName; protected ModuleConfiguration moduleConfiguration; + private ConfigurableNavigationOptions navigationOptions; @Override protected void onCreate(Bundle savedInstanceState) { moduleName = Utils.extractModuleName(getIntent()); fetchModuleConfiguration(); - + initNavigationOptions(); super.onCreate(savedInstanceState); onStartActivityWithAction(); } @@ -61,6 +67,13 @@ private void fetchModuleConfiguration() { .getModuleConfiguration(getModuleName()); } + private void initNavigationOptions() { + Class navigationOptionsClass = moduleConfiguration.getNavigationOptions(); + if (navigationOptionsClass != null) { + this.navigationOptions = ConfigurationInstancesHelper.newInstance(navigationOptionsClass); + } + } + public String getModuleName() { return moduleName; } @@ -86,12 +99,23 @@ protected void onStartActivityWithAction() { @Override protected void registerBottomNavigation() { try { - View bottomNavGeneralView = findViewById(org.smartregister.R.id.bottom_navigation); - if (bottomNavGeneralView instanceof BottomNavigationView) { - BottomNavigationView bottomNavigationView = (BottomNavigationView) bottomNavGeneralView; - if (!getModuleConfiguration().isBottomNavigationEnabled()) { + if (!getModuleConfiguration().isBottomNavigationEnabled()) { + View bottomNavGeneralView = findViewById(org.smartregister.R.id.bottom_navigation); + if (bottomNavGeneralView instanceof BottomNavigationView) { + BottomNavigationView bottomNavigationView = (BottomNavigationView) bottomNavGeneralView; bottomNavigationView.setVisibility(View.GONE); } + } else { + BottomNavigationOptions bottomNavigationOptions = navigationOptions.getBottomNavigationOptions(); + if (bottomNavigationOptions != null) { + BottomNavigationView bottomNavigationView = findViewById(bottomNavigationOptions.getBottomNavigationLayoutId()); + bottomNavigationView.setOnNavigationItemSelectedListener(new ConfigurableBottomNavigationListener(this, + bottomNavigationOptions.getBottomNavigationOptionsModel())); + bottomNavigationView.setVisibility(View.VISIBLE); + BottomNavigationHelper bottomNavigationHelper = new BottomNavigationHelper(); + bottomNavigationHelper.disableShiftMode(bottomNavigationView); + bottomNavigationView.getMenu().findItem(bottomNavigationOptions.checkedItemId()).setChecked(true); + } } } catch (NoSuchFieldError e) { // This error occurs because the ID cannot be found on some client applications because the layout @@ -109,6 +133,7 @@ protected void initializePresenter() { protected BaseRegisterFragment getRegisterFragment() { BaseConfigurableRegisterFragment baseConfigurableRegisterFragment = new BaseConfigurableRegisterFragment(); baseConfigurableRegisterFragment.setModuleConfiguration(getModuleConfiguration()); + baseConfigurableRegisterFragment.setToolbarOptions(navigationOptions.getToolbarOptions()); return baseConfigurableRegisterFragment; } diff --git a/opensrp-app/src/main/java/org/smartregister/view/fragment/BaseConfigurableRegisterFragment.java b/opensrp-app/src/main/java/org/smartregister/view/fragment/BaseConfigurableRegisterFragment.java index 08389ca0a..9951195e7 100644 --- a/opensrp-app/src/main/java/org/smartregister/view/fragment/BaseConfigurableRegisterFragment.java +++ b/opensrp-app/src/main/java/org/smartregister/view/fragment/BaseConfigurableRegisterFragment.java @@ -34,6 +34,7 @@ import org.smartregister.view.activity.BaseConfigurableRegisterActivity; import org.smartregister.view.activity.BaseRegisterActivity; import org.smartregister.view.contract.BaseRegisterFragmentContract; +import org.smartregister.view.dialog.DialogOptionModel; import org.smartregister.view.dialog.NoMatchDialogFragment; import org.smartregister.view.model.BaseConfigurableRegisterFragmentModel; import org.smartregister.view.presenter.BaseConfigurableRegisterFragmentPresenter; @@ -50,6 +51,7 @@ public class BaseConfigurableRegisterFragment extends BaseRegisterFragment { private static final String DUE_FILTER_TAG = "PRESSED"; + private View navbarContainer; private View dueOnlyLayout; private boolean dueFilterActive = false; private ModuleRegisterQueryProviderContract moduleRegisterQueryProvider; @@ -59,10 +61,10 @@ public class BaseConfigurableRegisterFragment extends BaseRegisterFragment { public void setModuleConfiguration(@NonNull ModuleConfiguration moduleConfiguration) { moduleRegisterQueryProvider = ConfigurationInstancesHelper.newInstance(moduleConfiguration.getRegisterQueryProvider()); this.moduleConfiguration = moduleConfiguration; - Class toolbarOptionsClass = moduleConfiguration.getToolbarOptions(); - if (toolbarOptionsClass != null) { - this.toolbarOptions = ConfigurationInstancesHelper.newInstance(toolbarOptionsClass); - } + } + + public void setToolbarOptions(ToolbarOptions toolbarOptions) { + this.toolbarOptions = toolbarOptions; } public ModuleConfiguration getModuleConfiguration() { @@ -85,7 +87,7 @@ protected int getLayout() { @Override public void setupViews(View view) { super.setupViews(view); - + navbarContainer = view.findViewById(R.id.register_nav_bar_container); if (toolbarOptions != null && toolbarOptions.isNewToolbarEnabled()) { initializeConfigurableLayoutViews(view); return; @@ -128,7 +130,6 @@ public void setupViews(View view) { titleView.setPadding(0, titleView.getTop(), titleView.getPaddingRight(), titleView.getPaddingBottom()); } - View navbarContainer = view.findViewById(R.id.register_nav_bar_container); navbarContainer.setFocusable(false); View topLeftLayout = view.findViewById(R.id.top_left_layout); @@ -153,6 +154,10 @@ public void setupViews(View view) { } public void initializeConfigurableLayoutViews(View view) { + // Update Toolbar color + if (toolbarOptions.getToolBarColor() > 0) { + navbarContainer.setBackgroundColor(toolbarOptions.getToolBarColor()); + } // Update logo ImageView logo = view.findViewById(R.id.top_left_logo); if (logo != null && toolbarOptions.getLogoResourceId() > 0) { @@ -163,6 +168,15 @@ public void initializeConfigurableLayoutViews(View view) { if (backButton != null) backButton.setOnClickListener(v -> getActivity().finish()); + + // Hide unwanted toolbar options + List hiddenToolbarOptions = toolbarOptions.getHiddenToolOptions(); + if (hiddenToolbarOptions.size() > 0) { + for (int layoutId : hiddenToolbarOptions) { + view.findViewById(layoutId).setVisibility(View.GONE); + } + } + ExtendedFloatingActionButton addClientsFab = view.findViewById(R.id.add_new_client_fab); if (addClientsFab != null) { setupAddClientFab(addClientsFab); @@ -172,7 +186,9 @@ public void initializeConfigurableLayoutViews(View view) { if (registerSelect != null) { registerSelect.setOnClickListener(v -> { if (getActivity() instanceof BaseConfigurableRegisterActivity) { - ((BaseConfigurableRegisterActivity) getActivity()).showFragmentDialog(toolbarOptions.getDialogOptionModel()); + DialogOptionModel dialogOptionModel = toolbarOptions.getDialogOptionModel(); + if (dialogOptionModel != null) + ((BaseConfigurableRegisterActivity) getActivity()).showFragmentDialog(dialogOptionModel); } }); } diff --git a/opensrp-app/src/test/java/org/smartregister/view/fragment/BaseConfigurableRegisterFragmentTest.java b/opensrp-app/src/test/java/org/smartregister/view/fragment/BaseConfigurableRegisterFragmentTest.java index d7de4e633..e367b33aa 100644 --- a/opensrp-app/src/test/java/org/smartregister/view/fragment/BaseConfigurableRegisterFragmentTest.java +++ b/opensrp-app/src/test/java/org/smartregister/view/fragment/BaseConfigurableRegisterFragmentTest.java @@ -75,7 +75,7 @@ private void setupModuleConfiguration() { moduleConfiguration = Mockito.mock(ModuleConfiguration.class, Mockito.CALLS_REAL_METHODS); Mockito.doReturn(MockRegisterQueryProvider.class).when(moduleConfiguration).getRegisterQueryProvider(); Mockito.doReturn(FormActivity.class).when(moduleConfiguration).getJsonFormActivity(); - Mockito.doReturn(ToolbarOptions.class).when(moduleConfiguration).getToolbarOptions(); + Mockito.doReturn(ToolbarOptions.class).when(moduleConfiguration).getNavigationOptions(); CoreLibrary.getInstance().addModuleConfiguration(moduleName, moduleConfiguration); }