Author: bleny Date: 2014-03-11 14:44:08 +0100 (Tue, 11 Mar 2014) New Revision: 1717 Url: http://forge.codelutin.com/projects/wao/repository/revisions/1717 Log: refs #4483 introduce edit-sample-row form Added: trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSamplingPlanService.java trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/UpdateSampleRowCommand.java trunk/wao-web/src/main/java/fr/ifremer/wao/web/action/obsmer/EditSampleRowAction.java trunk/wao-web/src/main/webapp/WEB-INF/content/obsmer/edit-sample-row-input.jsp Modified: trunk/wao-persistence/src/main/java/fr/ifremer/wao/entity/Boats.java trunk/wao-persistence/src/main/java/fr/ifremer/wao/entity/DCF5CodeImpl.java trunk/wao-persistence/src/main/java/fr/ifremer/wao/entity/SamplingStrategy.java trunk/wao-persistence/src/main/xmi/wao-model.zargo trunk/wao-services/src/main/java/fr/ifremer/wao/services/AuthenticatedWaoUser.java trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/administration/CompaniesService.java trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/administration/ReferentialService.java trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/administration/WaoUsersService.java trunk/wao-web/src/main/java/fr/ifremer/wao/web/WaoInterceptor.java trunk/wao-web/src/main/java/fr/ifremer/wao/web/action/administration/CompaniesAction.java trunk/wao-web/src/main/resources/i18n/wao-web_en_GB.properties trunk/wao-web/src/main/resources/i18n/wao-web_fr_FR.properties trunk/wao-web/src/main/webapp/css/wao.css Modified: trunk/wao-persistence/src/main/java/fr/ifremer/wao/entity/Boats.java =================================================================== --- trunk/wao-persistence/src/main/java/fr/ifremer/wao/entity/Boats.java 2014-03-06 16:50:28 UTC (rev 1716) +++ trunk/wao-persistence/src/main/java/fr/ifremer/wao/entity/Boats.java 2014-03-11 13:44:08 UTC (rev 1717) @@ -1,6 +1,8 @@ package fr.ifremer.wao.entity; import com.google.common.base.Function; +import com.google.common.collect.Iterables; +import org.apache.commons.lang3.StringUtils; public class Boats { @@ -8,6 +10,12 @@ return new GetImmatriculation(); } + public static String toImmatriculations(Iterable<Boat> boats) { + return StringUtils.join( + Iterables.transform(boats, getImmatriculation()), + ' '); + } + protected static class GetImmatriculation implements Function<Boat, Integer> { @Override Modified: trunk/wao-persistence/src/main/java/fr/ifremer/wao/entity/DCF5CodeImpl.java =================================================================== --- trunk/wao-persistence/src/main/java/fr/ifremer/wao/entity/DCF5CodeImpl.java 2014-03-06 16:50:28 UTC (rev 1716) +++ trunk/wao-persistence/src/main/java/fr/ifremer/wao/entity/DCF5CodeImpl.java 2014-03-11 13:44:08 UTC (rev 1717) @@ -20,6 +20,8 @@ */ package fr.ifremer.wao.entity; +import com.google.common.base.Objects; + public class DCF5CodeImpl extends DCF5CodeAbstract { @Override @@ -51,11 +53,18 @@ } @Override - public String toString() { + public String getCode() { String toString = getFishingGearCode(); if (getTargetSpeciesDCF() != null) { toString += "_" + getTargetSpeciesCode(); } return toString; } + + @Override + public String toString() { + String toString = Objects.toStringHelper(this).add("code", getCode()).toString(); + return toString; + } + } Modified: trunk/wao-persistence/src/main/java/fr/ifremer/wao/entity/SamplingStrategy.java =================================================================== --- trunk/wao-persistence/src/main/java/fr/ifremer/wao/entity/SamplingStrategy.java 2014-03-06 16:50:28 UTC (rev 1716) +++ trunk/wao-persistence/src/main/java/fr/ifremer/wao/entity/SamplingStrategy.java 2014-03-11 13:44:08 UTC (rev 1717) @@ -49,4 +49,8 @@ // return WaoUtils.t(i18nKey); throw new UnsupportedOperationException(); } + + public boolean isSpecificStock() { + return SPECIFIC_STOCK == this; + } } Modified: trunk/wao-persistence/src/main/xmi/wao-model.zargo =================================================================== (Binary files differ) Modified: trunk/wao-services/src/main/java/fr/ifremer/wao/services/AuthenticatedWaoUser.java =================================================================== --- trunk/wao-services/src/main/java/fr/ifremer/wao/services/AuthenticatedWaoUser.java 2014-03-06 16:50:28 UTC (rev 1716) +++ trunk/wao-services/src/main/java/fr/ifremer/wao/services/AuthenticatedWaoUser.java 2014-03-11 13:44:08 UTC (rev 1717) @@ -166,4 +166,8 @@ } return authorizedToEditOrDeleteNews; } + + public boolean isAuthorizedToCreateSampleRow() { + return userProfile.isAdmin(); + } } Added: trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSamplingPlanService.java =================================================================== --- trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSamplingPlanService.java (rev 0) +++ trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSamplingPlanService.java 2014-03-11 13:44:08 UTC (rev 1717) @@ -0,0 +1,235 @@ +package fr.ifremer.wao.services.service; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import fr.ifremer.wao.entity.Boat; +import fr.ifremer.wao.entity.Boats; +import fr.ifremer.wao.entity.Company; +import fr.ifremer.wao.entity.DCF5Code; +import fr.ifremer.wao.entity.ElligibleBoat; +import fr.ifremer.wao.entity.ElligibleBoatImpl; +import fr.ifremer.wao.entity.ElligibleBoatTopiaDao; +import fr.ifremer.wao.entity.FishingZone; +import fr.ifremer.wao.entity.ObsProgram; +import fr.ifremer.wao.entity.ProfessionImpl; +import fr.ifremer.wao.entity.SampleMonth; +import fr.ifremer.wao.entity.SampleRow; +import fr.ifremer.wao.entity.SampleRowImpl; +import fr.ifremer.wao.entity.SampleRowLog; +import fr.ifremer.wao.entity.SampleRowLogImpl; +import fr.ifremer.wao.entity.SampleRowTopiaDao; +import fr.ifremer.wao.entity.SamplingStrategy; +import fr.ifremer.wao.services.AuthenticatedWaoUser; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.topia.persistence.TopiaEntities; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class ObsMerSamplingPlanService extends WaoServiceSupport { + + private static final Log log = LogFactory.getLog(ObsMerSamplingPlanService.class); + + public UpdateSampleRowCommand newUpdateSampleRowCommand(AuthenticatedWaoUser authenticatedWaoUser, Optional<String> optionalSampleRowId) { + + Preconditions.checkState(authenticatedWaoUser.isAuthorizedToCreateSampleRow()); + + UpdateSampleRowCommand updateSampleRowCommand = + new UpdateSampleRowCommand(); + + if (optionalSampleRowId.isPresent()) { + + String sampleRowId = optionalSampleRowId.get(); + + SampleRow sampleRow = getSampleRowDao().findByTopiaId(sampleRowId); + + updateSampleRowCommand.setSampleRow(sampleRow); + + updateSampleRowCommand.setCreation(false); + + SampleRowLogImpl newSampleRowLog = new SampleRowLogImpl(); + newSampleRowLog.setAuthor(authenticatedWaoUser.getWaoUser()); + newSampleRowLog.setFromAdmin(authenticatedWaoUser.isAdmin()); + updateSampleRowCommand.setSampleRowLog(newSampleRowLog); + sampleRow.addSampleRowLog(newSampleRowLog); + + Set<Boat> elligibleBoats = new HashSet<>(); + for (ElligibleBoat elligibleBoat : sampleRow.getElligibleBoat()) { + boolean boatIsElligibleForUser = + authenticatedWaoUser.isAdmin() && elligibleBoat.isGlobalActive() || + authenticatedWaoUser.isCoordinator() && BooleanUtils.isTrue(elligibleBoat.getCompanyActive()); + if (boatIsElligibleForUser) { + elligibleBoats.add(elligibleBoat.getBoat()); + } + } + String elligibleBoatImmatriculations = Boats.toImmatriculations(elligibleBoats); + updateSampleRowCommand.setElligibleBoatImmatriculations(elligibleBoatImmatriculations); + + Set<String> dcf5Codes = new HashSet<>(); + for (DCF5Code dcf5Code : sampleRow.getdCF5Code()) { + dcf5Codes.add(dcf5Code.getCode()); + } + updateSampleRowCommand.setDcf5Codes(StringUtils.join(dcf5Codes, ' ')); + + } else { + + SampleRow newSampleRow = new SampleRowImpl(); + + newSampleRow.setObsProgram(ObsProgram.OBSMER); + newSampleRow.setProfession(new ProfessionImpl()); + newSampleRow.setFishingZone(new ArrayList<FishingZone>()); + newSampleRow.setSampleMonth(new ArrayList<SampleMonth>()); + newSampleRow.setSamplingStrategy(SamplingStrategy.SIMULTANEOUS_ALL_SPECIES); + + String newSampleRowCode = getNewSampleRowCode(ObsProgram.OBSMER); + newSampleRow.setCode(newSampleRowCode); + + updateSampleRowCommand.setSampleRow(newSampleRow); + + updateSampleRowCommand.setCreation(true); + + } + + ImmutableMap<String, FishingZone> allFishingZones = + Maps.uniqueIndex( + getReferentialService().getAllFishingZones(), + TopiaEntities.getTopiaIdFunction() + ); + updateSampleRowCommand.setAllFishingZones(allFishingZones); + + ImmutableMap<String, Company> allCompanies = + Maps.uniqueIndex( + getCompaniesService().getAllCompanies(), + TopiaEntities.getTopiaIdFunction() + ); + updateSampleRowCommand.setAllCompanies(allCompanies); + + return updateSampleRowCommand; + + } + + /** + * On va rechercher en base pour générer un code qui n'existe pas déjà. + */ + protected String getNewSampleRowCode(ObsProgram obsProgram) { + + // On pré-définit un code pour la nouvelle ligne. + // au moment de la création d'une nouvelle ligne, on a aucune info donc + // on suppose que c'est pour l'année en cours + + Calendar begin = new GregorianCalendar(); + begin.setTime(getNow()); + int year = begin.get(Calendar.YEAR); + + String newSampleRowCodePrefix = year + "_" + obsProgram.getShortCode(); + + SampleRowTopiaDao dao = getSampleRowDao(); + + Optional<String> optionalMaxSampleRowCode = dao.findMaxSampleRowCode(newSampleRowCodePrefix); + int maxSampleRowCodeSequence; + if (optionalMaxSampleRowCode.isPresent()) { + String maxSampleRowCode = optionalMaxSampleRowCode.get(); + if (log.isDebugEnabled()) { + log.debug("max code found : " + maxSampleRowCode); + } + String sequenceStr = StringUtils.removeStart(maxSampleRowCode, newSampleRowCodePrefix); + maxSampleRowCodeSequence = Integer.parseInt(sequenceStr); + } else { + maxSampleRowCodeSequence = 0; + } + + maxSampleRowCodeSequence += 1; + + String newSampleRowCodeSuffix = StringUtils.leftPad(String.valueOf(maxSampleRowCodeSequence), 4, "0"); + + String newSampleRowCode = newSampleRowCodePrefix + newSampleRowCodeSuffix; + + if (log.isInfoEnabled()) { + log.info("new sample row code for " + obsProgram + " is " + newSampleRowCode); + } + + return newSampleRowCode; + + } + + public void preValidate(AuthenticatedWaoUser authenticatedWaoUser, UpdateSampleRowCommand updateSampleRowCommand) { + + // TODO brendan 10/03/14 mettre à jour les codes DCF5 + + String elligibleBoatImmatriculations = updateSampleRowCommand.getElligibleBoatImmatriculations(); + + List<Boat> elligibleBoats = getReferentialService().getBoatsFromImmatriculations(elligibleBoatImmatriculations); + + SampleRow sampleRow = updateSampleRowCommand.getSampleRow(); + + for (Boat boat : elligibleBoats) { + ElligibleBoat elligibleBoat = sampleRow.getElligibleBoatByBoat(boat); + if (elligibleBoat == null) { + elligibleBoat = new ElligibleBoatImpl(); + elligibleBoat.setSampleRow(sampleRow); + elligibleBoat.setBoat(boat); + } + if (authenticatedWaoUser.isAdmin()) { + elligibleBoat.setGlobalActive(true); + } else if (authenticatedWaoUser.isCoordinator()) { + elligibleBoat.setCompanyActive(true); + } + } + + for (ElligibleBoat elligibleBoat : sampleRow.getElligibleBoat()) { + Boat boat = elligibleBoat.getBoat(); + boolean isNoLongerActive = ! elligibleBoats.contains(boat); + if (isNoLongerActive) { + if (authenticatedWaoUser.isAdmin()) { + elligibleBoat.setGlobalActive(false); + } else if (authenticatedWaoUser.isCoordinator()) { + elligibleBoat.setCompanyActive(null); + } + } + } + + String dcf5Codes = updateSampleRowCommand.getDcf5Codes(); + + sampleRow.cleardCF5Code(); + sampleRow.addAlldCF5Code(getReferentialService().getDcf5Codes(dcf5Codes)); + + } + + public void save(UpdateSampleRowCommand updateSampleRowCommand) { + + SampleRow sampleRow = updateSampleRowCommand.getSampleRow(); + + if ( ! updateSampleRowCommand.isCreation()) { + SampleRowLog sampleRowLog = updateSampleRowCommand.getSampleRowLog(); + getSampleRowLogDao().create(sampleRowLog); + } + + ElligibleBoatTopiaDao elligibleBoatDao = getElligibleBoatDao(); + for (ElligibleBoat elligibleBoat : sampleRow.getElligibleBoat()) { + if (elligibleBoat.isPersisted()) { + elligibleBoatDao.update(elligibleBoat); + } else { + elligibleBoatDao.create(elligibleBoat); + } + } + + SampleRowTopiaDao dao = getSampleRowDao(); + if (sampleRow.isPersisted()) { + dao.update(sampleRow); + } else { + dao.create(sampleRow); + } + commit(); + + } + +} Added: trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/UpdateSampleRowCommand.java =================================================================== --- trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/UpdateSampleRowCommand.java (rev 0) +++ trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/UpdateSampleRowCommand.java 2014-03-11 13:44:08 UTC (rev 1717) @@ -0,0 +1,140 @@ +package fr.ifremer.wao.services.service; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; +import com.google.common.collect.Sets; +import fr.ifremer.wao.entity.Company; +import fr.ifremer.wao.entity.FishingZone; +import fr.ifremer.wao.entity.SampleRow; +import fr.ifremer.wao.entity.SampleRowLog; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.nuiton.topia.persistence.TopiaEntities; + +import java.util.Set; + +public class UpdateSampleRowCommand { + + protected boolean creation; + + protected SampleRow sampleRow; + + protected SampleRowLog sampleRowLog; + + protected ImmutableMap<String, FishingZone> allFishingZones; + + protected ImmutableMap<String, Company> allCompanies; + + protected String elligibleBoatImmatriculations; + + protected String dcf5Codes; + + public String getCompanyId() { + String companyId = null; + if (sampleRow.getCompany() != null) { + companyId = sampleRow.getCompany().getTopiaId(); + } + return companyId; + } + + public void setCompanyId(String companyId) { + Company company = null; + if (StringUtils.isNotBlank(companyId)) { + company = allCompanies.get(companyId); + } + sampleRow.setCompany(company); + } + + // TODO brendan 10/03/14 supprimer les sample months si effort = "" + + public void setCode(String code) { + Preconditions.checkState(isCreation(), "cannot change code for sample row " + sampleRow); + sampleRow.setCode(code); + } + + public String getCode() { + return sampleRow.getCode(); + } + + public boolean isCreation() { + return creation; + } + + public void setCreation(boolean creation) { + this.creation = creation; + } + + public void setSampleRow(SampleRow sampleRow) { + this.sampleRow = sampleRow; + } + + public SampleRow getSampleRow() { + return sampleRow; + } + + public void setSampleRowLog(SampleRowLog sampleRowLog) { + this.sampleRowLog = sampleRowLog; + } + + public SampleRowLog getSampleRowLog() { + return sampleRowLog; + } + + public Set<String> getFishingZoneIds() { + Set<String> fishingZoneIds; + if (sampleRow.getFishingZone() == null) { + fishingZoneIds = null; + } else { + fishingZoneIds = Sets.newHashSet( + Iterables.transform( + sampleRow.getFishingZone(), + TopiaEntities.getTopiaIdFunction() + ) + ); + } + return fishingZoneIds; + } + + public void setFishingZoneIds(Set<String> fishingZoneIds) { + sampleRow.clearFishingZone(); + if (CollectionUtils.isNotEmpty(fishingZoneIds)) { + for (String fishingZoneId : fishingZoneIds) { + FishingZone fishingZone = allFishingZones.get(fishingZoneId); + sampleRow.addFishingZone(fishingZone); + } + } + } + + public ImmutableMap<String, FishingZone> getAllFishingZones() { + return allFishingZones; + } + + public void setAllFishingZones(ImmutableMap<String, FishingZone> allFishingZones) { + this.allFishingZones = allFishingZones; + } + + public ImmutableMap<String, Company> getAllCompanies() { + return allCompanies; + } + + public void setAllCompanies(ImmutableMap<String, Company> allCompanies) { + this.allCompanies = allCompanies; + } + + public String getElligibleBoatImmatriculations() { + return elligibleBoatImmatriculations; + } + + public void setElligibleBoatImmatriculations(String elligibleBoatImmatriculations) { + this.elligibleBoatImmatriculations = elligibleBoatImmatriculations; + } + + public String getDcf5Codes() { + return dcf5Codes; + } + + public void setDcf5Codes(String dcf5Codes) { + this.dcf5Codes = dcf5Codes; + } +} Modified: trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/administration/CompaniesService.java =================================================================== --- trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/administration/CompaniesService.java 2014-03-06 16:50:28 UTC (rev 1716) +++ trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/administration/CompaniesService.java 2014-03-11 13:44:08 UTC (rev 1717) @@ -12,7 +12,7 @@ public class CompaniesService extends WaoServiceSupport { - public List<Company> getCompanies() { + public List<Company> getAllCompanies() { CompanyTopiaDao dao = getPersistenceContext().getCompanyDao(); Modified: trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/administration/ReferentialService.java =================================================================== --- trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/administration/ReferentialService.java 2014-03-06 16:50:28 UTC (rev 1716) +++ trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/administration/ReferentialService.java 2014-03-11 13:44:08 UTC (rev 1717) @@ -24,8 +24,10 @@ package fr.ifremer.wao.services.service.administration; +import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import fr.ifremer.wao.WaoTechnicalException; import fr.ifremer.wao.entity.Boat; @@ -36,6 +38,7 @@ import fr.ifremer.wao.entity.ContactStateMotif; import fr.ifremer.wao.entity.ContactStateMotifTopiaDao; import fr.ifremer.wao.entity.DCF5Code; +import fr.ifremer.wao.entity.DCF5CodeTopiaDao; import fr.ifremer.wao.entity.FishingGearDCF; import fr.ifremer.wao.entity.FishingGearDCFTopiaDao; import fr.ifremer.wao.entity.FishingZone; @@ -92,6 +95,7 @@ import java.io.InputStream; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -216,6 +220,17 @@ } + + public List<FishingZone> getAllFishingZones() { + + FishingZoneTopiaDao dao = getPersistenceContext().getFishingZoneDao(); + + List<FishingZone> fishingZones = dao.newQueryBuilder().setOrderByArguments(FishingZone.PROPERTY_LATITUDE + " desc").findAll(); + + return fishingZones; + + } + /** * Import des lieux terrestres (ports et criées). */ @@ -999,4 +1014,52 @@ } + /** + * Étant donné une suite de codes DCF séparés par des caractères blancs, on retourne + * les instances de {@link fr.ifremer.wao.entity.DCF5Code} correspondantes en ajoutant + * les manquantes au référentiel au besoin. + */ + public Collection<DCF5Code> getDcf5Codes(String joinedDcf5Codes) { + + Collection<DCF5Code> dcf5Codes = new HashSet<>(); + + DCF5CodeTopiaDao dao = getDCF5CodeDao(); + + if (StringUtils.isNotBlank(joinedDcf5Codes)) { + + String[] splitCodes = joinedDcf5Codes.split("\\s?"); + + for (String code : splitCodes) { + + String[] codeParts = code.split("_"); + + FishingGearDCF fishingGearDCF = getFishingGearDCFDao().forCodeEquals(codeParts[0]).findUnique(); + TargetSpeciesDCF targetSpeciesDCF = null; + if (codeParts.length == 2) { + targetSpeciesDCF = getTargetSpeciesDCFDao().forCodeEquals(codeParts[1]).findUnique(); + } + + ImmutableMap<String, Object> properties = + ImmutableMap.of( + DCF5Code.PROPERTY_FISHING_GEAR_DCF, (Object) fishingGearDCF, + DCF5Code.PROPERTY_TARGET_SPECIES_DCF, targetSpeciesDCF + ); + + Optional<DCF5Code> optionalDcf5Code = dao.forProperties(properties).tryFindUnique(); + + DCF5Code dcf5Code; + if (optionalDcf5Code.isPresent()) { + dcf5Code = optionalDcf5Code.get(); + } else { + dcf5Code = dao.create(properties); + } + + dcf5Codes.add(dcf5Code); + + } + } + + return dcf5Codes; + } + } Modified: trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/administration/WaoUsersService.java =================================================================== --- trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/administration/WaoUsersService.java 2014-03-06 16:50:28 UTC (rev 1716) +++ trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/administration/WaoUsersService.java 2014-03-11 13:44:08 UTC (rev 1717) @@ -2,7 +2,6 @@ import com.google.common.base.Optional; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; import com.google.common.collect.Maps; import fr.ifremer.wao.entity.Boat; import fr.ifremer.wao.entity.Boats; @@ -73,7 +72,7 @@ updateWaoUserCommand.setObsProgram(obsProgram); ImmutableMap<String, Company> allCompanies = Maps.uniqueIndex( - getCompaniesService().getCompanies(), + getCompaniesService().getAllCompanies(), TopiaEntities.getTopiaIdFunction()); updateWaoUserCommand.setAllCompanies(allCompanies); @@ -88,10 +87,7 @@ if (waoUser.isCanReadBoatsNotEmpty()) { - String canReadBoats = StringUtils.join( - Iterables.transform(waoUser.getCanReadBoats(), Boats.getImmatriculation()), - ' ' - ); + String canReadBoats = Boats.toImmatriculations(waoUser.getCanReadBoats()); updateWaoUserCommand.setCanReadBoats(canReadBoats); Modified: trunk/wao-web/src/main/java/fr/ifremer/wao/web/WaoInterceptor.java =================================================================== --- trunk/wao-web/src/main/java/fr/ifremer/wao/web/WaoInterceptor.java 2014-03-06 16:50:28 UTC (rev 1716) +++ trunk/wao-web/src/main/java/fr/ifremer/wao/web/WaoInterceptor.java 2014-03-11 13:44:08 UTC (rev 1717) @@ -56,7 +56,7 @@ // login à l'arrache WaoUser admin = serviceContext.getPersistenceContext().getWaoUserDao().forLoginEquals("admin").findUnique(); UserProfile userProfile = new UserProfileImpl(); - userProfile.setUserRole(UserRole.COORDINATOR); + userProfile.setUserRole(UserRole.ADMIN); userProfile.setObsProgram(ObsProgram.OBSMER); userProfile.setCanWrite(true); AuthenticatedWaoUser authenticatedWaoUser = new AuthenticatedWaoUser(admin, userProfile); Modified: trunk/wao-web/src/main/java/fr/ifremer/wao/web/action/administration/CompaniesAction.java =================================================================== --- trunk/wao-web/src/main/java/fr/ifremer/wao/web/action/administration/CompaniesAction.java 2014-03-06 16:50:28 UTC (rev 1716) +++ trunk/wao-web/src/main/java/fr/ifremer/wao/web/action/administration/CompaniesAction.java 2014-03-11 13:44:08 UTC (rev 1717) @@ -20,7 +20,7 @@ @Override public void prepare() { - companies = service.getCompanies(); + companies = service.getAllCompanies(); } Added: trunk/wao-web/src/main/java/fr/ifremer/wao/web/action/obsmer/EditSampleRowAction.java =================================================================== --- trunk/wao-web/src/main/java/fr/ifremer/wao/web/action/obsmer/EditSampleRowAction.java (rev 0) +++ trunk/wao-web/src/main/java/fr/ifremer/wao/web/action/obsmer/EditSampleRowAction.java 2014-03-11 13:44:08 UTC (rev 1717) @@ -0,0 +1,113 @@ +package fr.ifremer.wao.web.action.obsmer; + +import com.google.common.base.Optional; +import com.google.common.base.Strings; +import com.opensymphony.xwork2.Preparable; +import fr.ifremer.wao.WaoUtils; +import fr.ifremer.wao.entity.SampleRow; +import fr.ifremer.wao.services.service.ObsMerSamplingPlanService; +import fr.ifremer.wao.services.service.UpdateSampleRowCommand; +import fr.ifremer.wao.web.WaoJspActionSupport; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.struts2.convention.annotation.Result; +import org.apache.struts2.convention.annotation.Results; + +@Results({ + @Result(name="success", type="redirectAction", params = { "actionName", "sampling-plan" }) +}) +public class EditSampleRowAction extends WaoJspActionSupport implements Preparable { + + private static final Log log = LogFactory.getLog(EditSampleRowAction.class); + + protected ObsMerSamplingPlanService service; + + protected Optional<String> optionalSampleRowId = Optional.absent(); + + protected UpdateSampleRowCommand updateSampleRowCommand; + + public void setService(ObsMerSamplingPlanService service) { + this.service = service; + } + + public String getSampleRowId() { + return optionalSampleRowId.orNull(); + } + + public void setSampleRowId(String sampleRowId) { + this.optionalSampleRowId = Optional.fromNullable(Strings.emptyToNull(sampleRowId)); + } + + @Override + public void prepare() { + + updateSampleRowCommand = service.newUpdateSampleRowCommand(getAuthenticatedWaoUser(), optionalSampleRowId); + + } + + @Override + public void validate() { + + service.preValidate(getAuthenticatedWaoUser(), updateSampleRowCommand); + + SampleRow sampleRow = updateSampleRowCommand.getSampleRow(); + + if (updateSampleRowCommand.isCreation()) { + if ( ! WaoUtils.getSampleRowCodePattern(sampleRow.getObsProgram()).matcher(sampleRow.getCode()).matches()) { + addFieldError("updateSampleRowCommand.code", t("wao.import.sampleRow.failure.wrongSampleRowCodeFormat", sampleRow.getCode())); + } + } else { + if (StringUtils.isBlank(updateSampleRowCommand.getSampleRowLog().getComment())) { + addFieldError("updateSampleRowCommand.sampleRowLog.comment", t("wao.ui.form.SampleRow.error.missingLogComment")); + } + } + + if (StringUtils.isBlank(sampleRow.getProgramName())) { + addFieldError("updateSampleRowCommand.sampleRow.programName", t("wao.ui.form.SampleRow.error.missingProgramName")); + } + + if (sampleRow.getPeriodBegin() == null) { + addFieldError("updateSampleRowCommand.sampleRow.periodBegin", t("wao.ui.form.SampleRow.error.missingPeriodBegin")); + } + + if (sampleRow.getPeriodEnd() == null) { + addFieldError("updateSampleRowCommand.sampleRow.periodEnd", t("wao.ui.form.SampleRow.error.missingPeriodEnd")); + } + + if (CollectionUtils.isEmpty(sampleRow.getdCF5Code())) { + addFieldError("updateSampleRowCommand.dcf5Codes", t("wao.ui.form.SampleRow.error.missingDcf5Codes")); + } + + if (CollectionUtils.isEmpty(sampleRow.getFishingZone())) { + addFieldError("updateSampleRowCommand.fishingZones", t("wao.ui.form.SampleRow.error.missingFishingZones")); + } + + if (sampleRow.getSamplingStrategy().isSpecificStock() && StringUtils.isEmpty(sampleRow.getProfession().getSpecies())) { + addFieldError("updateSampleRowCommand.sampleRow.samplingStrategy", t("wao.ui.form.SampleRow.error.missingProfessionSpecies")); + } + + // FIXME brendan 06/03/14 check code uniqueness + + } + + @Override + public String execute() { + + service.save(updateSampleRowCommand); + + session.addMessage(t("wao.ui.form.updateSampleRowCommand.success", updateSampleRowCommand.getSampleRow().getCode())); + + return SUCCESS; + + } + + public UpdateSampleRowCommand getUpdateSampleRowCommand() { + if (updateSampleRowCommand == null) { + prepare(); + } + return updateSampleRowCommand; + } + +} \ No newline at end of file Modified: trunk/wao-web/src/main/resources/i18n/wao-web_en_GB.properties =================================================================== --- trunk/wao-web/src/main/resources/i18n/wao-web_en_GB.properties 2014-03-06 16:50:28 UTC (rev 1716) +++ trunk/wao-web/src/main/resources/i18n/wao-web_en_GB.properties 2014-03-11 13:44:08 UTC (rev 1717) @@ -11,6 +11,7 @@ wao.import.fishingZones.success=Import fishing zones successful wao.import.obsDebCodes.prompt=Import ObsDeb codes wao.import.obsDebCodes.success=Import ObsDeb codes successful +wao.import.sampleRow.failure.wrongSampleRowCodeFormat= wao.import.terrestrialDivisions.prompt=Import ObsDeb terrestrial divisions wao.import.terrestrialDivisions.success=Import ObsDeb terrestrial divisions successful wao.import.terrestrialLocations.prompt=Import terrestrial locations @@ -151,6 +152,7 @@ wao.ui.field.FishingZone.facadeName=Facade wao.ui.field.FishingZone.sectorName=Sector wao.ui.field.SampleRow.appliedCoverageRate=Applied coverage rate +wao.ui.field.SampleRow.averageTideTime= wao.ui.field.SampleRow.boat=Boat wao.ui.field.SampleRow.code=Line code wao.ui.field.SampleRow.comment=Comment @@ -158,10 +160,14 @@ wao.ui.field.SampleRow.dCF5Code=DCF5 Codes wao.ui.field.SampleRow.day=Day wao.ui.field.SampleRow.dcf5Code=DCF5 code +wao.ui.field.SampleRow.dcf5Codes= +wao.ui.field.SampleRow.elligibleBoat= wao.ui.field.SampleRow.expectedDate=Date wao.ui.field.SampleRow.fishingZones=Fishing zone(s) +wao.ui.field.SampleRow.fishingZonesInfos= wao.ui.field.SampleRow.libelle=Labels wao.ui.field.SampleRow.meshSize=Mesh size +wao.ui.field.SampleRow.nbObservants= wao.ui.field.SampleRow.observationType=Observation type wao.ui.field.SampleRow.observationUnit=Observation unit wao.ui.field.SampleRow.observers=Observers @@ -197,10 +203,17 @@ wao.ui.filters.refresh=Refresh filters wao.ui.forgotPassword=Forgot password ? wao.ui.form.SampleRow.boatsDescription=This field contains registration numbers of the ships that areeligible for this ligne. You can use any separator to separate numbers (space, dot, line-return, comma) +wao.ui.form.SampleRow.error.missingDcf5Codes= +wao.ui.form.SampleRow.error.missingFishingZones= wao.ui.form.SampleRow.error.missingLogComment=You must add a comment to explain why you modified the line +wao.ui.form.SampleRow.error.missingPeriodBegin= +wao.ui.form.SampleRow.error.missingPeriodEnd= +wao.ui.form.SampleRow.error.missingProfessionSpecies= +wao.ui.form.SampleRow.error.missingProgramName= wao.ui.form.SampleRow.missingBeginDate=Begin date missing to generate line code wao.ui.form.SampleRow.others=Others data of the sample row wao.ui.form.SampleRow.program=Associated program and observation effort by months +wao.ui.form.SampleRow.warn.hasSampleMonthRealTideTime= wao.ui.form.WaoUser.credentials=Credentials wao.ui.form.WaoUser.identity=Identity wao.ui.form.WaoUser.preferences=Preferences @@ -230,6 +243,7 @@ wao.ui.form.repeatPassword=Repeat password wao.ui.form.roles=Roles wao.ui.form.sortByTideBegin=Sort by observation begin date +wao.ui.form.updateSampleRowCommand.success= wao.ui.form.updateWaoUserCommand.admin=Administrator wao.ui.form.updateWaoUserCommand.adminReadOnly=Administrator (read-only) wao.ui.form.updateWaoUserCommand.canReadBoats=Only able to read boats @@ -395,6 +409,8 @@ wao.ui.synthesis.observationHours.description=Number of observations according to the time of the day (based on the observation begin date) wao.ui.synthesis.observationHours.title=Observation hours wao.ui.unavailableOperation=Unavailable operation +wao.ui.unit.days= +wao.ui.unit.observers= wao.ui.userList=Users list wao.ui.userMustAcceptCgu=You must accept the terms of use wao.ui.validLogin=Valid identifier Modified: trunk/wao-web/src/main/resources/i18n/wao-web_fr_FR.properties =================================================================== --- trunk/wao-web/src/main/resources/i18n/wao-web_fr_FR.properties 2014-03-06 16:50:28 UTC (rev 1716) +++ trunk/wao-web/src/main/resources/i18n/wao-web_fr_FR.properties 2014-03-11 13:44:08 UTC (rev 1717) @@ -11,6 +11,7 @@ wao.import.fishingZones.success=Import des zones de pêches réalisé avec succès wao.import.obsDebCodes.prompt=Import des codes ObsDeb wao.import.obsDebCodes.success=Import des codes ObsDeb réalisé avec succès +wao.import.sampleRow.failure.wrongSampleRowCodeFormat= wao.import.terrestrialDivisions.prompt=Import des unités d'observation wao.import.terrestrialDivisions.success=Import des unités d'observation réalisé avec succès wao.import.terrestrialLocations.prompt=Import des lieux terrestres @@ -151,6 +152,7 @@ wao.ui.field.FishingZone.facadeName=Façade wao.ui.field.FishingZone.sectorName=Zone wao.ui.field.SampleRow.appliedCoverageRate=Taux de couverture appliqué +wao.ui.field.SampleRow.averageTideTime= wao.ui.field.SampleRow.boat=Navire wao.ui.field.SampleRow.code=Code ligne wao.ui.field.SampleRow.comment=Commentaire @@ -158,10 +160,14 @@ wao.ui.field.SampleRow.dCF5Code=Codes wao.ui.field.SampleRow.day=Jour wao.ui.field.SampleRow.dcf5Code=Code DCF Niv. 5 +wao.ui.field.SampleRow.dcf5Codes= +wao.ui.field.SampleRow.elligibleBoat= wao.ui.field.SampleRow.expectedDate=Date wao.ui.field.SampleRow.fishingZones=Zone(s) de pêche +wao.ui.field.SampleRow.fishingZonesInfos= wao.ui.field.SampleRow.libelle=Libellé wao.ui.field.SampleRow.meshSize=Maillage +wao.ui.field.SampleRow.nbObservants= wao.ui.field.SampleRow.observationType=Type d'observation wao.ui.field.SampleRow.observationUnit=Unité d'observation wao.ui.field.SampleRow.observers=Observateurs @@ -197,10 +203,17 @@ wao.ui.filters.refresh=Rafraîchir les champs du filtre wao.ui.forgotPassword=Mot de passe oublié ? wao.ui.form.SampleRow.boatsDescription=Ce champs correspond aux immatriculations des navires qui sont éligibles pour cette ligne. Vous pouvez utiliser n'importe quel séparateur pour séparer les immatriculations (virgule, point, espace ou saut de ligne) +wao.ui.form.SampleRow.error.missingDcf5Codes= +wao.ui.form.SampleRow.error.missingFishingZones= wao.ui.form.SampleRow.error.missingLogComment=Vous devez préciser la raison de vos modifications +wao.ui.form.SampleRow.error.missingPeriodBegin= +wao.ui.form.SampleRow.error.missingPeriodEnd= +wao.ui.form.SampleRow.error.missingProfessionSpecies= +wao.ui.form.SampleRow.error.missingProgramName= wao.ui.form.SampleRow.missingBeginDate=Date de début manquante pour générer le code de la ligne \! wao.ui.form.SampleRow.others=Autres données de la ligne d'échantillonnage wao.ui.form.SampleRow.program=Programme de rattachement et effort d'observation par mois +wao.ui.form.SampleRow.warn.hasSampleMonthRealTideTime= wao.ui.form.WaoUser.credentials=Informations d'authentification wao.ui.form.WaoUser.identity=Identité wao.ui.form.WaoUser.preferences=Préférences @@ -230,6 +243,7 @@ wao.ui.form.repeatPassword=Répéter le mot de passe wao.ui.form.roles=Rôles wao.ui.form.sortByTideBegin=Trier par date de début d'observation (du plus récent au plus ancien) +wao.ui.form.updateSampleRowCommand.success= wao.ui.form.updateWaoUserCommand.admin=Administrateur wao.ui.form.updateWaoUserCommand.adminReadOnly=Administrateur (lecture seule) wao.ui.form.updateWaoUserCommand.canReadBoats=Limiter à la consultation des navires @@ -395,6 +409,8 @@ wao.ui.synthesis.observationHours.description=Nombre d'observations effectuée selon l'heure d'arrivée wao.ui.synthesis.observationHours.title=Distribution des périodes d'observation wao.ui.unavailableOperation=Opération non-disponible +wao.ui.unit.days= +wao.ui.unit.observers= wao.ui.userList=Liste des utilisateurs wao.ui.userMustAcceptCgu=Vous devez accepter les conditions d'utilisation pour utiliser Wao wao.ui.validLogin=Identifiant valide Copied: trunk/wao-web/src/main/webapp/WEB-INF/content/obsmer/edit-sample-row-input.jsp (from rev 1716, trunk/wao-web/src/main/webapp/WEB-INF/content/obsmer/edit-news-input.jsp) =================================================================== --- trunk/wao-web/src/main/webapp/WEB-INF/content/obsmer/edit-sample-row-input.jsp (rev 0) +++ trunk/wao-web/src/main/webapp/WEB-INF/content/obsmer/edit-sample-row-input.jsp 2014-03-11 13:44:08 UTC (rev 1717) @@ -0,0 +1,124 @@ +<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> +<%@taglib uri="/struts-tags" prefix="s" %> + +<html> + <head> + <title> + <s:if test="updateSampleRowCommand.creation"> + <s:text name="wao.ui.sampleRow.creation" /> + </s:if> + <s:else> + <s:property value="t('wao.ui.sampleRow.edition', updateSampleRowCommand.sampleRow.code)" /> + </s:else> + </title> + </head> + + + <h1> + <s:if test="updateSampleRowCommand.creation"> + <s:text name="wao.ui.sampleRow.creation" /> + </s:if> + <s:else> + <s:property value="t('wao.ui.sampleRow.edition', updateSampleRowCommand.sampleRow.code)" /> + </s:else> + </h1> + + <s:if test="updateSampleRowCommand.sampleRow.hasSampleMonthRealTideTime()"> + <div class="alert"> + <s:text name="wao.ui.form.SampleRow.warn.hasSampleMonthRealTideTime" /> + </div> + </s:if> + + <s:form> + + <s:hidden name="sampleRowId" value="%{sampleRowId}" /> + + <fieldset> + + <legend><s:text name="wao.ui.field.SampleRow.profession" /></legend> + + <s:textfield name="updateSampleRowCommand.sampleRow.profession.libelle" label="%{getText('wao.ui.field.SampleRow.libelle')}" /> + <s:textfield name="updateSampleRowCommand.sampleRow.profession.size" label="%{getText('wao.ui.field.SampleRow.size')}" inputAppend="m" cssClass="input-small" /> + <s:textfield name="updateSampleRowCommand.sampleRow.profession.meshSize" label="%{getText('wao.ui.field.SampleRow.meshSize')}" inputAppend="mm" cssClass="input-small" /> + <s:textfield name="updateSampleRowCommand.sampleRow.profession.species" label="%{getText('wao.ui.field.SampleRow.species')}" /> + <s:textfield name="updateSampleRowCommand.sampleRow.profession.other" label="%{getText('wao.ui.field.SampleRow.other')}" /> + <s:textfield name="updateSampleRowCommand.dcf5Codes" label="%{getText('wao.ui.field.SampleRow.dcf5Codes')}" cssClass="input-xxlarge" /> + + </fieldset> + + <fieldset> + + <legend><s:text name="wao.ui.field.SampleRow.fishingZones" /></legend> + + <s:select name="updateSampleRowCommand.fishingZoneIds" + label="%{getText('wao.ui.field.SampleRow.fishingZones')}" + list="updateSampleRowCommand.allFishingZones" + listValue="%{value.code}" + multiple="true" + cssClass="input-xxlarge" + /> + + <s:textfield name="updateSampleRowCommand.sampleRow.fishingZonesInfos" label="%{getText('wao.ui.field.SampleRow.fishingZonesInfos')}" cssClass="input-xxlarge" /> + + </fieldset> + + <fieldset> + + <legend><s:text name="wao.ui.form.SampleRow.program" /></legend> + + </fieldset> + + <fieldset> + + <legend><s:text name="wao.ui.form.SampleRow.others" /></legend> + + <s:if test="updateSampleRowCommand.creation"> + <s:textfield name="updateSampleRowCommand.code" label="%{getText('wao.ui.field.SampleRow.code')}" cssClass="input-small"/> + </s:if> + + <s:select name="updateSampleRowCommand.companyId" + label="%{getText('wao.ui.field.SampleRow.company')}" + list="updateSampleRowCommand.allCompanies" + listValue="%{value.name}" + cssClass="input-xxlarge" + /> + + <s:textfield type="number" name="updateSampleRowCommand.sampleRow.nbObservants" label="%{getText('wao.ui.field.SampleRow.nbObservants')}" inputAppend="%{getText('wao.ui.unit.observers')}" cssClass="input-small"/> + <s:textfield type="number" name="updateSampleRowCommand.sampleRow.averageTideTime" label="%{getText('wao.ui.field.SampleRow.averageTideTime')}" inputAppend="%{getText('wao.ui.unit.days')}" cssClass="input-small"/> + <s:textfield type="number" name="updateSampleRowCommand.sampleRow.appliedCoverageRate" label="%{getText('wao.ui.field.SampleRow.appliedCoverageRate')}" inputAppend="%" cssClass="input-small"/> + + <s:textarea name="updateSampleRowCommand.elligibleBoatImmatriculations" label="%{getText('wao.ui.field.SampleRow.elligibleBoat')}" /> + + <s:textarea name="updateSampleRowCommand.sampleRow.comment" label="%{getText('wao.ui.field.SampleRow.comment')}" /> + + </fieldset> + + <s:if test=" ! updateSampleRowCommand.creation"> + + <fieldset> + + <legend><s:text name="wao.ui.form.editComment" /></legend> + + <s:text name="wao.ui.form.editionAuthor" /> <s:property value="updateSampleRowCommand.sampleRowLog.author.fullName" /> + + <s:textarea name="updateSampleRowCommand.sampleRowLog.comment" label="%{getText('wao.ui.form.editComment')}" requiredLabel="true" /> + + </fieldset> + + </s:if> + + <div class="form-actions"> + <s:url namespace="/obsmer" action="sampling-plan" id="samplingPlanUrl" /> + <s:a href="%{samplingPlanUrl}" cssClass="btn"> + <i class="icon-chevron-left"></i> <s:text name="wao.ui.action.cancel" /> + </s:a> + + <s:submit type="button" cssClass="btn"> + <i class="icon-hdd"></i> <s:text name="wao.ui.action.save" /> + </s:submit> + </div> + + </s:form> + +</html> + Modified: trunk/wao-web/src/main/webapp/css/wao.css =================================================================== --- trunk/wao-web/src/main/webapp/css/wao.css 2014-03-06 16:50:28 UTC (rev 1716) +++ trunk/wao-web/src/main/webapp/css/wao.css 2014-03-11 13:44:08 UTC (rev 1717) @@ -33,7 +33,7 @@ textarea { width: 100%; - min-height: 300px; + min-height: 150px; } .form-actions button[type="submit"] {