/*
* Copyright (c) 2014. The Trustees of Indiana University.
*
* This version of the code is licensed under the MPL 2.0 Open Source license with additional
* healthcare disclaimer. If the user is an entity intending to commercialize any application
* that uses this code in a for-profit venture, please contact the copyright holder.
*/
package com.muzima.service;
import android.content.Intent;
import android.util.Log;
import com.muzima.MuzimaApplication;
import com.muzima.R;
import com.muzima.api.context.Context;
import com.muzima.api.exception.AuthenticationException;
import com.muzima.api.model.Cohort;
import com.muzima.api.model.CohortData;
import com.muzima.api.model.Concept;
import com.muzima.api.model.Encounter;
import com.muzima.api.model.Form;
import com.muzima.api.model.FormTemplate;
import com.muzima.api.model.Location;
import com.muzima.api.model.Notification;
import com.muzima.api.model.Observation;
import com.muzima.api.model.Patient;
import com.muzima.api.model.Provider;
import com.muzima.api.model.SetupConfiguration;
import com.muzima.api.model.SetupConfigurationTemplate;
import com.muzima.controller.CohortController;
import com.muzima.controller.ConceptController;
import com.muzima.controller.EncounterController;
import com.muzima.controller.FormController;
import com.muzima.controller.LocationController;
import com.muzima.controller.NotificationController;
import com.muzima.controller.ObservationController;
import com.muzima.controller.PatientController;
import com.muzima.controller.ProviderController;
import com.muzima.controller.SetupConfigurationController;
import com.muzima.utils.Constants;
import com.muzima.utils.Constants.SERVER_CONNECTIVITY_STATUS;
import com.muzima.utils.NetworkUtils;
import com.muzima.utils.StringUtils;
import com.muzima.view.progressdialog.ProgressDialogUpdateIntentService;
import org.apache.lucene.queryParser.ParseException;
import java.io.IOException;
import java.net.ConnectException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static com.muzima.utils.Constants.DataSyncServiceConstants.SyncStatusConstants;
import static com.muzima.utils.Constants.LOCAL_PATIENT;
import static java.util.Collections.singleton;
public class MuzimaSyncService {
private static final String TAG = "MuzimaSyncService";
private MuzimaApplication muzimaApplication;
private FormController formController;
private ConceptController conceptController;
private CohortController cohortController;
private PatientController patientController;
private ObservationController observationController;
private final CohortPrefixPreferenceService cohortPrefixPreferenceService;
private EncounterController encounterController;
private NotificationController notificationController;
private LocationController locationController;
private ProviderController providerController;
private SetupConfigurationController setupConfigurationController;
public MuzimaSyncService(MuzimaApplication muzimaContext) {
this.muzimaApplication = muzimaContext;
cohortPrefixPreferenceService = muzimaApplication.getCohortPrefixesPreferenceService();
formController = muzimaApplication.getFormController();
conceptController = muzimaApplication.getConceptController();
cohortController = muzimaApplication.getCohortController();
patientController = muzimaApplication.getPatientController();
observationController = muzimaApplication.getObservationController();
encounterController = muzimaApplication.getEncounterController();
notificationController = muzimaApplication.getNotificationController();
locationController = muzimaApplication.getLocationController();
providerController = muzimaApplication.getProviderController();
setupConfigurationController = muzimaApplication.getSetupConfigurationController();
}
public int authenticate(String[] credentials){
return authenticate(credentials, false);
}
public int authenticate(String[] credentials, boolean isUpdatePasswordRequired) {
String username = credentials[0].trim();
String password = credentials[1];
String server = credentials[2];
Context muzimaContext = muzimaApplication.getMuzimaContext();
try {
// if(hasInvalidSpecialCharacter(username)){
// return SyncStatusConstants.INVALID_CHARACTER_IN_USERNAME;
// }
muzimaContext.openSession();
if (!muzimaContext.isAuthenticated()){
if(isUpdatePasswordRequired && !NetworkUtils.isConnectedToNetwork(muzimaApplication)) {
return SyncStatusConstants.LOCAL_CONNECTION_ERROR;
} else {
muzimaContext.authenticate(username, password, server, isUpdatePasswordRequired);
}
}
} catch (ConnectException e) {
Log.e(TAG, "ConnectException Exception thrown while authentication.", e);
return SyncStatusConstants.SERVER_CONNECTION_ERROR;
} catch (ParseException e) {
Log.e(TAG, "ParseException Exception thrown while authentication.", e);
return SyncStatusConstants.PARSING_ERROR;
} catch (MalformedURLException e) {
Log.e(TAG, "IOException Exception thrown while authentication.", e);
return SyncStatusConstants.MALFORMED_URL_ERROR;
} catch (IOException e) {
Log.e(TAG, "IOException Exception thrown while authentication.", e);
return SyncStatusConstants.AUTHENTICATION_ERROR;
} catch (AuthenticationException e) {
Log.e(TAG, "Exception thrown while authentication.", e);
return SyncStatusConstants.INVALID_CREDENTIALS_ERROR;
} finally {
if (muzimaContext != null)
muzimaContext.closeSession();
}
return SyncStatusConstants.AUTHENTICATION_SUCCESS;
}
private boolean hasInvalidSpecialCharacter(String username) {
String invalidCharacters = SyncStatusConstants.INVALID_CHARACTER_FOR_USERNAME;
for (int i = 0; i < invalidCharacters.length(); i++) {
String substring = invalidCharacters.substring(i, i + 1);
if (username.contains(substring)) {
return true;
}
}
return false;
}
public int[] downloadForms() {
int[] result = new int[3];
try {
long startDownloadForms = System.currentTimeMillis();
List<Form> allDownloadedForms = formController.downloadAllForms();
List<Form> allForms = formController.getAllAvailableForms();
int deletedFormCount = getDeletedFormCount(allDownloadedForms, allForms);
long endDownloadForms = System.currentTimeMillis();
List<Form> voidedForms = deleteVoidedForms(allDownloadedForms);
allDownloadedForms.removeAll(voidedForms);
formController.updateAllForms(allDownloadedForms);
long endSaveForms = System.currentTimeMillis();
Log.d(TAG, "In downloading forms: " + (endDownloadForms - startDownloadForms) / 1000 + " sec\n" +
"In replacing forms: " + (endDownloadForms - endSaveForms) / 1000 + " sec");
result[0] = SyncStatusConstants.SUCCESS;
result[1] = allDownloadedForms.size();
result[2] = deletedFormCount;
} catch (FormController.FormFetchException e) {
Log.e(TAG, "Exception when trying to download forms", e);
result[0] = SyncStatusConstants.DOWNLOAD_ERROR;
return result;
} catch (FormController.FormSaveException e) {
Log.e(TAG, "Exception when trying to save forms", e);
result[0] = SyncStatusConstants.SAVE_ERROR;
return result;
} catch (FormController.FormDeleteException e) {
Log.e(TAG, "Exception when trying to delete forms", e);
result[0] = SyncStatusConstants.DELETE_ERROR;
return result;
}
return result;
}
private int getDeletedFormCount(List<Form> allDownloadedForms, List<Form> allForms) {
int deletedFormCount = 0;
for (Form form : allForms) {
for (Form downloadedForm : allDownloadedForms) {
if (form.getUuid().equals(downloadedForm.getUuid()) && downloadedForm.isRetired()) {
deletedFormCount++;
}
}
}
return deletedFormCount;
}
private List<Form> deleteVoidedForms(List<Form> forms) throws FormController.FormDeleteException {
Log.i(TAG, "Voided forms are deleted");
List<Form> voidedForms = new ArrayList<Form>();
for (Form form : forms) {
if (form.isRetired()) {
voidedForms.add(form);
}
}
formController.deleteForms(voidedForms);
return voidedForms;
}
public int[] downloadFormTemplatesAndRelatedMetadata(String[] formIds, boolean replaceExistingTemplates) {
int[] result = new int[4];
try {
List<FormTemplate> formTemplates = formController.downloadFormTemplates(formIds);
Log.i(TAG, formTemplates.size() + " form template download successful");
List<Concept> concepts = conceptController.getRelatedConcepts(formTemplates);
List<Provider> providers = new ArrayList<Provider>();
Provider loggedInProvider = providerController.getLoggedInProvider(
muzimaApplication.getAuthenticatedUser().getSystemId());
if(loggedInProvider != null) providers.add(loggedInProvider);
if (replaceExistingTemplates) {
formController.replaceFormTemplates(formTemplates);
conceptController.newConcepts(concepts);
providerController.newProviders(providers);
}
else {
formController.saveFormTemplates(formTemplates);
}
conceptController.saveConcepts(concepts);
providerController.saveProviders(providers);
Log.i(TAG, "Form templates replaced");
result[0] = SyncStatusConstants.SUCCESS;
result[1] = formTemplates.size();
result[2] = concepts.size();
} catch (FormController.FormSaveException e) {
Log.e(TAG, "Exception when trying to save forms", e);
result[0] = SyncStatusConstants.SAVE_ERROR;
return result;
} catch (FormController.FormFetchException e) {
Log.e(TAG, "Exception when trying to download forms", e);
result[0] = SyncStatusConstants.DOWNLOAD_ERROR;
return result;
} catch (ConceptController.ConceptDownloadException e) {
Log.e(TAG, "Exception while parsing Concepts", e);
result[0] = SyncStatusConstants.DOWNLOAD_ERROR;
return result;
} catch (ConceptController.ConceptSaveException e) {
Log.e(TAG, "Exception when trying to download forms", e);
result[0] = SyncStatusConstants.SAVE_ERROR;
return result;
} catch (ConceptController.ConceptFetchException e) {
e.printStackTrace();
} catch (ProviderController.ProviderLoadException e) {
Log.e(TAG, "Exception while loading Providers", e);
result[0] = SyncStatusConstants.LOAD_ERROR;
return result;
} catch (ProviderController.ProviderSaveException e) {
Log.e(TAG, "Exception while saving Provider", e);
result[0] = SyncStatusConstants.SAVE_ERROR;
return result;
}
return result;
}
public int[] downloadFormTemplates(String[] formIds, boolean replaceExistingTemplates) {
int[] result = new int[4];
try {
List<FormTemplate> formTemplates = formController.downloadFormTemplates(formIds);
formTemplates.removeAll(Collections.singleton(null));
Log.i(TAG, formTemplates.size() + " form template download successful");
if (replaceExistingTemplates) {
formController.replaceFormTemplates(formTemplates);
}
else {
formController.saveFormTemplates(formTemplates);
}
Log.i(TAG, "Form templates replaced");
result[0] = SyncStatusConstants.SUCCESS;
result[1] = formTemplates.size();
} catch (FormController.FormSaveException e) {
Log.e(TAG, "Exception when trying to save forms", e);
result[0] = SyncStatusConstants.SAVE_ERROR;
return result;
} catch (FormController.FormFetchException e) {
Log.e(TAG, "Exception when trying to download forms", e);
result[0] = SyncStatusConstants.DOWNLOAD_ERROR;
return result;
}
return result;
}
public int[] downloadLocations(String[] locationIds) {
int[] result = new int[4];
try {
List<Location> locations = locationController.downloadLocationsFromServerByUuid(locationIds);
locationController.saveLocations(locations);
Log.i(TAG, "Downloaded "+locations.size()+" locations");
result[0] = SyncStatusConstants.SUCCESS;
result[1] = locations.size();
} catch (LocationController.LocationSaveException e) {
Log.e(TAG, "Exception when trying to save locations", e);
result[0] = SyncStatusConstants.SAVE_ERROR;
return result;
} catch (LocationController.LocationDownloadException e) {
Log.e(TAG, "Exception when trying to download locations", e);
result[0] = SyncStatusConstants.DOWNLOAD_ERROR;
return result;
}
return result;
}
public int[] downloadProviders(String[] providerIds) {
int[] result = new int[4];
try {
List<Provider> providers = providerController.downloadProvidersFromServerByUuid(providerIds);
providerController.saveProviders(providers);
Log.i(TAG, "Downloaded "+providers.size()+" providers");
result[0] = SyncStatusConstants.SUCCESS;
result[1] = providers.size();
} catch (ProviderController.ProviderSaveException e) {
Log.e(TAG, "Exception when trying to save providers", e);
result[0] = SyncStatusConstants.SAVE_ERROR;
return result;
} catch (ProviderController.ProviderDownloadException e) {
Log.e(TAG, "Exception when trying to download providers", e);
result[0] = SyncStatusConstants.DOWNLOAD_ERROR;
return result;
}
return result;
}
public int[] downloadConcepts(String[] conceptIds) {
int[] result = new int[4];
try {
List<Concept> concepts = conceptController.downloadConceptsByUuid(conceptIds);
conceptController.saveConcepts(concepts);
Log.i(TAG, "Downloaded "+concepts.size()+" concepts");
result[0] = SyncStatusConstants.SUCCESS;
result[1] = concepts.size();
} catch (ConceptController.ConceptSaveException e) {
Log.e(TAG, "Exception when trying to save concepts", e);
result[0] = SyncStatusConstants.SAVE_ERROR;
return result;
} catch (ConceptController.ConceptDownloadException e) {
Log.e(TAG, "Exception when trying to download concepts", e);
result[0] = SyncStatusConstants.DOWNLOAD_ERROR;
return result;
}
return result;
}
public int[] downloadCohorts() {
int[] result = new int[3];
try {
List<Cohort> cohorts = downloadCohortsList();
List<Cohort> voidedCohorts = deleteVoidedCohorts(cohorts);
cohorts.removeAll(voidedCohorts);
cohortController.saveAllCohorts(cohorts);
Log.i(TAG, "New cohorts are saved");
result[0] = SyncStatusConstants.SUCCESS;
result[1] = cohorts.size();
result[2] = voidedCohorts.size();
} catch (CohortController.CohortDownloadException e) {
Log.e(TAG, "Exception when trying to download cohorts", e);
result[0] = SyncStatusConstants.DOWNLOAD_ERROR;
return result;
} catch (CohortController.CohortSaveException e) {
Log.e(TAG, "Exception when trying to save cohorts", e);
result[0] = SyncStatusConstants.SAVE_ERROR;
return result;
} catch (CohortController.CohortDeleteException e) {
Log.e(TAG, "Exception occurred while deleting voided cohorts", e);
result[0] = SyncStatusConstants.DELETE_ERROR;
return result;
}
return result;
}
private List<Cohort> deleteVoidedCohorts(List<Cohort> cohorts) throws CohortController.CohortDeleteException {
Log.i(TAG, "Voided cohorts are deleted");
List<Cohort> voidedCohorts = new ArrayList<Cohort>();
for (Cohort cohort : cohorts) {
if (cohort.isVoided()) {
voidedCohorts.add(cohort);
}
}
cohortController.deleteCohorts(voidedCohorts);
return voidedCohorts;
}
public int[] downloadPatientsForCohorts(String[] cohortUuids) {
int[] result = new int[4];
int patientCount = 0;
try {
long startDownloadCohortData = System.currentTimeMillis();
List<CohortData> cohortDataList = cohortController.downloadCohortData(cohortUuids);
long endDownloadCohortData = System.currentTimeMillis();
Log.i(TAG, "Cohort data download successful with " + cohortDataList.size() + " cohorts");
ArrayList<Patient> voidedPatients = new ArrayList<Patient>();
List<Patient> cohortPatients;
for (CohortData cohortData : cohortDataList) {
cohortController.addCohortMembers(cohortData.getCohortMembers());
cohortPatients = cohortData.getPatients();
getVoidedPatients(voidedPatients, cohortPatients);
cohortPatients.removeAll(voidedPatients);
patientController.replacePatients(cohortPatients);
patientCount += cohortData.getPatients().size();
}
patientController.deletePatient(voidedPatients);
long cohortMemberAndPatientReplaceTime = System.currentTimeMillis();
Log.i(TAG, "Cohort data replaced");
Log.i(TAG, "Patients downloaded " + patientCount);
Log.d(TAG, "In Downloading cohort data: " + (endDownloadCohortData - startDownloadCohortData) / 1000 + " sec\n" +
"In Replacing cohort members and patients: " + (cohortMemberAndPatientReplaceTime - endDownloadCohortData) / 1000 + " sec");
result[0] = SyncStatusConstants.SUCCESS;
result[1] = patientCount;
result[2] = cohortDataList.size();
result[3] = voidedPatients.size();
} catch (CohortController.CohortDownloadException e) {
Log.e(TAG, "Exception thrown while downloading cohort data.", e);
result[0] = SyncStatusConstants.DOWNLOAD_ERROR;
} catch (CohortController.CohortReplaceException e) {
Log.e(TAG, "Exception thrown while replacing cohort data.", e);
result[0] = SyncStatusConstants.REPLACE_ERROR;
} catch (PatientController.PatientSaveException e) {
Log.e(TAG, "Exception thrown while replacing patients.", e);
result[0] = SyncStatusConstants.REPLACE_ERROR;
} catch (PatientController.PatientDeleteException e) {
Log.e(TAG, "Exception thrown while deleting patients.", e);
result[0] = SyncStatusConstants.DELETE_ERROR;
}
return result;
}
private void getVoidedPatients(ArrayList<Patient> voidedPatients, List<Patient> cohortPatients) {
for (Patient patient : cohortPatients) {
if (patient.isVoided()) {
voidedPatients.add(patient);
}
}
}
public int[] downloadPatients(String[] patientUUIDs) {
int[] result = new int[2];
List<Patient> downloadedPatients;
try {
downloadedPatients = downloadPatientsByUUID(patientUUIDs);
patientController.savePatients(downloadedPatients);
result[0] = SyncStatusConstants.SUCCESS;
result[1] = downloadedPatients.size();
} catch (PatientController.PatientDownloadException e) {
Log.e(TAG, "Error while downloading patients.", e);
result[0] = SyncStatusConstants.DOWNLOAD_ERROR;
} catch (PatientController.PatientSaveException e) {
Log.e(TAG, "Error while saving patients.", e);
result[0] = SyncStatusConstants.DOWNLOAD_ERROR;
}
return result;
}
public int[] downloadObservationsForPatientsByCohortUUIDs(String[] cohortUuids, boolean replaceExistingObservation) {
int[] result = new int[3];
List<Patient> patients;
try {
patients = patientController.getPatientsForCohorts(cohortUuids);
int patientsTotal = patients.size();
int patientsObsDownloaded = 0;
int totalObsDownloaded = 0;
int count = 0;
for(Patient patient : patients){
count++;
Log.i(TAG, "Downloading Obs for patient " + count + " of "+ patientsTotal);
updateProgressDialog(muzimaApplication.getString(R.string.info_observations_download_pogress, count, patientsTotal));
List<String> patientlist = new ArrayList();
patientlist.add(patient.getUuid());
result = downloadObservationsForPatientsByPatientUUIDs(patientlist,replaceExistingObservation);
if(result[0] != SyncStatusConstants.SUCCESS){
Log.e(TAG, "Obs for patient " + count + " of "+ patientsTotal + " not downloaded");
updateProgressDialog(muzimaApplication.getString(R.string.info_observations_not_downloaded_progress, count, patientsTotal));
} else if(result[1] > 0) {
patientsObsDownloaded++;
totalObsDownloaded += result[1];
}
}
result[1]=totalObsDownloaded;
result[2]=patientsObsDownloaded;
} catch (PatientController.PatientLoadException e) {
Log.e(TAG, "Exception thrown while loading patients.", e);
result[0] = SyncStatusConstants.LOAD_ERROR;
}
return result;
}
private void updateProgressDialog(String message){
Intent progressUpdateIntent = new Intent(muzimaApplication.getApplicationContext(),ProgressDialogUpdateIntentService.class);
progressUpdateIntent.putExtra(Constants.ProgressDialogConstants.PROGRESS_UPDATE_MESSAGE, message);
muzimaApplication.getApplicationContext().startService(progressUpdateIntent);
}
private List<List<String>> split(final List<String> strings) {
List<List<String>> lists = new ArrayList<List<String>>();
int count = 0;
boolean hasElements = !strings.isEmpty();
while (hasElements) {
int startElement = count * 50;
int endElement = ++count * 50;
hasElements = strings.size() > endElement;
if (hasElements) {
lists.add(strings.subList(startElement, endElement));
} else {
lists.add(strings.subList(startElement, strings.size()));
}
}
return lists;
}
public int[] downloadObservationsForPatientsByPatientUUIDs(List<String> patientUuids, boolean replaceExistingObservations) {
int[] result = new int[3];
try {
long startDownloadObservations = System.currentTimeMillis();
List<String> conceptUuidsFromConcepts = getConceptUuidsFromConcepts(conceptController.getConcepts());
List<List<String>> slicedPatientUuids = split(patientUuids);
List<List<String>> slicedConceptUuids = split(conceptUuidsFromConcepts);
List<Observation> allObservations = new ArrayList<Observation>();
for (List<String> slicedPatientUuid : slicedPatientUuids) {
for (List<String> slicedConceptUuid : slicedConceptUuids) {
allObservations.addAll(
observationController.downloadObservationsByPatientUuidsAndConceptUuids(
slicedPatientUuid, slicedConceptUuid)
);
}
}
long endDownloadObservations = System.currentTimeMillis();
Log.i(TAG, "Observations download successful with " + allObservations.size() + " observations");
List<Observation> voidedObservations = getVoidedObservations(allObservations);
observationController.deleteObservations(voidedObservations);
allObservations.removeAll(voidedObservations);
Log.i(TAG, "Voided observations delete successful with " + voidedObservations.size() + " observations");
if(replaceExistingObservations) {
observationController.replaceObservations(allObservations);
long replacedObservations = System.currentTimeMillis();
Log.d(TAG, "In Downloading observations : " + (endDownloadObservations - startDownloadObservations) / 1000 + " sec\n" +
"In Replacing observations for patients: " + (replacedObservations - endDownloadObservations) / 1000 + " sec");
}
else {
observationController.saveObservations(allObservations);
Log.d(TAG, "In Saving observations : " + (endDownloadObservations - startDownloadObservations) / 1000 + " sec\n");
}
result[0] = SyncStatusConstants.SUCCESS;
result[1] = allObservations.size();
result[2] = voidedObservations.size();
} catch (ObservationController.DownloadObservationException e) {
Log.e(TAG, "Exception thrown while downloading observations.", e);
result[0] = SyncStatusConstants.DOWNLOAD_ERROR;
} catch (ObservationController.ReplaceObservationException e) {
Log.e(TAG, "Exception thrown while replacing observations.", e);
result[0] = SyncStatusConstants.REPLACE_ERROR;
} catch (ConceptController.ConceptFetchException e) {
Log.e(TAG, "Exception thrown while loading concepts.", e);
result[0] = SyncStatusConstants.LOAD_ERROR;
} catch (ObservationController.DeleteObservationException e) {
Log.e(TAG, "Exception thrown while deleting observations.", e);
result[0] = SyncStatusConstants.DELETE_ERROR;
} catch (ObservationController.SaveObservationException e) {
Log.e(TAG, "Exception thrown while saving observations.", e);
result[0] = SyncStatusConstants.SAVE_ERROR;
}
return result;
}
private List<Observation> getVoidedObservations(List<Observation> allObservations) {
List<Observation> voidedObservations = new ArrayList<Observation>();
for (Observation observation : allObservations) {
if (observation.isVoided()) {
voidedObservations.add(observation);
}
}
return voidedObservations;
}
public int[] downloadEncountersForPatientsByCohortUUIDs(String[] cohortUuids, boolean replaceExistingEncounters) {
int[] result = new int[3];
List<Patient> patients;
try {
patients = patientController.getPatientsForCohorts(cohortUuids);
int patientsTotal = patients.size();
int count = 0;
int patientsEncountersDownloaded=0;
int totalEncountersDownloaded=0;
for(Patient patient : patients){
count++;
Log.i(TAG, "Downloading Encounters for patient " + count + " of "+ patientsTotal);
updateProgressDialog(muzimaApplication.getString(R.string.info_encounter_download_progress, count, patientsTotal));
List<String> patientlist = new ArrayList();
patientlist.add(patient.getUuid());
result = downloadEncountersForPatientsByPatientUUIDs(patientlist,replaceExistingEncounters);
if(result[0] != SyncStatusConstants.SUCCESS){
Log.e(TAG, "Encounters for patient " + count + " of "+ patientsTotal + " not downloaded");
updateProgressDialog(muzimaApplication.getString(R.string.info_encounter_not_downloaded_progress, count, patientsTotal));
} else if(result[1] > 0) {
patientsEncountersDownloaded++;
totalEncountersDownloaded += result[1];
}
}
result[1]=totalEncountersDownloaded;
result[2]=patientsEncountersDownloaded;
} catch (PatientController.PatientLoadException e) {
Log.e(TAG, "Exception thrown while loading patients.", e);
result[0] = SyncStatusConstants.LOAD_ERROR;
}
return result;
}
public int[] downloadEncountersForPatientsByPatientUUIDs(List<String> patientUuids, boolean replaceExistingEncounters) {
int[] result = new int[3];
try {
long startDownloadEncounters = System.currentTimeMillis();
List<Encounter> allEncounters = new ArrayList<Encounter>();
List<List<String>> slicedPatientUuids = split(patientUuids);
for (List<String> slicedPatientUuid : slicedPatientUuids) {
allEncounters.addAll(encounterController.downloadEncountersByPatientUuids(slicedPatientUuid));
}
long endDownloadObservations = System.currentTimeMillis();
Log.i(TAG, "Encounters download successful with " + allEncounters.size() + " encounters");
ArrayList<Encounter> voidedEncounters = getVoidedEncounters(allEncounters);
allEncounters.removeAll(voidedEncounters);
encounterController.deleteEncounters(voidedEncounters);
Log.i(TAG, "Voided encounters delete successful with " + allEncounters.size() + " encounters");
if(replaceExistingEncounters) {
encounterController.replaceEncounters(allEncounters);
long replacedEncounters = System.currentTimeMillis();
Log.d(TAG, "In Downloading encounters : " + (endDownloadObservations - startDownloadEncounters) / 1000 + " sec\n" +
"In Replacing encounters for patients: " + (replacedEncounters - endDownloadObservations) / 1000 + " sec");
}else {
encounterController.saveEncounters(allEncounters);
Log.d(TAG, "In Saving encounters : " + (endDownloadObservations - startDownloadEncounters) / 1000 + " sec\n" );
}
result[0] = SyncStatusConstants.SUCCESS;
result[1] = allEncounters.size();
result[2] = voidedEncounters.size();
} catch (EncounterController.DownloadEncounterException e) {
Log.e(TAG, "Exception thrown while downloading encounters.", e);
result[0] = SyncStatusConstants.DOWNLOAD_ERROR;
} catch (EncounterController.ReplaceEncounterException e) {
Log.e(TAG, "Exception thrown while replacing encounters.", e);
result[0] = SyncStatusConstants.REPLACE_ERROR;
} catch (EncounterController.DeleteEncounterException e) {
Log.e(TAG, "Exception thrown while deleting encounters.", e);
result[0] = SyncStatusConstants.DELETE_ERROR;
} catch (EncounterController.SaveEncounterException e) {
Log.e(TAG, "Exception thrown while saving encounters.", e);
result[0] = SyncStatusConstants.SAVE_ERROR;
}
return result;
}
private ArrayList<Encounter> getVoidedEncounters(List<Encounter> allEncounters) {
ArrayList<Encounter> voidedEncounters = new ArrayList<Encounter>();
for (Encounter encounter : allEncounters) {
if (encounter.isVoided()) {
voidedEncounters.add(encounter);
}
}
return voidedEncounters;
}
public int[] uploadAllCompletedForms() {
int[] result = new int[1];
try {
result[0] = formController.uploadAllCompletedForms() ? SyncStatusConstants.SUCCESS : SyncStatusConstants.UPLOAD_ERROR;
} catch (FormController.UploadFormDataException e) {
Log.e(TAG, "Exception thrown while uploading forms.", e);
result[0] = SyncStatusConstants.UPLOAD_ERROR;
}
return result;
}
public void consolidatePatients() {
List<Patient> allLocalPatients = patientController.getAllPatientsCreatedLocallyAndNotSynced();
for (Patient localPatient : allLocalPatients) {
Patient patientFromServer = patientController.consolidateTemporaryPatient(localPatient);
if (patientFromServer != null) {
checkChangeInPatientId(localPatient, patientFromServer);
patientFromServer.addIdentifier(localPatient.getIdentifier(LOCAL_PATIENT));
patientController.deletePatient(localPatient);
try {
patientController.savePatient(patientFromServer);
} catch (PatientController.PatientSaveException e) {
Log.e(TAG, "Error while saving patients.", e);
}
}
}
}
private void checkChangeInPatientId(Patient localPatient, Patient patientFromServer) {
String patientIdentifier = patientFromServer.getIdentifier();
String localPatientIdentifier = localPatient.getIdentifier();
if (patientFromServer == null || localPatientIdentifier == null) {
return;
}
if (!patientIdentifier.equals(localPatientIdentifier)) {
JSONInputOutputToDisk jsonInputOutputToDisk = new JSONInputOutputToDisk(muzimaApplication);
try {
jsonInputOutputToDisk.add(patientIdentifier);
} catch (IOException e) {
Log.e(TAG, "Exception thrown when writing to phone disk.", e);
}
}
}
public List<Patient> updatePatientsNotPartOfCohorts() {
List<Patient> patientsNotInCohorts = patientController.getPatientsNotInCohorts();
List<Patient> downloadedPatients = new ArrayList<Patient>();
try {
for (Patient patient : patientsNotInCohorts) {
downloadedPatients.add(patientController.downloadPatientByUUID(patient.getUuid()));
}
downloadedPatients.removeAll(singleton(null));
patientController.replacePatients(downloadedPatients);
} catch (PatientController.PatientSaveException e) {
Log.e(TAG, "Exception thrown while updating patients from server.", e);
} catch (PatientController.PatientDownloadException e) {
Log.e(TAG, "Exception thrown while downloading patients from server.", e);
}
return downloadedPatients;
}
private List<String> getConceptUuidsFromConcepts(List<Concept> concepts) {
List<String> conceptUuids = new ArrayList<String>();
for (Concept concept : concepts) {
conceptUuids.add(concept.getUuid());
}
return conceptUuids;
}
private List<Patient> downloadPatientsByUUID(String[] patientUUIDs) throws PatientController.PatientDownloadException {
List<Patient> downloadedPatients = new ArrayList<Patient>();
for (String patientUUID : patientUUIDs) {
Log.i(TAG, "Downloading patient with UUID: " + patientUUID);
downloadedPatients.add(patientController.downloadPatientByUUID(patientUUID));
}
downloadedPatients.removeAll(singleton(null));
return downloadedPatients;
}
private List<Cohort> downloadCohortsList() throws CohortController.CohortDownloadException {
List<String> cohortPrefixes = cohortPrefixPreferenceService.getCohortPrefixes();
List<Cohort> cohorts;
if (cohortPrefixes.isEmpty()) {
cohorts = cohortController.downloadAllCohorts();
} else {
cohorts = cohortController.downloadCohortsByPrefix(cohortPrefixes);
}
return cohorts;
}
List<String> getPatientUuids(List<Patient> patients) {
List<String> patientUuids = new ArrayList<String>();
for (Patient patient : patients) {
patientUuids.add(patient.getUuid());
}
return patientUuids;
}
public int[] downloadNotifications(String receiverUuid) {
int[] result = new int[2];
try {
List<Notification> notifications;
notifications = notificationController.downloadNotificationByReceiver(receiverUuid);
Log.i(TAG, "Notifications download successful");
notificationController.deleteAllNotifications(receiverUuid);
Log.i(TAG, "Old notifications are deleted");
notificationController.saveNotifications(notifications);
Log.i(TAG, "New notifications are saved");
result[0] = SyncStatusConstants.SUCCESS;
result[1] = notifications.size();
} catch (NotificationController.NotificationDownloadException e) {
Log.e(TAG, "Exception when trying to download notifications", e);
result[0] = SyncStatusConstants.DOWNLOAD_ERROR;
return result;
} catch (NotificationController.NotificationDeleteException e) {
Log.e(TAG, "Exception occurred while deleting existing notifications", e);
result[0] = SyncStatusConstants.DELETE_ERROR;
return result;
} catch (NotificationController.NotificationFetchException e) {
Log.e(TAG, "Exception occurred while fetching existing notifications", e);
result[0] = SyncStatusConstants.DOWNLOAD_ERROR;
return result;
} catch (NotificationController.NotificationSaveException e) {
Log.e(TAG, "Exception when trying to save notifications", e);
result[0] = SyncStatusConstants.SAVE_ERROR;
return result;
} catch (ParseException e) {
Log.e(TAG, "Exception when trying to download notifications", e);
result[0] = SyncStatusConstants.DOWNLOAD_ERROR;
return result;
}
return result;
}
public int[] downloadSetupConfigurations(){
int[] result = new int[2];
try {
List<SetupConfiguration> setupConfigurations = setupConfigurationController.downloadAllSetupConfigurations();
result[0] = SyncStatusConstants.SUCCESS;
result[1] = setupConfigurations.size();
Log.i(TAG, "Setup Configs downloaded: "+setupConfigurations.size());
//ToDo: Remove all retired
setupConfigurationController.saveSetupConfigurations(setupConfigurations);
} catch (SetupConfigurationController.SetupConfigurationDownloadException e){
Log.e(TAG, "Exception when trying to download setup configs");
result[0] = SyncStatusConstants.DOWNLOAD_ERROR;
} catch (SetupConfigurationController.SetupConfigurationSaveException e){
Log.e(TAG, "Exception when trying to save setup configs");
result[0] = SyncStatusConstants.SAVE_ERROR;
}
return result;
}
public int[] downloadSetupConfigurationTemplate(String uuid){
int[] result = new int[2];
try {
SetupConfigurationTemplate setupConfigurationTemplate =
setupConfigurationController.downloadSetupConfigurationTemplate(uuid);
result[0] = SyncStatusConstants.SUCCESS;
if(setupConfigurationTemplate != null) {
result[1] = 1;
}
setupConfigurationController.saveSetupConfigurationTemplate(setupConfigurationTemplate);
} catch (SetupConfigurationController.SetupConfigurationDownloadException e){
Log.e(TAG, "Exception when trying to download setup configs");
result[0] = SyncStatusConstants.DOWNLOAD_ERROR;
} catch (SetupConfigurationController.SetupConfigurationSaveException e){
Log.e(TAG, "Exception when trying to save setup configs");
result[0] = SyncStatusConstants.SAVE_ERROR;
}
return result;
}
}