View Javadoc
1   package fr.ifremer.tutti.ui.swing.content.operation.fishing.actions;
2   
3   /*
4    * #%L
5    * Tutti :: UI
6    * %%
7    * Copyright (C) 2012 - 2014 Ifremer
8    * %%
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU General Public License as
11   * published by the Free Software Foundation, either version 3 of the 
12   * License, or (at your option) any later version.
13   * 
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Public License for more details.
18   * 
19   * You should have received a copy of the GNU General Public 
20   * License along with this program.  If not, see
21   * <http://www.gnu.org/licenses/gpl-3.0.html>.
22   * #L%
23   */
24  
25  import com.google.common.collect.Lists;
26  import com.google.common.collect.Sets;
27  import fr.ifremer.tutti.persistence.InvalidBatchModelException;
28  import fr.ifremer.tutti.persistence.ProgressionModel;
29  import fr.ifremer.tutti.persistence.entities.CaracteristicMap;
30  import fr.ifremer.tutti.persistence.entities.TuttiEntities;
31  import fr.ifremer.tutti.persistence.entities.data.Attachment;
32  import fr.ifremer.tutti.persistence.entities.data.CatchBatch;
33  import fr.ifremer.tutti.persistence.entities.data.CatchBatchs;
34  import fr.ifremer.tutti.persistence.entities.data.Cruise;
35  import fr.ifremer.tutti.persistence.entities.data.FishingOperation;
36  import fr.ifremer.tutti.persistence.entities.data.FishingOperations;
37  import fr.ifremer.tutti.persistence.entities.referential.Gear;
38  import fr.ifremer.tutti.persistence.entities.referential.GearWithOriginalRankOrders;
39  import fr.ifremer.tutti.persistence.entities.referential.Person;
40  import fr.ifremer.tutti.persistence.entities.referential.TuttiLocation;
41  import fr.ifremer.tutti.persistence.entities.referential.Vessel;
42  import fr.ifremer.tutti.service.PersistenceService;
43  import fr.ifremer.tutti.ui.swing.content.operation.EditFishingOperationUI;
44  import fr.ifremer.tutti.ui.swing.content.operation.EditFishingOperationUIHandler;
45  import fr.ifremer.tutti.ui.swing.content.operation.EditFishingOperationUIModel;
46  import fr.ifremer.tutti.ui.swing.content.operation.FishingOperationsUI;
47  import fr.ifremer.tutti.ui.swing.content.operation.FishingOperationsUIHandler;
48  import fr.ifremer.tutti.ui.swing.content.operation.FishingOperationsUIModel;
49  import fr.ifremer.tutti.ui.swing.content.operation.SecondaryVesselTypeEnum;
50  import fr.ifremer.tutti.ui.swing.content.operation.catches.EditCatchesUI;
51  import fr.ifremer.tutti.ui.swing.content.operation.catches.EditCatchesUIModel;
52  import fr.ifremer.tutti.ui.swing.content.operation.catches.actions.SaveCatchBatchAction;
53  import fr.ifremer.tutti.ui.swing.content.operation.catches.species.EditSpeciesBatchPanelUI;
54  import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUI;
55  import fr.ifremer.tutti.ui.swing.content.operation.fishing.GearUseFeatureTabUI;
56  import fr.ifremer.tutti.ui.swing.content.operation.fishing.VesselUseFeatureTabUI;
57  import fr.ifremer.tutti.ui.swing.util.TuttiBeanMonitor;
58  import fr.ifremer.tutti.ui.swing.util.actions.LongActionSupport;
59  import org.apache.commons.collections4.CollectionUtils;
60  import org.apache.commons.logging.Log;
61  import org.apache.commons.logging.LogFactory;
62  
63  import javax.swing.JComponent;
64  import javax.swing.JLabel;
65  import javax.swing.JOptionPane;
66  import javax.swing.JTabbedPane;
67  import javax.swing.SwingUtilities;
68  import java.awt.BorderLayout;
69  import java.beans.PropertyChangeEvent;
70  import java.beans.PropertyChangeListener;
71  import java.util.Collections;
72  import java.util.List;
73  import java.util.Set;
74  
75  import static org.nuiton.i18n.I18n.t;
76  
77  /**
78   * To edit the given fishing operation.
79   *
80   * @author Tony Chemit - chemit@codelutin.com
81   * @since 1.0
82   */
83  public class EditFishingOperationAction extends LongActionSupport<FishingOperationsUIModel, FishingOperationsUI, FishingOperationsUIHandler> {
84  
85      /** Logger. */
86      private static final Log log = LogFactory.getLog(EditFishingOperationAction.class);
87  
88      /**
89       * The incoming fishing operation to edit.
90       *
91       * Can be null (means do not edit any fishing operation), or with no id
92       * (means create a ne fishing operation), or with an id (means edit an
93       * existing fishing operation).
94       *
95       * @since 1.0
96       */
97      protected FishingOperation fishingOperation;
98  
99      /**
100      * A flag to not check if there is a previous edit.
101      *
102      * This flag is used when we launch the cancel action.
103      *
104      * @since 1.0
105      */
106     protected boolean checkPreviousEdit = true;
107 
108     /**
109      * Delegate action to save Fising Operation.
110      *
111      * @since 1.0
112      */
113     protected SaveFishingOperationAction saveFishingOperationAction;
114 
115 //    /**
116 //     * Delegate action to compute the weight of the operations.
117 //     *
118 //     * @since 1.1
119 //     */
120 //    protected ComputeBatchWeightsAction computeBatchWeightsAction;
121 
122     /**
123      * Delegate action to save catch batch.
124      *
125      * @since 1.0
126      */
127     protected SaveCatchBatchAction saveCatchBatchAction;
128 
129     /**
130      * To keep catch validation error while loading batches.
131      *
132      * @since 2.4
133      */
134     protected final List<String> errorMessages = Lists.newArrayList();
135 
136     /**
137      * Flag to know if this action is part of another action.
138      *
139      * @since 2.4
140      */
141     protected boolean internalAction;
142 
143     /**
144      * To recompute distance when coordinate change.
145      *
146      * @since 2.4
147      */
148     private final PropertyChangeListener coordinatePropertiesListener = new PropertyChangeListener() {
149 
150         private List<String> properties = Lists.newArrayList(
151                 EditFishingOperationUIModel.PROPERTY_FISHING_OPERATION_RECTILIGNE,
152                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_END_LATITUDE,
153                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_END_LATITUDE_DMS_SIGN,
154                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_END_LATITUDE_DMS_DEGREE,
155                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_END_LATITUDE_DMS_MINUTE,
156                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_END_LATITUDE_DMS_SECOND,
157                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_END_LATITUDE_DMD_SIGN,
158                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_END_LATITUDE_DMD_DEGREE,
159                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_END_LATITUDE_DMD_MINUTE,
160                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_END_LONGITUDE,
161                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_END_LONGITUDE_DMS_SIGN,
162                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_END_LONGITUDE_DMS_DEGREE,
163                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_END_LONGITUDE_DMS_MINUTE,
164                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_END_LONGITUDE_DMS_SECOND,
165                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_END_LONGITUDE_DMD_SIGN,
166                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_END_LONGITUDE_DMD_DEGREE,
167                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_END_LONGITUDE_DMD_MINUTE,
168                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_START_LATITUDE,
169                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_START_LATITUDE_DMS_SIGN,
170                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_START_LATITUDE_DMS_DEGREE,
171                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_START_LATITUDE_DMS_MINUTE,
172                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_START_LATITUDE_DMS_SECOND,
173                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_START_LATITUDE_DMD_SIGN,
174                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_START_LATITUDE_DMD_DEGREE,
175                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_START_LATITUDE_DMD_MINUTE,
176                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_START_LONGITUDE,
177                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_START_LONGITUDE_DMS_SIGN,
178                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_START_LONGITUDE_DMS_DEGREE,
179                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_START_LONGITUDE_DMS_MINUTE,
180                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_START_LONGITUDE_DMS_SECOND,
181                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_START_LONGITUDE_DMD_SIGN,
182                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_START_LONGITUDE_DMD_DEGREE,
183                 EditFishingOperationUIModel.PROPERTY_GEAR_SHOOTING_START_LONGITUDE_DMD_MINUTE
184         );
185 
186         @Override
187         public void propertyChange(PropertyChangeEvent evt) {
188             if (properties.contains(evt.getPropertyName())) {
189                 EditFishingOperationUIModel source = (EditFishingOperationUIModel) evt.getSource();
190                 if (source.isFishingOperationRectiligne()) {
191                     source.computeDistance();
192                 }
193             }
194         }
195     };
196 
197     public EditFishingOperationAction(FishingOperationsUIHandler handler) {
198         super(handler, true);
199         setActionDescription(t("tutti.editFishingOperation.action.editFishingOperation.tip"));
200     }
201 
202     public void setFishingOperation(FishingOperation fishingOperation) {
203         this.fishingOperation = fishingOperation;
204         getDataContext().setFishingOperationId(fishingOperation != null ? fishingOperation.getIdAsInt() : null);
205     }
206 
207     public void setCheckPreviousEdit(boolean checkPreviousEdit) {
208         this.checkPreviousEdit = checkPreviousEdit;
209     }
210 
211     @Override
212     public void releaseAction() {
213         fishingOperation = null;
214         checkPreviousEdit = true;
215         internalAction = false;
216         super.releaseAction();
217     }
218 
219     protected SaveFishingOperationAction getSaveFishingOperationAction() {
220         if (saveFishingOperationAction == null) {
221             saveFishingOperationAction = new SaveFishingOperationAction(getUI().getFishingOperationTabContent().getHandler());
222         }
223         return saveFishingOperationAction;
224     }
225 
226     protected SaveCatchBatchAction getSaveCatchBatchAction() {
227         if (saveCatchBatchAction == null) {
228             saveCatchBatchAction = new SaveCatchBatchAction(getUI().getCatchesTabContent().getHandler());
229         }
230         return saveCatchBatchAction;
231     }
232 
233 //    protected ComputeBatchWeightsAction getComputeBatchWeightsAction() {
234 //        if (computeBatchWeightsAction == null) {
235 //            computeBatchWeightsAction = new ComputeBatchWeightsAction(getUI().getCatchesTabContent().getHandler());
236 //        }
237 //        return computeBatchWeightsAction;
238 //    }
239 
240     @Override
241     public boolean prepareAction() {
242 
243         errorMessages.clear();
244 
245         boolean canContinue = true;
246         if (checkPreviousEdit) {
247             FishingOperationsUI ui = getUI();
248 
249             final FishingOperationsUIModel model = ui.getModel();
250 
251             FishingOperation editFishingOperation = model.getEditFishingOperation();
252 
253             String editFishingOperationId = null;
254 
255             if (editFishingOperation == null) {
256 
257                 // no previous fishing operation in edition, can continue
258                 canContinue = true;
259             } else {
260 
261                 editFishingOperationId = editFishingOperation.getId();
262 
263                 boolean create = TuttiEntities.isNew(editFishingOperation);
264 
265                 boolean fishingOperationModified = getHandler().isFishingOperationModified();
266                 boolean catchBatchModified = getHandler().isCatchBatchModified();
267 
268                 boolean fishingOperationValid = getHandler().isFishingOperationValid();
269                 boolean catchBatchValid = getHandler().isCatchBatchValid();
270 
271                 boolean needSave = create || fishingOperationModified || catchBatchModified;
272 
273 
274                 if (needSave) {
275 
276                     boolean canSave = fishingOperationValid && catchBatchValid;
277 
278                     canContinue = false;
279 
280                     if (canSave) {
281 
282                         String message;
283 
284                         if (create) {
285                             message = t("tutti.editFishingOperation.askSaveBeforeLeaving.createFishingOperation");
286                         } else if (fishingOperationModified) {
287                             message = t("tutti.editFishingOperation.askSaveBeforeLeaving.saveFishingOperation");
288                         } else {
289                             message = t("tutti.editCatchBatch.askSaveBeforeLeaving.saveCatchBatch");
290                         }
291 
292                         int answer = getHandler().askSaveBeforeLeaving(message);
293 
294 
295                         switch (answer) {
296                             case JOptionPane.OK_OPTION:
297 
298                                 // persist previous fishing operation
299                                 if (fishingOperationModified) {
300                                     getSaveFishingOperationAction().setUpdateUI(false);
301                                     getActionEngine().runInternalAction(getSaveFishingOperationAction());
302                                 }
303 
304                                 if (catchBatchModified) {
305                                     getSaveCatchBatchAction().setUpdateUI(false);
306                                     getActionEngine().runInternalAction(getSaveCatchBatchAction());
307                                 }
308 
309                                 canContinue = true;
310                                 break;
311 
312                             case JOptionPane.NO_OPTION:
313 
314                                 // won't save modification
315                                 // so since we will edit a new operation, nothing to do here
316 
317                                 canContinue = true;
318                                 break;
319                         }
320                     } else {
321 
322                         // data are not valid
323                         String message;
324 
325                         if (fishingOperationValid) {
326                             message = t("tutti.editCatchBatch.askCancelEditBeforeLeaving.cancelEditCatchBatch");
327                         } else {
328                             message = t("tutti.editFishingOperation.askCancelEditBeforeLeaving.cancelEditFishingOperation");
329                         }
330 
331                         // ok will revert any modification by
332                         // editing new fishing operation (if user says yes)
333                         canContinue = handler.askCancelEditBeforeLeaving(message);
334                     }
335                 }
336 
337                 if (canContinue) {
338 
339                     // check can quit frequency ui (if on it)
340                     if (EditCatchesUI.class.equals(getUI().getTabPane().getSelectedComponent().getClass())) {
341                         // on est sur l'onglet captures
342 
343                         if (EditSpeciesBatchPanelUI.class.equals(getUI().getCatchesTabContent().getTabPane().getSelectedComponent().getClass())) {
344 
345                             // on est sur l'onglet espèce ou benthos
346                             EditSpeciesBatchPanelUI speciesOrBenthosUI = (EditSpeciesBatchPanelUI) getUI().getCatchesTabContent().getTabPane().getSelectedComponent();
347                             if (EditSpeciesBatchPanelUI.EDIT_FREQUENCY_CARD.equals(speciesOrBenthosUI.getTopPanelLayout().getSelected())) {
348 
349                                 // on est sur l'écran des mensurations / observations individuelles
350                                 SpeciesFrequencyUI editFrequenciesUI = speciesOrBenthosUI.getEditFrequenciesUI();
351 
352                                 canContinue = editFrequenciesUI.leaveIfConfirmed();
353 
354                             }
355                         }
356                     }
357                 }
358             }
359 
360             if (!canContinue) {
361 
362                 FishingOperation selectFishingOperation;
363                 if (TuttiEntities.isNew(editFishingOperation)) {
364 
365                     // no selection
366                     selectFishingOperation = null;
367                 } else {
368                     // rollback selected fishing operation
369                     selectFishingOperation =
370                             model.getFishingOperation(editFishingOperationId);
371                 }
372 
373                 model.setEditionAdjusting(true);
374                 try {
375                     model.setSelectedFishingOperation(selectFishingOperation);
376                 } finally {
377                     model.setEditionAdjusting(false);
378                 }
379             }
380         }
381 
382         if (canContinue) {
383 
384             // always close attachments
385             FishingOperationsUI ui = getUI();
386             ui.getCatchesTabContent().getHandler().closeAttachments();
387             ui.getFishingOperationTabContent().getFishingOperationAttachmentsButton().onCloseUI();
388         }
389 
390         return canContinue;
391     }
392 
393     @Override
394     public void doAction() throws Exception {
395 
396         errorMessages.clear();
397 
398         FishingOperationsUI ui = getUI();
399 
400         FishingOperationsUIModel model = ui.getModel();
401 
402         // edit new fishing operation
403         if (log.isDebugEnabled()) {
404             log.debug("Edit fishingOperation: " + fishingOperation);
405         }
406 
407         // now fishing operation is edited
408         model.setEditFishingOperation(fishingOperation);
409 
410         loadFishingOperation(fishingOperation);
411 
412         loadCatchBatch(fishingOperation);
413 
414         JTabbedPane form = ui.getTabPane();
415         JLabel noContentPane = ui.getNoTraitPane();
416 
417         if (fishingOperation == null) {
418 
419             // nothing to display
420 
421             // close fishing operation ui
422             ui.getFishingOperationTabContent().getHandler().onCloseUI();
423             // close catch ui
424             ui.getCatchesTabContent().getHandler().onCloseUI();
425 
426             ui.remove(form);
427 
428             // just display <no trait!>
429             ui.add(noContentPane, BorderLayout.CENTER);
430 
431         } else {
432 
433             ui.remove(noContentPane);
434 
435             // wait last minute to display (avoid dirty display effects)
436             ui.add(form, BorderLayout.CENTER);
437 
438             ui.getFishingOperationTabContent().getFishingOperationTabPane().setSelectedIndex(0);
439 
440             if (checkPreviousEdit) {
441 
442                 ui.getCatchesTabContent().getModel().setDoNotCheckLeavingFrequencyScreen(true);
443 
444                 try {
445                     ui.getTabPane().setSelectedIndex(0);
446                 } finally {
447 
448                     ui.getCatchesTabContent().getModel().setDoNotCheckLeavingFrequencyScreen(false);
449                 }
450             }
451         }
452 
453         model.addPropertyChangeListener(coordinatePropertiesListener);
454     }
455 
456     @Override
457     public void postSuccessAction() {
458         super.postSuccessAction();
459 
460         // always go back to main content (see https://forge.codelutin.com/issues/5705)
461         getUI().getCatchesTabContent().getSpeciesTabPanel().switchToEditBatch();
462         getUI().getCatchesTabContent().getBenthosTabPanel().switchToEditBatch();
463 
464         final EditFishingOperationUI fishingOperationTabContent = getUI().getFishingOperationTabContent();
465         fishingOperationTabContent.getModel().setModify(false);
466 
467         SwingUtilities.invokeLater(
468                 () -> {
469 
470                     JComponent componentToFocus = fishingOperationTabContent.getHandler().getComponentToFocus();
471                     componentToFocus.requestFocusInWindow();
472 
473                 }
474         );
475 
476         getUI().repaint();
477 
478     }
479 
480 //    public void displayValidationErrors() {
481 //        if (CollectionUtils.isNotEmpty(errorMessages)) {
482 //            for (String errorMessage : errorMessages) {
483 //                getContext().getErrorHelper().showErrorDialog(errorMessage, null);
484 //            }
485 //        }
486 //    }
487 
488     public void loadFishingOperation(FishingOperation bean) {
489 
490         EditFishingOperationUI ui = getUI().getFishingOperationTabContent();
491 
492         EditFishingOperationUIHandler handler = ui.getHandler();
493 
494         EditFishingOperationUIModel editFishingOperationUIModel = ui.getModel();
495 
496         editFishingOperationUIModel.setLoadingData(true);
497 
498         editFishingOperationUIModel.removeAllAttachment(editFishingOperationUIModel.getAttachment());
499 
500         handler.uninstallStartDateListener();
501         handler.uninstallCoordinatesListener();
502 
503         if (bean == null) {
504 
505             editFishingOperationUIModel.fromEntity(
506                     FishingOperations.newFishingOperation());
507 
508             editFishingOperationUIModel.setFishingOperation(null);
509             editFishingOperationUIModel.setAllSecondaryVessel(null);
510             editFishingOperationUIModel.setFishingSecondaryVessel(null);
511             editFishingOperationUIModel.setScientificSecondaryVessel(null);
512             editFishingOperationUIModel.setOnlyCruisSecondaryVessel(null);
513             editFishingOperationUIModel.setSecondaryVesselType(null);
514 
515             handler.clearValidators();
516 
517             handler.resetAllModels();
518 
519         } else { //if (!bean.equals(editFishingOperationUIModel.getFishingOperation()) || handler.isAModelModified()) {
520 
521             TuttiLocation strata = bean.getStrata();
522             TuttiLocation subStrata = bean.getSubStrata();
523             TuttiLocation location = bean.getLocation();
524 
525             PersistenceService persistenceService = getContext().getPersistenceService();
526 
527             Cruise cruise = bean.getCruise();
528             if (cruise != null) {
529 
530                 // update gear universe
531                 // add a equals on id + rankOrder
532                 List<Gear> gears = Lists.newArrayList();
533                 for (Gear gear : cruise.getGear()) {
534                     CaracteristicMap caracteristics =
535                             persistenceService.getGearCaracteristics(
536                                     cruise.getIdAsInt(),
537                                     gear.getIdAsInt(),
538                                     gear.getRankOrder());
539 
540                     Gear toKeep = GearWithOriginalRankOrders.newGearWithOriginalRankOrder(gear);
541                     toKeep.setCaracteristics(caracteristics);
542 
543                     gears.add(toKeep);
544                 }
545                 ui.getGearComboBox().setData(gears);
546             }
547 
548             editFishingOperationUIModel.fromEntity(bean);
549 
550             // to be sure combo list will be reloaded
551             editFishingOperationUIModel.setStrata(null);
552             editFishingOperationUIModel.setSubStrata(null);
553             editFishingOperationUIModel.setLocation(null);
554 
555             editFishingOperationUIModel.convertGearShootingCoordinatesFromDD();
556 
557             if (strata != null) {
558                 ui.getStrataComboBox().setSelectedItem(strata);
559             }
560 
561             if (subStrata != null) {
562                 ui.getSubStrataComboBox().setSelectedItem(subStrata);
563             }
564 
565             if (location != null) {
566                 ui.getLocationComboBox().setSelectedItem(location);
567             }
568 
569             editFishingOperationUIModel.setFishingOperation(bean);
570 
571             // update saisisseur selection
572             List<Person> saisisseur = editFishingOperationUIModel.getRecorderPerson();
573             ui.getRecorderPersonList().getHandler().setSelected(saisisseur);
574 
575             //reset gear use feature tab
576             GearUseFeatureTabUI gearUseFeatureTabContent = ui.getGearUseFeatureTabContent();
577             gearUseFeatureTabContent.getHandler().reset(bean);
578 
579             //reset vessel use feature tab
580             VesselUseFeatureTabUI vesselUseFeatureTabContent = ui.getVesselUseFeatureTabContent();
581             vesselUseFeatureTabContent.getHandler().reset(bean);
582 
583             Integer objectId = editFishingOperationUIModel.getObjectId();
584             if (objectId != null) {
585 
586                 List<Attachment> attachments =
587                         persistenceService.getAllAttachments(
588                                 editFishingOperationUIModel.getObjectType(),
589                                 objectId);
590 
591                 editFishingOperationUIModel.addAllAttachment(attachments);
592             }
593 
594             Vessel cruiseVessel = getDataContext().getCruise().getVessel();
595             List<Vessel> scientificVessels = getDataContext().getScientificVessels();
596             List<Vessel> fishingVessels = getDataContext().getFishingVessels();
597 
598             {  // update all secondary vessel universe
599                 List<Vessel> vessels = Lists.newArrayList();
600                 vessels.addAll(scientificVessels);
601                 vessels.addAll(fishingVessels);
602                 vessels.remove(cruiseVessel);
603                 editFishingOperationUIModel.setAllSecondaryVessel(vessels);
604             }
605 
606             {  // update scientific secondary vessel universe
607                 List<Vessel> vessels = Lists.newArrayList();
608                 vessels.addAll(scientificVessels);
609                 vessels.remove(cruiseVessel);
610                 editFishingOperationUIModel.setScientificSecondaryVessel(vessels);
611             }
612 
613             {  // update fishing secondary vessel universe
614                 List<Vessel> vessels = Lists.newArrayList();
615                 vessels.addAll(fishingVessels);
616                 vessels.remove(cruiseVessel);
617                 editFishingOperationUIModel.setFishingSecondaryVessel(vessels);
618             }
619 
620             { // update only cruise vessel universe
621 
622                 List<FishingOperation> fishingOperation =
623                         getModel().getFishingOperation();
624 
625                 Set<Vessel> vesselSet = Sets.newHashSet();
626                 for (FishingOperation operation : fishingOperation) {
627                     List<Vessel> secondaryVessel = persistenceService.getFishingOperationSecondaryVessel(operation.getIdAsInt());
628                     if (CollectionUtils.isNotEmpty(secondaryVessel)) {
629                         vesselSet.addAll(secondaryVessel);
630                     }
631                 }
632                 List<Vessel> vessel = Lists.newArrayList(vesselSet);
633                 editFishingOperationUIModel.setOnlyCruisSecondaryVessel(vessel);
634             }
635 
636             // will propagate to model
637             ui.getSecondaryVesselList().getModel().setSelected(bean.getSecondaryVessel());
638 
639             editFishingOperationUIModel.setSecondaryVesselType(SecondaryVesselTypeEnum.ALL);
640 
641             editFishingOperationUIModel.setModify(false);
642             handler.getFishingOperationMonitor().clearModified();
643             handler.registerValidator();
644         }
645 
646         editFishingOperationUIModel.setLoadingData(false);
647 
648         handler.installStartDateListener();
649         handler.installCoordinatesListener();
650 
651     }
652 
653     public void loadCatchBatch(FishingOperation bean) {
654 
655         boolean empty = bean == null || TuttiEntities.isNew(bean);
656 
657         EditCatchesUI ui = getUI().getCatchesTabContent();
658 
659         ui.getHandler().uninstallTotalRejectWeightListener();
660 
661         TuttiBeanMonitor<EditCatchesUIModel> catchBatchMonitor =
662                 ui.getHandler().getCatchBatchMonitor();
663 
664         EditCatchesUIModel catchesUIModel = ui.getModel();
665 
666         catchesUIModel.setLoadingData(true);
667 
668         catchesUIModel.reset();
669 
670         CatchBatch batch;
671 
672         List<Attachment> attachments;
673 
674         boolean catchEnabled;
675 
676         Integer operationId = bean == null ? null : bean.getIdAsInt();
677 
678         ProgressionModel progressionModel = getProgressionModel();
679         if (progressionModel == null) {
680             progressionModel = new ProgressionModel();
681             setProgressionModel(progressionModel);
682         }
683         progressionModel.adaptTotal(empty ? 1 : 6);
684 
685         String validationErrorMessage = null;
686 
687         if (empty) {
688 
689             // create a new CatchBatch
690             progressionModel.increments("Create new catch batch");
691             if (log.isDebugEnabled()) {
692                 log.debug("Create a new CatchBatch (fishing operation is null)");
693             }
694             batch = CatchBatchs.newCatchBatch();
695             batch.setFishingOperation(bean);
696 
697             attachments = Collections.emptyList();
698 
699             catchEnabled = true;
700 
701         } else {
702 
703             if (log.isDebugEnabled()) {
704                 log.debug("Load existing CatchBatch from operation id: " +
705                           operationId);
706             }
707 
708             PersistenceService persistenceService =
709                     getContext().getPersistenceService();
710 
711             progressionModel.increments("Chargement de la capture");
712 
713             boolean withCatchBath =
714                     persistenceService.isFishingOperationWithCatchBatch(
715                             operationId);
716 
717             if (withCatchBath) {
718 
719                 // load it
720                 try {
721                     batch = persistenceService.getCatchBatchFromFishingOperation(operationId);
722                     batch.setFishingOperation(bean);
723                     Integer objectId = batch.getIdAsInt();
724                     attachments = persistenceService.getAllAttachments(catchesUIModel.getObjectType(), objectId);
725                     catchEnabled = true;
726 
727                 } catch (InvalidBatchModelException e) {
728 
729                     // batch is not compatible with Tutti
730                     if (log.isDebugEnabled()) {
731                         log.debug("Invalid batch model", e);
732                     }
733                     batch = null;
734                     attachments = Collections.emptyList();
735 
736                     validationErrorMessage = t("tutti.fishingOperations.warn.catchBatch.invalidSampleCategoryModel");
737 
738                     getModel().setValidationErrorMessage(validationErrorMessage);
739 
740                     catchEnabled = false;
741                 }
742             } else {
743 
744                 // no catch batch
745                 batch = null;
746                 attachments = Collections.emptyList();
747 
748                 catchEnabled = false;
749 
750                 validationErrorMessage = t("tutti.fishingOperations.warn.catchBatch.notFound");
751             }
752         }
753 
754         setCatch(attachments,
755                  catchesUIModel,
756                  catchBatchMonitor,
757                  batch,
758                  catchEnabled);
759 
760         // 4) Propagate new selected fishingoperation to others tabs
761 
762         FishingOperation operationToLoad = batch == null ? null : bean;
763 
764         boolean catchValid = true;
765 
766         try {
767             progressionModel.increments("Chargement des captures Espèces");
768 
769             ui.getSpeciesTabPanel().getEditBatchesUI().getHandler().selectFishingOperation(operationToLoad);
770         } catch (InvalidBatchModelException e) {
771 
772             // invalid sample category model for species batches
773             if (log.isDebugEnabled()) {
774                 log.debug("Invalid sample category model for species batches", e);
775             }
776             errorMessages.add(e.getMessage());
777             catchValid = false;
778         }
779 
780         try {
781             progressionModel.increments("Chargement des captures Benthos");
782             ui.getBenthosTabPanel().getEditBatchesUI().getHandler().selectFishingOperation(operationToLoad);
783         } catch (InvalidBatchModelException e) {
784 
785             // invalid sample category model for benthos batches
786             if (log.isDebugEnabled()) {
787                 log.debug("Invalid sample category model for benthos batches", e);
788             }
789             errorMessages.add(e.getMessage());
790             catchValid = false;
791         }
792 
793         if (!errorMessages.isEmpty()) {
794 
795             StringBuilder message = new StringBuilder();
796             for (String errorMessage : errorMessages) {
797                 message.append("<li>").append(errorMessage).append("</li>");
798             }
799             validationErrorMessage = t("tutti.fishingOperations.warn.invalid.batch", message.toString());
800 
801         }
802 
803         getModel().setValidationErrorMessage(validationErrorMessage);
804 
805         if (catchValid) {
806 
807             // load other tabs
808 
809             progressionModel.increments("Chargmenent des macro-déchets");
810             ui.getMarineLitterTabContent().getHandler().selectFishingOperation(operationToLoad);
811 
812             progressionModel.increments("Chargement des captures accidentelles");
813             ui.getAccidentalTabContent().getHandler().selectFishingOperation(operationToLoad);
814 
815         } else {
816 
817             // remove catch
818             setCatch(Collections.<Attachment>emptyList(),
819                      catchesUIModel,
820                      catchBatchMonitor,
821                      null,
822                      false);
823         }
824 
825         ui.getHandler().installTotalRejectWeightListener();
826 
827         catchesUIModel.setLoadingData(false);
828     }
829 
830     @Override
831     public void postFailedAction(Throwable error) {
832         super.postFailedAction(error);
833     }
834 
835 
836     protected void setCatch(List<Attachment> attachments,
837                             EditCatchesUIModel catchesUIModel,
838                             TuttiBeanMonitor<EditCatchesUIModel> catchBatchMonitor,
839                             CatchBatch batch,
840                             boolean catchEnabled) {
841 
842         getModel().setCatchEnabled(catchEnabled);
843 //        getModel().setCatchNotFound(catchNotFound);
844 //        getModel().setSampleCatchModelValid(sampleModelValid);
845 
846         catchesUIModel.fromEntity(batch);
847         catchesUIModel.addAllAttachment(attachments);
848 
849         catchesUIModel.setModify(false);
850         catchBatchMonitor.clearModified();
851     }
852 
853     public void setInternalAction(boolean internalAction) {
854         this.internalAction = internalAction;
855     }
856 }