Author: tchemit Date: 2014-04-07 19:44:45 +0200 (Mon, 07 Apr 2014) New Revision: 1861 Url: http://forge.codelutin.com/projects/wao/repository/revisions/1861 Log: refs #4487 recompute sample rows tides when contact is modified or created Removed: trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ContactStatus.java trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/NullSampleMonthException.java Modified: trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerContactsService.java trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSamplingPlanService.java Deleted: trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ContactStatus.java =================================================================== --- trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ContactStatus.java 2014-04-07 17:13:57 UTC (rev 1860) +++ trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ContactStatus.java 2014-04-07 17:44:45 UTC (rev 1861) @@ -1,350 +0,0 @@ -/* - * #%L - * Wao :: Business - * * - * $Id$ - * $HeadURL: https://svn.codelutin.com/wao/tags/wao-3.4.1/wao-business/src/main/java/fr/i... $ - * %% - * Copyright (C) 2009 - 2010 Ifremer - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ - -package fr.ifremer.wao.services.service; - -import fr.ifremer.wao.entity.Contact; -import fr.ifremer.wao.entity.ContactState; -import fr.ifremer.wao.entity.SampleMonth; -import fr.ifremer.wao.entity.SampleMonthTopiaDao; -import fr.ifremer.wao.entity.SampleRow; -import org.apache.commons.lang3.BooleanUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.nuiton.topia.persistence.TopiaNoResultException; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; - -/** - * //FIXME a revoir... - * This class is used to know status changed between an old contact and a new - * one (new change to apply). There is three different cases for constructor - * parameters : - * <ul> - * <li>CREATE : olContact is null and newContact is defined</li> - * <li>UPDATE : both oldContact and newContact are defined</li> - * <li>DELETE : oldContact is defined and newContact is null</li> - * </ul> - * Three fields of contact are considered to be changed for sampleMonth calcul - * on tides value : - * <ul> - * <li> - * STATE : check the change on {@link ContactState#OBSERVATION_DONE} state. - * Use {@link #isContactDoneChanged() } method to check the change. - * This change is important to manage estimated tides value on sampleMonth - * referenced by the contact retrieve with {@link #getSampleMonth()} - * </li> - * <li> - * VALIDATION : check the change on validationCompany and validationProgram. - * Use {@link #isContactValidateChanged() } method to check the change. - * This change is important to manage real tides value on sampleMonth - * referenced by the contact retrieve with {@link #getSampleMonth()} - * </li> - * <li> - * TIDE BEGIN DATE : check the change on tideBeginDate month. - * Use {@link #isTideBeginDateMonthChanged() } method to check the change. - * This change is important to manage both estimated and real tides value on - * the old sampleMonth referenced by the old contact retrieve with - * {@link #getOldSampleMonth()} - * </ul> - * <p/> - * <p/> - * Created: 19 avr. 2010 - * - * @author fdesbois - */ -public class ContactStatus { - - /** Logger. */ - private static final Log logger = LogFactory.getLog(ContactStatus.class); - - protected Contact oldContact; - - protected Contact newContact; - - protected SampleRow sampleRow; - - protected SampleMonth oldSampleMonth; - - protected SampleMonth sampleMonth; - - protected final SampleMonthTopiaDao dao; - - public ContactStatus(SampleMonthTopiaDao dao, - Contact old, - Contact contact) { - this.dao = dao; - this.oldContact = old; - this.newContact = contact; - this.sampleRow = contact != null ? - newContact.getSampleRow() : oldContact.getSampleRow(); - } - - public boolean isOldContactValidate() { - return isContactValidate(Context.OLD); - } - - public boolean isNewContactValidate() { - return isContactValidate(Context.NEW); - } - - /** - * Return true if oldContact validate is not the same as newContact - * validate. - * - * @return true if contact validate has changed. - * @see #isContactValidate(Context) - */ - public boolean isContactValidateChanged() { - return isOldContactValidate() != isNewContactValidate(); - } - - public boolean isOldContactDone() { - return isContactDone(Context.OLD); - } - - public boolean isNewContactDone() { - return isContactDone(Context.NEW); - } - - /** - * Return true if oldContact state is not the same as newContact state. - * Check only for {@link ContactState#OBSERVATION_DONE} changed. - * - * @return true if contact state has changed. - * @see #isContactDone(Context) - */ - public boolean isContactDoneChanged() { - return isOldContactDone() != isNewContactDone(); - } - - /** - * Return true if tideBeginDate has changed its month between oldContact - * and newContact. The both oldContact and newContact dates must be not - * null. - * - * @return true if tideBeginDate status changed - */ - public boolean isTideBeginDateMonthChanged() { - - if (oldContact == null || newContact == null) { - return false; - } - DateFormat dateFormat = new SimpleDateFormat("MM/yyyy"); - Date oldTideBeginDate = oldContact.getObservationBeginDate(); - Date newTideBeginDate = newContact.getObservationBeginDate(); - - logger.debug("old : " + oldTideBeginDate + ", new : " + newTideBeginDate); - - // Only if old not null and new not null - if (oldTideBeginDate != null && newTideBeginDate != null) { - String oldTideBeginStr = dateFormat.format(oldTideBeginDate); - String newTideBeginStr = dateFormat.format(newTideBeginDate); - return !oldTideBeginStr.equals(newTideBeginStr); - } - return false; - } - - public SampleRow getSampleRow() { - return sampleRow; - } - - /** - * Retrive the old SampleMonth referenced by the tideBeginDate of the - * old contact. - * - * @return the sampleMonth found or throw NullSampleMonthException - * @throws NullSampleMonthException - */ - public SampleMonth getOldSampleMonth() - throws NullSampleMonthException { - if (oldSampleMonth == null) { - oldSampleMonth = getExistingSampleMonth(Context.OLD); - } - return oldSampleMonth; - } - - /** - * Retrive the SampleMonth referenced by the tideBeginDate of the - * new contact. - * - * @return the sampleMonth found or throw NullSampleMonthException - * @throws NullSampleMonthException - */ - public SampleMonth getSampleMonth() - throws NullSampleMonthException { - if (sampleMonth == null) { - sampleMonth = getExistingSampleMonth(Context.NEW); - } - return sampleMonth; - } - - protected enum Context { - OLD, NEW - } - - /** - * Retrieve existing sampleMonth corresponding to the contact. The - * sampleMonth must match with contact sampleRow, also the tideBeginDate - * (day) of the contact must match the sampleMonth periodDate (month). - * - * @param context OLD or NEW - * @return the sampleMonth found if exists, or NullSampleMonthException - * will be thrown - * @throws NullSampleMonthException if month was not found - */ - protected SampleMonth getExistingSampleMonth(Context context) throws NullSampleMonthException { - - // Reference date for query - Date tideBeginDate = null; - - switch (context) { - case OLD: - tideBeginDate = oldContact.getObservationBeginDate(); - break; - // newContact may be null in CREATE case, so we use the previous - // one - case NEW: - if (newContact != null && - newContact.getObservationBeginDate() != null) { - tideBeginDate = newContact.getObservationBeginDate(); - } else { - tideBeginDate = oldContact.getObservationBeginDate(); - } - } - - SampleMonth result; - try { - result = dao.getExistingSampleMonth(sampleRow, tideBeginDate); - } catch (TopiaNoResultException e) { - throw new NullSampleMonthException( - "Aucun mois correspondant pour" + - " la ligne du plan d'échantillonnage " + - sampleRow.getCode() + - " et la date de début de marée du contact " + - tideBeginDate - ); - } - return result; - } - - /** - * Return true if contact is validate depends on {@code context}. The - * oldContact validation will be tested for an {@link Context#OLD} context - * and the newContact will be tested for a {@link Context#NEW} context. - * The validation is tested as validationCompany must be TRUE and - * validationProgram must be not FALSE (otherwise TRUE or NULL). - * - * @param context to check the good contact - * @return true depends on validationCompany and validationProgram of - * the contact (oldContact or newContact depends on context in argument). - */ - protected boolean isContactValidate(Context context) { - Contact contact = context == Context.OLD ? oldContact : newContact; - - Boolean validationCompany = contact != null ? - contact.getValidationCompany() : null; - Boolean validationProgram = contact != null ? - contact.getValidationProgram() : null; - - if (logger.isTraceEnabled()) { - logger.trace(context + " validation company = " + validationCompany - + " _ validation program = " + validationProgram); - } - - boolean contactValidate = - BooleanUtils.isTrue(validationCompany) && - BooleanUtils.isNotFalse(validationProgram); - return contactValidate; - } - - public boolean isRefused() { - Boolean oldValidationProgram = oldContact != null ? - oldContact.getValidationProgram() : null; - Boolean newValidationProgram = newContact != null ? - newContact.getValidationProgram() : null; - - return BooleanUtils.isNotFalse(oldValidationProgram) && - BooleanUtils.isFalse(newValidationProgram); - } - - public boolean isNoMoreRefused() { - Boolean oldValidationProgram = oldContact != null ? - oldContact.getValidationProgram() : null; - Boolean newValidationProgram = newContact != null ? - newContact.getValidationProgram() : null; - - return BooleanUtils.isFalse(oldValidationProgram) && - BooleanUtils.isNotFalse(newValidationProgram); - } - - /** - * Return true if contact state is {@link ContactState#OBSERVATION_DONE} - * depends on {@code context}. To check oldContact state, use - * {@link Context#OLD} and to check newContact state, use - * {@link Context#NEW}. A null contact will return false. - * - * @param context to check the good contact - * @return true if the contact state is {@link ContactState#OBSERVATION_DONE} - */ - protected boolean isContactDone(Context context) { - Contact contact = context == Context.OLD ? oldContact : newContact; - ContactState contactState = contact != null ? - contact.getContactState() : null; - - if (logger.isTraceEnabled()) { - logger.trace(context + " contact state = " + contactState); - } - boolean contactDone = ContactState.OBSERVATION_DONE.equals(contactState); - return contactDone; - } - - @Override - public String toString() { - DateFormat dateFormat = new SimpleDateFormat("MM/yyyy"); - String oldMonth = oldContact != null && - oldContact.getObservationBeginDate() != null ? - dateFormat.format(oldContact.getObservationBeginDate()) : ""; - - String newMonth = newContact != null && - newContact.getObservationBeginDate() != null ? - dateFormat.format(newContact.getObservationBeginDate()) : ""; - - StringBuilder builder = - new StringBuilder("\nContactStatus : VALIDATE :: "). - append("oldValidate = ").append(isOldContactValidate()). - append(" _ newValidate = ").append(isNewContactValidate()). - append("\nContactStatus : CONTACT_STATE :: "). - append("oldDone = ").append(isOldContactDone()). - append(" _ newDone = ").append(isNewContactDone()). - append("\nContactStatus : TIDE_BEGIN_DATE :: "). - append("oldMonth = ").append(oldMonth). - append(" _ newMonth = ").append(newMonth). - append(" _ changed = ").append(isTideBeginDateMonthChanged()); - - return builder.toString(); - } -} Deleted: trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/NullSampleMonthException.java =================================================================== --- trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/NullSampleMonthException.java 2014-04-07 17:13:57 UTC (rev 1860) +++ trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/NullSampleMonthException.java 2014-04-07 17:44:45 UTC (rev 1861) @@ -1,37 +0,0 @@ -package fr.ifremer.wao.services.service; - -/* - * #%L - * Wao :: Services - * %% - * Copyright (C) 2009 - 2014 Ifremer - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ - -import fr.ifremer.wao.WaoException; - -/** - * This exception is used to indicate that a problem is occured during - * retrieving sampleMonth corresponding to a contact. - */ -public final class NullSampleMonthException extends WaoException { - - private static final long serialVersionUID = 1L; - - public NullSampleMonthException(String message) { - super(message); - } -} Modified: trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerContactsService.java =================================================================== --- trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerContactsService.java 2014-04-07 17:13:57 UTC (rev 1860) +++ trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerContactsService.java 2014-04-07 17:44:45 UTC (rev 1861) @@ -41,7 +41,6 @@ import fr.ifremer.wao.entity.ObsProgram; import fr.ifremer.wao.entity.ObservedDataControl; import fr.ifremer.wao.entity.SampleMonth; -import fr.ifremer.wao.entity.SampleMonths; import fr.ifremer.wao.entity.SampleRow; import fr.ifremer.wao.entity.WaoUser; import fr.ifremer.wao.entity.WaoUserTopiaDao; @@ -402,8 +401,6 @@ // Pass validation controls Contact contact = updateContactCommand.getContact(); - Locale l = serviceContext.getLocale(); - Company company = contact.getSampleRow().getCompany(); WaoUser mainObserver = contact.getMainObserver(); @@ -625,9 +622,10 @@ throw new IllegalDeletionException(allUsages); } - //FIXME -// updateSampleMonthTidesValue(contact, null, true); + ObsMerSamplingPlanService samplingPlanService = newService(ObsMerSamplingPlanService.class); + samplingPlanService.recomputeSampleRowEstimatedAndRealTides(contact.getSampleRow()); + dao.delete(contact); commit(); @@ -640,6 +638,8 @@ ContactTopiaDao dao = getContactDao(); + ObsMerSamplingPlanService samplingPlanService = newService(ObsMerSamplingPlanService.class); + if (updateContactCommand.isCreation()) { //Update the elligible boat depends on contact creation. The @@ -659,19 +659,17 @@ } elligible.setCompanyActive(Boolean.TRUE); - //FIXME Recompute for the hole sample row? -// updateSampleMonthTidesValue(null, contact, true); - if (contact.getCreationDate() == null) { contact.setCreationDate(serviceContext.getNow()); } + samplingPlanService.recomputeSampleRowEstimatedAndRealTides(contact.getSampleRow()); + dao.create(contact); } else { - //FIXME Recompute for the hole sample row? -// updateSampleMonthTidesValue(contactFound, contact, true); + samplingPlanService.recomputeSampleRowEstimatedAndRealTides(contact.getSampleRow()); if (updateContactCommand.isMammalsInfosChanged()) { @@ -689,133 +687,8 @@ getEmailService().send(email); } + dao.update(contact); } } - - /** - * 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#OBSERVATION_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. Three cases : - * <ul> - * <li>CREATE : {@code oldContact} = null and {@code contact} is defined</li> - * <li>UPDATE : both {@code oldContact} and {@code contact} are defined</li> - * <li>DELETE : {@code oldContact} is defined and {@code contact} = null</li> - * </ul> - * <p> - * <strong>Estimated Tides value</strong> = nbContacts with OBSERVATION_DONE - * state and not refused by program (validationProgram != FALSE) - * </p> - * <p> - * <strong>Real Tides value</strong> = nbContacts accepted by company - * (validationCompany = TRUE) and not refused by program - * (validationProgram != FALSE) - * </p> - * - * @param oldContact old state of the contact - * @param contact changed can be null for delete case - * @param calculateReal to calculate real tides value - * @throws NullSampleMonthException if SampleMonth can't be found - */ - protected void updateSampleMonthTidesValue(Contact oldContact, - Contact contact, - boolean calculateReal) throws NullSampleMonthException { - - if (oldContact == null && contact == null) { - throw new IllegalArgumentException("Both contact and oldContact" + - " can't be null to update sampleMonth tides value"); - } - - // Instantiate contact status which provide status on oldContact and - // contact changes - ContactStatus status = new ContactStatus(getSampleMonthDao(), oldContact, contact); - - if (log.isDebugEnabled()) { - log.debug(status.toString()); - } - - // Month of TideBeginDate has changed, must decrement values on - // old sampleMonth - boolean tideBeginDateChanged = false; - if (oldContact != null && contact != null && - status.isTideBeginDateMonthChanged()) { - - tideBeginDateChanged = status.isTideBeginDateMonthChanged(); - - // Retrieve oldMonth from status - try { - SampleMonth oldMonth = status.getOldSampleMonth(); - - // Apply changes on oldMonth - if (status.isOldContactValidate()) { - // decrement real tides - SampleMonths.addRealTideTime(oldMonth, -1); - } - // Decrement estimated only if old state is OBSERVATION_DONE - // and old validationProgram is NOT FALSE - // the estimated value has already been decremented during - // refused - if (status.isOldContactDone() && BooleanUtils.isNotFalse( - oldContact.getValidationProgram())) { - // decrement estimated tides - SampleMonths.addEstimatedTideTime(oldMonth, -1); - } - - // Catch the null exception, only a warning if the oldSampleMonth is - // not found - } catch (NullSampleMonthException eee) { - if (log.isWarnEnabled()) { - log.warn("Error on retrieve old sampleMonth", eee); - } - } - } - - ContactState currentState = contact != null ? - contact.getContactState() : oldContact.getContactState(); - - // Validation of contact has changed in status, modify realTides - // Only calculate real for a currentState equals to OBSERVATION_DONE - if (calculateReal && ContactState.OBSERVATION_DONE.equals(currentState) && - (status.isContactValidateChanged() || tideBeginDateChanged)) { - - SampleMonth sampleMonth = status.getSampleMonth(); - - if (status.isNewContactValidate()) { - // increment real tides - SampleMonths.addRealTideTime(sampleMonth, 1); - // validationProgram becomes not FALSE, estimatedTides must be - // incremented - if (status.isNoMoreRefused()) { - SampleMonths.addEstimatedTideTime(sampleMonth, 1); - } - // never decrement if tideBeginDate has changed - } else if (status.isOldContactValidate() && !tideBeginDateChanged) { - // decrement real tides - SampleMonths.addRealTideTime(sampleMonth, -1); - // validationProgram becomes FALSE, estimatedTides must be - // decremented - if (status.isRefused()) { - SampleMonths.addEstimatedTideTime(sampleMonth, -1); - } - } - } - - // ContactState of contact has changed in status, modify estimatedTides - if (status.isContactDoneChanged() || tideBeginDateChanged) { - - SampleMonth sampleMonth = status.getSampleMonth(); - - if (status.isNewContactDone()) { - // increment estimated tides - SampleMonths.addEstimatedTideTime(sampleMonth, 1); - // never decrement if tideBeginDate has changed - } else if (status.isOldContactDone() && !tideBeginDateChanged) { - // decrement estimated tides - SampleMonths.addEstimatedTideTime(sampleMonth, -1); - } - } - } } Modified: trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSamplingPlanService.java =================================================================== --- trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSamplingPlanService.java 2014-04-07 17:13:57 UTC (rev 1860) +++ trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSamplingPlanService.java 2014-04-07 17:44:45 UTC (rev 1861) @@ -702,4 +702,55 @@ commit(); } + + public void recomputeSampleRowEstimatedAndRealTides(SampleRow sampleRow) { + + //---- + // Reset des tides de la ligne + //---- + + for (SampleMonth sampleMonth : sampleRow.getSampleMonth()) { + sampleMonth.setEstimatedTidesValue(0); + sampleMonth.setRealTidesValue(0); + } + + //---- + // Recuperation de tous les contacts de la ligne + //---- + + ContactsFilter contactFilter = new ContactsFilter(sampleRow.getObsProgram()); + + contactFilter.setFilterOnObservationBeginDate(true); + contactFilter.getSampleRowFilter().setSampleRowIds(Sets.newHashSet(sampleRow.getTopiaId())); + + contactFilter.setContactStates(ImmutableSet.of(ContactState.OBSERVATION_DONE)); + // on exclue les contacts qui sont invalidés par le programme + contactFilter.setProgramAcceptations(Sets.newHashSet(true, null)); + // on exclue les contacts invalidés par la société + contactFilter.setCompanyAcceptations(Sets.newHashSet(true, null)); + + Collection<Contact> contacts = getContactDao().findAll(contactFilter); + + //---- + // Recalcul des tides + //---- + + for (Contact contact : contacts) { + + Boolean validationProgram = contact.getValidationProgram(); + Boolean validationCompany = contact.getValidationCompany(); + + boolean accepted = validationCompany != null || validationProgram != null; + + Date observationBeginDate = contact.getObservationBeginDate(); + + SampleMonth month = sampleRow.getSampleMonth(observationBeginDate); + + if (accepted) { + month.setRealTidesValue(month.getRealTidesValue() + 1); + } else { + month.setEstimatedTidesValue(month.getEstimatedTidesValue() + 1); + } + } + } }