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

validate_categorical_barcode_data #1110

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -623,30 +623,20 @@ public void refreshMain() {
*/
@Override
public boolean validateData() {
final String strValue = collectInputView.getText();
final String data = collectInputView.getText();
final TraitObject currentTrait = traitBox.getCurrentTrait();

if (currentTrait == null) return false;

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

final String trait = currentTrait.getName();
if (data.isEmpty()) return true;

if (traitBox.existsNewTraits()
&& traitBox.getCurrentTrait() != null
&& strValue.length() > 0
&& !traitBox.getCurrentTrait().isValidValue(strValue)) {
BaseTraitLayout layout = traitLayouts.getTraitLayout(currentTrait.getFormat());
if (!layout.validate(data)) {

//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());
}
removeTrait(currentTrait);

removeTrait(trait);
collectInputView.clear();

soundHelper.playError();
Expand Down Expand Up @@ -720,7 +710,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 @@ -1249,9 +1239,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 @@ -1261,19 +1250,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
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 @@ -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) {

//check if the data is in the list of categories
ArrayList<BrAPIScaleValidValuesCategories> cats = getCategories();
if (CategoryJsonUtil.Companion.contains(cats, data)) {
return true;
} else {
getCollectActivity().runOnUiThread(() -> {
//Utils.makeToast(controller.getContext(),
// controller.getContext().getString(R.string.trait_error_invalid_value));
});
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public void afterLoadNotExists(CollectActivity act) {

@Override
public void deleteTraitListener() {
removeTrait(getCurrentTrait().getName());
removeTrait(getCurrentTrait());
super.deleteTraitListener();
ObservationModel model = getCurrentObservation();
if (model != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ public void afterLoadNotExists(CollectActivity act) {

@Override
public void deleteTraitListener() {
removeTrait(getCurrentTrait().getName());
removeTrait(getCurrentTrait());

super.deleteTraitListener();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public void loadLayout() {

@Override
public void deleteTraitListener() {
removeTrait(getCurrentTrait().getName());
removeTrait(getCurrentTrait());
super.deleteTraitListener();

ObservationModel model = getCurrentObservation();
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 All @@ -23,6 +25,7 @@
import org.brapi.v2.model.pheno.BrAPIScaleValidValuesCategories;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringJoiner;

public class MultiCatTraitLayout extends BaseTraitLayout {
Expand Down Expand Up @@ -355,4 +358,33 @@ public String decodeValue(String value) {
}
return joiner.toString();
}

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

String[] classTokens = data.split(":");

boolean valid = false;

ArrayList<BrAPIScaleValidValuesCategories> cats = new ArrayList<>(Arrays.asList(getCategories()));

for (String token : classTokens) {

BrAPIScaleValidValuesCategories validValue = new BrAPIScaleValidValuesCategories()
.label(token)
.value(token);

valid = hasCategory(validValue);
}

//check if the data is in the list of categories
if (!valid) {
getCollectActivity().runOnUiThread(() ->
Utils.makeToast(controller.getContext(),
controller.getContext().getString(R.string.trait_error_invalid_multicat_value)));
}

return valid;
}
}
Loading