This is an automated email from the git hooks/post-receive script. New commit to branch feature/8157 in repository tutti. See https://gitlab.nuiton.org/codelutin/tutti.git commit 23c74c2d63dc112e468ec09a1d5f08ef343a2001 Author: Kevin Morin <morin@codelutin.com> Date: Fri Apr 1 15:45:21 2016 +0200 service d'export du rapport de prélèvements (refs #8157) --- .../cps/CalcifiedPiecesSamplingExportService.java | 156 +++++++++++++++++++++ .../export/cps/CalcifiedPiecesSamplingRow.java | 76 ++++++++++ .../cps/CalcifiedPiecesSamplingRowModel.java | 63 +++++++++ .../resources/i18n/tutti-service_en_GB.properties | 10 ++ .../resources/i18n/tutti-service_fr_FR.properties | 10 ++ 5 files changed, 315 insertions(+) diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/export/cps/CalcifiedPiecesSamplingExportService.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/export/cps/CalcifiedPiecesSamplingExportService.java new file mode 100644 index 0000000..7e103a6 --- /dev/null +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/export/cps/CalcifiedPiecesSamplingExportService.java @@ -0,0 +1,156 @@ +package fr.ifremer.tutti.service.export.cps; + +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.adagio.core.dao.referential.pmfm.QualitativeValueId; +import fr.ifremer.tutti.persistence.ProgressionModel; +import fr.ifremer.tutti.persistence.entities.protocol.CalcifiedPiecesSamplingDefinition; +import fr.ifremer.tutti.persistence.entities.protocol.SpeciesProtocol; +import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocol; +import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; +import fr.ifremer.tutti.persistence.entities.referential.Species; +import fr.ifremer.tutti.persistence.entities.referential.Speciess; +import fr.ifremer.tutti.service.AbstractTuttiService; +import fr.ifremer.tutti.service.DecoratorService; +import fr.ifremer.tutti.service.PersistenceService; +import fr.ifremer.tutti.service.TuttiDataContext; +import fr.ifremer.tutti.service.TuttiServiceContext; +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.csv.Export; +import org.nuiton.decorator.Decorator; +import org.nuiton.jaxx.application.ApplicationTechnicalException; + +import java.io.BufferedWriter; +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.stream.Collectors; + +import static org.nuiton.i18n.I18n.t; + +/** + * @author Kevin Morin (Code Lutin) + * @since 4.5 + */ +public class CalcifiedPiecesSamplingExportService extends AbstractTuttiService { + + private static final Log log = LogFactory.getLog(CalcifiedPiecesSamplingExportService.class); + + protected PersistenceService persistenceService; + protected DecoratorService decoratorService; + + @Override + public void setServiceContext(TuttiServiceContext context) { + super.setServiceContext(context); + persistenceService = getService(PersistenceService.class); + decoratorService = getService(DecoratorService.class); + } + + /** + * Export selected cruise with the csv sumatra format. + * + * @param file where to generate report + * @since 2.0 + */ + public void exportCruiseCalcifiedPiecesSamplingsReport(File file, + ProgressionModel progressionModel) { + + Preconditions.checkNotNull(file, "Cannot export to a null file"); + + TuttiDataContext dataContext = context.getDataContext(); + Preconditions.checkState(dataContext.isCruiseSamplingCacheLoaded()); + + List<CalcifiedPiecesSamplingRow> rows = Lists.newArrayList(); + + CalcifiedPiecesSamplingRowModel csvModel = new CalcifiedPiecesSamplingRowModel(context.getConfig().getCsvSeparator()); + + TuttiProtocol protocol = dataContext.getProtocol(); + + Map<Integer, Species> referenceSpeciesByReferenceTaxonId = Maps.uniqueIndex(dataContext.getReferentSpecies(), Speciess.GET_REFERECE_TAXON_ID_AS_INT); + + List<SpeciesProtocol> speciesInAlogirthm = + protocol.getSpecies().stream().filter(speciesProtocol -> !speciesProtocol.isCalcifiedPiecesSamplingDefinitionEmpty()).collect(Collectors.toList()); + + progressionModel.adaptTotal(progressionModel.getTotal() + speciesInAlogirthm.size()); + + Decorator<Species> speciesDecorator = decoratorService.getDecoratorByType(Species.class, DecoratorService.WITH_SURVEY_CODE); + + speciesInAlogirthm.forEach(speciesProtocol -> { + + Species species = referenceSpeciesByReferenceTaxonId.get(speciesProtocol.getSpeciesReferenceTaxonId()); + if (log.isDebugEnabled()) { + log.debug("export species " + species.getReferenceTaxonId() + " " + speciesDecorator.toString(species)); + } + progressionModel.increments(t("tutti.service.cpsExport.step.export.species", speciesDecorator.toString(species))); + + Collection<CalcifiedPiecesSamplingDefinition> cpsDefs = speciesProtocol.getCalcifiedPiecesSamplingDefinition(); + + cpsDefs.forEach(cpsDef -> { + if (cpsDef.isSex()) { + dataContext.getGenderValues().forEach(gender -> rows.addAll(getRows(species, cpsDef, gender))); + + } else { + rows.addAll(getRows(species, cpsDef, null)); + } + }); + }); + + 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 ApplicationTechnicalException(t("tutti.service.cpsExport.error", file), e); + } finally { + IOUtils.closeQuietly(writer); + } + } + + protected List<CalcifiedPiecesSamplingRow> getRows(Species species, CalcifiedPiecesSamplingDefinition cpsDef, CaracteristicQualitativeValue gender) { + Preconditions.checkState(context.getDataContext().isCruiseSamplingCacheLoaded()); + + Integer speciesId = species.getReferenceTaxonId(); + Boolean maturity = cpsDef.getMaturity(); + Integer maxByLenghtStep = cpsDef.getMaxByLenghtStep(); + int minSize = cpsDef.getMinSize(); + Integer maxSize = cpsDef.getMaxSize(); + + if (log.isDebugEnabled()) { + log.debug("create rows for " + speciesId + " (mat: " + maturity + ", sex: " + gender.getName() + ", max/lengthstep : " + maxByLenghtStep + ", min: " + minSize + ", max: " + maxSize + ")"); + } + + TreeMap<Integer, Integer> samplingNbByLengthStep = + context.getDataContext().getOptionalCruiseSamplingCache().get() + .getSamplingNbByLengthStepForCruise(speciesId, gender, maturity, minSize, maxSize); + + List<CalcifiedPiecesSamplingRow> rows = new ArrayList<>(); + samplingNbByLengthStep.keySet().forEach(lengthStep -> { + CalcifiedPiecesSamplingRow row = new CalcifiedPiecesSamplingRow(); + row.setSpecies(species); + row.setMaturity(maturity); + row.setSex(gender == null ? null : QualitativeValueId.fromValue(gender.getIdAsInt())); + row.setMaxByLengthStep(maxByLenghtStep); + row.setLengthStep(lengthStep); + row.setSamplingNb(samplingNbByLengthStep.getOrDefault(lengthStep, 0)); + rows.add(row); + }); + + if (log.isDebugEnabled()) { + log.debug("==> " + rows.size() + " found"); + } + + return rows; + } + +} diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/export/cps/CalcifiedPiecesSamplingRow.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/export/cps/CalcifiedPiecesSamplingRow.java new file mode 100644 index 0000000..c719b51 --- /dev/null +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/export/cps/CalcifiedPiecesSamplingRow.java @@ -0,0 +1,76 @@ +package fr.ifremer.tutti.service.export.cps; + +import fr.ifremer.adagio.core.dao.referential.pmfm.QualitativeValueId; +import fr.ifremer.tutti.persistence.entities.referential.Species; + +import java.io.Serializable; + +/** + * @author Kevin Morin (Code Lutin) + * @since 4.5 + */ +public class CalcifiedPiecesSamplingRow implements Serializable { + + + public static final String PROPERTY_SPECIES = "species"; + public static final String PROPERTY_LENGTH_STEP = "lengthStep"; + public static final String PROPERTY_MATURITY = "maturity"; + public static final String PROPERTY_SEX = "sex"; + public static final String PROPERTY_SAMPLING_NB = "samplingNb"; + public static final String PROPERTY_MAX_BY_LENGTH_STEP = "maxByLengthStep"; + + protected Species species; + protected int lengthStep; + protected Boolean maturity; + protected QualitativeValueId sex; + protected int samplingNb; + protected Integer maxByLengthStep; + + public int getLengthStep() { + return lengthStep; + } + + public void setLengthStep(int lengthStep) { + this.lengthStep = lengthStep; + } + + public Boolean getMaturity() { + return maturity; + } + + public void setMaturity(Boolean maturity) { + this.maturity = maturity; + } + + public Integer getMaxByLengthStep() { + return maxByLengthStep; + } + + public void setMaxByLengthStep(Integer maxByLengthStep) { + this.maxByLengthStep = maxByLengthStep; + } + + public int getSamplingNb() { + return samplingNb; + } + + public void setSamplingNb(int samplingNb) { + this.samplingNb = samplingNb; + } + + public QualitativeValueId getSex() { + return sex; + } + + public void setSex(QualitativeValueId sex) { + this.sex = sex; + } + + public Species getSpecies() { + return species; + } + + public void setSpecies(Species species) { + this.species = species; + } +} diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/export/cps/CalcifiedPiecesSamplingRowModel.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/export/cps/CalcifiedPiecesSamplingRowModel.java new file mode 100644 index 0000000..81cb5af --- /dev/null +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/export/cps/CalcifiedPiecesSamplingRowModel.java @@ -0,0 +1,63 @@ +package fr.ifremer.tutti.service.export.cps; + +import fr.ifremer.adagio.core.dao.referential.pmfm.QualitativeValueId; +import fr.ifremer.tutti.persistence.entities.referential.Species; +import fr.ifremer.tutti.service.csv.AbstractTuttiImportExportModel; +import fr.ifremer.tutti.service.csv.TuttiCsvUtil; +import org.nuiton.csv.ValueFormatter; + +import static org.nuiton.i18n.I18n.t; + +/** + * @author Kevin Morin (Code Lutin) + * @since 4.5 + */ +public class CalcifiedPiecesSamplingRowModel extends AbstractTuttiImportExportModel<CalcifiedPiecesSamplingRow> { + + public CalcifiedPiecesSamplingRowModel(char separator) { + super(separator); + + newColumnForExport(t("tutti.service.calcifiedPiecesSamplingReport.header.surveyCode"), CalcifiedPiecesSamplingRow.PROPERTY_SPECIES, new ValueFormatter<Species>() { + + @Override + public String format(Species species) { + return String.valueOf(species.getSurveyCode()); + } + }); + newColumnForExport(t("tutti.service.calcifiedPiecesSamplingReport.header.geniusName"), CalcifiedPiecesSamplingRow.PROPERTY_SPECIES, new ValueFormatter<Species>() { + + @Override + public String format(Species species) { + return String.valueOf(species.getName()); + } + }); + newColumnForExport(t("tutti.service.calcifiedPiecesSamplingReport.header.lengthStep"), CalcifiedPiecesSamplingRow.PROPERTY_LENGTH_STEP, TuttiCsvUtil.PRIMITIVE_INTEGER); + newColumnForExport(t("tutti.service.calcifiedPiecesSamplingReport.header.maturity"), CalcifiedPiecesSamplingRow.PROPERTY_MATURITY, new ValueFormatter<Boolean>() { + + @Override + public String format(Boolean maturity) { + if (maturity == null) { + return ""; + } + return maturity ? t("tutti.maturity.mature") : t("tutti.maturity.immature"); + } + }); + newColumnForExport(t("tutti.service.calcifiedPiecesSamplingReport.header.gender"), CalcifiedPiecesSamplingRow.PROPERTY_SEX, new ValueFormatter<QualitativeValueId>() { + + @Override + public String format(QualitativeValueId sex) { + if (sex == null) { + return ""; + } + return t(sex.getDescription()); + } + }); + newColumnForExport(t("tutti.service.calcifiedPiecesSamplingReport.header.samplingNb"), CalcifiedPiecesSamplingRow.PROPERTY_SAMPLING_NB, TuttiCsvUtil.PRIMITIVE_INTEGER); + newColumnForExport(t("tutti.service.calcifiedPiecesSamplingReport.header.maxByLengthStep"), CalcifiedPiecesSamplingRow.PROPERTY_MAX_BY_LENGTH_STEP, TuttiCsvUtil.INTEGER); + } + + @Override + public CalcifiedPiecesSamplingRow newEmptyInstance() { + return new CalcifiedPiecesSamplingRow(); + } +} 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 5d79d71..1514c68 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 @@ -6,6 +6,7 @@ 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= @@ -80,8 +81,17 @@ tutti.service.bigfinImport.warning.species.notInProtocol= tutti.service.bigfinImport.warning.species.tooCategorized= tutti.service.bigfinImport.warning.speciesBatch.tooCategorized= tutti.service.bigfinimport.error.no.protocol= +tutti.service.calcifiedPiecesSamplingReport.header.gender= +tutti.service.calcifiedPiecesSamplingReport.header.geniusName= +tutti.service.calcifiedPiecesSamplingReport.header.lengthStep= +tutti.service.calcifiedPiecesSamplingReport.header.maturity= +tutti.service.calcifiedPiecesSamplingReport.header.maxByLengthStep= +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.csv.caracteristic.qualitativeValue.notFound= tutti.service.csv.parse.entityNotFound= tutti.service.csv.parse.foreignEntityNotFound= diff --git a/tutti-service/src/main/resources/i18n/tutti-service_fr_FR.properties b/tutti-service/src/main/resources/i18n/tutti-service_fr_FR.properties index c064cbe..cd062bf 100644 --- a/tutti-service/src/main/resources/i18n/tutti-service_fr_FR.properties +++ b/tutti-service/src/main/resources/i18n/tutti-service_fr_FR.properties @@ -3,6 +3,7 @@ tutti.caracteristicType.INDIVIDUAL_OBSERVATION=Observations individuelles tutti.caracteristicType.LENGTH_STEP=Classes de tailles tutti.caracteristicType.VESSEL_USE_FEATURE=Autres caractéristiques tutti.caracteristicType.lengthStep= +tutti.cruise.cacheLoader.loading.fishingOperation=Chargement du cache d'échantillons pour le trait \: %s tutti.csv.import.error.on.field=Colonne %s \: %s tutti.csv.import.error.on.row=Des erreurs ont été détectées à la ligne %s \:\n %s tutti.decorator.null.infinite=∞ @@ -69,8 +70,17 @@ tutti.service.bigfinImport.warning.species.notInProtocol=[Enregistrement %s] L'e tutti.service.bigfinImport.warning.species.tooCategorized=L'espèce '<strong>%1s</strong>' est trop catégorisée (pas limitée à '<strong>%2s</strong>' et '<strong>%3s</strong>') tutti.service.bigfinImport.warning.speciesBatch.tooCategorized=[Enregistrement %s] Le lot '<strong>%1s</strong>' contient des sous catégories, on ne peut pas y ajouter des mensurations. tutti.service.bigfinimport.error.no.protocol=Impossible de faire un import Bigfin sans protocol. +tutti.service.calcifiedPiecesSamplingReport.header.gender=Sexe +tutti.service.calcifiedPiecesSamplingReport.header.geniusName=Nom scientifique +tutti.service.calcifiedPiecesSamplingReport.header.lengthStep=Classe de taille (mm) +tutti.service.calcifiedPiecesSamplingReport.header.maturity=Maturité +tutti.service.calcifiedPiecesSamplingReport.header.maxByLengthStep=Max/classe de taille +tutti.service.calcifiedPiecesSamplingReport.header.samplingNb=Nombre de prélèvements +tutti.service.calcifiedPiecesSamplingReport.header.surveyCode=Code campagne tutti.service.compressZipFile.error=Erreur lors de la compression du dossier %1s dans le fichier %2s tutti.service.context.serviceInstanciation.error=Erreur lors de l'instanciation du service %s +tutti.service.cpsExport.error=Erreur à l'export du rapport des prélèvements +tutti.service.cpsExport.step.export.species=Export des prélèvements pour l'espèce %s tutti.service.csv.caracteristic.qualitativeValue.notFound=La caractéristique qualitative %s n'a pas de value d'id %s tutti.service.csv.parse.entityNotFound=L'entité de type %1s avec la propriété %2s de valeur %3s n'a pas été trouvée tutti.service.csv.parse.foreignEntityNotFound=L'entité de type %1s avec l'identifiant %3s n'a pas été trouvée -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.