Author: fdesbois Date: 2010-04-16 14:42:50 +0000 (Fri, 16 Apr 2010) New Revision: 450 Log: - Evo #2100 : calculate estimated tides for sampleMonth when contact is saved (new field in model -> need a migration) - Decompose importContactCsv method in three methods : loadContactCsv, updateElligibleBoatForContact, createOrUpdateContact (which calls the update for tides in sampleMonth) - Improve contact import using a bean ContactInput + ImportRefusedException - Add EntityProperty classes to easily manage properties in HQL (TopiaQuery) - Add tests for serviceContact using Mockito - Repair other tests broken by new update sampleMonth in contact save - NOTE : import/export are very heterogeneous, may be a refactor is needed to clean that Added: trunk/wao-business/src/main/java/fr/ifremer/wao/entity/ContactProperty.java trunk/wao-business/src/main/java/fr/ifremer/wao/entity/EntityProperty.java trunk/wao-business/src/main/java/fr/ifremer/wao/entity/FishingZoneProperty.java trunk/wao-business/src/main/java/fr/ifremer/wao/entity/SampleMonthProperty.java trunk/wao-business/src/main/java/fr/ifremer/wao/entity/SampleRowProperty.java trunk/wao-business/src/main/java/fr/ifremer/wao/io/ContactInput.java trunk/wao-business/src/main/java/fr/ifremer/wao/io/ImportRefusedException.java trunk/wao-business/src/test/java/fr/ifremer/wao/service/ServiceContactImplTest.java Modified: trunk/wao-business/pom.xml trunk/wao-business/src/main/java/fr/ifremer/wao/PostgresMigrationCallback.java trunk/wao-business/src/main/java/fr/ifremer/wao/WaoMigrationCallBack.java trunk/wao-business/src/main/java/fr/ifremer/wao/entity/SampleMonthImpl.java trunk/wao-business/src/main/java/fr/ifremer/wao/entity/SampleRowImpl.java trunk/wao-business/src/main/java/fr/ifremer/wao/io/ImportHelper.java trunk/wao-business/src/main/java/fr/ifremer/wao/io/WaoCsvHeader.java trunk/wao-business/src/main/java/fr/ifremer/wao/service/ServiceContactImpl.java trunk/wao-business/src/main/resources/i18n/wao-business-en_GB.properties trunk/wao-business/src/main/resources/i18n/wao-business-fr_FR.properties trunk/wao-business/src/main/resources/oldmappings/Wao/1.2/fr/ifremer/wao/entity/SampleMonthImpl.hbm.xml trunk/wao-business/src/main/xmi/wao.zargo trunk/wao-business/src/test/java/fr/ifremer/wao/TestManager.java trunk/wao-business/src/test/java/fr/ifremer/wao/entity/BoatImplTest.java trunk/wao-business/src/test/java/fr/ifremer/wao/io/ImportHelperTest.java trunk/wao-business/src/test/java/fr/ifremer/wao/service/ServiceSynthesisImplTest.java trunk/wao-business/src/test/resources/import/ trunk/wao-business/src/test/resources/log4j.properties trunk/wao-ui/src/main/java/fr/ifremer/wao/ui/services/AppModule.java Modified: trunk/wao-business/pom.xml =================================================================== --- trunk/wao-business/pom.xml 2010-04-15 10:24:24 UTC (rev 449) +++ trunk/wao-business/pom.xml 2010-04-16 14:42:50 UTC (rev 450) @@ -76,6 +76,10 @@ <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + </dependency> </dependencies> <!-- ************************************************************* --> Modified: trunk/wao-business/src/main/java/fr/ifremer/wao/PostgresMigrationCallback.java =================================================================== --- trunk/wao-business/src/main/java/fr/ifremer/wao/PostgresMigrationCallback.java 2010-04-15 10:24:24 UTC (rev 449) +++ trunk/wao-business/src/main/java/fr/ifremer/wao/PostgresMigrationCallback.java 2010-04-16 14:42:50 UTC (rev 450) @@ -72,7 +72,7 @@ } @Override - protected void createBoatInfosNewColumns_1_2(List<String> queries) { + protected void createBoatInfosNewColumns_1_2a(List<String> queries) { // Evo #2060 : add new columns in BoatInfos (contactSiret, // contactAddress1, contactAddress2, contactCity, contactPostalCode) queries.add("ALTER TABLE BoatInfos ADD contactAddress1 TEXT;"); @@ -82,4 +82,11 @@ queries.add("ALTER TABLE BoatInfos ADD contactSiret TEXT;"); } + @Override + protected void createSampleMonthEstimatedTidesColumn_1_2b(List<String> queries) { + queries.add("ALTER TABLE SampleMonth ADD estimatedTidesValue INTEGER;"); + // TODO : calculate estimatedTidesValue for all existing contacts + // estimatedTidesValue = nbContacts with state BOARDING_DONE + } + } Modified: trunk/wao-business/src/main/java/fr/ifremer/wao/WaoMigrationCallBack.java =================================================================== --- trunk/wao-business/src/main/java/fr/ifremer/wao/WaoMigrationCallBack.java 2010-04-15 10:24:24 UTC (rev 449) +++ trunk/wao-business/src/main/java/fr/ifremer/wao/WaoMigrationCallBack.java 2010-04-16 14:42:50 UTC (rev 450) @@ -56,9 +56,12 @@ protected abstract void changeSampleRowLogAdminColumn_1_1c( List<String> queries); - protected abstract void createBoatInfosNewColumns_1_2( + protected abstract void createBoatInfosNewColumns_1_2a( List<String> queries); + protected abstract void createSampleMonthEstimatedTidesColumn_1_2b( + List<String> queries); + @Override public boolean askUser(Version dbVersion, Version applicationVersion, @@ -103,8 +106,10 @@ List<String> queries = new ArrayList<String>(); - createBoatInfosNewColumns_1_2(queries); + createBoatInfosNewColumns_1_2a(queries); + createSampleMonthEstimatedTidesColumn_1_2b(queries); + String[] strings = queries.toArray(new String[queries.size()]); executeSQL(tx, showSql, showProgression, strings); } Added: trunk/wao-business/src/main/java/fr/ifremer/wao/entity/ContactProperty.java =================================================================== --- trunk/wao-business/src/main/java/fr/ifremer/wao/entity/ContactProperty.java (rev 0) +++ trunk/wao-business/src/main/java/fr/ifremer/wao/entity/ContactProperty.java 2010-04-16 14:42:50 UTC (rev 450) @@ -0,0 +1,56 @@ +/* + * #%L + * Wao :: Business + * + * $Author$ + * $LastChangedDate$ + * $LastChangedRevision$ + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2010 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +package fr.ifremer.wao.entity; + +/** + * ContactProperty + * + * Created: 14 avr. 2010 + * + * @author fdesbois <fdesbois at codelutin.com> + */ +public class ContactProperty extends EntityProperty { + + public ContactProperty(String mainAlias) { + super(); + setMainAlias(mainAlias); + } + + public String nameSampleRow() { + return nameProperty(Contact.SAMPLE_ROW); + } + + public String nameState() { + return nameProperty(Contact.STATE); + } + + public String nameTideBeginDate() { + return nameProperty(Contact.TIDE_BEGIN_DATE); + } +} Property changes on: trunk/wao-business/src/main/java/fr/ifremer/wao/entity/ContactProperty.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL" Added: trunk/wao-business/src/main/java/fr/ifremer/wao/entity/EntityProperty.java =================================================================== --- trunk/wao-business/src/main/java/fr/ifremer/wao/entity/EntityProperty.java (rev 0) +++ trunk/wao-business/src/main/java/fr/ifremer/wao/entity/EntityProperty.java 2010-04-16 14:42:50 UTC (rev 450) @@ -0,0 +1,67 @@ +/* + * #%L + * Wao :: Business + * + * $Author$ + * $LastChangedDate$ + * $LastChangedRevision$ + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2010 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +package fr.ifremer.wao.entity; + +import org.nuiton.topia.framework.TopiaQuery; + +/** + * EntityProperty + * + * Created: 14 avr. 2010 + * + * @author fdesbois <fdesbois at codelutin.com> + */ +public abstract class EntityProperty { + + protected String mainAlias; + + public EntityProperty() { + } + + public void setMainAlias(String mainAlias) { + this.mainAlias = mainAlias; + } + + public String getMainAlias() { + return mainAlias; + } + + public String name() { + return getMainAlias(); + } + + protected String nameProperty(String propertyName) { + return TopiaQuery.getProperty(mainAlias, propertyName); + } + + @Override + public String toString() { + return name(); + } +} Property changes on: trunk/wao-business/src/main/java/fr/ifremer/wao/entity/EntityProperty.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL" Added: trunk/wao-business/src/main/java/fr/ifremer/wao/entity/FishingZoneProperty.java =================================================================== --- trunk/wao-business/src/main/java/fr/ifremer/wao/entity/FishingZoneProperty.java (rev 0) +++ trunk/wao-business/src/main/java/fr/ifremer/wao/entity/FishingZoneProperty.java 2010-04-16 14:42:50 UTC (rev 450) @@ -0,0 +1,64 @@ +/* + * #%L + * Wao :: Business + * + * $Author$ + * $LastChangedDate$ + * $LastChangedRevision$ + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2010 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +package fr.ifremer.wao.entity; + +/** + * FishingZoneProperty + * + * Created: 14 avr. 2010 + * + * @author fdesbois + * @version $Revision$ + * + * Mise a jour: $Date$ + * par : $Author$ + */ +public class FishingZoneProperty extends EntityProperty { + + public FishingZoneProperty(String mainAlias) { + super(); + setMainAlias(mainAlias); + } + + public String nameFacadeName() { + return nameProperty(FishingZone.FACADE_NAME); + } + + public String nameSectorName() { + return nameProperty(FishingZone.SECTOR_NAME); + } + + public String nameDistrictCode() { + return nameProperty(FishingZone.DISTRICT_CODE); + } + + public String nameSampleRow() { + return nameProperty(FishingZone.SAMPLE_ROW); + } +} Property changes on: trunk/wao-business/src/main/java/fr/ifremer/wao/entity/FishingZoneProperty.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL" Modified: trunk/wao-business/src/main/java/fr/ifremer/wao/entity/SampleMonthImpl.java =================================================================== --- trunk/wao-business/src/main/java/fr/ifremer/wao/entity/SampleMonthImpl.java 2010-04-15 10:24:24 UTC (rev 449) +++ trunk/wao-business/src/main/java/fr/ifremer/wao/entity/SampleMonthImpl.java 2010-04-16 14:42:50 UTC (rev 450) @@ -61,8 +61,11 @@ * the real tides value will be set to 0. * @param nbDays to add or remove (if negative) * @throws WaoException for saving problem + * @deprecated the realTideTime will be automatically update on contact + * change */ @Override + @Deprecated public void addRealTideTime(int nbDays) throws WaoException { TopiaContext transaction = null; try { Added: trunk/wao-business/src/main/java/fr/ifremer/wao/entity/SampleMonthProperty.java =================================================================== --- trunk/wao-business/src/main/java/fr/ifremer/wao/entity/SampleMonthProperty.java (rev 0) +++ trunk/wao-business/src/main/java/fr/ifremer/wao/entity/SampleMonthProperty.java 2010-04-16 14:42:50 UTC (rev 450) @@ -0,0 +1,52 @@ +/* + * #%L + * Wao :: Business + * + * $Author$ + * $LastChangedDate$ + * $LastChangedRevision$ + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2010 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +package fr.ifremer.wao.entity; + +/** + * SampleMonthProperty + * + * Created: 14 avr. 2010 + * + * @author fdesbois <fdesbois at codelutin.com> + */ +public class SampleMonthProperty extends EntityProperty{ + + public SampleMonthProperty(String mainAlias) { + super(); + setMainAlias(mainAlias); + } + + public String nameSampleRow() { + return nameProperty(SampleMonth.SAMPLE_ROW); + } + + public String namePeriodDate() { + return nameProperty(SampleMonth.PERIOD_DATE); + } +} Property changes on: trunk/wao-business/src/main/java/fr/ifremer/wao/entity/SampleMonthProperty.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL" Modified: trunk/wao-business/src/main/java/fr/ifremer/wao/entity/SampleRowImpl.java =================================================================== --- trunk/wao-business/src/main/java/fr/ifremer/wao/entity/SampleRowImpl.java 2010-04-15 10:24:24 UTC (rev 449) +++ trunk/wao-business/src/main/java/fr/ifremer/wao/entity/SampleRowImpl.java 2010-04-16 14:42:50 UTC (rev 450) @@ -288,6 +288,7 @@ } @Override + @Deprecated public boolean addRealTideTime(Contact contact) throws WaoException { if (contact.getTideEndDate() == null || contact.getTideBeginDate() == null) { @@ -307,6 +308,7 @@ } @Override + @Deprecated public void removeRealTideTime(Contact contact) throws WaoException { if (contact.getTideEndDate() == null || contact.getTideBeginDate() == null) { Added: trunk/wao-business/src/main/java/fr/ifremer/wao/entity/SampleRowProperty.java =================================================================== --- trunk/wao-business/src/main/java/fr/ifremer/wao/entity/SampleRowProperty.java (rev 0) +++ trunk/wao-business/src/main/java/fr/ifremer/wao/entity/SampleRowProperty.java 2010-04-16 14:42:50 UTC (rev 450) @@ -0,0 +1,53 @@ +/* + * #%L + * Wao :: Business + * + * $Author$ + * $LastChangedDate$ + * $LastChangedRevision$ + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2010 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +package fr.ifremer.wao.entity; + +/** + * SampleRowProperty + * + * Created: 14 avr. 2010 + * + * @author fdesbois <fdesbois at codelutin.com> + */ +public class SampleRowProperty extends EntityProperty { + + public SampleRowProperty(String mainAlias) { + super(); + setMainAlias(mainAlias); + } + + public String nameCode() { + return nameProperty(SampleRow.CODE); + } + + public String nameCompany() { + return nameProperty(SampleRow.COMPANY); + } + +} Property changes on: trunk/wao-business/src/main/java/fr/ifremer/wao/entity/SampleRowProperty.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL" Added: trunk/wao-business/src/main/java/fr/ifremer/wao/io/ContactInput.java =================================================================== --- trunk/wao-business/src/main/java/fr/ifremer/wao/io/ContactInput.java (rev 0) +++ trunk/wao-business/src/main/java/fr/ifremer/wao/io/ContactInput.java 2010-04-16 14:42:50 UTC (rev 450) @@ -0,0 +1,190 @@ + +package fr.ifremer.wao.io; + +import fr.ifremer.wao.bean.*; +import fr.ifremer.wao.WaoDAOHelper; +import fr.ifremer.wao.entity.Boat; +import fr.ifremer.wao.entity.BoatDAO; +import fr.ifremer.wao.entity.Company; +import fr.ifremer.wao.entity.ContactImpl; +import fr.ifremer.wao.entity.SampleRow; +import fr.ifremer.wao.entity.SampleRowDAO; +import fr.ifremer.wao.entity.WaoUser; +import fr.ifremer.wao.entity.WaoUserDAO; +import org.nuiton.topia.TopiaContext; +import org.nuiton.topia.TopiaException; + +/** + * ContactInput is an extension of ContactImpl. This class add behavior on + * properties setter which takes String instead of Entity (SampleRow, Boat, + * Observer). There is also exceptions thrown if data can't be found. + * The ContactInput need to be initialized with a TopiaContext. + * ContactInput is used in contacts import. + * + * Created: 15 avr. 2010 + * + * @author fdesbois + */ +public class ContactInput extends ContactImpl { + + private static final long serialVersionUID = 1L; + + protected TopiaContext transaction; + + protected int rowNumber; + + protected WaoUser creator; + + protected Company company; + + /** + * Initialization of the ContactInput. Need a {@code transaction} to + * retrieve data entity from there key string. Need the creator to check + * the company reference to the observer (only an admin can import a contact + * for any companies). Need also the {@code rowNumber} in the import file to + * use it in {@link ImportRefusedException} thrown by methods. + * + * @param transaction to use for loading entity data + * @param creator of the contact + * @param rowNumber in the input file + */ + public void initialize(TopiaContext transaction, WaoUser creator, + int rowNumber) { + this.transaction = transaction; + this.rowNumber = rowNumber; + this.creator = creator; + } + + /** + * Creator of the contact. + * + * @return the WaoUser creator of the contact. + */ + public WaoUser getCreator() { + return creator; + } + + /** + * Set the contact {@code state} of the Contact. This will check if the + * {@code state} is corresponding to an existing {@link ContactState}. + * + * @param state to set + * @throws ImportRefusedException if state is not allowed + */ + public void setContactState(String state) throws ImportRefusedException { + ContactState contactState = ContactState.valueOfLibelle(state); + if (contactState == null) { + throw new ImportRefusedException( + "Etat du contact invalide '" + state + "', " + + "valeurs possibles : " + + ContactState.availableStates(), rowNumber, STATE); + } + setContactState(contactState); + } + + /** + * Set the observer from his {@code observerLogin}. + * + * @param observerLogin to find the observer + * @throws TopiaException + * @throws ImportRefusedException if user doesn't exist + */ + public void setObserver(String observerLogin) + throws TopiaException, ImportRefusedException { + // Find existing user with login + WaoUserDAO userDAO = WaoDAOHelper.getWaoUserDAO(transaction); + WaoUser user = userDAO.findByLogin(observerLogin); + if (user == null) { + throw new ImportRefusedException("Utilisateur inexistant avec " + + "l'identifiant : " + observerLogin, rowNumber, OBSERVER); + } + setObserver(user); + } + + /** + * Initialize the company for the Contact. Used to check with sampleRow + * company. This method check if the observer company is the same as + * the creator company in the case of a non admin creator. The observer + * need to be set before calling this method. + * + * @throws ImportRefusedException if observer company differs from creator + * one + */ + public void initCompany() throws ImportRefusedException { + // Keep observer company for an admin creator + if (creator.isAdmin()) { + company = observer.getCompany(); + // For a non admin creator, use his own company + } else { + company = creator.getCompany(); + + // Check if the observer company is the same as the creator one + if (!observer.getCompany().equals(company)) { + throw new ImportRefusedException( + "L'observateur avec pour login '" + + observer.getLogin() + + "' n'appartient pas à votre société !", rowNumber, + WaoUser.COMPANY); + } + } + } + + /** + * Company of the contact. + * + * @return the Company of the contact. + */ + public Company getCompany() { + return company; + } + + /** + * Set the sampleRow from its {@code sampleRowCode}. The company must be + * initalize before using this method because the sampleRow will be found + * using the company and sampleRowCode constraints to be sure to set a + * sampleRow allowed for the contact. + * + * @param sampleRowCode to find the sampleRow + * @throws TopiaException + * @throws ImportRefusedException if the sampleRow not exists or not allowed + * for the company + */ + public void setSampleRow(String sampleRowCode) + throws TopiaException, ImportRefusedException { + if (company == null) { + throw new NullPointerException("Company can't be null to save" + + " the contact with SampleRow [code = " + + sampleRowCode + "]"); + } + SampleRowDAO dao = WaoDAOHelper.getSampleRowDAO(transaction); + SampleRow rowFound = dao.findByProperties( + SampleRow.CODE, sampleRowCode, + SampleRow.COMPANY, company); + if(rowFound == null) { + throw new ImportRefusedException("Ligne d'échantillon inexistante" + + " ou incompatible avec la société pour le code : " + + sampleRowCode, rowNumber, SAMPLE_ROW); + } + setSampleRow(rowFound); + } + + /** + * Set the boat from its {@code boatImmatriculation}. + * + * @param boatImmatriculation to find the boat + * @throws TopiaException + * @throws ImportRefusedException if boat no exists + */ + public void setBoat(int boatImmatriculation) + throws TopiaException, ImportRefusedException { + BoatDAO dao = WaoDAOHelper.getBoatDAO(transaction); + Boat boatFound = dao.findByImmatriculation(boatImmatriculation); + if(boatFound == null) { + throw new ImportRefusedException("Navire inexistant avec" + + " l'immatriculation : " + boatImmatriculation, + rowNumber, BOAT); + } + setBoat(boatFound); + } + +} Property changes on: trunk/wao-business/src/main/java/fr/ifremer/wao/io/ContactInput.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL" Modified: trunk/wao-business/src/main/java/fr/ifremer/wao/io/ImportHelper.java =================================================================== --- trunk/wao-business/src/main/java/fr/ifremer/wao/io/ImportHelper.java 2010-04-15 10:24:24 UTC (rev 449) +++ trunk/wao-business/src/main/java/fr/ifremer/wao/io/ImportHelper.java 2010-04-16 14:42:50 UTC (rev 450) @@ -95,12 +95,11 @@ return "X".equals(mammals); } - public static Date parseContactCreateDate(String code, String createDate) throws ParseException { + public static Date parseContactCreateDate(String code, Date createDate) throws ParseException { Calendar time = new GregorianCalendar(Locale.FRENCH); if (StringUtils.isNotEmpty(code)) { - DateFormat timeFormat = CONTACT.getTimeFormat(); time = new GregorianCalendar(Locale.FRENCH); - time.setTime(timeFormat.parse(code)); + time.setTime(CONTACT.TIME_FORMAT.parse(code)); } else { // Use current date with no time as a reference if no code is set time.setTime(context.getCurrentDate()); @@ -111,9 +110,8 @@ } Calendar result = new GregorianCalendar(Locale.FRENCH); - if (StringUtils.isNotEmpty(createDate)) { - DateFormat dateFormat = CONTACT.getDateFormat(); - result.setTime(dateFormat.parse(createDate)); + if (createDate != null) { + result.setTime(createDate); result.set(Calendar.HOUR_OF_DAY, time.get(Calendar.HOUR_OF_DAY)); result.set(Calendar.MINUTE, time.get(Calendar.MINUTE)); result.set(Calendar.SECOND, time.get(Calendar.SECOND)); @@ -210,6 +208,7 @@ * @throws IOException * @throws ParseException * @see ImportHelper#read(CsvReader, IOHeader) + * @see ImportHelper#parseDate(String, String) */ public static Date readDate(CsvReader reader, DatedHeader header) throws IOException, ParseException { Added: trunk/wao-business/src/main/java/fr/ifremer/wao/io/ImportRefusedException.java =================================================================== --- trunk/wao-business/src/main/java/fr/ifremer/wao/io/ImportRefusedException.java (rev 0) +++ trunk/wao-business/src/main/java/fr/ifremer/wao/io/ImportRefusedException.java 2010-04-16 14:42:50 UTC (rev 450) @@ -0,0 +1,42 @@ + +package fr.ifremer.wao.io; + +/** + * ImportRefusedException is used to advise import service that an error occurs + * during loading data. Generally this exception is catched and messages will + * be encapsulated in {@link fr.ifremer.wao.bean.ImportResults}. + * + * Created: 15 avr. 2010 + * + * @author fdesbois + */ +public class ImportRefusedException extends Exception { + + private static final long serialVersionUID = 1L; + + /** Number of the row in import file **/ + protected int rowNumber; + + /** Name of the field in import file **/ + protected String field; + + public ImportRefusedException(String message, int rowNumber, String field, + Throwable eee) { + super(message, eee); + this.rowNumber = rowNumber; + this.field = field; + } + + public ImportRefusedException(String message, int rowNumber, String field) { + this(message, rowNumber, field, null); + } + + public int getRowNumber() { + return rowNumber; + } + + public String getField() { + return field; + } + +} Property changes on: trunk/wao-business/src/main/java/fr/ifremer/wao/io/ImportRefusedException.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL" Modified: trunk/wao-business/src/main/java/fr/ifremer/wao/io/WaoCsvHeader.java =================================================================== --- trunk/wao-business/src/main/java/fr/ifremer/wao/io/WaoCsvHeader.java 2010-04-15 10:24:24 UTC (rev 449) +++ trunk/wao-business/src/main/java/fr/ifremer/wao/io/WaoCsvHeader.java 2010-04-16 14:42:50 UTC (rev 450) @@ -338,6 +338,12 @@ private int contactHeader; + public static final DateFormat DATE_FORMAT = + new SimpleDateFormat(defaultDatePattern(), Locale.FRENCH); + + public static final DateFormat TIME_FORMAT = + new SimpleDateFormat("HHmmssS", Locale.FRENCH); + CONTACT(int index) { this.contactHeader = index; } @@ -356,14 +362,6 @@ return "dd/MM/yyyy"; } - public static DateFormat getDateFormat() { - return new SimpleDateFormat(defaultDatePattern(), Locale.FRENCH); - } - - public static DateFormat getTimeFormat() { - return new SimpleDateFormat("HHmmssS", Locale.FRENCH); - } - public static int getTotalHeaders() { // CONT_PROGRAM_VALID is the last column return CONT_PROGRAM_VALID.forContactCsv() + 1; Modified: trunk/wao-business/src/main/java/fr/ifremer/wao/service/ServiceContactImpl.java =================================================================== --- trunk/wao-business/src/main/java/fr/ifremer/wao/service/ServiceContactImpl.java 2010-04-15 10:24:24 UTC (rev 449) +++ trunk/wao-business/src/main/java/fr/ifremer/wao/service/ServiceContactImpl.java 2010-04-16 14:42:50 UTC (rev 450) @@ -42,7 +42,6 @@ import com.csvreader.CsvReader; import com.csvreader.CsvWriter; import org.apache.commons.lang.BooleanUtils; -import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.nuiton.topia.TopiaContext; @@ -50,7 +49,6 @@ import org.nuiton.topia.persistence.TopiaEntity; import org.nuiton.topia.framework.TopiaQuery; import fr.ifremer.wao.*; -import fr.ifremer.wao.WaoBusinessException.Type; import fr.ifremer.wao.bean.ContactFilter; import fr.ifremer.wao.bean.ContactState; import fr.ifremer.wao.bean.ImportResults; @@ -58,6 +56,9 @@ import fr.ifremer.wao.entity.*; import fr.ifremer.wao.io.*; import fr.ifremer.wao.io.WaoCsvHeader.*; +import org.nuiton.util.PeriodDates; +import org.nuiton.util.beans.BinderBuilder; +import org.nuiton.util.beans.BinderProvider; /** * ServiceContactImpl @@ -73,6 +74,38 @@ private WaoContext context; + + public ServiceContactImpl() { + prepareBinderForContact(); + } + + /** + * Prepare the Binder for Contact copy. This method is called in + * service constructor. The copy from two Contact will be available + * anywhere using BinderProvider.get(Contact.class).copy(source, dest); + * + * @see org.nuiton.util.beans.Binder + * @see org.nuiton.util.beans.BinderProvider + */ + protected void prepareBinderForContact() { + BinderBuilder builder = new BinderBuilder(); + // Properties SAMPLE_ROW, BOAT, TOPIA_CREATE_DATE are immuable + builder.createBinderModel(Contact.class).addSimpleProperties( + Contact.COMMENT, + Contact.DATA_INPUT_DATE, + Contact.MAMMALS_CAPTURE, + Contact.MAMMALS_OBSERVATION, + Contact.NB_OBSERVANTS, + Contact.OBSERVER, + Contact.STATE, + Contact.TIDE_BEGIN_DATE, + Contact.TIDE_END_DATE, + Contact.TIDE_NB_DAYS, + Contact.VALIDATION_COMPANY, + Contact.VALIDATION_PROGRAM); + BinderProvider.registerBinder(builder); + } + public void setContext(WaoContext context) { this.context = context; } @@ -137,7 +170,8 @@ @Override public void executeSaveContact(TopiaContext transaction, - Contact contact, boolean delete) throws TopiaException { + Contact contact, boolean delete) + throws TopiaException, NullSampleMonthException { ContactDAO dao = WaoDAOHelper.getContactDAO(transaction); @@ -145,16 +179,57 @@ log.debug("Create date : " + contact.getTopiaCreateDate()); } - context.prepareTopiaId(Contact.class, contact); + Contact contactFound = dao.findByTopiaId(contact.getTopiaId()); + + //context.prepareTopiaId(Contact.class, contact); if (delete) { - dao.delete(contact); + dao.delete(contactFound); } else { - dao.update(contact); + createOrUpdateContact(dao, contact, contactFound, true); } - transaction.commitTransaction(); } + /** + * Create or Update a Contact from {@code source} to {@code destination}. + * The sampleMonth referenced to this contact will be automatically updated + * for realTidesValue and estimatedTidesValue (corresponding to number of + * contacts which are corrects). The {@code calculateReal} identify that + * real tides has to be calculated or not during sampleMonth update. + * + * @param dao to use for create or update + * @param source which contains data to save + * @param destination receiver to save (will be null for a creation) + * @param calculateReal for sampleMonth update + * @throws TopiaException + * @throws NullSampleMonthException + * @see #updateSampleMonthTidesValue(TopiaContext, Contact, Contact, boolean) + */ + protected void createOrUpdateContact(ContactDAO dao, Contact source, + Contact destination, boolean calculateReal) + throws TopiaException, NullSampleMonthException { + + updateSampleMonthTidesValue(dao.getContext(), destination, + source, calculateReal); + + // Create the contact if not defined + if (destination == null) { + destination = dao.create( + Contact.BOAT, source.getBoat(), + Contact.SAMPLE_ROW, source.getSampleRow(), + // FIXME-FD20100415 : don't use the topiaCreateDate as a business field + TopiaEntity.TOPIA_CREATE_DATE, + source.getTopiaCreateDate()); + // Set the new topiaId in source contact + source.setTopiaId(destination.getTopiaId()); + } + // Bind the contact in argument with the contact in session + BinderProvider.getBinder(Contact.class). + copy(source, destination); + // Update the change + dao.update(destination); + } + @Override public InputStream executeExportContactCsv(TopiaContext transaction, ContactFilter filter) throws Exception { @@ -194,7 +269,7 @@ export.writeHeaders(); - DateFormat dateFormat = CONTACT.getDateFormat(); + DateFormat dateFormat = CONTACT.DATE_FORMAT; // Get contacts from database ContactDAO dao = WaoDAOHelper.getContactDAO(transaction); @@ -210,7 +285,7 @@ List<Contact> contacts = dao.findAllByQuery(query); - DateFormat timeFormat = CONTACT.getTimeFormat(); + DateFormat timeFormat = CONTACT.TIME_FORMAT; for (Contact contact : contacts) { export.newRecord(); @@ -318,236 +393,388 @@ int currRow = 1; CsvReader reader = new CsvReader(input, context.getCsvCharset()); - reader.readHeaders(); + try { + reader.readHeaders(); - ContactDAO dao = WaoDAOHelper.getContactDAO(transaction); - WaoUserDAO userDAO = WaoDAOHelper.getWaoUserDAO(transaction); - SampleRowDAO rowDAO = WaoDAOHelper.getSampleRowDAO(transaction); - BoatDAO boatDAO = WaoDAOHelper.getBoatDAO(transaction); + ContactDAO dao = WaoDAOHelper.getContactDAO(transaction); - long tic; - tic = System.currentTimeMillis(); - while(reader.readRecord()) { - currRow++; + long tic; + tic = System.currentTimeMillis(); + DateFormat dateFormat = new SimpleDateFormat("MM/yyyy"); + while(reader.readRecord()) { + try { + currRow++; - String observerId = ImportHelper.read(reader, CONTACT.OBSERV_ID); - String state = ImportHelper.read(reader, CONTACT.CONT_ETAT); + boolean updateValidation = user.isAdmin() && + user.getLogin().equals("admin"); - ContactState contactState = ContactState.valueOfLibelle(state); + // Load ContactInput using CsvReader + ContactInput contactCsv = new ContactInput(); + contactCsv.initialize(transaction, user, currRow); + loadContactCsv(reader, contactCsv, updateValidation); - if (contactState == null) { - throw new WaoBusinessException(Type.IMPORT_ERROR, - this.getClass(), - "Erreur ligne " + currRow + " : " + - "Etat du contact invalide '" + state + "', " + - "valeurs possibles : " + - ContactState.availableStates()); - } + if (log.isDebugEnabled()) { + log.debug("Ligne " + currRow + " : " + + "Create date : " + + contactCsv.getTopiaCreateDate()); + } - WaoUser observer = userDAO.findByLogin(observerId); - if (observer != null) { - Company company = user.getCompany(); - // For an admin, get the company from database - if (user.isAdmin()) { - company = observer.getCompany(); - // For a user, check if the observer as the same company as the current user - } else if (!observer.getCompany().equals(company)) { - throw new WaoBusinessException(Type.IMPORT_ERROR, - this.getClass(), - "Erreur ligne " + currRow + " : " + - "L'observateur avec pour login '" + observerId + - "' n'appartient pas à votre société !"); + // Retrieve the existing contact + String companyProperty = + TopiaQuery.getProperty(Contact.OBSERVER, + WaoUser.COMPANY); + + Contact contact = dao.findByProperties( + TopiaEntity.TOPIA_CREATE_DATE, + contactCsv.getTopiaCreateDate(), + companyProperty, contactCsv.getCompany(), + Contact.BOAT, contactCsv.getBoat(), + Contact.SAMPLE_ROW, contactCsv.getSampleRow()); + + // Check validation for existing Contact + if (!updateValidation && contact != null && + contact.getValidationCompany() != null) { + throw new ImportRefusedException("Le contact est" + + " déjà validé dans l'application" + + " et ne peut pas être importé", currRow, + Contact.VALIDATION_COMPANY); + } + + // Create elligibleBoat if needed before saving the contact + updateElligibleBoatForContact(transaction, contact); + + try { + // Execute createOrUpdateContact + // Will calculate data for SampleMonth and maybe + // throw a NullSampleMonthException if there is + // an error during the calcul of sampleMonthTidesValue + createOrUpdateContact(dao, contact, contact, + updateValidation); + } catch (NullSampleMonthException eee) { + // The row will be refused in this case + throw new ImportRefusedException("Impossible de " + + "mettre à jour le nombre de marée réels, " + + "vérifiez le mois de " + + dateFormat.format(contact.getTideBeginDate()) + + " pour la ligne du plan " + + contactCsv.getSampleRow().getCode(), currRow, + Contact.TIDE_BEGIN_DATE, eee); + } + + result.incNbImported(); + + if (result.getNbRowsImported() % 1000 == 0) { + transaction.commitTransaction(); + tic = ImportHelper.logTimeAndMemory(log, tic, + "contacts ligne " + currRow); + } + + } catch(ImportRefusedException eee) { + if (log.isWarnEnabled()) { + log.warn("Error during contact import row : " + + eee.getRowNumber(), eee); + } + result.addError(eee.getRowNumber(), eee.getMessage()); + result.incNbRefused(); } + } - if (company != null) { - String rowCode = ImportHelper.readSampleRowCode(reader); + // Commit for last rows imported + transaction.commitTransaction(); + } finally { + reader.close(); + } + return result; + } - SampleRow row = rowDAO.findByProperties( - SampleRow.CODE, rowCode, - SampleRow.COMPANY, company); + /** + * Will load a {@code contact} from reading data in {@code reader}. + * The order is important for loading the contact (state, observer, company, + * sampleRow, boat and others). + * + * @param reader which contains data from Csv file + * @param contact to load + * @param updateValidation if validations need to be loaded + * @throws IOException from CsvReader + * @throws TopiaException if an error occurs during ToPIA usage + * @throws ImportRefusedException when data is not correct to load contact + * @throws ParseException from ImportHelper + * @see ImportHelper + */ + protected void loadContactCsv(CsvReader reader, ContactInput contact, + boolean updateValidation) throws IOException, + TopiaException, + ImportRefusedException, + ParseException { - if (row != null) { - int boatImmatriculation = - ImportHelper.readInt(reader, BOAT.NAVS_COD); + contact.setContactState(ImportHelper.read(reader, CONTACT.CONT_ETAT)); - Boat boat = boatDAO.findByImmatriculation( - boatImmatriculation); + contact.setObserver(ImportHelper.read(reader, CONTACT.OBSERV_ID)); - if (boat != null) { + contact.initCompany(); - ElligibleBoatDAO elligibleDAO = - WaoDAOHelper.getElligibleBoatDAO(transaction); - ElligibleBoat elligible = - elligibleDAO.findByProperties( - ElligibleBoat.BOAT, boat, - ElligibleBoat.SAMPLE_ROW, row); + contact.setSampleRow(ImportHelper.readSampleRowCode(reader)); - if (elligible == null) { - // Create new elligible boat not active in a global way - elligible = elligibleDAO.create( - ElligibleBoat.BOAT, boat, - ElligibleBoat.SAMPLE_ROW, row); - if (log.isTraceEnabled()) { - log.trace("Create elligibleBoat for : " + - boat.getImmatriculation() + " - " + - row.getCode()); - } - } - elligible.setCompanyActive(Boolean.TRUE); + contact.setBoat(ImportHelper.readInt(reader, BOAT.NAVS_COD)); - Contact contact = null; + contact.setTideBeginDate( + ImportHelper.readDate(reader, CONTACT.CONT_DEBUT_MAREE)); + contact.setTideEndDate( + ImportHelper.readDate(reader, CONTACT.CONT_FIN_MAREE)); - String createDateString = - ImportHelper.read(reader, - CONTACT.CONT_CREATION); - String contactCode = - ImportHelper.read(reader, - CONTACT.CONT_CODE); - Date createDate = - ImportHelper.parseContactCreateDate( - contactCode, createDateString); + int nbObservants = + ImportHelper.readInt(reader, CONTACT.CONT_NB_OBSERV); + contact.setNbObservants( + nbObservants == -1 ? 0 : nbObservants); - if (log.isDebugEnabled()) { - log.debug("Ligne " + currRow + - " : Create date : " + createDate); - } + contact.setMammalsCapture( + ImportHelper.parseContactMammals(reader,CONTACT.CONT_MAM_CAPT)); - if (/*!StringUtils.isEmpty(contactCode) && */ - StringUtils.isNotEmpty(createDateString)) { - // Get entity from database - TopiaQuery query = dao.createQuery(). - add(TopiaEntity.TOPIA_CREATE_DATE, - createDate). - add(Contact.OBSERVER + "." + - WaoUser.COMPANY, company). - add(Contact.BOAT, boat). - add(Contact.SAMPLE_ROW, row); - contact = dao.findByQuery(query); - } + contact.setMammalsObservation( + ImportHelper.parseContactMammals(reader, CONTACT.CONT_MAM_OBS)); - if (contact != null && - contact.getValidationCompany() != null) { - result.addError(currRow, "Le contact est" + - " déjà validé dans l'application" + - " et ne peut pas être importé"); - result.incNbRefused(); - continue; - } + contact.setDataInputDate( + ImportHelper.readDate(reader, CONTACT.CONT_ALLEGRO)); - // new contact to import - boolean newContact = false; - if (contact == null) { - contact = dao.create( - TopiaEntity.TOPIA_CREATE_DATE, createDate, - Contact.SAMPLE_ROW, row, - Contact.BOAT, boat); - newContact = true; - } + if (updateValidation) { + if (log.isDebugEnabled()) { + log.debug("SuperAdmin import :: validations"); + } + contact.setValidationCompany( + ImportHelper.parseContactValidation(reader, + CONTACT.CONT_SOCIETE_VALID)); + contact.setValidationProgram( + ImportHelper.parseContactValidation(reader, + CONTACT.CONT_PROGRAM_VALID)); + } - Date tideBegin = - ImportHelper.readDate(reader, - CONTACT.CONT_DEBUT_MAREE); - Date tideEnd = - ImportHelper.readDate(reader, - CONTACT.CONT_FIN_MAREE); - Date dataInput = - ImportHelper.readDate(reader, - CONTACT.CONT_ALLEGRO); - int nbObservants = ImportHelper.readInt(reader, - CONTACT.CONT_NB_OBSERV); - if (nbObservants == -1) { - nbObservants = 0; - } - boolean mammalsCapture = - ImportHelper.parseContactMammals(reader, - CONTACT.CONT_MAM_CAPT); - boolean mammalsObsv = - ImportHelper.parseContactMammals(reader, - CONTACT.CONT_MAM_OBS); + // FIXME-FD20100416 : very strange behavior -> need to stop using topiaCreateDate + Date createDateCsv = + ImportHelper.readDate(reader, CONTACT.CONT_CREATION); + String contactCode = + ImportHelper.read(reader, CONTACT.CONT_CODE); + Date createDate = + ImportHelper.parseContactCreateDate( + contactCode, createDateCsv); - contact.setObserver(observer); - contact.setContactState(contactState); - contact.setTideBeginDate(tideBegin); - contact.setTideEndDate(tideEnd); - contact.setNbObservants(nbObservants); - contact.setMammalsCapture(mammalsCapture); - contact.setMammalsObservation(mammalsObsv); - contact.setDataInputDate(dataInput); + contact.setTopiaCreateDate(createDate); + } - // Import validations only for superadmin and a new contact : useful for archives - // FIXME : can update validation when the user is the super admin - if (newContact && user.isAdmin() && user.getLogin().equals("admin")) { - if (log.isDebugEnabled()) { - log.debug("SuperAdmin import :: validations"); - } - Boolean companyValidation = ImportHelper.parseContactValidation(reader, CONTACT.CONT_SOCIETE_VALID); - Boolean programValidation = ImportHelper.parseContactValidation(reader, CONTACT.CONT_PROGRAM_VALID); - contact.setValidationCompany(companyValidation); - contact.setValidationProgram(programValidation); + /** + * Update the SampleMonth data for tidesValue (estimated and real) from + * {@code contact} compared to its old state {@code oldContact}. The + * estimated is update when contact state {@link ContactState#BOARDING_DONE} + * is changed. The real is update when contact validationCompany is changed. + * The {@code calculateReal} flag determines if the real tides has to be + * calculated or not. + * + * @param transaction used to update the SampleMonth + * @param oldContact old state of the contact + * @param contact changed + * @param calculateReal to calculate real tides value + * @throws TopiaException + * @throws NullSampleMonthException if SampleMonth can't be found + */ + protected void updateSampleMonthTidesValue( + TopiaContext transaction, Contact oldContact, + Contact contact, boolean calculateReal) + throws TopiaException, NullSampleMonthException { - // Add realTideTime for this contact if validations are ok and state is BOARDING_DONE - if (BooleanUtils.isTrue(companyValidation) && BooleanUtils.isNotFalse(programValidation) && - contact.getContactState().equals(ContactState.BOARDING_DONE)) { - boolean ok = contact.getSampleRow().addRealTideTime(contact); - if (!ok) { - DateFormat dateFormat1 = new SimpleDateFormat("MM/yyyy"); - result.addError(currRow, "Impossible de mettre à jour le nombre de marée réels, vérifiez le mois " + - "de " + dateFormat1.format(contact.getTideBeginDate()) + " pour la ligne du plan " + row.getCode()); - result.incNbRefused(); - continue; - } - } - } + SampleMonthDAO monthDAO = WaoDAOHelper.getSampleMonthDAO(transaction); - //dao.update(contact); + if (log.isDebugEnabled()) { + log.debug("oldState = " + (oldContact != null ? + oldContact.getContactState() : "null") + + " _ newState = " + contact.getContactState()); + } - result.incNbImported(); + boolean oldContactDone = oldContact != null && + oldContact.getContactState().equals(ContactState.BOARDING_DONE); - } else { - result.addError(currRow, "Navire inexistant avec l'immatriculation : " + boatImmatriculation); - result.incNbRefused(); - } - } else { - result.addError(currRow, "Ligne d'échantillon inexistante ou incompatible avec la société " + - "pour le code : " + rowCode); - result.incNbRefused(); - } - } else { - result.addError(currRow, "Cet utilisateur n'est lié à aucune société : " + user.getFullName()); - result.incNbRefused(); + boolean newContactDone = contact.getContactState(). + equals(ContactState.BOARDING_DONE); + + boolean contactStateChanged = oldContact == null || + !contact.getContactState().equals(oldContact.getContactState()); + + SampleMonth sampleMonth = null; + // Estimated tides calcul + if ((oldContactDone || newContactDone) && contactStateChanged) { + if (log.isDebugEnabled()) { + log.debug("Calculate estimated tides value for date : " + + contact.getTideBeginDate()); + } + + sampleMonth = getExistingSampleMonthForContact(monthDAO, contact); + + if (oldContactDone) { + // dec estimatedTides + int estimated = sampleMonth.getEstimatedTidesValue(); + if (estimated > 0) { + sampleMonth.setEstimatedTidesValue(estimated - 1); } - } else { - result.addError(currRow, "Utilisateur inexistant avec l'identifiant : " + observerId); - result.incNbRefused(); + if (log.isDebugEnabled()) { + log.debug("Decrement : " + estimated + " -> " + + sampleMonth.getEstimatedTidesValue()); + } + } else if (newContactDone) { + // inc estimatedTides + int estimated = sampleMonth.getEstimatedTidesValue(); + sampleMonth.setEstimatedTidesValue(estimated + 1); + if (log.isDebugEnabled()) { + log.debug("Increment : " + estimated + " -> " + + sampleMonth.getEstimatedTidesValue()); + } } + } - if (result.getNbRowsImported() % 1000 == 0) { - transaction.commitTransaction(); - tic = ImportHelper.logTimeAndMemory(log, tic, "contacts ligne " + currRow); + // Real tides calcul (only if needed) + if (calculateReal) { + Boolean oldValidationCompany = oldContact != null ? + oldContact.getValidationCompany() : null; + Boolean newValidationCompany = contact.getValidationCompany(); + + boolean oldContactValidate = + BooleanUtils.isTrue(oldValidationCompany); + boolean newContactValidate = + BooleanUtils.isTrue(newValidationCompany); + + boolean contactValidationChanged = oldContact == null || + (oldValidationCompany != null && + !oldValidationCompany.equals(newValidationCompany)); + + if (log.isDebugEnabled()) { + log.debug("oldValidation = " + oldContactValidate + + " _ newValidation = " + newContactValidate); } + + if ((oldContactValidate || newContactValidate) && + contactValidationChanged) { + if (log.isDebugEnabled()) { + log.debug("Calculate real tides value for date : " + + contact.getTideBeginDate()); + } + + // Do not retrieve the sampleMonth if it is already defined from + // previous calcul on estimatedTidesValue + if (sampleMonth == null) { + sampleMonth = getExistingSampleMonthForContact( + monthDAO, contact); + } + + if (oldContactValidate) { + // dec realTides + int real = sampleMonth.getRealTidesValue(); + if (real > 0) { + sampleMonth.setRealTidesValue(real - 1); + } + if (log.isDebugEnabled()) { + log.debug("Decrement : " + real + " -> " + + sampleMonth.getRealTidesValue()); + } + } else if (newContactValidate) { + // inc realTides + int real = sampleMonth.getRealTidesValue(); + sampleMonth.setRealTidesValue(real + 1); + if (log.isDebugEnabled()) { + log.debug("Increment : " + real + " -> " + + sampleMonth.getRealTidesValue()); + } + } + } } + } - transaction.commitTransaction(); + /** + * This exception is used to indicate that a problem is occured during + * retrieving sampleMonth corresponding to a contact. + * @see #updateSampleMonthTidesValue(TopiaContext, Contact, Contact, boolean) + */ + public static final class NullSampleMonthException extends Exception { - //transaction.closeContext(); -// } catch (ParseException eee) { -// context.serviceException(transaction, -// "Erreur ligne " + currRow + " : " + -// "Le format des dates est incorrect, il doit être de la forme : JJ/MM/AAAA", eee); -// } catch (Exception eee) { -// if (log.isDebugEnabled()) { -// try { -// log.debug("Ligne : " + currRow + " :: " + Arrays.toString(reader.getValues())); -// } catch (IOException ex) { -// log.error("Reader error", ex); -// } -// } -// context.serviceException(transaction, -// "Impossible d'importer les contacts", eee); -// } finally { -// context.closeTransaction(transaction); -// } + private static final long serialVersionUID = 1L; + + public NullSampleMonthException(String message) { + super(message); + } + } + + /** + * Retrieve existing sampleMonth corresponding to the {@code contact}. The + * sampleMonth must match with contact sampleRow, also the tideBeginDate + * (day) of the contact must match the sampleMonth periodDate (month). + * + * @param monthDAO used to find the sampleMonth + * @param contact reference + * @return the sampleMonth found if exists, or NullSampleMonthException + * will be thrown + * @throws TopiaException + * @throws NullSampleMonthException if month was not found + */ + protected SampleMonth getExistingSampleMonthForContact( + SampleMonthDAO monthDAO, Contact contact) + throws TopiaException, NullSampleMonthException { + TopiaQuery query = monthDAO.createQuery(); + + PeriodDates period = new PeriodDates( + contact.getTideBeginDate(), contact.getTideBeginDate()); + period.initDayOfMonthExtremities(); + + // Bind sampleMonth.sampleRow with contact sampleRow + query.add(SampleMonth.SAMPLE_ROW, contact.getSampleRow()). + add(SampleMonth.PERIOD_DATE + " BETWEEN :fromDate AND :thruDate"). + addParam("fromDate", period.getFromDate()). + addParam("thruDate", period.getThruDate()); + //add(SampleMonth.PERIOD_DATE, period); + SampleMonth result = monthDAO.findByQuery(query); + if (result == null) { + throw new NullSampleMonthException("Aucun mois correspondant pour" + + " la ligne du plan d'échantillonnage " + + contact.getSampleRow().getCode() + + " et la date de début de marée du contact " + + contact.getTideBeginDate()); + } return result; } + /** + * Update the elligible boat depends on contact creation. The + * {@code contact} reference can only be created for a sampleRow and a + * boat if both are linked with an elligibleBoat. So this method is + * used to create the link if needed during contacts import. This + * elligibleBoat is needed for the contact owned by a company, so + * the companyActive property of ElligibleBoat will be set to TRUE. No + * admin has decided to explicitly create this link. + * + * @param transaction used to update the ElligibleBoat + * @param contact which contains sampleRow and boat to link + * @throws TopiaException + */ + protected void updateElligibleBoatForContact(TopiaContext transaction, + Contact contact) throws TopiaException { + + Boat boat = contact.getBoat(); + SampleRow row = contact.getSampleRow(); + + ElligibleBoatDAO elligibleDAO = + WaoDAOHelper.getElligibleBoatDAO(transaction); + ElligibleBoat elligible = + elligibleDAO.findByProperties( + ElligibleBoat.BOAT, contact.getBoat(), + ElligibleBoat.SAMPLE_ROW, contact.getSampleRow()); + + if (elligible == null) { + // Create new elligible boat not active in a global way + elligible = elligibleDAO.create( + ElligibleBoat.BOAT, boat, + ElligibleBoat.SAMPLE_ROW, row); + if (log.isTraceEnabled()) { + log.trace("Create elligibleBoat for : " + + boat.getImmatriculation() + " - " + + row.getCode()); + } + } + elligible.setCompanyActive(Boolean.TRUE); + } + } Modified: trunk/wao-business/src/main/resources/i18n/wao-business-en_GB.properties =================================================================== --- trunk/wao-business/src/main/resources/i18n/wao-business-en_GB.properties 2010-04-15 10:24:24 UTC (rev 449) +++ trunk/wao-business/src/main/resources/i18n/wao-business-en_GB.properties 2010-04-16 14:42:50 UTC (rev 450) @@ -30,6 +30,7 @@ wao.error.serviceContact.getNewContact= wao.error.serviceContact.importContactCsv= wao.error.serviceContact.saveContact= +wao.error.serviceContact.updateSampleMonthTidesValue= wao.error.serviceNews.getNews= wao.error.serviceNews.saveNews= wao.error.serviceReferential.getCodesDCF5Contains= Modified: trunk/wao-business/src/main/resources/i18n/wao-business-fr_FR.properties =================================================================== --- trunk/wao-business/src/main/resources/i18n/wao-business-fr_FR.properties 2010-04-15 10:24:24 UTC (rev 449) +++ trunk/wao-business/src/main/resources/i18n/wao-business-fr_FR.properties 2010-04-16 14:42:50 UTC (rev 450) @@ -29,6 +29,7 @@ wao.error.serviceContact.getNewContact=Impossible d'instancier un nouveau contact wao.error.serviceContact.importContactCsv=Impossible d'importer les contacts wao.error.serviceContact.saveContact=Impossible de sauvegarder le contact +wao.error.serviceContact.updateSampleMonthTidesValue= wao.error.serviceNews.getNews=Impossible de r\u00E9cup\u00E9rer l'ensemble des news wao.error.serviceNews.saveNews=Impossible d'enregistrer la news ayant pour titre '%1$s' wao.error.serviceReferential.getCodesDCF5Contains= Modified: trunk/wao-business/src/main/resources/oldmappings/Wao/1.2/fr/ifremer/wao/entity/SampleMonthImpl.hbm.xml =================================================================== --- trunk/wao-business/src/main/resources/oldmappings/Wao/1.2/fr/ifremer/wao/entity/SampleMonthImpl.hbm.xml 2010-04-15 10:24:24 UTC (rev 449) +++ trunk/wao-business/src/main/resources/oldmappings/Wao/1.2/fr/ifremer/wao/entity/SampleMonthImpl.hbm.xml 2010-04-16 14:42:50 UTC (rev 450) @@ -8,6 +8,7 @@ <property name="realTidesValue" type="int" access="field" column="realTidesValue" node="realTidesValue"/> <property name="expectedTidesValue" type="int" access="field" column="expectedTidesValue" node="expectedTidesValue"/> <property name="periodDate" type="java.util.Date" access="field" column="periodDate" node="periodDate"/> + <property name="estimatedTidesValue" type="int" access="field" column="estimatedTidesValue" node="estimatedTidesValue"/> <many-to-one name="sampleRow" class="fr.ifremer.wao.entity.SampleRowImpl" column="sampleRow" node="sampleRow/@topiaId" embed-xml="false"/> </class> </hibernate-mapping> Modified: trunk/wao-business/src/main/xmi/wao.zargo =================================================================== (Binary files differ) Modified: trunk/wao-business/src/test/java/fr/ifremer/wao/TestManager.java =================================================================== --- trunk/wao-business/src/test/java/fr/ifremer/wao/TestManager.java 2010-04-15 10:24:24 UTC (rev 449) +++ trunk/wao-business/src/test/java/fr/ifremer/wao/TestManager.java 2010-04-16 14:42:50 UTC (rev 450) @@ -157,7 +157,7 @@ return instance; } - public ServiceContact getServiceContact() { + public ServiceContactImpl getServiceContact() { ServiceContactImpl instance = new ServiceContactImpl(); instance.setContext(getContext()); return instance; Modified: trunk/wao-business/src/test/java/fr/ifremer/wao/entity/BoatImplTest.java =================================================================== --- trunk/wao-business/src/test/java/fr/ifremer/wao/entity/BoatImplTest.java 2010-04-15 10:24:24 UTC (rev 449) +++ trunk/wao-business/src/test/java/fr/ifremer/wao/entity/BoatImplTest.java 2010-04-16 14:42:50 UTC (rev 450) @@ -155,6 +155,7 @@ Assert.assertTrue(result); contact1.setContactState(ContactState.BOARDING_DONE); + contact1.setTideBeginDate(DateUtils.createDate(3, 3, 2010)); serviceContact.saveContact(contact1, false); result = boat.canCreateContact(company); @@ -204,35 +205,55 @@ WaoUser.COMPANY, company2); company2.addWaoUser(user2); + transaction.commitTransaction(); + + FishingZoneDAO zoneDAO = WaoDAOHelper.getFishingZoneDAO(transaction); + FishingZone zoneIId = zoneDAO.create(FishingZone.DISTRICT_CODE, "IId"); + FishingZone zoneIV = zoneDAO.create(FishingZone.DISTRICT_CODE, "IV"); + FishingZone zoneI = zoneDAO.create(FishingZone.DISTRICT_CODE, "I"); + + transaction.commitTransaction(); + + ServiceSampling serviceSampling = manager.getServiceSampling(); + input = getClass().getResourceAsStream("/import/echantillonnage.csv"); + serviceSampling.importSamplingPlanCsv(input); + + SampleRowDAO rowDAO = WaoDAOHelper.getSampleRowDAO(transaction); + SampleRow row = rowDAO.findByCode("2010_0001"); + SampleRow row2 = rowDAO.findByCode("2009_0006"); + row.getCompany(); + row.getProfession(); + row.sizeElligibleBoat(); + row.sizeSampleMonth(); + row2.getCompany(); + row2.getProfession(); + row2.sizeElligibleBoat(); + row2.sizeSampleMonth(); + // BoatInfosDAO boatInfosDAO = WaoDAOHelper.getBoatInfosDAO(transaction); // BoatInfos boatInfos = boatInfosDAO.create(BoatInfos.BOAT, boat, BoatInfos.COMPANY, company); - transaction.commitTransaction(); transaction.closeContext(); ServiceContact serviceContact = manager.getServiceContact(); // First contact : OK - Contact contact1 = new ContactImpl(); - contact1.setBoat(boat); - contact1.setObserver(user); + Contact contact1 = serviceContact.getNewContact(user, row, boat); contact1.setContactState(ContactState.BOARDING_DONE); - Date begin = DateUtils.createDate(3, 3, 2009); + Date begin = DateUtils.createDate(3, 5, 2010); contact1.setTideBeginDate(begin); contact1.setValidationCompany(Boolean.TRUE); serviceContact.saveContact(contact1, false); /** EXEC METHOD **/ - Date fromDate = DateUtils.createDate(1, 1, 2009); + Date fromDate = DateUtils.createDate(1, 5, 2010); int result = boat.getNbBoarding(fromDate); Assert.assertEquals(1, result); - Contact contact2 = new ContactImpl(); + Contact contact2 = serviceContact.getNewContact(user, row, boat); // Second contact with ValidationProgram = FALSE - contact2.setBoat(boat); - contact2.setObserver(user); contact2.setContactState(ContactState.BOARDING_DONE); - begin = DateUtils.createDate(3, 8, 2009); + begin = DateUtils.createDate(3, 8, 2010); contact2.setTideBeginDate(begin); contact2.setValidationCompany(Boolean.TRUE); contact2.setValidationProgram(Boolean.FALSE); @@ -241,12 +262,10 @@ result = boat.getNbBoarding(fromDate); Assert.assertEquals(1, result); - Contact contact3 = new ContactImpl(); + Contact contact3 = serviceContact.getNewContact(user, row, boat); // Third contact with tideBeginDate < fromDate - contact3.setBoat(boat); - contact3.setObserver(user); contact3.setContactState(ContactState.BOARDING_DONE); - begin = DateUtils.createDate(3, 8, 2008); + begin = DateUtils.createDate(3, 3, 2010); contact3.setTideBeginDate(begin); contact3.setValidationCompany(Boolean.TRUE); serviceContact.saveContact(contact3, false); @@ -254,12 +273,10 @@ result = boat.getNbBoarding(fromDate); Assert.assertEquals(1, result); - Contact contact4 = new ContactImpl(); + Contact contact4 = serviceContact.getNewContact(user2, row2, boat); // Fourth contact : OK with an other company - contact4.setBoat(boat); - contact4.setObserver(user2); contact4.setContactState(ContactState.BOARDING_DONE); - begin = DateUtils.createDate(3, 4, 2009); + begin = DateUtils.createDate(3, 5, 2010); contact4.setTideBeginDate(begin); contact4.setValidationCompany(Boolean.TRUE); serviceContact.saveContact(contact4, false); Modified: trunk/wao-business/src/test/java/fr/ifremer/wao/io/ImportHelperTest.java =================================================================== --- trunk/wao-business/src/test/java/fr/ifremer/wao/io/ImportHelperTest.java 2010-04-15 10:24:24 UTC (rev 449) +++ trunk/wao-business/src/test/java/fr/ifremer/wao/io/ImportHelperTest.java 2010-04-16 14:42:50 UTC (rev 450) @@ -140,8 +140,7 @@ calendar.set(Calendar.SECOND, 50); calendar.set(Calendar.MILLISECOND, 260); String expResult = "100150260"; - DateFormat timeFormat = CONTACT.getTimeFormat(); - String result = timeFormat.format(calendar.getTime()); + String result = CONTACT.TIME_FORMAT.format(calendar.getTime()); assertEquals(expResult, result); } @@ -160,7 +159,8 @@ calendar.set(Calendar.SECOND, 50); calendar.set(Calendar.MILLISECOND, 718); Date expResult = calendar.getTime(); - Date result = ImportHelper.parseContactCreateDate(code, "23/10/2009"); + Date date = DateUtils.createDate(23,10,2009); + Date result = ImportHelper.parseContactCreateDate(code, date); assertEquals(expResult, result); } Added: trunk/wao-business/src/test/java/fr/ifremer/wao/service/ServiceContactImplTest.java =================================================================== --- trunk/wao-business/src/test/java/fr/ifremer/wao/service/ServiceContactImplTest.java (rev 0) +++ trunk/wao-business/src/test/java/fr/ifremer/wao/service/ServiceContactImplTest.java 2010-04-16 14:42:50 UTC (rev 450) @@ -0,0 +1,431 @@ + +package fr.ifremer.wao.service; + +import com.csvreader.CsvReader; +import fr.ifremer.wao.TestManager; +import fr.ifremer.wao.WaoBusinessException; +import fr.ifremer.wao.WaoDAOHelper; +import fr.ifremer.wao.bean.ContactState; +import fr.ifremer.wao.bean.UserRole; +import fr.ifremer.wao.entity.Boat; +import fr.ifremer.wao.entity.BoatDAO; +import fr.ifremer.wao.entity.Company; +import fr.ifremer.wao.entity.CompanyDAO; +import fr.ifremer.wao.entity.Contact; +import fr.ifremer.wao.entity.SampleMonth; +import fr.ifremer.wao.entity.SampleMonthDAO; +import fr.ifremer.wao.entity.SampleRow; +import fr.ifremer.wao.entity.SampleRowDAO; +import fr.ifremer.wao.entity.WaoUser; +import fr.ifremer.wao.entity.WaoUserDAO; +import fr.ifremer.wao.io.ContactInput; +import fr.ifremer.wao.io.ImportRefusedException; +import fr.ifremer.wao.io.WaoCsvHeader.BOAT; +import fr.ifremer.wao.io.WaoCsvHeader.CONTACT; +import fr.ifremer.wao.io.WaoCsvHeader.SAMPLING; +import fr.ifremer.wao.service.ServiceContactImpl.NullSampleMonthException; +import java.io.IOException; +import java.text.ParseException; +import java.util.Date; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.nuiton.topia.TopiaContext; +import org.nuiton.topia.TopiaException; +import org.nuiton.util.DateUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import static org.mockito.Mockito.*; +import static org.junit.Assert.*; + +/** + * ServiceContactImplTest + * + * Created: 16 avr. 2010 + * + * @author fdesbois + * @version $Revision$ + * + * Mise a jour: $Date$ + * par : $Author$ + */ +public class ServiceContactImplTest { + + private static TestManager manager; + + private static final Logger logger = + LoggerFactory.getLogger(ServiceContactImplTest.class); + + private ServiceContactImpl service; + + @BeforeClass + public static void setUpClass() throws Exception { + manager = new TestManager(); + } + + @Before + public void setUp() throws Exception { + manager.start(); + MockitoAnnotations.initMocks(this); + service = manager.getServiceContact(); + sampleMonth = null; + sampleRow = null; + boat = null; + company = null; + observer = null; + } + + @After + public void tearDown() throws Exception { + manager.stop(); + } + + // Real data + protected SampleRow sampleRow; + protected SampleMonth sampleMonth; + protected Boat boat; + protected Company company; + protected WaoUser observer; + + // Mock data + @Mock + protected Contact contact; + @Mock + protected Contact contactReference; + @Mock + protected WaoUser creator; + @Mock + protected CsvReader reader; + + protected void prepareData(boolean needBoat, boolean needObserver) + throws TopiaException { + logger.info("Prepare data :"); + TopiaContext transaction = manager.getContext().beginTransaction(); + try { + + if (needObserver) { + CompanyDAO companyDAO = WaoDAOHelper.getCompanyDAO(transaction); + company = companyDAO.create(Company.NAME, "TARTANPION"); + + WaoUserDAO userDAO = WaoDAOHelper.getWaoUserDAO(transaction); + observer = userDAO.create( + WaoUser.COMPANY, company, + WaoUser.LOGIN, "jmichmuche", + WaoUser.FIRST_NAME, "Jean", + WaoUser.LAST_NAME, "Michmuche", + WaoUser.ROLE, UserRole.OBSERVER.ordinal()); + + when(contact.getObserver()).thenReturn(observer); + } + + SampleRowDAO rowDAO = + WaoDAOHelper.getSampleRowDAO(transaction); + logger.info("SampleRow : 2010_0001"); + sampleRow = rowDAO.create(SampleRow.CODE, "2010_0001", + SampleRow.COMPANY, company); + + SampleMonthDAO monthDAO = + WaoDAOHelper.getSampleMonthDAO(transaction); + logger.info("SampleMonth : 03/2010 _ row 2010_0001"); + Date monthDate = DateUtils.createDate(1, 3, 2010); + sampleMonth = monthDAO.create(SampleMonth.SAMPLE_ROW, sampleRow, + SampleMonth.PERIOD_DATE, monthDate); + + Date contactDate = DateUtils.createDate(18, 3, 2010); + when(contact.getTideBeginDate()).thenReturn(contactDate); + when(contact.getSampleRow()).thenReturn(sampleRow); + + if (needBoat) { + BoatDAO boatDAO = WaoDAOHelper.getBoatDAO(transaction); + boat = boatDAO.create(Boat.IMMATRICULATION, 175846); + when(contact.getBoat()).thenReturn(boat); + } + + transaction.commitTransaction(); + } finally { + transaction.closeContext(); + } + } + + @Test + public void testGetExistingSampleMonthForContact() + throws TopiaException, NullSampleMonthException { + logger.info("testGetExistingSampleMonthForContact"); + + /** PREPARE DATA **/ + prepareData(false, false); + + /** EXEC METHOD **/ + logger.info("test 1 : SampleMonth exists for contact"); + TopiaContext transaction = manager.getContext().beginTransaction(); + try { + SampleMonthDAO monthDAO = + WaoDAOHelper.getSampleMonthDAO(transaction); + + // Contact is valid for the sampleMonth + + SampleMonth result = + service.getExistingSampleMonthForContact(monthDAO, contact); + + assertEquals(sampleMonth, result); + + } finally { + transaction.closeContext(); + } + + logger.info("test 2 : contact tideBeginDate doesn't match with any" + + " SampleMonth"); + transaction = manager.getContext().beginTransaction(); + try { + SampleMonthDAO monthDAO = + WaoDAOHelper.getSampleMonthDAO(transaction); + + Date contactDate = DateUtils.createDate(18, 10, 2010); + when(contact.getTideBeginDate()).thenReturn(contactDate); + + service.getExistingSampleMonthForContact(monthDAO, contact); + } catch (Exception eee) { + logger.error("Error : " + eee.getMessage()); + assertEquals(NullSampleMonthException.class, eee.getClass()); + } finally { + transaction.closeContext(); + } + } + + @Test + public void testUpdateSampleMonthTidesValue() throws TopiaException, NullSampleMonthException { + logger.info("testUpdateSampleMonthTidesValue"); + + /** PREPARE DATA **/ + prepareData(false, false); + Date tideBeginDate = contact.getTideBeginDate(); + when(contactReference.getTideBeginDate()).thenReturn(tideBeginDate); + when(contactReference.getSampleRow()).thenReturn(sampleRow); + + /** EXEC METHOD **/ + logger.info("test 1 : ContactState changed from null to BOARDING_DONE" + + " -> increment estimated tides value"); + TopiaContext transaction = manager.getContext().beginTransaction(); + try { + when(contact.getContactState()). + thenReturn(ContactState.BOARDING_DONE); + + service.updateSampleMonthTidesValue(transaction, null, + contact, false); + + transaction.commitTransaction(); + } finally { + transaction.closeContext(); + } + + logger.info("test 1 : verification sampleMonth estimated tides = 1"); + checkTidesValue(1, false); + + logger.info("test 2 : ContactState changed from BOARDING_DONE to " + + "BOAT_REFUSED -> decrement estimated tides value"); + transaction = manager.getContext().beginTransaction(); + try { + when(contact.getContactState()). + thenReturn(ContactState.BOAT_REFUSED); + + when(contactReference.getContactState()). + thenReturn(ContactState.BOARDING_DONE); + + service.updateSampleMonthTidesValue(transaction, contactReference, + contact, false); + + transaction.commitTransaction(); + } finally { + transaction.closeContext(); + } + + logger.info("test 2 : verification sampleMonth estimated tides = 0"); + checkTidesValue(0, false); + + when(contact.getContactState()). + thenReturn(ContactState.BOARDING_DONE); + + logger.info("test 3 : CompanyValidation changed from null to " + + "FALSE -> do nothing"); + transaction = manager.getContext().beginTransaction(); + try { + when(contact.getValidationCompany()).thenReturn(Boolean.FALSE); + + when(contactReference.getValidationCompany()).thenReturn(null); + + service.updateSampleMonthTidesValue(transaction, contactReference, + contact, true); + + transaction.commitTransaction(); + } finally { + transaction.closeContext(); + } + + logger.info("test 3 : verification sampleMonth real tides = 0"); + checkTidesValue(0, true); + + logger.info("test 4 : CompanyValidation changed from FALSE to " + + "TRUE -> increment real tides value"); + transaction = manager.getContext().beginTransaction(); + try { + when(contact.getValidationCompany()).thenReturn(Boolean.TRUE); + + when(contactReference.getValidationCompany()). + thenReturn(Boolean.FALSE); + + service.updateSampleMonthTidesValue(transaction, contactReference, + contact, true); + + transaction.commitTransaction(); + } finally { + transaction.closeContext(); + } + + logger.info("test 4 : verification sampleMonth real tides = 1"); + checkTidesValue(1, true); + } + + protected void checkTidesValue(int expected, boolean real) + throws TopiaException { + TopiaContext transaction = manager.getContext().beginTransaction(); + try { + SampleMonthDAO dao = WaoDAOHelper.getSampleMonthDAO(transaction); + + SampleMonth result = dao.findByTopiaId(sampleMonth.getTopiaId()); + int test = real ? result.getRealTidesValue() : + result.getEstimatedTidesValue(); + assertEquals(expected, test); + } finally { + transaction.closeContext(); + } + } + + @Test + public void testLoadContactCsv() throws TopiaException, + WaoBusinessException, + IOException, + ImportRefusedException, + ImportRefusedException, + ParseException { + logger.info("testUpdateSampleMonthTidesValue"); + + /** PREPARE DATA **/ + prepareData(true, true); + + when(reader.get(CONTACT.CONT_ETAT.name())). + thenReturn(ContactState.BOARDING_DONE.libelle()); + when(reader.get(CONTACT.OBSERV_ID.name())). + thenReturn(observer.getLogin()); + when(reader.get(SAMPLING.PLAN_CODE.name())). + thenReturn(sampleRow.getCode()); + when(reader.get(BOAT.NAVS_COD.name())). + thenReturn(String.valueOf(boat.getImmatriculation())); + when(reader.get(CONTACT.CONT_DEBUT_MAREE.name())). + thenReturn("22/03/2010"); + when(reader.get(CONTACT.CONT_FIN_MAREE.name())). + thenReturn("22/03/10"); + when(reader.get(CONTACT.CONT_NB_OBSERV.name())). + thenReturn("1"); + when(reader.get(CONTACT.CONT_MAM_CAPT.name())). + thenReturn(""); + when(reader.get(CONTACT.CONT_MAM_OBS.name())). + thenReturn("X"); + when(reader.get(CONTACT.CONT_ALLEGRO.name())). + thenReturn("25/03/2010"); + when(reader.get(CONTACT.CONT_SOCIETE_VALID.name())). + thenReturn("A"); + when(reader.get(CONTACT.CONT_PROGRAM_VALID.name())). + thenReturn(""); + when(reader.get(CONTACT.CONT_CREATION.name())). + thenReturn("18/03/10"); + when(reader.get(CONTACT.CONT_CODE.name())). + thenReturn(""); + + when(creator.getCompany()).thenReturn(company); + when(creator.isAdmin()).thenReturn(false); + when(creator.getLogin()).thenReturn(observer.getLogin()); + + /** EXEC METHOD **/ + + logger.info("test 1 : load contact by Creator jmichmuche -> no error"); + ContactInput result = new ContactInput(); + TopiaContext transaction = manager.getContext().beginTransaction(); + try { + result.initialize(transaction, creator, 1); + service.loadContactCsv(reader, result, false); + Date createDate = DateUtils.createDate(18,3,2010); + assertEquals(createDate, result.getTopiaCreateDate()); + assertEquals(ContactState.BOARDING_DONE, result.getContactState()); + assertEquals(observer, result.getObserver()); + assertEquals(sampleRow, result.getSampleRow()); + assertEquals(boat, result.getBoat()); + assertEquals(DateUtils.createDate(22,3,2010), + result.getTideBeginDate()); + assertEquals(DateUtils.createDate(22,3,2010), + result.getTideEndDate()); + assertEquals(1, result.getNbObservants()); + assertFalse(result.getMammalsCapture()); + assertTrue(result.getMammalsObservation()); + assertEquals(DateUtils.createDate(25,3,2010), + result.getDataInputDate()); + // No validation update : creator is not an admin + assertNull(result.getValidationCompany()); + assertNull(result.getValidationProgram()); + } finally { + transaction.closeContext(); + } + + logger.info("test 2 : Error on boat"); + when(reader.get(BOAT.NAVS_COD.name())).thenReturn("2222"); + checkImportError(Contact.BOAT); + // Reinit boat + when(reader.get(BOAT.NAVS_COD.name())). + thenReturn(String.valueOf(boat.getImmatriculation())); + + logger.info("test 3 : Error on company"); + when(creator.getCompany()).thenReturn(null); + checkImportError(WaoUser.COMPANY); + // Reinit creator company + when(creator.getCompany()).thenReturn(company); + + logger.info("test 4 : Error on observer"); + when(reader.get(CONTACT.OBSERV_ID.name())).thenReturn("FAKE"); + checkImportError(Contact.OBSERVER); + // Reinit observer + when(reader.get(CONTACT.OBSERV_ID.name())). + thenReturn(observer.getLogin()); + + logger.info("test 5 : Error on sampleRow"); + when(reader.get(SAMPLING.PLAN_CODE.name())).thenReturn("FAKE"); + checkImportError(Contact.SAMPLE_ROW); + // Reinit sampleRow + when(reader.get(SAMPLING.PLAN_CODE.name())). + thenReturn(sampleRow.getCode()); + + logger.info("test 6 : Error on state"); + when(reader.get(CONTACT.CONT_ETAT.name())).thenReturn("FAKE"); + checkImportError(Contact.STATE); + // Reinit state + when(reader.get(CONTACT.CONT_ETAT.name())). + thenReturn(ContactState.BOARDING_DONE.libelle()); + } + + protected void checkImportError(String field) throws TopiaException { + ContactInput result = new ContactInput(); + TopiaContext transaction = manager.getContext().beginTransaction(); + try { + result.initialize(transaction, creator, 1); + service.loadContactCsv(reader, result, false); + } catch (Exception eee) { + logger.error("Error : " + eee.getMessage()); + assertEquals(ImportRefusedException.class, eee.getClass()); + ImportRefusedException ex = (ImportRefusedException)eee; + assertEquals(field, ex.getField()); + } finally { + transaction.closeContext(); + } + } +} Property changes on: trunk/wao-business/src/test/java/fr/ifremer/wao/service/ServiceContactImplTest.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL" Modified: trunk/wao-business/src/test/java/fr/ifremer/wao/service/ServiceSynthesisImplTest.java =================================================================== --- trunk/wao-business/src/test/java/fr/ifremer/wao/service/ServiceSynthesisImplTest.java 2010-04-15 10:24:24 UTC (rev 449) +++ trunk/wao-business/src/test/java/fr/ifremer/wao/service/ServiceSynthesisImplTest.java 2010-04-16 14:42:50 UTC (rev 450) @@ -157,7 +157,7 @@ contact1.setObserver(user); contact1.setSampleRow(row); contact1.setContactState(ContactState.BOARDING_DONE); - Date begin = DateUtils.createDate(3, 3, 2009); + Date begin = DateUtils.createDate(3, 3, 2010); contact1.setTideBeginDate(begin); contact1.setValidationCompany(Boolean.TRUE); serviceContact.saveContact(contact1, false); @@ -167,7 +167,7 @@ contact2.setObserver(user); contact2.setSampleRow(row); contact2.setContactState(ContactState.BOARDING_DONE); - begin = DateUtils.createDate(3, 3, 2009); + begin = DateUtils.createDate(3, 3, 2010); contact2.setTideBeginDate(begin); contact2.setValidationCompany(Boolean.TRUE); serviceContact.saveContact(contact2, false); @@ -177,7 +177,7 @@ contact3.setObserver(user); contact3.setSampleRow(row); contact3.setContactState(ContactState.BOARDING_DONE); - begin = DateUtils.createDate(3, 3, 2009); + begin = DateUtils.createDate(3, 3, 2010); contact3.setTideBeginDate(begin); contact3.setValidationCompany(Boolean.TRUE); serviceContact.saveContact(contact3, false); @@ -248,7 +248,7 @@ // 1 real observer over 1 contact1.setNbObservants(1); contact1.setContactState(ContactState.BOARDING_DONE); - Date begin = DateUtils.createDate(3, 3, 2009); + Date begin = DateUtils.createDate(3, 3, 2010); contact1.setTideBeginDate(begin); contact1.setValidationCompany(Boolean.TRUE); serviceContact.saveContact(contact1, false); @@ -260,7 +260,7 @@ // 2 real observer over 1 contact2.setNbObservants(2); contact2.setContactState(ContactState.BOARDING_DONE); - begin = DateUtils.createDate(3, 3, 2009); + begin = DateUtils.createDate(3, 3, 2010); contact2.setTideBeginDate(begin); contact2.setValidationCompany(Boolean.TRUE); serviceContact.saveContact(contact2, false); @@ -272,7 +272,7 @@ // 1 real observer over 2 contact3.setNbObservants(1); contact3.setContactState(ContactState.BOARDING_DONE); - begin = DateUtils.createDate(3, 3, 2009); + begin = DateUtils.createDate(3, 3, 2010); contact3.setTideBeginDate(begin); contact3.setValidationCompany(Boolean.TRUE); serviceContact.saveContact(contact3, false); @@ -341,6 +341,7 @@ SampleRowDAO rowDAO = WaoDAOHelper.getSampleRowDAO(transaction); SampleRow row = rowDAO.findByCode("2010_0001"); + SampleRow row2 = rowDAO.findByCode("2009_0006"); transaction.closeContext(); @@ -349,44 +350,56 @@ // Contacts for company TARTANPION Contact contact1 = new ContactImpl(); + contact1.setBoat(boat); contact1.setObserver(user); + contact1.setSampleRow(row); contact1.setContactState(ContactState.BOARDING_DONE); - Date begin = DateUtils.createDate(3, 3, 2009); + Date begin = DateUtils.createDate(3, 3, 2010); contact1.setTideBeginDate(begin); serviceContact.saveContact(contact1, false); Contact contact2 = new ContactImpl(); + contact2.setBoat(boat); contact2.setObserver(user); + contact2.setSampleRow(row); contact2.setContactState(ContactState.BOARDING_DONE); - begin = DateUtils.createDate(3, 10, 2009); + begin = DateUtils.createDate(3, 10, 2010); contact2.setTideBeginDate(begin); serviceContact.saveContact(contact2, false); Contact contact3 = new ContactImpl(); + contact3.setBoat(boat); contact3.setObserver(user); + contact3.setSampleRow(row); contact3.setContactState(ContactState.BOAT_REFUSED); - begin = DateUtils.createDate(3, 5, 2009); + begin = DateUtils.createDate(3, 5, 2010); contact3.setTopiaCreateDate(begin); serviceContact.saveContact(contact3, false); // Contacts for company BIS Contact contact4 = new ContactImpl(); + contact4.setBoat(boat2); contact4.setObserver(user2); + contact4.setSampleRow(row2); contact4.setContactState(ContactState.BOARDING_EXPECTED); - begin = DateUtils.createDate(3, 5, 2009); + begin = DateUtils.createDate(3, 3, 2010); contact4.setTopiaCreateDate(begin); serviceContact.saveContact(contact4, false); Contact contact5 = new ContactImpl(); + contact5.setBoat(boat2); contact5.setObserver(user2); + contact5.setSampleRow(row2); contact5.setContactState(ContactState.BOAT_UNAVAILABLE); - begin = DateUtils.createDate(3, 3, 2010); + begin = DateUtils.createDate(3, 5, 2010); contact5.setTopiaCreateDate(begin); serviceContact.saveContact(contact5, false); // Contact refused by program, will not be in result Contact contact6 = new ContactImpl(); + contact6.setBoat(boat2); contact6.setObserver(user2); + contact6.setSampleRow(row2); contact6.setContactState(ContactState.BOAT_UNAVAILABLE); begin = DateUtils.createDate(3, 3, 2010); contact6.setTopiaCreateDate(begin); @@ -426,9 +439,9 @@ assertEquals(1, data.get(ContactState.BOARDING_EXPECTED).intValue()); assertEquals(1, data.get(ContactState.BOAT_UNAVAILABLE).intValue()); - // result for period 3/5/2009 to 3/10/2009 for BIS company - begin = DateUtils.createDate(3, 5, 2009); - Date end = DateUtils.createDate(31, 10, 2009); + // result for period 3/1/2010 to 31/3/2010 for BIS company + begin = DateUtils.createDate(3, 1, 2010); + Date end = DateUtils.createDate(31, 3, 2010); PeriodDates period = new PeriodDates(begin, end); results = service.getContactStateStatistics(company2, period); @@ -492,28 +505,34 @@ ServiceContact serviceContact = manager.getServiceContact(); // First contact : OK Contact contact1 = new ContactImpl(); + contact1.setBoat(boat); contact1.setObserver(user); - Date begin = DateUtils.createDate(3, 3, 2009); + contact1.setSampleRow(row); + Date begin = DateUtils.createDate(3, 3, 2010); contact1.setTideBeginDate(begin); - Date inputDate = DateUtils.createDate(15, 4, 2009); + Date inputDate = DateUtils.createDate(15, 4, 2010); contact1.setDataInputDate(inputDate); contact1.setContactState(ContactState.BOARDING_DONE); contact1.setValidationCompany(Boolean.TRUE); serviceContact.saveContact(contact1, false); Contact contact2 = new ContactImpl(); + contact2.setBoat(boat); contact2.setObserver(user); - begin = DateUtils.createDate(3, 3, 2009); + contact2.setSampleRow(row); + begin = DateUtils.createDate(3, 3, 2010); contact2.setTideBeginDate(begin); - inputDate = DateUtils.createDate(15, 3, 2009); + inputDate = DateUtils.createDate(15, 3, 2010); contact2.setDataInputDate(inputDate); contact2.setContactState(ContactState.BOARDING_DONE); contact2.setValidationCompany(Boolean.TRUE); serviceContact.saveContact(contact2, false); Contact contact3 = new ContactImpl(); + contact3.setBoat(boat2); contact3.setObserver(user2); - begin = DateUtils.createDate(3, 3, 2009); + contact3.setSampleRow(row2); + begin = DateUtils.createDate(3, 3, 2010); contact3.setTideBeginDate(begin); contact3.setDataInputDate(begin); contact3.setContactState(ContactState.BOARDING_DONE); Property changes on: trunk/wao-business/src/test/resources/import ___________________________________________________________________ Added: svn:ignore + .~lock.echantillonnage.csv# Modified: trunk/wao-business/src/test/resources/log4j.properties =================================================================== --- trunk/wao-business/src/test/resources/log4j.properties 2010-04-15 10:24:24 UTC (rev 449) +++ trunk/wao-business/src/test/resources/log4j.properties 2010-04-16 14:42:50 UTC (rev 450) @@ -8,6 +8,6 @@ log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=%d [%p] %c{2} %m%n -log4j.logger.fr.ifremer.wao=INFO +log4j.logger.fr.ifremer.wao=DEBUG log4j.logger.org.nuiton.util=INFO log4j.logger.org.nuiton.util.beans.BinderProvider=ERROR Modified: trunk/wao-ui/src/main/java/fr/ifremer/wao/ui/services/AppModule.java =================================================================== --- trunk/wao-ui/src/main/java/fr/ifremer/wao/ui/services/AppModule.java 2010-04-15 10:24:24 UTC (rev 449) +++ trunk/wao-ui/src/main/java/fr/ifremer/wao/ui/services/AppModule.java 2010-04-16 14:42:50 UTC (rev 450) @@ -228,4 +228,10 @@ new ApplicationStateContribution("session", creator)); } +// public void contributeValidationMessagesSource(OrderedConfiguration<String> configuration) { +// configuration.add("myValidationMessages", "jumpstart/web/validators/ValidationMessages"); +// configuration.add("myTranslationMessages", "jumpstart/web/translators/TranslationMessages"); +// } + + }