branch feature/revue_algorithme created (now 2488271)
This is an automated email from the git hooks/post-receive script. New change to branch feature/revue_algorithme in repository tutti. See https://gitlab.nuiton.org/codelutin/tutti.git at 2488271 Utilisation d'un nouvel handler pour gérer la zone de notification This branch includes the following new commits: new d0bfe06 Déplacement du cache de haut niveau dans un paquetage plus adapté + amélioration code dans le cache (côté ui) new 2dad5f3 Revue de comment interroger le cache new 2488271 Utilisation d'un nouvel handler pour gérer la zone de notification 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 2488271da21803a1723b47c1f907c7963cad1749 Author: Tony CHEMIT <chemit@codelutin.com> Date: Tue Apr 19 10:53:45 2016 +0200 Utilisation d'un nouvel handler pour gérer la zone de notification commit 2dad5f37f58930d5fb512d9a4325c2b5304d647a Author: Tony CHEMIT <chemit@codelutin.com> Date: Tue Apr 19 10:50:16 2016 +0200 Revue de comment interroger le cache commit d0bfe0616ac5a7dd3620d00d59de2c7a770511d3 Author: Tony CHEMIT <chemit@codelutin.com> Date: Mon Apr 18 11:05:24 2016 +0200 Déplacement du cache de haut niveau dans un paquetage plus adapté + amélioration code dans le cache (côté ui) -- 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/revue_algorithme in repository tutti. See https://gitlab.nuiton.org/codelutin/tutti.git commit d0bfe0616ac5a7dd3620d00d59de2c7a770511d3 Author: Tony CHEMIT <chemit@codelutin.com> Date: Mon Apr 18 11:05:24 2016 +0200 Déplacement du cache de haut niveau dans un paquetage plus adapté + amélioration code dans le cache (côté ui) --- .../ifremer/tutti/service/PersistenceService.java | 4 +- .../fr/ifremer/tutti/service/TuttiDataContext.java | 4 +- .../service/{sampling => cruise}/CruiseCache.java | 4 +- .../{sampling => cruise}/CruiseCacheAble.java | 2 +- .../{sampling => cruise}/CruiseCacheLoader.java | 4 +- .../cps/CalcifiedPiecesSamplingExportService.java | 2 +- .../service/sampling/CruiseSamplingCache.java | 57 +++++++++++++++++++++- .../tutti/service/sampling/SamplingCodeCache.java | 1 + .../fr/ifremer/tutti/ui/swing/TuttiUIContext.java | 2 +- .../content/actions/EditCatchesSupportAction.java | 2 +- .../CalcifiedPiecesSamplingReportAction.java | 2 +- .../SamplingCodeCellEditor.java | 2 +- .../IndividualObservationBatchTableHandler.java | 2 +- .../frequency/IndividualObservationUICache.java | 14 +++--- 14 files changed, 81 insertions(+), 21 deletions(-) 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 d72bfa5..771cc7e 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 @@ -66,8 +66,8 @@ import fr.ifremer.tutti.persistence.entities.referential.Vessels; import fr.ifremer.tutti.persistence.model.ProgramDataModel; import fr.ifremer.tutti.persistence.service.TuttiPersistenceServiceLocator; import fr.ifremer.tutti.persistence.service.UpdateSchemaContextSupport; -import fr.ifremer.tutti.service.sampling.CruiseCache; -import fr.ifremer.tutti.service.sampling.CruiseCacheLoader; +import fr.ifremer.tutti.service.cruise.CruiseCache; +import fr.ifremer.tutti.service.cruise.CruiseCacheLoader; import fr.ifremer.tutti.service.sampling.CruiseSamplingCache; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.io.IOUtils; diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/TuttiDataContext.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/TuttiDataContext.java index e35776a..09fd0b0 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/TuttiDataContext.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/TuttiDataContext.java @@ -40,8 +40,8 @@ import fr.ifremer.tutti.persistence.entities.referential.Species; import fr.ifremer.tutti.persistence.entities.referential.TaxonCache; import fr.ifremer.tutti.persistence.entities.referential.TaxonCaches; import fr.ifremer.tutti.persistence.entities.referential.Vessel; -import fr.ifremer.tutti.service.sampling.CruiseCache; -import fr.ifremer.tutti.service.sampling.CruiseCacheLoader; +import fr.ifremer.tutti.service.cruise.CruiseCache; +import fr.ifremer.tutti.service.cruise.CruiseCacheLoader; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseCache.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/cruise/CruiseCache.java similarity index 96% rename from tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseCache.java rename to tutti-service/src/main/java/fr/ifremer/tutti/service/cruise/CruiseCache.java index 98bf67f..acc4edb 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseCache.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/cruise/CruiseCache.java @@ -1,8 +1,10 @@ -package fr.ifremer.tutti.service.sampling; +package fr.ifremer.tutti.service.cruise; import com.google.common.base.MoreObjects; import fr.ifremer.tutti.persistence.entities.data.FishingOperation; import fr.ifremer.tutti.persistence.entities.data.IndividualObservationBatch; +import fr.ifremer.tutti.service.sampling.CruiseSamplingCache; +import fr.ifremer.tutti.service.sampling.SamplingCodeCache; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseCacheAble.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/cruise/CruiseCacheAble.java similarity index 97% rename from tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseCacheAble.java rename to tutti-service/src/main/java/fr/ifremer/tutti/service/cruise/CruiseCacheAble.java index 88e2015..7cb6f1f 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseCacheAble.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/cruise/CruiseCacheAble.java @@ -1,4 +1,4 @@ -package fr.ifremer.tutti.service.sampling; +package fr.ifremer.tutti.service.cruise; import fr.ifremer.tutti.persistence.entities.data.FishingOperation; import fr.ifremer.tutti.persistence.entities.data.IndividualObservationBatch; diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseCacheLoader.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/cruise/CruiseCacheLoader.java similarity index 97% rename from tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseCacheLoader.java rename to tutti-service/src/main/java/fr/ifremer/tutti/service/cruise/CruiseCacheLoader.java index db4c529..00be5f3 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseCacheLoader.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/cruise/CruiseCacheLoader.java @@ -1,4 +1,4 @@ -package fr.ifremer.tutti.service.sampling; +package fr.ifremer.tutti.service.cruise; /* * #%L @@ -31,6 +31,8 @@ import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocol; import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; import fr.ifremer.tutti.service.DecoratorService; import fr.ifremer.tutti.service.PersistenceService; +import fr.ifremer.tutti.service.sampling.CruiseSamplingCache; +import fr.ifremer.tutti.service.sampling.SamplingCodeCache; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuiton.decorator.Decorator; diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/export/cps/CalcifiedPiecesSamplingExportService.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/export/cps/CalcifiedPiecesSamplingExportService.java index 58d2dac..8142513 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/export/cps/CalcifiedPiecesSamplingExportService.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/export/cps/CalcifiedPiecesSamplingExportService.java @@ -34,7 +34,7 @@ import fr.ifremer.tutti.service.PersistenceService; import fr.ifremer.tutti.service.TuttiDataContext; import fr.ifremer.tutti.service.TuttiServiceContext; import fr.ifremer.tutti.service.sampling.CacheExtractedKey; -import fr.ifremer.tutti.service.sampling.CruiseCache; +import fr.ifremer.tutti.service.cruise.CruiseCache; import fr.ifremer.tutti.service.sampling.CruiseSamplingCache; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; 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 ad39cb7..663a33f 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 @@ -38,6 +38,7 @@ import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; import fr.ifremer.tutti.persistence.entities.referential.Species; import fr.ifremer.tutti.persistence.entities.referential.TuttiLocation; +import fr.ifremer.tutti.service.cruise.CruiseCacheAble; import fr.ifremer.tutti.util.Numbers; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -136,7 +137,7 @@ public class CruiseSamplingCache implements CruiseCacheAble { public void addFishingOperation(FishingOperation fishingOperation, Collection<IndividualObservationBatch> individualObservations) { addIndividualObservations(fishingOperation, individualObservations); - + } @Override @@ -334,6 +335,60 @@ public class CruiseSamplingCache implements CruiseCacheAble { .toString(); } + public CalcifiedPiecesSamplingStatus getStatus(IndividualObservationBatch individualObservationBatch, + Integer lengthStep, + CaracteristicQualitativeValue gender, + Boolean maturity) { + + Objects.requireNonNull(individualObservationBatch); + + FishingOperation fishingOperation = individualObservationBatch.getFishingOperation(); + Objects.requireNonNull(fishingOperation); + + Species species = individualObservationBatch.getSpecies(); + Objects.requireNonNull(species); + + if (lengthStep == null) { + + // pas de classe de taille définie, on ne peut rien calculer + // on considère que l'observation individuelle ne rentre pas dans l'algorithme + + throw new RuntimeException(""); + + } + + Optional<Zone> optionalZone = tryFindZone(fishingOperation); + if (!optionalZone.isPresent()) { + throw new IllegalStateException("Can't find zone for a matching individual observation: " + individualObservationBatch); + } + + Optional<CalcifiedPiecesSamplingDefinition> optionalCalcifiedPiecesSamplingDefinition = + tryToFindCalcifiedPiecesSamplingDefinition(species, maturity, lengthStep, gender); + + if (!optionalCalcifiedPiecesSamplingDefinition.isPresent()) { + + // ne rentre pas dans l'algorithme + throw new RuntimeException(""); + + } + + CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); + + + Zone zone = optionalZone.get(); + int totalSamplingInCruise = 0; + int totalSamplingInFishingOperation = 0; + int totalSamplingInZone = 0; + + return new CalcifiedPiecesSamplingStatus(individualObservationBatch, + calcifiedPiecesSamplingDefinition, + zone, + totalSamplingInCruise, + totalSamplingInFishingOperation, + totalSamplingInZone); + + } + /** * Ajout d'un observation dans le cache. * diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingCodeCache.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingCodeCache.java index 149f8d2..e184bfc 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingCodeCache.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingCodeCache.java @@ -2,6 +2,7 @@ package fr.ifremer.tutti.service.sampling; import fr.ifremer.tutti.persistence.entities.data.FishingOperation; import fr.ifremer.tutti.persistence.entities.data.IndividualObservationBatch; +import fr.ifremer.tutti.service.cruise.CruiseCacheAble; import org.apache.commons.lang3.mutable.MutableInt; import java.io.IOException; diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiUIContext.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiUIContext.java index 71e144e..f7e5919 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiUIContext.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiUIContext.java @@ -57,7 +57,7 @@ import fr.ifremer.tutti.service.referential.ReferentialTemporarySpeciesService; import fr.ifremer.tutti.service.referential.ReferentialTemporaryVesselService; import fr.ifremer.tutti.service.referential.TuttiReferentialSynchronizeService; import fr.ifremer.tutti.service.report.ReportGenerationService; -import fr.ifremer.tutti.service.sampling.CruiseCacheLoader; +import fr.ifremer.tutti.service.cruise.CruiseCacheLoader; import fr.ifremer.tutti.ui.swing.content.MainUI; import fr.ifremer.tutti.ui.swing.updater.DeleteHelper; import fr.ifremer.tutti.ui.swing.util.SoundEngine; diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/actions/EditCatchesSupportAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/actions/EditCatchesSupportAction.java index 494a8c1..6d19ec6 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/actions/EditCatchesSupportAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/actions/EditCatchesSupportAction.java @@ -27,7 +27,7 @@ import fr.ifremer.tutti.persistence.ProgressionModel; import fr.ifremer.tutti.persistence.entities.data.FishingOperation; import fr.ifremer.tutti.service.TuttiDataContext; import fr.ifremer.tutti.service.ValidationService; -import fr.ifremer.tutti.service.sampling.CruiseCacheLoader; +import fr.ifremer.tutti.service.cruise.CruiseCacheLoader; import fr.ifremer.tutti.ui.swing.TuttiScreen; import fr.ifremer.tutti.ui.swing.TuttiUIContext; import fr.ifremer.tutti.ui.swing.content.MainUIHandler; diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/home/actions/CalcifiedPiecesSamplingReportAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/home/actions/CalcifiedPiecesSamplingReportAction.java index 41148e7..e035763 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/home/actions/CalcifiedPiecesSamplingReportAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/home/actions/CalcifiedPiecesSamplingReportAction.java @@ -29,7 +29,7 @@ import fr.ifremer.tutti.persistence.ProgressionModel; import fr.ifremer.tutti.persistence.entities.data.Cruise; import fr.ifremer.tutti.service.TuttiDataContext; import fr.ifremer.tutti.service.export.cps.CalcifiedPiecesSamplingExportService; -import fr.ifremer.tutti.service.sampling.CruiseCacheLoader; +import fr.ifremer.tutti.service.cruise.CruiseCacheLoader; import fr.ifremer.tutti.ui.swing.TuttiUIContext; import fr.ifremer.tutti.ui.swing.content.MainUIHandler; import fr.ifremer.tutti.ui.swing.content.actions.AbstractMainUITuttiAction; diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/SamplingCodeCellEditor.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/SamplingCodeCellEditor.java index 3fdba0f..a300165 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/SamplingCodeCellEditor.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/SamplingCodeCellEditor.java @@ -23,7 +23,7 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.individualobservatio */ import com.google.common.base.Preconditions; -import fr.ifremer.tutti.service.sampling.CruiseCache; +import fr.ifremer.tutti.service.cruise.CruiseCache; import fr.ifremer.tutti.service.sampling.SamplingCodeCache; import fr.ifremer.tutti.ui.swing.TuttiUIContext; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.IndividualObservationBatchRowModel; diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationBatchTableHandler.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationBatchTableHandler.java index 7a563e3..3652e9b 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationBatchTableHandler.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationBatchTableHandler.java @@ -13,7 +13,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.TuttiDataContext; -import fr.ifremer.tutti.service.sampling.CruiseCache; +import fr.ifremer.tutti.service.cruise.CruiseCache; import fr.ifremer.tutti.service.sampling.SamplingCodePrefix; import fr.ifremer.tutti.type.WeightUnit; import fr.ifremer.tutti.ui.swing.content.operation.catches.individualobservation.SamplingCodeCellEditor; 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 5a0bf0a..ebe8de6 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 @@ -30,7 +30,7 @@ import fr.ifremer.tutti.persistence.entities.protocol.Zone; import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; import fr.ifremer.tutti.persistence.entities.referential.Species; import fr.ifremer.tutti.service.DecoratorService; -import fr.ifremer.tutti.service.sampling.CruiseCache; +import fr.ifremer.tutti.service.cruise.CruiseCache; import fr.ifremer.tutti.service.sampling.CruiseSamplingCache; import fr.ifremer.tutti.service.sampling.SamplingCodeCache; import fr.ifremer.tutti.service.sampling.SamplingCodePrefix; @@ -252,7 +252,7 @@ public class IndividualObservationUICache implements Closeable { if (withSamplingCache) { - Boolean maturity = cruiseSamplingCache.getMaturity(uiModel.getBatch().getSpecies().getReferenceTaxonId(), maturityQualitativeValue); + Boolean maturity = cruiseSamplingCache.getMaturity(species.getReferenceTaxonId(), maturityQualitativeValue); cruiseSamplingCache.addIndividualObservation(fishingOperation, species, gender, @@ -286,7 +286,7 @@ public class IndividualObservationUICache implements Closeable { if (withSamplingCache) { - Boolean maturity = cruiseSamplingCache.getMaturity(uiModel.getBatch().getSpecies().getReferenceTaxonId(), maturityQualitativeValue); + Boolean maturity = cruiseSamplingCache.getMaturity(species.getReferenceTaxonId(), maturityQualitativeValue); int lengthStepInMm = uiModel.getLengthStepInMm(lengthStep); cruiseSamplingCache.addSampling(fishingOperation, species, @@ -353,7 +353,7 @@ public class IndividualObservationUICache implements Closeable { if (withSamplingCache) { - Boolean maturity = cruiseSamplingCache.getMaturity(uiModel.getBatch().getSpecies().getReferenceTaxonId(), maturityQualitativeValue); + Boolean maturity = cruiseSamplingCache.getMaturity(species.getReferenceTaxonId(), maturityQualitativeValue); cruiseSamplingCache.removeIndividualObservation(fishingOperation, species, gender, @@ -380,7 +380,7 @@ public class IndividualObservationUICache implements Closeable { if (withSamplingCache) { - Boolean maturity = cruiseSamplingCache.getMaturity(uiModel.getBatch().getSpecies().getReferenceTaxonId(), maturityQualitativeValue); + Boolean maturity = cruiseSamplingCache.getMaturity(species.getReferenceTaxonId(), maturityQualitativeValue); cruiseSamplingCache.removeSampling(fishingOperation, species, gender, @@ -523,7 +523,7 @@ public class IndividualObservationUICache implements Closeable { public void decrementsSamplingCode(String samplingCode) { - samplingCodeCache.removeSamplingCode(uiModel.getBatch().getSpecies().getReferenceTaxonId(), samplingCode); + samplingCodeCache.removeSamplingCode(species.getReferenceTaxonId(), samplingCode); // Le code est utilisable addSamplingCodeAvailable(samplingCode); @@ -532,7 +532,7 @@ public class IndividualObservationUICache implements Closeable { public void incrementsSamplingCode(String samplingCode) { - samplingCodeCache.addSamplingCode(uiModel.getBatch().getSpecies().getReferenceTaxonId(), samplingCode); + samplingCodeCache.addSamplingCode(species.getReferenceTaxonId(), samplingCode); // Le code n'est plus utilisable addSamplingCodeNotAvailable(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/revue_algorithme in repository tutti. See https://gitlab.nuiton.org/codelutin/tutti.git commit 2dad5f37f58930d5fb512d9a4325c2b5304d647a Author: Tony CHEMIT <chemit@codelutin.com> Date: Tue Apr 19 10:50:16 2016 +0200 Revue de comment interroger le cache --- ...cesSamplingAlgorithmEntryNotFoundException.java | 17 + .../service/sampling/CruiseSamplingCache.java | 576 ++++++++++----------- .../sampling/CruiseSamplingInternalCache.java | 147 ++---- .../IndividualObservationSamplingContext.java | 148 ++++++ .../IndividualObservationSamplingStatus.java | 126 +++++ ...lObservationSamplingStatusExceptionSupport.java | 29 ++ .../tutti/service/sampling/SamplingEvent.java | 68 +-- .../tutti/service/sampling/SamplingListener.java | 1 - ...NotDefinedOnIndividualObservationException.java | 17 + .../ZoneNotDefinedOnFishingOperationException.java | 17 + 10 files changed, 691 insertions(+), 455 deletions(-) diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CalcifiedPiecesSamplingAlgorithmEntryNotFoundException.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CalcifiedPiecesSamplingAlgorithmEntryNotFoundException.java new file mode 100644 index 0000000..b099a83 --- /dev/null +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CalcifiedPiecesSamplingAlgorithmEntryNotFoundException.java @@ -0,0 +1,17 @@ +package fr.ifremer.tutti.service.sampling; + +import fr.ifremer.tutti.persistence.entities.data.IndividualObservationBatch; + +/** + * Quand l'algorithme de prélèvement de pièces calcifiés n'est pas trouvé pour une observation individuelle. + * + * Created on 18/04/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class CalcifiedPiecesSamplingAlgorithmEntryNotFoundException extends IndividualObservationSamplingStatusExceptionSupport { + + public CalcifiedPiecesSamplingAlgorithmEntryNotFoundException(IndividualObservationBatch individualObservationBatch) { + super(individualObservationBatch); + } +} 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 663a33f..61507f6 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 @@ -64,15 +64,15 @@ public class CruiseSamplingCache implements CruiseCacheAble { /** * Le cache des échantillons au niveau de la campagne. */ - private final CruiseSamplingInternalCache totalCruiseCache = new CruiseSamplingInternalCache(); + private final CruiseSamplingInternalCache cruiseCache = new CruiseSamplingInternalCache(); /** * Le cache des échantillons au niveau de chaque zone. */ private final CruiseSamplingInternalCache zoneCache = new CruiseSamplingInternalCache(); /** - * Le cache des échantillons au niveau de chaque opération. + * Le cache des échantillons au niveau de chaque opération de pêche. */ - private final CruiseSamplingInternalCache operationCache = new CruiseSamplingInternalCache(); + private final CruiseSamplingInternalCache fishingOperationCache = new CruiseSamplingInternalCache(); /** * Le dictionnaire des identifiants de strates ou sous-strates pour chaque zone. */ @@ -146,12 +146,20 @@ public class CruiseSamplingCache implements CruiseCacheAble { Objects.requireNonNull(fishingOperation); Objects.requireNonNull(individualObservations); + Optional<Zone> optionalZone = tryFindZone(fishingOperation); + if (!optionalZone.isPresent()) { + + // pas de zone définie pour cette opération de pêche, on n'enregistre rien ici. + return; + + } + + Zone zone = optionalZone.get(); + setLoading(true); try { - - Zone optionalZone = tryFindZone(fishingOperation).orElse(null); int fishingOperationId = fishingOperation.getIdAsInt(); for (IndividualObservationBatch individualObservationBatch : individualObservations) { @@ -178,14 +186,23 @@ public class CruiseSamplingCache implements CruiseCacheAble { CaracteristicQualitativeValue gender = individualObservationBatch.getCaracteristics().getQualitativeValue(sexCaracteristic); - CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); +// CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); + + IndividualObservationSamplingContext individualObservationSamplingContext = + createContext(fishingOperation.getIdAsInt(), + species, + zone, + optionalCalcifiedPiecesSamplingDefinition.get(), + lengthStepInMm, + maturity, + gender); - addIndividualObservation(calcifiedPiecesSamplingDefinition, fishingOperationId, optionalZone, species, gender, maturity, lengthStepInMm); + addIndividualObservation(individualObservationSamplingContext); String samplingCode = individualObservationBatch.getSamplingCode(); if (samplingCode != null) { - addSampling(calcifiedPiecesSamplingDefinition, fishingOperationId, optionalZone, species, gender, maturity, lengthStepInMm); + addSampling(individualObservationSamplingContext); } @@ -205,11 +222,20 @@ public class CruiseSamplingCache implements CruiseCacheAble { Objects.requireNonNull(fishingOperation); Objects.requireNonNull(individualObservations); + Optional<Zone> optionalZone = tryFindZone(fishingOperation); + if (!optionalZone.isPresent()) { + + // pas de zone définie pour cette opération de pêche, rien à supprimer alors. + return; + + } + + Zone zone = optionalZone.get(); + setLoading(true); try { - Zone optionalZone = tryFindZone(fishingOperation).orElse(null); int fishingOperationId = fishingOperation.getIdAsInt(); for (IndividualObservationBatch individualObservationBatch : individualObservations) { @@ -219,7 +245,7 @@ public class CruiseSamplingCache implements CruiseCacheAble { if (!optionalCalcifiedPiecesSamplingDefinition.isPresent()) { - // pas dans l'algorithme, one ne tient pas compte de cette observation + // pas dans l'algorithme, on ne tient pas compte de cette observation continue; } @@ -228,21 +254,32 @@ public class CruiseSamplingCache implements CruiseCacheAble { Boolean maturity = getMaturity(individualObservationBatch); + Objects.requireNonNull(individualObservationBatch.getSize()); float lengthStep = individualObservationBatch.getSize(); int lengthStepInMm = Numbers.convertToMm(lengthStep, individualObservationBatch.getLengthStepCaracteristic().getUnit()); CaracteristicQualitativeValue gender = individualObservationBatch.getCaracteristics().getQualitativeValue(sexCaracteristic); - CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); +// CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); + + IndividualObservationSamplingContext individualObservationSamplingContext = + createContext(fishingOperation.getIdAsInt(), + species, + zone, + optionalCalcifiedPiecesSamplingDefinition.get(), + lengthStepInMm, + maturity, + gender); String samplingCode = individualObservationBatch.getSamplingCode(); if (samplingCode != null) { - removeSampling(calcifiedPiecesSamplingDefinition, fishingOperationId, optionalZone, species, gender, maturity, lengthStepInMm); + removeSampling(individualObservationSamplingContext); } - removeIndividualObservation(calcifiedPiecesSamplingDefinition, fishingOperationId, optionalZone, species, gender, maturity, lengthStepInMm); + + removeIndividualObservation(individualObservationSamplingContext); } @@ -260,6 +297,16 @@ public class CruiseSamplingCache implements CruiseCacheAble { Objects.requireNonNull(fishingOperation); Objects.requireNonNull(individualObservations); + Optional<Zone> optionalZone = tryFindZone(fishingOperation); + if (!optionalZone.isPresent()) { + + // pas de zone définie pour cette opération de pêche, rien à supprimer alors. + return; + + } + + Zone zone = optionalZone.get(); + setLoading(true); try { @@ -271,27 +318,23 @@ public class CruiseSamplingCache implements CruiseCacheAble { } // suppression de toutes les entrées du cache des opérations (et récupération des clefs) - Set<String> removedKeys = operationCache.removeAllWhereKeyStartingWith(fishingOperationId); + Set<String> removedKeys = fishingOperationCache.removeAllWhereKeyStartingWith(fishingOperationId); if (log.isInfoEnabled()) { - log.info("Fishing operation: " + fishingOperation + " removed from operationCache: " + operationCache.size()); + log.info("Fishing operation: " + fishingOperation + " removed from fishingOperationCache: " + fishingOperationCache.size()); } - removedKeys.forEach(totalCruiseCache::decrementObservationNb); + removedKeys.forEach(cruiseCache::removeOneIndividualObservation); if (log.isInfoEnabled()) { - log.info("Fishing operation: " + fishingOperation + " removed from totalCruiseCache: " + totalCruiseCache.size()); + log.info("Fishing operation: " + fishingOperation + " removed from cruiseCache: " + cruiseCache.size()); } - Optional<Zone> optionalZone = tryFindZone(fishingOperation); + String zoneId = zone.getId(); + removedKeys.forEach(key -> zoneCache.removeOneIndividualObservation(CruiseSamplingInternalCache.addPrefixKey(zoneId, key))); - if (optionalZone.isPresent()) { - String zoneId = optionalZone.get().getId(); - removedKeys.forEach(key -> zoneCache.decrementObservationNbIfExist(CruiseSamplingInternalCache.addPrefixKey(zoneId, key))); - - if (log.isInfoEnabled()) { - log.info("Fishing operation: " + fishingOperation + " removed from zoneCache: " + zoneCache.size()); - } + if (log.isInfoEnabled()) { + log.info("Fishing operation: " + fishingOperation + " removed from zoneCache: " + zoneCache.size()); } if (log.isInfoEnabled()) { @@ -312,9 +355,9 @@ public class CruiseSamplingCache implements CruiseCacheAble { if (log.isInfoEnabled()) { log.info("Closing cruise sampling cache."); } - totalCruiseCache.close(); + cruiseCache.close(); zoneCache.close(); - operationCache.close(); + fishingOperationCache.close(); locationIdsPerZone.clear(); cpsDefinitionsBySpecies.clear(); maturityCaracteristicBySpecies.clear(); @@ -329,63 +372,63 @@ public class CruiseSamplingCache implements CruiseCacheAble { @Override public String toString() { return MoreObjects.toStringHelper(this) - .add("totalCruiseCache", totalCruiseCache.size()) + .add("cruiseCache", cruiseCache.size()) .add("zoneCache", zoneCache.size()) - .add("operationCache", operationCache.size()) + .add("fishingOperationCache", fishingOperationCache.size()) .toString(); } - public CalcifiedPiecesSamplingStatus getStatus(IndividualObservationBatch individualObservationBatch, - Integer lengthStep, - CaracteristicQualitativeValue gender, - Boolean maturity) { - - Objects.requireNonNull(individualObservationBatch); + public IndividualObservationSamplingStatus getIndividualObservationSamplingStatus(FishingOperation fishingOperation, + IndividualObservationBatch individualObservationBatch, + Integer lengthStep, + CaracteristicQualitativeValue gender, + CaracteristicQualitativeValue maturity) throws SizeNotDefinedOnIndividualObservationException, ZoneNotDefinedOnFishingOperationException, CalcifiedPiecesSamplingAlgorithmEntryNotFoundException { - FishingOperation fishingOperation = individualObservationBatch.getFishingOperation(); Objects.requireNonNull(fishingOperation); + Objects.requireNonNull(individualObservationBatch); Species species = individualObservationBatch.getSpecies(); Objects.requireNonNull(species); if (lengthStep == null) { - // pas de classe de taille définie, on ne peut rien calculer - // on considère que l'observation individuelle ne rentre pas dans l'algorithme - - throw new RuntimeException(""); - + throw new SizeNotDefinedOnIndividualObservationException(individualObservationBatch); } Optional<Zone> optionalZone = tryFindZone(fishingOperation); if (!optionalZone.isPresent()) { - throw new IllegalStateException("Can't find zone for a matching individual observation: " + individualObservationBatch); + + throw new ZoneNotDefinedOnFishingOperationException(individualObservationBatch); } + Boolean maturityAsBoolean = getMaturity(individualObservationBatch, maturity); + Optional<CalcifiedPiecesSamplingDefinition> optionalCalcifiedPiecesSamplingDefinition = - tryToFindCalcifiedPiecesSamplingDefinition(species, maturity, lengthStep, gender); + tryToFindCalcifiedPiecesSamplingDefinition(species, maturityAsBoolean, lengthStep, gender); if (!optionalCalcifiedPiecesSamplingDefinition.isPresent()) { - // ne rentre pas dans l'algorithme - throw new RuntimeException(""); - + throw new CalcifiedPiecesSamplingAlgorithmEntryNotFoundException(individualObservationBatch); } - CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); + IndividualObservationSamplingContext context = createContext(fishingOperation.getIdAsInt(), + individualObservationBatch.getSpecies(), + optionalZone.get(), + optionalCalcifiedPiecesSamplingDefinition.get(), + lengthStep, + maturityAsBoolean, + gender); + String cruiseSamplingKey = context.getCruiseSamplingKey(); + CruiseSamplingInternalCache.SamplingData cruiseSamplingData = cruiseCache.getSamplingData(cruiseSamplingKey); - Zone zone = optionalZone.get(); - int totalSamplingInCruise = 0; - int totalSamplingInFishingOperation = 0; - int totalSamplingInZone = 0; + String zoneSamplingKey = context.getZoneSamplingKey(); + CruiseSamplingInternalCache.SamplingData zoneSamplingData = zoneCache.getSamplingData(zoneSamplingKey); - return new CalcifiedPiecesSamplingStatus(individualObservationBatch, - calcifiedPiecesSamplingDefinition, - zone, - totalSamplingInCruise, - totalSamplingInFishingOperation, - totalSamplingInZone); + String fishingOperationSamplingKey = context.getFishingOperationSamplingKey(); + CruiseSamplingInternalCache.SamplingData fishingOperationSamplingData = fishingOperationCache.getSamplingData(fishingOperationSamplingKey); + + return new IndividualObservationSamplingStatus(context, cruiseSamplingData, zoneSamplingData, fishingOperationSamplingData); } @@ -407,20 +450,36 @@ public class CruiseSamplingCache implements CruiseCacheAble { Objects.requireNonNull(fishingOperation); Objects.requireNonNull(species); + Optional<Zone> optionalZone = tryFindZone(fishingOperation); + if (!optionalZone.isPresent()) { + + if (log.isInfoEnabled()) { + log.info("Do not add individual observation in cache, fishing operation has no matching zone."); + } + return; + } + Optional<CalcifiedPiecesSamplingDefinition> optionalCalcifiedPiecesSamplingDefinition = tryToFindCalcifiedPiecesSamplingDefinition(species, maturity, lengthStep, gender); if (!optionalCalcifiedPiecesSamplingDefinition.isPresent()) { - // pas dans l'algorithme, one ne tient pas compte de cette observation + if (log.isInfoEnabled()) { + log.info("Do not add individual observation in cache, no definition matched."); + } return; } - CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); + IndividualObservationSamplingContext individualObservationSamplingContext = + createContext(fishingOperation.getIdAsInt(), + species, + optionalZone.get(), + optionalCalcifiedPiecesSamplingDefinition.get(), + lengthStep, + maturity, + gender); - Optional<Zone> optionalZone = tryFindZone(fishingOperation); - - addIndividualObservation(calcifiedPiecesSamplingDefinition, fishingOperation.getIdAsInt(), optionalZone.orElse(null), species, gender, maturity, lengthStep); + addIndividualObservation(individualObservationSamplingContext); } @@ -443,17 +502,35 @@ public class CruiseSamplingCache implements CruiseCacheAble { Objects.requireNonNull(species); Optional<Zone> optionalZone = tryFindZone(fishingOperation); + if (!optionalZone.isPresent()) { + + if (log.isInfoEnabled()) { + log.info("Do not remove individual observation from cache, fishing operation has no matching zone."); + } + return; + } Optional<CalcifiedPiecesSamplingDefinition> optionalCalcifiedPiecesSamplingDefinition = tryToFindCalcifiedPiecesSamplingDefinition(species, maturity, lengthStep, gender); if (!optionalCalcifiedPiecesSamplingDefinition.isPresent()) { + + if (log.isInfoEnabled()) { + log.info("Do not remove individual observation from cache, no definition matched."); + } return; } - CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); + IndividualObservationSamplingContext individualObservationSamplingContext = + createContext(fishingOperation.getIdAsInt(), + species, + optionalZone.get(), + optionalCalcifiedPiecesSamplingDefinition.get(), + lengthStep, + maturity, + gender); - removeIndividualObservation(calcifiedPiecesSamplingDefinition, fishingOperation.getIdAsInt(), optionalZone.orElse(null), species, gender, maturity, lengthStep); + removeIndividualObservation(individualObservationSamplingContext); } @@ -476,6 +553,13 @@ public class CruiseSamplingCache implements CruiseCacheAble { Objects.requireNonNull(species); Optional<Zone> optionalZone = tryFindZone(fishingOperation); + if (!optionalZone.isPresent()) { + + if (log.isInfoEnabled()) { + log.info("Do not record sampling in cache, fishing operation has no matching zone."); + } + return; + } Optional<CalcifiedPiecesSamplingDefinition> optionalCalcifiedPiecesSamplingDefinition = tryToFindCalcifiedPiecesSamplingDefinition(species, maturity, lengthStep, gender); @@ -483,14 +567,21 @@ public class CruiseSamplingCache implements CruiseCacheAble { if (!optionalCalcifiedPiecesSamplingDefinition.isPresent()) { if (log.isInfoEnabled()) { - log.info("Do not record sampling code in cache, definition not matched."); + log.info("Do not record sampling in cache, no definition matched."); } return; } - CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); + IndividualObservationSamplingContext individualObservationSamplingContext = + createContext(fishingOperation.getIdAsInt(), + species, + optionalZone.get(), + optionalCalcifiedPiecesSamplingDefinition.get(), + lengthStep, + maturity, + gender); - addSampling(calcifiedPiecesSamplingDefinition, fishingOperation.getIdAsInt(), optionalZone.orElse(null), species, gender, maturity, lengthStep); + addSampling(individualObservationSamplingContext); } @@ -513,72 +604,34 @@ public class CruiseSamplingCache implements CruiseCacheAble { Objects.requireNonNull(species); Optional<Zone> optionalZone = tryFindZone(fishingOperation); + if (!optionalZone.isPresent()) { - Optional<CalcifiedPiecesSamplingDefinition> optionalCalcifiedPiecesSamplingDefinition = tryToFindCalcifiedPiecesSamplingDefinition(species, maturity, lengthStep, gender); - - if (!optionalCalcifiedPiecesSamplingDefinition.isPresent()) { + if (log.isInfoEnabled()) { + log.info("Do not remove sampling from cache, fishing operation has no matching zone."); + } return; } - CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); - - removeSampling(calcifiedPiecesSamplingDefinition, fishingOperation.getIdAsInt(), optionalZone.orElse(null), species, gender, maturity, lengthStep); - - } - - public Optional<SamplingEvent> getEventForSummary(FishingOperation fishingOperation, - Species species, - Boolean maturity, - CaracteristicQualitativeValue gender, - int lengthStep) { - - Objects.requireNonNull(fishingOperation); - Objects.requireNonNull(species); - Optional<CalcifiedPiecesSamplingDefinition> optionalCalcifiedPiecesSamplingDefinition = tryToFindCalcifiedPiecesSamplingDefinition(species, maturity, lengthStep, gender); - SamplingEvent event = null; - if (optionalCalcifiedPiecesSamplingDefinition.isPresent()) { - - CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = optionalCalcifiedPiecesSamplingDefinition.get(); - - if (log.isInfoEnabled()) { - log.info("Found matching sampling definition: " + calcifiedPiecesSamplingDefinition); - } - - if (!calcifiedPiecesSamplingDefinition.isSex()) { - gender = null; - } - - String samplingKey = CruiseSamplingInternalCache.createSamplingKey(species, gender, maturity, lengthStep); - - int totalValue = totalCruiseCache.getObservationNb(samplingKey); - int totalSamplingNb = totalCruiseCache.getSamplingNb(samplingKey); - - int zoneValue = 0; - int zoneSamplingNb = 0; - - Optional<Zone> optionalZone = tryFindZone(fishingOperation); - if (optionalZone.isPresent()) { - String zoneKey = CruiseSamplingInternalCache.addPrefixKey(optionalZone.get().getId(), samplingKey); - zoneValue = zoneCache.getObservationNb(zoneKey); - zoneSamplingNb = zoneCache.getSamplingNb(zoneKey); - } - - String operationKey = CruiseSamplingInternalCache.addPrefixKey(fishingOperation.getIdAsInt(), samplingKey); - - int operationValue = operationCache.getObservationNb(operationKey); - int operationSamplingNb = operationCache.getSamplingNb(operationKey); + if (!optionalCalcifiedPiecesSamplingDefinition.isPresent()) { if (log.isInfoEnabled()) { - log.info("add Individual Observation " + samplingKey + " ⇒ op " + operationValue + " / zone " + zoneValue + " / cruise " + totalValue); + log.info("Do not remove sampling from cache, no definition matched."); } - - event = new SamplingEvent(this, lengthStep, gender, maturity, calcifiedPiecesSamplingDefinition, optionalZone.orElse(null), totalSamplingNb, zoneSamplingNb, operationSamplingNb); - + return; } - return Optional.ofNullable(event); + IndividualObservationSamplingContext individualObservationSamplingContext = + createContext(fishingOperation.getIdAsInt(), + species, + optionalZone.get(), + optionalCalcifiedPiecesSamplingDefinition.get(), + lengthStep, + maturity, + gender); + + removeSampling(individualObservationSamplingContext); } @@ -607,7 +660,18 @@ public class CruiseSamplingCache implements CruiseCacheAble { listeners.remove(SamplingListener.class, listener); } - private Optional<Zone> tryFindZone(FishingOperation operation) { + public List<CacheExtractedKey> getSamplingNumbers(Map<String, Species> speciesById) { + List<CacheExtractedKey> result = cruiseCache.getSamplingNumbers(speciesById, sexQualitativeValues); + result.forEach(key -> { + Optional<CalcifiedPiecesSamplingDefinition> cpsDef = tryToFindCalcifiedPiecesSamplingDefinition(key.getSpecies(), key.getMaturity(), key.getLengthStep(), key.getSex()); + if (cpsDef.isPresent()) { + key.setMaxByLengthStep(cpsDef.get().getMaxByLenghtStep()); + } + }); + return result; + } + + public Optional<Zone> tryFindZone(FishingOperation operation) { Optional<Zone> result; if (operation.getSubStrata() != null) { result = tryFindZone(operation.getSubStrata()); @@ -619,24 +683,17 @@ public class CruiseSamplingCache implements CruiseCacheAble { return result; } - private void fireSamplingNeeded(SamplingEvent event) { - - SamplingListener[] samplingListeners = listeners.getListeners(SamplingListener.class); - if (samplingListeners.length > 0) { - - for (SamplingListener listener : samplingListeners) { - listener.samplingNeeded(event); - } - } + public boolean isSpeciesDefined(Species species) { + return cpsDefinitionsBySpecies.containsKey(species.getReferenceTaxonId()); } - private void fireSummaryUpdated(SamplingEvent event) { + private void fireSamplingNeeded(SamplingEvent event) { SamplingListener[] samplingListeners = listeners.getListeners(SamplingListener.class); if (samplingListeners.length > 0) { for (SamplingListener listener : samplingListeners) { - listener.summaryUpdated(event); + listener.samplingNeeded(event); } } } @@ -664,81 +721,65 @@ public class CruiseSamplingCache implements CruiseCacheAble { return maturity; } - public List<CacheExtractedKey> getSamplingNumbers(Map<String, Species> speciesById) { - List<CacheExtractedKey> result = totalCruiseCache.getSamplingNumbers(speciesById, sexQualitativeValues); - result.forEach(key -> { - Optional<CalcifiedPiecesSamplingDefinition> cpsDef = tryToFindCalcifiedPiecesSamplingDefinition(key.getSpecies(), key.getMaturity(), key.getLengthStep(), key.getSex()); - if (cpsDef.isPresent()) { - key.setMaxByLengthStep(cpsDef.get().getMaxByLenghtStep()); + private Boolean getMaturity(IndividualObservationBatch individualObservationBatch, CaracteristicQualitativeValue qualitativeValue) { + Boolean maturity = null; + Caracteristic maturityCaracteristic = maturityCaracteristicBySpecies.get(individualObservationBatch.getSpecies().getReferenceTaxonId()); + // if a maturity caracteristic is defined in the protocol for this species + if (maturityCaracteristic != null) { + // it the maturity is set + if (qualitativeValue != null) { + maturity = matureStatesByMaturityCracteristic.containsEntry(maturityCaracteristic.getId(), qualitativeValue.getId()); } - }); - return result; - } - - private void addIndividualObservation(CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition, - int fishingOperationId, - Zone zone, - Species species, - CaracteristicQualitativeValue gender, - Boolean maturity, - int lengthStep) { - - if (!calcifiedPiecesSamplingDefinition.isSex()) { - gender = null; } + return maturity; + } - String samplingKey = CruiseSamplingInternalCache.createSamplingKey(species, gender, maturity, lengthStep); - - if (isLoading()) { + private String createCruiseSamplingKey(Species species, + CaracteristicQualitativeValue gender, + Boolean maturity, + int lengthStep) { + return CruiseSamplingInternalCache.createSamplingKey(species, gender, maturity, lengthStep); + } - int totalValue = totalCruiseCache.incrementObservationNb(samplingKey); + private String createZoneSamplingKey(String cruiseSamplingKey, Zone zone) { + return CruiseSamplingInternalCache.addPrefixKey(zone.getId(), cruiseSamplingKey); + } - int zoneValue = 0; - if (zone != null) { - String zoneKey = CruiseSamplingInternalCache.addPrefixKey(zone.getId(), samplingKey); - zoneValue = zoneCache.incrementObservationNb(zoneKey); - } - String operationKey = CruiseSamplingInternalCache.addPrefixKey(fishingOperationId, samplingKey); + private String createFishingOperationSamplingKey(String cruiseSamplingKey, int fishingOperationId) { + return CruiseSamplingInternalCache.addPrefixKey(fishingOperationId, cruiseSamplingKey); + } - int operationValue = operationCache.incrementObservationNb(operationKey); + private void addIndividualObservation(IndividualObservationSamplingContext individualObservationSamplingContext) { - if (log.isInfoEnabled()) { - log.info("add individual observation " + samplingKey + " ⇒ op " + operationValue + " / zone " + zoneValue + " / cruise " + totalValue); - } + Objects.requireNonNull(individualObservationSamplingContext); - } else { + String cruiseSamplingKey = individualObservationSamplingContext.getCruiseSamplingKey(); + CruiseSamplingInternalCache.SamplingData cruiseSamplingData = cruiseCache.addOneIndividualObservation(cruiseSamplingKey); - int totalValue = totalCruiseCache.incrementObservationNb(samplingKey); - int totalSamplingNb = totalCruiseCache.getSamplingNb(samplingKey); + String zoneSamplingKey = individualObservationSamplingContext.getZoneSamplingKey(); + CruiseSamplingInternalCache.SamplingData zoneSamplingData = zoneCache.addOneIndividualObservation(zoneSamplingKey); - int zoneValue = 0; - int zoneSamplingNb = 0; - if (zone != null) { - String zoneKey = CruiseSamplingInternalCache.addPrefixKey(zone.getId(), samplingKey); - zoneValue = zoneCache.incrementObservationNb(zoneKey); - zoneSamplingNb = zoneCache.getSamplingNb(zoneKey); - } - String operationKey = CruiseSamplingInternalCache.addPrefixKey(fishingOperationId, samplingKey); + String fishingOperationSamplingKey = individualObservationSamplingContext.getFishingOperationSamplingKey(); + CruiseSamplingInternalCache.SamplingData fishingOperationSamplingData = fishingOperationCache.addOneIndividualObservation(fishingOperationSamplingKey); - int operationValue = operationCache.incrementObservationNb(operationKey); - int operationSamplingNb = operationCache.getSamplingNb(operationKey); + if (log.isInfoEnabled()) { + log.info("add individual observation " + cruiseSamplingKey + " => op " + fishingOperationSamplingData.getSamplingCount() + " / zone " + zoneSamplingData.getSamplingCount() + " / cruise " + cruiseSamplingData.getSamplingCount()); + } - if (log.isInfoEnabled()) { - log.info("add individual observation " + samplingKey + " ⇒ op " + operationValue + " / zone " + zoneValue + " / cruise " + totalValue); - } + if (!isLoading()) { - SamplingEvent event = new SamplingEvent(this, lengthStep, gender, maturity, calcifiedPiecesSamplingDefinition, zone, totalSamplingNb, zoneSamplingNb, operationSamplingNb); + int samplingInterval = individualObservationSamplingContext.getCalcifiedPiecesSamplingDefinition().getSamplingInterval(); + int cruiseIndividualObservationCount = cruiseSamplingData.getIndividualObservationCount(); + if (cruiseIndividualObservationCount == 1 || samplingInterval == 1 || cruiseIndividualObservationCount % samplingInterval == 1) { - int samplingInterval = calcifiedPiecesSamplingDefinition.getSamplingInterval(); - if (totalValue == 1 || samplingInterval == 1 || totalValue % samplingInterval == 1) { + IndividualObservationSamplingStatus status = new IndividualObservationSamplingStatus(individualObservationSamplingContext, cruiseSamplingData, zoneSamplingData, fishingOperationSamplingData); + SamplingEvent event = new SamplingEvent(this, status); if (log.isInfoEnabled()) { log.info("-> needs sampling"); } fireSamplingNeeded(event); } - fireSummaryUpdated(event); - } } @@ -746,140 +787,86 @@ public class CruiseSamplingCache implements CruiseCacheAble { /** * Suppression d'un échantillon du cache. * - * @param calcifiedPiecesSamplingDefinition la définition de l'alrithme à utiliser - * @param fishingOperationId l'identifiant de l'opération de pêche concernée - * @param zone la zone (facultative) de l'opération de pêche concernée - * @param species l'espèces concernée - * @param gender le sexe de l'échantillon (peut-être null) - * @param maturity la maturité de l'échantillon (peut-être null) - * @param lengthStep la classe de taille de l'échantillon (en mm) + * @param individualObservationSamplingContext le contexte de l'observation individuelle */ - private void removeIndividualObservation(CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition, - int fishingOperationId, - Zone zone, - Species species, - CaracteristicQualitativeValue gender, - Boolean maturity, - int lengthStep) { - - Objects.requireNonNull(calcifiedPiecesSamplingDefinition); - Objects.requireNonNull(fishingOperationId); - Objects.requireNonNull(species); + private void removeIndividualObservation(IndividualObservationSamplingContext individualObservationSamplingContext) { - if (!calcifiedPiecesSamplingDefinition.isSex()) { - gender = null; - } + Objects.requireNonNull(individualObservationSamplingContext); - String samplingKey = CruiseSamplingInternalCache.createSamplingKey(species, gender, maturity, lengthStep); + String cruiseSamplingKey = individualObservationSamplingContext.getCruiseSamplingKey(); + CruiseSamplingInternalCache.SamplingData cruiseSamplingData = cruiseCache.removeOneIndividualObservation(cruiseSamplingKey); - int totalValue = totalCruiseCache.decrementObservationNb(samplingKey); - int zoneValue = 0; - if (zone != null) { - String zoneKey = CruiseSamplingInternalCache.addPrefixKey(zone.getId(), samplingKey); - zoneValue = zoneCache.decrementObservationNb(zoneKey); - } - String operationKey = CruiseSamplingInternalCache.addPrefixKey(fishingOperationId, samplingKey); + String zoneSamplingKey = individualObservationSamplingContext.getZoneSamplingKey(); + CruiseSamplingInternalCache.SamplingData zoneSamplingData = zoneCache.removeOneIndividualObservation(zoneSamplingKey); - int operationValue = operationCache.decrementObservationNb(operationKey); + String fishingOperationSamplingKey = individualObservationSamplingContext.getFishingOperationSamplingKey(); + CruiseSamplingInternalCache.SamplingData fishingOperationSamplingData = fishingOperationCache.removeOneIndividualObservation(fishingOperationSamplingKey); if (log.isInfoEnabled()) { - log.info("remove individual observation " + samplingKey + " ⇒ op " + operationValue + " / zone " + zoneValue + " / cruise " + totalValue); + log.info("remove individual observation " + cruiseSamplingKey + " => op " + fishingOperationSamplingData.getSamplingCount() + " / zone " + zoneSamplingData.getSamplingCount() + " / cruise " + cruiseSamplingData.getSamplingCount()); } } - /** - * Ajout d'un prélèvement dans le cache. - * - * @param fishingOperationId l'identifiant de l'opération de pêche concernée - * @param zone la zone (facultative) de l'opération de pêche concernée - * @param species l'espèces concernée - * @param gender le sexe de l'échantillon (peut-être null) - * @param maturity la maturité de l'échantillon (peut-être null) - * @param lengthStep la classe de taille de l'échantillon (en mm) - */ - private void addSampling(CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition, - int fishingOperationId, - Zone zone, - Species species, - CaracteristicQualitativeValue gender, - Boolean maturity, - int lengthStep) { - - Objects.requireNonNull(calcifiedPiecesSamplingDefinition); - Objects.requireNonNull(fishingOperationId); - Objects.requireNonNull(species); + private void addSampling(IndividualObservationSamplingContext individualObservationSamplingContext) { - if (!calcifiedPiecesSamplingDefinition.isSex()) { - gender = null; - } - String samplingKey = CruiseSamplingInternalCache.createSamplingKey(species, gender, maturity, lengthStep); + Objects.requireNonNull(individualObservationSamplingContext); - int totalSamplingNb = totalCruiseCache.incrementSamplingNb(samplingKey); + String cruiseSamplingKey = individualObservationSamplingContext.getCruiseSamplingKey(); + CruiseSamplingInternalCache.SamplingData cruiseSamplingData = cruiseCache.addOneSampling(cruiseSamplingKey); - int zoneSamplingNb = 0; - if (zone != null) { - String zoneKey = CruiseSamplingInternalCache.addPrefixKey(zone.getId(), samplingKey); - zoneSamplingNb = zoneCache.incrementSamplingNb(zoneKey); - } - String operationKey = CruiseSamplingInternalCache.addPrefixKey(fishingOperationId, samplingKey); + String zoneSamplingKey = individualObservationSamplingContext.getZoneSamplingKey(); + CruiseSamplingInternalCache.SamplingData zoneSamplingData = zoneCache.addOneSampling(zoneSamplingKey); - int operationSamplingNb = operationCache.incrementSamplingNb(operationKey); + String fishingOperationSamplingKey = individualObservationSamplingContext.getFishingOperationSamplingKey(); + CruiseSamplingInternalCache.SamplingData fishingOperationSamplingData = fishingOperationCache.addOneSampling(fishingOperationSamplingKey); if (log.isInfoEnabled()) { - log.info("add Sampling " + samplingKey + " => op " + operationSamplingNb + " / zone " + zoneSamplingNb + " / cruise " + totalSamplingNb); + log.info("add Sampling " + cruiseSamplingKey + " => op " + fishingOperationSamplingData.getSamplingCount() + " / zone " + zoneSamplingData.getSamplingCount() + " / cruise " + cruiseSamplingData.getSamplingCount()); } - SamplingEvent event = new SamplingEvent(this, lengthStep, gender, maturity, calcifiedPiecesSamplingDefinition, zone, totalSamplingNb, zoneSamplingNb, operationSamplingNb); - fireSummaryUpdated(event); - } - /** - * Suppression d'un prélèvement dans le cache. - * - * @param fishingOperationId l'identifiant de l'opération de pêche concernée - * @param zone la zone (facultative) de l'opération de pêche concernée - * @param species l'espèces concernée - * @param gender le sexe de l'échantillon (peut-être null) - * @param maturity la maturité de l'échantillon (peut-être null) - * @param lengthStep la classe de taille de l'échantillon (en mm) - */ - private void removeSampling(CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition, - int fishingOperationId, - Zone zone, - Species species, - CaracteristicQualitativeValue gender, - Boolean maturity, - int lengthStep) { - - Objects.requireNonNull(calcifiedPiecesSamplingDefinition); - Objects.requireNonNull(fishingOperationId); - Objects.requireNonNull(species); + private void removeSampling(IndividualObservationSamplingContext individualObservationSamplingContext) { - if (!calcifiedPiecesSamplingDefinition.isSex()) { - gender = null; - } + Objects.requireNonNull(individualObservationSamplingContext); - String samplingKey = CruiseSamplingInternalCache.createSamplingKey(species, gender, maturity, lengthStep); + String cruiseSamplingKey = individualObservationSamplingContext.getCruiseSamplingKey(); + CruiseSamplingInternalCache.SamplingData cruiseSamplingData = cruiseCache.removeOneSampling(cruiseSamplingKey); - int totalSamplingNb = totalCruiseCache.decrementSamplingNb(samplingKey); + String zoneSamplingKey = individualObservationSamplingContext.getZoneSamplingKey(); + CruiseSamplingInternalCache.SamplingData zoneSamplingData = zoneCache.removeOneSampling(zoneSamplingKey); - int zoneSamplingNb = 0; - if (zone != null) { - String zoneKey = CruiseSamplingInternalCache.addPrefixKey(zone.getId(), samplingKey); - zoneSamplingNb = zoneCache.decrementSamplingNb(zoneKey); - } - String operationKey = CruiseSamplingInternalCache.addPrefixKey(fishingOperationId, samplingKey); - - int operationSamplingNb = operationCache.decrementSamplingNb(operationKey); + String fishingOperationSamplingKey = individualObservationSamplingContext.getFishingOperationSamplingKey(); + CruiseSamplingInternalCache.SamplingData fishingOperationSamplingData = fishingOperationCache.removeOneSampling(fishingOperationSamplingKey); if (log.isInfoEnabled()) { - log.info("remove Sampling " + samplingKey + " => op " + operationSamplingNb + " / zone " + zoneSamplingNb + " / cruise " + totalSamplingNb); + log.info("remove Sampling " + cruiseSamplingKey + " => op " + fishingOperationSamplingData.getSamplingCount() + " / zone " + zoneSamplingData.getSamplingCount() + " / cruise " + cruiseSamplingData.getSamplingCount()); } - SamplingEvent event = new SamplingEvent(this, lengthStep, gender, maturity, calcifiedPiecesSamplingDefinition, zone, totalSamplingNb, zoneSamplingNb, operationSamplingNb); - fireSummaryUpdated(event); + } + + private IndividualObservationSamplingContext createContext(int fishingOperationId, + Species species, + Zone zone, + CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition, + Integer lengthStep, + Boolean maturity, + CaracteristicQualitativeValue gender) { + + String cruiseSamplingKey = createCruiseSamplingKey(species, gender, maturity, lengthStep); + String zoneSamplingKey = createZoneSamplingKey(cruiseSamplingKey, zone); + String fishingOperationSamplingKey = createFishingOperationSamplingKey(cruiseSamplingKey, fishingOperationId); + + return new IndividualObservationSamplingContext(species, + lengthStep, + maturity, + gender, + calcifiedPiecesSamplingDefinition, + zone, + cruiseSamplingKey, + zoneSamplingKey, + fishingOperationSamplingKey); } @@ -972,5 +959,4 @@ public class CruiseSamplingCache implements CruiseCacheAble { return Optional.ofNullable(result); } - } diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseSamplingInternalCache.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseSamplingInternalCache.java index 371d836..9b896d4 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseSamplingInternalCache.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/CruiseSamplingInternalCache.java @@ -70,77 +70,14 @@ class CruiseSamplingInternalCache implements Closeable { private final Map<String, SamplingData> data = new TreeMap<>(); - public int incrementObservationNb(String samplingKey) { + public SamplingData getSamplingData(String samplingKey) { Objects.requireNonNull(samplingKey); - SamplingData value = data.computeIfAbsent(samplingKey, s -> new SamplingData()); - int obsNb = value.incrementObservationNb(); - if (log.isDebugEnabled()) { - log.debug(samplingKey + " → " + obsNb); - } - return obsNb; - } - - public int decrementObservationNb(String samplingKey) { - Objects.requireNonNull(samplingKey); - SamplingData value = data.get(samplingKey); - int obsNb = value.decrementObservationNb(); - if (log.isDebugEnabled()) { - log.debug(samplingKey + " → " + obsNb); - } - return obsNb; - } - - public Integer decrementObservationNbIfExist(String samplingKey) { - Objects.requireNonNull(samplingKey); - Integer result = null; - SamplingData value = data.get(samplingKey); - if (value != null) { - result = value.decrementObservationNb(); - if (log.isDebugEnabled()) { - log.debug(samplingKey + " → " + value); - } - } - return result; - } - - public int getObservationNb(String samplingKey) { - Objects.requireNonNull(samplingKey); - SamplingData value = data.get(samplingKey); - int observationNb = value.getObservationNb(); - if (log.isDebugEnabled()) { - log.debug(samplingKey + " → " + observationNb); - } - return observationNb; + return data.get(samplingKey); } - public int incrementSamplingNb(String samplingKey) { + public SamplingData getOrCreateSamplingData(String samplingKey) { Objects.requireNonNull(samplingKey); - SamplingData value = data.computeIfAbsent(samplingKey, s -> new SamplingData()); - int samplingNb = value.incrementSamplingNb(); - if (log.isDebugEnabled()) { - log.debug(samplingKey + " → " + samplingNb); - } - return samplingNb; - } - - public int decrementSamplingNb(String samplingKey) { - Objects.requireNonNull(samplingKey); - SamplingData value = data.get(samplingKey); - int samplingNb = value.decrementSamplingNb(); - if (log.isDebugEnabled()) { - log.debug(samplingKey + " → " + samplingNb); - } - return samplingNb; - } - - public int getSamplingNb(String samplingKey) { - Objects.requireNonNull(samplingKey); - SamplingData value = data.get(samplingKey); - int samplingNb = value.getSamplingNb(); - if (log.isDebugEnabled()) { - log.debug(samplingKey + " → " + samplingNb); - } - return samplingNb; + return data.computeIfAbsent(samplingKey, s -> new SamplingData()); } @Override @@ -229,7 +166,7 @@ class CruiseSamplingInternalCache implements Closeable { key.setLengthStep(lengthStep); } - key.setSamplingNb(samplingData.getSamplingNb()); + key.setSamplingNb(samplingData.getSamplingCount()); result.add(key); } @@ -240,54 +177,68 @@ class CruiseSamplingInternalCache implements Closeable { } - private class SamplingData { + public SamplingData addOneIndividualObservation(String key) { + SamplingData samplingData = getOrCreateSamplingData(key); + samplingData.individualObservationCount++; + return samplingData; + } - private int observationNb; - private int samplingNb; + public SamplingData removeOneIndividualObservation(String key) { + SamplingData samplingData = getSamplingData(key); - public int incrementObservationNb() { - observationNb++; - return getObservationNb(); - } + Objects.requireNonNull(samplingData, "[" + key + "] You cannot decrement a individual observation if the sampling data does not exist"); + Preconditions.checkState(samplingData.withIndividualObservation(), "[" + key + "] You cannot decrement the observation count if there is no observation"); + samplingData.individualObservationCount--; + return samplingData; + } - public int decrementObservationNb() { - Preconditions.checkState(withObservation(), "You cannot decrement the observation number if there is no observation"); - observationNb--; - return getObservationNb(); - } + public SamplingData addOneSampling(String key) { + //FIXME Normalement on ne doit pas créer ici car si on ajoute un prélèvement c'est qu'il y a déjà au préalable une observation + SamplingData samplingData = getOrCreateSamplingData(key); + samplingData.samplingCount++; + return samplingData; + } - public int getObservationNb() { - return observationNb; - } + public SamplingData removeOneSampling(String key) { + SamplingData samplingData = getSamplingData(key); + Objects.requireNonNull(samplingData, "[" + key + "] You cannot decrement a sampling count if the sampling data does not exist"); + Preconditions.checkState(samplingData.withSampling(), "[" + key + "] You cannot decrement a sampling count if there is no sampling"); + samplingData.samplingCount--; + return samplingData; + } - public int incrementSamplingNb() { - samplingNb++; - return getSamplingNb(); - } + class SamplingData { + + /** + * Nombre d'observations individuelles. + */ + private int individualObservationCount; + /** + * Nombre de prélèvements. + */ + private int samplingCount; - public int decrementSamplingNb() { - Preconditions.checkState(withSampling(), "You cannot decrement a sampling number if there is no sampling"); - samplingNb--; - return getSamplingNb(); + public int getIndividualObservationCount() { + return individualObservationCount; } public boolean withSampling() { - return samplingNb > 0; + return samplingCount > 0; } - public boolean withObservation() { - return observationNb > 0; + public boolean withIndividualObservation() { + return individualObservationCount > 0; } - public int getSamplingNb() { - return samplingNb; + public int getSamplingCount() { + return samplingCount; } @Override public String toString() { return MoreObjects.toStringHelper(SamplingData.class) - .add("observationNb", observationNb) - .add("samplingNb", samplingNb) + .add("individualObservationCount", individualObservationCount) + .add("samplingCount", samplingCount) .toString(); } } diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingContext.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingContext.java new file mode 100644 index 0000000..2ec4318 --- /dev/null +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingContext.java @@ -0,0 +1,148 @@ +package fr.ifremer.tutti.service.sampling; + +import fr.ifremer.tutti.persistence.entities.protocol.CalcifiedPiecesSamplingDefinition; +import fr.ifremer.tutti.persistence.entities.protocol.Zone; +import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; +import fr.ifremer.tutti.persistence.entities.referential.Species; + +import java.util.Objects; + +/** + * Définit le context d'une observation individuelles ou d'un prélèvement, i.e toutes les caractéristiques qui + * permettent de retrouver cette observation individuelle au niveau de l'algorithme de prélèvement. + * + * L'utilisation de cet objet sous-entend que l'observation individuelle liée rentre bien dans l'algorithme. + * + * Created on 18/04/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class IndividualObservationSamplingContext { + + /** + * L'espèce de l'observation individuelle. + */ + private final Species species; + + /** + * La classe de taille de l'observation individuelle. + */ + private final Integer lengthStep; + + /** + * Le statut de maturité. + */ + private final Boolean maturity; + + /** + * Le sexe observé. + */ + private final CaracteristicQualitativeValue gender; + + /** + * La définition de l'algorithme de prélèvement de picèes calcifiées utilisée pour cette observation. + */ + private final CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition; + + /** + * La zone où est effectuée l'observation individuelle. + */ + private final Zone zone; + + /** + * La clef pour accéder au cache des compteurs (de niveau Campagne). + */ + private final String cruiseSamplingKey; + + /** + * La clef pour accéder au cache des compteurs (de niveau Zone). + */ + private final String zoneSamplingKey; + + /** + * La clef pour accéder au cache des compteurs (de niveau Opération de pêche). + */ + private final String fishingOperationSamplingKey; + + public IndividualObservationSamplingContext(Species species, + Integer lengthStep, + Boolean maturity, + CaracteristicQualitativeValue gender, + CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition, + Zone zone, + String cruiseSamplingKey, + String zoneSamplingKey, + String fishingOperationSamplingKey) { + Objects.requireNonNull(species); + Objects.requireNonNull(calcifiedPiecesSamplingDefinition); + Objects.requireNonNull(zone); + Objects.requireNonNull(cruiseSamplingKey); + Objects.requireNonNull(zoneSamplingKey); + Objects.requireNonNull(fishingOperationSamplingKey); + this.species = species; + this.lengthStep = lengthStep; + this.maturity = maturity; + this.gender = gender; + this.calcifiedPiecesSamplingDefinition = calcifiedPiecesSamplingDefinition; + this.zone = zone; + this.cruiseSamplingKey = cruiseSamplingKey; + this.zoneSamplingKey = zoneSamplingKey; + this.fishingOperationSamplingKey = fishingOperationSamplingKey; + } + + public Species getSpecies() { + return species; + } + + public Integer getLengthStep() { + return lengthStep; + } + + public Boolean getMaturity() { + return maturity; + } + + public CaracteristicQualitativeValue getGender() { + return gender; + } + + public CalcifiedPiecesSamplingDefinition getCalcifiedPiecesSamplingDefinition() { + return calcifiedPiecesSamplingDefinition; + } + + public Zone getZone() { + return zone; + } + + public int getTotalSamplingRequiredInCruise() { + return calcifiedPiecesSamplingDefinition.getMaxByLenghtStep(); + } + + public int getTotalSamplingRequiredInFishingOperation() { + return calcifiedPiecesSamplingDefinition.getOperationLimitation(); + } + + public int getTotalSamplingRequiredInZone() { + return calcifiedPiecesSamplingDefinition.getZoneLimitation(); + } + + public String getCruiseSamplingKey() { + return cruiseSamplingKey; + } + + public String getZoneSamplingKey() { + return zoneSamplingKey; + } + + public String getFishingOperationSamplingKey() { + return fishingOperationSamplingKey; + } + + public boolean withGender() { + return gender!=null; + } + + public boolean withMaturity() { + return maturity!=null; + } +} diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingStatus.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingStatus.java new file mode 100644 index 0000000..92184c6 --- /dev/null +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingStatus.java @@ -0,0 +1,126 @@ +package fr.ifremer.tutti.service.sampling; + +import fr.ifremer.tutti.persistence.entities.protocol.CalcifiedPiecesSamplingDefinition; + +import java.util.Objects; + +/** + * Définit l'état en terme de prélèvement (de pièces calcifiées) d'une observation individuelle. + * + * L'utilisation de cet objet sous-entend que l'observation individuelle liée rentre bien dans l'algorithme. + * + * Created on 18/04/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class IndividualObservationSamplingStatus { + + /** + * Le context d'une observation individuelle (i.e ses caractéristiques). + */ + private final IndividualObservationSamplingContext individualObservationSamplingContext; + + /** + * Le nombre d'observations individuelles similaires effectués sur la campagne. + */ + private final int individualObservationCountInCruise; + + /** + * Le nombre de prélèvements similaires effectués sur la campagne. + */ + private final int samplingCountInCruise; + + /** + * Le nombre d'observations individuelles similaires effectués sur l'opération de pêche. + */ + private final int individualObservationCountInFishingOperation; + + /** + * Le nombre de prélèvements similaires effectués sur l'opération de pêche. + */ + private final int samplingCountInFishingOperation; + + /** + * Le nombre d'observations individuelles similaires effectués sur la zone. + */ + private final int individualObservationCountInZone; + + /** + * Le nombre de prélèvements similaires effectués sur la zone. + */ + private final int samplingCountInZone; + + public IndividualObservationSamplingStatus(IndividualObservationSamplingContext individualObservationSamplingContext, + CruiseSamplingInternalCache.SamplingData cruiseSamplingData, + CruiseSamplingInternalCache.SamplingData zoneSamplingData, + CruiseSamplingInternalCache.SamplingData fishingOperationSamplingData) { + Objects.requireNonNull(individualObservationSamplingContext); + this.individualObservationSamplingContext = individualObservationSamplingContext; + this.samplingCountInCruise = cruiseSamplingData.getSamplingCount(); + this.individualObservationCountInCruise = cruiseSamplingData.getIndividualObservationCount(); + this.samplingCountInZone = zoneSamplingData.getSamplingCount(); + this.individualObservationCountInZone = zoneSamplingData.getIndividualObservationCount(); + this.samplingCountInFishingOperation = fishingOperationSamplingData.getSamplingCount(); + this.individualObservationCountInFishingOperation = fishingOperationSamplingData.getIndividualObservationCount(); + } + + public IndividualObservationSamplingContext getIndividualObservationSamplingContext() { + return individualObservationSamplingContext; + } + + public CalcifiedPiecesSamplingDefinition getCalcifiedPiecesSamplingDefinition() { + return individualObservationSamplingContext.getCalcifiedPiecesSamplingDefinition(); + } + + public int getSamplingCountInCruise() { + return samplingCountInCruise; + } + + public int getSamplingCountInFishingOperation() { + return samplingCountInFishingOperation; + } + + public int getSamplingCountInZone() { + return samplingCountInZone; + } + + public int getIndividualObservationCountInCruise() { + return individualObservationCountInCruise; + } + + public int getIndividualObservationCountInFishingOperation() { + return individualObservationCountInFishingOperation; + } + + public int getIndividualObservationCountInZone() { + return individualObservationCountInZone; + } + + public int getTotalSamplingRequiredInCruise() { + return getCalcifiedPiecesSamplingDefinition().getMaxByLenghtStep(); + } + + public int getTotalSamplingRequiredInFishingOperation() { + return getCalcifiedPiecesSamplingDefinition().getOperationLimitation(); + } + + public int getTotalSamplingRequiredInZone() { + return getCalcifiedPiecesSamplingDefinition().getZoneLimitation(); + } + + public boolean isTotalInCruiseAttained() { + return getTotalSamplingRequiredInCruise() > 0 && getSamplingCountInCruise() >= getTotalSamplingRequiredInCruise(); + } + + public boolean isTotalInFishingOperationAttained() { + return getTotalSamplingRequiredInFishingOperation() > 0 && getSamplingCountInFishingOperation() >= getTotalSamplingRequiredInFishingOperation(); + } + + public boolean isTotalInZoneAttained() { + return getTotalSamplingRequiredInZone() > 0 && getSamplingCountInZone() >= getTotalSamplingRequiredInZone(); + } + + public boolean isOneTotalCountIsAttained() { + return isTotalInCruiseAttained() || isTotalInZoneAttained() || isTotalInFishingOperationAttained(); + } +} diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingStatusExceptionSupport.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingStatusExceptionSupport.java new file mode 100644 index 0000000..7bfc5db --- /dev/null +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingStatusExceptionSupport.java @@ -0,0 +1,29 @@ +package fr.ifremer.tutti.service.sampling; + +import fr.ifremer.tutti.persistence.entities.data.FishingOperation; +import fr.ifremer.tutti.persistence.entities.data.IndividualObservationBatch; + +import java.util.Objects; + +/** + * Created on 18/04/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public abstract class IndividualObservationSamplingStatusExceptionSupport extends Exception { + + private final IndividualObservationBatch individualObservationBatch; + + public IndividualObservationSamplingStatusExceptionSupport(IndividualObservationBatch individualObservationBatch) { + Objects.requireNonNull(individualObservationBatch); + this.individualObservationBatch = individualObservationBatch; + } + + public IndividualObservationBatch getIndividualObservationBatch() { + return individualObservationBatch; + } + + public FishingOperation getFishingOperation() { + return individualObservationBatch.getFishingOperation(); + } +} diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingEvent.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingEvent.java index 79f204c..f06583c 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingEvent.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingEvent.java @@ -24,10 +24,6 @@ package fr.ifremer.tutti.service.sampling; * #L% */ -import fr.ifremer.tutti.persistence.entities.protocol.CalcifiedPiecesSamplingDefinition; -import fr.ifremer.tutti.persistence.entities.protocol.Zone; -import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; - import java.util.EventObject; /** @@ -36,65 +32,11 @@ import java.util.EventObject; */ public class SamplingEvent extends EventObject { - protected final int lengthStep; - - protected final CaracteristicQualitativeValue gender; - - protected final Boolean maturity; - - protected final CalcifiedPiecesSamplingDefinition cpsDef; - - protected final Zone zone; - - protected final int nbSamplingForCruise; - - protected final int nbSamplingForZone; + private final IndividualObservationSamplingStatus status; - protected final int nbSamplingForOperation; - - public SamplingEvent(CruiseSamplingCache source, int lengthStep, CaracteristicQualitativeValue gender, Boolean maturity, - CalcifiedPiecesSamplingDefinition cpsDef, Zone zone, int nbSamplingForCruise, int nbSamplingForZone, int nbSamplingForOperation) { + public SamplingEvent(CruiseSamplingCache source, IndividualObservationSamplingStatus status) { super(source); - this.lengthStep = lengthStep; - this.gender = gender; - this.maturity = maturity; - this.cpsDef = cpsDef; - this.zone = zone; - this.nbSamplingForCruise = nbSamplingForCruise; - this.nbSamplingForZone = nbSamplingForZone; - this.nbSamplingForOperation = nbSamplingForOperation; - } - - public int getLengthStep() { - return lengthStep; - } - - public CaracteristicQualitativeValue getGender() { - return gender; - } - - public Boolean getMaturity() { - return maturity; - } - - public CalcifiedPiecesSamplingDefinition getCpsDef() { - return cpsDef; - } - - public Zone getZone() { - return zone; - } - - public int getNbSamplingForCruise() { - return nbSamplingForCruise; - } - - public int getNbSamplingForZone() { - return nbSamplingForZone; - } - - public int getNbSamplingForOperation() { - return nbSamplingForOperation; + this.status = status; } @Override @@ -102,4 +44,8 @@ public class SamplingEvent extends EventObject { return (CruiseSamplingCache) super.getSource(); } + public IndividualObservationSamplingStatus getStatus() { + return status; + } + } diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingListener.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingListener.java index f120f10..8f14783 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingListener.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SamplingListener.java @@ -34,6 +34,5 @@ public interface SamplingListener extends EventListener { void samplingNeeded(SamplingEvent event); - void summaryUpdated(SamplingEvent event); } diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SizeNotDefinedOnIndividualObservationException.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SizeNotDefinedOnIndividualObservationException.java new file mode 100644 index 0000000..8a5ac44 --- /dev/null +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/SizeNotDefinedOnIndividualObservationException.java @@ -0,0 +1,17 @@ +package fr.ifremer.tutti.service.sampling; + +import fr.ifremer.tutti.persistence.entities.data.IndividualObservationBatch; + +/** + * Quand la taille n'est pas définie sur l'observation individuelle. + * + * Created on 18/04/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class SizeNotDefinedOnIndividualObservationException extends IndividualObservationSamplingStatusExceptionSupport { + + public SizeNotDefinedOnIndividualObservationException(IndividualObservationBatch individualObservationBatch) { + super(individualObservationBatch); + } +} diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/ZoneNotDefinedOnFishingOperationException.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/ZoneNotDefinedOnFishingOperationException.java new file mode 100644 index 0000000..8a0cdb1 --- /dev/null +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/ZoneNotDefinedOnFishingOperationException.java @@ -0,0 +1,17 @@ +package fr.ifremer.tutti.service.sampling; + +import fr.ifremer.tutti.persistence.entities.data.IndividualObservationBatch; + +/** + * Quand la zone n'est pas définie sur l'opération de pêche de l'observation individuelle. + * + * Created on 18/04/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class ZoneNotDefinedOnFishingOperationException extends IndividualObservationSamplingStatusExceptionSupport { + + public ZoneNotDefinedOnFishingOperationException(IndividualObservationBatch individualObservationBatch) { + super(individualObservationBatch); + } +} -- 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/revue_algorithme in repository tutti. See https://gitlab.nuiton.org/codelutin/tutti.git commit 2488271da21803a1723b47c1f907c7963cad1749 Author: Tony CHEMIT <chemit@codelutin.com> Date: Tue Apr 19 10:53:45 2016 +0200 Utilisation d'un nouvel handler pour gérer la zone de notification --- .../IndividualObservationBatchRowModel.java | 16 ++ .../IndividualObservationBatchTableHandler.java | 34 +-- ...dividualObservationNotificationZoneHandler.java | 260 +++++++++++++++++++++ .../frequency/IndividualObservationUICache.java | 195 +++++----------- .../species/frequency/SpeciesFrequencyUI.jcss | 4 - .../frequency/SpeciesFrequencyUIHandler.java | 7 +- .../resources/i18n/tutti-ui-swing_en_GB.properties | 1 + .../resources/i18n/tutti-ui-swing_fr_FR.properties | 3 +- 8 files changed, 354 insertions(+), 166 deletions(-) diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationBatchRowModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationBatchRowModel.java index 8244875..9895745 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationBatchRowModel.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationBatchRowModel.java @@ -34,6 +34,7 @@ import fr.ifremer.tutti.persistence.entities.data.SpeciesBatch; import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; import fr.ifremer.tutti.persistence.entities.referential.Species; +import fr.ifremer.tutti.service.sampling.IndividualObservationSamplingStatus; import fr.ifremer.tutti.service.sampling.SamplingCodePrefix; import fr.ifremer.tutti.type.WeightUnit; import fr.ifremer.tutti.ui.swing.util.AbstractTuttiBeanUIModel; @@ -95,6 +96,13 @@ public class IndividualObservationBatchRowModel extends AbstractTuttiBeanUIModel */ protected SamplingCodePrefix samplingCodePrefix; + /** + * Le statut venant du cache des observations individuelles. + * + * @since 4.5 + */ + protected IndividualObservationSamplingStatus individualObservationSamplingStatus; + protected static final Binder<IndividualObservationBatch, IndividualObservationBatchRowModel> fromBeanBinder = BinderFactory.newBinder(IndividualObservationBatch.class, IndividualObservationBatchRowModel.class); @@ -136,6 +144,14 @@ public class IndividualObservationBatchRowModel extends AbstractTuttiBeanUIModel firePropertyChange(PROPERTY_DEFAULT_CARACTERISTICS, oldValue, defaultCaracteristics); } + public IndividualObservationSamplingStatus getIndividualObservationSamplingStatus() { + return individualObservationSamplingStatus; + } + + public void setIndividualObservationSamplingStatus(IndividualObservationSamplingStatus individualObservationSamplingStatus) { + this.individualObservationSamplingStatus = individualObservationSamplingStatus; + } + //------------------------------------------------------------------------// //-- AbstractTuttiBeanUIModel --// //------------------------------------------------------------------------// diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationBatchTableHandler.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationBatchTableHandler.java index 3652e9b..cdd6e9d 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationBatchTableHandler.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationBatchTableHandler.java @@ -479,23 +479,23 @@ public class IndividualObservationBatchTableHandler implements Closeable { }); - individualObservationTable.getSelectionModel().addListSelectionListener(e -> { - - if (!model.isInRafaleRowCreation()) { - uiHandler.resetSamplingLabel(); - } - - IndividualObservationBatchRowModel selectedRow = null; - - if (!individualObservationTable.getSelectionModel().isSelectionEmpty()) { - if (individualObservationTable.getSelectedRowCount() == 1) { - selectedRow = individualObservationTableModel.getEntry(individualObservationTable.getSelectedRow()); - - } - } - - individualObservationUICache.updateSelectedRow(selectedRow); - }); +// individualObservationTable.getSelectionModel().addListSelectionListener(e -> { +// +// if (!model.isInRafaleRowCreation()) { +// uiHandler.resetSamplingLabel(); +// } +// +// IndividualObservationBatchRowModel selectedRow = null; +// +// if (!individualObservationTable.getSelectionModel().isSelectionEmpty()) { +// if (individualObservationTable.getSelectedRowCount() == 1) { +// selectedRow = individualObservationTableModel.getEntry(individualObservationTable.getSelectedRow()); +// +// } +// } +// +// individualObservationUICache.updateSelectedRow(selectedRow); +// }); model2.addPropertyChangeListener(IndividualObservationBatchUIModel.PROPERTY_ROWS, evt -> individualObservationTableModel.setRows((List<IndividualObservationBatchRowModel>) evt.getNewValue())); diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationNotificationZoneHandler.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationNotificationZoneHandler.java new file mode 100644 index 0000000..806258c --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationNotificationZoneHandler.java @@ -0,0 +1,260 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency; + +import fr.ifremer.tutti.persistence.entities.protocol.CalcifiedPiecesSamplingDefinition; +import fr.ifremer.tutti.persistence.entities.protocol.Zone; +import fr.ifremer.tutti.persistence.entities.referential.Species; +import fr.ifremer.tutti.service.DecoratorService; +import fr.ifremer.tutti.service.sampling.CalcifiedPiecesSamplingAlgorithmEntryNotFoundException; +import fr.ifremer.tutti.service.sampling.IndividualObservationSamplingContext; +import fr.ifremer.tutti.service.sampling.IndividualObservationSamplingStatus; +import fr.ifremer.tutti.service.sampling.SamplingListener; +import fr.ifremer.tutti.service.sampling.SizeNotDefinedOnIndividualObservationException; +import fr.ifremer.tutti.service.sampling.ZoneNotDefinedOnFishingOperationException; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.edit.SpeciesBatchRowModel; +import fr.ifremer.tutti.util.Numbers; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.decorator.Decorator; + +import javax.swing.JLabel; +import javax.swing.ListSelectionModel; +import javax.swing.event.ListSelectionListener; +import java.awt.Color; +import java.io.Closeable; + +import static org.nuiton.i18n.I18n.t; + +/** + * Pour gérer la zone de notification des observations individuelles. + * + * Created on 18/04/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class IndividualObservationNotificationZoneHandler implements Closeable { + + /** Logger. */ + private static final Log log = LogFactory.getLog(IndividualObservationNotificationZoneHandler.class); + + private final SpeciesFrequencyUI ui; + private final SpeciesFrequencyUIModel uiModel; + private final SpeciesFrequencyUIHandler uiHandler; + private final IndividualObservationUICache individualObservationUICache; + private final IndividualObservationBatchTableModel individualObservationTableModel; + private final JLabel samplingWarningLabel; + private final JLabel samplingSummaryLabel; + private final SamplingListener samplingListener; + private final ListSelectionListener listSelectionListener; + private final Decorator<Integer> infiniteDecorator; + private final Decorator<Species> speciesDecorator; + + public IndividualObservationNotificationZoneHandler(SpeciesFrequencyUI ui) { + this.ui = ui; + this.uiModel = ui.getModel(); + this.samplingWarningLabel = ui.getSamplingWarningLabel(); + this.samplingSummaryLabel = ui.getSamplingResumeLabel(); + this.individualObservationTableModel = (IndividualObservationBatchTableModel) ui.getObsTable().getModel(); + this.uiHandler = ui.getHandler(); + this.individualObservationUICache = uiHandler.getIndividualObservationUICache(); + this.infiniteDecorator = ui.getHandler().getDecorator(Integer.class, DecoratorService.NULL_INFINITE); + this.speciesDecorator = ui.getHandler().getDecorator(Species.class, DecoratorService.WITH_SURVEY_CODE); + // Ecoute sur le cache de données pour savoir quand il faut afficher les notifications de prélèvements + this.samplingListener = event -> { + + if (uiModel.isCanDisplayNotifications()) { + + whenSamplingNeeded(event.getStatus()); + + } + }; + + listSelectionListener = e -> { + + ListSelectionModel source = (ListSelectionModel) e.getSource(); + + if (e.getValueIsAdjusting()) { + return; + } + + if (source.isSelectionEmpty()) { + whenCanNotUseSampling("Aucune observation individuelle sélectionnée."); + return; + } + + if (getSelectedRowCount(source) > 1) { + whenCanNotUseSampling("Plusieurs observations individuelles sélectionnées."); + return; + } + + IndividualObservationBatchRowModel selectedRow = individualObservationTableModel.getEntry(source.getMinSelectionIndex()); + updateSelectedRow(selectedRow); + + }; + + } + + public void editBatch(SpeciesBatchRowModel speciesBatch) { + + if (log.isInfoEnabled()) { + log.info("Edit batch for " + speciesBatch); + } + + samplingWarningLabel.setText(""); + samplingSummaryLabel.setText(""); + + if (!uiHandler.getContext().isProtocolFilled()) { + + // pas de protocole + whenCanNotUseSampling("Pas de protocole défini."); + return; + } + + if (!uiHandler.getContext().getDataContext().getProtocol().isUseCalcifiedPieceSampling()) { + + // pas d'utilisation de l'algorithme de prélèvement des pièces calcifiées + whenCanNotUseSampling("L'utilisation de l'algorithme n'est pas activée dans le protocole."); + return; + } + + if (!individualObservationUICache.isFishingOperationWithZone()) { + + // pas de zone définie sur l'opération de pêche + whenCanNotUseSampling("Le trait n'est pas dans une zone."); + return; + } + + if (!individualObservationUICache.isSpeciesDefinedInCalcifiedPiecesSampling()) { + + // pas de définition d'algorithme sur cette espèce + whenCanNotUseSampling("L'espèce du lot n'est pas connue dans la définition de l'algorithme."); + return; + } + + individualObservationUICache.getCruiseSamplingCache().addSamplingListener(samplingListener); + + ui.getObsTable().getSelectionModel().addListSelectionListener(listSelectionListener); + + // on vide volontairement la sélection pour que la zone de notification soit bien mise à jour + whenCanNotUseSampling("Aucune observation individuelle sélectionnée."); + + + } + + @Override + public void close() { + + ui.getObsTable().getSelectionModel().removeListSelectionListener(listSelectionListener); + if (individualObservationUICache.useCruiseSamplingCache()) { + individualObservationUICache.getCruiseSamplingCache().removeSamplingListener(samplingListener); + } + + } + + public void updateSelectedRow(IndividualObservationBatchRowModel selectedRow) { + + try { + + IndividualObservationSamplingStatus status = individualObservationUICache.getIndividualObservationStatus(selectedRow); + selectedRow.setIndividualObservationSamplingStatus(status); + whenUpdateSummary(status); + + } catch (CalcifiedPiecesSamplingAlgorithmEntryNotFoundException e) { + whenCanNotUseSampling("Pas de correspondance sur l'observation individuelle sélectionnée dans le protocole."); + } catch (SizeNotDefinedOnIndividualObservationException e) { + whenCanNotUseSampling("La taille n'est pas définie sur l'observation individuelle sélectionnée."); + } catch (ZoneNotDefinedOnFishingOperationException e) { + whenCanNotUseSampling("Le trait n'est pas dans une zone."); + } + + } + + private void whenCanNotUseSampling(String message) { + samplingWarningLabel.setText("< L'algorithme de prélèvements des pièces calcifiées n'est pas utilisé >"); + samplingWarningLabel.setForeground(null); + samplingWarningLabel.setBackground(Color.LIGHT_GRAY); + samplingSummaryLabel.setText(message); + } + + private void whenSamplingNeeded(IndividualObservationSamplingStatus status) { + + if (log.isInfoEnabled()) { + log.info("samplingNeeded for " + status); + } + + samplingWarningLabel.setText(t("tutti.editSpeciesFrequencies.samplingNeeded.warning")); + samplingWarningLabel.setForeground(uiHandler.getConfig().getColorHighlightInfoForeground()); + samplingWarningLabel.setBackground(uiHandler.getConfig().getColorHighlightInfoBackground()); + displaySummary(status); + + } + + private void whenUpdateSummary(IndividualObservationSamplingStatus status) { + if (status.isOneTotalCountIsAttained()) { + samplingWarningLabel.setText(t("tutti.editSpeciesFrequencies.samplingTotalCountAttained.warning")); + samplingWarningLabel.setForeground(null); + samplingWarningLabel.setBackground(Color.LIGHT_GRAY); + } else { + samplingWarningLabel.setText(null); + } + displaySummary(status); + } + + private void displaySummary(IndividualObservationSamplingStatus event) { + + IndividualObservationSamplingContext individualObservationSamplingContext = event.getIndividualObservationSamplingContext(); + + CalcifiedPiecesSamplingDefinition calcifiedPiecesSamplingDefinition = event.getCalcifiedPiecesSamplingDefinition(); + + int nbForOperation = event.getSamplingCountInFishingOperation(); + int nbForZone = event.getSamplingCountInZone(); + int nbForCruise = event.getSamplingCountInCruise(); + + String nbForOperationLabel = getLabelForSamplingNumber(nbForOperation, calcifiedPiecesSamplingDefinition.getOperationLimitation()); + String nbForZoneLabel = getLabelForSamplingNumber(nbForZone, calcifiedPiecesSamplingDefinition.getZoneLimitation()); + String nbForCruiseLabel = getLabelForSamplingNumber(nbForCruise, calcifiedPiecesSamplingDefinition.getMaxByLenghtStep()); + + String key = speciesDecorator.toString(individualObservationSamplingContext.getSpecies()) + + " " + Numbers.convertFromMm(individualObservationSamplingContext.getLengthStep(), uiModel.getLengthStepCaracteristicUnit()) + + " " + uiModel.getLengthStepCaracteristicUnit(); + if (individualObservationSamplingContext.withGender()) { + key += " " + individualObservationSamplingContext.getGender().getDescription(); + } + if (individualObservationSamplingContext.withMaturity()) { + if (individualObservationSamplingContext.getMaturity()) { + key += " " + t("tutti.editSpeciesFrequencies.samplingNeeded.mature"); + } else { + key += " " + t("tutti.editSpeciesFrequencies.samplingNeeded.immature"); + } + } + + Decorator<Zone> zoneDecorator = ui.getHandler().getDecorator(Zone.class, null); + String zone = zoneDecorator.toString(individualObservationSamplingContext.getZone()); + String summary = t("tutti.editSpeciesFrequencies.samplingNeeded.summary", key, nbForOperationLabel, zone, nbForZoneLabel, nbForCruiseLabel); + + samplingSummaryLabel.setText(summary); + } + + /** + * Returns the number of selected rows. + * + * @return the number of selected rows, 0 if no rows are selected + */ + private int getSelectedRowCount(ListSelectionModel selectionModel) { + int iMin = selectionModel.getMinSelectionIndex(); + int iMax = selectionModel.getMaxSelectionIndex(); + int count = 0; + + for (int i = iMin; i <= iMax; i++) { + if (selectionModel.isSelectedIndex(i)) { + count++; + } + } + return count; + } + + + private String getLabelForSamplingNumber(int value, Integer max) { + + return "<strong>" + infiniteDecorator.toString(value) + "</strong> (" + infiniteDecorator.toString(max) + ")"; + } +} 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 ebe8de6..926a62c 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 @@ -25,33 +25,30 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency; */ import fr.ifremer.tutti.persistence.entities.data.FishingOperation; -import fr.ifremer.tutti.persistence.entities.protocol.CalcifiedPiecesSamplingDefinition; import fr.ifremer.tutti.persistence.entities.protocol.Zone; import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; import fr.ifremer.tutti.persistence.entities.referential.Species; -import fr.ifremer.tutti.service.DecoratorService; import fr.ifremer.tutti.service.cruise.CruiseCache; +import fr.ifremer.tutti.service.sampling.CalcifiedPiecesSamplingAlgorithmEntryNotFoundException; import fr.ifremer.tutti.service.sampling.CruiseSamplingCache; +import fr.ifremer.tutti.service.sampling.IndividualObservationSamplingStatus; import fr.ifremer.tutti.service.sampling.SamplingCodeCache; 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.service.sampling.SizeNotDefinedOnIndividualObservationException; +import fr.ifremer.tutti.service.sampling.ZoneNotDefinedOnFishingOperationException; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.edit.SpeciesBatchRowModel; -import fr.ifremer.tutti.util.Numbers; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -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; - /** * Cache des observations individuelles. * @@ -66,27 +63,26 @@ public class IndividualObservationUICache implements Closeable { /** Logger. */ private static final Log log = LogFactory.getLog(IndividualObservationUICache.class); - private final SamplingListener samplingListener; - private final CruiseCache cruiseCache; + private final CruiseSamplingCache cruiseSamplingCache; private final SamplingCodeCache samplingCodeCache; + + private final boolean useCruiseSamplingCache; + private boolean speciesDefinedInCalcifiedPiecesSampling; + private final SpeciesFrequencyUIModel uiModel; private final IndividualObservationBatchUIModel individualObservationModel; - private final boolean withSamplingCache; - private final CruiseSamplingCache cruiseSamplingCache; - private SpeciesBatchRowModel speciesEditRow; private FishingOperation fishingOperation; + private Zone fishingOperationZone; + private SpeciesBatchRowModel speciesEditRow; private Species species; - 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. * @@ -99,8 +95,7 @@ public class IndividualObservationUICache implements Closeable { private boolean on; public IndividualObservationUICache(CruiseCache cruiseCache, SpeciesFrequencyUIModel uiModel) { - this.cruiseCache = cruiseCache; - this.withSamplingCache = cruiseCache.useSamplingCache(); + this.useCruiseSamplingCache = cruiseCache.useSamplingCache(); this.cruiseSamplingCache = cruiseCache.getSamplingCruiseCache().orElse(null); this.samplingCodeCache = cruiseCache.getSamplingCodeCache(); this.uiModel = uiModel; @@ -135,45 +130,10 @@ public class IndividualObservationUICache implements Closeable { } }); - // Ecoute sur le cache de données pour savoir quand il faut afficher les notifications de prélèvements - this.samplingListener = new SamplingListener() { - - @Override - public void samplingNeeded(SamplingEvent event) { - - if (uiModel.isCanDisplayNotifications()) { - CalcifiedPiecesSamplingDefinition cpsDef = event.getCpsDef(); - if (log.isInfoEnabled()) { - log.info("samplingNeeded for " + cpsDef); - } - - int nbForOperation = event.getNbSamplingForOperation(); - int nbForZone = event.getNbSamplingForZone(); - int nbForCruise = event.getNbSamplingForCruise(); - - if (log.isInfoEnabled()) { - - Integer operationLimitation = cpsDef.getOperationLimitation(); - Integer zoneLimitation = cpsDef.getZoneLimitation(); - Integer maxByLenghtStep = cpsDef.getMaxByLenghtStep(); - - log.info(String.format("nbForOperation: %d/%s - nbForZone: %d/%s - nbForCruise: %d/%s", - nbForOperation, operationLimitation == null ? "∞" : operationLimitation, - nbForZone, zoneLimitation == null ? "∞" : zoneLimitation, - nbForCruise, maxByLenghtStep == null ? "∞" : maxByLenghtStep)); - } - - ui.getSamplingWarningLabel().setVisible(true); - } - } - - @Override - public void summaryUpdated(SamplingEvent event) { - displaySummary(event); - } - - }; + } + public boolean useCruiseSamplingCache() { + return useCruiseSamplingCache; } public void init(SpeciesFrequencyUI ui, SpeciesBatchRowModel speciesEditRow, FishingOperation fishingOperation, List<IndividualObservationBatchRowModel> individualObservationRows) { @@ -183,12 +143,19 @@ public class IndividualObservationUICache implements Closeable { Objects.requireNonNull(speciesEditRow.getSpecies()); Objects.requireNonNull(fishingOperation); - this.ui = ui; this.speciesEditRow = speciesEditRow; this.species = speciesEditRow.getSpecies(); this.fishingOperation = fishingOperation; - if (withSamplingCache) { - cruiseSamplingCache.addSamplingListener(samplingListener); + if (useCruiseSamplingCache) { + + // calcule de la zone associée à l'opération de pêche + + Optional<Zone> optionalZone = cruiseSamplingCache.tryFindZone(fishingOperation); + fishingOperationZone = optionalZone.orElse(null); + + // est-ce que l'espèce du lot existe dans l'algortihme des pièces calcifiées + speciesDefinedInCalcifiedPiecesSampling = cruiseSamplingCache.isSpeciesDefined(species); + } this.samplingCodesAvailable.clear(); @@ -199,16 +166,34 @@ public class IndividualObservationUICache implements Closeable { .forEach(individualObservationRow -> addSamplingCodeNotAvailable(individualObservationRow.getSamplingCode())); } + public CruiseSamplingCache getCruiseSamplingCache() { + return cruiseSamplingCache; + } + + public boolean isFishingOperationWithZone() { + return fishingOperationZone != null; + } + + public boolean isSpeciesDefinedInCalcifiedPiecesSampling() { + return speciesDefinedInCalcifiedPiecesSampling; + } @Override public void close() { - this.ui = null; this.speciesEditRow = null; this.species = null; this.fishingOperation = null; - if (withSamplingCache) { - cruiseSamplingCache.removeSamplingListener(samplingListener); - } + } + + public IndividualObservationSamplingStatus getIndividualObservationStatus(IndividualObservationBatchRowModel row) throws CalcifiedPiecesSamplingAlgorithmEntryNotFoundException, SizeNotDefinedOnIndividualObservationException, ZoneNotDefinedOnFishingOperationException { + + Float size = row.getSize(); + return cruiseSamplingCache.getIndividualObservationSamplingStatus(fishingOperation, + row, + size == null ? null : uiModel.getLengthStepInMm(size), + individualObservationModel.getGender(row), + individualObservationModel.getMaturityValue(row)); + } /** @@ -250,7 +235,7 @@ public class IndividualObservationUICache implements Closeable { return; } - if (withSamplingCache) { + if (useCruiseSamplingCache) { Boolean maturity = cruiseSamplingCache.getMaturity(species.getReferenceTaxonId(), maturityQualitativeValue); cruiseSamplingCache.addIndividualObservation(fishingOperation, @@ -284,7 +269,7 @@ public class IndividualObservationUICache implements Closeable { return; } - if (withSamplingCache) { + if (useCruiseSamplingCache) { Boolean maturity = cruiseSamplingCache.getMaturity(species.getReferenceTaxonId(), maturityQualitativeValue); int lengthStepInMm = uiModel.getLengthStepInMm(lengthStep); @@ -351,7 +336,7 @@ public class IndividualObservationUICache implements Closeable { decrementsSamplingCode(samplingCode); } - if (withSamplingCache) { + if (useCruiseSamplingCache) { Boolean maturity = cruiseSamplingCache.getMaturity(species.getReferenceTaxonId(), maturityQualitativeValue); cruiseSamplingCache.removeIndividualObservation(fishingOperation, @@ -378,7 +363,7 @@ public class IndividualObservationUICache implements Closeable { return; } - if (withSamplingCache) { + if (useCruiseSamplingCache) { Boolean maturity = cruiseSamplingCache.getMaturity(species.getReferenceTaxonId(), maturityQualitativeValue); cruiseSamplingCache.removeSampling(fishingOperation, @@ -445,82 +430,6 @@ public class IndividualObservationUICache implements Closeable { return samplingCodesAvailable.contains(samplingCode); } - public void updateSelectedRow(IndividualObservationBatchRowModel selectedRow) { - - SamplingEvent event = null; - - if (withSamplingCache && selectedRow != null && selectedRow.withSize()) { - - CaracteristicQualitativeValue maturityQualitativeValue = individualObservationModel.getMaturityValue(selectedRow); - Boolean maturity = cruiseSamplingCache.getMaturity(selectedRow.getSpecies().getReferenceTaxonId(), maturityQualitativeValue); - int lengthstep = uiModel.getLengthStepInMm(selectedRow.getSize()); - - event = cruiseSamplingCache.getEventForSummary(fishingOperation, species, maturity, individualObservationModel.getGender(selectedRow), lengthstep).orElse(null); - - } - - displaySummary(event); - } - - protected void displaySummary(SamplingEvent event) { - - if (isInit()) { - String summary = null; - - if (event != null && uiModel.isCanDisplayNotifications()) { - - CalcifiedPiecesSamplingDefinition cpsDef = event.getCpsDef(); - if (log.isInfoEnabled()) { - log.info("displaySummary for " + cpsDef); - } - - int nbForOperation = event.getNbSamplingForOperation(); - int nbForZone = event.getNbSamplingForZone(); - int nbForCruise = event.getNbSamplingForCruise(); - - String nbForOperationLabel = getLabelForSamplingNumber(nbForOperation, cpsDef.getOperationLimitation()); - String nbForZoneLabel = getLabelForSamplingNumber(nbForZone, cpsDef.getZoneLimitation()); - String nbForCruiseLabel = getLabelForSamplingNumber(nbForCruise, cpsDef.getMaxByLenghtStep()); - - 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(); - if (event.getGender() != null) { - key += " " + event.getGender().getDescription(); - } - if (event.getMaturity() != null) { - if (event.getMaturity()) { - key += " " + t("tutti.editSpeciesFrequencies.samplingNeeded.mature"); - } else { - key += " " + t("tutti.editSpeciesFrequencies.samplingNeeded.immature"); - } - } - if (event.getZone() != null) { - Decorator<Zone> zoneDecorator = ui.getHandler().getDecorator(Zone.class, null); - String zone = zoneDecorator.toString(event.getZone()); - summary = t("tutti.editSpeciesFrequencies.samplingNeeded.summary", key, nbForOperationLabel, zone, nbForZoneLabel, nbForCruiseLabel); - } else { - summary = t("tutti.editSpeciesFrequencies.samplingNeeded.summary.noZone", key, nbForOperationLabel, nbForZoneLabel, nbForCruiseLabel); - } - } - - if (log.isInfoEnabled()) { - log.info("getSamplingResumeLabel: " + summary); - } - ui.getSamplingResumeLabel().setText(summary); - } - } - - private boolean isInit() { - return ui != null; - } - - private String getLabelForSamplingNumber(int value, Integer max) { - Decorator<Integer> valueDecorator = ui.getHandler().getDecorator(Integer.class, DecoratorService.NULL_INFINITE); - return "<strong>" + valueDecorator.toString(value) + "</strong> (" + valueDecorator.toString(max) + ")"; - } - public void decrementsSamplingCode(String samplingCode) { samplingCodeCache.removeSamplingCode(species.getReferenceTaxonId(), samplingCode); diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUI.jcss b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUI.jcss index cb41d94..948b1d0 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUI.jcss +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUI.jcss @@ -394,11 +394,7 @@ ComputableDataEditor { } #samplingWarningLabel { - text: "tutti.editSpeciesFrequencies.samplingNeeded.warning"; - visible: false; opaque: true; - foreground: {handler.getConfig().getColorHighlightInfoForeground()}; - background: {handler.getConfig().getColorHighlightInfoBackground()}; horizontalAlignment: {SwingConstants.CENTER}; font-size: 16; border: {BorderFactory.createEmptyBorder(3, 10, 5, 10)}; 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 f9049fa..592561c 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 @@ -136,6 +136,7 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci protected IndividualObservationBatchTableHandler individualObservationBatchTableHandler; protected AverageWeightsHistogramHandler averageWeightsHistogramHandler; protected FrequenciesHistogramHandler frequenciesHistogramHandler; + protected IndividualObservationNotificationZoneHandler individualObservationNotificationZoneHandler; protected Decorator<Caracteristic> caracteristicDecorator; protected Decorator<Caracteristic> caracteristicTipDecorator; @@ -480,6 +481,7 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci this.individualObservationBatchTableHandler = new IndividualObservationBatchTableHandler(ui); this.averageWeightsHistogramHandler = new AverageWeightsHistogramHandler(ui); this.frequenciesHistogramHandler = new FrequenciesHistogramHandler(ui); + this.individualObservationNotificationZoneHandler = new IndividualObservationNotificationZoneHandler(ui); listenValidatorValid(ui.getValidator(), model); @@ -508,6 +510,7 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci IOUtils.closeQuietly(individualObservationBatchTableHandler); IOUtils.closeQuietly(averageWeightsHistogramHandler); IOUtils.closeQuietly(frequenciesHistogramHandler); + IOUtils.closeQuietly(individualObservationBatchTableHandler); // resetSamplingLabel(); @@ -644,7 +647,9 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci loadFrequenciesAndObservations(frequency, individualObservations); - individualObservationBatchTableHandler.initObservationsCache(frequencyEditor.getEditRow(), getDataContext().getFishingOperation()); + individualObservationBatchTableHandler.initObservationsCache(speciesBatch, getDataContext().getFishingOperation()); + + individualObservationNotificationZoneHandler.editBatch(speciesBatch); // individualObservationUICache.init(ui, frequencyEditor.getEditRow(), getDataContext().getFishingOperation(), model.getRows()); diff --git a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties index f7e654d..a1df422 100644 --- a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties +++ b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties @@ -1651,6 +1651,7 @@ tutti.editSpeciesFrequencies.samplingNeeded.resume.noZone= tutti.editSpeciesFrequencies.samplingNeeded.summary= tutti.editSpeciesFrequencies.samplingNeeded.summary.noZone= tutti.editSpeciesFrequencies.samplingNeeded.warning= +tutti.editSpeciesFrequencies.samplingTotalCountAttained.warning= tutti.editSpeciesFrequencies.simpleCountingAndFrequencies= tutti.editSpeciesFrequencies.table.header.lengthStep= tutti.editSpeciesFrequencies.table.header.number= diff --git a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties index a99f983..4f46f12 100644 --- a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties +++ b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties @@ -1534,7 +1534,8 @@ tutti.editSpeciesFrequencies.samplingNeeded.mature=Mature tutti.editSpeciesFrequencies.samplingNeeded.max=max tutti.editSpeciesFrequencies.samplingNeeded.summary=<html><body><strong>%s</strong> \: Trait \: %s | %s \: %s | Campagne \: %s tutti.editSpeciesFrequencies.samplingNeeded.summary.noZone=<html><body><strong>%s</strong> \: Trait \: %s | (pas dans une zone) | Campagne \: %s -tutti.editSpeciesFrequencies.samplingNeeded.warning=<html><body><strong>Prélevez les pièces calcifiées \!</body></html> +tutti.editSpeciesFrequencies.samplingNeeded.warning= +tutti.editSpeciesFrequencies.samplingTotalCountAttained.warning=<html><body><strong>Le nombre de prélèvements requis est atteint \!</body></html> tutti.editSpeciesFrequencies.simpleCountingAndFrequencies=Des mensurations ont été saisies dans le tableau. Saisir un simple dénombrement les effacera. tutti.editSpeciesFrequencies.table.header.lengthStep=Classe de taille tutti.editSpeciesFrequencies.table.header.number=Nombre -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
participants (1)
-
codelutin.com scm