This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository wao. See http://git.codelutin.com/wao.git commit fd59834846ebbb3791bedd46b9a6884483e60643 Author: Brendan Le Ny <bleny@codelutin.com> Date: Mon Dec 15 15:49:36 2014 +0100 Modification du modèle de la ligne du plan, introduction du service et de la vue pour le plan scléro, migration --- .../wao/entity/IndividualMeasurementStrategy.java | 39 ++ .../entity/SclerochronologySamplingContext.java | 38 ++ .../db/migration/V5_0__sclerochronology.sql | 5 + .../i18n/wao-persistence_en_GB.properties | 6 + .../i18n/wao-persistence_fr_FR.properties | 6 + wao-persistence/src/main/xmi/wao-model.zargo | Bin 61366 -> 61993 bytes .../service/SclerochronologySamplingPlan.java | 107 +++++ .../SclerochronologySamplingPlanBuilder.java | 326 +++++++++++++++ .../SclerochronologySamplingPlanService.java | 89 ++++ .../sclerochronology/SamplingPlanAction.java | 43 ++ .../SamplingPlanAction-conversion.properties | 1 + .../main/resources/i18n/wao-web_en_GB.properties | 4 + .../main/resources/i18n/wao-web_fr_FR.properties | 4 + .../content/sclerochronology/sampling-plan.jsp | 449 +++++++++++++++++++++ 14 files changed, 1117 insertions(+) diff --git a/wao-persistence/src/main/java/fr/ifremer/wao/entity/IndividualMeasurementStrategy.java b/wao-persistence/src/main/java/fr/ifremer/wao/entity/IndividualMeasurementStrategy.java new file mode 100644 index 0000000..0f69565 --- /dev/null +++ b/wao-persistence/src/main/java/fr/ifremer/wao/entity/IndividualMeasurementStrategy.java @@ -0,0 +1,39 @@ +package fr.ifremer.wao.entity; + +import static org.nuiton.i18n.I18n.n; + +/** + * Dans la sclérochronologie, représente les caractéristiques qu'il est demander de mesurer + * lors de l'échantillonnage d'un individu. + * + * @since 5.0 + */ +public enum IndividualMeasurementStrategy implements I18nAble { + + /** + * Taille, poids » et « » + */ + SIZE_WEIGHT(n("IndividualMeasurementStrategy.SIZE_WEIGHT")), + + /** + * Taille, poids, sexe + */ + SIZE_WEIGHT_SEX(n("IndividualMeasurementStrategy.SIZE_WEIGHT_SEX")), + + /** + * Taille, poids, sexe, maturité, âge + */ + SIZE_WEIGHT_SEX_MATURITY_AGE(n("IndividualMeasurementStrategy.SIZE_WEIGHT_SEX_MATURITY_AGE")); + + protected String i18nKey; + + IndividualMeasurementStrategy(String i18nKey) { + this.i18nKey = i18nKey; + } + + @Override + public String getI18nKey() { + return i18nKey; + } + +} diff --git a/wao-persistence/src/main/java/fr/ifremer/wao/entity/SclerochronologySamplingContext.java b/wao-persistence/src/main/java/fr/ifremer/wao/entity/SclerochronologySamplingContext.java new file mode 100644 index 0000000..68648a3 --- /dev/null +++ b/wao-persistence/src/main/java/fr/ifremer/wao/entity/SclerochronologySamplingContext.java @@ -0,0 +1,38 @@ +package fr.ifremer.wao.entity; + + +import static org.nuiton.i18n.I18n.n; + +/** + * Contexte dans lequel l'échantillonnage pour la sclérochronologie a été effectué. + * + * @since 5.0 + */ +public enum SclerochronologySamplingContext implements I18nAble { + + /** + * Campagne scientifique + */ + SCIENTIFIC_CAMPAIGN(n("SclerochronologySamplingContext.SCIENTIFIC_CAMPAIGN")), + + /** + * Échantillonnage en mer + */ + FISHING_TRIP(n("SclerochronologySamplingContext.FISHING_TRIP")), + + /** + * Échantillonnage à terre + */ + TERRESTRIAL_SAMPLING(n("SclerochronologySamplingContext.TERRESTRIAL_SAMPLING")); + + protected String i18nKey; + + SclerochronologySamplingContext(String i18nKey) { + this.i18nKey = i18nKey; + } + + @Override + public String getI18nKey() { + return i18nKey; + } +} diff --git a/wao-persistence/src/main/resources/db/migration/V5_0__sclerochronology.sql b/wao-persistence/src/main/resources/db/migration/V5_0__sclerochronology.sql index ee61e50..fe74d39 100644 --- a/wao-persistence/src/main/resources/db/migration/V5_0__sclerochronology.sql +++ b/wao-persistence/src/main/resources/db/migration/V5_0__sclerochronology.sql @@ -11,3 +11,8 @@ insert into UserProfile values ( true, uuid_in(md5(random()::text || now()::text)::cstring) ); + +alter table SampleRow add column species character varying(255) references Species(topiaId); +alter table SampleRow add column sclerochronologySamplingContext character varying(255); +alter table SampleRow add column individualMeasurementStrategy character varying(255); +alter table SampleRow add column sclerochronologySamplingContextInfo text; diff --git a/wao-persistence/src/main/resources/i18n/wao-persistence_en_GB.properties b/wao-persistence/src/main/resources/i18n/wao-persistence_en_GB.properties index 4334ea7..e4f6dfb 100644 --- a/wao-persistence/src/main/resources/i18n/wao-persistence_en_GB.properties +++ b/wao-persistence/src/main/resources/i18n/wao-persistence_en_GB.properties @@ -21,6 +21,9 @@ GlobalIndicatorValue.GOOD=Level 1 bonus GlobalIndicatorValue.NEUTRAL=Conform GlobalIndicatorValue.VERY_BAD=Level 2 penalty GlobalIndicatorValue.VERY_GOOD=Level 2 bonus +IndividualMeasurementStrategy.SIZE_WEIGHT=Size, weight +IndividualMeasurementStrategy.SIZE_WEIGHT_SEX=Size, weight, sex +IndividualMeasurementStrategy.SIZE_WEIGHT_SEX_MATURITY_AGE=Size, weight, sex, maturity, age LocationType.AUCTION=Auction LocationType.DISTRICT=District LocationType.PORT=Port @@ -37,6 +40,9 @@ SamplingStrategy.SIMULTANEOUS_ALL_SPECIES=Simultaneous \: All commercial species SamplingStrategy.SIMULTANEOUS_G1_G2_SPECIES=Simultaneous \: G1+G2 species SamplingStrategy.SIMULTANEOUS_G1_SPECIES=Simultaneous \: G1 species SamplingStrategy.SPECIFIC_STOCK=Specific stock +SclerochronologySamplingContext.FISHING_TRIP=Fishing trip +SclerochronologySamplingContext.SCIENTIFIC_CAMPAIGN=Scientific campaign +SclerochronologySamplingContext.TERRESTRIAL_SAMPLING=Terrestrial sampling StrategyValues.CONTACTS_STATES=Contact states by boat district StrategyValues.CONTACTS_STATES_MOTIFS=Refusal motives StrategyValues.CONTACTS_STATES_SEABOARDS=Contact states by seaboard diff --git a/wao-persistence/src/main/resources/i18n/wao-persistence_fr_FR.properties b/wao-persistence/src/main/resources/i18n/wao-persistence_fr_FR.properties index cf72839..972c780 100644 --- a/wao-persistence/src/main/resources/i18n/wao-persistence_fr_FR.properties +++ b/wao-persistence/src/main/resources/i18n/wao-persistence_fr_FR.properties @@ -21,6 +21,9 @@ GlobalIndicatorValue.GOOD=Bonus de niveau 1 GlobalIndicatorValue.NEUTRAL=Conforme au cahier des charges GlobalIndicatorValue.VERY_BAD=Pénalité de niveau 2 GlobalIndicatorValue.VERY_GOOD=Bonus de niveau 2 +IndividualMeasurementStrategy.SIZE_WEIGHT=Poids, taille +IndividualMeasurementStrategy.SIZE_WEIGHT_SEX=Poids, taille, sexe +IndividualMeasurementStrategy.SIZE_WEIGHT_SEX_MATURITY_AGE=Poids, taille, sexe, maturité, âge LocationType.AUCTION=Criée LocationType.DISTRICT=Quartier maritime LocationType.PORT=Port @@ -37,6 +40,9 @@ SamplingStrategy.SIMULTANEOUS_ALL_SPECIES=Simultané \: Toutes espèces commerci SamplingStrategy.SIMULTANEOUS_G1_G2_SPECIES=Simultané \: espèces G1+G2 SamplingStrategy.SIMULTANEOUS_G1_SPECIES=Simultané \: espèces G1 SamplingStrategy.SPECIFIC_STOCK=Stock spécifique +SclerochronologySamplingContext.FISHING_TRIP=Échantillonnage en mer +SclerochronologySamplingContext.SCIENTIFIC_CAMPAIGN=Campagne scientifique +SclerochronologySamplingContext.TERRESTRIAL_SAMPLING=Échantillonnage à terre StrategyValues.CONTACTS_STATES=États des contacts selon le quartier maritime StrategyValues.CONTACTS_STATES_MOTIFS=Motifs de refus StrategyValues.CONTACTS_STATES_SEABOARDS=États des contacts selon la façade maritime diff --git a/wao-persistence/src/main/xmi/wao-model.zargo b/wao-persistence/src/main/xmi/wao-model.zargo index 5f27d3a..5535ef4 100644 Binary files a/wao-persistence/src/main/xmi/wao-model.zargo and b/wao-persistence/src/main/xmi/wao-model.zargo differ diff --git a/wao-services/src/main/java/fr/ifremer/wao/services/service/SclerochronologySamplingPlan.java b/wao-services/src/main/java/fr/ifremer/wao/services/service/SclerochronologySamplingPlan.java new file mode 100644 index 0000000..d23fefd --- /dev/null +++ b/wao-services/src/main/java/fr/ifremer/wao/services/service/SclerochronologySamplingPlan.java @@ -0,0 +1,107 @@ +package fr.ifremer.wao.services.service; + +/* + * #%L + * Wao :: Services + * %% + * Copyright (C) 2009 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + +import fr.ifremer.wao.WaoUtils; +import fr.ifremer.wao.entity.ObsProgram; +import fr.ifremer.wao.entity.SampleRow; + +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +public class SclerochronologySamplingPlan extends SamplingPlan implements Iterable<SamplingPlan.SamplingPlanFacadePart> { + + public SclerochronologySamplingPlan(List<Date> months, Collection<SamplingPlanFacadePart> facadeParts, Map<Date, Effort> totalEffortInObservationsPerMonths, Effort highTotalEffortInObservations, SampleRowsFilterValues filterValues, Set<String> sampleRowIds) { + super(months, facadeParts, totalEffortInObservationsPerMonths, highTotalEffortInObservations, filterValues, sampleRowIds); + } + + public static class SclerochronologySamplingPlanSampleRowPart extends SamplingPlanSampleRowPart { + + protected String samplingContext; + + protected String samplingContextInfo; + + protected String individualMeasurementStrategy; + + protected String species; + + public SclerochronologySamplingPlanSampleRowPart(Locale locale, Map<Date, Effort> effortInObservationsPerMonths, SampleRow sampleRow, long sampleRowContactCounts) { + super(locale, effortInObservationsPerMonths, sampleRow, sampleRowContactCounts); + species = sampleRow.getSpecies().getVernacularName(); + samplingContext = WaoUtils.l(locale, sampleRow.getSclerochronologySamplingContext()); + samplingContextInfo = sampleRow.getSclerochronologySamplingContextInfo(); + individualMeasurementStrategy = WaoUtils.l(locale, sampleRow.getIndividualMeasurementStrategy()); + } + + public String getSamplingContextInfo() { + return samplingContextInfo; + } + + public String getIndividualMeasurementStrategy() { + return individualMeasurementStrategy; + } + + public String getSpecies() { + return species; + } + + public String getSamplingContext() { + return samplingContext; + } + + @Override + public Map<String, String> getDcf5CodesAndDescriptions() { + throw new UnsupportedOperationException("not in " + ObsProgram.SCLEROCHRONOLOGY); + } + + @Override + public String getProfessionMeshSize() { + throw new UnsupportedOperationException("not in " + ObsProgram.SCLEROCHRONOLOGY); + } + + @Override + public String getProfessionSize() { + throw new UnsupportedOperationException("not in " + ObsProgram.SCLEROCHRONOLOGY); + } + + @Override + public String getProfessionOther() { + throw new UnsupportedOperationException("not in " + ObsProgram.SCLEROCHRONOLOGY); + } + + @Override + public String getProfessionLibelle() { + throw new UnsupportedOperationException("not in " + ObsProgram.SCLEROCHRONOLOGY); + } + + @Override + public String getProfessionSpecies() { + throw new UnsupportedOperationException("not in " + ObsProgram.SCLEROCHRONOLOGY); + } + + } + +} \ No newline at end of file diff --git a/wao-services/src/main/java/fr/ifremer/wao/services/service/SclerochronologySamplingPlanBuilder.java b/wao-services/src/main/java/fr/ifremer/wao/services/service/SclerochronologySamplingPlanBuilder.java new file mode 100644 index 0000000..aed9964 --- /dev/null +++ b/wao-services/src/main/java/fr/ifremer/wao/services/service/SclerochronologySamplingPlanBuilder.java @@ -0,0 +1,326 @@ +package fr.ifremer.wao.services.service; + +/* + * #%L + * Wao :: Services + * %% + * Copyright (C) 2009 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.common.collect.Ordering; +import fr.ifremer.wao.SampleRowsFilter; +import fr.ifremer.wao.entity.ObsProgram; +import fr.ifremer.wao.entity.SampleRow; +import fr.ifremer.wao.entity.SampleRows; +import org.apache.commons.lang3.mutable.MutableInt; +import org.nuiton.util.PeriodDates; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +/** + * @since 5.0 + */ +public class SclerochronologySamplingPlanBuilder { + + /** + * Incoming filter used. + */ + protected SampleRowsFilter sampleRowsFilter; + + /** + * Bean to hold all values that user can select to fill {@link fr.ifremer.wao.SampleRowsFilter}. + */ + protected SampleRowsFilterValues sampleRowsFilterValues; + + /** + * Ids of all the sample rows included in this sampling plan. + */ + protected Set<String> sampleRowIds; + + /** + * List of month computed from the filter. + */ + protected List<Date> months; + + /** + * Dictionnary of facades indexed by their facade name. + */ + protected Map<String, FacadeContext> facadeMap; + + /** + * To compute the high total expected. + * + * @see fr.ifremer.wao.services.service.SclerochronologySamplingPlan#highTotalEffortInObservations + */ + protected int highTotalExpected; + + /** + * To compute the high total real. + * + * @see fr.ifremer.wao.services.service.SclerochronologySamplingPlan#highTotalEffortInObservations + */ + protected int highTotalReal; + + /** + * To compute the high total estimated. + * + * @see fr.ifremer.wao.services.service.SclerochronologySamplingPlan#highTotalEffortInObservations + */ + protected int highTotalEstimated; + + /** + * To compute by month the total of expected tides. + * + * @see fr.ifremer.wao.services.service.SamplingPlan.Effort#expected + */ + protected Map<Date, MutableInt> totalExpectedForMonths; + + /** + * To compute by month the total of expected tides. + * + * @see fr.ifremer.wao.services.service.SamplingPlan.Effort#estimated + */ + protected Map<Date, MutableInt> totalEstimatedForMonths; + + /** + * To compute by month the total of real tides. + * + * @see fr.ifremer.wao.services.service.SamplingPlan.Effort#real + */ + protected Map<Date, MutableInt> totalRealForMonths; + + public SclerochronologySamplingPlanBuilder(Locale locale, + Optional<String> optionalCompanyId, + SampleRowsFilter sampleRowsFilter) { + this.sampleRowsFilter = sampleRowsFilter; + this.sampleRowsFilterValues = new SampleRowsFilterValues(locale, ObsProgram.SCLEROCHRONOLOGY, optionalCompanyId); + this.sampleRowIds = new HashSet<>(); + this.facadeMap = new TreeMap<>(); + this.totalExpectedForMonths = new TreeMap<>(); + this.totalRealForMonths = new TreeMap<>(); + this.totalEstimatedForMonths = new TreeMap<>(); + + PeriodDates periodDates = new PeriodDates(sampleRowsFilter.getPeriodFrom(), + sampleRowsFilter.getPeriodTo()); + this.months = periodDates.getMonths(); + } + + public SclerochronologySamplingPlanBuilder addSampleRow(SampleRow sampleRow, long sampleRowContactCounts) { + + String facade = sampleRow.getFacade(); + FacadeContext facadeContext = facadeMap.get(facade); + + if (facadeContext == null) { + + // register a new facade + facadeContext = new FacadeContext(facade); + facadeMap.put(facade, facadeContext); + } + + String sectors = sampleRow.getSectors(); + + // get sector context + SectorContext sectorPart = facadeContext.getOrAddSectorContext(sectors); + + // compute nb tides per month + Map<Date, SamplingPlan.Effort> effortInObservationsPerMonths = getEffortInObservationsPerMonths(sampleRow); + + // add sample row + sectorPart.addSampleRow(sampleRowsFilterValues.getLocale(), + sampleRow, + effortInObservationsPerMonths, + sampleRowContactCounts); + + sampleRowsFilterValues.addSampleRow(sampleRow); + + sampleRowIds.add(sampleRow.getTopiaId()); + + return this; + } + + public SclerochronologySamplingPlan toPlan() { + + // Get facade parts + Collection<SamplingPlan.SamplingPlanFacadePart> facadeParts = new ArrayList<>(); + for (FacadeContext facadeContext : facadeMap.values()) { + SamplingPlan.SamplingPlanFacadePart facadePart = facadeContext.toBean(); + facadeParts.add(facadePart); + } + + // Sort them + Collection<SamplingPlan.SamplingPlanFacadePart> sortedFacades = Ordering.natural().onResultOf(new Function<SamplingPlan.SamplingPlanFacadePart, String>() { + public String apply(SamplingPlan.SamplingPlanFacadePart input) { + return input.getFacade(); + } + }).immutableSortedCopy(facadeParts); + + // Get statistics + Map<Date, SamplingPlan.Effort> statisticsMap = new TreeMap<>(); + for (Date month : months) { + + MutableInt totalExpected = totalExpectedForMonths.get(month); + MutableInt totalReal = totalRealForMonths.get(month); + MutableInt totalEstimated = totalEstimatedForMonths.get(month); + SamplingPlan.Effort planStatistics = + new SamplingPlan.Effort(totalExpected == null ? null : totalExpected.toInteger(), + totalReal == null ? null : totalReal.toInteger(), + totalEstimated == null ? null : totalEstimated.toInteger()); + statisticsMap.put(month, planStatistics); + } + + SamplingPlan.Effort highTotals = new SamplingPlan.Effort(highTotalExpected, highTotalReal, highTotalEstimated); + + SclerochronologySamplingPlan result = new SclerochronologySamplingPlan(months, + sortedFacades, + statisticsMap, + highTotals, + sampleRowsFilterValues, + sampleRowIds); + return result; + } + + protected Map<Date, SamplingPlan.Effort> getEffortInObservationsPerMonths(SampleRow sampleRow) { + Map<Date, SamplingPlan.Effort> result = new TreeMap<>(); + for (Date month : months) { + Integer expectedTidesValue = SampleRows.getExpectedTidesValue(sampleRow, month); + if (expectedTidesValue != null) { + MutableInt mutableInt = totalExpectedForMonths.get(month); + if (mutableInt == null) { + totalExpectedForMonths.put(month, mutableInt = new MutableInt()); + } + mutableInt.add(expectedTidesValue); + highTotalExpected += expectedTidesValue; + } + Integer realTidesValue = SampleRows.getRealTidesValue(sampleRow, month); + if (realTidesValue != null) { + MutableInt mutableInt = totalRealForMonths.get(month); + if (mutableInt == null) { + totalRealForMonths.put(month, mutableInt = new MutableInt()); + } + mutableInt.add(realTidesValue); + highTotalReal += realTidesValue; + } + + Integer estimatedTidesValue = SampleRows.getEstimatedTidesValue(sampleRow, month); + if (estimatedTidesValue != null) { + MutableInt mutableInt = totalEstimatedForMonths.get(month); + if (mutableInt == null) { + totalEstimatedForMonths.put(month, mutableInt = new MutableInt()); + } + mutableInt.add(estimatedTidesValue); + highTotalEstimated += estimatedTidesValue; + } + result.put(month, new SamplingPlan.Effort(expectedTidesValue, + realTidesValue, + estimatedTidesValue)); + + } + return result; + } + + protected static class FacadeContext { + + protected String facade; + + protected Map<String, SectorContext> sectorMap; + + protected FacadeContext(String facade) { + this.facade = facade; + this.sectorMap = new TreeMap<>(); + } + + protected SectorContext getOrAddSectorContext(String sectors) { + SectorContext sectorPart = sectorMap.get(sectors); + if (sectorPart == null) { + + // register a new sector + sectorPart = new SectorContext(sectors); + sectorMap.put(sectors, sectorPart); + } + return sectorPart; + } + + protected SamplingPlan.SamplingPlanFacadePart toBean() { + + // get sector parts + Collection<SamplingPlan.SamplingPlanSectorPart> sectorParts = new ArrayList<>(); + for (SectorContext sectorContext : sectorMap.values()) { + SamplingPlan.SamplingPlanSectorPart sectorPart = sectorContext.toBean(); + sectorParts.add(sectorPart); + } + // sort them + Collection<SamplingPlan.SamplingPlanSectorPart> sortedSectors = Ordering.natural().onResultOf(new Function<SamplingPlan.SamplingPlanSectorPart, String>() { + public String apply(SamplingPlan.SamplingPlanSectorPart input) { + return input.getSectors(); + } + }).immutableSortedCopy(sectorParts); + SamplingPlan.SamplingPlanFacadePart result = + new SamplingPlan.SamplingPlanFacadePart(facade, sortedSectors); + return result; + } + } + + protected static class SectorContext { + + protected String sectors; + + protected Collection<SclerochronologySamplingPlan.SclerochronologySamplingPlanSampleRowPart> rows; + + protected SectorContext(String sectors) { + this.sectors = sectors; + this.rows = new ArrayList<>(); + } + + protected ObsMerSamplingPlan.SamplingPlanSampleRowPart addSampleRow(Locale locale, + SampleRow row, + Map<Date, SamplingPlan.Effort> effortInObservationsPerMonths, + long sampleRowContactCounts) { + + SclerochronologySamplingPlan.SclerochronologySamplingPlanSampleRowPart rowPart = + new SclerochronologySamplingPlan.SclerochronologySamplingPlanSampleRowPart( + locale, + effortInObservationsPerMonths, + row, + sampleRowContactCounts); + rows.add(rowPart); + + return rowPart; + } + + protected SamplingPlan.SamplingPlanSectorPart toBean() { + + Collection<SclerochronologySamplingPlan.SclerochronologySamplingPlanSampleRowPart> sortedRows = Ordering.natural().onResultOf(new Function<SclerochronologySamplingPlan.SclerochronologySamplingPlanSampleRowPart, String>() { + public String apply(SclerochronologySamplingPlan.SclerochronologySamplingPlanSampleRowPart input) { + return input.getCode(); + } + }).immutableSortedCopy(rows); + SamplingPlan.SamplingPlanSectorPart result = + new SamplingPlan.SamplingPlanSectorPart(sectors, sortedRows); + return result; + } + } +} diff --git a/wao-services/src/main/java/fr/ifremer/wao/services/service/SclerochronologySamplingPlanService.java b/wao-services/src/main/java/fr/ifremer/wao/services/service/SclerochronologySamplingPlanService.java new file mode 100644 index 0000000..f0cd05f --- /dev/null +++ b/wao-services/src/main/java/fr/ifremer/wao/services/service/SclerochronologySamplingPlanService.java @@ -0,0 +1,89 @@ +package fr.ifremer.wao.services.service; + +/* + * #%L + * Wao :: Services + * %% + * Copyright (C) 2009 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + +import com.google.common.base.Optional; +import com.google.common.cache.Cache; +import fr.ifremer.wao.SampleRowsFilter; +import fr.ifremer.wao.entity.ContactTopiaDao; +import fr.ifremer.wao.entity.SampleRow; +import fr.ifremer.wao.entity.SampleRowTopiaDao; +import fr.ifremer.wao.services.AuthenticatedWaoUser; + +import java.util.List; + +public class SclerochronologySamplingPlanService extends SamplingPlanService { + + public SclerochronologySamplingPlan getSamplingPlan( + AuthenticatedWaoUser authenticatedWaoUser, + SampleRowsFilter sampleRowsFilter) { + + Optional<String> optionalCompanyId = Optional.absent(); + if (authenticatedWaoUser.isCoordinatorOrObserver()) { + optionalCompanyId = Optional.of(authenticatedWaoUser.getCompany().getTopiaId()); + } + + SamplingPlanCacheKey samplingPlanCacheKey = + new SamplingPlanCacheKey( + serviceContext.getLocale(), + optionalCompanyId, + sampleRowsFilter); + + Cache<SamplingPlanCacheKey, SamplingPlan> samplingPlansCache = + serviceContext.getSamplingPlansCache(); + + SclerochronologySamplingPlan result = (SclerochronologySamplingPlan) samplingPlansCache.getIfPresent(samplingPlanCacheKey); + + if (result == null) { + + SampleRowTopiaDao dao = getSampleRowDao(); + ContactTopiaDao contactDao = getContactDao(); + + // recuperation des lignes du plan + List<SampleRow> sampleRows = dao.findAll(sampleRowsFilter); + + // creation du plan d'echantillonnage + SclerochronologySamplingPlanBuilder builder = new SclerochronologySamplingPlanBuilder( + serviceContext.getLocale(), + optionalCompanyId, + sampleRowsFilter); + + for (SampleRow sampleRow : sampleRows) { + + long sampleRowContactCounts = contactDao.forSampleRowEquals(sampleRow).count(); + + // ajout de la ligne au build de plan + builder.addSampleRow(sampleRow, sampleRowContactCounts); + + } + + result = builder.toPlan(); + + samplingPlansCache.put(samplingPlanCacheKey.clone(), result); + + } + + return result; + + } + +} diff --git a/wao-web/src/main/java/fr/ifremer/wao/web/action/sclerochronology/SamplingPlanAction.java b/wao-web/src/main/java/fr/ifremer/wao/web/action/sclerochronology/SamplingPlanAction.java new file mode 100644 index 0000000..fe9f68a --- /dev/null +++ b/wao-web/src/main/java/fr/ifremer/wao/web/action/sclerochronology/SamplingPlanAction.java @@ -0,0 +1,43 @@ +package fr.ifremer.wao.web.action.sclerochronology; + +/* + * #%L + * Wao :: Web + * %% + * Copyright (C) 2009 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + +import fr.ifremer.wao.services.service.SclerochronologySamplingPlan; +import fr.ifremer.wao.services.service.SclerochronologySamplingPlanService; +import fr.ifremer.wao.web.action.AbstractSamplingPlanAction; + +public class SamplingPlanAction extends AbstractSamplingPlanAction { + + protected SclerochronologySamplingPlanService service; + + public void setService(SclerochronologySamplingPlanService service) { + this.service = service; + } + + @Override + protected SclerochronologySamplingPlan samplingPlan() { + + return service.getSamplingPlan(getAuthenticatedWaoUser(), filter); + + } + +} diff --git a/wao-web/src/main/resources/fr/ifremer/wao/web/action/sclerochronology/SamplingPlanAction-conversion.properties b/wao-web/src/main/resources/fr/ifremer/wao/web/action/sclerochronology/SamplingPlanAction-conversion.properties new file mode 100644 index 0000000..977bee2 --- /dev/null +++ b/wao-web/src/main/resources/fr/ifremer/wao/web/action/sclerochronology/SamplingPlanAction-conversion.properties @@ -0,0 +1 @@ +filter=org.nuiton.web.struts2.converters.JsonConverter diff --git a/wao-web/src/main/resources/i18n/wao-web_en_GB.properties b/wao-web/src/main/resources/i18n/wao-web_en_GB.properties index da6df47..e540698 100644 --- a/wao-web/src/main/resources/i18n/wao-web_en_GB.properties +++ b/wao-web/src/main/resources/i18n/wao-web_en_GB.properties @@ -253,6 +253,7 @@ wao.ui.field.SampleRow.elligibleBoat=Eligible boats wao.ui.field.SampleRow.expectedDate=Date wao.ui.field.SampleRow.fishingZones=Fishing zone(s) wao.ui.field.SampleRow.fishingZonesInfos=Fishing zone(s) details +wao.ui.field.SampleRow.individualMeasurementStrategy=Individual measurement strategy wao.ui.field.SampleRow.libelle=Labels wao.ui.field.SampleRow.meshSize=Mesh size wao.ui.field.SampleRow.nbObservants=Number of observers @@ -266,7 +267,10 @@ wao.ui.field.SampleRow.profession=Profession wao.ui.field.SampleRow.professionCode=Profession code wao.ui.field.SampleRow.programName=Program wao.ui.field.SampleRow.regionIfremer=Region +wao.ui.field.SampleRow.samplingContext= wao.ui.field.SampleRow.samplingStrategy=Sampling strategy +wao.ui.field.SampleRow.sclerochronologySamplingContext=Context +wao.ui.field.SampleRow.sclerochronologySamplingContextInfo=Context (details) wao.ui.field.SampleRow.size=Boat size wao.ui.field.SampleRow.species=Species wao.ui.field.SampleRow.terrestrialLocation=Maritime district diff --git a/wao-web/src/main/resources/i18n/wao-web_fr_FR.properties b/wao-web/src/main/resources/i18n/wao-web_fr_FR.properties index 5f60f26..0726cc6 100644 --- a/wao-web/src/main/resources/i18n/wao-web_fr_FR.properties +++ b/wao-web/src/main/resources/i18n/wao-web_fr_FR.properties @@ -254,6 +254,7 @@ wao.ui.field.SampleRow.elligibleBoat=Navires éligibles wao.ui.field.SampleRow.expectedDate=Date wao.ui.field.SampleRow.fishingZones=Zone(s) de pêche wao.ui.field.SampleRow.fishingZonesInfos=Autres informations +wao.ui.field.SampleRow.individualMeasurementStrategy=Paramètres à mesurer wao.ui.field.SampleRow.libelle=Libellé wao.ui.field.SampleRow.meshSize=Maillage wao.ui.field.SampleRow.nbObservants=Nombre d'observateurs @@ -267,7 +268,10 @@ wao.ui.field.SampleRow.profession=Métier wao.ui.field.SampleRow.professionCode=Code métier wao.ui.field.SampleRow.programName=Programme wao.ui.field.SampleRow.regionIfremer=Région +wao.ui.field.SampleRow.samplingContext= wao.ui.field.SampleRow.samplingStrategy=Stratégie d'échantillonnage +wao.ui.field.SampleRow.sclerochronologySamplingContext=Contexte +wao.ui.field.SampleRow.sclerochronologySamplingContextInfo=Contexte (complément) wao.ui.field.SampleRow.size=Taille du navire wao.ui.field.SampleRow.species=Espèces cibles wao.ui.field.SampleRow.terrestrialLocation=Quartier maritime diff --git a/wao-web/src/main/webapp/WEB-INF/content/sclerochronology/sampling-plan.jsp b/wao-web/src/main/webapp/WEB-INF/content/sclerochronology/sampling-plan.jsp new file mode 100644 index 0000000..30dd0c5 --- /dev/null +++ b/wao-web/src/main/webapp/WEB-INF/content/sclerochronology/sampling-plan.jsp @@ -0,0 +1,449 @@ +<%-- + #%L + Wao :: Web + %% + Copyright (C) 2009 - 2014 Ifremer + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --%> +<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> +<%@taglib uri="/struts-tags" prefix="s" %> + +<html> + + <head> + <title> + <s:text name="wao.ui.page.SamplingPlan.title" /> + </title> + + <script> + + $(document).ready(function () { + + // var sampleRowsFilterController = new FilterController(WAO.SAMPLE_ROWS_FILTER_VALUES_JSON_URL, $('#sampling-plan-filters-form')); + // sampleRowsFilterController.init(); + + var sampleRowsFilterMappings = [ + <s:if test="authenticatedWaoUser.authorizedToViewOtherCompanies"> + { + filterName: 'companyIds', + filterLabel: "<s:text name="wao.ui.entity.Company"/>", + filterValuesField: 'companies', + }, + </s:if> + { + filterName: 'programNames', + filterLabel: "<s:text name="wao.ui.field.SampleRow.programName"/>", + filterValuesField: 'programNames', + }, + { + filterName: 'sampleRowCodes', + filterLabel: "<s:text name="wao.ui.field.SampleRow.code"/>", + filterValuesField: 'sampleRowCodes', + }, + { + filterName: 'fishingZoneFacadeNames', + filterLabel: "<s:text name="wao.ui.field.FishingZone.facadeName"/>", + filterValuesField: 'fishingZoneFacadeNames', + }, + { + filterName: 'fishingZoneSectorNames', + filterLabel: "<s:text name="wao.ui.field.FishingZone.sectorName"/>", + filterValuesField: 'fishingZoneSectorNames', + }, + { + filterName: 'samplingContext', + filterLabel: "<s:text name="wao.ui.field.SampleRow.sclerochronologySamplingContext"/>", + filterValuesField: 'samplingContexts', + }, + { + filterName: 'individualMeasurementStrategy', + filterLabel: "<s:text name="wao.ui.field.SampleRow.individualMeasurementStrategy"/>", + filterValuesField: 'individualMeasurementStrategies', + }, + { + filterName: 'species', + filterLabel: "<s:text name="wao.ui.field.SampleRow.species"/>", + filterValuesField: 'species' + } + ]; + + filter = <s:property value="filter" escapeHtml="false"/>; + + sampleRowsFilterController2 = new FilterController2(sampleRowsFilterMappings, filter, WAO.SAMPLE_ROWS_FILTER_VALUES_JSON_URL, $('#sampling-plan-filters-form fieldset.extra-filters')); + sampleRowsFilterController2.init(); + + $('#switch-estimated-real').click(function () { + $('#switch-estimated-real').toggleClass('show-estimated').toggleClass('show-real'); + $('table.sampling-plan').toggleClass('show-estimated').toggleClass('show-real'); + $('.estimated-differ-from-real').effect( "highlight", "slow" ) + }); + + var $views = $('#switch-compact-full-view, table.sampling-plan'); + $views.toggleCompactFullView(WAO.getCookie().samplingPlanFullView); + + $('#switch-compact-full-view').click(function () { + WAO.getCookie().samplingPlanFullView = ! WAO.getCookie().samplingPlanFullView; + $views.toggleCompactFullView(WAO.getCookie().samplingPlanFullView); + }); + + }); + + </script> + + </head> + + <content tag="mainClass">large</content> + <content tag="samplingPlanMenuItemClass">active</content> + + <s:if test="authenticatedWaoUser.authorizedToEditSamplingPlan"> + <content tag="administrationMenuOtherOptions"> + <li> + <s:url action="edit-sample-row!input" id="createSampleRow"/> + <s:a href="%{createSampleRow}"> + <i class="icon-plus"></i> <s:text name="wao.ui.action.createSampleRow"/> + </s:a> + </li> + </content> + </s:if> + + <s:form method="GET" id="sampling-plan-filters-form" cssClass="filters-form"> + + <fieldset class="filters-group"> + + <s:textfield name="filter.periodFrom" + label="%{getText('wao.ui.form.periodFrom')}" + placeholder="%{getFilterPeriodFromPlaceholder()}" + cssClass="input-small" /> + + <s:textfield name="filter.periodTo" + label="%{getText('wao.ui.form.period.to')}" + placeholder="%{getFilterPeriodToPlaceholder()}" + cssClass="input-small" /> + + </fieldset> + + <fieldset class="extra-filters"> + + </fieldset> + + <div class="form-actions"> + + <s:submit type="button" action="sampling-plan!applyFilter" cssClass="btn btn-primary"> + <i class="icon-filter"></i> <s:text name="wao.ui.action.filter" /> + </s:submit> + + <s:submit type="button" action="sampling-plan!resetFilter" cssClass="btn"> + <i class="icon-trash"></i> <s:text name="wao.ui.action.reset"/> + </s:submit> + + <s:if test="authenticatedWaoUser.authorizedToExportSamplingPlan"> + <s:submit action="export-sampling-plan" type="button" cssClass="btn"> + <i class="icon-download"></i> <s:text name="wao.ui.action.csvExport" /> + </s:submit> + </s:if> + + </div> + + </s:form> + + <div class="sticky-buttons"> + <button type="button" id="switch-compact-full-view" class="btn"> + <span class="only-in-compact-view"> + <i class="fa fa-expand"></i><span class="only-on-hover"> <s:text name="wao.ui.action.switchToFullView" /></span> + </span> + <span class="only-in-full-view"> + <i class="fa fa-compress"></i><span class="only-on-hover"> <s:text name="wao.ui.action.switchToCompactView" /></span> + </span> + </button> + + <s:if test="authenticatedWaoUser.authorizedToViewSamplingPlanReal"> + <button type="button" id="switch-estimated-real" class="btn show-estimated"> + <span class="estimated"> + <i class="fa fa-adjust"></i><span class="only-on-hover"> <s:text name="wao.ui.action.viewReal" /></span> + </span> + <span class="real"> + <i class="fa fa-adjust"></i><span class="only-on-hover"> <s:text name="wao.ui.action.viewEstimated" /></span> + </span> + </button> + </s:if> + </div> + +<s:if test="authenticatedWaoUser.authorizedToViewOtherCompanies"> + <s:set var="nbColumnsForProfessionInFullView" value="10" /> +</s:if> +<s:else> + <s:set var="nbColumnsForProfessionInFullView" value="9" /> +</s:else> +<s:set var="nbColumnsForProfessionInCompactView" value="6" /> +<s:set var="nbColumnsForMonths" value="%{samplingPlan.months.size() + 1}" /> +<s:set var="nbColumnsForOther" value="2" /> +<s:set var="nbColumnsTotalInFullView" value="%{#nbColumnsForProfessionInFullView + #nbColumnsForMonths + #nbColumnsForOther}" /> +<s:set var="nbColumnsTotalInCompactView" value="%{#nbColumnsForProfessionInCompactView + #nbColumnsForMonths + #nbColumnsForOther}" /> + + <table id="sampling-plan" class="large-table sampling-plan show-estimated"> + <thead> + <tr> + <th colspan="<s:property value="#nbColumnsForProfessionInFullView" />" class="only-in-full-view"> + <s:text name="wao.ui.samplingPlan.sampledProfessions" /> + </th> + <th colspan="<s:property value="#nbColumnsForProfessionInCompactView" />" class="only-in-compact-view"> + <s:text name="wao.ui.samplingPlan.sampledProfessions" /> + </th> + <th colspan="${nbColumnsForMonths}"> + <s:text name="wao.ui.samplingPlan.effort" /> + + <s:if test="authenticatedWaoUser.authorizedToViewSamplingPlanReal"> + [ + <span class="estimated"> + (<s:text name="wao.ui.samplingPlan.actual" /> + <s:text name="wao.ui.samplingPlan.estimated" />) + </span> + <span class="real"> + <s:text name="wao.ui.samplingPlan.actual" /> + </span> + / + <s:text name="wao.ui.samplingPlan.expected" /> + ] + </s:if> + </th> + <th colspan="${nbColumnsForOther}"><s:text name="wao.ui.misc.others" /></th> + </tr> + <tr> + <!-- Profession columns --> + <th><s:text name="wao.ui.field.SampleRow.code"/></th> + <th><s:text name="wao.ui.samplingPlan.program"/></th> + <s:if test="authenticatedWaoUser.authorizedToViewOtherCompanies"> + <th class="only-in-full-view"> + <s:text name="wao.ui.entity.Organisation"/> + </th> + </s:if> + <th><s:text name="wao.ui.entity.FishingZone"/></th> + <th class="only-in-full-view"><s:text name="wao.ui.samplingPlan.fishingZoneInfo"/></th> + <th><s:text name="wao.ui.field.SampleRow.sclerochronologySamplingContext"/></th> + <th><s:text name="wao.ui.field.SampleRow.sclerochronologySamplingContextInfo"/></th> + <th><s:text name="wao.ui.field.SampleRow.individualMeasurementStrategy"/></th> + <th class="only-in-full-view"><s:text name="wao.ui.field.SampleRow.periodBegin"/></th> + <th class="only-in-full-view"><s:text name="wao.ui.field.SampleRow.periodEnd"/></th> + + <!-- Months columns --> + <s:iterator value="samplingPlan.months" var="month"> + <th class="effort <s:if test="isCurrentMonth(#month)"> now</s:if>"> + <span class="month"><s:property value="%{formatDateMonth(#month)}"/></span> + <span class="year"><s:property value="%{formatDateYear(#month)}"/></span> + </th> + </s:iterator> + <th><s:text name="wao.ui.misc.total"/></th> + <!-- Other columns --> + <th><s:text name="wao.ui.misc.comment"/></th> + <th><s:text name="wao.ui.samplingPlan.actions"/></th> + </tr> + </thead> + <tbody> + +<%--Iterate on Facades--%> +<s:iterator value="samplingPlan" var="samplingPlanFacade"> + <tr class="facade-row"> + <th colspan="${nbColumnsTotalInFullView}" class="facade only-in-full-view"> + <s:property value="%{#samplingPlanFacade.facade}"/> + </th> + <th colspan="${nbColumnsTotalInCompactView}" class="facade only-in-compact-view"> + <s:property value="%{#samplingPlanFacade.facade}"/> + </th> + </tr> +<%--Iterate on Sectors --%> +<s:iterator value="samplingPlanFacade" var="samplingPlanSector"> + <tr class="sector-row"> + <th colspan="${nbColumnsTotalInFullView}" class="sector only-in-full-view"> + <s:property value="%{#samplingPlanSector.sectors}"/> + </th> + </tr> + <tr class="sector-row"> + <th colspan="${nbColumnsTotalInCompactView}" class="sector only-in-compact-view"> + <s:property value="%{#samplingPlanSector.sectors}"/> + </th> + </tr> +<%--Iterate on SampleRows --%> +<s:iterator value="samplingPlanSector" var="samplingPlanRow"> + <tr class="sample-row-row<s:if test="sampleRowId.equals(sampleRowToHighlightId)"> highlight</s:if>"> + <th> + <s:property value="code" /> + <s:if test="recentlyUpdated"> + <span class="label label-important"> + <s:text name="wao.ui.misc.recentUpdate" /> + </span> + </s:if> + </th> + <td><s:property value="programName" /></td> + <s:if test="authenticatedWaoUser.authorizedToViewOtherCompanies"> + <td class="only-in-full-view"> + <s:property value="companyName" /> + </td> + </s:if> + <td class="only-in-full-view"><s:property value="fishingZones" /></td> + <td class="only-in-compact-view"> + <s:if test="fishingZonesInfos == null"> + <s:property value="fishingZones"/> + </s:if> + <s:else> + <span data-original-title="<s:property value="fishingZonesInfos" escapeHtml="false"/>" data-toggle="tooltip" data-placement="left"> + <s:property value="fishingZones"/> + </span> + </s:else> + </td> + <td class="only-in-full-view"> + <s:property value="fishingZonesInfos" /> + </td> + <td> + <s:property value="samplingContext"/> + </td> + <td> + <s:property value="samplingContextInfo"/> + </td> + <td> + <s:property value="individualMeasurementStrategy"/> + </td> + <td class="only-in-full-view"><s:property value="%{formatMonth(periodBegin)}" /></td> + <td class="only-in-full-view"><s:property value="%{formatMonth(periodEnd)}" /></td> + <!-- Months columns --> +<s:iterator value="samplingPlan.months" var="month"> + <s:set var="effort" value="#samplingPlanRow.effortInObservationsPerMonths.get(#month)"/> + <s:set var="now" value="%{isCurrentMonth(#month)}"/> + <s:set var="showPercentage" value="false"/> + <%@include file="../templates/td-effort.jsp" %> +</s:iterator> + + <s:set var="effort" value="#samplingPlanRow.totalObservations"/> + <s:set var="now" value="false"/> + <s:set var="showPercentage" value="true"/> + <%@include file="../templates/td-effort.jsp" %> + + <td> + <s:if test=" ! comment.empty"> + <i title="<s:property value="comment" escapeHtml="true"/>" class="fa fa-comment"></i> + </s:if> + </td> + + <td class="actions"> + <div class="dropdown"> + <a class="btn dropdown-toggle" data-toggle="dropdown" href="#"> + <s:text name="wao.ui.actions" /> + <b class="caret"></b> + </a> + <ul class="dropdown-menu"> + <s:if test="authenticatedWaoUser.authorizedToEditSamplingPlan"> + <li> + <s:url action="edit-sample-row!input" id="editSampleRowUrl"> + <s:param name="sampleRowId" value="sampleRowId" /> + </s:url> + <s:a href="%{editSampleRowUrl}"> + <i class="icon-edit"></i> <s:text name="wao.ui.action.editOrDeleteSampleRow" /> + </s:a> + </li> + </s:if> + <s:if test="authenticatedWaoUser.authorizedToViewSampleRowLog"> + <li> + <s:url action="sample-row-log" id="sampleRowLogUrl"> + <s:param name="sampleRowId" value="sampleRowId" /> + </s:url> + <s:a href="%{sampleRowLogUrl}"> + <i class="icon-time"></i> <s:text name="wao.ui.action.viewSampleRowLog" /> + </s:a> + </li> + </s:if> + <li> + <s:url action="sampling-plan!applyFilter" id="sampleRowZoomUrl"> + <s:param name="filter.periodFrom" value="%{formatMonth(firstSampleMonthDate)}"/> + <s:param name="filter.periodTo" value="%{formatMonth(lastSampleMonthDate)}"/> + <s:param name="filter.companyIds" value="%{filter.companyIds}"/> + <s:param name="filter.programNames" value="%{filter.programNames}"/> + <s:param name="filter.sampleRowCodes" value="%{filter.sampleRowCodes}"/> + <s:param name="filter.fishingZoneFacadeNames" value="%{filter.targetSpeciesDcfIds}"/> + <s:param name="filter.fishingZoneSectorNames" value="%{filter.targetSpeciesDcfIds}"/> + <s:param name="filter.fishingGearDcfIds" value="%{filter.targetSpeciesDcfIds}"/> + <s:param name="filter.targetSpeciesDcfIds" value="%{filter.targetSpeciesDcfIds}"/> + </s:url> + <s:a href="%{sampleRowZoomUrl}"> + <i class="icon-filter"></i> <s:text name="wao.ui.action.zoomOnSampleRowPeriod" /> + </s:a> + </li> + <s:if test="authenticatedWaoUser.authorizedToViewBoats && elligibleBoatsProvided"> + <li> + <s:url action="boats!applyFilter" id="viewElligibleBoatsUrl"> + <s:param name="filter.elligibleForSampleRowsFilter.sampleRowCodes" value="code" /> + </s:url> + <s:a href="%{viewElligibleBoatsUrl}"> + <i class="fa fa-anchor"></i> <s:text name="wao.ui.action.viewElligibleBoats" /> + </s:a> + </li> + </s:if> + <s:if test="authenticatedWaoUser.authorizedToViewContacts && sampleRowContactCounts > 0"> + <li> + <s:url action="contacts!applyFilter" id="viewAssociatedContactsUrl"> + <s:param name="filter.sampleRowFilter.sampleRowCodes" value="code" /> + <s:param name="filter.periodFrom" /> + <s:param name="filter.periodTo" /> + </s:url> + <s:a href="%{viewAssociatedContactsUrl}"> + <i class="fa fa-stack-exchange"></i> <s:text name="wao.ui.action.viewAssociatedContacts" /> + </s:a> + </li> + </s:if> + <s:if test="authenticatedWaoUser.authorizedToCreateContact && newContactCreatable"> + <li> + <s:url action="boats!applyFilter" id="createAssociatedContactUrl"> + <s:param name="startBoatSelectionForSampleRowId" value="sampleRowId" /> + </s:url> + <s:a href="%{createAssociatedContactUrl}"> + <i class="icon-plus"></i> <s:text name="wao.ui.action.createAssociatedContact" /> + </s:a> + </li> + </s:if> + </ul> + </div> + </td> + </tr> +<%--Iterate on SampleRows --%> +</s:iterator> +<%--Iterate on Sectors --%> +</s:iterator> +<%--Iterate on Facades--%> +</s:iterator> + + </todby> + <tfoot> + <th colspan="<s:property value="#nbColumnsForProfessionInFullView" />" class="only-in-full-view"> + <s:text name="wao.ui.misc.totals" /> + </th> + <th colspan="<s:property value="#nbColumnsForProfessionInCompactView" />" class="only-in-compact-view"> + <s:text name="wao.ui.misc.totals" /> + </th> + <!-- Months columns --> + <s:iterator value="samplingPlan.months" var="month"> + <s:set var="effort" value="samplingPlan.totalEffortInObservationsPerMonths.get(#month)"/> + <s:set var="now" value="%{isCurrentMonth(#month)}"/> + <s:set var="showPercentage" value="true"/> + <%@include file="../templates/td-effort.jsp" %> + </s:iterator> + + <s:set var="effort" value="samplingPlan.highTotalEffortInObservations"/> + <s:set var="now" value="false"/> + <s:set var="showPercentage" value="true"/> + <%@include file="../templates/td-effort.jsp" %> + + <th colspan="${nbColumnsForOther}"></th> + </tfoot> + </table> + +</html> -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.