Author: fdesbois Date: 2010-02-02 23:48:45 +0000 (Tue, 02 Feb 2010) New Revision: 317 Added: trunk/suiviobsmer-business/src/test/java/fr/ifremer/suiviobsmer/impl/ServiceSynthesisImplTest.java Modified: trunk/changelog.txt trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/entity/ContactDAOImpl.java trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/impl/ServiceSynthesisImpl.java trunk/suiviobsmer-business/src/main/xmi/suiviobsmer.zargo trunk/suiviobsmer-ui/src/main/java/fr/ifremer/suiviobsmer/ui/pages/Synthesis.java trunk/suiviobsmer-ui/src/main/webapp/Synthesis.tml Log: - Use a new BoardingResult bean to simplify result for boardingsBoat synthesis - Return boat from query and order by count to easily get max boarding boat find + add junit test - Use contact alias in doneContactsFromDate query Modified: trunk/changelog.txt =================================================================== --- trunk/changelog.txt 2010-02-02 21:01:46 UTC (rev 316) +++ trunk/changelog.txt 2010-02-02 23:48:45 UTC (rev 317) @@ -7,6 +7,8 @@ Evolutions ++++++++++ +- [fdesbois] Evo #2078 : Synthèse nombre de sollicitation : affichage du + près + de la valeur maximum - [fdesbois] Evo #1964 : Calendrier d'activité : Log des accès à la page - [fdesbois] Evo #2081 : Log des changement sur plan : manque ancienne valeur effort si modifiée Modified: trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/entity/ContactDAOImpl.java =================================================================== --- trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/entity/ContactDAOImpl.java 2010-02-02 21:01:46 UTC (rev 316) +++ trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/entity/ContactDAOImpl.java 2010-02-02 23:48:45 UTC (rev 317) @@ -76,18 +76,18 @@ */ @Override public TopiaQuery<E> createQueryDoneContactsFromDate(Boat boat, Date fromDate) { - TopiaQuery<E> query = createQuery(). - add(Contact.STATE, ContactState.BOARDING_DONE.toString()). - add(Contact.VALIDATION_COMPANY, Boolean.TRUE). - add(Contact.VALIDATION_PROGRAM + " IS NULL OR " + Contact.VALIDATION_PROGRAM + " = :booleanTrue"). + TopiaQuery<E> query = createQuery("C"). + add("C." + Contact.STATE, ContactState.BOARDING_DONE.toString()). + add("C." + Contact.VALIDATION_COMPANY, Boolean.TRUE). + add("C." + Contact.VALIDATION_PROGRAM + " IS NULL OR " + "C." + Contact.VALIDATION_PROGRAM + " = :booleanTrue"). addParam("booleanTrue", Boolean.TRUE); if (boat != null) { - query.add(Contact.BOAT, boat); + query.add("C." + Contact.BOAT, boat); } if (fromDate != null) { - query.add(Contact.TIDE_BEGIN_DATE, Op.GE, fromDate); + query.add("C." + Contact.TIDE_BEGIN_DATE, Op.GE, fromDate); } return query; } Modified: trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/impl/ServiceSynthesisImpl.java =================================================================== --- trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/impl/ServiceSynthesisImpl.java 2010-02-02 21:01:46 UTC (rev 316) +++ trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/impl/ServiceSynthesisImpl.java 2010-02-02 23:48:45 UTC (rev 317) @@ -24,6 +24,8 @@ import fr.ifremer.suiviobsmer.SuiviObsmerContext; import fr.ifremer.suiviobsmer.SuiviObsmerException; import fr.ifremer.suiviobsmer.SuiviObsmerModelDAOHelper; +import fr.ifremer.suiviobsmer.bean.BoardingResult; +import fr.ifremer.suiviobsmer.bean.BoardingResultImpl; import fr.ifremer.suiviobsmer.bean.SamplingFilter; import fr.ifremer.suiviobsmer.entity.Boat; import fr.ifremer.suiviobsmer.entity.Company; @@ -34,7 +36,6 @@ import fr.ifremer.suiviobsmer.entity.SampleRow; import fr.ifremer.suiviobsmer.services.ServiceSynthesis; import java.text.DateFormat; -import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; @@ -132,104 +133,105 @@ return results; } - protected static final int MAX_BOARDINGS = 12; - public static final String MAX_BOARDINGS_KEY = MAX_BOARDINGS + " +"; - + /** + * We need to select the boats and for each one, the number of boardings + * done. The number of boardings is calculated with the number of contacts + * finished linked with each boat. The {@code fromDate} is used to filter + * results since this date. For observer view, only results for his + * company is needed. + * + * @param company the company used to filter results + * @param fromDate the since date used to filter contact results + * @return a BoardingResult which contains the number of boats for boardings + * from 1 to {@link MAX_BOARDINGS}, the boat with the max boarding and its + * value. + * @throws SuiviObsmerException + */ @Override - public Map<String, Integer> getBoardingBoats(Company company, Date fromDate) throws SuiviObsmerException { + public BoardingResult getBoardingBoats(Company company, Date fromDate) + throws SuiviObsmerException { TopiaContext transaction = null; - //Pair<SortedMap<String, Integer>, Boat> result = null; Map<String, Integer> map = new LinkedHashMap<String, Integer>(); + BoardingResult result = new BoardingResultImpl(); + result.setData(map); try { transaction = rootContext.beginTransaction(); - //SortedMap<String, Integer> map = new TreeMap<String, Integer>(); + // Initialiaze max boardings and its max key value + final int MAX_BOARDINGS = 12; + final String MAX_BOARDINGS_KEY = MAX_BOARDINGS + " +"; -// NumberFormat numberFormat = NumberFormat.getNumberInstance(); -// numberFormat.setMinimumIntegerDigits( -// String.valueOf(MAX_BOARDINGS).length()); - + // Prepare map which contains for each entry the number of boardings + // for the key and the number of boats for the value. for (int i = 1; i < MAX_BOARDINGS; i++) { map.put(String.valueOf(i), 0); } map.put(MAX_BOARDINGS_KEY, 0); - ContactDAO dao = SuiviObsmerModelDAOHelper.getContactDAO(transaction); - TopiaQuery<Contact> query = dao.createQueryDoneContactsFromDate(null, fromDate); + ContactDAO dao = + SuiviObsmerModelDAOHelper.getContactDAO(transaction); + // The number of boardings is the number of finished contacts + // Use fromDate to filter contacts finished from this date + // No need to use boat filter for this method + TopiaQuery<Contact> query = + dao.createQueryDoneContactsFromDate(null, fromDate); + + String contact = query.getMainAlias(); + String sampleRow = contact + "." + Contact.SAMPLE_ROW; // Only for sampleRows with averageTideTime less or equals to 2 days - String countAlias = "nbElmts"; - query.add(Contact.SAMPLE_ROW + "." + SampleRow.AVERAGE_TIDE_TIME, Op.LE, 2.). - addGroup(Contact.BOAT). - setSelect("COUNT(*)"); - //setSelect("COUNT(*) AS " + countAlias + ", " + Contact.BOAT). - //addOrderDesc(countAlias); + query.add(sampleRow + "." + SampleRow.AVERAGE_TIDE_TIME, Op.LE, 2.); + // Add filter on sampleRow company if needed if (company != null) { - query.add(Contact.SAMPLE_ROW + "." + SampleRow.COMPANY, company); + query.add(sampleRow + "." + SampleRow.COMPANY, company); } + // Prepare aliases for mapping results in select part + String countAlias = "nbBoardings"; + String boatAlias = "boat"; + // Use a map for each result with boat and its number of boardings + // Order by number of boardings to easily find the max value (the + // first result) + query.setSelect("new map(" + contact + "." + Contact.BOAT + " as " + + boatAlias + ", COUNT(*) as " + countAlias + ")"). + addGroup(contact + "." + Contact.BOAT). + addOrderDesc("COUNT(*)"); + if (log.isTraceEnabled()) { log.trace("Exec query : " + query); } - //List<Object[]> nbBoardingsByBoat = (List<Object[]>)query.execute(); - List<Long> nbBoardingsByBoat = (List<Long>)query.execute(); + List<Map<String, Object>> nbBoardingsByBoat = query.execute(); - Boat maxBoat = null; if (!nbBoardingsByBoat.isEmpty()) { - for (Long boardings : nbBoardingsByBoat) { - //int intValue = ((Long)boardings[0]).intValue(); - int intValue = boardings.intValue(); - String value = boardings.toString(); + for (Map<String, Object> row : nbBoardingsByBoat) { + Long count = (Long)row.get(countAlias); + int intValue = count.intValue(); + String value = count.toString(); if (intValue >= MAX_BOARDINGS) { value = MAX_BOARDINGS_KEY; } + // Increment the number of boats for the current number of + // boardings Integer nbBoats = map.get(value); map.put(value, nbBoats + 1); } -// Object[] first = nbBoardingsByBoat.get(0); -// maxBoat = (Boat)first[1]; + // Set the max boat and its number of boardings value + Map<String, Object> max = nbBoardingsByBoat.get(0); + result.setMaxBoardingBoat((Boat)max.get(boatAlias)); + Long maxValue = (Long)max.get(countAlias); + result.setMaxBoardingValue(maxValue.intValue()); } - //result = new Pair<SortedMap<String, Integer>, Boat>(map, maxBoat); - - //Entry<String, Integer> plop = new SimpleEntry<String, Integer>("bol", 3); - //Pair<String, Integer> plop = new Pair<String, Integer>("bol",3); - //Pair<Boat, Integer> maxBoardingsBoat = - transaction.closeContext(); } catch (Exception eee) { SuiviObsmerContext.serviceException(transaction, - "Impossible de récupérer les données pour le graphique dynamique des efforts de marées", eee); + "Impossible de récupérer les données pour le graphique " + + "dynamique des efforts de marées", eee); } - return map; + return result; } -// @Override -// public Boat getBoatWithMaxBoardings(Date fromDate) { -// TopiaContext transaction = null; -// Boat result = null; -// try { -// transaction = rootContext.beginTransaction(); -// -// -// BoatDAO dao = SuiviObsmerModelDAOHelper.getBoatDAO(transaction); -// TopiaQuery<Boat> query = dao.createQuery(); -// //result = query.setSelect(Contact.BOAT). -// -// ContactDAO contactDAO = SuiviObsmerModelDAOHelper.getContactDAO(transaction); -// TopiaQuery<Contact> subquery = contactDAO. -// createQueryDoneContactsFromDate(null, fromDate). -// setSelect(Contact.BOAT); -// -// transaction.closeContext(); -// } catch (Exception eee) { -// SuiviObsmerContext.serviceException(transaction, -// "Impossible de récupérer le navire ayant le plus de sollicitations", eee); -// } -// return result; -// } - } Modified: trunk/suiviobsmer-business/src/main/xmi/suiviobsmer.zargo =================================================================== (Binary files differ) Added: trunk/suiviobsmer-business/src/test/java/fr/ifremer/suiviobsmer/impl/ServiceSynthesisImplTest.java =================================================================== --- trunk/suiviobsmer-business/src/test/java/fr/ifremer/suiviobsmer/impl/ServiceSynthesisImplTest.java (rev 0) +++ trunk/suiviobsmer-business/src/test/java/fr/ifremer/suiviobsmer/impl/ServiceSynthesisImplTest.java 2010-02-02 23:48:45 UTC (rev 317) @@ -0,0 +1,167 @@ + +package fr.ifremer.suiviobsmer.impl; + +import fr.ifremer.suiviobsmer.SuiviObsmerContext; +import fr.ifremer.suiviobsmer.SuiviObsmerModelDAOHelper; +import fr.ifremer.suiviobsmer.SuiviObsmerRunner; +import fr.ifremer.suiviobsmer.SuiviObsmerRunnerTest; +import fr.ifremer.suiviobsmer.bean.BoardingResult; +import fr.ifremer.suiviobsmer.bean.ContactState; +import fr.ifremer.suiviobsmer.entity.Boat; +import fr.ifremer.suiviobsmer.entity.Company; +import fr.ifremer.suiviobsmer.entity.CompanyDAO; +import fr.ifremer.suiviobsmer.entity.Contact; +import fr.ifremer.suiviobsmer.entity.ContactImpl; +import fr.ifremer.suiviobsmer.entity.SampleRow; +import fr.ifremer.suiviobsmer.entity.SampleRowDAO; +import fr.ifremer.suiviobsmer.entity.WaoUser; +import fr.ifremer.suiviobsmer.entity.WaoUserDAO; +import fr.ifremer.suiviobsmer.services.ServiceBoat; +import fr.ifremer.suiviobsmer.services.ServiceContact; +import fr.ifremer.suiviobsmer.services.ServiceReferential; +import fr.ifremer.suiviobsmer.services.ServiceSampling; +import java.io.InputStream; +import java.util.Date; +import java.util.List; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.nuiton.topia.TopiaContext; +import org.nuiton.util.DateUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import static org.junit.Assert.*; + +/** + * + * @author fdesbois + */ +public class ServiceSynthesisImplTest { + + private static SuiviObsmerRunner runner; + + private static final Logger log = LoggerFactory.getLogger(ServiceSynthesisImplTest.class); + + private ServiceSynthesisImpl service; + + public ServiceSynthesisImplTest() { + } + + @BeforeClass + public static void setUpClass() throws Exception { + runner = new SuiviObsmerRunnerTest(); + } + + @AfterClass + public static void tearDownClass() throws Exception { + } + + @Before + public void setUp() throws Exception { + runner.start(); + service = new ServiceSynthesisImpl(); + } + + @After + public void tearDown() throws Exception { + runner.stop(); + } + + /** + * Test of getDataSampling method, of class ServiceSynthesisImpl. + */ + //@Test + public void testGetDataSampling() throws Exception { + System.out.println("getDataSampling"); + } + + /** + * Test of getBoardingBoats method, of class ServiceSynthesisImpl. + */ + @Test + public void testGetBoardingBoats() throws Exception { + System.out.println("getBoardingBoats"); + /** PREPARE DATA **/ + InputStream input = getClass().getResourceAsStream("/import/navires.csv"); + ServiceBoat serviceBoat = new ServiceBoatImpl(); + serviceBoat.importBoatCsv(input); + List<Boat> boats = serviceBoat.getBoatsByImmatriculations("174258"); + Boat boat = boats.get(0); + + List<Boat> boats2 = serviceBoat.getBoatsByImmatriculations("177474"); + Boat boat2 = boats2.get(0); + + TopiaContext transaction = SuiviObsmerContext.getTopiaRootContext().beginTransaction(); + + CompanyDAO companyDAO = SuiviObsmerModelDAOHelper.getCompanyDAO(transaction); + Company company = companyDAO.create(Company.NAME, "TARTANPION"); + Company company2 = companyDAO.create(Company.NAME, "BIS"); + + WaoUserDAO userDAO = SuiviObsmerModelDAOHelper.getWaoUserDAO(transaction); + WaoUser user = userDAO.create(WaoUser.FIRST_NAME,"Jean", WaoUser.LAST_NAME, "Michmuche", + WaoUser.COMPANY, company); + company.addWaoUser(user); + WaoUser user2 = userDAO.create(WaoUser.FIRST_NAME,"Bill", WaoUser.LAST_NAME, "Murray", + WaoUser.COMPANY, company2); + company2.addWaoUser(user2); + + transaction.commitTransaction(); + + input = getClass().getResourceAsStream("/import/zonesPeche.csv"); + ServiceReferential serviceReferential = new ServiceReferentialImpl(); + serviceReferential.importFishingZoneCsv(input); + + input = getClass().getResourceAsStream("/import/echantillonnage.csv"); + ServiceSampling serviceSampling = new ServiceSamplingImpl(); + serviceSampling.importSamplingPlanCsv(input); + + SampleRowDAO rowDAO = SuiviObsmerModelDAOHelper.getSampleRowDAO(transaction); + SampleRow row = rowDAO.findByCode("2010_0001"); + + transaction.closeContext(); + + + ServiceContact serviceContact = new ServiceContactImpl(); + // First contact : OK + Contact contact1 = new ContactImpl(); + contact1.setBoat(boat); + contact1.setObserver(user); + contact1.setSampleRow(row); + contact1.setState(ContactState.BOARDING_DONE.toString()); + Date begin = DateUtils.createDate(3, 3, 2009); + contact1.setTideBeginDate(begin); + contact1.setValidationCompany(Boolean.TRUE); + serviceContact.saveContact(contact1, false); + + Contact contact2 = new ContactImpl(); + contact2.setBoat(boat); + contact2.setObserver(user); + contact2.setSampleRow(row); + contact2.setState(ContactState.BOARDING_DONE.toString()); + begin = DateUtils.createDate(3, 3, 2009); + contact2.setTideBeginDate(begin); + contact2.setValidationCompany(Boolean.TRUE); + serviceContact.saveContact(contact2, false); + + Contact contact3 = new ContactImpl(); + contact3.setBoat(boat2); + contact3.setObserver(user); + contact3.setSampleRow(row); + contact3.setState(ContactState.BOARDING_DONE.toString()); + begin = DateUtils.createDate(3, 3, 2009); + contact3.setTideBeginDate(begin); + contact3.setValidationCompany(Boolean.TRUE); + serviceContact.saveContact(contact3, false); + + BoardingResult result = service.getBoardingBoats(null, null); + // one boat with one boarding (177474) + assertEquals(1, result.getData().get("1").intValue()); + // one boat with two boardings (174258) + assertEquals(1, result.getData().get("2").intValue()); + assertEquals(2, result.getMaxBoardingValue()); + assertEquals(174258, result.getMaxBoardingBoat().getImmatriculation()); + } + +} \ No newline at end of file Property changes on: trunk/suiviobsmer-business/src/test/java/fr/ifremer/suiviobsmer/impl/ServiceSynthesisImplTest.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL" Modified: trunk/suiviobsmer-ui/src/main/java/fr/ifremer/suiviobsmer/ui/pages/Synthesis.java =================================================================== --- trunk/suiviobsmer-ui/src/main/java/fr/ifremer/suiviobsmer/ui/pages/Synthesis.java 2010-02-02 21:01:46 UTC (rev 316) +++ trunk/suiviobsmer-ui/src/main/java/fr/ifremer/suiviobsmer/ui/pages/Synthesis.java 2010-02-02 23:48:45 UTC (rev 317) @@ -22,9 +22,9 @@ package fr.ifremer.suiviobsmer.ui.pages; import fr.ifremer.suiviobsmer.SuiviObsmerException; +import fr.ifremer.suiviobsmer.bean.BoardingResult; import fr.ifremer.suiviobsmer.bean.BoatFilter; import fr.ifremer.suiviobsmer.bean.BoatFilterImpl; -import fr.ifremer.suiviobsmer.entity.Boat; import fr.ifremer.suiviobsmer.entity.WaoUser; import fr.ifremer.suiviobsmer.services.ServiceSynthesis; import fr.ifremer.suiviobsmer.ui.base.AbstractFilteredPage; @@ -176,26 +176,13 @@ /********************* STATIC GRAPH : BOARDINGBOAT ************************/ - @Property - private Boat maxBoat; + private BoardingResult boardingResult; public JFreeChart getBoardingBoatsChart() throws SuiviObsmerException { - if (log.isInfoEnabled()) { - log.info("BUSINESS REQUEST [getBoardingBoats]"); - } - //Company company = user.getAdmin() ? null : user.getCompany(); - //Date fromDate = DateUtils.createDateAfterToday(0, -12, 0); - Map<String, Integer> result = - serviceSynthesis.getBoardingBoats( - getFilter().getCompany(), - getFromDate()); - Map<String, Map<?, Integer>> data = new HashMap<String, Map<?, Integer>>(); - data.put("Navires", result); + data.put("Navires", getBoardingResult().getData()); - //maxBoat = result.getSecond(); - String title = "Sollicitations des navires depuis le " + getDateFormat().format(getFromDate()); @@ -203,6 +190,17 @@ "Nb embarquements", ChartType.BAR, data); } + public BoardingResult getBoardingResult() throws SuiviObsmerException { + if (boardingResult == null) { + if (log.isInfoEnabled()) { + log.info("BUSINESS REQUEST [getBoardingBoats]"); + } + boardingResult = serviceSynthesis.getBoardingBoats( + getFilter().getCompany(), getFromDate()); + } + return boardingResult; + } + public Date getFromDate() { return DateUtils.createDateAfterToday(0, -12, 0); } Modified: trunk/suiviobsmer-ui/src/main/webapp/Synthesis.tml =================================================================== --- trunk/suiviobsmer-ui/src/main/webapp/Synthesis.tml 2010-02-02 21:01:46 UTC (rev 316) +++ trunk/suiviobsmer-ui/src/main/webapp/Synthesis.tml 2010-02-02 23:48:45 UTC (rev 317) @@ -108,6 +108,11 @@ </div> <div class="acenter"> <t:chart t:width="600" t:height="400" t:chart="boardingBoatsChart" /> - <!--<p>Navire le plus sollicité avec ${maxBoat.getNbBoarding(fromDate)} : ${maxBoat.name}</p>--> + <t:if t:test="boardingResult.maxBoardingBoat"> + <p> + Navire le plus sollicité avec ${boardingResult.maxBoardingValue} : + ${boardingResult.maxBoardingBoat.name} (${boardingResult.maxBoardingBoat.immatriculation}) + </p> + </t:if> </div> </t:layout>