Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v5 repeated values compatibility with brapi field sync #1009

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public class Observation extends BrapiObservation {
private String collector;
private String season;
private String studyId;
private String internalVariableDbId;
private String value;
private String rep;

Expand Down Expand Up @@ -49,6 +50,14 @@ public void setStudyId(String studyId) {
this.studyId = studyId;
}

public String getInternalVariableDbId() {
return internalVariableDbId;
}

public void setInternalVariableDbId(String internalVariableDbId) {
this.internalVariableDbId = internalVariableDbId;
}

public String getValue() {
return value;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.threeten.bp.OffsetDateTime;

import java.lang.reflect.Type;
import java.util.ArrayList;
Expand Down Expand Up @@ -308,31 +309,31 @@ public void getPrograms(final BrapiPaginationManager paginationManager,
final Function<Integer, Void> failFunction) {
Integer initPage = paginationManager.getPage();
try {
BrapiV2ApiCallBack<BrAPIProgramListResponse> callback = new BrapiV2ApiCallBack<BrAPIProgramListResponse>() {
@Override
public void onSuccess(BrAPIProgramListResponse programsResponse, int i, Map<String, List<String>> map) {
// Cancel processing if the page that was processed is not the page
// that we are currently on. For Example: User taps "Next Page" before brapi call returns data
if (initPage.equals(paginationManager.getPage())) {
updatePageInfo(paginationManager, programsResponse.getMetadata());
List<BrAPIProgram> programList = programsResponse.getResult().getData();
function.apply(mapPrograms(programList));
}
}

@Override
public void onFailure(ApiException error, int i, Map<String, List<String>> map) {
failFunction.apply(error.getCode());
Log.e("BrAPIServiceV2", "API Exception", error);
}
};
ProgramQueryParams queryParams = new ProgramQueryParams();
queryParams.page(paginationManager.getPage()).pageSize(paginationManager.getPageSize());
programsApi.programsGetAsync(queryParams, callback);
} catch (ApiException error) {
failFunction.apply(error.getCode());
Log.e("BrAPIServiceV2", "API Exception", error);
}
BrapiV2ApiCallBack<BrAPIProgramListResponse> callback = new BrapiV2ApiCallBack<BrAPIProgramListResponse>() {
@Override
public void onSuccess(BrAPIProgramListResponse programsResponse, int i, Map<String, List<String>> map) {
// Cancel processing if the page that was processed is not the page
// that we are currently on. For Example: User taps "Next Page" before brapi call returns data
if (initPage.equals(paginationManager.getPage())) {
updatePageInfo(paginationManager, programsResponse.getMetadata());
List<BrAPIProgram> programList = programsResponse.getResult().getData();
function.apply(mapPrograms(programList));
}
}

@Override
public void onFailure(ApiException error, int i, Map<String, List<String>> map) {
failFunction.apply(error.getCode());
Log.e("BrAPIServiceV2", "API Exception", error);
}
};
ProgramQueryParams queryParams = new ProgramQueryParams();
queryParams.page(paginationManager.getPage()).pageSize(paginationManager.getPageSize());
programsApi.programsGetAsync(queryParams, callback);
} catch (ApiException error) {
failFunction.apply(error.getCode());
Log.e("BrAPIServiceV2", "API Exception", error);
}
}

private List<BrapiProgram> mapPrograms(List<BrAPIProgram> programList) {
Expand Down Expand Up @@ -972,6 +973,13 @@ private Observation mapToObservation(BrAPIObservation obs){
newObservation.setDbId(obs.getObservationDbId());
newObservation.setUnitDbId(obs.getObservationUnitDbId());
newObservation.setVariableDbId(obs.getObservationVariableDbId());
newObservation.setTimestamp(obs.getObservationTimeStamp().toString());

newObservation.setTimestamp(
OffsetDateTime.parse(
obs.getObservationTimeStamp().toString()
)
);

//search imported obs references for first field book id
List<BrAPIExternalReference> references = obs.getExternalReferences();
Expand Down Expand Up @@ -1012,6 +1020,11 @@ private List<Observation> mapObservations(List<BrAPIObservation> brapiObservatio
String internalVarId = extVariableDbIdMap.get(brapiObservation.getObservationVariableDbId());
newObservation.setVariableDbId(internalVarId);
newObservation.setValue(brapiObservation.getValue());
newObservation.setTimestamp(
OffsetDateTime.parse(
brapiObservation.getObservationTimeStamp().toString()
)
);

//Make sure we are on the right experiment level.
// This will cause bugs if there have been plot and plant level traits found as the observations retrieves all of them
Expand All @@ -1024,8 +1037,8 @@ private List<Observation> mapObservations(List<BrAPIObservation> brapiObservatio
}

public void createObservations(List<Observation> observations,
final Function<List<Observation>, Void> function,
final Function<Integer, Void> failFunction) {
final Function<List<Observation>, Void> function,
final Function<Integer, Void> failFunction) {
try {
BrapiV2ApiCallBack<BrAPIObservationListResponse> callback = new BrapiV2ApiCallBack<BrAPIObservationListResponse>() {
@Override
Expand Down Expand Up @@ -1071,8 +1084,8 @@ public void onFailure(ApiException error, int statusCode, Map<String, List<Strin
}

public void updateObservations(List<Observation> observations,
final Function<List<Observation>, Void> function,
final Function<Integer, Void> failFunction) {
final Function<List<Observation>, Void> function,
final Function<Integer, Void> failFunction) {
try {

BrapiV2ApiCallBack<BrAPIObservationListResponse> callback = new BrapiV2ApiCallBack<BrAPIObservationListResponse>() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ class ObservationDao {
obs.value AS value,
obs.observation_time_stamp,
obs.observation_unit_id,
obs.observation_variable_db_id,
obs.observation_db_id,
obs.last_synced_time,
obs.collector,
Expand All @@ -197,6 +198,7 @@ class ObservationDao {
rep = getStringVal(row, "rep")
unitDbId = getStringVal(row, "uniqueName")
variableDbId = getStringVal(row, "external_db_id")
internalVariableDbId = getStringVal(row, "observation_variable_db_id")
value = CategoryJsonUtil.processValue(row)
variableName = getStringVal(row, "observation_variable_name")
fieldBookDbId = getStringVal(row, "id")
Expand Down Expand Up @@ -378,14 +380,14 @@ class ObservationDao {

fun insertObservation(studyId: Int, model: BrapiObservation, traitIdToTypeMap:Map<String,String>): Int = withDatabase { db ->

if (getObservation("$studyId", model.unitDbId, model.variableDbId, "1")?.dbId != null) {
if (getObservation("$studyId", model.unitDbId, model.variableDbId, model.rep ?: "1")?.dbId != null) {
println(
"DbId: ${
getObservation(
"$studyId",
model.unitDbId,
model.variableDbId,
"1"
model.rep ?: "1"
)?.dbId
}"
)
Expand All @@ -398,15 +400,15 @@ class ObservationDao {
"observation_variable_name" to model.variableName,
"observation_variable_field_book_format" to variableFormat,
"value" to model.value,
"observation_time_stamp" to model.timestamp,
"observation_time_stamp" to model.timestamp.toString(),
"collector" to model.collector,
// "geoCoordinates" to model.geo_coordinates,
"geoCoordinates" to null,
"last_synced_time" to model.lastSyncedTime,
// "additional_info" to model.additional_info,
"additional_info" to null,
"observation_db_id" to model.dbId,
"rep" to "1",
"rep" to model.rep,
Study.FK to studyId,
ObservationUnit.FK to model.unitDbId,
ObservationVariable.FK to model.variableDbId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,9 @@ class BrapiSyncObsDialog(context: Context, private val syncController: FieldSync

null
}) {
println("Stopped:")
null
}
println("Stopped:")
null
}

null
}) { null }
Expand Down Expand Up @@ -256,30 +256,37 @@ internal class ImportRunnableTask(
}

try {
//Sorting here to only save the most recently taken observation if it is not already in the DB
val observationList =
studyObservations.observationList.sortedByDescending { it.timestamp }
// Calculate rep numbers for new observations based on existing observations
val hostURL = BrAPIService.getHostUrl(context)
val existingObservations = dataHelper.getObservations(hostURL)

// Track the count of existing observations for each unit-variable pair
val observationRepBaseMap = mutableMapOf<Pair<String?, String?>, Int>()
for (obs in existingObservations) {
val key = Pair(obs.unitDbId, obs.internalVariableDbId)
observationRepBaseMap[key] = observationRepBaseMap.getOrDefault(key, 0) + 1
}

// Sort new observations by timestamp so rep # will ascend in order with time
val observationList = studyObservations.observationList.sortedBy { it.timestamp }

//Then sync the observations
for (obs in observationList) {
//Leaving this here for debugging purposes
// println("****************************")
// println("Saving: varName: " + obs.variableName)
// println("Saving: value: " + obs.value)
// println("Saving: studyId: " + obs.studyId)
// println("Saving: unitDBId: " + obs.unitDbId)
// println("Saving: varDbId: " + obs.variableDbId)
val key = Pair(obs.unitDbId, obs.variableDbId)
val baseRep = observationRepBaseMap.getOrDefault(key, 0)
val nextRep = baseRep + 1
obs.rep = nextRep.toString()

// Save observation to the database and update highest rep # for the pair
dataHelper.setTraitObservations(studyObservations.fieldBookStudyDbId, obs, traitIdToType)
observationRepBaseMap[key] = nextRep
}
return 0
}
catch (exc: Exception) {
} catch (exc: Exception) {
fail = true
failMessage = exc.message ?: "ERROR"
println(exc)
Log.e("ImportRunnableTask", "Exception occurred: ${exc.message}", exc)
return null
}

}


Expand Down