This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository tutti. See https://gitlab.nuiton.org/codelutin/tutti.git commit 068770c7e130af4b6014a0e2f3f2645fecc02194 Author: Tony CHEMIT <chemit@codelutin.com> Date: Sun Apr 24 17:53:30 2016 +0200 Corrections et améliorations diverses sur l'écran des observations individuelles --- .../main/java/fr/ifremer/tutti/util/Numbers.java | 14 +- .../service/sampling/CruiseSamplingCache.java | 13 +- .../IndividualObservationSamplingCacheRequest.java | 24 ++ .../IndividualObservationSamplingStatus.java | 56 +++- .../resources/i18n/tutti-service_en_GB.properties | 127 --------- .../SamplingCodeCellEditor.java | 36 ++- .../IndividualObservationBatchRowModel.java | 28 +- .../IndividualObservationBatchTableHandler.java | 299 ++++++++++----------- .../IndividualObservationBatchTableModel.java | 46 ++-- .../IndividualObservationBatchUIModel.java | 62 ++++- .../IndividualObservationToFrequencyEngine.java | 171 +++++------- ...IndividualObservationToSamplingCacheEngine.java | 119 ++++++++ ...dividualObservationToSamplingCacheResolver.java | 147 ---------- .../frequency/IndividualObservationUICache.java | 190 +++---------- .../species/frequency/SamplingCodeUICache.java | 230 ++++++++++++++++ .../frequency/SamplingNotificationZoneHandler.java | 194 +++++++++---- .../frequency/SamplingNotificationZoneModel.java | 30 ++- .../frequency/SamplingNotificationZoneStatus.java | 2 + .../frequency/SpeciesFrequencyTableModel.java | 82 ++++-- .../frequency/SpeciesFrequencyUIHandler.java | 279 +++++++------------ .../species/frequency/SpeciesFrequencyUIModel.java | 115 +++++++- .../actions/ApplySpeciesFrequencyRafaleAction.java | 13 +- .../actions/CancelEditSpeciesFrequencyAction.java | 13 +- .../frequency/actions/EditSampleCodeAction.java | 29 +- .../ImportMultiPostSpeciesSupportAction.java | 6 +- .../frequency/actions/RemoveObservationAction.java | 2 +- .../actions/ResetSpeciesFrequencyAction.java | 5 +- .../resources/i18n/tutti-ui-swing_en_GB.properties | 37 +-- .../resources/i18n/tutti-ui-swing_fr_FR.properties | 16 +- .../fr/ifremer/tutti/ui/swing/SoundUtilTest.java | 19 +- 30 files changed, 1312 insertions(+), 1092 deletions(-) diff --git a/tutti-persistence/src/main/java/fr/ifremer/tutti/util/Numbers.java b/tutti-persistence/src/main/java/fr/ifremer/tutti/util/Numbers.java index d2e5414..ca4e005 100644 --- a/tutti-persistence/src/main/java/fr/ifremer/tutti/util/Numbers.java +++ b/tutti-persistence/src/main/java/fr/ifremer/tutti/util/Numbers.java @@ -34,6 +34,10 @@ import java.math.BigDecimal; */ public class Numbers { + public static final String MM_UNIT = "mm"; + + public static final String CM_UNIT = "cm"; + public static float getRoundedLengthStep(float lengthStep, boolean aroundUp) { int intValue = (int) ((lengthStep + (aroundUp ? 0.001f : 0f)) * 10); return intValue / 10f; @@ -70,8 +74,8 @@ public class Numbers { * @since 4.2 */ public static Float roundDecimalCoordinateComponent(Float value) { - Float result =null; - if (value!=null) { + Float result = null; + if (value != null) { BigDecimal sumB = new BigDecimal(String.valueOf(value)) .setScale(4, BigDecimal.ROUND_HALF_UP); // pourquoi abs() ? @@ -82,7 +86,7 @@ public class Numbers { } public static float convertToCm(float source, String sourceUnit) { - if ("mm".equals(sourceUnit)) { + if (MM_UNIT.equals(sourceUnit)) { // measurement in cm asked source = source / 10; } @@ -90,7 +94,7 @@ public class Numbers { } public static int convertToMm(float source, String sourceUnit) { - if ("cm".equals(sourceUnit)) { + if (CM_UNIT.equals(sourceUnit)) { // measurement in mm asked source = source * 10; } @@ -98,7 +102,7 @@ public class Numbers { } public static float convertFromMm(float source, String targetUnit) { - if ("cm".equals(targetUnit)) { + if (CM_UNIT.equals(targetUnit)) { // measurement in cm asked source = source / 10; } 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 06c3cf8..d7c30af 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 @@ -396,16 +396,11 @@ public class CruiseSamplingCache implements CruiseCacheAble { String fishingOperationSamplingKey = context.getFishingOperationSamplingKey(); CruiseSamplingInternalCache.SamplingData fishingOperationSamplingData = fishingOperationCache.getSamplingData(fishingOperationSamplingKey); - boolean needSampling; - if (request.withSamplingCode()) { - needSampling = false; - } else { - int samplingInterval = context.getCalcifiedPiecesSamplingDefinition().getSamplingInterval(); - int cruiseIndividualObservationCount = cruiseSamplingData.getIndividualObservationCount(); - needSampling = cruiseIndividualObservationCount == 1 || samplingInterval == 1 || cruiseIndividualObservationCount % samplingInterval == 1; - } + // on demande à calculer needSampling uniquement s'il n'y a pas de code de prélèvement sur l'observation + boolean computeSampling = !request.withSamplingCode(); + + return new IndividualObservationSamplingStatus(context, computeSampling, cruiseSamplingData, zoneSamplingData, fishingOperationSamplingData); - return new IndividualObservationSamplingStatus(context, needSampling, cruiseSamplingData, zoneSamplingData, fishingOperationSamplingData); } public void addIndividualObservation(IndividualObservationSamplingCacheRequest request) { diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingCacheRequest.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingCacheRequest.java index 3e528b7..05a387c 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingCacheRequest.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/sampling/IndividualObservationSamplingCacheRequest.java @@ -1,5 +1,6 @@ package fr.ifremer.tutti.service.sampling; +import com.google.common.base.MoreObjects; import fr.ifremer.tutti.persistence.entities.data.FishingOperation; import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; import fr.ifremer.tutti.persistence.entities.referential.Species; @@ -77,4 +78,27 @@ public class IndividualObservationSamplingCacheRequest { public boolean withSamplingCode() { return samplingCode != null; } + + @Override + public String toString() { + + MoreObjects.ToStringHelper toStringHelper = MoreObjects.toStringHelper(this) + .add("fishingOperation", fishingOperation) + .add("species", species); + if (withLengthClass()) { + toStringHelper.add("lengthClass", lengthClass); + } + if (withMaturity()) { + toStringHelper.add("maturity", maturity); + } + if (withGender()) { + toStringHelper.add("gender", gender); + } + if (withSamplingCode()) { + toStringHelper.add("samplingCode", samplingCode); + } + + return toStringHelper.toString(); + + } } 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 index dd47b50..760b051 100644 --- 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 @@ -1,5 +1,6 @@ package fr.ifremer.tutti.service.sampling; +import com.google.common.base.MoreObjects; import fr.ifremer.tutti.persistence.entities.protocol.CalcifiedPiecesSamplingDefinition; import java.util.Objects; @@ -56,7 +57,7 @@ public class IndividualObservationSamplingStatus { private final boolean needSampling; public IndividualObservationSamplingStatus(IndividualObservationSamplingContext individualObservationSamplingContext, - boolean needSampling, + boolean computeSampling, CruiseSamplingInternalCache.SamplingData cruiseSamplingData, CruiseSamplingInternalCache.SamplingData zoneSamplingData, CruiseSamplingInternalCache.SamplingData fishingOperationSamplingData) { @@ -71,8 +72,22 @@ public class IndividualObservationSamplingStatus { this.individualObservationCountInZone = zoneSamplingData.getIndividualObservationCount(); this.samplingCountInFishingOperation = fishingOperationSamplingData.getSamplingCount(); this.individualObservationCountInFishingOperation = fishingOperationSamplingData.getIndividualObservationCount(); - // on ne peux demander un prélèvement uniquement si la limite n'est pas atteinte - this.needSampling = needSampling && !isOneTotalCountIsAttained(); + + boolean needSampling; + + // on calcule needSampling si on nous le demande, que la définnition nous autorise (au moins un max n'est pas à 0) et qu'aucun max n'a été atteint + if (computeSampling && !isNotUsingSampling() && !isOneTotalCountIsAttained()) { + + int samplingInterval = individualObservationSamplingContext.getCalcifiedPiecesSamplingDefinition().getSamplingInterval(); + needSampling = individualObservationCountInCruise== 1 || samplingInterval == 1 || individualObservationCountInCruise % samplingInterval == 1; + + } else { + + needSampling = false; + + } + this.needSampling = needSampling; + } public IndividualObservationSamplingContext getIndividualObservationSamplingContext() { @@ -125,7 +140,7 @@ public class IndividualObservationSamplingStatus { public boolean isTotalInCruiseAttained() { Integer totalSamplingRequiredInCruise = getTotalSamplingRequiredInCruise(); - return totalSamplingRequiredInCruise != null && (totalSamplingRequiredInCruise > 0 && getSamplingCountInCruise() >= totalSamplingRequiredInCruise); + return totalSamplingRequiredInCruise != null && totalSamplingRequiredInCruise > 0 && getSamplingCountInCruise() >= totalSamplingRequiredInCruise; } public boolean isTotalInFishingOperationAttained() { @@ -141,4 +156,37 @@ public class IndividualObservationSamplingStatus { public boolean isOneTotalCountIsAttained() { return isTotalInCruiseAttained() || isTotalInZoneAttained() || isTotalInFishingOperationAttained(); } + + public boolean isTotalInCruiseNotUsed() { + Integer totalSamplingRequiredInCruise = getTotalSamplingRequiredInCruise(); + return totalSamplingRequiredInCruise != null && totalSamplingRequiredInCruise == 0; + } + + public boolean isTotalInFishingOperationNotUsed() { + Integer totalSamplingRequiredInFishingOperation = getTotalSamplingRequiredInFishingOperation(); + return totalSamplingRequiredInFishingOperation != null && totalSamplingRequiredInFishingOperation == 0; + } + + public boolean isTotalInZoneNotUsed() { + Integer totalSamplingRequiredInZone = getTotalSamplingRequiredInZone(); + return totalSamplingRequiredInZone != null && totalSamplingRequiredInZone == 0; + } + + public boolean isNotUsingSampling() { + return isTotalInCruiseNotUsed() && isTotalInFishingOperationNotUsed() && isTotalInZoneNotUsed(); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("individualObservationSamplingContext", individualObservationSamplingContext) + .add("individualObservationCountInCruise", getIndividualObservationCountInCruise()) + .add("samplingCountInCruise", samplingCountInCruise) + .add("individualObservationCountInFishingOperation", getIndividualObservationCountInFishingOperation()) + .add("samplingCountInFishingOperation", samplingCountInFishingOperation) + .add("individualObservationCountInZone", getIndividualObservationCountInZone()) + .add("samplingCountInZone", samplingCountInZone) + .add("needSampling", needSampling) + .toString(); + } } diff --git a/tutti-service/src/main/resources/i18n/tutti-service_en_GB.properties b/tutti-service/src/main/resources/i18n/tutti-service_en_GB.properties index 1f0e6be..c48deb5 100644 --- a/tutti-service/src/main/resources/i18n/tutti-service_en_GB.properties +++ b/tutti-service/src/main/resources/i18n/tutti-service_en_GB.properties @@ -1,25 +1,14 @@ tutti.caracteristicType.GEAR_USE_FEATURE= tutti.caracteristicType.INDIVIDUAL_OBSERVATION= -tutti.caracteristicType.LENGTH_STEP= tutti.caracteristicType.VESSEL_USE_FEATURE= -tutti.caracteristicType.gearUseFeature= -tutti.caracteristicType.individualObservation= tutti.caracteristicType.lengthStep= -tutti.caracteristicType.vesselUseFeature= tutti.cruise.cacheLoader.loading.fishingOperation= tutti.csv.import.error.on.field= tutti.csv.import.error.on.row= tutti.decorator.null.infinite= -tutti.error.benthos.not.in.protocol= -tutti.error.messages= -tutti.error.species.not.in.protocol= -tutti.fatal.messages= tutti.io.mkDir.error= tutti.maturity.immature= -tutti.maturity.immature.short= tutti.maturity.mature= -tutti.maturity.mature.short= -tutti.pdf.export.missing.species.code= tutti.property.attachment= tutti.property.caracteristic= tutti.property.country= @@ -64,15 +53,9 @@ tutti.propety.vessel.nation.registrationCode= tutti.report.step.export.fishingOperation= tutti.report.step.generateReport= tutti.report.step.load.fishingOperation= -tutti.service.arp.import.attachment.comment= tutti.service.bigfin.import.attachment.comment= -tutti.service.bigfinImport.error.species.batch.frequenciesOnHigherLevel= -tutti.service.bigfinImport.error.species.categoriesSkipped= -tutti.service.bigfinImport.error.species.categorySkipped= tutti.service.bigfinImport.error.species.not.found= -tutti.service.bigfinImport.error.species.tooCategorized= tutti.service.bigfinImport.error.species.without.lengthstep= -tutti.service.bigfinImport.error.species.wrongNextCategory= tutti.service.bigfinImport.error.szClass.unknwon= tutti.service.bigfinImport.warning.species.batch.frequenciesOnHigherLevel= tutti.service.bigfinImport.warning.species.categoriesSkipped= @@ -86,13 +69,10 @@ tutti.service.calcifiedPiecesSamplingReport.header.geniusName= tutti.service.calcifiedPiecesSamplingReport.header.lengthStep= tutti.service.calcifiedPiecesSamplingReport.header.maturity= tutti.service.calcifiedPiecesSamplingReport.header.maxByLengthStep= -tutti.service.calcifiedPiecesSamplingReport.header.observationNb= tutti.service.calcifiedPiecesSamplingReport.header.samplingNb= tutti.service.calcifiedPiecesSamplingReport.header.surveyCode= -tutti.service.compressZipFile.error= tutti.service.context.serviceInstanciation.error= tutti.service.cpsExport.error= -tutti.service.cpsExport.step.export.species= tutti.service.cpsExport.step.toFile= tutti.service.csv.caracteristic.qualitativeValue.notFound= tutti.service.csv.parse.entityNotFound= @@ -102,9 +82,6 @@ tutti.service.cvs.format.error= tutti.service.cvs.mandatory.value= tutti.service.error.species.null= tutti.service.exportPdf.error= -tutti.service.exportProgram.exportSpecies= -tutti.service.exportSumatra.error.species.null= -tutti.service.exportSumatra.error.station.null= tutti.service.exportSumatra.header.averageSize= tutti.service.exportSumatra.header.averageWeight= tutti.service.exportSumatra.header.endDate= @@ -116,37 +93,19 @@ tutti.service.exportSumatra.header.multirigAggregation= tutti.service.exportSumatra.header.number= tutti.service.exportSumatra.header.sign= tutti.service.exportSumatra.header.sortedWeight= -tutti.service.exportSumatra.header.species= tutti.service.exportSumatra.header.startDate= tutti.service.exportSumatra.header.startLatitude= tutti.service.exportSumatra.header.startLongitude= tutti.service.exportSumatra.header.station= tutti.service.exportSumatra.header.surveySpecies= tutti.service.exportSumatra.header.totalWeight= -tutti.service.exportSumatra.header.weight= tutti.service.exportSumatra.header.year= -tutti.service.exportSumatraV2.header.averageSize=Averagesize -tutti.service.exportSumatraV2.header.averageWeight=AverageWeight -tutti.service.exportSumatraV2.header.moule=Moule -tutti.service.exportSumatraV2.header.multirigAggregation=MultirigAggregation -tutti.service.exportSumatraV2.header.number=Number -tutti.service.exportSumatraV2.header.sign=Sign -tutti.service.exportSumatraV2.header.sortedWeight=SortedWeight -tutti.service.exportSumatraV2.header.species=Species -tutti.service.exportSumatraV2.header.station=Station number -tutti.service.exportSumatraV2.header.totalWeight=TotalWeight -tutti.service.exportSumatraV2.header.year=Year tutti.service.genericFormat.checkCruise= tutti.service.genericFormat.checkCruiseFishingOperation= tutti.service.genericFormat.checkWeights.fishingOperation= tutti.service.genericFormat.cleanWeights.fishingOperation= -tutti.service.genericFormat.export.accidentalCatch.error= tutti.service.genericFormat.export.attachment.error= -tutti.service.genericFormat.export.attachments.error= tutti.service.genericFormat.export.buildZip= -tutti.service.genericFormat.export.catches.error= -tutti.service.genericFormat.export.closeContext.error= -tutti.service.genericFormat.export.context.error= tutti.service.genericFormat.export.emptyFile.error= tutti.service.genericFormat.export.exportProtocol= tutti.service.genericFormat.export.exportSampleCategoyModel= @@ -156,37 +115,13 @@ tutti.service.genericFormat.export.exportTemporaryPerson= tutti.service.genericFormat.export.exportTemporarySpecies= tutti.service.genericFormat.export.exportTemporaryVessel= tutti.service.genericFormat.export.gearCaracteristics.error= -tutti.service.genericFormat.export.individualObservations.error= -tutti.service.genericFormat.export.invalid.cruise= -tutti.service.genericFormat.export.invalid.fishingOperation= -tutti.service.genericFormat.export.marineLitters.error= tutti.service.genericFormat.export.operation.error= -tutti.service.genericFormat.export.operations.error= -tutti.service.genericFormat.export.parameters.error= tutti.service.genericFormat.export.skipProtocolExport= -tutti.service.genericFormat.export.skipTemporaryGearExport= -tutti.service.genericFormat.export.skipTemporaryPersonExport= -tutti.service.genericFormat.export.skipTemporarySpeciesExport= -tutti.service.genericFormat.export.skipTemporaryVesselExport= tutti.service.genericFormat.export.species.error= tutti.service.genericFormat.export.survey.error= tutti.service.genericFormat.export.zip.error= -tutti.service.genericFormat.exportCruise.buildZip= -tutti.service.genericFormat.exportCruise.checkCruise= -tutti.service.genericFormat.exportCruise.checkCruiseFishingOperation= -tutti.service.genericFormat.exportCruise.exportAccidentalCatches= -tutti.service.genericFormat.exportCruise.exportCatch= -tutti.service.genericFormat.exportCruise.exportCatches= tutti.service.genericFormat.exportCruise.exportGearCaracteristics= -tutti.service.genericFormat.exportCruise.exportIndividualObservation= -tutti.service.genericFormat.exportCruise.exportIndividualObservations= -tutti.service.genericFormat.exportCruise.exportMarineLitter= -tutti.service.genericFormat.exportCruise.exportMarineLitters= tutti.service.genericFormat.exportCruise.exportOperation= -tutti.service.genericFormat.exportCruise.exportOperations= -tutti.service.genericFormat.exportCruise.exportParameter= -tutti.service.genericFormat.exportCruise.exportParameters= -tutti.service.genericFormat.exportCruise.exportSpecies= tutti.service.genericFormat.exportCruise.exportSurvey= tutti.service.genericFormat.import.accidentalCatches= tutti.service.genericFormat.import.catches= @@ -216,12 +151,8 @@ tutti.service.genericFormat.import.protocol.notValid= tutti.service.genericFormat.import.sampleCategoryModel= tutti.service.genericFormat.import.sampleCategoryModel.error.alreadyUsedCaracteristic= tutti.service.genericFormat.import.sampleCategoryModel.error.alreadyUsedCode= -tutti.service.genericFormat.import.sampleCategoryModel.error.caracteristicNotMatching= -tutti.service.genericFormat.import.sampleCategoryModel.error.codeNotMatching= -tutti.service.genericFormat.import.sampleCategoryModel.error.missingCategories= tutti.service.genericFormat.import.sampleCategoryModel.error.noCaracteristic= tutti.service.genericFormat.import.sampleCategoryModel.error.noCode= -tutti.service.genericFormat.import.sampleCategoryModel.error.tooMuchCategories= tutti.service.genericFormat.import.temporaryGears= tutti.service.genericFormat.import.temporaryPersons= tutti.service.genericFormat.import.temporarySpecies= @@ -231,12 +162,9 @@ tutti.service.genericFormat.importError.missArchiveFile= tutti.service.genericFormat.invalid.cruise= tutti.service.genericFormat.invalid.fishingOperation= tutti.service.genericFormat.load.attachments= -tutti.service.genericFormat.load.protocol= tutti.service.genericFormat.persist.create.cruise= tutti.service.genericFormat.persist.create.operation= -tutti.service.genericFormat.persist.cruise= tutti.service.genericFormat.persist.gearCaracteristics= -tutti.service.genericFormat.persist.operation= tutti.service.genericFormat.persist.operation.accidentalBatches= tutti.service.genericFormat.persist.operation.benthosBatches= tutti.service.genericFormat.persist.operation.individualObservations= @@ -249,8 +177,6 @@ tutti.service.genericFormat.persist.skipNotSelected.cruise= tutti.service.genericFormat.persist.skipNotSelected.operation= tutti.service.genericFormat.persist.update.cruise= tutti.service.genericFormat.persist.update.operation= -tutti.service.genericFormat.remove.existingCruise.fishingOperation= -tutti.service.genericFormat.reuse.protocol= tutti.service.genericFormat.skip.import.accidentalCatches= tutti.service.genericFormat.skip.import.catches= tutti.service.genericFormat.skip.import.cruises= @@ -285,12 +211,6 @@ tutti.service.multipost.export.frequencies.error= tutti.service.multipost.export.operation.error= tutti.service.multipost.export.weight.error= tutti.service.multipost.export.weights.error= -tutti.service.multipost.import.attachments.error= -tutti.service.multipost.import.batches.error= -tutti.service.multipost.import.caracteristics.error= -tutti.service.multipost.import.frequencies.error= -tutti.service.multipost.import.operation.error= -tutti.service.multipost.import.weights.error= tutti.service.multipost.import.wrongOperation.error= tutti.service.multipost.import.wrongSpecies.error= tutti.service.multipost.uncompress.error= @@ -301,26 +221,19 @@ tutti.service.operations.cleanWeights.error.redundant.weight= tutti.service.operations.cleanWeights.species.batch= tutti.service.operations.computeWeights.error.benthos.incoherentCategoryWeight= tutti.service.operations.computeWeights.error.benthos.incoherentParentCategoryWeight= -tutti.service.operations.computeWeights.error.benthos.incoherentRowWeightCategory= tutti.service.operations.computeWeights.error.benthos.incoherentRowWeightFrequency= -tutti.service.operations.computeWeights.error.benthos.incoherentSampleWeight= tutti.service.operations.computeWeights.error.benthos.incoherentTotalSorted= tutti.service.operations.computeWeights.error.benthos.noWeight= -tutti.service.operations.computeWeights.error.incoherentRowWeightCategory= tutti.service.operations.computeWeights.error.incoherentTotal= tutti.service.operations.computeWeights.error.incoherentTotalWithRejected= tutti.service.operations.computeWeights.error.marineLitter.incoherentTotal= tutti.service.operations.computeWeights.error.species.incoherentCategoryWeight= tutti.service.operations.computeWeights.error.species.incoherentParentCategoryWeight= -tutti.service.operations.computeWeights.error.species.incoherentRowWeightCategory= tutti.service.operations.computeWeights.error.species.incoherentRowWeightFrequency= -tutti.service.operations.computeWeights.error.species.incoherentSampleWeight= tutti.service.operations.computeWeights.error.species.incoherentTotalSorted= tutti.service.operations.computeWeights.error.species.noWeight= tutti.service.operations.computeWeights.error.speciesOrBenthos.incoherentRowWeightCategory= tutti.service.operations.computeWeights.error.speciesOrBenthos.incoherentSampleWeight= -tutti.service.operations.computeWeights.error.totalLessThanSortedAndUnsorted= -tutti.service.operations.exportCatchesReport.error= tutti.service.operations.exportCatchesReport.specialRows.benthos.code= tutti.service.operations.exportCatchesReport.specialRows.benthos.name= tutti.service.operations.exportCatchesReport.specialRows.inertAndLivinngNotItemized.code= @@ -342,7 +255,6 @@ tutti.service.protocol.export.benthos.error= tutti.service.protocol.export.caracteristics.all.error= tutti.service.protocol.export.caracteristics.protocol.error= tutti.service.protocol.export.cps.error= -tutti.service.protocol.export.cps.interval.error= tutti.service.protocol.export.species.error= tutti.service.protocol.import.benthos.error= tutti.service.protocol.import.cps.error= @@ -352,7 +264,6 @@ tutti.service.protocol.import.species.error= tutti.service.protocol.import.taxonUsed.error= tutti.service.psion.import.attachment.comment= tutti.service.psionimport.error.inconsistentVracCategory.message= -tutti.service.psionimport.error.inconsistentVracWeight.message= tutti.service.psionimport.error.invalid.category.syntax= tutti.service.psionimport.error.invalid.command.syntax= tutti.service.psionimport.error.invalid.date.format= @@ -365,7 +276,6 @@ tutti.service.psionimport.error.no.lengthClass.caracteristic= tutti.service.psionimport.error.no.protocol= tutti.service.psionimport.error.species.already.used= tutti.service.psionimport.error.species.not.found= -tutti.service.psionimport.error.unkonwSampleCategory.message= tutti.service.pupitri.export.species.error= tutti.service.pupitri.import.attachment.comment= tutti.service.pupitri.import.carrousel.error= @@ -379,9 +289,7 @@ tutti.service.referential.export.person.error= tutti.service.referential.export.species.error= tutti.service.referential.export.vessel.error= tutti.service.referential.import.error.vessel.used= -tutti.service.referential.import.gear.cannotDeleteNotExisting.error= tutti.service.referential.import.gear.error.cannotDeleteWithoutId= -tutti.service.referential.import.gear.error.cannotUpdateOrDeleteForGenericFormatImport= tutti.service.referential.import.gear.error.existingName= tutti.service.referential.import.gear.error.id.alreaydAdded= tutti.service.referential.import.gear.error.idNotNegative= @@ -391,12 +299,8 @@ tutti.service.referential.import.gear.error.noId= tutti.service.referential.import.gear.error.noName= tutti.service.referential.import.gear.error.notExistingId= tutti.service.referential.import.gear.error.used= -tutti.service.referential.import.gear.idNotNegative.error= -tutti.service.referential.import.gear.notExistingId.error= tutti.service.referential.import.gears.error= -tutti.service.referential.import.person.cannotDeleteNotExisting.error= tutti.service.referential.import.person.error.cannotDeleteWithoutId= -tutti.service.referential.import.person.error.cannotUpdateOrDeleteForGenericFormatImport= tutti.service.referential.import.person.error.existingName= tutti.service.referential.import.person.error.id.alreaydAdded= tutti.service.referential.import.person.error.idNotNegative= @@ -406,13 +310,9 @@ tutti.service.referential.import.person.error.noId= tutti.service.referential.import.person.error.noName= tutti.service.referential.import.person.error.notExistingId= tutti.service.referential.import.person.error.used= -tutti.service.referential.import.person.idNotNegative.error= -tutti.service.referential.import.person.notExistingId.error= tutti.service.referential.import.persons.error= -tutti.service.referential.import.species.cannotDeleteNotExisting.error= tutti.service.referential.import.species.error= tutti.service.referential.import.species.error.cannotDeleteWithoutId= -tutti.service.referential.import.species.error.cannotUpdateOrDeleteForGenericFormatImport= tutti.service.referential.import.species.error.existingName= tutti.service.referential.import.species.error.id.alreaydAdded= tutti.service.referential.import.species.error.idNotNegative= @@ -423,12 +323,8 @@ tutti.service.referential.import.species.error.noName= tutti.service.referential.import.species.error.noReferencetTaxonId= tutti.service.referential.import.species.error.notExistingId= tutti.service.referential.import.species.error.used= -tutti.service.referential.import.species.idNotNegative.error= -tutti.service.referential.import.vessel.add.noName.error= -tutti.service.referential.import.vessel.cannotDeleteNotExisting.error= tutti.service.referential.import.vessel.codePrefixMissing.error= tutti.service.referential.import.vessel.error.cannotDeleteWithoutId= -tutti.service.referential.import.vessel.error.cannotUpdateOrDeleteForGenericFormatImport= tutti.service.referential.import.vessel.error.existingRegistrationCode= tutti.service.referential.import.vessel.error.id.alreaydAdded= tutti.service.referential.import.vessel.error.idNotTemporary= @@ -436,12 +332,7 @@ tutti.service.referential.import.vessel.error.name.alreaydAdded= tutti.service.referential.import.vessel.error.noId= tutti.service.referential.import.vessel.error.noRegistrationCode= tutti.service.referential.import.vessel.error.notExistingId= -tutti.service.referential.import.vessel.existingInternationalRegistrationCode.error= -tutti.service.referential.import.vessel.existingName.error= -tutti.service.referential.import.vessel.noInternationalRegistrationCode.error= -tutti.service.referential.import.vessel.noName.error= tutti.service.referential.import.vessels.error= -tutti.service.referential.import.vessels.existingValue.error= tutti.service.sumatra.export.error= tutti.service.sumatra.export.step.export= tutti.service.sumatra.export.step.load.cruise= @@ -449,24 +340,15 @@ tutti.service.sumatra.export.step.load.fishingOperation= tutti.service.sumatra.export.step.load.fishingOperationIds= tutti.service.validateCruise.cruise.check= tutti.service.validateCruise.cruise.loading= -tutti.service.validateCruise.cruise.progress= tutti.service.validateCruise.exportResult.error= tutti.service.validateCruise.operations.check= tutti.service.validateCruise.operations.loading= -tutti.service.validateCruise.operations.progress= tutti.toconfirmReport.generate.report= tutti.toconfirmReport.loading.cruise= -tutti.toconfirmReport.loading.fishingOperation= tutti.toconfirmReport.loading.operation= tutti.toconfirmReport.loading.protocol= -tutti.toconfirmReport.start.fishingOperation= -tutti.validator.error.accidental.species.required= tutti.validator.error.accidentalBatch.species.required= tutti.validator.error.accidentalBatch.species.temporary= -tutti.validator.error.accidentalBatch.vessel.temporary= -tutti.validator.error.benthosBatch.species.required= -tutti.validator.error.benthosBatch.species.temporary= -tutti.validator.error.benthosBatch.vessel.temporary= tutti.validator.error.catchBatch.catchTotalRejectedWeight.zeroValue= tutti.validator.error.comment.too.long= tutti.validator.error.cruise.beginDate.required= @@ -511,11 +393,6 @@ tutti.validator.error.fishingOperation.trawlNetNumber.invalid= tutti.validator.error.fishingOperation.trawlNetNumber.required= tutti.validator.error.fishingOperation.vessel.required= tutti.validator.error.fishingOperation.vessel.temporary= -tutti.validator.error.individualObservation.lengthStepCaracteristic.required= -tutti.validator.error.individualObservation.size.required= -tutti.validator.error.individualObservation.species.required= -tutti.validator.error.individualObservation.vessel.temporary= -tutti.validator.error.individualObservation.weight.required= tutti.validator.error.individualObservationBatch.lengthStepCaracteristic.required= tutti.validator.error.individualObservationBatch.size.required= tutti.validator.error.individualObservationBatch.species.required= @@ -535,9 +412,6 @@ tutti.validator.error.program.name.required= tutti.validator.error.program.zone.required= tutti.validator.error.protocol.name.alreadyUsed= tutti.validator.error.protocol.name.required= -tutti.validator.error.speciesBatch.species.required= -tutti.validator.error.speciesBatch.species.temporary= -tutti.validator.error.speciesBatch.vessel.temporary= tutti.validator.error.speciesOrBenthosBatch.species.required= tutti.validator.error.speciesOrBenthosBatch.species.temporary= tutti.validator.export.message.error= @@ -550,4 +424,3 @@ tutti.validator.warning.latitude.outOfBounds= tutti.validator.warning.longitude.outOfBounds= tutti.validator.warning.marineLitter.weight.required= tutti.validator.warning.species.protocolNotRespected= -tutti.warning.messages= 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 a300165..e404e57 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,12 +23,9 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.individualobservatio */ import com.google.common.base.Preconditions; -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; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.IndividualObservationBatchTableModel; -import fr.ifremer.tutti.ui.swing.util.TuttiUI; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUIModel; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -40,7 +37,7 @@ import javax.swing.table.TableCellEditor; import java.awt.Color; import java.awt.Component; import java.util.EventObject; -import java.util.Optional; +import java.util.Objects; import static org.nuiton.i18n.I18n.t; @@ -55,9 +52,9 @@ public class SamplingCodeCellEditor extends AbstractCellEditor implements TableC /** Logger. */ private static final Log log = LogFactory.getLog(SamplingCodeCellEditor.class); - public static TableCellEditor newEditor(TuttiUI ui) { + public static TableCellEditor newEditor(SpeciesFrequencyUIModel model) { - return new SamplingCodeCellEditor(ui.getHandler().getContext()); + return new SamplingCodeCellEditor(model); } protected JTable table; @@ -70,8 +67,8 @@ public class SamplingCodeCellEditor extends AbstractCellEditor implements TableC protected final SampleCodeGenerator editorButton; - public SamplingCodeCellEditor(TuttiUIContext context) { - this.editorButton = new SampleCodeGenerator(context); + public SamplingCodeCellEditor(SpeciesFrequencyUIModel model) { + this.editorButton = new SampleCodeGenerator(model); } @Override @@ -127,12 +124,15 @@ public class SamplingCodeCellEditor extends AbstractCellEditor implements TableC public class SampleCodeGenerator extends JButton { - final TuttiUIContext context; + private final SpeciesFrequencyUIModel model; - IndividualObservationBatchRowModel row; + private IndividualObservationBatchRowModel row; - SampleCodeGenerator(TuttiUIContext context) { - this.context = context; + SampleCodeGenerator(SpeciesFrequencyUIModel model) { + + Objects.requireNonNull(model); + + this.model = model; setBorder(new LineBorder(Color.BLACK)); setText(t("tutti.editIndividualObservationBatch.table.editor.codeSampleGenerator.label")); addActionListener(evt -> generateCode()); @@ -148,13 +148,9 @@ public class SamplingCodeCellEditor extends AbstractCellEditor implements TableC protected void generateCode() { - Optional<CruiseCache> optionalCruiseCache = context.getDataContext().getOptionalCruiseCache(); - if (!optionalCruiseCache.isPresent()) { - throw new IllegalStateException("No cruise cache found!"); - } - SamplingCodeCache samplingCodeCache = optionalCruiseCache.get().getSamplingCodeCache(); - int i = samplingCodeCache.getNextSamplingCodeId(getRow().getSpecies().getReferenceTaxonId()); - String samplingCode = row.getSamplingCodePrefix().toSamplingCode(i); + int samplingCodeId = model.getSamplingCodeUICache().getNextSamplingCodeId(); + String samplingCode = model.getIndividualObservationModel().getSamplingCodePrefix().toSamplingCode(samplingCodeId); + if (log.isInfoEnabled()) { log.info("Generated sampling code: " + samplingCode); } 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 4809cea..8dc9b31 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 @@ -88,10 +88,10 @@ public class IndividualObservationBatchRowModel extends AbstractTuttiBeanUIModel */ protected final WeightUnit weightUnit; - /** - * @since 4.5 - */ - protected SamplingCodePrefix samplingCodePrefix; +// /** +// * @since 4.5 +// */ +// protected SamplingCodePrefix samplingCodePrefix; protected static final Binder<IndividualObservationBatch, IndividualObservationBatchRowModel> fromBeanBinder = BinderFactory.newBinder(IndividualObservationBatch.class, @@ -373,21 +373,21 @@ public class IndividualObservationBatchRowModel extends AbstractTuttiBeanUIModel return SamplingCodePrefix.extractSamplingCodeIdFromSamplingCode(getSamplingCode()); } - public SamplingCodePrefix getSamplingCodePrefix() { - return samplingCodePrefix; - } - - public void setSamplingCodePrefix(SamplingCodePrefix samplingCodePrefix) { - this.samplingCodePrefix = samplingCodePrefix; - } +// public SamplingCodePrefix getSamplingCodePrefix() { +// return samplingCodePrefix; +// } +// +// public void setSamplingCodePrefix(SamplingCodePrefix samplingCodePrefix) { +// this.samplingCodePrefix = samplingCodePrefix; +// } public boolean withSamplingCode() { return StringUtils.isNotBlank(getSamplingCode()); } - public boolean withSamplingCodePrefix() { - return samplingCodePrefix != null; - } +// public boolean withSamplingCodePrefix() { +// return samplingCodePrefix != null; +// } //------------------------------------------------------------------------// //-- AttachmentModelAware --// 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 cd2947f..57b98cd 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 @@ -7,14 +7,10 @@ import fr.ifremer.tutti.persistence.entities.data.Attachment; import fr.ifremer.tutti.persistence.entities.data.CopyIndividualObservationMode; import fr.ifremer.tutti.persistence.entities.data.SampleCategory; import fr.ifremer.tutti.persistence.entities.protocol.SpeciesProtocol; -import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocol; 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.DecoratorService; -import fr.ifremer.tutti.service.TuttiDataContext; -import fr.ifremer.tutti.service.cruise.CruiseCache; -import fr.ifremer.tutti.service.sampling.IndividualObservationSamplingCacheRequest; import fr.ifremer.tutti.service.sampling.SamplingCodePrefix; import fr.ifremer.tutti.type.WeightUnit; import fr.ifremer.tutti.ui.swing.content.operation.catches.individualobservation.SamplingCodeCellEditor; @@ -29,7 +25,6 @@ import fr.ifremer.tutti.ui.swing.util.comment.CommentCellEditor; import fr.ifremer.tutti.ui.swing.util.comment.CommentCellRenderer; import jaxx.runtime.SwingUtil; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jdesktop.swingx.JXTable; @@ -38,6 +33,7 @@ import org.jdesktop.swingx.decorator.Highlighter; import org.jdesktop.swingx.table.DefaultTableColumnModelExt; import org.jdesktop.swingx.table.TableColumnExt; import org.jdesktop.swingx.table.TableColumnModelExt; +import org.nuiton.decorator.Decorator; import org.nuiton.jaxx.application.swing.table.ColumnIdentifier; import javax.swing.event.TableModelEvent; @@ -45,13 +41,11 @@ import java.awt.Color; import java.beans.PropertyChangeListener; import java.io.Closeable; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Optional; import java.util.Set; import java.util.function.Function; @@ -67,30 +61,69 @@ public class IndividualObservationBatchTableHandler implements Closeable { /** Logger. */ private static final Log log = LogFactory.getLog(IndividualObservationBatchTableHandler.class); + /** + * Le controleur principal de l'écran. + */ private final SpeciesFrequencyUIHandler uiHandler; + /** + * Le tableau des observations individuelleS. + */ private final JXTable individualObservationTable; - + /** + * Le modèle globale de l'écran. + */ private final SpeciesFrequencyUIModel model; + /** + * Le modèle pour gérer les observations individuelles. + */ + private final IndividualObservationBatchUIModel individualObservationsModel; + /** + * Le modèle du tableau des mensurations. + */ private final SpeciesFrequencyTableModel frequencyTableModel; - private final IndividualObservationBatchUIModel model2; + /** + * Le modèle du tableau des observations individuelles. + */ private final IndividualObservationBatchTableModel individualObservationTableModel; - - private final IndividualObservationUICache individualObservationUICache; + /** + * Le dictionnaire (indexé par identifiant) des caractéristiques de maturités définies dans le protocole. + */ private final Map<String, Caracteristic> maturityCaracteristics; - + /** + * L'identifiant de la colonne de maturité si elle existe. + */ private ColumnIdentifier<IndividualObservationBatchRowModel> maturityColumnId; - + /** + * Décorateur d'espèce. + */ + private final Decorator<Species> speciesDecorator; + /** + * Pour calculer la recopie d'une observation individuelle vers les mensurations. + */ + private final IndividualObservationToFrequencyEngine individualObservationToFrequencyEngine; + /** + * Pour calculer les actions à effectuer sur le cache des échantillons. + */ + private final IndividualObservationToSamplingCacheEngine individualObservationToSamplingCacheEngine; /** * Pour écouter le changement de la taille sur une ligne. */ private final PropertyChangeListener individualObservationRowSizeChangedListener; + /** + * Pour écouter les changement de poids sur une ligne. + */ private final PropertyChangeListener individualObservationRowWeightChangedListener; + /** + * Pour écouter les changement de code de prélèvement sur une ligne. + */ private final PropertyChangeListener individualObservationRowSamplingCodeChangedListener; + /** + * Pour écouter les changement de caractéristiques sur une ligne. + */ private final PropertyChangeListener individualObservationRowCaracteristicsChangedListener; - - private final IndividualObservationToFrequencyEngine individualObservationToFrequencyEngine; - private final IndividualObservationToSamplingCacheResolver individualObservationToSamplingCacheResolver; - + /** + * Pour installer les listener sur chaque ligne d'observation individuelle. + */ private final Function<IndividualObservationBatchRowModel, Void> installListenersOnRow = new Function<IndividualObservationBatchRowModel, Void>() { @Override public Void apply(IndividualObservationBatchRowModel row) { @@ -103,103 +136,20 @@ public class IndividualObservationBatchTableHandler implements Closeable { } }; - private void onSamplingRowChanged(IndividualObservationBatchRowModel row, - IndividualObservationBatchRowState oldValue, - IndividualObservationBatchRowState newValue) { - - IndividualObservationToSamplingCacheResolver.SamplingCacheUpdate samplingCacheUpdate = individualObservationToSamplingCacheResolver.computeSamplingCacheUpdate(oldValue, newValue); - - Optional<IndividualObservationSamplingCacheRequest> optionalAddIndividualObservation = samplingCacheUpdate.getAddIndividualObservationRequest(); - if (optionalAddIndividualObservation.isPresent()) { - individualObservationUICache.addIndividualObservation(optionalAddIndividualObservation.get()); - } - Optional<IndividualObservationSamplingCacheRequest> optionalRemoveIndividualObservation = samplingCacheUpdate.getRemoveIndividualObservationRequest(); - if (optionalRemoveIndividualObservation.isPresent()) { - individualObservationUICache.removeIndividualObservation(optionalRemoveIndividualObservation.get()); - } - Optional<IndividualObservationSamplingCacheRequest> optionalAddSampling = samplingCacheUpdate.getAddSamplingRequest(); - if (optionalAddSampling.isPresent()) { - individualObservationUICache.addSampling(optionalAddSampling.get()); - } - Optional<IndividualObservationSamplingCacheRequest> optionalRemoveSampling = samplingCacheUpdate.getRemoveSamplingRequest(); - if (optionalRemoveSampling.isPresent()) { - individualObservationUICache.removeSampling(optionalRemoveSampling.get()); - } - - // recalcul de la zone de notification - model2.getSamplingNotificationZoneModel().setSelectedRow(row); - - } - - private void onRowChangedForFrequencies(IndividualObservationBatchRowModel row, - IndividualObservationBatchRowState oldValue, - IndividualObservationBatchRowState newValue) { - - Optional<IndividualObservationToFrequencyEngine.FrequencyUpdate> optionalFrequencyUpdate = - individualObservationToFrequencyEngine.computeFrequencyUpdate(model.getCopyIndividualObservationMode(), oldValue, newValue); - - if (optionalFrequencyUpdate.isPresent()) { - - IndividualObservationToFrequencyEngine.FrequencyUpdate frequencyUpdate = optionalFrequencyUpdate.get(); - - Optional<Float> optionalDecrementSize = frequencyUpdate.getDecrementSize(); - if (optionalDecrementSize.isPresent()) { - float lengthStepToDecrement = optionalDecrementSize.get(); - frequencyTableModel.decrementFrequencyRowsNumbers(lengthStepToDecrement); - } - - Optional<Float> optionalIncrementSize = frequencyUpdate.getIncrementSize(); - if (optionalIncrementSize.isPresent()) { - float lengthStepToIncrement = optionalIncrementSize.get(); - frequencyTableModel.incrementFrequencyRowsNumbers(lengthStepToIncrement); - } - - Optional<Pair<Float, Float>> optionalSubstractWeight = frequencyUpdate.getSubstractWeight(); - if (optionalSubstractWeight.isPresent()) { - Pair<Float, Float> substractWeight = optionalSubstractWeight.get(); - float weight = substractWeight.getValue(); - float weightToRemove = frequencyTableModel.convertWeightFromIndividualObservation(weight); - frequencyTableModel.removeWeightToFrequencyRow(substractWeight.getKey(), weightToRemove); - } - - Optional<Pair<Float, Float>> optionalAddWeight = frequencyUpdate.getAddWeight(); - if (optionalAddWeight.isPresent()) { - Pair<Float, Float> addWeight = optionalAddWeight.get(); - float weight = addWeight.getValue(); - float weightToAdd = frequencyTableModel.convertWeightFromIndividualObservation(weight); - frequencyTableModel.addWeightToFrequencyRow(addWeight.getKey(), weightToAdd); - } - - } - - if (individualObservationToFrequencyEngine.isValidStateChanged(oldValue, newValue)) { - - // l'état de validité de la ligne a changé, on recalcule les lignes en erreurs - model2.recomputeRowValidState(row); - - } - - } - public IndividualObservationBatchTableHandler(SpeciesFrequencyUI ui) { this.model = ui.getModel(); - this.model2 = ui.getModel().getIndividualObservationModel(); + this.individualObservationsModel = ui.getModel().getIndividualObservationModel(); this.uiHandler = ui.getHandler(); - TuttiDataContext dataContext = uiHandler.getDataContext(); - Optional<CruiseCache> optionalCruiseCache = dataContext.getOptionalCruiseCache(); - if (!optionalCruiseCache.isPresent()) { - throw new IllegalStateException("Can't find cruise cache"); - } - TuttiProtocol protocol = dataContext.isProtocolFilled() ? dataContext.getProtocol() : null; - this.individualObservationUICache = new IndividualObservationUICache(optionalCruiseCache.get(), model, protocol); + this.speciesDecorator = uiHandler.getDecorator(Species.class, DecoratorService.WITH_SURVEY_CODE_NO_NAME); + this.individualObservationTable = ui.getObsTable(); this.frequencyTableModel = uiHandler.getTableModel(); - this.individualObservationToFrequencyEngine = new IndividualObservationToFrequencyEngine(model2.getIndividualObservationWeightUnit()); - this.individualObservationToSamplingCacheResolver = new IndividualObservationToSamplingCacheResolver(model); + this.individualObservationToFrequencyEngine = new IndividualObservationToFrequencyEngine(model); + this.individualObservationToSamplingCacheEngine = new IndividualObservationToSamplingCacheEngine(model); - List<Caracteristic> maturityCaracteristics = new ArrayList<>(dataContext.getMaturityCaracteristics()); + List<Caracteristic> maturityCaracteristics = new ArrayList<>(uiHandler.getDataContext().getMaturityCaracteristics()); this.maturityCaracteristics = TuttiEntities.splitById(maturityCaracteristics); @@ -211,8 +161,8 @@ public class IndividualObservationBatchTableHandler implements Closeable { Float weight = source.getWeight(); - CaracteristicQualitativeValue maturity = model2.getMaturityValue(source); - CaracteristicQualitativeValue gender = model2.getGender(source); + CaracteristicQualitativeValue maturity = individualObservationsModel.getMaturityValue(source); + CaracteristicQualitativeValue gender = individualObservationsModel.getGender(source); String samplingCode = source.getSamplingCode(); @@ -240,8 +190,8 @@ public class IndividualObservationBatchTableHandler implements Closeable { Float oldWeight = (Float) event.getOldValue(); Float size = source.getSize(); - CaracteristicQualitativeValue maturity = model2.getMaturityValue(source); - CaracteristicQualitativeValue gender = model2.getGender(source); + CaracteristicQualitativeValue maturity = individualObservationsModel.getMaturityValue(source); + CaracteristicQualitativeValue gender = individualObservationsModel.getGender(source); String samplingCode = source.getSamplingCode(); @@ -270,8 +220,8 @@ public class IndividualObservationBatchTableHandler implements Closeable { Float size = source.getSize(); Float weight = source.getWeight(); - CaracteristicQualitativeValue maturity = model2.getMaturityValue(source); - CaracteristicQualitativeValue gender = model2.getGender(source); + CaracteristicQualitativeValue maturity = individualObservationsModel.getMaturityValue(source); + CaracteristicQualitativeValue gender = individualObservationsModel.getGender(source); boolean validState = source.computeValid(); @@ -294,8 +244,8 @@ public class IndividualObservationBatchTableHandler implements Closeable { CaracteristicMap oldCaracteristicMap = (CaracteristicMap) event.getOldValue(); - CaracteristicQualitativeValue oldGender = model2.getGender(oldCaracteristicMap); - CaracteristicQualitativeValue newGender = model2.getGender(source); + CaracteristicQualitativeValue oldGender = individualObservationsModel.getGender(oldCaracteristicMap); + CaracteristicQualitativeValue newGender = individualObservationsModel.getGender(source); if (!Objects.equals(oldGender, newGender)) { @@ -303,7 +253,7 @@ public class IndividualObservationBatchTableHandler implements Closeable { Float size = source.getSize(); Float weight = source.getWeight(); - CaracteristicQualitativeValue maturity = model2.getMaturityValue(source); + CaracteristicQualitativeValue maturity = individualObservationsModel.getMaturityValue(source); String samplingCode = source.getSamplingCode(); boolean validState = source.computeValid(); @@ -312,10 +262,10 @@ public class IndividualObservationBatchTableHandler implements Closeable { IndividualObservationBatchRowState newState = new IndividualObservationBatchRowState(size, weight, maturity, newGender, samplingCode, validState); onSamplingRowChanged(source, oldState, newState); - } else if (model2.withMaturityCaracteristic()) { + } else if (individualObservationsModel.withMaturityCaracteristic()) { - CaracteristicQualitativeValue oldMaturity = model2.getMaturityValue(oldCaracteristicMap); - CaracteristicQualitativeValue newMaturity = model2.getMaturityValue(source); + CaracteristicQualitativeValue oldMaturity = individualObservationsModel.getMaturityValue(oldCaracteristicMap); + CaracteristicQualitativeValue newMaturity = individualObservationsModel.getMaturityValue(source); if (!Objects.equals(oldMaturity, newMaturity)) { @@ -323,7 +273,7 @@ public class IndividualObservationBatchTableHandler implements Closeable { Float size = source.getSize(); Float weight = source.getWeight(); - CaracteristicQualitativeValue gender = model2.getGender(source); + CaracteristicQualitativeValue gender = individualObservationsModel.getGender(source); String samplingCode = source.getSamplingCode(); boolean validState = source.computeValid(); @@ -374,7 +324,7 @@ public class IndividualObservationBatchTableHandler implements Closeable { individualObservationTable); } - List<Caracteristic> defaultCaracteristic = model2.getDefaultCaracteristic(); + List<Caracteristic> defaultCaracteristic = individualObservationsModel.getDefaultCaracteristic(); for (Caracteristic caracteristic : defaultCaracteristic) { uiHandler.addCaracteristicColumnToModel(individualObservationTable, @@ -385,7 +335,7 @@ public class IndividualObservationBatchTableHandler implements Closeable { { // Other caracteristics column Set<Caracteristic> caracteristicsToSkip = Collections.unmodifiableSet( - Sets.newHashSet(model2.getDefaultCaracteristic())); + Sets.newHashSet(individualObservationsModel.getDefaultCaracteristic())); uiHandler.addColumnToModel(columnModel, CaracteristicMapCellComponent.newEditor(ui, caracteristicsToSkip), @@ -398,7 +348,7 @@ public class IndividualObservationBatchTableHandler implements Closeable { // Smapling code column uiHandler.addColumnToModel(columnModel, - SamplingCodeCellEditor.newEditor(ui), + SamplingCodeCellEditor.newEditor(model), SamplingCodeCellRenderer.newRender(), IndividualObservationBatchTableModel.SAMPLING_CODE); @@ -423,6 +373,7 @@ public class IndividualObservationBatchTableHandler implements Closeable { // create table model individualObservationTableModel = new IndividualObservationBatchTableModel(individualObservationWeightUnit, model, columnModel); + individualObservationsModel.setIndividualObservationTableModel(individualObservationTableModel); individualObservationTable.setModel(individualObservationTableModel); individualObservationTable.setColumnModel(columnModel); @@ -467,7 +418,7 @@ public class IndividualObservationBatchTableHandler implements Closeable { } - model2.recomputeRowValidState(newRow); + individualObservationsModel.recomputeRowValidState(newRow); } break; @@ -477,7 +428,7 @@ public class IndividualObservationBatchTableHandler implements Closeable { }); - model2.addPropertyChangeListener(IndividualObservationBatchUIModel.PROPERTY_ROWS, evt -> individualObservationTableModel.setRows((List<IndividualObservationBatchRowModel>) evt.getNewValue())); + individualObservationsModel.addPropertyChangeListener(IndividualObservationBatchUIModel.PROPERTY_ROWS, evt -> individualObservationTableModel.setRows((List<IndividualObservationBatchRowModel>) evt.getNewValue())); // Pour mettre à jour les mensurations suite au changement du mode de recopie des observations individuelles model.addPropertyChangeListener(SpeciesFrequencyUIModel.PROPERTY_COPY_INDIVIDUAL_OBSERVATION_MODE, evt -> { @@ -512,10 +463,10 @@ public class IndividualObservationBatchTableHandler implements Closeable { model.reloadRows(); // On change le mode de recopie sur toutes les observation individuelles - model2.setCopyIndividualObservationMode(newCopyMode); + individualObservationsModel.setCopyIndividualObservationMode(newCopyMode); // Recalcul des mensurations à partir des observations individuelles - uiHandler.reloadRowsFromIndividualObservations(); + frequencyTableModel.reloadRowsFromIndividualObservations(); frequencyTableModel.fireTableDataChanged(); individualObservationTableModel.fireTableDataChanged(); @@ -537,17 +488,8 @@ public class IndividualObservationBatchTableHandler implements Closeable { // on supprime la colonne maturité en fermant, pour avoir les même colonnes qu'à la création de l'écran (important pour la swing session) removeMaturityColumnIfPresent(); - individualObservationUICache.close(); - - } - - public void removeIndividualObservations(Collection<IndividualObservationBatchRowModel> rows) { - - // on supprime les observations individuelles du cache - individualObservationUICache.removeIndividualObservations(rows); - - // on supprime les observations individuelles du model - individualObservationTableModel.removeRows(rows); + model.getIndividualObservationUICache().close(); + model.getSamplingCodeUICache().close(); } @@ -560,36 +502,37 @@ public class IndividualObservationBatchTableHandler implements Closeable { } } - public List<IndividualObservationBatchRowModel> loadIndividualObservations(Species species, List<IndividualObservationBatchRowModel> individualObservations) { + public List<IndividualObservationBatchRowModel> loadRows(Species species, List<IndividualObservationBatchRowModel> individualObservations) { individualObservationTableModel.setSpecies(species); - SamplingCodePrefix samplingCodePrefix = new SamplingCodePrefix(uiHandler.getConfig().getSamplingCodePrefix(), uiHandler.decorate(species, DecoratorService.WITH_SURVEY_CODE_NO_NAME)); - individualObservationTableModel.setSamplingCodePrefix(samplingCodePrefix); + SamplingCodePrefix samplingCodePrefix = new SamplingCodePrefix(uiHandler.getConfig().getSamplingCodePrefix(), speciesDecorator.toString(species)); + individualObservationsModel.setSamplingCodePrefix(samplingCodePrefix); return individualObservationTableModel.loadRows(individualObservations, installListenersOnRow); } - public void editBatch(SpeciesBatchRowModel speciesBatch, List<IndividualObservationBatchRowModel> individualObservationRows, boolean addToCache) { - - CaracteristicMap sampleCategoryValues = new CaracteristicMap(); - Iterator<SampleCategory<?>> iterator = speciesBatch.iterator(); - iterator.forEachRemaining(sampleCategory -> { - Caracteristic caracteristic = sampleCategory.getCategoryDef().getCaracteristic(); - sampleCategoryValues.put(caracteristic, sampleCategory.getCategoryValue()); - }); + public void loadSpeciesBatch(SpeciesBatchRowModel speciesBatch, List<IndividualObservationBatchRowModel> individualObservationRows, boolean addToCache) { - individualObservationTableModel.setDefaultCaracteristicValues(sampleCategoryValues); - model2.setNotEditableCaracteristic(sampleCategoryValues.keySet()); +// CaracteristicMap sampleCategoryValues = new CaracteristicMap(); +// Iterator<SampleCategory<?>> iterator = speciesBatch.iterator(); +// iterator.forEachRemaining(sampleCategory -> { +// Caracteristic caracteristic = sampleCategory.getCategoryDef().getCaracteristic(); +// sampleCategoryValues.put(caracteristic, sampleCategory.getCategoryValue()); +// }); +// +// individualObservationTableModel.setDefaultCaracteristicValues(sampleCategoryValues); +// individualObservationsModel.setNotEditableCaracteristic(sampleCategoryValues.keySet()); - model2.setRows(individualObservationRows); + individualObservationsModel.setRows(individualObservationRows); if (individualObservationRows.isEmpty()) { individualObservationTableModel.addNewRow(); } - model2.recomputeRowsValidateState(); + individualObservationsModel.recomputeRowsValidateState(); - individualObservationUICache.init(speciesBatch.getSpecies(), model2.getRows(), addToCache); + model.getIndividualObservationUICache().init(speciesBatch.getSpecies(), individualObservationsModel.getRows(), addToCache); + model.getSamplingCodeUICache().init(speciesBatch.getSpecies(), individualObservationsModel.getRows(), addToCache); individualObservationTable.packAll(); @@ -600,11 +543,6 @@ public class IndividualObservationBatchTableHandler implements Closeable { && individualObservationTableModel.getRows().get(individualObservationTable.getSelectedRow()).withSamplingCode(); } - - public IndividualObservationUICache getIndividualObservationUICache() { - return individualObservationUICache; - } - public void initMaturityCaracteristic(SpeciesProtocol speciesProtocol) { Caracteristic maturityCaracteristic; @@ -617,7 +555,7 @@ public class IndividualObservationBatchTableHandler implements Closeable { // Add maturity column if necessary - model2.setMaturityCaracteristic(maturityCaracteristic); + individualObservationsModel.setMaturityCaracteristic(maturityCaracteristic); if (maturityCaracteristic != null) { @@ -658,5 +596,48 @@ public class IndividualObservationBatchTableHandler implements Closeable { } + public void initDefaultCaracteristics(SpeciesBatchRowModel speciesBatch) { + + CaracteristicMap sampleCategoryValues = new CaracteristicMap(); + Iterator<SampleCategory<?>> iterator = speciesBatch.iterator(); + iterator.forEachRemaining(sampleCategory -> { + Caracteristic caracteristic = sampleCategory.getCategoryDef().getCaracteristic(); + sampleCategoryValues.put(caracteristic, sampleCategory.getCategoryValue()); + }); + + individualObservationTableModel.setDefaultCaracteristicValues(sampleCategoryValues); + individualObservationsModel.setNotEditableCaracteristic(sampleCategoryValues.keySet()); + + } + + private void onSamplingRowChanged(IndividualObservationBatchRowModel row, + IndividualObservationBatchRowState oldValue, + IndividualObservationBatchRowState newValue) { + + boolean needUpdateSamplingNotificationZone = individualObservationToSamplingCacheEngine.computeSamplingCacheUpdate(oldValue, newValue); + + if (needUpdateSamplingNotificationZone) { + + // recalcul de la zone de notification + individualObservationsModel.getSamplingNotificationZoneModel().setUpdatedRow(row); + + } + + } + + private void onRowChangedForFrequencies(IndividualObservationBatchRowModel row, + IndividualObservationBatchRowState oldValue, + IndividualObservationBatchRowState newValue) { + + boolean needRecomputeRowsValidState = individualObservationToFrequencyEngine.computeFrequencyUpdate(model.getCopyIndividualObservationMode(), oldValue, newValue); + + if (needRecomputeRowsValidState) { + + // l'état de validité de la ligne a changé, on recalcule les lignes en erreurs + individualObservationsModel.recomputeRowValidState(row); + + } + + } } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationBatchTableModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationBatchTableModel.java index 550333b..49fee2d 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationBatchTableModel.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationBatchTableModel.java @@ -27,7 +27,6 @@ import fr.ifremer.tutti.persistence.entities.data.CopyIndividualObservationMode; 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.SamplingCodePrefix; import fr.ifremer.tutti.type.WeightUnit; import fr.ifremer.tutti.ui.swing.util.table.CaracteristicColumnIdentifier; import org.apache.commons.collections4.CollectionUtils; @@ -103,8 +102,6 @@ public class IndividualObservationBatchTableModel extends AbstractApplicationTab protected Species species; - protected SamplingCodePrefix samplingCodePrefix; - protected Caracteristic lengthstepCaracteristic; protected final SpeciesFrequencyUIModel uiModel; @@ -143,13 +140,6 @@ public class IndividualObservationBatchTableModel extends AbstractApplicationTab } } - public void setSamplingCodePrefix(SamplingCodePrefix samplingCodePrefix) { - this.samplingCodePrefix = samplingCodePrefix; - if (rows != null) { - rows.forEach(row -> row.setSamplingCodePrefix(samplingCodePrefix)); - } - } - public void setLengthstepCaracteristic(Caracteristic lengthstepCaracteristic) { this.lengthstepCaracteristic = lengthstepCaracteristic; if (rows != null) { @@ -180,7 +170,6 @@ public class IndividualObservationBatchTableModel extends AbstractApplicationTab result.setValid(false); result.setRankOrder(getRowCount() + 1); result.setSpecies(species); - result.setSamplingCodePrefix(samplingCodePrefix); result.setLengthStepCaracteristic(lengthstepCaracteristic); if (getRowCount() > 0) { @@ -195,17 +184,19 @@ public class IndividualObservationBatchTableModel extends AbstractApplicationTab } } + //FIXME Revoir ça, je comprends pas le but (mais en ayant déplacer le samplingCodePrefix ailleurs cela doit peut-être + //FIXME éviter de faire cela...) // quand l'utilisateur change le prefix dans la conf, si la ligne a deja un code prélèvement, // le prefix reste le même, même si l'utilisateur supprime le code et en regénère un // il faut pousser le nouveau prefix si l'utilisateur supprime le code - result.addPropertyChangeListener(IndividualObservationBatchRowModel.PROPERTY_SAMPLING_CODE, evt -> { - if (result.withSamplingCode() && result.withSamplingCodePrefix()) { - result.setSamplingCodePrefix(new SamplingCodePrefix(result.getSamplingCode())); - - } else if (!result.withSamplingCode()) { - result.setSamplingCodePrefix(samplingCodePrefix); - } - }); +// result.addPropertyChangeListener(IndividualObservationBatchRowModel.PROPERTY_SAMPLING_CODE, evt -> { +// if (result.withSamplingCode() && result.withSamplingCodePrefix()) { +// result.setSamplingCodePrefix(new SamplingCodePrefix(result.getSamplingCode())); +// +// } else if (!result.withSamplingCode()) { +// result.setSamplingCodePrefix(samplingCodePrefix); +// } +// }); return result; } @@ -269,10 +260,11 @@ public class IndividualObservationBatchTableModel extends AbstractApplicationTab newRow.setRankOrder(rankOrder++); newRow.setValid(true); + model.moveGenderValueFromCaracteristicsToDefaultCaracteristics(newRow); model.moveMaturityValueFromCaracteristicsToDefaultCaracteristics(newRow); obsRows.add(newRow); - + individualObservationRowChangedListener.apply(newRow); } @@ -344,7 +336,7 @@ public class IndividualObservationBatchTableModel extends AbstractApplicationTab fireTableRowsDeleted(minSelection, maxSelection); - if (getRowCount() == 0) { + if (rows.isEmpty()) { addNewRow(); } else { @@ -353,4 +345,16 @@ public class IndividualObservationBatchTableModel extends AbstractApplicationTab } + public void clear() { + + if (!rows.isEmpty()) { + + int rowCount = rows.size(); + rows.clear(); + fireTableRowsDeleted(0, rowCount - 1); + addNewRow(); + + } + + } } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationBatchUIModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationBatchUIModel.java index 666646a..5b9cd63 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationBatchUIModel.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationBatchUIModel.java @@ -4,6 +4,7 @@ import fr.ifremer.tutti.persistence.entities.CaracteristicMap; import fr.ifremer.tutti.persistence.entities.data.CopyIndividualObservationMode; import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; +import fr.ifremer.tutti.service.sampling.SamplingCodePrefix; import fr.ifremer.tutti.type.WeightUnit; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.edit.SpeciesBatchRowModel; import fr.ifremer.tutti.ui.swing.util.table.AbstractTuttiTableUIModel; @@ -34,6 +35,7 @@ public class IndividualObservationBatchUIModel extends AbstractTuttiTableUIModel private final WeightUnit individualObservationWeightUnit; + private final SpeciesFrequencyUIModel parentModel; private final Caracteristic sexCaracteristic; /** @@ -55,15 +57,27 @@ public class IndividualObservationBatchUIModel extends AbstractTuttiTableUIModel */ private Collection<Caracteristic> notEditableCaracteristic; + /** + * Le préfixe du code de prélèvement. + * + * @since 4.5 + */ + protected SamplingCodePrefix samplingCodePrefix; + private final SamplingNotificationZoneModel samplingNotificationZoneModel; + private IndividualObservationBatchTableModel individualObservationTableModel; @Override protected SpeciesBatchRowModel newEntity() { return null; // Jamais utilisé! } - public IndividualObservationBatchUIModel(Caracteristic sexCaracteristic, WeightUnit individualObservationWeightUnit, List<Caracteristic> defaultCaracteristic) { + public IndividualObservationBatchUIModel(SpeciesFrequencyUIModel parentModel, + Caracteristic sexCaracteristic, + WeightUnit individualObservationWeightUnit, + List<Caracteristic> defaultCaracteristic) { super(SpeciesBatchRowModel.class, null, null); + this.parentModel = parentModel; this.sexCaracteristic = sexCaracteristic; this.individualObservationWeightUnit = individualObservationWeightUnit; this.defaultCaracteristic = defaultCaracteristic == null ? new ArrayList<>() : new ArrayList<>(defaultCaracteristic); @@ -74,8 +88,12 @@ public class IndividualObservationBatchUIModel extends AbstractTuttiTableUIModel return samplingNotificationZoneModel; } - public WeightUnit getIndividualObservationWeightUnit() { - return individualObservationWeightUnit; + public SamplingCodePrefix getSamplingCodePrefix() { + return samplingCodePrefix; + } + + public void setSamplingCodePrefix(SamplingCodePrefix samplingCodePrefix) { + this.samplingCodePrefix = samplingCodePrefix; } public List<Caracteristic> getDefaultCaracteristic() { @@ -142,6 +160,13 @@ public class IndividualObservationBatchUIModel extends AbstractTuttiTableUIModel result.getDefaultCaracteristics().put(sexCaracteristic, gender); } + public void moveGenderValueFromCaracteristicsToDefaultCaracteristics(IndividualObservationBatchRowModel newRow) { + Serializable caracteristicValue = newRow.getCaracteristics().remove(sexCaracteristic); + if (caracteristicValue != null) { + newRow.getDefaultCaracteristics().putIfAbsent(sexCaracteristic, caracteristicValue); + } + } + public Collection<Caracteristic> getNotEditableCaracteristic() { return notEditableCaracteristic; } @@ -218,4 +243,35 @@ public class IndividualObservationBatchUIModel extends AbstractTuttiTableUIModel } + public void removeIndividualObservations(Collection<IndividualObservationBatchRowModel> rows) { + + // on supprime les observations individuelles des caches + parentModel.getIndividualObservationUICache().removeIndividualObservations(rows); + parentModel.getSamplingCodeUICache().removeIndividualObservations(rows); + + // on supprime les observations individuelles du modèle + individualObservationTableModel.removeRows(rows); + + recomputeCanEditLengthStep(); + recomputeRowsValidateState(); + + } + + public void setIndividualObservationTableModel(IndividualObservationBatchTableModel individualObservationTableModel) { + this.individualObservationTableModel = individualObservationTableModel; + } + + public void clear() { + + // on supprime les observations individuelles des caches + parentModel.getIndividualObservationUICache().removeIndividualObservations(rows); + parentModel.getSamplingCodeUICache().removeIndividualObservations(rows); + + rowsInError.clear(); + individualObservationTableModel.clear(); + + recomputeCanEditLengthStep(); + recomputeRowsValidateState(); + + } } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationToFrequencyEngine.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationToFrequencyEngine.java index c488833..22fd6b7 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationToFrequencyEngine.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationToFrequencyEngine.java @@ -1,6 +1,5 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency; -import com.google.common.base.MoreObjects; import fr.ifremer.tutti.persistence.entities.data.CopyIndividualObservationMode; import fr.ifremer.tutti.type.WeightUnit; import org.apache.commons.lang3.tuple.Pair; @@ -8,7 +7,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.util.Objects; -import java.util.Optional; /** * Pour générer ce qui doit être recopié depuis une observation individuelle vers les mensurations lors d'une @@ -23,109 +21,38 @@ public class IndividualObservationToFrequencyEngine { /** Logger. */ private static final Log log = LogFactory.getLog(IndividualObservationToFrequencyEngine.class); - private final WeightUnit individualObservationWeightUnit; - - public IndividualObservationToFrequencyEngine(WeightUnit individualObservationWeightUnit) { - this.individualObservationWeightUnit = individualObservationWeightUnit; - } - /** - * Ce qui doit être fait sur la table des mensurations suite à une modification d'une observation individuelle. + * Le modèle du tableau des mensurations. */ - public static class FrequencyUpdate { - - /** - * la taille dont il faut décrémenter la classe de taille. - */ - private final Float decrementSize; - /** - * la taille dont il faut incrémenter la classe de taille. - */ - private final Float incrementSize; - - /** - * Le poids à soustraire du poids total de la classe de taille en clef. - */ - private final Pair<Float, Float> substractWeight; - /** - * Le poids à ajouter au poids total de la classe de taille en clef. - */ - private final Pair<Float, Float> addWeight; - - private FrequencyUpdate(Float decrementSize, Float incrementSize, Pair<Float, Float> substractWeight, Pair<Float, Float> addWeight) { - this.decrementSize = decrementSize; - this.incrementSize = incrementSize; - this.substractWeight = substractWeight; - this.addWeight = addWeight; - } - - public Optional<Float> getDecrementSize() { - return Optional.ofNullable(decrementSize); - } - - public Optional<Float> getIncrementSize() { - return Optional.ofNullable(incrementSize); - } - - public Optional<Pair<Float, Float>> getSubstractWeight() { - return Optional.ofNullable(substractWeight); - } - - public Optional<Pair<Float, Float>> getAddWeight() { - return Optional.ofNullable(addWeight); - } - - @Override - public String toString() { - MoreObjects.ToStringHelper toStringHelper = MoreObjects.toStringHelper(this); - if (decrementSize != null) { - toStringHelper.add("decrementSize", decrementSize); - } - if (incrementSize != null) { - toStringHelper.add("incrementSize", incrementSize); - } - if (substractWeight != null) { - toStringHelper.add("substractWeight", substractWeight); - } - if (addWeight != null) { - toStringHelper.add("addWeight", addWeight); - } - return toStringHelper.toString(); - } + private final SpeciesFrequencyTableModel frequencyTableModel; - } + private final WeightUnit individualObservationWeightUnit; + private final WeightUnit frequencyWeightUnit; - public boolean isValidStateChanged(IndividualObservationBatchRowState oldState, - IndividualObservationBatchRowState newState) { - return oldState.isValid() != newState.isValid(); + public IndividualObservationToFrequencyEngine(SpeciesFrequencyUIModel speciesFrequencyUIModel) { + this.individualObservationWeightUnit = speciesFrequencyUIModel.getIndividualObservationWeightUnit(); + this.frequencyWeightUnit = speciesFrequencyUIModel.getWeightUnit(); + this.frequencyTableModel = speciesFrequencyUIModel.getFrequencyTableModel(); } - public Optional<FrequencyUpdate> computeFrequencyUpdate(CopyIndividualObservationMode copyIndividualObservationMode, - IndividualObservationBatchRowState oldState, - IndividualObservationBatchRowState newState) { + public boolean computeFrequencyUpdate(CopyIndividualObservationMode copyIndividualObservationMode, + IndividualObservationBatchRowState oldState, + IndividualObservationBatchRowState newState) { - FrequencyUpdate result; switch (copyIndividualObservationMode) { case ALL: - result = computeFrequencyUpdateForSizeAndWeight(oldState, newState); - if (log.isInfoEnabled()) { - log.info("[Copy Mode All] result: " + result); - } + computeFrequencyUpdateForSizeAndWeight(oldState, newState); + break; case SIZE: - result = computeFrequencyUpdateForSizeOnly(oldState, newState); - if (log.isInfoEnabled()) { - log.info("[Copy Mode Size] result: " + (result == null ? "No size changed." : result)); - } + computeFrequencyUpdateForSizeOnly(oldState, newState); + break; case NOTHING: - if (log.isDebugEnabled()) { - log.debug("[Copy Mode None] Do nothing."); - } - result = null; + break; default: @@ -133,11 +60,11 @@ public class IndividualObservationToFrequencyEngine { } - return Optional.ofNullable(result); + return oldState.isValid() != newState.isValid(); } - public FrequencyUpdate computeFrequencyUpdateForSizeOnly(IndividualObservationBatchRowState oldState, IndividualObservationBatchRowState newState) { + public void computeFrequencyUpdateForSizeOnly(IndividualObservationBatchRowState oldState, IndividualObservationBatchRowState newState) { Objects.requireNonNull(oldState); Objects.requireNonNull(newState); @@ -146,8 +73,6 @@ public class IndividualObservationToFrequencyEngine { Float newSize = newState.getSize(); boolean sizeChanged = !Objects.equals(oldSize, newSize); - FrequencyUpdate frequencyUpdate; - if (sizeChanged) { Float decrementSize = null; @@ -161,19 +86,13 @@ public class IndividualObservationToFrequencyEngine { incrementSize = newSize; } - frequencyUpdate = new FrequencyUpdate(decrementSize, incrementSize, null, null); - - } else { - - frequencyUpdate = null; + apply(decrementSize, incrementSize, null, null); } - return frequencyUpdate; - } - public FrequencyUpdate computeFrequencyUpdateForSizeAndWeight(IndividualObservationBatchRowState oldState, IndividualObservationBatchRowState newState) { + public void computeFrequencyUpdateForSizeAndWeight(IndividualObservationBatchRowState oldState, IndividualObservationBatchRowState newState) { Objects.requireNonNull(oldState); Objects.requireNonNull(newState); @@ -189,7 +108,7 @@ public class IndividualObservationToFrequencyEngine { if (!sizeChanged && !weightChanged) { // ce cas limite peut arrive quand on passe de null à null - return null; + return; } @@ -264,7 +183,53 @@ public class IndividualObservationToFrequencyEngine { } - return new FrequencyUpdate(decrementSize, incrementSize, substractWeight, addWeight); + apply(decrementSize, incrementSize, substractWeight, addWeight); + + } + + private void apply(Float lengthStepToDecrement, Float lengthStepToIncrement, Pair<Float, Float> substractWeight, Pair<Float, Float> addWeight) { + + if (lengthStepToDecrement != null) { + + if (log.isInfoEnabled()) { + log.info("Decrements frequency rows number for length class: " + lengthStepToDecrement); + } + frequencyTableModel.decrementFrequencyRowsNumbers(lengthStepToDecrement); + + } + + if (lengthStepToIncrement != null) { + + if (log.isInfoEnabled()) { + log.info("Increments frequency rows number for length class: " + lengthStepToDecrement); + } + frequencyTableModel.incrementFrequencyRowsNumbers(lengthStepToIncrement); + + } + + if (substractWeight != null) { + + float weight = substractWeight.getValue(); + float weightToRemove = frequencyTableModel.convertWeightFromIndividualObservation(weight); + Float lengthClass = substractWeight.getKey(); + if (log.isInfoEnabled()) { + log.info("Substract weight: " + weightToRemove + frequencyWeightUnit.getShortLabel() + " for length class: " + lengthClass); + } + frequencyTableModel.removeWeightToFrequencyRow(lengthClass, weightToRemove); + + } + + if (addWeight != null) { + + float weight = addWeight.getValue(); + float weightToAdd = frequencyTableModel.convertWeightFromIndividualObservation(weight); + Float lengthClass = addWeight.getKey(); + if (log.isInfoEnabled()) { + log.info("Add weight: " + weightToAdd + frequencyWeightUnit.getShortLabel() + " for length class: " + lengthClass); + } + frequencyTableModel.addWeightToFrequencyRow(lengthClass, weightToAdd); + + } } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationToSamplingCacheEngine.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationToSamplingCacheEngine.java new file mode 100644 index 0000000..ad0f64a --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationToSamplingCacheEngine.java @@ -0,0 +1,119 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency; + +import fr.ifremer.tutti.service.sampling.IndividualObservationSamplingCacheRequest; + +import java.util.Objects; + +/** + * Pour effectuer depuis une modification ou sélection d'une observation individuelle, les actions sur les caches. + * + * Created on 20/04/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class IndividualObservationToSamplingCacheEngine { + + private final SpeciesFrequencyUIModel speciesFrequencyUIModel; + private final IndividualObservationUICache individualObservationUICache; + private final SamplingCodeUICache samplingCodeUICache; + + public IndividualObservationToSamplingCacheEngine(SpeciesFrequencyUIModel speciesFrequencyUIModel) { + + this.speciesFrequencyUIModel = speciesFrequencyUIModel; + this.individualObservationUICache = speciesFrequencyUIModel.getIndividualObservationUICache(); + this.samplingCodeUICache = speciesFrequencyUIModel.getSamplingCodeUICache(); + + } + + public boolean computeSamplingCacheUpdate(IndividualObservationBatchRowState oldState, IndividualObservationBatchRowState newState) { + + IndividualObservationSamplingCacheRequest addIndividualObservation = null; + IndividualObservationSamplingCacheRequest removeIndividualObservation = null; + IndividualObservationSamplingCacheRequest addSamplingAction = null; + IndividualObservationSamplingCacheRequest removeSamplingAction = null; + IndividualObservationSamplingCacheRequest addSamplingCodeAction = null; + IndividualObservationSamplingCacheRequest removeSamplingCodeAction = null; + + boolean sizeChanged = !Objects.equals(oldState.getSize(), newState.getSize()); + boolean maturityChanged = !Objects.equals(oldState.getMaturity(), newState.getMaturity()); + boolean genderChanged = !Objects.equals(oldState.getGender(), newState.getGender()); + boolean samplingCodeChanged = !Objects.equals(oldState.getSamplingCode(), newState.getSamplingCode()); + boolean withOldSamplingCode = oldState.withSamplingCode(); + boolean withNewSamplingCode = newState.withSamplingCode(); + + if (sizeChanged || maturityChanged || genderChanged) { + + removeIndividualObservation = toRequest(oldState); + if (withOldSamplingCode) { + removeSamplingAction = toRequest(oldState); + } + addIndividualObservation = toRequest(newState); + if (withNewSamplingCode) { + addSamplingAction = toRequest(newState); + } + + } else if (samplingCodeChanged) { + + boolean removeSampling = withOldSamplingCode && !withNewSamplingCode; + boolean addSampling = withNewSamplingCode && !withOldSamplingCode; + + if (removeSampling) { + + removeSamplingAction = toRequest(oldState); + + } else if (addSampling) { + + addSamplingAction = toRequest(newState); + + } else { + + removeSamplingCodeAction = toRequest(oldState); + addSamplingCodeAction = toRequest(newState); + + } + + } + + boolean actionDone = false; + if (removeIndividualObservation != null) { + individualObservationUICache.removeIndividualObservation(removeIndividualObservation); + actionDone=true; + } + if (addIndividualObservation != null) { + individualObservationUICache.addIndividualObservation(addIndividualObservation); + actionDone=true; + } + if (removeSamplingAction != null) { + individualObservationUICache.removeSampling(removeSamplingAction); + samplingCodeUICache.removeSampling(removeSamplingAction); + actionDone=true; + } + if (addSamplingAction != null) { + individualObservationUICache.addSampling(addSamplingAction); + samplingCodeUICache.addSampling(addSamplingAction); + actionDone=true; + } + if (removeSamplingCodeAction != null) { + samplingCodeUICache.removeSampling(removeSamplingCodeAction); + actionDone=true; + } + if (addSamplingCodeAction != null) { + samplingCodeUICache.addSampling(addSamplingCodeAction); + actionDone=true; + } + + return actionDone; + + } + + private IndividualObservationSamplingCacheRequest toRequest(IndividualObservationBatchRowState state) { + + return new IndividualObservationSamplingCacheRequest(speciesFrequencyUIModel.getFishingOperation(), + speciesFrequencyUIModel.getBatch().getSpecies(), + speciesFrequencyUIModel.getLengthStepInMm(state.getSize()), + state.getMaturity(), + state.getGender(), + state.getSamplingCode()); + } + +} diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationToSamplingCacheResolver.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationToSamplingCacheResolver.java deleted file mode 100644 index 2d8b5f8..0000000 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/IndividualObservationToSamplingCacheResolver.java +++ /dev/null @@ -1,147 +0,0 @@ -package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency; - -import com.google.common.base.MoreObjects; -import fr.ifremer.tutti.service.sampling.IndividualObservationSamplingCacheRequest; - -import java.util.Objects; -import java.util.Optional; - -/** - * Pour déduire depuis une modification sur une observation individuelle, ce qui doit être fait sur le cache - * des prélèvements. - * - * Created on 20/04/16. - * - * @author Tony Chemit - chemit@codelutin.com - */ -public class IndividualObservationToSamplingCacheResolver { - - private final SpeciesFrequencyUIModel speciesFrequencyUIModel; - - public IndividualObservationToSamplingCacheResolver(SpeciesFrequencyUIModel speciesFrequencyUIModel) { - - this.speciesFrequencyUIModel = speciesFrequencyUIModel; - } - - /** - * Ce qui doit être fait sur la table des mensurations suite à une modification d'une observation individuelle. - */ - public static class SamplingCacheUpdate { - - /** - * Pour ajouter une observation individuelle du cache. - */ - private final IndividualObservationSamplingCacheRequest addIndividualObservationRequest; - /** - * Pour supprimer une observation individuelle du cache. - */ - private final IndividualObservationSamplingCacheRequest removeIndividualObservationRequest; - - /** - * Pour ajouter un prélèvement dans le cache. - */ - private final IndividualObservationSamplingCacheRequest addSamplingRequest; - /** - * Pour supprimer un prélèvement du cache. - */ - private final IndividualObservationSamplingCacheRequest removeSamplingRequest; - - public SamplingCacheUpdate(IndividualObservationSamplingCacheRequest addIndividualObservationRequest, - IndividualObservationSamplingCacheRequest removeIndividualObservationRequest, - IndividualObservationSamplingCacheRequest addSamplingRequest, - IndividualObservationSamplingCacheRequest removeSamplingRequest) { - this.addIndividualObservationRequest = addIndividualObservationRequest; - this.removeIndividualObservationRequest = removeIndividualObservationRequest; - this.addSamplingRequest = addSamplingRequest; - this.removeSamplingRequest = removeSamplingRequest; - } - - public Optional<IndividualObservationSamplingCacheRequest> getAddIndividualObservationRequest() { - return Optional.ofNullable(addIndividualObservationRequest); - } - - public Optional<IndividualObservationSamplingCacheRequest> getRemoveIndividualObservationRequest() { - return Optional.ofNullable(removeIndividualObservationRequest); - } - - public Optional<IndividualObservationSamplingCacheRequest> getAddSamplingRequest() { - return Optional.ofNullable(addSamplingRequest); - } - - public Optional<IndividualObservationSamplingCacheRequest> getRemoveSamplingRequest() { - return Optional.ofNullable(removeSamplingRequest); - } - - @Override - public String toString() { - MoreObjects.ToStringHelper toStringHelper = MoreObjects.toStringHelper(this); - if (addIndividualObservationRequest != null) { - toStringHelper.add("addIndividualObservationRequest", addIndividualObservationRequest); - } - if (removeIndividualObservationRequest != null) { - toStringHelper.add("removeIndividualObservationRequest", removeIndividualObservationRequest); - } - if (addSamplingRequest != null) { - toStringHelper.add("addSamplingRequest", addSamplingRequest); - } - if (removeSamplingRequest != null) { - toStringHelper.add("removeSamplingRequest", removeSamplingRequest); - } - return toStringHelper.toString(); - } - - } - - public SamplingCacheUpdate computeSamplingCacheUpdate(IndividualObservationBatchRowState oldState, - IndividualObservationBatchRowState newState) { - - IndividualObservationSamplingCacheRequest addIndividualObservation = null; - IndividualObservationSamplingCacheRequest removeIndividualObservation = null; - IndividualObservationSamplingCacheRequest addSamplingAction = null; - IndividualObservationSamplingCacheRequest removeSamplingAction = null; - - boolean sizeChanged = !Objects.equals(oldState.getSize(), newState.getSize()); - boolean maturityChanged = !Objects.equals(oldState.getMaturity(), newState.getMaturity()); - boolean genderChanged = !Objects.equals(oldState.getGender(), newState.getGender()); - boolean samplingCodeChanged = !Objects.equals(oldState.getSamplingCode(), newState.getSamplingCode()); - - if (sizeChanged || maturityChanged || genderChanged) { - - removeIndividualObservation = toRequest(oldState); - addIndividualObservation = toRequest(newState); - - } else if (samplingCodeChanged) { - - boolean withOldSamplingCode = oldState.withSamplingCode(); - boolean withNewSamplingCode = newState.withSamplingCode(); - - boolean removeSampling = withOldSamplingCode && !withNewSamplingCode; - boolean addSampling = withNewSamplingCode && !withOldSamplingCode; - - if (removeSampling) { - - removeSamplingAction = toRequest(oldState); - - } else if (addSampling) { - - addSamplingAction = toRequest(newState); - - } - - } - - return new SamplingCacheUpdate(addIndividualObservation, removeIndividualObservation, addSamplingAction, removeSamplingAction); - - } - - private IndividualObservationSamplingCacheRequest toRequest(IndividualObservationBatchRowState state) { - - return new IndividualObservationSamplingCacheRequest(speciesFrequencyUIModel.getFishingOperation(), - speciesFrequencyUIModel.getBatch().getSpecies(), - speciesFrequencyUIModel.getLengthStepInMm(state.getSize()), - state.getMaturity(), - state.getGender(), - state.getSamplingCode()); - } - -} 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 e71827f..dac9edd 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 @@ -24,7 +24,6 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency; * #L% */ -import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocol; import fr.ifremer.tutti.persistence.entities.protocol.Zone; import fr.ifremer.tutti.persistence.entities.referential.Species; import fr.ifremer.tutti.service.cruise.CruiseCache; @@ -32,20 +31,14 @@ import fr.ifremer.tutti.service.sampling.CalcifiedPiecesSamplingAlgorithmEntryNo import fr.ifremer.tutti.service.sampling.CruiseSamplingCache; import fr.ifremer.tutti.service.sampling.IndividualObservationSamplingCacheRequest; 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.SizeNotDefinedOnIndividualObservationException; import fr.ifremer.tutti.service.sampling.ZoneNotDefinedOnFishingOperationException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import java.io.Closeable; import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.Optional; -import java.util.Set; -import java.util.TreeSet; /** * Cache des observations individuelles. @@ -58,55 +51,36 @@ import java.util.TreeSet; */ public class IndividualObservationUICache implements Closeable { - /** Logger. */ - private static final Log log = LogFactory.getLog(IndividualObservationUICache.class); - private final CruiseSamplingCache cruiseSamplingCache; - private final SamplingCodeCache samplingCodeCache; - private final boolean useCruiseSamplingCache; - private final boolean protocolFilled; - private final boolean protocolUseCalcifiedPieceSampling; - private boolean speciesDefinedInCalcifiedPiecesSampling; - private final SpeciesFrequencyUIModel uiModel; - private final IndividualObservationBatchUIModel individualObservationModel; + private boolean speciesDefinedInCalcifiedPiecesSampling; private Zone fishingOperationZone; - private Integer speciesReferenceTaxonId; - - /** - * Contient les codes de prélèvements qu'on sait non utilisables. - * - * Au chargement de l'écran, on remplit cet ensemble avec les codes des observations individuelles du lot. - */ - private final Set<Integer> samplingCodesNotAvailable = new TreeSet<>(); - /** - * Contient les codes de prélèvements qu'on sait utilisables. - * - * Dès qu'un code de prélèvement est ajouté ou modifié dans l'écran, on l'ajoute ici. - */ - private final Set<Integer> samplingCodesAvailable = new TreeSet<>(); - - public IndividualObservationUICache(CruiseCache cruiseCache, SpeciesFrequencyUIModel uiModel, TuttiProtocol protocol) { + + public IndividualObservationUICache(CruiseCache cruiseCache, SpeciesFrequencyUIModel uiModel) { this.useCruiseSamplingCache = cruiseCache.useSamplingCache(); this.cruiseSamplingCache = cruiseCache.getSamplingCruiseCache().orElse(null); - this.samplingCodeCache = cruiseCache.getSamplingCodeCache(); this.uiModel = uiModel; - this.individualObservationModel = uiModel.getIndividualObservationModel(); - this.protocolFilled = protocol != null; - this.protocolUseCalcifiedPieceSampling = protocolFilled && protocol.isUseCalcifiedPieceSampling(); } public boolean useCruiseSamplingCache() { return useCruiseSamplingCache; } - public void init(Species species, List<IndividualObservationBatchRowModel> individualObservationRows, boolean addToCache) { + public boolean isSpeciesDefinedInCalcifiedPiecesSampling() { + return speciesDefinedInCalcifiedPiecesSampling; + } + + public boolean isFishingOperationWithZone() { + return fishingOperationZone != null; + } + + public void init(Species species, List<IndividualObservationBatchRowModel> individualObservations, boolean addToCache) { Objects.requireNonNull(species); + Objects.requireNonNull(individualObservations); - this.speciesReferenceTaxonId = species.getReferenceTaxonId(); if (useCruiseSamplingCache) { // calcule de la zone associée à l'opération de pêche @@ -118,82 +92,56 @@ public class IndividualObservationUICache implements Closeable { } - this.samplingCodesAvailable.clear(); - this.samplingCodesNotAvailable.clear(); - if (addToCache) { - addIndividualObservations(individualObservationRows); + addIndividualObservations(individualObservations); - } else { - individualObservationRows.stream() - .filter(individualObservationRow -> individualObservationRow.getSamplingCode() != null) - .forEach(individualObservationRow -> addSamplingCodeNotAvailable(individualObservationRow.getSamplingCode())); } - } - public boolean isFishingOperationWithZone() { - return fishingOperationZone != null; - } - - public boolean isProtocolFilled() { - return protocolFilled; - } - - public boolean isProtocolUseCalcifiedPieceSampling() { - return protocolUseCalcifiedPieceSampling; - } - - public boolean isSpeciesDefinedInCalcifiedPiecesSampling() { - return speciesDefinedInCalcifiedPiecesSampling; } @Override public void close() { - this.speciesReferenceTaxonId = null; + this.fishingOperationZone = null; } public IndividualObservationSamplingStatus getIndividualObservationSamplingStatus(IndividualObservationBatchRowModel row) throws CalcifiedPiecesSamplingAlgorithmEntryNotFoundException, SizeNotDefinedOnIndividualObservationException, ZoneNotDefinedOnFishingOperationException { Objects.requireNonNull(row); - IndividualObservationSamplingCacheRequest samplingCacheRequest = toIndividualObservationSamplingCacheRequest(row); + IndividualObservationSamplingCacheRequest samplingCacheRequest = uiModel.toSamplingCacheRequest(row); return cruiseSamplingCache.getIndividualObservationSamplingStatus(samplingCacheRequest); } - public void removeIndividualObservations(Collection<IndividualObservationBatchRowModel> individualObservationBatchRows) { + public void addIndividualObservations(Collection<IndividualObservationBatchRowModel> individualObservationRows) { - individualObservationBatchRows.stream() - .filter(IndividualObservationBatchRowModel::withSize) - .forEach(row -> { + Objects.requireNonNull(individualObservationRows); - IndividualObservationSamplingCacheRequest samplingCacheRequest = toIndividualObservationSamplingCacheRequest(row); - removeIndividualObservation(samplingCacheRequest); + individualObservationRows.stream() + .filter(IndividualObservationBatchRowModel::withSize) + .forEach(row -> { - }); + IndividualObservationSamplingCacheRequest samplingCacheRequest = uiModel.toSamplingCacheRequest(row); + addIndividualObservation(samplingCacheRequest); + + }); } - public void addIndividualObservations(Collection<IndividualObservationBatchRowModel> individualObservationBatchRows) { - - individualObservationBatchRows.stream() - .filter(IndividualObservationBatchRowModel::withSize) - .forEach(row -> { + public void removeIndividualObservations(Collection<IndividualObservationBatchRowModel> individualObservationRows) { - IndividualObservationSamplingCacheRequest samplingCacheRequest = toIndividualObservationSamplingCacheRequest(row); - addIndividualObservation(samplingCacheRequest); + Objects.requireNonNull(individualObservationRows); - }); + individualObservationRows.stream() + .filter(IndividualObservationBatchRowModel::withSize) + .forEach(row -> { - } + IndividualObservationSamplingCacheRequest samplingCacheRequest = uiModel.toSamplingCacheRequest(row); + removeIndividualObservation(samplingCacheRequest); - public boolean isSamplingCodeNotAvailable(int samplingCode) { - return samplingCodesNotAvailable.contains(samplingCode); - } + }); - public boolean isSamplingCodeAvailable(int samplingCode) { - return samplingCodesAvailable.contains(samplingCode); } public void addIndividualObservation(IndividualObservationSamplingCacheRequest samplingCacheRequest) { @@ -206,12 +154,6 @@ public class IndividualObservationUICache implements Closeable { } - if (samplingCacheRequest.withSamplingCode()) { - - addSampling0(samplingCacheRequest, false); - - } - } public void removeIndividualObservation(IndividualObservationSamplingCacheRequest samplingCacheRequest) { @@ -224,61 +166,16 @@ public class IndividualObservationUICache implements Closeable { } - if (samplingCacheRequest.withSamplingCode()) { - - removeSampling0(samplingCacheRequest, false); - - } - } public void addSampling(IndividualObservationSamplingCacheRequest samplingCacheRequest) { - addSampling0(samplingCacheRequest, true); - - } - - public void removeSampling(IndividualObservationSamplingCacheRequest samplingCacheRequest) { - - removeSampling0(samplingCacheRequest, true); - - } - - private void addSamplingCodeAvailable(String samplingCode) { - - int samplingCodeNumber = SamplingCodePrefix.extractSamplingCodeIdFromSamplingCode(samplingCode); - if (log.isDebugEnabled()) { - log.debug(String.format("Make samplingCode: %s (%d) available", samplingCode, samplingCodeNumber)); - } - samplingCodesNotAvailable.remove(samplingCodeNumber); - samplingCodesAvailable.add(samplingCodeNumber); - - } - - private void addSamplingCodeNotAvailable(String samplingCode) { - - int samplingCodeNumber = SamplingCodePrefix.extractSamplingCodeIdFromSamplingCode(samplingCode); - if (log.isDebugEnabled()) { - log.debug(String.format("Make samplingCode: %s (%d) not available", samplingCode, samplingCodeNumber)); - } - samplingCodesNotAvailable.add(samplingCodeNumber); - samplingCodesAvailable.remove(samplingCodeNumber); - - } - - private void addSampling0(IndividualObservationSamplingCacheRequest samplingCacheRequest, boolean addToCruiseSamplingCache) { - Objects.requireNonNull(samplingCacheRequest); String samplingCode = samplingCacheRequest.getSamplingCode(); Objects.requireNonNull(samplingCode); - samplingCodeCache.addSamplingCode(speciesReferenceTaxonId, samplingCode); - - // Le code n'est plus utilisable - addSamplingCodeNotAvailable(samplingCode); - - if (addToCruiseSamplingCache && useCruiseSamplingCache && samplingCacheRequest.withLengthClass()) { + if (useCruiseSamplingCache && samplingCacheRequest.withLengthClass()) { cruiseSamplingCache.addSampling(samplingCacheRequest); @@ -286,19 +183,14 @@ public class IndividualObservationUICache implements Closeable { } - private void removeSampling0(IndividualObservationSamplingCacheRequest samplingCacheRequest, boolean removeFromCruiseSamplingCache) { + public void removeSampling(IndividualObservationSamplingCacheRequest samplingCacheRequest) { Objects.requireNonNull(samplingCacheRequest); String samplingCode = samplingCacheRequest.getSamplingCode(); Objects.requireNonNull(samplingCode); - samplingCodeCache.removeSamplingCode(speciesReferenceTaxonId, samplingCode); - - // Le code est réutilisable - addSamplingCodeAvailable(samplingCode); - - if (removeFromCruiseSamplingCache && useCruiseSamplingCache && samplingCacheRequest.withLengthClass()) { + if (useCruiseSamplingCache && samplingCacheRequest.withLengthClass()) { cruiseSamplingCache.removeSampling(samplingCacheRequest); @@ -306,14 +198,4 @@ public class IndividualObservationUICache implements Closeable { } - private IndividualObservationSamplingCacheRequest toIndividualObservationSamplingCacheRequest(IndividualObservationBatchRowModel row) { - - return new IndividualObservationSamplingCacheRequest(uiModel.getFishingOperation(), - row.getSpecies(), - uiModel.getLengthStepInMm(row.getSize()), - individualObservationModel.getMaturityValue(row), - individualObservationModel.getGender(row), - row.getSamplingCode()); - - } } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SamplingCodeUICache.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SamplingCodeUICache.java new file mode 100644 index 0000000..6a71cdb --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SamplingCodeUICache.java @@ -0,0 +1,230 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency; + +import fr.ifremer.tutti.persistence.entities.referential.Species; +import fr.ifremer.tutti.service.sampling.IndividualObservationSamplingCacheRequest; +import fr.ifremer.tutti.service.sampling.SamplingCodeCache; +import fr.ifremer.tutti.service.sampling.SamplingCodePrefix; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.Closeable; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.TreeSet; + +import static fr.ifremer.tutti.persistence.service.TuttiPersistenceServiceLocator.getPersistenceService; + +/** + * Pour gérer le cache des codes de prélèvements. + * + * Created on 23/04/16. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.5 + */ +public class SamplingCodeUICache implements Closeable { + + /** Logger. */ + private static final Log log = LogFactory.getLog(SamplingCodeUICache.class); + + private final SpeciesFrequencyUIModel uiModel; + + private final Integer cruiseId; + + private final SamplingCodeCache samplingCodeCache; + + /** + * Contient les codes de prélèvements qu'on sait non utilisables. + * + * Au chargement de l'écran, on remplit cet ensemble avec les codes des observations individuelles du lot. + */ + private final Set<Integer> samplingCodesNotAvailable = new TreeSet<>(); + /** + * Contient les codes de prélèvements qu'on sait utilisables. + * + * Dès qu'un code de prélèvement est ajouté ou modifié dans l'écran, on l'ajoute ici. + */ + private final Set<Integer> samplingCodesAvailable = new TreeSet<>(); + + /** + * La code référent du taxon du lot en cours d'édition. + */ + private Integer speciesReferenceTaxonId; + + public SamplingCodeUICache(SamplingCodeCache samplingCodeCache, SpeciesFrequencyUIModel uiModel, Integer cruiseId) { + this.samplingCodeCache = samplingCodeCache; + this.uiModel = uiModel; + this.cruiseId = cruiseId; + } + + public void init(Species species, List<IndividualObservationBatchRowModel> individualObservations, boolean addToCache) { + + Objects.requireNonNull(species); + Objects.requireNonNull(individualObservations); + + this.speciesReferenceTaxonId = species.getReferenceTaxonId(); + + this.samplingCodesAvailable.clear(); + this.samplingCodesNotAvailable.clear(); + + if (addToCache) { + + addIndividualObservations(individualObservations); + + } else { + + individualObservations.stream() + .filter(individualObservationRow -> individualObservationRow.getSamplingCode() != null) + .forEach(individualObservationRow -> addSamplingCodeNotAvailable(individualObservationRow.getSamplingCode())); + + } + } + + @Override + public void close() { + this.samplingCodesNotAvailable.clear(); + this.samplingCodesAvailable.clear(); + this.speciesReferenceTaxonId = null; + } + + public void addIndividualObservations(Collection<IndividualObservationBatchRowModel> individualObservations) { + + Objects.requireNonNull(individualObservations); + + individualObservations.stream() + .filter(IndividualObservationBatchRowModel::withSamplingCode) + .forEach(row -> { + + IndividualObservationSamplingCacheRequest samplingCacheRequest = uiModel.toSamplingCacheRequest(row); + addSampling(samplingCacheRequest); + + }); + + } + + public void removeIndividualObservations(Collection<IndividualObservationBatchRowModel> individualObservations) { + + Objects.requireNonNull(individualObservations); + + individualObservations.stream() + .filter(IndividualObservationBatchRowModel::withSamplingCode) + .forEach(row -> { + + IndividualObservationSamplingCacheRequest samplingCacheRequest = uiModel.toSamplingCacheRequest(row); + removeSampling(samplingCacheRequest); + + }); + + } + + public boolean canUseSamplingCode(Integer sampleCode) { + + if (isSamplingCodeNotAvailable(sampleCode)) { + + // le code n'est pas disponible (on le sait depuis le cache de l'écran) + if (log.isDebugEnabled()) { + log.debug("Sampling code " + sampleCode + " is known as not available from cache. Can't use it."); + } + return false; + } + + if (isSamplingCodeAvailable(sampleCode)) { + + // le code est pas disponible (on le sait depuis le cache de l'écran) + if (log.isDebugEnabled()) { + log.debug("Sampling code " + sampleCode + " is known as available from cache. Can use it."); + } + return true; + } + + // on demande en base si le code est disponible + + String samplingCodeSuffix = uiModel.getIndividualObservationModel().getSamplingCodePrefix().toSpeciesOnlySamplingCode(sampleCode); + boolean samplingCodeAvailable = getPersistenceService().isSamplingCodeAvailable(cruiseId, + speciesReferenceTaxonId, + samplingCodeSuffix); + + if (log.isDebugEnabled()) { + if (samplingCodeAvailable) { + log.debug("Sampling code " + sampleCode + " is known as available from database. Can use it."); + } else { + log.debug("Sampling code " + sampleCode + " is known as not available from database. Can't use it."); + } + } + + return samplingCodeAvailable; + + } + + public int getNextSamplingCodeId() { + + int nextSamplingCodeId = samplingCodeCache.getNextSamplingCodeId(speciesReferenceTaxonId); + + if (log.isInfoEnabled()) { + log.info("Generated sampling code: " + nextSamplingCodeId); + } + return nextSamplingCodeId; + + } + + public void addSampling(IndividualObservationSamplingCacheRequest samplingCacheRequest) { + + Objects.requireNonNull(samplingCacheRequest); + + String samplingCode = samplingCacheRequest.getSamplingCode(); + Objects.requireNonNull(samplingCode); + + samplingCodeCache.addSamplingCode(speciesReferenceTaxonId, samplingCode); + + // Le code n'est plus utilisable + addSamplingCodeNotAvailable(samplingCode); + + } + + public void removeSampling(IndividualObservationSamplingCacheRequest samplingCacheRequest) { + + Objects.requireNonNull(samplingCacheRequest); + + String samplingCode = samplingCacheRequest.getSamplingCode(); + Objects.requireNonNull(samplingCode); + + samplingCodeCache.removeSamplingCode(speciesReferenceTaxonId, samplingCode); + + // Le code est réutilisable + addSamplingCodeAvailable(samplingCode); + + } + + private boolean isSamplingCodeNotAvailable(int samplingCode) { + return samplingCodesNotAvailable.contains(samplingCode); + } + + private boolean isSamplingCodeAvailable(int samplingCode) { + return samplingCodesAvailable.contains(samplingCode); + } + + private void addSamplingCodeAvailable(String samplingCode) { + + int samplingCodeNumber = SamplingCodePrefix.extractSamplingCodeIdFromSamplingCode(samplingCode); + if (log.isDebugEnabled()) { + log.debug(String.format("Make samplingCode: %s (%d) available", samplingCode, samplingCodeNumber)); + } + samplingCodesNotAvailable.remove(samplingCodeNumber); + samplingCodesAvailable.add(samplingCodeNumber); + + } + + private void addSamplingCodeNotAvailable(String samplingCode) { + + int samplingCodeNumber = SamplingCodePrefix.extractSamplingCodeIdFromSamplingCode(samplingCode); + if (log.isDebugEnabled()) { + log.debug(String.format("Make samplingCode: %s (%d) not available", samplingCode, samplingCodeNumber)); + } + samplingCodesNotAvailable.add(samplingCodeNumber); + samplingCodesAvailable.remove(samplingCodeNumber); + + } + +} diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SamplingNotificationZoneHandler.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SamplingNotificationZoneHandler.java index d643d78..09da2bb 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SamplingNotificationZoneHandler.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SamplingNotificationZoneHandler.java @@ -1,6 +1,7 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency; import com.google.common.base.Preconditions; +import fr.ifremer.tutti.persistence.entities.data.SpeciesBatch; import fr.ifremer.tutti.persistence.entities.protocol.CalcifiedPiecesSamplingDefinition; import fr.ifremer.tutti.persistence.entities.protocol.Zone; import fr.ifremer.tutti.persistence.entities.referential.Species; @@ -10,7 +11,6 @@ import fr.ifremer.tutti.service.sampling.IndividualObservationSamplingContext; import fr.ifremer.tutti.service.sampling.IndividualObservationSamplingStatus; 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; @@ -22,6 +22,7 @@ import javax.swing.event.ListSelectionListener; import java.awt.Color; import java.beans.PropertyChangeListener; import java.io.Closeable; +import java.util.Objects; import static org.nuiton.i18n.I18n.t; @@ -50,6 +51,7 @@ public class SamplingNotificationZoneHandler implements Closeable { private final ListSelectionListener listSelectionListener; private final PropertyChangeListener modelSummaryTextChanged; private final PropertyChangeListener modelSelectedRowChanged; + private final PropertyChangeListener modelUpdatedRowChanged; private final PropertyChangeListener modelStatusChanged; private final Decorator<Integer> infiniteDecorator; @@ -59,7 +61,7 @@ public class SamplingNotificationZoneHandler implements Closeable { private final Color colorHighlightInfoForeground; private final Color colorHighlightInfoBackground; - public SamplingNotificationZoneHandler(SpeciesFrequencyUI ui, SamplingNotificationZoneModel model) { + public SamplingNotificationZoneHandler(SpeciesFrequencyUI ui, SamplingNotificationZoneModel model, IndividualObservationUICache individualObservationUICache) { this.uiModel = ui.getModel(); this.samplingWarningLabel = ui.getSamplingWarningLabel(); this.samplingSummaryLabel = ui.getSamplingResumeLabel(); @@ -68,7 +70,7 @@ public class SamplingNotificationZoneHandler implements Closeable { this.listSelectionModel = ui.getObsTable().getSelectionModel(); SpeciesFrequencyUIHandler uiHandler = ui.getHandler(); - this.individualObservationUICache = uiHandler.getIndividualObservationUICache(); + this.individualObservationUICache = individualObservationUICache; this.infiniteDecorator = uiHandler.getDecorator(Integer.class, DecoratorService.NULL_INFINITE); this.speciesDecorator = uiHandler.getDecorator(Species.class, DecoratorService.WITH_SURVEY_CODE); this.zoneDecorator = uiHandler.getDecorator(Zone.class, null); @@ -84,25 +86,40 @@ public class SamplingNotificationZoneHandler implements Closeable { case DISABLED: - samplingWarningLabel.setText("< L'algorithme de prélèvements des pièces calcifiées n'est pas utilisé >"); + samplingWarningLabel.setText(t("tutti.editSpeciesFrequencies.samplingNotification.warning.samplingDisabled")); + samplingWarningLabel.setForeground(null); + samplingWarningLabel.setBackground(Color.LIGHT_GRAY); + + break; + case NOT_USING_SAMPLING: + + samplingWarningLabel.setText(t("tutti.editSpeciesFrequencies.samplingNotification.warning.samplingNotUsed")); samplingWarningLabel.setForeground(null); samplingWarningLabel.setBackground(Color.LIGHT_GRAY); break; case NEED_SAMPLING: - samplingWarningLabel.setText(t("tutti.editSpeciesFrequencies.samplingNeeded.warning")); + samplingWarningLabel.setText(t("tutti.editSpeciesFrequencies.samplingNotification.warning.samplingNeeded")); samplingWarningLabel.setForeground(colorHighlightInfoForeground); samplingWarningLabel.setBackground(colorHighlightInfoBackground); break; + case NO_SAMPLING_REQUIRED: + + samplingWarningLabel.setText(t("tutti.editSpeciesFrequencies.samplingNotification.warning.noSamplingRequired")); + samplingWarningLabel.setForeground(null); + samplingWarningLabel.setBackground(Color.LIGHT_GRAY); + + break; case COUNT_ATTAINED: - samplingWarningLabel.setText(t("tutti.editSpeciesFrequencies.samplingTotalCountAttained.warning")); + samplingWarningLabel.setText(t("tutti.editSpeciesFrequencies.samplingNotification.warning.samplingTotalCountAttained")); samplingWarningLabel.setForeground(null); samplingWarningLabel.setBackground(Color.LIGHT_GRAY); break; + case NONE: samplingWarningLabel.setText(null); @@ -121,30 +138,87 @@ public class SamplingNotificationZoneHandler implements Closeable { }; + // Ecoute le changement de sélection d'une observation individuelle pour demander au cache le statut de celle-ci this.modelSelectedRowChanged = event -> { IndividualObservationBatchRowModel selectedRow = (IndividualObservationBatchRowModel) event.getNewValue(); if (selectedRow == null) { - whenCanNotUseSampling("Aucune observation individuelle sélectionnée."); + whenCanNotUseSampling(t("tutti.editSpeciesFrequencies.samplingNotification.warning.noRowSelected")); return; } - try { + IndividualObservationSamplingStatus status = getIndividualObservationSamplingStatus(selectedRow); + + if (status != null) { + + // mise à jour du résumé + String summaryText = getSummaryText(status); + model.setSummaryText(summaryText); + + // mise à jour du statut de l'observation individuelle + SamplingNotificationZoneStatus samplingNotificationZoneStatus; + + if (status.isOneTotalCountIsAttained()) { + + // plus besoin de prélever (max atteint) + samplingNotificationZoneStatus = SamplingNotificationZoneStatus.COUNT_ATTAINED; + } else if (status.isNotUsingSampling()) { + + // ne jamais prélever (max à 0) + samplingNotificationZoneStatus = SamplingNotificationZoneStatus.NOT_USING_SAMPLING; + } else { + + // rien à afficher (en mode sélection, on ne peut pas dire s'il faut ou non prélever) + samplingNotificationZoneStatus = SamplingNotificationZoneStatus.NONE; + } + + model.setSamplingNotificationZoneStatus(samplingNotificationZoneStatus); + + } + + }; + + // Ecoute le changement de modification d'une observation individuelle pour demander au cache le statut de celle-ci + this.modelUpdatedRowChanged = event -> { + + IndividualObservationBatchRowModel updatedRow = (IndividualObservationBatchRowModel) event.getNewValue(); + + Objects.requireNonNull(updatedRow); + + // récupération du status de l'observation individuelle + IndividualObservationSamplingStatus status = getIndividualObservationSamplingStatus(updatedRow); + + if (status != null) { + + // mise à jour du résumé + String summaryText = getSummaryText(status); + model.setSummaryText(summaryText); + + // mise à jour du statut de l'observation individuelle + SamplingNotificationZoneStatus samplingNotificationZoneStatus; + + if (status.isNeedSampling()) { + + // demande de prélèvement, bingo! + samplingNotificationZoneStatus = SamplingNotificationZoneStatus.NEED_SAMPLING; + } else if (status.isOneTotalCountIsAttained()) { + + // plus besoin de prélever (max atteint) + samplingNotificationZoneStatus = SamplingNotificationZoneStatus.COUNT_ATTAINED; + } else if (status.isNotUsingSampling()) { + + // ne jamais prélever (max à 0) + samplingNotificationZoneStatus = SamplingNotificationZoneStatus.NOT_USING_SAMPLING; + } else { - // récupération du status de l'observation individuelle - IndividualObservationSamplingStatus status = individualObservationUICache.getIndividualObservationSamplingStatus(selectedRow); + // pas de prélèvement requis (samplingInterval) + samplingNotificationZoneStatus = SamplingNotificationZoneStatus.NO_SAMPLING_REQUIRED; + } - // mise à jour de la zone de notification - whenUpdateSummary(status); + model.setSamplingNotificationZoneStatus(samplingNotificationZoneStatus); - } 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."); } }; @@ -154,17 +228,29 @@ public class SamplingNotificationZoneHandler implements Closeable { ListSelectionModel source = (ListSelectionModel) event.getSource(); + if (model.isValueAdjusting()) { + + // évènement non terminée (en cours d'ajustement) + return; + } + if (event.getValueIsAdjusting()) { + + // évènement non terminée (en cours d'ajustement) return; } if (source.isSelectionEmpty()) { + + // on supprime la sélection dans le modèle model.setSelectedRow(null); return; } if (getSelectedRowCount(source) > 1) { - whenCanNotUseSampling("Plusieurs observations individuelles sélectionnées."); + + // plusieurs lignes sélectionnées, on ne peut pas afficher d'informations + whenCanNotUseSampling(t("tutti.editSpeciesFrequencies.samplingNotification.warning.moreThanOneRowSelected")); return; } @@ -175,7 +261,7 @@ public class SamplingNotificationZoneHandler implements Closeable { } - public void editBatch(SpeciesBatchRowModel speciesBatch) { + public void editBatch(SpeciesBatch speciesBatch) { if (log.isInfoEnabled()) { log.info("Edit batch for " + speciesBatch); @@ -183,46 +269,48 @@ public class SamplingNotificationZoneHandler implements Closeable { // toujours supprimer les listeners listSelectionModel.removeListSelectionListener(listSelectionListener); - model.removePropertyChangeListener(SamplingNotificationZoneModel.PROPERTY_SAMPLING_NOTIFICATION_ZONE_STATUS, modelStatusChanged); model.removePropertyChangeListener(SamplingNotificationZoneModel.PROPERTY_SELECTED_ROW, modelSelectedRowChanged); + model.removePropertyChangeListener(SamplingNotificationZoneModel.PROPERTY_UPDATED_ROW, modelUpdatedRowChanged); + model.removePropertyChangeListener(SamplingNotificationZoneModel.PROPERTY_SAMPLING_NOTIFICATION_ZONE_STATUS, modelStatusChanged); model.removePropertyChangeListener(SamplingNotificationZoneModel.PROPERTY_SUMMARY_TEXT, modelSummaryTextChanged); // on les ajoutent (on peut en avoir besoin pour désactiver la zone de notification) - model.addPropertyChangeListener(SamplingNotificationZoneModel.PROPERTY_SAMPLING_NOTIFICATION_ZONE_STATUS, modelStatusChanged); model.addPropertyChangeListener(SamplingNotificationZoneModel.PROPERTY_SELECTED_ROW, modelSelectedRowChanged); + model.addPropertyChangeListener(SamplingNotificationZoneModel.PROPERTY_UPDATED_ROW, modelUpdatedRowChanged); + model.addPropertyChangeListener(SamplingNotificationZoneModel.PROPERTY_SAMPLING_NOTIFICATION_ZONE_STATUS, modelStatusChanged); model.addPropertyChangeListener(SamplingNotificationZoneModel.PROPERTY_SUMMARY_TEXT, modelSummaryTextChanged); - if (!individualObservationUICache.isProtocolFilled()) { + if (!uiModel.isProtocolFilled()) { // pas de protocole - stopUsingStatusNotication("Pas de protocole défini."); + stopUsingStatusNotication(t("tutti.editSpeciesFrequencies.samplingNotification.warning.noProtocol")); return; } - if (!individualObservationUICache.isProtocolUseCalcifiedPieceSampling()) { + if (!uiModel.isProtocolUseCalcifiedPieceSampling()) { // pas d'utilisation de l'algorithme de prélèvement des pièces calcifiées - stopUsingStatusNotication("L'utilisation de l'algorithme n'est pas activée dans le protocole."); + stopUsingStatusNotication(t("tutti.editSpeciesFrequencies.samplingNotification.warning.notUsingAlgorithm")); return; } if (!individualObservationUICache.isFishingOperationWithZone()) { // pas de zone définie sur l'opération de pêche - stopUsingStatusNotication("Le trait n'est pas dans une zone."); + stopUsingStatusNotication(t("tutti.editSpeciesFrequencies.samplingNotification.warning.fishingOperationNotInAZone")); return; } if (!individualObservationUICache.isSpeciesDefinedInCalcifiedPiecesSampling()) { // pas de définition d'algorithme sur cette espèce - stopUsingStatusNotication("L'espèce du lot n'est pas connue dans la définition de l'algorithme."); + stopUsingStatusNotication(t("tutti.editSpeciesFrequencies.samplingNotification.warning.speciesNotInAlgorithm")); return; } Preconditions.checkState(individualObservationUICache.useCruiseSamplingCache()); - model.reset(); + model.setSelectedRow(null); listSelectionModel.addListSelectionListener(listSelectionListener); @@ -232,8 +320,9 @@ public class SamplingNotificationZoneHandler implements Closeable { public void close() { listSelectionModel.removeListSelectionListener(listSelectionListener); - model.removePropertyChangeListener(SamplingNotificationZoneModel.PROPERTY_SAMPLING_NOTIFICATION_ZONE_STATUS, modelStatusChanged); model.removePropertyChangeListener(SamplingNotificationZoneModel.PROPERTY_SELECTED_ROW, modelSelectedRowChanged); + model.removePropertyChangeListener(SamplingNotificationZoneModel.PROPERTY_UPDATED_ROW, modelUpdatedRowChanged); + model.removePropertyChangeListener(SamplingNotificationZoneModel.PROPERTY_SAMPLING_NOTIFICATION_ZONE_STATUS, modelStatusChanged); model.removePropertyChangeListener(SamplingNotificationZoneModel.PROPERTY_SUMMARY_TEXT, modelSummaryTextChanged); } @@ -248,30 +337,13 @@ public class SamplingNotificationZoneHandler implements Closeable { private void stopUsingStatusNotication(String message) { whenCanNotUseSampling(message); - model.removePropertyChangeListener(SamplingNotificationZoneModel.PROPERTY_SAMPLING_NOTIFICATION_ZONE_STATUS, modelStatusChanged); model.removePropertyChangeListener(SamplingNotificationZoneModel.PROPERTY_SELECTED_ROW, modelSelectedRowChanged); + model.removePropertyChangeListener(SamplingNotificationZoneModel.PROPERTY_UPDATED_ROW, modelUpdatedRowChanged); + model.removePropertyChangeListener(SamplingNotificationZoneModel.PROPERTY_SAMPLING_NOTIFICATION_ZONE_STATUS, modelStatusChanged); model.removePropertyChangeListener(SamplingNotificationZoneModel.PROPERTY_SUMMARY_TEXT, modelSummaryTextChanged); } - private void whenUpdateSummary(IndividualObservationSamplingStatus status) { - - model.setSummaryText(getSummaryText(status)); - - SamplingNotificationZoneStatus zoneStatus; - - if (status.isNeedSampling()) { - zoneStatus = SamplingNotificationZoneStatus.NEED_SAMPLING; - } else if (status.isOneTotalCountIsAttained()) { - zoneStatus = SamplingNotificationZoneStatus.COUNT_ATTAINED; - } else { - zoneStatus = SamplingNotificationZoneStatus.NONE; - } - - model.setSamplingNotificationZoneStatus(zoneStatus); - - } - private String getSummaryText(IndividualObservationSamplingStatus status) { IndividualObservationSamplingContext individualObservationSamplingContext = status.getIndividualObservationSamplingContext(); @@ -287,7 +359,7 @@ public class SamplingNotificationZoneHandler implements Closeable { String nbForCruiseLabel = getLabelForSamplingNumber(nbForCruise, calcifiedPiecesSamplingDefinition.getMaxByLenghtStep()); String key = speciesDecorator.toString(individualObservationSamplingContext.getSpecies()) - + " " + Numbers.convertFromMm(individualObservationSamplingContext.getLengthStep(), uiModel.getLengthStepCaracteristicUnit()) + + " " + uiModel.convertFromMm(individualObservationSamplingContext.getLengthStep()) + " " + uiModel.getLengthStepCaracteristicUnit(); if (individualObservationSamplingContext.withGender()) { key += " " + individualObservationSamplingContext.getGender().getDescription(); @@ -324,8 +396,28 @@ public class SamplingNotificationZoneHandler implements Closeable { return count; } - private String getLabelForSamplingNumber(int value, Integer max) { return "<strong>" + infiniteDecorator.toString(value) + "</strong> (" + infiniteDecorator.toString(max) + ")"; } + + private IndividualObservationSamplingStatus getIndividualObservationSamplingStatus(IndividualObservationBatchRowModel selectedRow) { + + IndividualObservationSamplingStatus individualObservationSamplingStatus = null; + + try { + + individualObservationSamplingStatus = individualObservationUICache.getIndividualObservationSamplingStatus(selectedRow); + + } catch (CalcifiedPiecesSamplingAlgorithmEntryNotFoundException e) { + whenCanNotUseSampling(t("tutti.editSpeciesFrequencies.samplingNotification.warning.noAlgorithmEntry")); + } catch (SizeNotDefinedOnIndividualObservationException e) { + whenCanNotUseSampling(t("tutti.editSpeciesFrequencies.samplingNotification.warning.sizeNotDefined")); + } catch (ZoneNotDefinedOnFishingOperationException e) { + whenCanNotUseSampling(t("tutti.editSpeciesFrequencies.samplingNotification.warning.fishingOperationNotInAZone")); + } + + return individualObservationSamplingStatus; + + } + } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SamplingNotificationZoneModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SamplingNotificationZoneModel.java index 33e0d4d..ad969a7 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SamplingNotificationZoneModel.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SamplingNotificationZoneModel.java @@ -6,12 +6,28 @@ import org.jdesktop.beans.AbstractSerializableBean; * Created on 19/04/16. * * @author Tony Chemit - chemit@codelutin.com + * @since 4.5 */ public class SamplingNotificationZoneModel extends AbstractSerializableBean { + public static final String PROPERTY_SELECTED_ROW = "selectedRow"; + public static final String PROPERTY_UPDATED_ROW = "updatedRow"; public static final String PROPERTY_SAMPLING_NOTIFICATION_ZONE_STATUS = "samplingNotificationZoneStatus"; public static final String PROPERTY_SUMMARY_TEXT = "summaryText"; - public static final String PROPERTY_SELECTED_ROW = "selectedRow"; + + /** + * Pour bloquer le recalcul du modèle lors du changement de sélection (Pour le mode rafale, où l'on ajoute la + * ligne puis ensuite on la sélectionne). + */ + private boolean valueAdjusting; + + public void setSelectedRow(IndividualObservationBatchRowModel selectedRow) { + firePropertyChange(PROPERTY_SELECTED_ROW, null /* On force la propagation de l'évènement! */, selectedRow); + } + + public void setUpdatedRow(IndividualObservationBatchRowModel updatedRow) { + firePropertyChange(PROPERTY_UPDATED_ROW, null /* On force la propagation de l'évènement! */, updatedRow); + } public void setSamplingNotificationZoneStatus(SamplingNotificationZoneStatus samplingNotificationZoneStatus) { firePropertyChange(PROPERTY_SAMPLING_NOTIFICATION_ZONE_STATUS, null /* On force la propagation de l'évènement! */, samplingNotificationZoneStatus); @@ -21,15 +37,11 @@ public class SamplingNotificationZoneModel extends AbstractSerializableBean { firePropertyChange(PROPERTY_SUMMARY_TEXT, null /* On force la propagation de l'évènement! */, summaryText); } - public void reset() { - - setSamplingNotificationZoneStatus(SamplingNotificationZoneStatus.DISABLED); - setSummaryText("Aucune observation individuelle sélectionnée."); - + public void setValueAdjusting(boolean valueAdjusting) { + this.valueAdjusting = valueAdjusting; } - public void setSelectedRow(IndividualObservationBatchRowModel selectedRow) { - firePropertyChange(PROPERTY_SELECTED_ROW, null /* On force la propagation de l'évènement! */, selectedRow); + public boolean isValueAdjusting() { + return valueAdjusting; } - } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SamplingNotificationZoneStatus.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SamplingNotificationZoneStatus.java index 6806581..033c237 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SamplingNotificationZoneStatus.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SamplingNotificationZoneStatus.java @@ -9,7 +9,9 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency; */ public enum SamplingNotificationZoneStatus { DISABLED, /* Not using algorithm */ + NOT_USING_SAMPLING, /* Selected indivdual observation is declared in algorithm, but not requiring sampling (max are 0) */ NEED_SAMPLING, /* Selected indivdual observation need sampling */ + NO_SAMPLING_REQUIRED, /* Selected indivdual observation use sampling, but not for this one */ COUNT_ATTAINED, /* Selected individual observation has attained one of his total count */ NONE /* Nothing in special */ } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyTableModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyTableModel.java index 7c3defb..a993a60 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyTableModel.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyTableModel.java @@ -24,7 +24,6 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency; import com.google.common.base.Preconditions; import fr.ifremer.tutti.persistence.entities.data.CopyIndividualObservationMode; -import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; import fr.ifremer.tutti.type.WeightUnit; import fr.ifremer.tutti.util.Numbers; import fr.ifremer.tutti.util.Weights; @@ -262,7 +261,7 @@ public class SpeciesFrequencyTableModel extends AbstractApplicationTableModel<Sp SpeciesFrequencyRowModel row = rowCache.get(realLengthStep); if (row == null) { - row = createNewRow(); + row = createNewRow(false, true); row.setLengthStep(realLengthStep); rowCache.put(realLengthStep, row); @@ -273,6 +272,7 @@ public class SpeciesFrequencyTableModel extends AbstractApplicationTableModel<Sp int indexToInsert = steps.indexOf(realLengthStep); addNewRow(indexToInsert, row); + } return row; @@ -293,8 +293,8 @@ public class SpeciesFrequencyTableModel extends AbstractApplicationTableModel<Sp public void incrementFrequencyRowsNumbers(float lengthStepToIncrement) { - if (log.isInfoEnabled()) { - log.info("incrementFrequencyRowsNumbers" + lengthStepToIncrement); + if (log.isDebugEnabled()) { + log.debug("incrementFrequencyRowsNumbers" + lengthStepToIncrement); } SpeciesFrequencyRowModel row = getOrCreateRowForLengthStep(lengthStepToIncrement); @@ -306,8 +306,8 @@ public class SpeciesFrequencyTableModel extends AbstractApplicationTableModel<Sp public void decrementFrequencyRowsNumbers(float lengthStepToDecrement) { - if (log.isInfoEnabled()) { - log.info("decrementFrequencyRowsNumbers " + lengthStepToDecrement); + if (log.isDebugEnabled()) { + log.debug("decrementFrequencyRowsNumbers " + lengthStepToDecrement); } Optional<SpeciesFrequencyRowModel> optionalRow = getOptionalRowForLengthStep(lengthStepToDecrement); @@ -340,8 +340,8 @@ public class SpeciesFrequencyTableModel extends AbstractApplicationTableModel<Sp public void addWeightToFrequencyRow(float lengthStep, float weight) { - if (log.isInfoEnabled()) { - log.info("add weight to frequency (lengthStep: " + lengthStep + "): " + weight); + if (log.isDebugEnabled()) { + log.debug("add weight to frequency (lengthStep: " + lengthStep + "): " + weight); } Preconditions.checkState(!weightUnit.isSmallerThanZero(weight)); @@ -356,8 +356,8 @@ public class SpeciesFrequencyTableModel extends AbstractApplicationTableModel<Sp public void removeWeightToFrequencyRow(float lengthStep, float weight) { - if (log.isInfoEnabled()) { - log.info("remove weight to frequency (lengthStep: " + lengthStep + "): " + weight); + if (log.isDebugEnabled()) { + log.debug("remove weight to frequency (lengthStep: " + lengthStep + "): " + weight); } Preconditions.checkState(!weightUnit.isSmallerThanZero(weight)); @@ -403,7 +403,7 @@ public class SpeciesFrequencyTableModel extends AbstractApplicationTableModel<Sp public SpeciesFrequencyRowModel addRafaleRow(float lengthStep) { - Map<Float, SpeciesFrequencyRowModel> rowsByStep = uiModel.getCache().getRowCache(); + Map<Float, SpeciesFrequencyRowModel> rowsByStep = modelCache.getRowCache(); SpeciesFrequencyRowModel row = rowsByStep.get(lengthStep); @@ -444,28 +444,62 @@ public class SpeciesFrequencyTableModel extends AbstractApplicationTableModel<Sp float minStep = uiModel.getLengthStep(uiModel.getMinStep()); float maxStep = uiModel.getLengthStep(uiModel.getMaxStep()); - Caracteristic lengthStepCaracteristic = uiModel.getLengthStepCaracteristic(); Map<Float, SpeciesFrequencyRowModel> rowsByStep = modelCache.getRowCache(); Set<Float> existingKeys = new HashSet<>(rowsByStep.keySet()); List<SpeciesFrequencyRowModel> rows = new ArrayList<>(rowsByStep.values()); - for (float i = minStep, step = uiModel.getStep(); i <= maxStep; i = Numbers.getRoundedLengthStep(i + step, true)) { + for (float lengthClass = minStep, step = uiModel.getStep(); lengthClass <= maxStep; lengthClass = Numbers.getRoundedLengthStep(lengthClass + step, true)) { - if (!existingKeys.contains(i)) { + if (!existingKeys.contains(lengthClass)) { // add it - SpeciesFrequencyRowModel newRow = createNewRow(); - newRow.setLengthStep(i); - newRow.setLengthStepCaracteristic(lengthStepCaracteristic); + SpeciesFrequencyRowModel newRow = createNewRow(false, true); + newRow.setLengthStep(lengthClass); rows.add(newRow); + } + } + Collections.sort(rows); uiModel.setRows(rows); } + public void reloadRowsFromIndividualObservations() { + + if (uiModel.mustCopyIndividualObservationSize()) { + + boolean copyWeights = uiModel.isCopyIndividualObservationAll(); + + uiModel.getValidIndividualObservations().stream() + .filter(IndividualObservationBatchRowModel::withSize) + .forEachOrdered(individualObservation -> { + + SpeciesFrequencyRowModel row = getOrCreateRowForLengthStep(individualObservation.getSize()); + row.incNumber(); + + if (copyWeights && individualObservation.withWeight()) { + Float weight = convertWeightFromIndividualObservation(individualObservation.getWeight()); + row.addToWeight(weight); + } + + }); + + } + + if (rows.isEmpty()) { + addNewRow(); + } else { + Collections.sort(rows); + } + + uiModel.reloadRows(); + + } + + private void lengthStepWasRemoved(Float lengthStep) { uiModel.getAverageWeightsHistogramModel().removeValue(lengthStep); @@ -473,7 +507,6 @@ public class SpeciesFrequencyTableModel extends AbstractApplicationTableModel<Sp } - private void lengthStepOrNumberWasUpdated(SpeciesFrequencyRowModel row) { if (row.withNumber()) { @@ -630,4 +663,17 @@ public class SpeciesFrequencyTableModel extends AbstractApplicationTableModel<Sp } + public void clear() { + + if (!rows.isEmpty()) { + + int rowCount = rows.size(); + rows.clear(); + fireTableRowsDeleted(0, rowCount - 1); + addNewRow(); + + } + + + } } \ No newline at end of file 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 44cbcc8..b61e68c 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 @@ -33,6 +33,7 @@ import fr.ifremer.tutti.persistence.entities.data.CopyIndividualObservationMode; import fr.ifremer.tutti.persistence.entities.data.SampleCategoryModel; import fr.ifremer.tutti.persistence.entities.protocol.Rtp; import fr.ifremer.tutti.persistence.entities.protocol.SpeciesProtocol; +import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocol; import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; import fr.ifremer.tutti.persistence.entities.referential.Sexs; @@ -40,6 +41,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.service.DecoratorService; +import fr.ifremer.tutti.service.TuttiDataContext; +import fr.ifremer.tutti.service.cruise.CruiseCache; import fr.ifremer.tutti.type.WeightUnit; import fr.ifremer.tutti.ui.swing.TuttiUIContext; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.EditSpeciesBatchPanelUI; @@ -57,7 +60,6 @@ import fr.ifremer.tutti.ui.swing.util.caracteristics.CaracteristicMapEditorUI; import fr.ifremer.tutti.ui.swing.util.table.AbstractTuttiTableUIHandler; import fr.ifremer.tutti.ui.swing.util.table.CaracteristicColumnIdentifier; import fr.ifremer.tutti.util.Units; -import fr.ifremer.tutti.util.Weights; import jaxx.runtime.swing.editor.bean.BeanFilterableComboBox; import jaxx.runtime.validator.swing.SwingValidator; import org.apache.commons.collections4.CollectionUtils; @@ -96,11 +98,10 @@ import java.beans.PropertyChangeListener; import java.beans.PropertyVetoException; import java.io.Serializable; import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import static org.nuiton.i18n.I18n.t; @@ -159,6 +160,7 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci protected Decorator<Caracteristic> caracteristicDecorator; protected Decorator<Caracteristic> caracteristicTipDecorator; protected Decorator<CaracteristicQualitativeValue> caracteristicQualitativeDecorator; + protected SoundEngine soundEngine; public SpeciesFrequencyUIHandler() { @@ -345,24 +347,36 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci this.caracteristicDecorator = getDecorator(Caracteristic.class, DecoratorService.CARACTERISTIC_PARAMETER_ONLY_WITH_UNIT); this.caracteristicTipDecorator = getDecorator(Caracteristic.class, DecoratorService.CARACTERISTIC_WITH_UNIT); this.caracteristicQualitativeDecorator = getDecorator(CaracteristicQualitativeValue.class, null); + this.soundEngine = getContext().getSoundEngine(); Caracteristic sexCaracteristic = getPersistenceService().getSexCaracteristic(); - SampleCategoryModel sampleCategoryModel = getDataContext().getSampleCategoryModel(); + TuttiDataContext dataContext = getDataContext(); + SampleCategoryModel sampleCategoryModel = dataContext.getSampleCategoryModel(); // get the default caracteristics - List<Caracteristic> defaultCaracteristic = new ArrayList<>(getDataContext().getDefaultIndividualObservationCaracteristics()); + List<Caracteristic> defaultCaracteristic = new ArrayList<>(dataContext.getDefaultIndividualObservationCaracteristics()); // on ajoute toujours la colonne sex if (!defaultCaracteristic.contains(sexCaracteristic)) { defaultCaracteristic.add(0, sexCaracteristic); } + Optional<CruiseCache> optionalCruiseCache = dataContext.getOptionalCruiseCache(); + if (!optionalCruiseCache.isPresent()) { + throw new IllegalStateException("Can't find cruise cache"); + } + + TuttiProtocol protocol = dataContext.isProtocolFilled() ? dataContext.getProtocol() : null; + SpeciesFrequencyUIModel model = new SpeciesFrequencyUIModel(speciesOrBenthosBatchUISupport, getConfig().getIndividualObservationWeightUnit(), sampleCategoryModel, sexCaracteristic, - defaultCaracteristic); + defaultCaracteristic, + optionalCruiseCache.get(), + dataContext.getCruiseId(), + protocol); this.ui.setContextValue(model); @@ -379,7 +393,7 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci applySpeciesFrequencyRafaleAction = new ApplySpeciesFrequencyRafaleAction(ui); - initUI(this.ui); + initUI(ui); List<Caracteristic> lengthStepCaracteristics = new ArrayList<>(getDataContext().getLengthStepCaracteristics()); @@ -538,7 +552,9 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci this.individualObservationBatchTableHandler = new IndividualObservationBatchTableHandler(ui); this.averageWeightsHistogramHandler = new AverageWeightsHistogramHandler(ui); this.frequenciesHistogramHandler = new FrequenciesHistogramHandler(ui); - this.samplingNotificationZoneHandler = new SamplingNotificationZoneHandler(ui, model.getIndividualObservationModel().getSamplingNotificationZoneModel()); + this.samplingNotificationZoneHandler = new SamplingNotificationZoneHandler(ui, + model.getIndividualObservationModel().getSamplingNotificationZoneModel(), + model.getIndividualObservationUICache()); listenValidatorValid(ui.getValidator(), model); @@ -662,6 +678,7 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci // init maturity caracteristic individualObservationBatchTableHandler.initMaturityCaracteristic(speciesProtocol); + individualObservationBatchTableHandler.initDefaultCaracteristics(speciesBatch); loadFrequenciesAndObservations(frequency, individualObservations, false); @@ -676,8 +693,8 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci if (getContext().isCaliperConnected()) { - // let's listen the caliper - listenCaliper(); + // let's listen the caliper + listenCaliper(); } @@ -703,10 +720,6 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci return saveResponse == 0; } - public IndividualObservationUICache getIndividualObservationUICache() { - return individualObservationBatchTableHandler.getIndividualObservationUICache(); - } - public void setCopyIndividualObservationMode(CopyIndividualObservationMode newCopyMode) { SpeciesFrequencyUIModel model = getModel(); @@ -756,7 +769,7 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci // on repositionne sur le bon radio-bouton // le code n'est pas optimal mais est moins dangeureux que de relancer des fires je pense - switch(model.getCopyIndividualObservationMode()) { + switch (model.getCopyIndividualObservationMode()) { case ALL: ui.getCopyAllButton().setSelected(true); break; @@ -838,6 +851,7 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci getConfig().getIndividualObservationWeightUnit(), columnModel, getModel()); + getModel().setFrequencyTableModel(tableModel); table.setModel(tableModel); table.setColumnModel(columnModel); @@ -989,29 +1003,29 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci protected void consumeIchtyometerFeedRecord(IchtyometerFeedReaderMeasureRecord record) { if (record.isValid()) { - String unit = getModel().getLengthStepCaracteristicUnit(); - - // board measurements are in mm - - float length; - - if ("mm".equals(unit)) { - - // measurement in mm asked - length = record.getMeasure(); - - } else { - - // measurement in cm asked - length = record.getMeasure() / 10f; - - } + float length = getModel().convertFromMm(record.getMeasure()); +// String unit = getModel().getLengthStepCaracteristicUnit(); + +// // board measurements are in mm +// +// float length; +// +// if ("mm".equals(unit)) { +// +// // measurement in mm asked +// length = record.getMeasure(); +// +// } else { +// +// // measurement in cm asked +// length = record.getMeasure() / 10f; +// +// } applySpeciesFrequencyRafaleAction.applyRafaleStep(length, true); } else { - SoundEngine soundEngine = getContext().getSoundEngine(); soundEngine.beepOnExternalDeviceErrorReception(); throw new ApplicationBusinessException(t("tutti.editSpeciesFrequencies.error.itchyometer.bad.record", record.getRecord())); @@ -1021,29 +1035,30 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci protected void consumeCaliperFeedRecord(CaliperFeedReaderMeasureRecord record) { if (record.isValid()) { - String unit = getModel().getLengthStepCaracteristicUnit(); - - // board measurements are in mm - - float length; - - if ("mm".equals(unit)) { - - // measurement in mm asked - length = record.getMeasure(); - - } else { - - // measurement in cm asked - length = record.getMeasure() / 10f; - - } + float length = getModel().convertFromMm(record.getMeasure()); + +// String unit = getModel().getLengthStepCaracteristicUnit(); +// +// // board measurements are in mm +// +// float length; +// +// if ("mm".equals(unit)) { +// +// // measurement in mm asked +// length = record.getMeasure(); +// +// } else { +// +// // measurement in cm asked +// length = record.getMeasure() / 10f; +// +// } applySpeciesFrequencyRafaleAction.applyRafaleStep(length, true); } else { - SoundEngine soundEngine = getContext().getSoundEngine(); soundEngine.beepOnExternalDeviceErrorReception(); throw new ApplicationBusinessException(t("tutti.editSpeciesFrequencies.error.caliper.bad.record", record.getRecord())); @@ -1118,58 +1133,6 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci secondSplitPane.setDividerSize(logVisible ? firstSplitPane.getDividerSize() : 0); ui.getLogsScrollPane().setVisible(logVisible); - } - - protected void reloadRowsFromIndividualObservations() { - SpeciesFrequencyUIModel model = getModel(); - CopyIndividualObservationMode copyMode = model.getCopyIndividualObservationMode(); - - if (CopyIndividualObservationMode.NOTHING != copyMode) { - - Caracteristic lengthStepCaracteristic = model.getLengthStepCaracteristic(); - - List<IndividualObservationBatchRowModel> validObsRow = new ArrayList<>(model.getIndividualObservationModel().getRows()); - validObsRow.removeAll(model.getIndividualObservationModel().getRowsInError()); - - WeightUnit individualObservationWeightUnit = getConfig().getIndividualObservationWeightUnit(); - - for (IndividualObservationBatchRowModel obsRow : validObsRow) { - - if (obsRow.withSize()) { - float size = model.getLengthStep(obsRow.getSize()); - if (log.isInfoEnabled()) { - log.info("size : " + size); - } - SpeciesFrequencyRowModel row = model.getCache().getRowCache().get(size); - if (row == null) { - row = getTableModel().createNewRow(false, true); - row.setLengthStep(size); - row.setLengthStepCaracteristic(lengthStepCaracteristic); - model.getRows().add(row); - model.getCache().getRowCache().put(size, row); - } - row.incNumber(); - if (CopyIndividualObservationMode.ALL == copyMode && obsRow.withWeight()) { - // conversion de poids - Float weight = Weights.convert(individualObservationWeightUnit, weightUnit, obsRow.getWeight()); - row.addToWeight(weight); - } - } - - } - - if (model.getRowCount() == 0) { - getTableModel().addNewRow(); - - } else { - Collections.sort(model.getRows()); - } - - } else if (getTableModel().getRowCount() == 0) { - getTableModel().addNewRow(); - } - - model.reloadRows(); } @@ -1201,63 +1164,41 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci try { - Integer number = speciesBatch.getNumber(); - model.setSimpleCount(number); - - model.setTotalNumber(null); - model.setTotalComputedWeight(null); - model.setTotalWeight(null); + model.loadSpeciesBatch(speciesBatch); Species species = speciesBatch.getSpecies(); - model.setTotalWeight(speciesBatch.getWeight()); - List<SpeciesFrequencyRowModel> frequencyRows = getTableModel().loadRows(frequency); - List<IndividualObservationBatchRowModel> individualObservationRows = individualObservationBatchTableHandler.loadIndividualObservations(species, individualObservations); + List<IndividualObservationBatchRowModel> individualObservationRows = individualObservationBatchTableHandler.loadRows(species, individualObservations); if (log.isDebugEnabled()) { - log.debug("Will edit batch row: " + speciesBatch + " with " + frequencyRows.size() + " frequencies and " + individualObservationRows.size() + " indivudual observations."); + log.debug("Will edit batch row: " + speciesBatch + " with " + frequencyRows.size() + " frequencies and " + individualObservationRows.size() + " individual observations."); } - CopyIndividualObservationMode copyIndividualObservationMode; - if (individualObservationRows.isEmpty()) { - - copyIndividualObservationMode = CopyIndividualObservationMode.NOTHING; - - } else { - - IndividualObservationBatchRowModel firstIndividualObservationRow = individualObservationRows.get(0); - copyIndividualObservationMode = firstIndividualObservationRow.getCopyIndividualObservationMode(); - - } + CopyIndividualObservationMode copyIndividualObservationMode = computeCopyIndividualObservationMode(individualObservationRows); if (log.isInfoEnabled()) { - log.info("CopyIndividualObservationMode: " + copyIndividualObservationMode); + log.info("copyIndividualObservationMode: " + copyIndividualObservationMode); } Caracteristic lengthStepCaracteristic = computeLengthStepCaracteristic(species, frequencyRows, individualObservationRows); - model.setLengthStepCaracteristic(lengthStepCaracteristic); - - FrequencyConfigurationMode mode; - if (number != null || lengthStepCaracteristic == null) { - - mode = FrequencyConfigurationMode.SIMPLE_COUNTING; - - } else { + if (log.isInfoEnabled()) { + log.info("lengthStepCaracteristic: " + lengthStepCaracteristic); + } - mode = FrequencyConfigurationMode.FREQUENCIES; + model.setLengthStepCaracteristic(lengthStepCaracteristic); - } + FrequencyConfigurationMode configurationMode = model.guessFrequencyConfigurationMode(); if (log.isInfoEnabled()) { - log.info("FrequencyConfigurationMode: " + mode); + log.info("configurationMode: " + configurationMode); } // make sure configuration mode will be rebound model.setConfigurationMode(null); - model.setConfigurationMode(mode); + model.setConfigurationMode(configurationMode); model.setFrequenciesConfigurationMode(null); model.setFrequenciesConfigurationMode(FrequencyConfigurationMode.AUTO_GEN); @@ -1267,9 +1208,9 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci model.setRows(frequencyRows); - individualObservationBatchTableHandler.editBatch(speciesBatch, individualObservationRows, addToCache); + individualObservationBatchTableHandler.loadSpeciesBatch(speciesBatch, individualObservationRows, addToCache); - // let's change the copy mode (mark it in init mode to avoid user change confirmation and some recompuations) + // let's change the copy mode (mark it in init mode to avoid user change confirmation and some recomputations) model.setCopyIndividualObservationMode(null); model.setCopyIndividualObservationMode(copyIndividualObservationMode); @@ -1315,6 +1256,22 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci return super.decorate(object, context); } + private CopyIndividualObservationMode computeCopyIndividualObservationMode(List<IndividualObservationBatchRowModel> individualObservationRows) { + + CopyIndividualObservationMode copyIndividualObservationMode; + if (individualObservationRows.isEmpty()) { + + copyIndividualObservationMode = CopyIndividualObservationMode.NOTHING; + + } else { + + IndividualObservationBatchRowModel firstIndividualObservationRow = individualObservationRows.get(0); + copyIndividualObservationMode = firstIndividualObservationRow.getCopyIndividualObservationMode(); + + } + return copyIndividualObservationMode; + + } private Caracteristic computeLengthStepCaracteristic(Species species, List<SpeciesFrequencyRowModel> frequencyRows, List<IndividualObservationBatchRowModel> individualObservationRows) { @@ -1381,48 +1338,4 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci } - public void removeIndividualObservations(Collection<IndividualObservationBatchRowModel> rows) { - individualObservationBatchTableHandler.removeIndividualObservations(rows); - } - - public boolean isSamplingCodeAvailable(Integer sampleCode, IndividualObservationBatchRowModel selectedRow) { - - IndividualObservationUICache individualObservationUICache = ui.getHandler().getIndividualObservationUICache(); - - if (individualObservationUICache.isSamplingCodeNotAvailable(sampleCode)) { - - // le code n'est pas disponible (on le sait depuis le cache de l'écran) - if (log.isDebugEnabled()) { - log.debug("Sampling code " + sampleCode + " is known as not available from cache. Can't use it."); - } - return false; - } - - if (individualObservationUICache.isSamplingCodeAvailable(sampleCode)) { - - // le code est pas disponible (on le sait depuis le cache de l'écran) - if (log.isDebugEnabled()) { - log.debug("Sampling code " + sampleCode + " is known as available from cache. Can use it."); - } - return true; - } - - // on demande en base si le code est disponible - - String samplingCodeSuffix = selectedRow.getSamplingCodePrefix().toSpeciesOnlySamplingCode(sampleCode); - boolean samplingCodeAvailable = getPersistenceService().isSamplingCodeAvailable(getDataContext().getCruiseId(), - selectedRow.getSpecies().getReferenceTaxonId(), - samplingCodeSuffix); - - if (log.isDebugEnabled()) { - if (samplingCodeAvailable) { - log.debug("Sampling code " + sampleCode + " is known as available from database. Can use it."); - } else { - log.debug("Sampling code " + sampleCode + " is known as not available from database. Can't use it."); - } - } - - return samplingCodeAvailable; - - } } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIModel.java index a2e0251..1617359 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIModel.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIModel.java @@ -26,7 +26,10 @@ import fr.ifremer.tutti.persistence.entities.data.CopyIndividualObservationMode; import fr.ifremer.tutti.persistence.entities.data.FishingOperation; import fr.ifremer.tutti.persistence.entities.data.SampleCategoryModel; import fr.ifremer.tutti.persistence.entities.protocol.Rtp; +import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocol; import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; +import fr.ifremer.tutti.service.cruise.CruiseCache; +import fr.ifremer.tutti.service.sampling.IndividualObservationSamplingCacheRequest; import fr.ifremer.tutti.type.WeightUnit; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.SpeciesOrBenthosBatchUISupport; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.edit.SpeciesBatchRowModel; @@ -39,6 +42,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.beans.PropertyVetoException; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -268,12 +272,25 @@ public class SpeciesFrequencyUIModel extends AbstractTuttiTableUIModel<SpeciesBa private final FrequenciesHistogramModel frequenciesHistogramModel; private final IndividualObservationBatchUIModel individualObservationModel; + private final IndividualObservationUICache individualObservationUICache; + private final SamplingCodeUICache samplingCodeUICache; + private SpeciesFrequencyTableModel frequencyTableModel; + + private final boolean protocolFilled; + private final boolean protocolUseCalcifiedPieceSampling; + private boolean speciesDefinedInCalcifiedPiecesSampling; + public SpeciesFrequencyUIModel(SpeciesOrBenthosBatchUISupport speciesOrBenthosBatchUISupport, WeightUnit individualObservationWeightUnit, SampleCategoryModel sampleCategoryModel, Caracteristic sexCaracteristic, - List<Caracteristic> defaultCaracteristic) { + List<Caracteristic> defaultCaracteristic, + CruiseCache cruiseCache, + Integer cruiseId, + TuttiProtocol protocol) { super(SpeciesBatchRowModel.class, null, null); + this.protocolFilled = protocol != null; + this.protocolUseCalcifiedPieceSampling = protocolFilled && protocol.isUseCalcifiedPieceSampling(); this.speciesOrBenthosBatchUISupport = speciesOrBenthosBatchUISupport; this.weightUnit = speciesOrBenthosBatchUISupport.getWeightUnit(); this.individualObservationWeightUnit = individualObservationWeightUnit; @@ -286,15 +303,27 @@ public class SpeciesFrequencyUIModel extends AbstractTuttiTableUIModel<SpeciesBa this.frequenciesConfigurationMode = FrequencyConfigurationMode.AUTO_GEN; setEmptyRows(new HashSet<>()); - this.individualObservationModel = new IndividualObservationBatchUIModel(sexCaracteristic, individualObservationWeightUnit, defaultCaracteristic); + this.individualObservationModel = new IndividualObservationBatchUIModel(this, sexCaracteristic, individualObservationWeightUnit, defaultCaracteristic); this.averageWeightsHistogramModel = new AverageWeightsHistogramModel(weightUnit); this.frequenciesHistogramModel = new FrequenciesHistogramModel(); + + this.individualObservationUICache = new IndividualObservationUICache(cruiseCache, this); + this.samplingCodeUICache = new SamplingCodeUICache(cruiseCache.getSamplingCodeCache(), this, cruiseId); + } public SpeciesFrequencyUIModelCache getCache() { return cache; } + public SamplingCodeUICache getSamplingCodeUICache() { + return samplingCodeUICache; + } + + public IndividualObservationUICache getIndividualObservationUICache() { + return individualObservationUICache; + } + public AverageWeightsHistogramModel getAverageWeightsHistogramModel() { return averageWeightsHistogramModel; } @@ -431,6 +460,10 @@ public class SpeciesFrequencyUIModel extends AbstractTuttiTableUIModel<SpeciesBa return lengthStepCaracteristic == null ? null : lengthStepCaracteristic.getUnit(); } + public float convertFromMm(float source) { + return Numbers.convertFromMm(source, getLengthStepCaracteristicUnit()); + } + public Float getMinStep() { return minStep; } @@ -851,7 +884,81 @@ public class SpeciesFrequencyUIModel extends AbstractTuttiTableUIModel<SpeciesBa } public void clear() { - getRows().clear(); - getRowsInError().clear(); + + rowsInError.clear(); + frequencyTableModel.clear(); + recomputeCanEditLengthStep(); + recomputeRowsValidateState(); + + } + + public IndividualObservationSamplingCacheRequest toSamplingCacheRequest(IndividualObservationBatchRowModel row) { + return new IndividualObservationSamplingCacheRequest(fishingOperation, + row.getSpecies(), + getLengthStepInMm(row.getSize()), + individualObservationModel.getMaturityValue(row), + individualObservationModel.getGender(row), + row.getSamplingCode()); + } + + public void addIndividualObservationsInCache(List<IndividualObservationBatchRowModel> individualObservations) { + + individualObservationUICache.addIndividualObservations(individualObservations); + samplingCodeUICache.addIndividualObservations(individualObservations); + + } + + public List<IndividualObservationBatchRowModel> getValidIndividualObservations() { + + List<IndividualObservationBatchRowModel> result = new ArrayList<>(individualObservationModel.getRows()); + result.removeAll(individualObservationModel.getRowsInError()); + return result; + + } + + public void setFrequencyTableModel(SpeciesFrequencyTableModel frequencyTableModel) { + this.frequencyTableModel = frequencyTableModel; + } + + public SpeciesFrequencyTableModel getFrequencyTableModel() { + return frequencyTableModel; + } + + public boolean isProtocolFilled() { + return protocolFilled; + } + + public boolean isProtocolUseCalcifiedPieceSampling() { + return protocolUseCalcifiedPieceSampling; + } + + + public void loadSpeciesBatch(SpeciesBatchRowModel speciesBatch) { + + Integer number = speciesBatch.getNumber(); + setSimpleCount(number); + + setTotalNumber(null); + setTotalComputedWeight(null); + setTotalWeight(null); + + setTotalWeight(speciesBatch.getWeight()); + + } + + public FrequencyConfigurationMode guessFrequencyConfigurationMode() { + + FrequencyConfigurationMode mode; + if (getSimpleCount() != null || lengthStepCaracteristic == null) { + + mode = FrequencyConfigurationMode.SIMPLE_COUNTING; + + } else { + + mode = FrequencyConfigurationMode.FREQUENCIES; + + } + return mode; + } } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/ApplySpeciesFrequencyRafaleAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/ApplySpeciesFrequencyRafaleAction.java index a77cd37..e4bfb39 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/ApplySpeciesFrequencyRafaleAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/ApplySpeciesFrequencyRafaleAction.java @@ -103,7 +103,18 @@ public class ApplySpeciesFrequencyRafaleAction { int rowIndex = obsTableModel.getRowIndex(obsRow); SwingUtilities.invokeLater(() -> { - selectRow(ui.getObsTable(), rowIndex); + + model.getIndividualObservationModel().getSamplingNotificationZoneModel().setValueAdjusting(true); + + try { + + selectRow(ui.getObsTable(), rowIndex); + + } finally { + + model.getIndividualObservationModel().getSamplingNotificationZoneModel().setValueAdjusting(false); + + } }); diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/CancelEditSpeciesFrequencyAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/CancelEditSpeciesFrequencyAction.java index fdd33b3..7dabf74 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/CancelEditSpeciesFrequencyAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/CancelEditSpeciesFrequencyAction.java @@ -26,7 +26,7 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.ac import fr.ifremer.tutti.ui.swing.content.operation.catches.species.edit.SpeciesBatchRowModel; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.IndividualObservationBatchRowModel; -import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.IndividualObservationUICache; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.IndividualObservationBatchUIModel; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUI; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUIHandler; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUIModel; @@ -72,15 +72,16 @@ public class CancelEditSpeciesFrequencyAction extends LongActionSupport<SpeciesF log.debug("Cancel UI " + getUI()); } - IndividualObservationUICache individualObservationUICache = handler.getIndividualObservationUICache(); + SpeciesFrequencyUIModel model = getModel(); - List<IndividualObservationBatchRowModel> individualObservationRows = getModel().getIndividualObservationModel().getRows(); + IndividualObservationBatchUIModel individualObservationModel = model.getIndividualObservationModel(); + List<IndividualObservationBatchRowModel> individualObservationRows = individualObservationModel.getRows(); - handler.removeIndividualObservations(individualObservationRows); + individualObservationModel.removeIndividualObservations(individualObservationRows); - SpeciesBatchRowModel batch = getModel().getBatch(); + SpeciesBatchRowModel batch = model.getBatch(); - individualObservationUICache.addIndividualObservations(batch.getIndividualObservation()); + model.addIndividualObservationsInCache(batch.getIndividualObservation()); // close dialog getHandler().onCloseUI(); diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/EditSampleCodeAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/EditSampleCodeAction.java index e69938a..4f19398 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/EditSampleCodeAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/EditSampleCodeAction.java @@ -24,6 +24,7 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.ac * #L% */ +import fr.ifremer.tutti.service.sampling.SamplingCodePrefix; import fr.ifremer.tutti.ui.swing.TuttiUIContext; import fr.ifremer.tutti.ui.swing.content.operation.catches.individualobservation.SampleCodeEditionPopupUI; import fr.ifremer.tutti.ui.swing.content.operation.catches.individualobservation.SampleCodeEditionPopupUIModel; @@ -59,11 +60,16 @@ public class EditSampleCodeAction extends SimpleActionSupport<SpeciesFrequencyUI IndividualObservationBatchRowModel selectedRow = obsTableModel.getRows().get(selectedRowIndex); SampleCodeEditionPopupUI sampleCodeEditionPopupUI = new SampleCodeEditionPopupUI(ui); + String samplingCode; boolean samplingCodeAvailable = false; boolean modelValid; do { + samplingCode = null; + Integer samplingCodeId = selectedRow.getSamplingCodeId(); - sampleCodeEditionPopupUI.open(selectedRow.getSamplingCodePrefix(), samplingCodeId); + + SamplingCodePrefix samplingCodePrefix = ui.getModel().getIndividualObservationModel().getSamplingCodePrefix(); + sampleCodeEditionPopupUI.open(samplingCodePrefix, samplingCodeId); SampleCodeEditionPopupUIModel model = sampleCodeEditionPopupUI.getModel(); modelValid = model.isValid(); @@ -72,12 +78,12 @@ public class EditSampleCodeAction extends SimpleActionSupport<SpeciesFrequencyUI Integer sampleCode = model.getSampleCode(); - String samplingCode = model.getSampleCodePrefix().toSamplingCode(sampleCode); + samplingCode = samplingCodePrefix.toSamplingCode(sampleCode); if (log.isDebugEnabled()) { log.debug("Test if sampling code " + samplingCode + " is available."); } - samplingCodeAvailable = samplingCodeId.equals(sampleCode) || ui.getHandler().isSamplingCodeAvailable(sampleCode, selectedRow); + samplingCodeAvailable = samplingCodeId.equals(sampleCode) || ui.getModel().getSamplingCodeUICache().canUseSamplingCode(sampleCode); if (!samplingCodeAvailable) { if (log.isDebugEnabled()) { @@ -85,20 +91,21 @@ public class EditSampleCodeAction extends SimpleActionSupport<SpeciesFrequencyUI } TuttiUIContext.getApplicationContext().getErrorHelper().showErrorDialog(t("tutti.editSpeciesFrequencies.error.notAvailableSamplingCode", samplingCode)); - } else { + } + } - if (log.isDebugEnabled()) { - log.debug("Sampling code " + samplingCode + " is available, use it on selected row."); - } + } while (!samplingCodeAvailable && modelValid); - selectedRow.setSamplingCode(samplingCode); - obsTableModel.fireTableRowsUpdated(selectedRowIndex, selectedRowIndex); + if (samplingCode != null) { - } + if (log.isDebugEnabled()) { + log.debug("Sampling code " + samplingCode + " is available, use it on selected row."); } - } while (!samplingCodeAvailable && modelValid); + selectedRow.setSamplingCode(samplingCode); + obsTableModel.fireTableRowsUpdated(selectedRowIndex, selectedRowIndex); + } } } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/ImportMultiPostSpeciesSupportAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/ImportMultiPostSpeciesSupportAction.java index 645e26a..0db76a2 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/ImportMultiPostSpeciesSupportAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/ImportMultiPostSpeciesSupportAction.java @@ -30,6 +30,7 @@ import fr.ifremer.tutti.service.catches.multipost.MultiPostImportResult; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.SpeciesOrBenthosBatchUISupport; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.edit.SpeciesBatchRowModel; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.IndividualObservationBatchRowModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.IndividualObservationBatchUIModel; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyCellComponent; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyRowModel; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUI; @@ -142,8 +143,9 @@ public abstract class ImportMultiPostSpeciesSupportAction extends LongActionSupp model.clear(); // remove all individual observations - List<IndividualObservationBatchRowModel> rows = model.getIndividualObservationModel().getRows(); - handler.removeIndividualObservations(rows); + IndividualObservationBatchUIModel individualObservationModel = model.getIndividualObservationModel(); + List<IndividualObservationBatchRowModel> rows = individualObservationModel.getRows(); + individualObservationModel.removeIndividualObservations(rows); getHandler().loadFrequenciesAndObservations(frequencyRows, individualObservationRows, true); diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/RemoveObservationAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/RemoveObservationAction.java index a9ff830..b8b470a 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/RemoveObservationAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/RemoveObservationAction.java @@ -100,7 +100,7 @@ public class RemoveObservationAction extends SimpleActionSupport<SpeciesFrequenc }); - handler.removeIndividualObservations(rowsToDelete); + model.getIndividualObservationModel().removeIndividualObservations(rowsToDelete); model.setModify(true); } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/ResetSpeciesFrequencyAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/ResetSpeciesFrequencyAction.java index b74ca71..bc02411 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/ResetSpeciesFrequencyAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/ResetSpeciesFrequencyAction.java @@ -24,7 +24,6 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.ac * #L% */ -import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.IndividualObservationBatchRowModel; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUI; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUIHandler; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUIModel; @@ -32,7 +31,6 @@ import fr.ifremer.tutti.ui.swing.util.actions.LongActionSupport; import org.nuiton.jaxx.application.swing.AbstractApplicationUIHandler; import javax.swing.JOptionPane; -import java.util.List; import static org.nuiton.i18n.I18n.t; @@ -95,8 +93,7 @@ public class ResetSpeciesFrequencyAction extends LongActionSupport<SpeciesFreque model.clear(); // remove all individual observations - List<IndividualObservationBatchRowModel> rows = model.getIndividualObservationModel().getRows(); - handler.removeIndividualObservations(rows); + model.getIndividualObservationModel().clear(); } 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 6289320..01b66f8 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 @@ -1522,7 +1522,6 @@ tutti.editSpeciesBatch.table.header.id= tutti.editSpeciesBatch.table.header.id.tip= tutti.editSpeciesBatch.table.header.species= tutti.editSpeciesBatch.table.header.species.tip= -tutti.editSpeciesBatch.table.header.toConfirm= tutti.editSpeciesBatch.table.header.toConfirm.tip= tutti.editSpeciesBatch.table.header.weight= tutti.editSpeciesBatch.table.header.weight.tip= @@ -1619,23 +1618,15 @@ tutti.editSpeciesFrequencies.field.maxStep= tutti.editSpeciesFrequencies.field.maxStep.tip= tutti.editSpeciesFrequencies.field.minStep= tutti.editSpeciesFrequencies.field.minStep.tip= -tutti.editSpeciesFrequencies.field.mode.autoGen= -tutti.editSpeciesFrequencies.field.mode.autoGen.mnemonic= -tutti.editSpeciesFrequencies.field.mode.autoGen.tip= tutti.editSpeciesFrequencies.field.mode.frequencyMode= tutti.editSpeciesFrequencies.field.mode.frequencyMode.mnemonic= tutti.editSpeciesFrequencies.field.mode.frequencyMode.tip= -tutti.editSpeciesFrequencies.field.mode.rafale= -tutti.editSpeciesFrequencies.field.mode.rafale.mnemonic= -tutti.editSpeciesFrequencies.field.mode.rafale.tip= tutti.editSpeciesFrequencies.field.mode.simpleCounting= tutti.editSpeciesFrequencies.field.mode.simpleCounting.mnemonic= tutti.editSpeciesFrequencies.field.mode.simpleCounting.tip= tutti.editSpeciesFrequencies.field.rafaleStep= tutti.editSpeciesFrequencies.field.rafaleStep.tip= tutti.editSpeciesFrequencies.field.rows= -tutti.editSpeciesFrequencies.field.simpleCounting= -tutti.editSpeciesFrequencies.field.simpleCounting.tip= tutti.editSpeciesFrequencies.field.simpleCountingNumber= tutti.editSpeciesFrequencies.field.simpleCountingNumber.tip= tutti.editSpeciesFrequencies.field.simpleCountingWeight= @@ -1646,29 +1637,27 @@ tutti.editSpeciesFrequencies.field.totalNumber= tutti.editSpeciesFrequencies.field.totalNumber.tip= tutti.editSpeciesFrequencies.field.totalWeight= tutti.editSpeciesFrequencies.field.totalWeight.tip= -tutti.editSpeciesFrequencies.field.useRtp= -tutti.editSpeciesFrequencies.field.useRtp.tip= tutti.editSpeciesFrequencies.frequenciesPanel= -tutti.editSpeciesFrequencies.ichtyometerConnected= tutti.editSpeciesFrequencies.individualObservationsPanel= -tutti.editSpeciesFrequencies.label.no.configuration= -tutti.editSpeciesFrequencies.logTable.header.date= tutti.editSpeciesFrequencies.logTable.header.label= -tutti.editSpeciesFrequencies.logTable.header.lengthStep= tutti.editSpeciesFrequencies.logTable.removeRow.confirm.message= tutti.editSpeciesFrequencies.logTable.removeRow.confirm.title= -tutti.editSpeciesFrequencies.removeObservationRow.message= -tutti.editSpeciesFrequencies.removeObservationRows.message= -tutti.editSpeciesFrequencies.removeObservationRows.title= tutti.editSpeciesFrequencies.samplingNeeded.immature= tutti.editSpeciesFrequencies.samplingNeeded.mature= -tutti.editSpeciesFrequencies.samplingNeeded.max= -tutti.editSpeciesFrequencies.samplingNeeded.resume= -tutti.editSpeciesFrequencies.samplingNeeded.resume.noZone= tutti.editSpeciesFrequencies.samplingNeeded.summary= -tutti.editSpeciesFrequencies.samplingNeeded.summary.noZone= -tutti.editSpeciesFrequencies.samplingNeeded.warning= -tutti.editSpeciesFrequencies.samplingTotalCountAttained.warning= +tutti.editSpeciesFrequencies.samplingNotification.warning.fishingOperationNotInAZone= +tutti.editSpeciesFrequencies.samplingNotification.warning.moreThanOneRowSelected= +tutti.editSpeciesFrequencies.samplingNotification.warning.noAlgorithmEntry= +tutti.editSpeciesFrequencies.samplingNotification.warning.noProtocol= +tutti.editSpeciesFrequencies.samplingNotification.warning.noRowSelected= +tutti.editSpeciesFrequencies.samplingNotification.warning.noSamplingRequired= +tutti.editSpeciesFrequencies.samplingNotification.warning.notUsingAlgorithm= +tutti.editSpeciesFrequencies.samplingNotification.warning.samplingDisabled= +tutti.editSpeciesFrequencies.samplingNotification.warning.samplingNeeded= +tutti.editSpeciesFrequencies.samplingNotification.warning.samplingNotUsed= +tutti.editSpeciesFrequencies.samplingNotification.warning.samplingTotalCountAttained= +tutti.editSpeciesFrequencies.samplingNotification.warning.sizeNotDefined= +tutti.editSpeciesFrequencies.samplingNotification.warning.speciesNotInAlgorithm= 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 bbcdcc2..b60f8a9 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 @@ -1528,7 +1528,6 @@ tutti.editSpeciesFrequencies.field.totalNumber=Nombre total tutti.editSpeciesFrequencies.field.totalNumber.tip=Nombre total d'individus des lignes valides tutti.editSpeciesFrequencies.field.totalWeight=Poids total tutti.editSpeciesFrequencies.field.totalWeight.tip=Poids total des lignes valides -tutti.editSpeciesFrequencies.field.useRtp=Utiliser les RTP tutti.editSpeciesFrequencies.field.useRtp.tip=Utiliser les RTP tutti.editSpeciesFrequencies.frequenciesPanel=Mensurations tutti.editSpeciesFrequencies.individualObservationsPanel=Observations individuelles @@ -1540,8 +1539,19 @@ tutti.editSpeciesFrequencies.samplingNeeded.immature=Immature 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.warning=<html><body><strong>Prélevez les pièces calcifiées \!</body></html> -tutti.editSpeciesFrequencies.samplingTotalCountAttained.warning=<html><body><strong>Le nombre de prélèvements requis est atteint \!</body></html> +tutti.editSpeciesFrequencies.samplingNotification.warning.fishingOperationNotInAZone=Le trait n'est pas dans une zone. +tutti.editSpeciesFrequencies.samplingNotification.warning.moreThanOneRowSelected=Plusieurs observations individuelles sélectionnées. +tutti.editSpeciesFrequencies.samplingNotification.warning.noAlgorithmEntry=Pas de correspondance sur l'observation individuelle sélectionnée dans le protocole. +tutti.editSpeciesFrequencies.samplingNotification.warning.noProtocol=Pas de protocole défini. +tutti.editSpeciesFrequencies.samplingNotification.warning.noRowSelected=Aucune observation individuelle sélectionnée. +tutti.editSpeciesFrequencies.samplingNotification.warning.noSamplingRequired=<html><body><em>Prélèvement non requis</body></html> +tutti.editSpeciesFrequencies.samplingNotification.warning.notUsingAlgorithm=L'utilisation de l'algorithme n'est pas activée dans le protocole. +tutti.editSpeciesFrequencies.samplingNotification.warning.samplingDisabled=<html><body><em>L'algorithme de prélèvements des pièces calcifiées n'est pas utilisé</body></html> +tutti.editSpeciesFrequencies.samplingNotification.warning.samplingNeeded=<html><body><strong>Prélevez les pièces calcifiées \!</body></html> +tutti.editSpeciesFrequencies.samplingNotification.warning.samplingNotUsed=<html><body><em>Aucun prélèvement requis sur ce type d'observation individuelle \!</body></html> +tutti.editSpeciesFrequencies.samplingNotification.warning.samplingTotalCountAttained=<html><body><strong>Le nombre de prélèvements requis est atteint \!</body></html> +tutti.editSpeciesFrequencies.samplingNotification.warning.sizeNotDefined=La taille n'est pas définie sur l'observation individuelle sélectionnée. +tutti.editSpeciesFrequencies.samplingNotification.warning.speciesNotInAlgorithm=L'espèce du lot n'est pas connue dans la définition de l'algorithme. 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 diff --git a/tutti-ui-swing/src/test/java/fr/ifremer/tutti/ui/swing/SoundUtilTest.java b/tutti-ui-swing/src/test/java/fr/ifremer/tutti/ui/swing/SoundUtilTest.java index 7813547..f1f5068 100644 --- a/tutti-ui-swing/src/test/java/fr/ifremer/tutti/ui/swing/SoundUtilTest.java +++ b/tutti-ui-swing/src/test/java/fr/ifremer/tutti/ui/swing/SoundUtilTest.java @@ -24,6 +24,7 @@ package fr.ifremer.tutti.ui.swing; import com.google.common.base.Optional; import fr.ifremer.tutti.ui.swing.util.SoundUtil; +import fr.ifremer.tutti.util.Numbers; import org.junit.Test; @@ -36,15 +37,15 @@ public class SoundUtilTest { @Test public void testSound() throws InterruptedException { - testReadNumber(101.5f, "cm"); - testReadNumber(1, "cm"); - testReadNumber(35, "mm"); - testReadNumber(2001, "cm"); - testReadNumber(2300, "cm"); - testReadNumber(2000.5f, "cm"); - testReadNumber(2000, "cm"); - testReadNumber(200, "cm"); - testReadNumber(201, "cm"); + testReadNumber(101.5f, Numbers.CM_UNIT); + testReadNumber(1, Numbers.CM_UNIT); + testReadNumber(35, Numbers.MM_UNIT); + testReadNumber(2001, Numbers.CM_UNIT); + testReadNumber(2300, Numbers.CM_UNIT); + testReadNumber(2000.5f, Numbers.CM_UNIT); + testReadNumber(2000, Numbers.CM_UNIT); + testReadNumber(200, Numbers.CM_UNIT); + testReadNumber(201, Numbers.CM_UNIT); testReadNumber(201, null); } -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.