Skip to content

Commit

Permalink
Merge pull request #1110 from PhenoApps/validate_categorical_barcode_…
Browse files Browse the repository at this point in the history
…data

validate_categorical_barcode_data
  • Loading branch information
trife authored Jan 4, 2025
2 parents 3d7ba53 + c0de86d commit 2e6cfc3
Show file tree
Hide file tree
Showing 31 changed files with 346 additions and 101 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
import com.fieldbook.tracker.traits.PhotoTraitLayout;
import com.fieldbook.tracker.traits.formats.TraitFormat;
import com.fieldbook.tracker.traits.formats.coders.StringCoder;
import com.fieldbook.tracker.traits.formats.Scannable;
import com.fieldbook.tracker.traits.formats.presenters.ValuePresenter;
import com.fieldbook.tracker.utilities.CameraXFacade;
import com.fieldbook.tracker.utilities.BluetoothHelper;
Expand Down Expand Up @@ -672,31 +673,29 @@ public void refreshMain() {
* @return boolean flag false when data is out of bounds, true otherwise
*/
@Override
public boolean validateData() {
final String strValue = collectInputView.getText();
public boolean validateData(@Nullable String data) {
final TraitObject currentTrait = traitBox.getCurrentTrait();

if (currentTrait == null) return false;

if (strValue.equals("NA")) return true;
if (data == null) return true;

final String trait = currentTrait.getName();
if (data.equals("NA")) return true;

if (traitBox.existsNewTraits()
&& traitBox.getCurrentTrait() != null
&& strValue.length() > 0
&& !traitBox.getCurrentTrait().isValidValue(strValue)) {
if (data.isEmpty()) return true;

//checks if the trait is numerical and within the bounds (otherwise returns false)
if (currentTrait.isOver(strValue)) {
Utils.makeToast(getApplicationContext(),getString(R.string.trait_error_maximum_value)
+ ": " + currentTrait.getMaximum());
} else if (currentTrait.isUnder(strValue)) {
Utils.makeToast(getApplicationContext(),getString(R.string.trait_error_minimum_value)
+ ": " + currentTrait.getMinimum());
}
BaseTraitLayout layout = traitLayouts.getTraitLayout(currentTrait.getFormat());
TraitFormat format = Formats.Companion.findTrait(currentTrait.getFormat());

String value = data;
if (format instanceof Scannable) {
value = ((Scannable) format).preprocess(data);
}

if (!layout.validate(value)) {

removeTrait(currentTrait);

removeTrait(trait);
collectInputView.clear();

soundHelper.playError();
Expand Down Expand Up @@ -770,7 +769,7 @@ private void initToolbars() {
// if a brapi observation that has been synced, don't allow deleting
String format = getTraitFormat();
if (status && !Formats.Companion.isCameraTrait(format)) {
brapiDelete(getTraitName(), false);
brapiDelete(getCurrentTrait(), false);
} else {
traitLayouts.deleteTraitListener(getTraitFormat());
}
Expand Down Expand Up @@ -1301,9 +1300,8 @@ public String getLocationByPreferences() {
.getLocationByCollectMode(this, preferences, expId, obsUnit, geoNavHelper.getMInternalLocation(), geoNavHelper.getMExternalLocation(), database);
}

private void brapiDelete(String parent, Boolean hint) {
private void brapiDelete(TraitObject trait, Boolean hint) {
Utils.makeToast(this, getString(R.string.brapi_delete_message));
TraitObject trait = traitBox.getCurrentTrait();
updateObservation(trait, getString(R.string.brapi_na), null);
if (hint) {
setNaTextBrapiEmptyField();
Expand All @@ -1313,19 +1311,20 @@ private void brapiDelete(String parent, Boolean hint) {
}

// Delete trait, including from database
public void removeTrait(String parent) {
public void removeTrait(TraitObject trait) {

if (rangeBox.isEmpty()) {
return;
}

String exp_id = Integer.toString(preferences.getInt(GeneralKeys.SELECTED_FIELD_ID, 0));
TraitObject trait = traitBox.getCurrentTrait();
if (database.isBrapiSynced(exp_id, getObservationUnit(), trait.getId(), getRep())) {
brapiDelete(parent, true);
String fieldId = Integer.toString(preferences.getInt(GeneralKeys.SELECTED_FIELD_ID, 0));

if (database.isBrapiSynced(fieldId, getObservationUnit(), trait.getId(), getRep())) {
brapiDelete(trait, true);
} else {
// Always remove existing trait before inserting again
// Based on plot_id, prevent duplicate
traitBox.remove(parent, getObservationUnit(), getRep());
traitBox.remove(trait, getObservationUnit(), getRep());
}
}

Expand Down Expand Up @@ -2079,12 +2078,21 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {

TraitObject currentTrait = traitBox.getCurrentTrait();
BaseTraitLayout currentTraitLayout = traitLayouts.getTraitLayout(currentTrait.getFormat());
currentTraitLayout.loadLayout();
TraitFormat traitFormat = Formats.Companion.findTrait(currentTrait.getFormat());

String oldValue = "";
ObservationModel currentObs = getCurrentObservation();
if (currentObs != null) {
oldValue = currentObs.getValue();
}

if (scannedBarcode != null && traitFormat instanceof Scannable && validateData(scannedBarcode)) {
updateObservation(currentTrait, ((Scannable) traitFormat).preprocess(scannedBarcode), null);
} else {
updateObservation(currentTrait, oldValue, null);
}

updateObservation(currentTrait, scannedBarcode, null);
currentTraitLayout.loadLayout();
validateData();
}
break;
case PhotoTraitLayout.PICTURE_REQUEST_CODE:
Expand Down Expand Up @@ -2652,7 +2660,7 @@ public void showObservationMetadataDialog(){
}
}

private ObservationModel getCurrentObservation() {
public ObservationModel getCurrentObservation() {
String rep = getCollectInputView().getRep();
List<ObservationModel> models = Arrays.asList(getDatabase().getRepeatedValues(getStudyId(), getObservationUnit(), getTraitDbId()));
for (ObservationModel m : models) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.fieldbook.tracker.interfaces
import android.content.Context
import android.location.Location
import android.os.Handler
import com.fieldbook.tracker.database.models.ObservationModel
import com.fieldbook.tracker.devices.camera.UsbCameraApi
import com.fieldbook.tracker.devices.camera.GoProApi
import com.fieldbook.tracker.devices.camera.CanonApi
Expand Down Expand Up @@ -59,5 +60,6 @@ interface CollectController: FieldController {
fun getFfmpegHelper(): FfmpegHelper
fun getCanonApi(): CanonApi
fun takePicture()
fun getCurrentObservation(): ObservationModel?
fun getRotationRelativeToDevice(): SensorHelper.RotationModel?
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.fieldbook.tracker.interfaces
import com.fieldbook.tracker.views.CollectInputView

interface CollectRangeController: CollectController {
fun validateData(): Boolean
fun validateData(data: String?): Boolean
fun initWidgets(rangeSuppress: Boolean)
fun cancelAndFinish()
fun callFinish()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import com.fieldbook.tracker.traits.LayoutCollections
import com.fieldbook.tracker.views.CollectInputView

interface CollectTraitController: CollectController {
fun validateData(): Boolean
fun validateData(data: String?): Boolean
fun getTraitLayouts(): LayoutCollections
fun isCyclingTraitsAdvances(): Boolean
fun refreshLock()
Expand Down
67 changes: 32 additions & 35 deletions app/src/main/java/com/fieldbook/tracker/objects/TraitObject.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package com.fieldbook.tracker.objects;

import android.graphics.Color;
import android.util.Log;

import androidx.annotation.NonNull;

import com.fieldbook.tracker.utilities.CategoryJsonUtil;

import org.brapi.v2.model.pheno.BrAPIScaleValidValuesCategories;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

Expand Down Expand Up @@ -144,47 +150,38 @@ public void setObservationLevelNames(List<String> observationLevelNames) {
this.observationLevelNames = observationLevelNames;
}

public boolean isValidValue(final String s) {
// this code is not perfect.
// I think that it is necessary to check
// the minimum and the maximum values
return !isUnder(s) && !isOver(s);
}

public boolean isUnder(final String s) {
if (!(format.equals("numeric")))
return false;

Log.d("FB",s);
if (minimum.length() > 0) { // minimum exists
try {
final double v = Double.parseDouble(s);
final double lowerValue = Double.parseDouble(minimum);
return v < lowerValue;
} catch (NumberFormatException e) {
return true;
}
} else {
return false;
}
}
public boolean isValidCategoricalValue(final String inputCategory) {

//check if its the new json
try {

public boolean isOver(final String s) {
if (!(format.equals("numeric")))
return false;
ArrayList<BrAPIScaleValidValuesCategories> c = CategoryJsonUtil.Companion.decode(inputCategory);

Log.d("FB",s);
if (maximum.length() > 0) { // maximum exists
try {
final double v = Double.parseDouble(s);
final double upperValue = Double.parseDouble(maximum);
return v > upperValue;
} catch (NumberFormatException e) {
return true;
if (!c.isEmpty()) {

//get the value from the single-sized array
BrAPIScaleValidValuesCategories labelVal = c.get(0);

//check that this pair is a valid label/val pair in the category,
//if it is then set the text based on the preference
return CategoryJsonUtil.Companion.contains(c, labelVal);
}
} else {
return false;

} catch (Exception e) {

e.printStackTrace(); //if it fails to decode, assume its an old string

// if (CategoryJsonUtil.Companion.contains(cats, value)) {
//
// getCollectInputView().setText(value);
//
// getCollectInputView().setTextColor(Color.parseColor(getDisplayColor()));
// }
}

return false;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ private void refreshButtonState() {
@Override
public void deleteTraitListener() {
deleteRecording();
removeTrait(getCurrentTrait().getName());
removeTrait(getCurrentTrait());
super.deleteTraitListener();
recordingLocation = null;
mediaPlayer = null;
Expand Down Expand Up @@ -263,7 +263,7 @@ private void stopPlayback() {

private void startRecording() {
try {
removeTrait(getCurrentTrait().getName());
removeTrait(getCurrentTrait());
audioRecordingText.setText("");
fieldAudioHelper.startRecording(false);
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import android.widget.EditText;
import android.widget.LinearLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceManager;

Expand Down Expand Up @@ -69,6 +70,15 @@ public boolean isTraitType(String trait) {

public abstract void init(Activity act);

/**
* validate is used in collect activity to check if the collected data is within the
* specification of the trait, such as min/max.
*/
@NonNull
public Boolean validate(String data) {
return true;
}

/**
* Override to block multi-measure navigation with specific condition
*/
Expand Down Expand Up @@ -303,8 +313,8 @@ public void updateObservation(TraitObject trait, String value) {
((CollectActivity) getContext()).updateObservation(trait, value, null);
}

public void removeTrait(String parent) {
((CollectActivity) getContext()).removeTrait(parent);
public void removeTrait(TraitObject trait) {
((CollectActivity) getContext()).removeTrait(trait);
}

public void triggerTts(String text) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
import android.widget.ImageView;
import android.widget.SeekBar;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.fieldbook.tracker.R;
import com.fieldbook.tracker.activities.CollectActivity;

import java.util.Locale;

public class BooleanTraitLayout extends BaseTraitLayout implements SeekBar.OnSeekBarChangeListener {

private SeekBar threeStateSeekBar;
Expand Down Expand Up @@ -93,6 +96,16 @@ public void deleteTraitListener() {
//resetToDefault();
}

@NonNull
@Override
public Boolean validate(String data) {
try {
return data.toLowerCase(Locale.ROOT).equals("true") || data.toLowerCase(Locale.ROOT).equals("false");
} catch (Exception e) {
return false;
}
}

private void resetToDefault() {

String value = getCurrentTrait().getDefaultValue().trim();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
import android.widget.Button;
import android.widget.LinearLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;

import com.fieldbook.tracker.R;
import com.fieldbook.tracker.activities.CollectActivity;
import com.fieldbook.tracker.preferences.GeneralKeys;
import com.fieldbook.tracker.utilities.CategoryJsonUtil;
import com.fieldbook.tracker.utilities.Utils;
import com.google.android.flexbox.AlignItems;
import com.google.android.flexbox.FlexDirection;
import com.google.android.flexbox.FlexWrap;
Expand Down Expand Up @@ -317,4 +319,21 @@ public String decodeValue(String value) {
} else return scale.get(0).getLabel();
} else return "";
}

@NonNull
@Override
public Boolean validate(String data) {

try {
ArrayList<BrAPIScaleValidValuesCategories> userChosenCats = CategoryJsonUtil.Companion.decode(data);
if (userChosenCats.isEmpty()) {
return true;
} else {
ArrayList<BrAPIScaleValidValuesCategories> cats = getCategories();
return CategoryJsonUtil.Companion.contains(cats, userChosenCats.get(0));
}
} catch (Exception e) {
return false;
}
}
}
Loading

0 comments on commit 2e6cfc3

Please sign in to comment.