Commit c2cc652c authored by PECQUOT's avatar PECQUOT

[fix] DuplicateSurveyAction: postpone duplicate line insertion in Swing thread (Mantis #50685)

[fix] Empty result won't crash on referential search (Mantis #50762)
[fix] MultiEdit: sampling operation is detected correctly and pmfm ids for transition length calculated are read-only (Mantis #50815)
Signed-off-by: PECQUOT's avatarlp1ee9d <ludovic.pecquot@e-is.pro>
parent 4c9a1e33
......@@ -438,6 +438,7 @@ public class ObservationServiceImpl implements ObservationInternalService {
Assert.notNull(duplicateSurvey);
// Remove ID
duplicateSurvey.setId(null);
duplicateSurvey.setDirty(true);
// duplicated data to keep:
if (survey.isObserversEmpty() && survey.getId() != null) {
......
......@@ -38,10 +38,7 @@ import fr.ifremer.reefdb.service.ReefDbServiceLocator;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.*;
import java.io.File;
import java.time.LocalDate;
......@@ -81,11 +78,13 @@ public class ExtractionPerformServiceRealTest {
config = ReefDbConfiguration.getInstance();
}
@Ignore
@Test
public void testConfig() {
Assert.assertTrue(StringUtils.isNotBlank(config.getApplicationConfig().getOption("reefdb.core.test.extraction.path")));
}
@Ignore
@Test
public void performRealExtraction() {
......
......@@ -36,10 +36,7 @@ import static org.nuiton.i18n.I18n.t;
*/
public class DuplicateSurveyAction extends AbstractReefDbAction<SurveysTableUIModel, SurveysTableUI, SurveysTableUIHandler> {
/**
* Row.
*/
private SurveysTableRowModel newRow;
private SurveyDTO duplicatedObservation;
private boolean fullDuplication;
private boolean duplicateCoordinate;
......@@ -62,12 +59,7 @@ public class DuplicateSurveyAction extends AbstractReefDbAction<SurveysTableUIMo
}
// Change message and buttons (Mantis #50011)
String title = t("reefdb.home.survey.duplicate.title");
// String message = String.format(SurveysTableUIHandler.CONFIRMATION_FORMAT,
// t("reefdb.home.survey.duplicate.message"), TODO remove after validation
// t("reefdb.home.survey.duplicate.help")); TODO remove after validation
JCheckBox duplicateCoordinateCheckBox = new JCheckBox(t("reefdb.home.survey.duplicate.coordinate"));
JCheckBox duplicateSurveyMeasurementsCheckBox = new JCheckBox(t("reefdb.home.survey.duplicate.surveyMeasurements"));
Object[] messageObjects = {/*message, */duplicateCoordinateCheckBox, duplicateSurveyMeasurementsCheckBox};
......@@ -98,18 +90,7 @@ public class DuplicateSurveyAction extends AbstractReefDbAction<SurveysTableUIMo
if (surveysTableRowModel != null) {
// Duplicate observation
final SurveyDTO duplicateObservation = getContext().getObservationService().duplicateSurvey(surveysTableRowModel.toBean(), fullDuplication, duplicateCoordinate, duplicateSurveyMeasurements);
if (duplicateObservation != null) {
// Add duplicate observation to table
newRow = getModel().addNewRow(duplicateObservation);
// Add local sharing
newRow.setSynchronizationStatus(getContext().getSystemService().getLocalShare());
// Set it dirty
newRow.setDirty(true);
}
duplicatedObservation = getContext().getObservationService().duplicateSurvey(surveysTableRowModel.toBean(), fullDuplication, duplicateCoordinate, duplicateSurveyMeasurements);
}
}
......@@ -118,9 +99,19 @@ public class DuplicateSurveyAction extends AbstractReefDbAction<SurveysTableUIMo
public void postSuccessAction() {
super.postSuccessAction();
getModel().setModify(true);
if (duplicatedObservation != null) {
// Add duplicate observation to table
getModel().addNewRow(duplicatedObservation);
getModel().setModify(true);
}
}
@Override
protected void releaseAction() {
super.releaseAction();
// Add focus on duplicate row
getHandler().setFocusOnCell(newRow);
duplicatedObservation = null;
}
}
......@@ -184,12 +184,12 @@ public class OperationMeasurementsTabUIHandler extends AbstractReefDbUIHandler<O
getModel().getUngroupedTableUIModel().addPropertyChangeListener(OperationMeasurementsUngroupedTableUIModel.EVENT_MEASUREMENTS_LOADED, evt -> {
// detect if the triplet of PMFM for transition length
detectPmfmForTransitionCalculator();
detectPmfmForGridInitialization();
detectPitPmfmForGridInitialization();
});
getModel().getGroupedTableUIModel().addPropertyChangeListener(OperationMeasurementsGroupedTableUIModel.EVENT_MEASUREMENTS_LOADED, evt -> {
// detect if the triplet of PMFM for transition length
detectPmfmForTransitionCalculator();
detectPmfmForGridInitialization();
detectPitPmfmForGridInitialization();
});
// Add listeners on PROPERTY_ROWS_IN_ERROR to catch modifications and revalidate
......@@ -430,6 +430,12 @@ public class OperationMeasurementsTabUIHandler extends AbstractReefDbUIHandler<O
continue;
}
// set pmfm ids in models
getModel().getUngroupedTableUIModel().setCalculatedLengthStartPositionPmfmId(startPositionPmfmId);
getModel().getGroupedTableUIModel().setCalculatedLengthEndPositionPmfmId(endPositionPmfmId);
getModel().getGroupedTableUIModel().setCalculatedLengthTransitionPmfmId(transitionLengthPmfmId);
// set the transition length column non editable
transitionLengthColumn.setEditable(false);
transitionLengthColumn.getPmfmIdentifier().setNotMandatory();
......@@ -459,7 +465,7 @@ public class OperationMeasurementsTabUIHandler extends AbstractReefDbUIHandler<O
}
}
private void detectPmfmForGridInitialization() {
private void detectPitPmfmForGridInitialization() {
try {
......@@ -493,9 +499,9 @@ public class OperationMeasurementsTabUIHandler extends AbstractReefDbUIHandler<O
return;
}
getModel().getGroupedTableUIModel().setTransectOriginPmfmId(originPmfmId != 0 ? originPmfmId : null);
getModel().getGroupedTableUIModel().setTransectLengthPmfmId(transectLengthPmfmId != 0 ? transectLengthPmfmId : null);
getModel().getGroupedTableUIModel().setTransitionLengthPmfmId(transitionPmfmId);
getModel().getGroupedTableUIModel().setPitTransectOriginPmfmId(originPmfmId != 0 ? originPmfmId : null);
getModel().getGroupedTableUIModel().setPitTransectLengthPmfmId(transectLengthPmfmId != 0 ? transectLengthPmfmId : null);
getModel().getGroupedTableUIModel().setPitTransitionLengthPmfmId(transitionPmfmId);
} finally {
......
......@@ -49,12 +49,6 @@ public class OperationMeasurementsGroupedTableModel extends AbstractMeasurements
n("reefdb.samplingOperation.measurement.mnemonic.tip"),
SamplingOperationDTO.class, true);
public static final ReefDbColumnIdentifier<OperationMeasurementsGroupedRowModel> SAMPLING_READ_ONLY = ReefDbColumnIdentifier.newReadOnlyId(
OperationMeasurementsGroupedRowModel.PROPERTY_SAMPLING_OPERATION,
n("reefdb.property.mnemonic"),
n("reefdb.samplingOperation.measurement.mnemonic.tip"),
SamplingOperationDTO.class);
/**
* Identifiant pour la colonne groupe taxon.
*/
......
......@@ -60,7 +60,7 @@
actionIcon: edit;
text: "reefdb.common.init";
toolTipText: "reefdb.samplingOperation.measurement.grouped.init.tip";
enabled: {model.getSurvey().isEditable() && model.isTransitionGridInitializationEnabled() && !model.getPmfms().isEmpty()};
enabled: {model.getSurvey().isEditable() && model.isPitTransitionGridInitializationEnabled() && !model.getPmfms().isEmpty()};
}
#multiEditButton {
......
......@@ -53,6 +53,8 @@ import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Controleur pour les mesures des prelevements (ecran prelevements/mesure).
......@@ -379,7 +381,7 @@ public class OperationMeasurementsGroupedTableUIHandler
@Override
protected boolean isMeasurementNotEmpty(MeasurementDTO measurement) {
return !measurement.getPmfm().getId().equals(getModel().getTransitionLengthPmfmId()) && super.isMeasurementNotEmpty(measurement);
return !measurement.getPmfm().getId().equals(getModel().getPitTransitionLengthPmfmId()) && super.isMeasurementNotEmpty(measurement);
}
/**
......@@ -396,18 +398,18 @@ public class OperationMeasurementsGroupedTableUIHandler
initModel.setLastSamplingOperation(getModel().getRows().get(getModel().getRowCount() - 1).getSamplingOperation());
}
if (getModel().getTransectOriginPmfmId() != null) {
initModel.setOriginPmfmId(getModel().getTransectOriginPmfmId());
PmfmDTO pmfm = getContext().getReferentialService().getPmfm(getModel().getTransectOriginPmfmId());
if (getModel().getPitTransectOriginPmfmId() != null) {
initModel.setOriginPmfmId(getModel().getPitTransectOriginPmfmId());
PmfmDTO pmfm = getContext().getReferentialService().getPmfm(getModel().getPitTransectOriginPmfmId());
initModel.setOriginUnit(pmfm != null ? pmfm.getUnit() : null);
}
if (getModel().getTransectLengthPmfmId() != null) {
initModel.setLengthPmfmId(getModel().getTransectLengthPmfmId());
PmfmDTO pmfm = getContext().getReferentialService().getPmfm(getModel().getTransectLengthPmfmId());
if (getModel().getPitTransectLengthPmfmId() != null) {
initModel.setLengthPmfmId(getModel().getPitTransectLengthPmfmId());
PmfmDTO pmfm = getContext().getReferentialService().getPmfm(getModel().getPitTransectLengthPmfmId());
initModel.setLengthUnit(pmfm != null ? pmfm.getUnit() : null);
}
initModel.setTransitionPmfmId(getModel().getTransitionLengthPmfmId());
initModel.setTransitionUnit(getContext().getReferentialService().getPmfm(getModel().getTransitionLengthPmfmId()).getUnit());
initModel.setTransitionPmfmId(getModel().getPitTransitionLengthPmfmId());
initModel.setTransitionUnit(getContext().getReferentialService().getPmfm(getModel().getPitTransitionLengthPmfmId()).getUnit());
openDialog(initGridUI);
if (initModel.isValid()) {
......@@ -463,9 +465,15 @@ public class OperationMeasurementsGroupedTableUIHandler
OperationMeasurementsMultiEditUI editUI = new OperationMeasurementsMultiEditUI(getUI());
// add the calculated transition pmfm as read-only
if (getModel().getTransitionLengthPmfmId() != null) {
editUI.getModel().getReadOnlyPmfmIds().add(getModel().getTransitionLengthPmfmId());
}
editUI.getModel().setReadOnlyPmfmIds(
Stream.of(
getModel().getPitTransitionLengthPmfmId(),
getModel().getPitTransectLengthPmfmId(),
getModel().getPitTransectOriginPmfmId(),
getModel().getCalculatedLengthEndPositionPmfmId(),
getModel().getCalculatedLengthTransitionPmfmId()
).filter(Objects::nonNull).collect(Collectors.toList())
);
editSelectedMeasurements(editUI);
......
......@@ -45,10 +45,14 @@ public class OperationMeasurementsGroupedTableUIModel
*/
public static final String PROPERTY_SAMPLING_OPERATION = "samplingOperation";
// transect length for grid initialization
private Integer transectOriginPmfmId;
private Integer transectLengthPmfmId;
private Integer transitionLengthPmfmId;
// pmfm ids for grid initialization (pit protocol)
private Integer pitTransectOriginPmfmId;
private Integer pitTransectLengthPmfmId;
private Integer pitTransitionLengthPmfmId;
// pmfm ids for auto calculation of transect length
private Integer calculatedLengthEndPositionPmfmId;
private Integer calculatedLengthTransitionPmfmId;
/**
* <p>getSamplingOperations.</p>
......@@ -59,39 +63,55 @@ public class OperationMeasurementsGroupedTableUIModel
return getSurvey() == null ? null : (List<SamplingOperationDTO>) getSurvey().getSamplingOperations();
}
public Integer getTransectOriginPmfmId() {
return transectOriginPmfmId;
public Integer getPitTransectOriginPmfmId() {
return pitTransectOriginPmfmId;
}
public void setTransectOriginPmfmId(Integer transectOriginPmfmId) {
this.transectOriginPmfmId = transectOriginPmfmId;
public void setPitTransectOriginPmfmId(Integer pitTransectOriginPmfmId) {
this.pitTransectOriginPmfmId = pitTransectOriginPmfmId;
}
public Integer getTransectLengthPmfmId() {
return transectLengthPmfmId;
public Integer getPitTransectLengthPmfmId() {
return pitTransectLengthPmfmId;
}
public void setTransectLengthPmfmId(Integer transectLengthPmfmId) {
this.transectLengthPmfmId = transectLengthPmfmId;
public void setPitTransectLengthPmfmId(Integer pitTransectLengthPmfmId) {
this.pitTransectLengthPmfmId = pitTransectLengthPmfmId;
}
public Integer getTransitionLengthPmfmId() {
return transitionLengthPmfmId;
public Integer getPitTransitionLengthPmfmId() {
return pitTransitionLengthPmfmId;
}
public void setTransitionLengthPmfmId(Integer transitionLengthPmfmId) {
this.transitionLengthPmfmId = transitionLengthPmfmId;
public void setPitTransitionLengthPmfmId(Integer pitTransitionLengthPmfmId) {
this.pitTransitionLengthPmfmId = pitTransitionLengthPmfmId;
}
public boolean isTransitionGridInitializationEnabled() {
public boolean isPitTransitionGridInitializationEnabled() {
return /* Mantis #38345 The grid initialisation is enabled even if the origin and transect length identifiers are missing
getTransectOriginPmfmId() != null
&& getTransectLengthPmfmId() != null
&&*/ getTransitionLengthPmfmId() != null
&&*/ getPitTransitionLengthPmfmId() != null
/* Mantis #50045: the grid initialisation is enabled even if there are measurements already inside
&& !getSamplingOperationsWithoutMeasurement().isEmpty()*/;
}
public Integer getCalculatedLengthEndPositionPmfmId() {
return calculatedLengthEndPositionPmfmId;
}
public void setCalculatedLengthEndPositionPmfmId(Integer calculatedLengthEndPositionPmfmId) {
this.calculatedLengthEndPositionPmfmId = calculatedLengthEndPositionPmfmId;
}
public Integer getCalculatedLengthTransitionPmfmId() {
return calculatedLengthTransitionPmfmId;
}
public void setCalculatedLengthTransitionPmfmId(Integer calculatedLengthTransitionPmfmId) {
this.calculatedLengthTransitionPmfmId = calculatedLengthTransitionPmfmId;
}
public List<SamplingOperationDTO> getSamplingOperationsWithoutMeasurement() {
List<SamplingOperationDTO> samplingOperationsWithoutMeasurement = Lists.newArrayList();
......
......@@ -86,7 +86,7 @@ public class OperationMeasurementsMultiEditUIHandler
@Override
protected void initTable() {
final TableColumnExt samplingCol = addColumn(OperationMeasurementsGroupedTableModel.SAMPLING_READ_ONLY);
final TableColumnExt samplingCol = addColumn(OperationMeasurementsGroupedTableModel.SAMPLING);
samplingCol.setEditable(false);
// Colonne groupe taxon
......
......@@ -39,7 +39,7 @@ public class OperationMeasurementsMultiEditUIModel
@Override
public Set<ReefDbColumnIdentifier<OperationMeasurementsGroupedRowModel>> getIdentifiersToCheck() {
return ImmutableSet.of(
OperationMeasurementsGroupedTableModel.SAMPLING_READ_ONLY, // use this read-only (and not mandatory) version of SAMPLING
OperationMeasurementsGroupedTableModel.SAMPLING,
OperationMeasurementsGroupedTableModel.TAXON_GROUP,
OperationMeasurementsGroupedTableModel.TAXON,
OperationMeasurementsGroupedTableModel.INPUT_TAXON_NAME,
......
......@@ -42,6 +42,7 @@ public class OperationMeasurementsUngroupedTableUIModel extends AbstractReefDbTa
private ObservationUIModel survey;
private SamplingOperationDTO samplingFilter;
private Integer calculatedLengthStartPositionPmfmId;
/**
* Constructor.
......@@ -113,6 +114,14 @@ public class OperationMeasurementsUngroupedTableUIModel extends AbstractReefDbTa
return measurements;
}
public Integer getCalculatedLengthStartPositionPmfmId() {
return calculatedLengthStartPositionPmfmId;
}
public void setCalculatedLengthStartPositionPmfmId(Integer calculatedLengthStartPositionPmfmId) {
this.calculatedLengthStartPositionPmfmId = calculatedLengthStartPositionPmfmId;
}
public void fireMeasurementsLoaded() {
firePropertyChange(EVENT_MEASUREMENTS_LOADED, null, null);
}
......
......@@ -681,6 +681,18 @@ public abstract class AbstractMeasurementsGroupedTableUIHandler<
protected boolean isRowValid(R row) {
boolean valid = super.isRowValid(row);
if (!valid && !row.isMandatoryValid()) {
// check invalid mandatory errors
new ArrayList<>(row.getInvalidMandatoryIdentifiers()).forEach(invalidIdentifier -> {
if (row.getMultipleValuesOnIdentifier().contains(invalidIdentifier)) {
// if this identifier has multiple value, remove error
row.getErrors().removeIf(error -> error.getPropertyName().size() == 1 && error.getPropertyName().contains(invalidIdentifier.getPropertyName()));
row.getInvalidMandatoryIdentifiers().remove(invalidIdentifier);
}
});
valid = row.isMandatoryValid();
}
boolean noUnicityDuplicates = hasNoUnicityDuplicates(row);
boolean noPreconditionErrors = hasNoPreconditionErrors(row);
boolean noGroupedRuleErrors = hasNoGroupedRuleErrors(row);
......
......@@ -316,13 +316,6 @@ public abstract class AbstractReefDbTableUIHandler<R extends AbstractReefDbRowUI
if (row instanceof ErrorAware) {
ErrorAware errorAwareRow = (ErrorAware) row;
/* LP #50538
// keep control errors and warnings
List<ErrorDTO> controlErrors = ReefDbBeans.getErrors(errorAwareRow, true);
boolean controlValid = controlErrors.isEmpty();
controlErrors.addAll(ReefDbBeans.getWarnings(errorAwareRow, true));
errorAwareRow.getErrors().clear();
*/
ReefDbBeans.removeBlockingErrors(errorAwareRow);
if (!valid) {
......@@ -336,11 +329,6 @@ public abstract class AbstractReefDbTableUIHandler<R extends AbstractReefDbRowUI
});
}
/* LP #50538
// restore control errors ans warnings
errorAwareRow.getErrors().addAll(controlErrors);
valid &= controlValid;
*/
}
return valid;
}
......
......@@ -672,8 +672,6 @@ reefdb.home.samplingOperation.title=3/ Liste des réplicats
reefdb.home.survey.changeStatus=Changer Etat
reefdb.home.survey.control=Contrôler
reefdb.home.survey.duplicate.coordinate=Dupliquer les coordonnées
reefdb.home.survey.duplicate.help=Simple \: Seul l'observation sera dupliquée<br/>Complète \: L'observation et ses réplicats seront dupliqués
reefdb.home.survey.duplicate.message=Sélectionner le type de duplication souhaité
reefdb.home.survey.duplicate.option.full=Observation + réplicats
reefdb.home.survey.duplicate.option.simple=Observation seule
reefdb.home.survey.duplicate.surveyMeasurements=Dupliquer les mesures de l'observation
......
......@@ -38,6 +38,15 @@
<action dev="ludovic.pecquot@e-is.pro" type="add" issue="50725">
Pmfmu labels are transcribed with specific label for extraction, if exists, or with "screen" label
</action>
<action dev="ludovic.pecquot@e-is.pro" type="fix" issue="50685">
DuplicateSurveyAction: postpone duplicate line insertion in Swing thread
</action>
<action dev="ludovic.pecquot@e-is.pro" type="fix" issue="50762">
Empty result won't crash on referential search
</action>
<action dev="ludovic.pecquot@e-is.pro" type="fix" issue="50815">
MultiEdit: sampling operation is detected correctly and pmfm ids for transition length calculated are read-only
</action>
</release>
<release version="3.9.1" date="2020-01-31" description="Stable release">
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment