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

Editable barcode search #1165

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
207 changes: 164 additions & 43 deletions app/src/main/java/com/fieldbook/tracker/activities/CollectActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -925,7 +925,7 @@ public boolean moveToSearch(
}

//move to plot id
if (command.equals("id") || command.equals("barcode")) {
if (command.equals("id")) {
int rangeSize = plotIndices.length;
for (int j = 1; j <= rangeSize; j++) {
rangeBox.setRangeByIndex(j - 1);
Expand All @@ -941,12 +941,148 @@ public boolean moveToSearch(
}
}

if (command.equals("barcode")) {
int currentFieldId = preferences.getInt(GeneralKeys.SELECTED_FIELD_ID, 0);
Log.d("Field Book", "Barcode search in current field: " + currentFieldId + ", searching for: " + data);

ObservationUnitModel[] matchingUnits = database.getObservationUnitsBySearchAttribute(
currentFieldId, data);
Log.d("Field Book", "Search attribute results: " + matchingUnits.length + " units found");

if (matchingUnits.length > 0) {
// If found by search attribute, move to that observation unit
String matchingObsUnitId = matchingUnits[0].getObservation_unit_db_id();
Log.d("Field Book", "Found match by search attribute. Unit ID: " + matchingObsUnitId);

// If multiple matches found, show notification
if (matchingUnits.length > 1) {
Utils.makeToast(this, getString(R.string.search_multiple_matches_found, matchingUnits.length));
}

for (int j = 1; j <= plotIndices.length; j++) {
rangeBox.setRangeByIndex(j - 1);
RangeObject ro = rangeBox.getCRange();

if (ro.plot_id.equals(matchingObsUnitId)) {
moveToResultCore(j);
return true;
}
}
}

// Fallback: check if the barcode directly matches a plot_id
Log.d("Field Book", "Falling back to direct plot_id matching");
for (int j = 1; j <= plotIndices.length; j++) {
rangeBox.setRangeByIndex(j - 1);
RangeObject ro = rangeBox.getCRange();

if (ro.plot_id.equals(data)) {
Log.d("Field Book", "Direct match found at index: " + j);
moveToResultCore(j);
return true;
}
}

// If we didn't find it in the current field, try the cross-field search
Log.d("Field Book", "Not found in current field, trying other fields");
return performCrossFallbackSearch(data);
}

if (!command.equals("quickgoto") && !command.equals("barcode"))
Utils.makeToast(this, getString(R.string.main_toolbar_moveto_no_match));

return false;
}

/**
* Searches for a barcode across all fields when not found in the current field.
* @param searchValue The barcode or search value to find
* @return true if found in another field, false otherwise
*/
private boolean performCrossFallbackSearch(String searchValue) {
Log.d("Field Book", "Starting cross-field fallback search for: " + searchValue);

boolean found = false;
FieldObject studyObj = null;

// Store search value in inputPlotId for use in the fallback
inputPlotId = searchValue;

int currentFieldId = preferences.getInt(GeneralKeys.SELECTED_FIELD_ID, 0);
Log.d("Field Book", "Current field ID: " + currentFieldId);

// Check all other fields by search attribute
ArrayList<FieldObject> allFields = database.getAllFieldObjects();
Log.d("Field Book", "Searching across " + allFields.size() + " fields");

for (FieldObject field : allFields) {
// Skip the current field
if (field.getExp_id() == currentFieldId) {
continue;
}

Log.d("Field Book", "Checking field: " + field.getExp_id() + " (" + field.getExp_name() + ")");

ObservationUnitModel[] matchingUnits = database.getObservationUnitsBySearchAttribute(
field.getExp_id(), searchValue);

Log.d("Field Book", "Found " + matchingUnits.length + " matches in field " + field.getExp_id());

if (matchingUnits.length > 0) {
studyObj = field;
String oldPlotId = inputPlotId;
inputPlotId = matchingUnits[0].getObservation_unit_db_id();
Log.d("Field Book", "Match found! Field: " + field.getExp_name() +
", unit ID updated from " + oldPlotId + " to " + inputPlotId);
found = true;
break;
}
}

// If not found by search attribute in any field, try direct plot_id matching
if (!found) {
Log.d("Field Book", "No matches by search attribute, trying direct ID match");

ObservationUnitModel[] models = database.getAllObservationUnits();

for (ObservationUnitModel m : models) {
if (m.getObservation_unit_db_id().equals(searchValue)) {
FieldObject study = database.getFieldObject(m.getStudy_id());
if (study != null && study.getExp_name() != null) {
studyObj = study;
found = true;
Log.d("Field Book", "Direct match found in study: " + study.getExp_name());
break;
}
}
}
}

// Handle the result of the search
if (found && studyObj != null && studyObj.getExp_name() != null && studyObj.getExp_id() != -1) {
int studyId = studyObj.getExp_id();
String fieldName = studyObj.getExp_alias();

// Save the matching observation unit ID from the matched unit, not the search value
final String matchedObsUnitId = inputPlotId; // This should be the one set earlier from matchingUnits[0]

Log.d("Field Book", "Showing navigation prompt to field: " + fieldName + " and plot ID: " + matchedObsUnitId);

String msg = getString(R.string.act_collect_barcode_search_exists_in_other_field, fieldName);

SnackbarUtils.showNavigateSnack(getLayoutInflater(), findViewById(R.id.traitHolder),
msg, R.id.toolbarBottom, 8000, null,
(v) -> switchField(studyId, matchedObsUnitId));

return true;
} else {
Log.d("Field Book", "No match found in any field");
soundHelper.playError();
Utils.makeToast(getApplicationContext(), getString(R.string.main_toolbar_moveto_no_match));
return false;
}
}

private void moveToResultCore(int j) {
rangeBox.setPaging(j);

Expand Down Expand Up @@ -1846,7 +1982,7 @@ public void onClick(DialogInterface dialog, int which) {
inputPlotId = barcodeId.getText().toString();
rangeBox.setAllRangeID();
int[] rangeID = rangeBox.getRangeID();
moveToSearch("id", rangeID, null, null, inputPlotId, -1);
moveToSearch("barcode", rangeID, null, null, inputPlotId, -1);
goToId.dismiss();
}
});
Expand Down Expand Up @@ -1992,57 +2128,42 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
}
break;
case BARCODE_SEARCH_CODE:
if(resultCode == RESULT_OK) {
if (resultCode == RESULT_OK) {
Log.d("Field Book", "Barcode scan successful");

if (geoNavHelper.getSnackbar() != null) geoNavHelper.getSnackbar().dismiss();
if(mlkitEnabled) {
inputPlotId = data.getStringExtra("barcode");
}
else {
IntentResult plotSearchResult = IntentIntegrator.parseActivityResult(resultCode, data);
inputPlotId = plotSearchResult.getContents();
if (geoNavHelper.getSnackbar() != null) {
geoNavHelper.getSnackbar().dismiss();
}
rangeBox.setAllRangeID();
int[] rangeID = rangeBox.getRangeID();
boolean success = moveToSearch("barcode", rangeID, null, null, inputPlotId, -1);

//play success or error sound if the plotId was not found
if (success) {
soundHelper.playCelebrate();
String barcodeValue;
if (mlkitEnabled) {
barcodeValue = data.getStringExtra("barcode");
} else {
boolean found = false;
FieldObject studyObj = null;
ObservationUnitModel[] models = database.getAllObservationUnits();
for (ObservationUnitModel m : models) {
if (m.getObservation_unit_db_id().equals(inputPlotId)) {

FieldObject study = database.getFieldObject(m.getStudy_id());
if (study != null && study.getExp_name() != null) {
studyObj = study;
found = true;
break;
}
}
}

if (found && studyObj.getExp_name() != null && studyObj.getExp_id() != -1) {

int studyId = studyObj.getExp_id();
String fieldName = studyObj.getExp_alias();

String msg = getString(R.string.act_collect_barcode_search_exists_in_other_field, fieldName);
IntentResult plotSearchResult = IntentIntegrator.parseActivityResult(resultCode, data);
barcodeValue = plotSearchResult.getContents();
}

SnackbarUtils.showNavigateSnack(getLayoutInflater(), findViewById(R.id.traitHolder), msg, R.id.toolbarBottom,8000, null,
(v) -> switchField(studyId, null));
if (barcodeValue != null && !barcodeValue.isEmpty()) {
Log.d("Field Book", "Scanned barcode: " + barcodeValue);

} else {
// Set inputPlotId globally to ensure it's available everywhere
inputPlotId = barcodeValue;

soundHelper.playError();
rangeBox.setAllRangeID();
int[] rangeID = rangeBox.getRangeID();

Utils.makeToast(getApplicationContext(), getString(R.string.main_toolbar_moveto_no_match));
boolean success = moveToSearch("barcode", rangeID, null, null, barcodeValue, -1);

}
// If success is true, moveToSearch found the barcode, either in current field
// or via the fallback in another field. Success sound happens in moveToSearch
// if needed. No additional action required here.
} else {
Log.d("Field Book", "Barcode scan returned empty result");
soundHelper.playError();
Utils.makeToast(getApplicationContext(), getString(R.string.main_toolbar_moveto_no_match));
}
} else {
Log.d("Field Book", "Barcode scan cancelled or failed");
}
break;
case BARCODE_COLLECT_CODE:
Expand Down
Loading