branch feature/8204 created (now 572e4a5)
This is an automated email from the git hooks/post-receive script. New change to branch feature/8204 in repository tutti. See https://gitlab.nuiton.org/codelutin/tutti.git at 572e4a5 Ajout d'un cache de code de prélèvement viables ou non + blocage si code de prélèvement pas possible (See #8204) This branch includes the following new commits: new db0df76 Amélioration du cache des codes de prélèvements (ne pas utiliser des Integer en valeurs d'une map) new 2c0517b Ajout d'une méthode sur la persistence pour tester qu'on peut utiliser un code de prélèvement (See #8204) new 572e4a5 Ajout d'un cache de code de prélèvement viables ou non + blocage si code de prélèvement pas possible (See #8204) The 3 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: commit 572e4a5e9007712e9099c3b56502ee570f2e8029 Author: Tony CHEMIT <chemit@codelutin.com> Date: Mon Apr 4 14:48:38 2016 +0200 Ajout d'un cache de code de prélèvement viables ou non + blocage si code de prélèvement pas possible (See #8204) commit 2c0517b040a0a3c39f0b1eddd97169e579940fc5 Author: Tony CHEMIT <chemit@codelutin.com> Date: Mon Apr 4 14:48:23 2016 +0200 Ajout d'une méthode sur la persistence pour tester qu'on peut utiliser un code de prélèvement (See #8204) commit db0df76812d1a127a7de8e5490db5b4dc3bcc343 Author: Tony CHEMIT <chemit@codelutin.com> Date: Mon Apr 4 10:23:53 2016 +0200 Amélioration du cache des codes de prélèvements (ne pas utiliser des Integer en valeurs d'une map) -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/8204 in repository tutti. See https://gitlab.nuiton.org/codelutin/tutti.git commit db0df76812d1a127a7de8e5490db5b4dc3bcc343 Author: Tony CHEMIT <chemit@codelutin.com> Date: Mon Apr 4 10:23:53 2016 +0200 Amélioration du cache des codes de prélèvements (ne pas utiliser des Integer en valeurs d'une map) --- .../service/sampling/CruiseSamplingCache.java | 60 +++++++++++++++++----- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseSamplingCache.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseSamplingCache.java index 3fc5dea..cfb80f0 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseSamplingCache.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseSamplingCache.java @@ -39,6 +39,7 @@ import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativ import fr.ifremer.tutti.persistence.entities.referential.Species; import fr.ifremer.tutti.persistence.entities.referential.TuttiLocation; import fr.ifremer.tutti.util.Numbers; +import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -111,7 +112,7 @@ public class CruiseSamplingCache implements Closeable { /** * Le code prélèvement le plus grand pour chaque espèce */ - private final Map<Integer, Integer> highestSamplingCodeBySpecies = new HashMap<>(); + private final Map<Integer, MutableInt> highestSamplingCodeBySpecies = new HashMap<>(); public CruiseSamplingCache(Integer cruiseId, TuttiProtocol protocol, Caracteristic sexCaracteristic, Collection<Caracteristic> maturityCaracteristics) { this.cruiseId = cruiseId; @@ -207,9 +208,13 @@ public class CruiseSamplingCache implements Closeable { if (samplingCode != null) { int code = SamplingCodePrefix.extractSamplingCodeIdFromSamplingCode(samplingCode); - Integer highestSamplingCode = highestSamplingCodeBySpecies.get(species.getReferenceTaxonId()); - if (highestSamplingCode == null || code > highestSamplingCode) { - highestSamplingCodeBySpecies.put(species.getReferenceTaxonId(), code); + MutableInt highestSamplingCode = highestSamplingCodeBySpecies.get(species.getReferenceTaxonId()); + if (highestSamplingCode == null) { + highestSamplingCode = new MutableInt(); + highestSamplingCodeBySpecies.put(species.getReferenceTaxonId(), highestSamplingCode); + } + if (code > highestSamplingCode.intValue()) { + highestSamplingCode.setValue(code); } addSampling(fishingOperationId, optionalZone, species, gender, maturity, lengthStepInMm, samplingCode); @@ -588,7 +593,8 @@ public class CruiseSamplingCache implements Closeable { int operationSamplingNb = operationCache.decrementSamplingNb(operationKey); - removeSamplingCode(species.getReferenceTaxonId(), samplingCode); + removeSamplingCode(species.getReferenceTaxonId()); +// removeSamplingCode(species.getReferenceTaxonId(), samplingCode); if (log.isInfoEnabled()) { log.info("remove Sampling " + samplingKey + " => op " + operationSamplingNb + " / zone " + zoneSamplingNb + " / cruise " + totalSamplingNb); @@ -729,7 +735,9 @@ public class CruiseSamplingCache implements Closeable { } public int getNextSamplingCodeId(Integer speciesId) { - return highestSamplingCodeBySpecies.getOrDefault(speciesId, 0) + 1; + MutableInt samplingCode = highestSamplingCodeBySpecies.get(speciesId); + return (samplingCode == null ? 0 : samplingCode.intValue()) + 1; +// return highestSamplingCodeBySpecies.getOrDefault(speciesId, 0) + 1; } public int addSamplingCode(Integer speciesId, String samplingCode) { @@ -737,17 +745,43 @@ public class CruiseSamplingCache implements Closeable { Integer code = Integer.parseInt(codeParts[codeParts.length - 1]); // increment the highest sampling code if it is this code - return highestSamplingCodeBySpecies.compute(speciesId, - (key, highestSamplingCode) -> highestSamplingCode == null ? code : Math.max(highestSamplingCode, code)); +// return highestSamplingCodeBySpecies.compute(speciesId, +// (key, highestSamplingCode) -> highestSamplingCode == null ? code : Math.max(highestSamplingCode, code)); + + MutableInt samplingCodeFound = highestSamplingCodeBySpecies.get(speciesId); + if (samplingCodeFound==null) { + samplingCodeFound = new MutableInt(code); + highestSamplingCodeBySpecies.put(speciesId, samplingCodeFound); + } else { + samplingCodeFound.setValue(Math.max(samplingCodeFound.intValue(), code)); + } + return samplingCodeFound.intValue(); + // Ce code ne compile pas. +// return highestSamplingCodeBySpecies.compute(speciesId, +// (key, highestSamplingCode) -> { +// if (highestSamplingCode == null) { +// highestSamplingCode = new MutableInt(code); +// } else { +// int nexValue = Math.max(highestSamplingCode.intValue(), code); +// highestSamplingCode.setValue(nexValue); +// } +// return highestSamplingCode; +// }); } - public int removeSamplingCode(Integer speciesId, String samplingCode) { - String[] codeParts = samplingCode.split("#"); - Integer code = Integer.parseInt(codeParts[codeParts.length - 1]); + + public void removeSamplingCode(Integer speciesId) { +// public void removeSamplingCode(Integer speciesId, String samplingCode) { +// String[] codeParts = samplingCode.split("#"); +// Integer code = Integer.parseInt(codeParts[codeParts.length - 1]); // decrement the highest sampling code if it is this code - return highestSamplingCodeBySpecies.computeIfPresent(speciesId, - (key, highestSamplingCode) -> code.equals(highestSamplingCode) ? code - 1 : highestSamplingCode); + MutableInt samplingCodeFound = highestSamplingCodeBySpecies.get(speciesId); + if (samplingCodeFound!=null) { + samplingCodeFound.decrement(); + } +// return highestSamplingCodeBySpecies.computeIfPresent(speciesId, +// (key, highestSamplingCode) -> code.equals(highestSamplingCode) ? code - 1 : highestSamplingCode); } } -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/8204 in repository tutti. See https://gitlab.nuiton.org/codelutin/tutti.git commit 2c0517b040a0a3c39f0b1eddd97169e579940fc5 Author: Tony CHEMIT <chemit@codelutin.com> Date: Mon Apr 4 14:48:23 2016 +0200 Ajout d'une méthode sur la persistence pour tester qu'on peut utiliser un code de prélèvement (See #8204) --- .../tutti/persistence/TuttiPersistenceImpl.java | 5 ++ .../persistence/TuttiPersistenceNoDbImpl.java | 5 ++ ...dividualObservationBatchPersistenceService.java | 10 +++ ...dualObservationBatchPersistenceServiceImpl.java | 49 +++++++++++++ .../service/util/SamplePersistenceHelper.java | 82 +++++++++++++++++----- .../src/main/resources/queries-failsafe.hbm.xml | 36 ++++++++++ .../ifremer/tutti/service/PersistenceService.java | 5 ++ .../tutti/service/sampling/SamplingCodePrefix.java | 4 ++ 8 files changed, 177 insertions(+), 19 deletions(-) diff --git a/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceImpl.java b/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceImpl.java index 5cf2795..a319038 100644 --- a/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceImpl.java +++ b/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceImpl.java @@ -1373,6 +1373,11 @@ public class TuttiPersistenceImpl implements TuttiPersistence { } @Override + public boolean isSamplingCodeAvailable(Integer cruiseId, Integer referenceTaxonId, String samplingCodeSuffix) { + return getIndividualObservationBatchService().isSamplingCodeAvailable(cruiseId, referenceTaxonId, samplingCodeSuffix); + } + + @Override public Collection<IndividualObservationBatch> createIndividualObservationBatches(Collection<IndividualObservationBatch> individualObservations) { return getIndividualObservationBatchService().createIndividualObservationBatches(individualObservations); } diff --git a/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceNoDbImpl.java b/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceNoDbImpl.java index c839c6d..abf9daa 100644 --- a/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceNoDbImpl.java +++ b/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceNoDbImpl.java @@ -922,6 +922,11 @@ public class TuttiPersistenceNoDbImpl implements TuttiPersistence { } @Override + public boolean isSamplingCodeAvailable(Integer cruiseId, Integer referenceTaxonId, String samplingCodeSuffix) { + throw notImplemented(); + } + + @Override public Collection<IndividualObservationBatch> createIndividualObservationBatches(Collection<IndividualObservationBatch> individualObservations) { throw notImplemented(); } diff --git a/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/IndividualObservationBatchPersistenceService.java b/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/IndividualObservationBatchPersistenceService.java index 9498897..75b27f2 100644 --- a/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/IndividualObservationBatchPersistenceService.java +++ b/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/IndividualObservationBatchPersistenceService.java @@ -44,6 +44,16 @@ public interface IndividualObservationBatchPersistenceService extends TuttiPersi List<IndividualObservationBatch> getAllIndividualObservationBatchsForCruise(Integer cruiseId); + /** + * Test if a sampling code suffix is available for a given cruise and species all over the existing individual observations. + * + * @param cruiseId id of the cruise of individual observations to test + * @param referenceTaxonId id of the species used in individual observations to test + * @param samplingCodeSuffix the sampling code suffix to test + * @return {@code true} if given sampling code is not already used in database, {@code false} otherwise. + */ + boolean isSamplingCodeAvailable(Integer cruiseId, Integer referenceTaxonId, String samplingCodeSuffix); + @Transactional(readOnly = false) Collection<IndividualObservationBatch> createIndividualObservationBatches(Collection<IndividualObservationBatch> individualObservations); diff --git a/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/IndividualObservationBatchPersistenceServiceImpl.java b/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/IndividualObservationBatchPersistenceServiceImpl.java index 7c274b5..3af20f5 100644 --- a/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/IndividualObservationBatchPersistenceServiceImpl.java +++ b/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/IndividualObservationBatchPersistenceServiceImpl.java @@ -63,6 +63,7 @@ import org.hibernate.type.IntegerType; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -106,6 +107,15 @@ public class IndividualObservationBatchPersistenceServiceImpl extends AbstractPe @Resource(name = "fishingOperationPersistenceService") protected FishingOperationPersistenceService fishingOperationPersistenceService; + protected Caracteristic sampleCodeCaracteristic; + + @Override + public void init() { + super.init(); + + sampleCodeCaracteristic = caracteristicService.getSampleCodeCaracteristic(); + } + @Override public List<IndividualObservationBatch> getAllIndividualObservationBatchsForCruise(Integer cruiseId) { Preconditions.checkNotNull(cruiseId); @@ -126,6 +136,45 @@ public class IndividualObservationBatchPersistenceServiceImpl extends AbstractPe } @Override + public boolean isSamplingCodeAvailable(Integer cruiseId, Integer referenceTaxonId, String samplingCodeSuffix) { + + Preconditions.checkNotNull(cruiseId); + Preconditions.checkNotNull(referenceTaxonId); + Preconditions.checkNotNull(samplingCodeSuffix); + + List<Integer> allFishingOperationIds = fishingOperationPersistenceService.getAllFishingOperationIds(cruiseId); + for (Integer fishingOperationId : allFishingOperationIds) { + + Iterator<Integer> list = queryListTyped("allFishingOperationSampleIdsWithBatchForSpecies", + "fishingOperationId", IntegerType.INSTANCE, fishingOperationId, + "referenceTaxonId", IntegerType.INSTANCE, referenceTaxonId); + + while (list.hasNext()) { + + Integer sampleId = list.next(); + + Serializable sampleMeasurementValue = samplePersistenceHelper.getSampleMeasurementValue(sampleId, sampleCodeCaracteristic); + if (sampleMeasurementValue != null) { + + if (sampleMeasurementValue.toString().endsWith(samplingCodeSuffix)) { + + // sampling code suffix found, stop NOW! + return false; + + } + + } + + } + + } + + // Free to use + return true; + + } + + @Override public List<IndividualObservationBatch> getAllIndividualObservationBatchsForFishingOperation(Integer fishingOperationId) { Preconditions.checkNotNull(fishingOperationId); diff --git a/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/util/SamplePersistenceHelper.java b/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/util/SamplePersistenceHelper.java index 36c2ddc..239c78a 100644 --- a/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/util/SamplePersistenceHelper.java +++ b/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/util/SamplePersistenceHelper.java @@ -140,27 +140,30 @@ public class SamplePersistenceHelper extends AbstractPersistenceService { CaracteristicMap caracteristicMap = sample.getCaracteristics(); while (list.hasNext()) { - int colIndex = 0; +// int colIndex = 0; Object[] source = list.next(); - Integer pmfmId = (Integer) source[colIndex++]; - Float numericalValue = (Float) source[colIndex++]; - String alphanumericalValue = (String) source[colIndex++]; - Integer qualitativeValueId = (Integer) source[colIndex]; - + Integer pmfmId = (Integer) source[0]; Caracteristic caracteristic = caracteristicService.getCaracteristic(pmfmId); - Serializable value = null; - switch (caracteristic.getCaracteristicType()) { - - case NUMBER: - value = numericalValue; - break; - case QUALITATIVE: - value = CaracteristicQualitativeValues.getQualitativeValue(caracteristic, qualitativeValueId); - break; - case TEXT: - value = alphanumericalValue; - break; - } + Serializable value = getMeasurementValue(caracteristic, source); + +// Float numericalValue = (Float) source[colIndex++]; +// String alphanumericalValue = (String) source[colIndex++]; +// Integer qualitativeValueId = (Integer) source[colIndex]; +// +// +// Serializable value = null; +// switch (caracteristic.getCaracteristicType()) { +// +// case NUMBER: +// value = numericalValue; +// break; +// case QUALITATIVE: +// value = CaracteristicQualitativeValues.getQualitativeValue(caracteristic, qualitativeValueId); +// break; +// case TEXT: +// value = alphanumericalValue; +// break; +// } caracteristicMap.put(caracteristic, value); } @@ -180,6 +183,20 @@ public class SamplePersistenceHelper extends AbstractPersistenceService { } + public <S extends SampleEntity> Serializable getSampleMeasurementValue(Integer sampleId, Caracteristic caracteristic) { + + Object[] source = queryUnique("sampleMeasurement", + "sampleId", IntegerType.INSTANCE, sampleId, + "pmfmId", IntegerType.INSTANCE, caracteristic.getIdAsInt()); + + Serializable value = null; + if (source != null) { + value = getMeasurementValue(caracteristic, source); + } + + return value; + } + public <S extends SampleEntity> CaracteristicMap extractCommonSampleCaracteristics(S sample) { CaracteristicMap caracteristics = CaracteristicMap.copy(sample.getCaracteristics()); @@ -233,4 +250,31 @@ public class SamplePersistenceHelper extends AbstractPersistenceService { return result; } + protected Serializable getMeasurementValue(Caracteristic caracteristic, Object[] source) { + + Serializable value; + // On commence à 1 car à 0 il y a le pmfmId + int colIndex = 1; +// Integer pmfmId = (Integer) source[colIndex++]; + Float numericalValue = (Float) source[colIndex++]; + String alphanumericalValue = (String) source[colIndex++]; + Integer qualitativeValueId = (Integer) source[colIndex]; + + switch (caracteristic.getCaracteristicType()) { + + case NUMBER: + value = numericalValue; + break; + case QUALITATIVE: + value = CaracteristicQualitativeValues.getQualitativeValue(caracteristic, qualitativeValueId); + break; + case TEXT: + value = alphanumericalValue; + break; + default: + throw new IllegalStateException("Can't deal with caracteristicType: " + caracteristic.getCaracteristicType()); + } + return value; + } + } diff --git a/tutti-persistence/src/main/resources/queries-failsafe.hbm.xml b/tutti-persistence/src/main/resources/queries-failsafe.hbm.xml index 4d1c4a0..464fa47 100644 --- a/tutti-persistence/src/main/resources/queries-failsafe.hbm.xml +++ b/tutti-persistence/src/main/resources/queries-failsafe.hbm.xml @@ -511,6 +511,24 @@ <query-param name="fishingOperationId" type="java.lang.Integer"/> </query> + <!-- [DAT-23] Get all fishing operations sample ids with a batch for a given taxon (they are all individual observations in Tutti) --> + <query cacheable="true" name="allFishingOperationSampleIdsWithBatchForSpecies"> + <![CDATA[ + SELECT + s.id AS id + FROM + SampleImpl s + WHERE + s.fishingOperation.id = :fishingOperationId + AND s.referenceTaxon.id = :referenceTaxonId + AND s.batch IS NOT NULL + ORDER BY + s.id + ]]> + <query-param name="fishingOperationId" type="java.lang.Integer"/> + <query-param name="referenceTaxonId" type="java.lang.Integer"/> + </query> + <!-- [DAT-23-1] Get all fishing operations samples for a given batch --> <query cacheable="true" name="allFishingOperationSamplesForBatch"> <![CDATA[ @@ -577,6 +595,24 @@ <query-param name="sampleId" type="java.lang.Integer"/> </query> + <!-- [DAT-24] Get sample measurement of a given sample id and pmfm id --> + <query cacheable="true" name="sampleMeasurement"> + <![CDATA[ + SELECT + sm.pmfm.id as pmfmId, + sm.numericalValue as numericalValue, + sm.alphanumericalValue as alphanumericalValue, + sm.qualitativeValue.id as qualitativeValueId + from + SampleMeasurementImpl sm + WHERE + sm.sample.id = :sampleId + AND sm.pmfm.id = :pmfmId + ]]> + <query-param name="sampleId" type="java.lang.Integer"/> + <query-param name="pmfmId" type="java.lang.Integer"/> + </query> + <!--query cacheable="true" name="catchBatch"> <![CDATA[ SELECT diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/PersistenceService.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/PersistenceService.java index 439a17b..6616593 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/PersistenceService.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/PersistenceService.java @@ -1665,6 +1665,11 @@ public class PersistenceService extends AbstractTuttiService implements TuttiPer } @Override + public boolean isSamplingCodeAvailable(Integer cruiseId, Integer referenceTaxonId, String samplingCodeSuffix) { + return driver.isSamplingCodeAvailable(cruiseId, referenceTaxonId, samplingCodeSuffix); + } + + @Override public Collection<IndividualObservationBatch> createIndividualObservationBatches(Collection<IndividualObservationBatch> individualObservations) { return driver.createIndividualObservationBatches(individualObservations); } diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingCodePrefix.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingCodePrefix.java index 3c65cd2..2e29d42 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingCodePrefix.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingCodePrefix.java @@ -64,6 +64,10 @@ public class SamplingCodePrefix { return toString() + samplingCodeId; } + public String toSpeciesOnlySamplingCode(int samplingCodeId) { + return species + SEPARATOR + samplingCodeId; + } + /** * Extrait l'id du code (le nombre à la fin) * @param samplingCode -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/8204 in repository tutti. See https://gitlab.nuiton.org/codelutin/tutti.git commit 572e4a5e9007712e9099c3b56502ee570f2e8029 Author: Tony CHEMIT <chemit@codelutin.com> Date: Mon Apr 4 14:48:38 2016 +0200 Ajout d'un cache de code de prélèvement viables ou non + blocage si code de prélèvement pas possible (See #8204) --- .../frequency/IndividualObservationUICache.java | 113 ++++++++++++++++----- .../frequency/SpeciesFrequencyUIHandler.java | 2 +- .../frequency/actions/EditSampleCodeAction.java | 59 ++++++++++- 3 files changed, 144 insertions(+), 30 deletions(-) diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationUICache.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationUICache.java index a0c2f63..f6a03ab 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationUICache.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationUICache.java @@ -32,6 +32,7 @@ import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativ import fr.ifremer.tutti.persistence.entities.referential.Species; import fr.ifremer.tutti.service.DecoratorService; import fr.ifremer.tutti.service.sampling.CruiseSamplingCache; +import fr.ifremer.tutti.service.sampling.SamplingCodePrefix; import fr.ifremer.tutti.service.sampling.SamplingEvent; import fr.ifremer.tutti.service.sampling.SamplingListener; import fr.ifremer.tutti.ui.swing.content.operation.catches.individualobservation.IndividualObservationBatchRowModel; @@ -44,8 +45,11 @@ import org.nuiton.decorator.Decorator; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.Closeable; +import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.Set; +import java.util.TreeSet; import static org.nuiton.i18n.I18n.t; @@ -74,11 +78,24 @@ public class IndividualObservationUICache implements Closeable { private SpeciesFrequencyUI ui; /** + * Contient les codes de prélèvements qu'on sait non utilisables. + * + * Au chargement de l'écran, on remplit cet ensemble avec les codes des observations individuelles du lot. + */ + private final Set<Integer> samplingCodesNotAvailable = new TreeSet<>(); + + /** + * Contient les codes de prélèvements qu'on sait utilisables. + * + * Dès qu'un code de prélèvement est ajouté ou modifié dans l'écran, on l'ajoute ici. + */ + private final Set<Integer> samplingCodesAvailable = new TreeSet<>(); + + /** * Est-ce que le cache est actif ? */ private boolean on; - public IndividualObservationUICache(Optional<CruiseSamplingCache> samplingCache, SpeciesFrequencyUIModel uiModel, Caracteristic sexCaracteristic) { this.samplingCache = samplingCache; @@ -162,8 +179,8 @@ public class IndividualObservationUICache implements Closeable { Decorator<Species> speciesDecorator = ui.getHandler().getDecorator(Species.class, DecoratorService.WITH_SURVEY_CODE); String key = speciesDecorator.toString(species) - + " " + Numbers.convertFromMm(event.getLengthStep(), uiModel.getLengthStepCaracteristicUnit()) - + " " + uiModel.getLengthStepCaracteristicUnit(); + + " " + Numbers.convertFromMm(event.getLengthStep(), uiModel.getLengthStepCaracteristicUnit()) + + " " + uiModel.getLengthStepCaracteristicUnit(); if (event.getGender() != null) { key += " " + event.getGender().getDescription(); } @@ -193,7 +210,7 @@ public class IndividualObservationUICache implements Closeable { } - public void init(SpeciesFrequencyUI ui, SpeciesBatchRowModel speciesEditRow, FishingOperation fishingOperation) { + public void init(SpeciesFrequencyUI ui, SpeciesBatchRowModel speciesEditRow, FishingOperation fishingOperation, List<IndividualObservationBatchRowModel> individualObservationRows) { Objects.requireNonNull(ui); Objects.requireNonNull(speciesEditRow); @@ -207,6 +224,12 @@ public class IndividualObservationUICache implements Closeable { if (samplingCache.isPresent()) { samplingCache.get().addSamplingListener(samplingListener); } + this.samplingCodesAvailable.clear(); + this.samplingCodesNotAvailable.clear(); + + individualObservationRows.stream() + .filter(individualObservationRow -> individualObservationRow.getSamplingCode() != null) + .forEach(individualObservationRow -> addSamplingCodeNotAvailable(individualObservationRow.getSamplingCode())); } @Override @@ -234,9 +257,9 @@ public class IndividualObservationUICache implements Closeable { /** * Ajoute une observation individuelle via ses composantes (sexe, maturité, classe de taille) dans le cache. * - * @param gender le sexe - * @param maturityQualitativeValue l'état de maturité - * @param lengthStep la classe de taille + * @param gender le sexe + * @param maturityQualitativeValue l'état de maturité + * @param lengthStep la classe de taille */ public void incrementsObservationNb(CaracteristicQualitativeValue gender, Optional<CaracteristicQualitativeValue> maturityQualitativeValue, float lengthStep) { incrementsObservationNb(gender, maturityQualitativeValue, lengthStep, Optional.empty()); @@ -245,10 +268,10 @@ public class IndividualObservationUICache implements Closeable { /** * Ajoute une observation individuelle via ses composantes (sexe, maturité, classe de taille) dans le cache. * - * @param gender le sexe - * @param maturityQualitativeValue l'état de maturité - * @param lengthStep la classe de taille - * @param samplingCode le code de prélèvement ajouté s'il y en a un + * @param gender le sexe + * @param maturityQualitativeValue l'état de maturité + * @param lengthStep la classe de taille + * @param samplingCode le code de prélèvement ajouté s'il y en a un */ public void incrementsObservationNb(CaracteristicQualitativeValue gender, Optional<CaracteristicQualitativeValue> maturityQualitativeValue, @@ -277,10 +300,10 @@ public class IndividualObservationUICache implements Closeable { /** * Ajoute une observation individuelle via ses composantes (sexe, maturité, classe de taille) dans le cache. * - * @param gender le sexe - * @param maturityQualitativeValue l'état de maturité - * @param lengthStep la classe de taille - * @param samplingCode le code de prélèvement ajouté + * @param gender le sexe + * @param maturityQualitativeValue l'état de maturité + * @param lengthStep la classe de taille + * @param samplingCode le code de prélèvement ajouté */ public void incrementsSamplingNb(CaracteristicQualitativeValue gender, Optional<CaracteristicQualitativeValue> maturityQualitativeValue, @@ -301,6 +324,10 @@ public class IndividualObservationUICache implements Closeable { maturity, uiModel.getLengthStepInMm(lengthStep), samplingCode); + + // Le code n'est plus utilisable + addSamplingCodeNotAvailable(samplingCode); + } /** @@ -317,9 +344,9 @@ public class IndividualObservationUICache implements Closeable { /** * Retire une observation individuelle via ses composantes (sexe, maturité, classe de taille) dans le cache. * - * @param gender le sexe - * @param maturityQualitativeValue l'état de maturité - * @param lengthStep la classe de taille + * @param gender le sexe + * @param maturityQualitativeValue l'état de maturité + * @param lengthStep la classe de taille */ public void decrementsObservationNb(CaracteristicQualitativeValue gender, Optional<CaracteristicQualitativeValue> maturityQualitativeValue, float lengthStep) { @@ -329,10 +356,10 @@ public class IndividualObservationUICache implements Closeable { /** * Retire une observation individuelle via ses composantes (sexe, maturité, classe de taille) dans le cache. * - * @param gender le sexe - * @param maturityQualitativeValue l'état de maturité - * @param lengthStep la classe de taille - * @param samplingCode le code de prélèvement supprimée + * @param gender le sexe + * @param maturityQualitativeValue l'état de maturité + * @param lengthStep la classe de taille + * @param samplingCode le code de prélèvement supprimée */ public void decrementsObservationNb(CaracteristicQualitativeValue gender, Optional<CaracteristicQualitativeValue> maturityQualitativeValue, @@ -361,10 +388,10 @@ public class IndividualObservationUICache implements Closeable { /** * Ajoute une observation individuelle via ses composantes (sexe, maturité, classe de taille) dans le cache. * - * @param gender le sexe - * @param maturityQualitativeValue l'état de maturité - * @param lengthStep la classe de taille - * @param samplingCode le code de prélèvement supprimé + * @param gender le sexe + * @param maturityQualitativeValue l'état de maturité + * @param lengthStep la classe de taille + * @param samplingCode le code de prélèvement supprimé */ public void decrementsSamplingNb(CaracteristicQualitativeValue gender, Optional<CaracteristicQualitativeValue> maturityQualitativeValue, @@ -385,6 +412,9 @@ public class IndividualObservationUICache implements Closeable { maturity, uiModel.getLengthStepInMm(lengthStep), samplingCode); + + addSamplingCodeAvailable(samplingCode); + } /** @@ -434,4 +464,35 @@ public class IndividualObservationUICache implements Closeable { } + public boolean isSamplingCodeNotAvailable(int samplingCode) { + return samplingCodesNotAvailable.contains(samplingCode); + } + + public boolean isSamplingCodeAvailable(int samplingCode) { + return samplingCodesAvailable.contains(samplingCode); + } + + public void addSamplingCodeAvailable(String samplingCode) { + + int samplingCodeNumber = SamplingCodePrefix.extractSamplingCodeIdFromSamplingCode(samplingCode); + if (log.isInfoEnabled()) { + log.info(String.format("Make samplingCode: %s (%d) available", samplingCode, samplingCodeNumber)); + } + samplingCodesNotAvailable.remove(samplingCodeNumber); + samplingCodesAvailable.add(samplingCodeNumber); + + } + + public void addSamplingCodeNotAvailable(String samplingCode) { + + int samplingCodeNumber = SamplingCodePrefix.extractSamplingCodeIdFromSamplingCode(samplingCode); + if (log.isInfoEnabled()) { + log.info(String.format("Make samplingCode: %s (%d) not available", samplingCode, samplingCodeNumber)); + } + samplingCodesNotAvailable.add(samplingCodeNumber); + samplingCodesAvailable.remove(samplingCodeNumber); + + } + + } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIHandler.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIHandler.java index f427f13..b2e114e 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIHandler.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIHandler.java @@ -934,7 +934,7 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci } - individualObservationUICache.init(ui, frequencyEditor.getEditRow(), getDataContext().getFishingOperation()); + individualObservationUICache.init(ui, frequencyEditor.getEditRow(), getDataContext().getFishingOperation(), model.getIndividualObservationRows()); model.setModify(false); diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/EditSampleCodeAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/EditSampleCodeAction.java index d935646..ad7923f 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/EditSampleCodeAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/EditSampleCodeAction.java @@ -24,12 +24,17 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.ac * #L% */ +import fr.ifremer.tutti.service.PersistenceService; +import fr.ifremer.tutti.ui.swing.TuttiUIContext; import fr.ifremer.tutti.ui.swing.content.operation.catches.individualobservation.IndividualObservationBatchRowModel; import fr.ifremer.tutti.ui.swing.content.operation.catches.individualobservation.IndividualObservationBatchTableModel; import fr.ifremer.tutti.ui.swing.content.operation.catches.individualobservation.SampleCodeEditionPopupUI; import fr.ifremer.tutti.ui.swing.content.operation.catches.individualobservation.SampleCodeEditionPopupUIModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.IndividualObservationUICache; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUI; import fr.ifremer.tutti.ui.swing.util.actions.SimpleActionSupport; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.jdesktop.swingx.JXTable; /** @@ -38,6 +43,9 @@ import org.jdesktop.swingx.JXTable; */ public class EditSampleCodeAction extends SimpleActionSupport<SpeciesFrequencyUI> { + /** Logger. */ + private static final Log log = LogFactory.getLog(EditSampleCodeAction.class); + public EditSampleCodeAction(SpeciesFrequencyUI speciesFrequencyUI) { super(speciesFrequencyUI, false); } @@ -45,8 +53,7 @@ public class EditSampleCodeAction extends SimpleActionSupport<SpeciesFrequencyUI @Override protected void onActionPerformed(SpeciesFrequencyUI ui) { JXTable obsTable = ui.getObsTable(); - IndividualObservationBatchTableModel obsTableModel = - (IndividualObservationBatchTableModel) obsTable.getModel(); + IndividualObservationBatchTableModel obsTableModel = (IndividualObservationBatchTableModel) obsTable.getModel(); int selectedRowIndex = obsTable.getSelectedRow(); IndividualObservationBatchRowModel selectedRow = obsTableModel.getRows().get(selectedRowIndex); @@ -55,8 +62,54 @@ public class EditSampleCodeAction extends SimpleActionSupport<SpeciesFrequencyUI SampleCodeEditionPopupUIModel model = sampleCodeEditionPopupUI.getModel(); if (model.isValid()) { - selectedRow.setSamplingCode(model.getSampleCodePrefix().toSamplingCode(model.getSampleCode())); + + Integer sampleCode = model.getSampleCode(); + + String samplingCode = model.getSampleCodePrefix().toSamplingCode(sampleCode); + if (log.isInfoEnabled()) { + log.info("Try to set sampling code: " + samplingCode); + } + + IndividualObservationUICache individualObservationUICache = ui.getHandler().getIndividualObservationUICache(); + + boolean samplingCodeAvailable = isSamplingCodeAvailable(individualObservationUICache, sampleCode, selectedRow); + if (!samplingCodeAvailable) { + + //TODO kmorin mettre une jolie boite de dialogue + throw new IllegalStateException("Le code de prélèvement " + samplingCode + " est déjà utilisé en base!"); + + } + selectedRow.setSamplingCode(samplingCode); obsTableModel.fireTableRowsUpdated(selectedRowIndex, selectedRowIndex); + + } + + } + + protected boolean isSamplingCodeAvailable(IndividualObservationUICache individualObservationUICache, + Integer sampleCode, + IndividualObservationBatchRowModel selectedRow) { + + if (individualObservationUICache.isSamplingCodeNotAvailable(sampleCode)) { + + // le code n'est pas disponible (on le sait depuis le cache de l'écran) + return false; + } + + if (individualObservationUICache.isSamplingCodeAvailable(sampleCode)) { + + // le code est pas disponible (on le sait depuis le cache de l'écran) + return true; } + + // on demande en base si le code est disponible + TuttiUIContext applicationContext = TuttiUIContext.getApplicationContext(); + PersistenceService persistenceService = applicationContext.getPersistenceService(); + + String samplingCodeSuffix = selectedRow.getSamplingCodePrefix().toSpeciesOnlySamplingCode(sampleCode); + return persistenceService.isSamplingCodeAvailable(applicationContext.getCruiseId(), + selectedRow.getSpecies().getReferenceTaxonId(), + samplingCodeSuffix); + } } -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
participants (1)
-
codelutin.com scm