Author: kmorin Date: 2013-04-22 15:30:21 +0200 (Mon, 22 Apr 2013) New Revision: 849 Url: http://forge.codelutin.com/projects/tutti/repository/revisions/849 Log: fixes #2252 [RAPPORT] - G?\195?\169n?\195?\169ration d'un fichier CSV de synth?\195?\168se pour le logiciel SUMATRA debug weight computing for benthos Added: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/sumatra/ trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/sumatra/CatchRow.java trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/sumatra/CatchRowModel.java trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/sumatra/TuttiCatchesSumatraExportService.java trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/home/ExportCruiseForSumatraAction.java Modified: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/catches/TuttiWeightComputingService.java trunk/tutti-service/src/main/resources/i18n/tutti-service_en_GB.properties trunk/tutti-service/src/main/resources/i18n/tutti-service_fr_FR.properties trunk/tutti-ui-swing/src/main/filtered-resources/tutti-help-en.properties trunk/tutti-ui-swing/src/main/filtered-resources/tutti-help-fr.properties trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiUIContext.java trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/home/SelectCruiseUI.css trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/home/SelectCruiseUI.jaxx trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/BenthosBatchUIHandler.java trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/SpeciesBatchUIHandler.java trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties Modified: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/catches/TuttiWeightComputingService.java =================================================================== --- trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/catches/TuttiWeightComputingService.java 2013-04-22 09:51:45 UTC (rev 848) +++ trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/catches/TuttiWeightComputingService.java 2013-04-22 13:30:21 UTC (rev 849) @@ -479,8 +479,7 @@ // if the weight of the frequencies is different from the category // weight, then set the weight of the sample if (frequencyWeight > categoryWeight) { - throw new TuttiWeightComputingException(_ - ("tutti.service.operations.computeWeights.species.error.incoherentCategoryWeight"), + throw new TuttiWeightComputingException(_("tutti.service.operations.computeWeights.species.error.incoherentCategoryWeight"), TuttiWeightComputingException.CatchType.SPECIES, thisIndex); Added: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/sumatra/CatchRow.java =================================================================== --- trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/sumatra/CatchRow.java (rev 0) +++ trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/sumatra/CatchRow.java 2013-04-22 13:30:21 UTC (rev 849) @@ -0,0 +1,63 @@ +package fr.ifremer.tutti.service.sumatra; + +import fr.ifremer.tutti.persistence.entities.data.FishingOperation; +import fr.ifremer.tutti.persistence.entities.referential.Species; + +import java.io.Serializable; + +/** + * @author kmorin <kmorin@codelutin.com> + * @since 2.0 + */ +public class CatchRow implements Serializable { + + private static final long serialVersionUID = 1L; + + public static final String PROPERTY_FISHING_OPERATION = "fishingOperation"; + + public static final String PROPERTY_SPECIES = "species"; + + public static final String PROPERTY_WEIGHT = "weight"; + + public static final String PROPERTY_NUMBER = "number"; + + protected FishingOperation fishingOperation; + + protected Species species; + + protected Float weight; + + protected Integer number; + + public FishingOperation getFishingOperation() { + return fishingOperation; + } + + public void setFishingOperation(FishingOperation fishingOperation) { + this.fishingOperation = fishingOperation; + } + + public Species getSpecies() { + return species; + } + + public void setSpecies(Species species) { + this.species = species; + } + + public Float getWeight() { + return weight; + } + + public void setWeight(Float weight) { + this.weight = weight; + } + + public Integer getNumber() { + return number; + } + + public void setNumber(Integer number) { + this.number = number; + } +} Added: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/sumatra/CatchRowModel.java =================================================================== --- trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/sumatra/CatchRowModel.java (rev 0) +++ trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/sumatra/CatchRowModel.java 2013-04-22 13:30:21 UTC (rev 849) @@ -0,0 +1,46 @@ +package fr.ifremer.tutti.service.sumatra; + +import com.google.common.base.Preconditions; +import fr.ifremer.tutti.persistence.entities.data.FishingOperation; +import fr.ifremer.tutti.persistence.entities.referential.Species; +import fr.ifremer.tutti.service.TuttiCsvUtil; +import org.nuiton.util.csv.Common; +import org.nuiton.util.csv.ValueFormatter; + +import static org.nuiton.i18n.I18n._; + +/** + * @author kmorin <kmorin@codelutin.com> + * @since 2.0 + */ +public class CatchRowModel extends TuttiCsvUtil.AbstractTuttiImportExportModel<CatchRow> { + + public CatchRowModel(char separator) { + super(separator); + + // export definition + + newColumnForExport(_("tutti.service.exportSumatra.header.station"), CatchRow.PROPERTY_FISHING_OPERATION, new ValueFormatter<FishingOperation>() { + @Override + public String format(FishingOperation o) { + Preconditions.checkNotNull(o, _("tutti.service.exportSumatra.error.station.null")); + return o.getStationNumber() + String.format("%04d", o.getFishingOperationNumber()); + } + }); + newColumnForExport(_("tutti.service.exportSumatra.header.species"), CatchRow.PROPERTY_SPECIES, new ValueFormatter<Species>() { + @Override + public String format(Species s) { + Preconditions.checkNotNull(s, _("tutti.service.exportSumatra.error.species.null")); + return s.getName(); + } + }); + newColumnForExport(_("tutti.service.exportSumatra.header.weight"), CatchRow.PROPERTY_WEIGHT, Common.PRIMITIVE_FLOAT); + newColumnForExport(_("tutti.service.exportSumatra.header.number"), CatchRow.PROPERTY_NUMBER, Common.PRIMITIVE_INTEGER); + } + + @Override + public CatchRow newEmptyInstance() { + return new CatchRow(); + } + +} Added: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/sumatra/TuttiCatchesSumatraExportService.java =================================================================== --- trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/sumatra/TuttiCatchesSumatraExportService.java (rev 0) +++ trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/sumatra/TuttiCatchesSumatraExportService.java 2013-04-22 13:30:21 UTC (rev 849) @@ -0,0 +1,162 @@ +package fr.ifremer.tutti.service.sumatra; + +import com.google.common.base.Charsets; +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.io.Files; +import fr.ifremer.tutti.TuttiTechnicalException; +import fr.ifremer.tutti.persistence.entities.data.*; +import fr.ifremer.tutti.persistence.entities.referential.Species; +import fr.ifremer.tutti.service.AbstractTuttiService; +import fr.ifremer.tutti.service.PersistenceService; +import fr.ifremer.tutti.service.TuttiServiceContext; +import fr.ifremer.tutti.service.catches.TuttiWeightComputingService; +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.util.csv.Export; + +import java.io.BufferedWriter; +import java.io.File; +import java.util.List; +import java.util.Map; + +/** + * @author kmorin <kmorin@codelutin.com> + * @since 2.0 + */ +public class TuttiCatchesSumatraExportService extends AbstractTuttiService { + + private static final Log log = + LogFactory.getLog(TuttiCatchesSumatraExportService.class); + + public static final char CSV_SEPARATOR = ';'; + + protected PersistenceService persistenceService; + + protected TuttiWeightComputingService tuttiWeightComputingService; + + @Override + public void setServiceContext(TuttiServiceContext context) { + super.setServiceContext(context); + persistenceService = getService(PersistenceService.class); + tuttiWeightComputingService = getService(TuttiWeightComputingService.class); + } + + public void exportCruiseForSumatra(File file, + String cruiseId) { + + Preconditions.checkNotNull(cruiseId, "Cannot export a null cruise"); + + if (log.isInfoEnabled()) { + log.info("Will export cruise " + cruiseId + " to file: " + file); + } + + Cruise cruise = persistenceService.getCruise(cruiseId); + Preconditions.checkNotNull(cruise, "Cruise not found"); + + CatchRowModel csvModel = + new CatchRowModel(CSV_SEPARATOR); + List<CatchRow> rows = Lists.newArrayList(); + + List<FishingOperation> operations = persistenceService.getAllFishingOperation(cruiseId); + if (operations != null) { + for (FishingOperation operation : operations) { + + // add species rows + + BatchContainer<SpeciesBatch> speciesBatchContainer = + tuttiWeightComputingService.getComputedSpeciesBatches(operation); + + Map<Species, CatchRow> rowMap = Maps.newHashMap(); + List<SpeciesBatch> speciesBatches = speciesBatchContainer.getChildren(); + for (SpeciesBatch batch : speciesBatches) { + Species sp = batch.getSpecies(); + + Float weight = batch.getSampleCategoryWeight(); + if (weight == null) { + weight = batch.getSampleCategoryComputedWeight(); + } + + Integer nb = batch.getNumber(); + if (nb == null) { + nb = batch.getComputedNumber(); + } + if (nb == null) { + nb = 0; + } + + CatchRow row = rowMap.get(sp); + if (row == null) { + row = new CatchRow(); + row.setFishingOperation(operation); + row.setSpecies(sp); + row.setWeight(weight); + row.setNumber(nb); + + } else { + row.setWeight(row.getWeight() + weight); + row.setNumber(row.getNumber() + nb); + } + rowMap.put(sp, row); + } + + rows.addAll(rowMap.values()); + + // add benthos rows + + BatchContainer<BenthosBatch> benthosBatchContainer = + tuttiWeightComputingService.getComputedBenthosBatches(operation); + + rowMap.clear(); + List<BenthosBatch> benthosBatches = benthosBatchContainer.getChildren(); + for (BenthosBatch batch : benthosBatches) { + Species sp = batch.getSpecies(); + + Float weight = batch.getSampleCategoryWeight(); + if (weight == null) { + weight = batch.getSampleCategoryComputedWeight(); + } + + Integer nb = batch.getNumber(); + if (nb == null) { + nb = batch.getComputedNumber(); + } + if (nb == null) { + nb = 0; + } + + CatchRow row = rowMap.get(sp); + if (row == null) { + row = new CatchRow(); + row.setFishingOperation(operation); + row.setSpecies(sp); + row.setWeight(weight); + row.setNumber(nb); + + } else { + row.setWeight(row.getWeight() + weight); + row.setNumber(row.getNumber() + nb); + } + rowMap.put(sp, row); + } + + rows.addAll(rowMap.values()); + } + } + + BufferedWriter writer = null; + try { + writer = Files.newWriter(file, Charsets.UTF_8); + Export export = Export.newExport(csvModel, rows); + export.write(writer); + writer.close(); + + } catch (Exception e) { + throw new TuttiTechnicalException("Could not export all caracteristics to file " + file, e); + } finally { + IOUtils.closeQuietly(writer); + } + } +} Modified: trunk/tutti-service/src/main/resources/i18n/tutti-service_en_GB.properties =================================================================== --- trunk/tutti-service/src/main/resources/i18n/tutti-service_en_GB.properties 2013-04-22 09:51:45 UTC (rev 848) +++ trunk/tutti-service/src/main/resources/i18n/tutti-service_en_GB.properties 2013-04-22 13:30:21 UTC (rev 849) @@ -55,6 +55,12 @@ tutti.service.exportCruise.exportOperations= tutti.service.exportCruise.exportParameters= tutti.service.exportCruise.exportSurvey= +tutti.service.exportSumatra.error.species.null= +tutti.service.exportSumatra.error.station.null= +tutti.service.exportSumatra.header.number= +tutti.service.exportSumatra.header.species= +tutti.service.exportSumatra.header.station= +tutti.service.exportSumatra.header.weight= tutti.service.operations.computeWeights.benthos.error.incoherentCategoryWeight= tutti.service.operations.computeWeights.benthos.error.incoherentParentCategoryWeight= tutti.service.operations.computeWeights.benthos.error.incoherentRowWeightFrequency= Modified: trunk/tutti-service/src/main/resources/i18n/tutti-service_fr_FR.properties =================================================================== --- trunk/tutti-service/src/main/resources/i18n/tutti-service_fr_FR.properties 2013-04-22 09:51:45 UTC (rev 848) +++ trunk/tutti-service/src/main/resources/i18n/tutti-service_fr_FR.properties 2013-04-22 13:30:21 UTC (rev 849) @@ -55,6 +55,12 @@ tutti.service.exportCruise.exportOperations=Export du fichier <strong>operations.csv</strong> pour la campagne %s tutti.service.exportCruise.exportParameters=Export du fichier <strong>parameters.csv</strong> pour la campagne %s tutti.service.exportCruise.exportSurvey=Export du fichier <strong>survey.csv</strong> pour la campagne %s +tutti.service.exportSumatra.error.species.null=L'espèce est nulle +tutti.service.exportSumatra.error.station.null=Le trait est nul +tutti.service.exportSumatra.header.number=NbIndividus +tutti.service.exportSumatra.header.species=Espèce +tutti.service.exportSumatra.header.station=Station +tutti.service.exportSumatra.header.weight=Total tutti.service.operations.computeWeights.benthos.error.incoherentCategoryWeight=Le poids total des mensurations d'un lot du benthos est supérieur au poids de la catégorie tutti.service.operations.computeWeights.benthos.error.incoherentParentCategoryWeight=Le poids de la catégorie d'un lot du benthos est différent de la somme des poids de ses sous-catégories tutti.service.operations.computeWeights.benthos.error.incoherentRowWeightFrequency=Le poids total des mensurations d'un lot du benthos est différent du poids du sous-échantillon Modified: trunk/tutti-ui-swing/src/main/filtered-resources/tutti-help-en.properties =================================================================== --- trunk/tutti-ui-swing/src/main/filtered-resources/tutti-help-en.properties 2013-04-22 09:51:45 UTC (rev 848) +++ trunk/tutti-ui-swing/src/main/filtered-resources/tutti-help-en.properties 2013-04-22 13:30:21 UTC (rev 849) @@ -1,28 +1,5 @@ -### -# #%L -# Tutti :: UI -# $Id$ -# $HeadURL$ -# %% -# Copyright (C) 2012 - 2013 Ifremer -# %% -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public -# License along with this program. If not, see -# <http://www.gnu.org/licenses/gpl-3.0.html>. -# #L% -### #Generated by org.nuiton.jaxx.plugin.GenerateHelpIdsMojo -#Mon Apr 22 08:30:46 CEST 2013 +#Mon Apr 22 10:46:45 CEST 2013 tutti.config.help=config.html tutti.createAccidentalBatch.action.cancel.help=createAccidentalBatch.html\#actions tutti.createAccidentalBatch.action.save.help=createAccidentalBatch.html\#actions @@ -248,6 +225,9 @@ tutti.fishingOperations.field.fishingOperation.help=fishingOperations.html\#fields tutti.fishingOperations.help=fishingOperations.html tutti.index.help=index.html +tutti.main.action.changeLocale.help= +tutti.main.action.changeLocaleFR.help= +tutti.main.action.changeLocaleUK.help= tutti.main.action.showHelp.help=index.html\#menu tutti.main.help=index.html tutti.main.menu.action.about.help=index.html\#menu @@ -283,6 +263,7 @@ tutti.selectCruise.action.editProgram.help=selectCruise.html\#actions tutti.selectCruise.action.editProtocol.help=selectCruise.html\#actions tutti.selectCruise.action.exportCruise.help= +tutti.selectCruise.action.exportCruiseForSumatra.help= tutti.selectCruise.action.exportProgram.help= tutti.selectCruise.action.exportProtocol.help=selectCruise.html\#actions tutti.selectCruise.action.importProtocol.help=selectCruise.html\#actions @@ -310,3 +291,8 @@ tutti.splitSpeciesBatch.field.sampleWeightField.help=splitSpeciesBatch.html\#fields tutti.splitSpeciesBatch.field.speciesField.help=splitSpeciesBatch.html\#fields tutti.splitSpeciesBatch.help=splitSpeciesBatch.html +tuttihelp.config.help= +tuttihelp.editAccidentalBatch.help= +tuttihelp.editIndividualObservationBatch.help= +tuttihelp.editMarineLitterBatch.help= +tuttihelp.editPlanktonBatch.help= Modified: trunk/tutti-ui-swing/src/main/filtered-resources/tutti-help-fr.properties =================================================================== --- trunk/tutti-ui-swing/src/main/filtered-resources/tutti-help-fr.properties 2013-04-22 09:51:45 UTC (rev 848) +++ trunk/tutti-ui-swing/src/main/filtered-resources/tutti-help-fr.properties 2013-04-22 13:30:21 UTC (rev 849) @@ -1,28 +1,5 @@ -### -# #%L -# Tutti :: UI -# $Id$ -# $HeadURL$ -# %% -# Copyright (C) 2012 - 2013 Ifremer -# %% -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public -# License along with this program. If not, see -# <http://www.gnu.org/licenses/gpl-3.0.html>. -# #L% -### #Generated by org.nuiton.jaxx.plugin.GenerateHelpIdsMojo -#Mon Apr 22 08:30:46 CEST 2013 +#Mon Apr 22 10:46:45 CEST 2013 tutti.config.help=config.html tutti.createAccidentalBatch.action.cancel.help=createAccidentalBatch.html\#actions tutti.createAccidentalBatch.action.save.help=createAccidentalBatch.html\#actions @@ -248,6 +225,9 @@ tutti.fishingOperations.field.fishingOperation.help=fishingOperations.html\#fields tutti.fishingOperations.help=fishingOperations.html tutti.index.help=index.html +tutti.main.action.changeLocale.help= +tutti.main.action.changeLocaleFR.help= +tutti.main.action.changeLocaleUK.help= tutti.main.action.showHelp.help=index.html\#menu tutti.main.help=index.html tutti.main.menu.action.about.help=index.html\#menu @@ -283,6 +263,7 @@ tutti.selectCruise.action.editProgram.help=selectCruise.html\#actions tutti.selectCruise.action.editProtocol.help=selectCruise.html\#actions tutti.selectCruise.action.exportCruise.help= +tutti.selectCruise.action.exportCruiseForSumatra.help= tutti.selectCruise.action.exportProgram.help= tutti.selectCruise.action.exportProtocol.help=selectCruise.html\#actions tutti.selectCruise.action.importProtocol.help=selectCruise.html\#actions @@ -310,3 +291,8 @@ tutti.splitSpeciesBatch.field.sampleWeightField.help=splitSpeciesBatch.html\#fields tutti.splitSpeciesBatch.field.speciesField.help=splitSpeciesBatch.html\#fields tutti.splitSpeciesBatch.help=splitSpeciesBatch.html +tuttihelp.config.help= +tuttihelp.editAccidentalBatch.help= +tuttihelp.editIndividualObservationBatch.help= +tuttihelp.editMarineLitterBatch.help= +tuttihelp.editPlanktonBatch.help= Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiUIContext.java =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiUIContext.java 2013-04-22 09:51:45 UTC (rev 848) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiUIContext.java 2013-04-22 13:30:21 UTC (rev 849) @@ -44,6 +44,7 @@ import fr.ifremer.tutti.service.pupitri.TuttiPupitriImportExportService; import fr.ifremer.tutti.service.referential.TuttiReferentialImportExportService; import fr.ifremer.tutti.service.referential.TuttiReferentialSynchronizeService; +import fr.ifremer.tutti.service.sumatra.TuttiCatchesSumatraExportService; import fr.ifremer.tutti.ui.swing.config.TuttiApplicationConfig; import fr.ifremer.tutti.ui.swing.content.MainUI; import fr.ifremer.tutti.ui.swing.util.TuttiErrorHelper; @@ -542,6 +543,10 @@ return serviceContext.getService(TuttiExportService.class); } + public TuttiCatchesSumatraExportService getCatchesSumatraExportService() { + return serviceContext.getService(TuttiCatchesSumatraExportService.class); + } + public boolean useRealPersistenceService() { return isDbExist() && isDbLoaded(); } Copied: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/home/ExportCruiseForSumatraAction.java (from rev 827, trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/home/SendCruiseReportAction.java) =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/home/ExportCruiseForSumatraAction.java (rev 0) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/home/ExportCruiseForSumatraAction.java 2013-04-22 13:30:21 UTC (rev 849) @@ -0,0 +1,89 @@ +package fr.ifremer.tutti.ui.swing.content.home; + +import com.google.common.base.Preconditions; +import fr.ifremer.tutti.TuttiIOUtil; +import fr.ifremer.tutti.persistence.entities.data.Cruise; +import fr.ifremer.tutti.service.catches.ExportCatchesReportService; +import fr.ifremer.tutti.service.sumatra.TuttiCatchesSumatraExportService; +import fr.ifremer.tutti.ui.swing.util.TuttiUIUtil; +import fr.ifremer.tutti.ui.swing.util.action.AbstractTuttiAction; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.File; + +import static org.nuiton.i18n.I18n._; + +/** + * Opens a file chooser, exports the cruise catches into the selected file and open the default email editor. + * + * @author kmorin <morin@codelutin.com> + * @since 1.0 + */ +public class ExportCruiseForSumatraAction extends AbstractTuttiAction<SelectCruiseUIModel, SelectCruiseUI, SelectCruiseUIHandler> { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ExportCruiseForSumatraAction.class); + + protected File file; + + public ExportCruiseForSumatraAction(SelectCruiseUIHandler handler) { + super(handler, true); + } + + @Override + protected boolean prepareAction() throws Exception { + + boolean doAction = super.prepareAction(); + + if (doAction) { + + // choose file to export + file = TuttiUIUtil.chooseFile( + getContext().getMainUI(), + _("tutti.exportCruiseForSumatra.title.choose.exportFile"), + _("tutti.exportCruiseForSumatra.action.chooseFile"), + "^.+\\.csv$", _("tutti.common.file.csv") + ); + doAction = file != null; + if (doAction) { + file = TuttiIOUtil.addExtensionIfMissing(file, ".csv"); + + // ask user to confirm overwrite. + doAction = getHandler().askOverwriteFile(file); + } + } + return doAction; + } + + @Override + protected void releaseAction() { + file = null; + super.releaseAction(); + } + + @Override + protected void doAction() throws Exception { + Cruise cruise = getModel().getCruise(); + Preconditions.checkNotNull(cruise); + Preconditions.checkNotNull(file); + + if (log.isInfoEnabled()) { + log.info("Will export cruise " + cruise.getId() + + " to file: " + file); + } + + // export catches + TuttiCatchesSumatraExportService service = + getContext().getCatchesSumatraExportService(); + service.exportCruiseForSumatra(file, cruise.getId()); + + } + + @Override + public void postSuccessAction() { + super.postSuccessAction(); + sendMessage(_("tutti.exportCruiseForSumatra.action.success", file)); + } +} Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/home/SelectCruiseUI.css =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/home/SelectCruiseUI.css 2013-04-22 09:51:45 UTC (rev 848) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/home/SelectCruiseUI.css 2013-04-22 13:30:21 UTC (rev 849) @@ -106,7 +106,7 @@ } #editCruiseComboBox { - model: {handler.newComboModel(editCruiseButton, exportCruiseButton, sendCruiseReportButton)}; + model: {handler.newComboModel(editCruiseButton, exportCruiseButton, sendCruiseReportButton, exportCruiseForSumatraButton)}; enabled: {model.isProgramFound() && model.isCruiseFound()}; renderer: {new ActionListCellRenderer()}; } @@ -135,6 +135,14 @@ _help: {"tutti.selectCruise.action.sendCruiseReport.help"}; } +#exportCruiseForSumatraButton { + actionIcon: export; + text: "tutti.selectCruise.action.exportCruiseForSumatra"; + toolTipText: "tutti.selectCruise.action.exportCruiseForSumatra.tip"; + _tuttiAction: {ExportCruiseForSumatraAction.class}; + _help: {"tutti.selectCruise.action.exportCruiseForSumatra.help"}; +} + #newCruiseButton { actionIcon: add; text: "tutti.selectCruise.action.newCruise"; Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/home/SelectCruiseUI.jaxx =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/home/SelectCruiseUI.jaxx 2013-04-22 09:51:45 UTC (rev 848) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/home/SelectCruiseUI.jaxx 2013-04-22 13:30:21 UTC (rev 849) @@ -78,6 +78,7 @@ <JButton id='editCruiseButton'/> <JButton id='exportCruiseButton'/> <JButton id='sendCruiseReportButton'/> + <JButton id='exportCruiseForSumatraButton'/> <JButton id='newProtocolButton'/> <JButton id='importProtocolButton'/> <JButton id='editProtocolButton'/> Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/BenthosBatchUIHandler.java =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/BenthosBatchUIHandler.java 2013-04-22 09:51:45 UTC (rev 848) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/BenthosBatchUIHandler.java 2013-04-22 13:30:21 UTC (rev 849) @@ -55,6 +55,7 @@ import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.split.SplitBenthosBatchRowModel; import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.split.SplitBenthosBatchUI; import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.split.SplitBenthosBatchUIModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.SpeciesBatchRowModel; import fr.ifremer.tutti.ui.swing.util.TuttiBeanMonitor; import fr.ifremer.tutti.ui.swing.util.TuttiUI; import fr.ifremer.tutti.ui.swing.util.TuttiUIUtil; @@ -820,7 +821,8 @@ newBatch, sampleCategoryEnum, row.getCategoryValue(), - row.getWeight()); + row.getWeight(), + null); recomputeRowValidState(newBatch); newBatches.add(newBatch); @@ -1056,11 +1058,11 @@ BenthosBatchRowModel parentRow, List<BenthosBatchRowModel> rows) { + String id = aBatch.getId(); + List<BenthosBatchFrequency> frequencies = - persistenceService.getAllBenthosBatchFrequency(aBatch.getId()); + persistenceService.getAllBenthosBatchFrequency(id); - - BenthosBatchRowModel newRow = new BenthosBatchRowModel(aBatch, frequencies); @@ -1091,7 +1093,8 @@ newRow, sampleCategoryEnum, aBatch.getSampleCategoryValue(), - aBatch.getSampleCategoryWeight()); + aBatch.getSampleCategoryWeight(), + aBatch.getSampleCategoryComputedWeight()); rows.add(newRow); @@ -1102,10 +1105,27 @@ List<BenthosBatchRowModel> batchChilds = Lists. newArrayListWithCapacity(aBatch.sizeChildBatchs()); + Float childrenWeights = 0f; for (BenthosBatch childBatch : aBatch.getChildBatchs()) { BenthosBatchRowModel childRow = loadBatch(childBatch, newRow, rows); + if (childrenWeights != null) { + Float weight = childRow.getFinestCategory().getNotNullWeight(); + if (weight == null) { + childrenWeights = null; + } else { + childrenWeights += weight; + } + } batchChilds.add(childRow); } + + Float rowWeight = newRow.getFinestCategory().getNotNullWeight(); + boolean subSample = rowWeight != null && childrenWeights != null + && childrenWeights < rowWeight; + for (BenthosBatchRowModel childRow : batchChilds) { + childRow.getFinestCategory().setSubSample(subSample); + } + newRow.setChildBatch(batchChilds); } @@ -1116,7 +1136,8 @@ BenthosBatchRowModel newRow, SampleCategoryEnum sampleCategoryEnum, Serializable categoryValue, - Float categoryWeight) { + Float categoryWeight, + Float categoryComputedWeight) { // get sample category from his type SampleCategory sampleCategory = @@ -1125,6 +1146,7 @@ // fill it sampleCategory.setCategoryValue(categoryValue); sampleCategory.setCategoryWeight(categoryWeight); + sampleCategory.setComputedWeight(categoryComputedWeight); // push it back to row as his *main* sample category newRow.setSampleCategory(sampleCategory); Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/SpeciesBatchUIHandler.java =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/SpeciesBatchUIHandler.java 2013-04-22 09:51:45 UTC (rev 848) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/SpeciesBatchUIHandler.java 2013-04-22 13:30:21 UTC (rev 849) @@ -355,25 +355,6 @@ recomputeBatchActionEnable(); } -// @Override -// protected void onRowModified(int rowIndex, -// SpeciesBatchRowModel row, -// String propertyName, -// Object oldValue, -// Object newValue) { -// -// if (SAMPLING_PROPERTIES.contains(propertyName)) { -// -// // species has changed, recompute valid property -// recomputeRowValidState(row); -// } -// -// saveSelectedRowIfNeeded(); -// -// // when row valid state has changed, recompute action enabled states -// recomputeBatchActionEnable(); -// } - @Override protected void saveSelectedRowIfRequired(TuttiBeanMonitor<SpeciesBatchRowModel> rowMonitor, SpeciesBatchRowModel row) { @@ -543,13 +524,6 @@ initUI(ui); -// SwingUtil.applyDataBinding( -// ui, -// SpeciesBatchUI.BINDING_CREATE_SPECIES_MELAG_MENU_ENABLED, -// SpeciesBatchUI.BINDING_REMOVE_SPECIES_BATCH_MENU_ENABLED, -// SpeciesBatchUI.BINDING_REMOVE_SPECIES_SUB_BATCH_MENU_ENABLED, -// SpeciesBatchUI.BINDING_RENAME_SPECIES_BATCH_MENU_ENABLED); - Map<Integer, SampleCategoryEnum> categoryEnumMap = SampleCategoryEnum.toIdMapping(); Modified: trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties =================================================================== --- trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties 2013-04-22 09:51:45 UTC (rev 848) +++ trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties 2013-04-22 13:30:21 UTC (rev 849) @@ -344,6 +344,13 @@ tutti.editCatchBatch.action.cancelEditCatchBatch.mnemonic= tutti.editCatchBatch.action.cancelEditCatchBatch.tip= tutti.editCatchBatch.action.computeWeights= +tutti.editCatchBatch.action.computeWeights.error.incoherentCategoryWeight= +tutti.editCatchBatch.action.computeWeights.error.incoherentParentCategoryWeight= +tutti.editCatchBatch.action.computeWeights.error.incoherentRowWeightCategory= +tutti.editCatchBatch.action.computeWeights.error.incoherentRowWeightFrequency= +tutti.editCatchBatch.action.computeWeights.error.incoherentSpeciesTotalSorted= +tutti.editCatchBatch.action.computeWeights.error.incoherentTotal= +tutti.editCatchBatch.action.computeWeights.error.noWeight= tutti.editCatchBatch.action.computeWeights.mnemonic= tutti.editCatchBatch.action.computeWeights.replaceTotalSortedWeight.help= tutti.editCatchBatch.action.computeWeights.replaceTotalSortedWeight.message= @@ -354,6 +361,8 @@ tutti.editCatchBatch.action.importPupitri.existingData.message= tutti.editCatchBatch.action.importPupitri.existingData.title= tutti.editCatchBatch.action.importPupitri.mnemonic= +tutti.editCatchBatch.action.importPupitri.noProtocol.message= +tutti.editCatchBatch.action.importPupitri.noProtocol.title= tutti.editCatchBatch.action.importPupitri.success= tutti.editCatchBatch.action.importPupitri.tip= tutti.editCatchBatch.action.saveCatchBatch= @@ -410,6 +419,8 @@ tutti.editCruise.field.beginDate.tip= tutti.editCruise.field.comment= tutti.editCruise.field.comment.tip= +tutti.editCruise.field.country= +tutti.editCruise.field.country.tip= tutti.editCruise.field.departureLocation= tutti.editCruise.field.departureLocation.tip= tutti.editCruise.field.endDate= @@ -800,6 +811,9 @@ tutti.error.ui.business.error= tutti.error.ui.other.error= tutti.exportCruise.action.success= +tutti.exportCruiseForSumatra.action.chooseFile= +tutti.exportCruiseForSumatra.action.success= +tutti.exportCruiseForSumatra.title.choose.exportFile= tutti.exportProgram.action.success= tutti.exportProtocol.action.success= tutti.fishingOperations.action.newFishingOperation.mnemonic= @@ -1010,6 +1024,8 @@ tutti.selectCruise.action.editProtocol.tip= tutti.selectCruise.action.exportCruise= tutti.selectCruise.action.exportCruise.tip= +tutti.selectCruise.action.exportCruiseForSumatra= +tutti.selectCruise.action.exportCruiseForSumatra.tip= tutti.selectCruise.action.exportProgram= tutti.selectCruise.action.exportProgram.tip= tutti.selectCruise.action.exportProtocol= Modified: trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties =================================================================== --- trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties 2013-04-22 09:51:45 UTC (rev 848) +++ trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties 2013-04-22 13:30:21 UTC (rev 849) @@ -7,6 +7,7 @@ tutti.about.bottomText=Copyright %s - %s - version %s tutti.about.message=<h3>Tutti</h3><p><strong>Outil de saisie de données d'opérations et de captures au cours des campagnes halieutiques.</strong></p><br/><p>Ce logiciel permettra la saisie en mer des données d'opération de pêche (positions, environnement, engin, etc) et des captures associées (composition de la capture en espèces scientifiques avec poids, nombres, tailles etc) pour l'ensemble des campagnes halieutiques réalisées par l'Ifremer.</p><p>Ce projet a été initiée en 2012 par l'<a href\="http\://www.ifremer.fr">Ifremer</a> et réalisé par la société <a href\="http\://codelutin.com">Codelutin</a>.</p><hr/><br/><p>Pour plus d'informations, vous pouvez visiter le <a href\="http\://maven-site.forge.codelutin.com/tutti">site du projet</a>.</p><p>Projet hébergé sur la forge <a href\="http\://forge.codelutin.com/projects/tutti">Forge.codelutin.com</a>.</p> tutti.about.title=À propos de Tutti +tutti.label.tab.species=Espèces tutti.about.translate.content=<h2>Comment traduire Tutti</h2>Vous pouvez nous aider à traduire Tutti.<hr/><br/><ul><li>Récupérer le fichier <a href\="%s">tutti-i18n.csv</a> dans le répertoire <strong>i18n</strong></li><li>ouvrez le avec un tableur (le caractère séprateur est une Tabultation)</li><li>Traduisez, Améliorer, ...</li><li>Enfin renvoyez-le nous</li></ul><br/>Nous intégrerons vos modifications avant la prochaine version. tutti.about.translate.title=Traduire Tutti tutti.about.update.app.noup.detail=<tr><td>%1$s</td><td>%2$s</td><td>%2$s<td><td></td></tr> @@ -799,6 +800,9 @@ tutti.error.ui.business.error=Erreur tutti.error.ui.other.error=Erreur tutti.exportCruise.action.success=La campagne <strong>%s</strong> a été exportée dans le fichier <strong>%s</strong>. +tutti.exportCruiseForSumatra.action.chooseFile=Choisir le fichier d'export +tutti.exportCruiseForSumatra.action.success=Les captures ont correctement été exporté dans le fichier %s +tutti.exportCruiseForSumatra.title.choose.exportFile=Exporter les captures de la campagne tutti.exportProgram.action.success=La série de campagne <strong>%s</strong> a été exportée dans le fichier <strong>%s</strong>. tutti.exportProtocol.action.success=Protocole [%1s] exporté dans le fichier <strong>%2s</strong>. tutti.fishingOperations.action.newFishingOperation.mnemonic=N @@ -1005,11 +1009,13 @@ tutti.selectCruise.action.editProgram=Éditer tutti.selectCruise.action.editProgram.tip=Éditer le programme sélectionné tutti.selectCruise.action.editProtocol=Éditer -tutti.selectCruise.action.editProtocol.tip=Éditer le protocole sélectionné +tutti.selectCruise.action.editProtocol.tip=Éditer le protocol sélectionné tutti.selectCruise.action.exportCruise=Exporter -tutti.selectCruise.action.exportCruise.tip=Exporter la campagne au format générique +tutti.selectCruise.action.exportCruise.tip=Exporter la campagne sélectionnée +tutti.selectCruise.action.exportCruiseForSumatra=Sumatra +tutti.selectCruise.action.exportCruiseForSumatra.tip=Exporter la campagne sélectionnée pour Sumatra tutti.selectCruise.action.exportProgram=Exporter -tutti.selectCruise.action.exportProgram.tip=Exporter les campagnes de la série au format générique +tutti.selectCruise.action.exportProgram.tip=Exporter la série sélectionnée tutti.selectCruise.action.exportProtocol=Exporter tutti.selectCruise.action.exportProtocol.tip=Exporter le protocole sélectionné tutti.selectCruise.action.importProtocol=Importer @@ -1048,7 +1054,7 @@ tutti.sendCruiseReport.action.success=Les captures ont correctement été exporté dans le fichier %s tutti.sendCruiseReport.mail.body=Bonjour,\n\nVeuillez trouver ci-joint le rapport des captures de la campagne %1s.\n*Pensez à joindre le fichier %2s*\n\nCordialement,\n\n*Votre nom* tutti.sendCruiseReport.mail.subject=Captures de la campagne %s -tutti.sendCruiseReport.title.choose.exportFile=Exporter les captures de la campagne +tutti.sendCruiseReport.title.choose.exportFile=Envoyer les captures de la campagne tutti.splitBenthosBatch.action.cancel=Annuler tutti.splitBenthosBatch.action.cancel.mnemonic=A tutti.splitBenthosBatch.action.cancel.tip=Annuler le sous-échantillonnage