1 package fr.ifremer.reefdb.ui.swing.content.manage.program.locations;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import com.google.common.collect.Lists;
27 import com.google.common.collect.Sets;
28 import fr.ifremer.quadrige3.core.dao.technical.Assert;
29 import fr.ifremer.quadrige3.ui.swing.table.SwingTable;
30 import fr.ifremer.quadrige3.ui.swing.table.SwingTableColumnModel;
31 import fr.ifremer.reefdb.dto.ReefDbBeans;
32 import fr.ifremer.reefdb.dto.configuration.programStrategy.AppliedStrategyDTO;
33 import fr.ifremer.reefdb.dto.configuration.programStrategy.ProgStratDTO;
34 import fr.ifremer.reefdb.dto.configuration.programStrategy.StrategyDTO;
35 import fr.ifremer.reefdb.dto.enums.FilterTypeValues;
36 import fr.ifremer.reefdb.dto.referential.LocationDTO;
37 import fr.ifremer.reefdb.service.StatusFilter;
38 import fr.ifremer.reefdb.ui.swing.content.manage.filter.select.SelectFilterUI;
39 import fr.ifremer.reefdb.ui.swing.content.manage.program.ProgramsUI;
40 import fr.ifremer.reefdb.ui.swing.content.manage.program.locations.updatePeriod.UpdatePeriodUI;
41 import fr.ifremer.reefdb.ui.swing.content.manage.program.programs.ProgramsTableRowModel;
42 import fr.ifremer.reefdb.ui.swing.content.manage.program.strategies.StrategiesTableRowModel;
43 import fr.ifremer.reefdb.ui.swing.util.AbstractReefDbBeanUIModel;
44 import fr.ifremer.reefdb.ui.swing.util.ReefDbUIs;
45 import fr.ifremer.reefdb.ui.swing.util.table.AbstractReefDbTableModel;
46 import fr.ifremer.reefdb.ui.swing.util.table.AbstractReefDbTableUIHandler;
47 import jaxx.runtime.SwingUtil;
48 import org.apache.commons.logging.Log;
49 import org.apache.commons.logging.LogFactory;
50 import org.jdesktop.swingx.table.TableColumnExt;
51
52 import javax.swing.JOptionPane;
53 import javax.swing.SortOrder;
54 import java.awt.Dimension;
55 import java.util.List;
56 import java.util.Set;
57 import java.util.stream.Collectors;
58
59 import static org.nuiton.i18n.I18n.t;
60
61
62
63
64 public class LocationsTableUIHandler extends AbstractReefDbTableUIHandler<LocationsTableRowModel, LocationsTableUIModel, LocationsTableUI> {
65
66
67
68
69 private static final Log LOG = LogFactory.getLog(LocationsTableUIHandler.class);
70
71
72 @Override
73 public AbstractReefDbTableModel<LocationsTableRowModel> getTableModel() {
74 return (LocationsTableModel) getTable().getModel();
75 }
76
77
78 @Override
79 public SwingTable getTable() {
80 return getUI().getLocationsTable();
81 }
82
83
84 @Override
85 public void beforeInit(final LocationsTableUI ui) {
86 super.beforeInit(ui);
87
88
89 final LocationsTableUIModel model = new LocationsTableUIModel();
90 ui.setContextValue(model);
91 }
92
93
94 @Override
95 public void afterInit(LocationsTableUI ui) {
96
97
98 initUI(ui);
99
100
101 getModel().setPeriodsEnabled(false);
102 initTable();
103 SwingUtil.setLayerUI(ui.getTableScrollPane(), ui.getTableBlockLayer());
104
105
106 initListeners();
107
108
109 initActionComboBox(getUI().getEditCombobox());
110
111
112 }
113
114
115
116
117
118
119 public void loadMonitoringLocationsFromProgram(ProgramsTableRowModel selectedProgram) {
120
121
122 if (getModel().isPeriodsEnabled()) {
123 getModel().setPeriodsEnabled(false);
124 initTable();
125 }
126
127 getModel().setSelectedProgram(selectedProgram);
128 getModel().setSelectedStrategy(null);
129
130
131 load();
132 }
133
134
135
136
137
138
139
140 public void loadAppliedStrategiesFromStrategy(ProgramsTableRowModel selectedProgram, StrategiesTableRowModel selectedStrategy) {
141
142
143 if (!getModel().isPeriodsEnabled()) {
144 getModel().setPeriodsEnabled(true);
145 initTable();
146 }
147
148 getModel().setSelectedProgram(selectedProgram);
149 getModel().setSelectedStrategy(selectedStrategy);
150
151
152 load();
153 }
154
155
156
157
158 private void load() {
159 try {
160
161 if (getModel().getSelectedProgram() == null) {
162 return;
163 }
164
165 getModel().setEditable(getModel().getSelectedProgram().isEditable());
166
167 if (getModel().getSelectedStrategy() == null) {
168
169
170 getModel().setBeans(ReefDbBeans.locationsToAppliedStrategyDTOs(getModel().getSelectedProgram().getLocations()));
171
172 } else {
173
174
175 if (getUI().getStrategyFilterCheckbox().isSelected()) {
176
177
178 getModel().setBeans(ReefDbBeans.filterNotEmptyAppliedPeriod(getModel().getSelectedStrategy().getAppliedStrategies()));
179
180 } else {
181
182
183 getModel().setBeans(getModel().getSelectedStrategy().getAppliedStrategies());
184 }
185 }
186
187 if (getContext().getSelectedLocationId() != null) {
188 selectRowById(getContext().getSelectedLocationId());
189 }
190
191 recomputeRowsValidState();
192 getModel().setLoaded(true);
193
194 } finally {
195 getModel().setLoading(false);
196 }
197 }
198
199
200
201
202 public void clearTable() {
203
204
205 getModel().setBeans(null);
206
207 getModel().setLoaded(false);
208 }
209
210
211
212
213
214
215 public ProgramsUI getProgramsUI() {
216 return getUI().getParentContainer(ProgramsUI.class);
217 }
218
219
220
221
222 public void addLocations() {
223
224 ProgramsTableRowModel program = getModel().getSelectedProgram();
225 StrategiesTableRowModel strategy = getModel().getSelectedStrategy();
226
227 Assert.notNull(program);
228
229 SelectFilterUI dialog = new SelectFilterUI(getContext(), FilterTypeValues.LOCATION.getFilterTypeId());
230 dialog.setTitle(t("reefdb.program.location.new.dialog.title"));
231 List<LocationDTO> locations = program.getLocations().stream()
232 .sorted(getDecorator(LocationDTO.class, null).getCurrentComparator())
233
234 .peek(location -> location.setReadOnly(true))
235 .collect(Collectors.toList());
236
237 dialog.getModel().setSelectedElements(locations);
238
239 if (!program.isLocal()) {
240
241 dialog.getHandler().getFilterElementUIHandler().forceLocal(false);
242 }
243
244 openDialog(dialog, new Dimension(1024, 720));
245
246 if (dialog.getModel().isValid()) {
247
248
249 List<LocationDTO> newLocations = dialog.getModel().getSelectedElements().stream()
250 .map(newLocation -> ((LocationDTO) newLocation))
251 .filter(newLocation -> program.getLocations().stream().noneMatch(location -> location.equals(newLocation)))
252 .collect(Collectors.toList());
253
254 if (!newLocations.isEmpty()) {
255
256
257 newLocations.forEach(program::addLocations);
258
259
260 if (strategy != null) {
261 newLocations.stream()
262
263 .filter(newLocation -> strategy.getAppliedStrategies().stream().noneMatch(appliedStrategy -> appliedStrategy.getId().equals(newLocation.getId())))
264 .forEach(newLocation -> strategy.addAppliedStrategies(ReefDbBeans.locationToAppliedStrategyDTO(newLocation)));
265 }
266
267
268 List<AppliedStrategyDTO> beans = strategy != null ? strategy.getAppliedStrategies() : ReefDbBeans.locationsToAppliedStrategyDTOs(program.getLocations());
269 getModel().setBeans(beans);
270
271 saveToStrategy();
272
273
274 unselectAllRows();
275 List<Integer> newLocIds = ReefDbBeans.collectIds(newLocations);
276 selectRows(getModel().getRows().stream().filter(row -> newLocIds.contains(row.getId())).collect(Collectors.toList()));
277
278 }
279 }
280 }
281
282
283
284
285 private void initListeners() {
286
287
288 getModel().addPropertyChangeListener(LocationsTableUIModel.PROPERTY_SINGLE_ROW_SELECTED, evt -> {
289
290
291 getContext().setSelectedLocationId(getModel().getSingleSelectedRow() == null ? null : getModel().getSingleSelectedRow().getId());
292
293 });
294
295
296 getUI().getStrategyFilterCheckbox().addItemListener(e -> {
297
298
299 load();
300 });
301 }
302
303
304
305
306 private void initTable() {
307
308
309 getModel().setBeans(null);
310
311
312 getTable().setColumnModel(new SwingTableColumnModel());
313
314
315 final TableColumnExt colonneCode = addColumn(LocationsTableModel.CODE);
316 colonneCode.setSortable(true);
317 colonneCode.setCellRenderer(newNumberCellRenderer(0));
318
319
320 final TableColumnExt colonneName = addColumn(
321 LocationsTableModel.LABEL);
322 colonneName.setSortable(true);
323
324
325 final TableColumnExt colonneComment = addColumn(
326 LocationsTableModel.NAME);
327 colonneComment.setSortable(true);
328
329
330 if (getModel().isPeriodsEnabled()) {
331
332
333 final TableColumnExt colonneStartDate = addLocalDatePickerColumnToModel(
334 LocationsTableModel.START_DATE, getConfig().getDateFormat());
335 colonneStartDate.setSortable(true);
336 colonneStartDate.setHideable(false);
337
338
339 final TableColumnExt colonneEndDate = addLocalDatePickerColumnToModel(
340 LocationsTableModel.END_DATE, getConfig().getDateFormat());
341 colonneEndDate.setSortable(true);
342 colonneEndDate.setHideable(false);
343
344
345 final TableColumnExt colonnePreleveur = addFilterableComboDataColumnToModel(
346 LocationsTableModel.PRELEVEUR,
347 getContext().getReferentialService().getDepartments(getModel().getSelectedProgram().isLocal() ? StatusFilter.ACTIVE : StatusFilter.NATIONAL_ACTIVE),
348 false);
349 colonnePreleveur.setSortable(true);
350 colonnePreleveur.setHideable(false);
351 }
352
353
354 final LocationsTableModel tableModel = new LocationsTableModel(getTable().getColumnModel());
355 getTable().setModel(tableModel);
356
357
358 tableModel.setNoneEditableCols();
359
360
361 colonneCode.setHideable(false);
362 colonneName.setHideable(false);
363 colonneComment.setHideable(false);
364
365
366 colonneCode.setEditable(false);
367 colonneName.setEditable(false);
368 colonneComment.setEditable(false);
369
370
371 initTable(getTable());
372
373
374 getTable().setVisibleRowCount(4);
375
376
377 getTable().setSortOrder(LocationsTableModel.CODE, SortOrder.ASCENDING);
378
379 if (getModel().isPeriodsEnabled()) {
380 overrideTabKeyActions(getTable(), true);
381 }
382 }
383
384
385 @Override
386 protected String[] getRowPropertiesToIgnore() {
387 return new String[]{LocationsTableRowModel.PROPERTY_ERRORS};
388 }
389
390
391 @Override
392 protected boolean isRowValid(LocationsTableRowModel row) {
393 row.getErrors().clear();
394 return super.isRowValid(row) && isDatesValid(row);
395 }
396
397 private boolean isDatesValid(LocationsTableRowModel row) {
398 if (getModel().isPeriodsEnabled()) {
399
400
401 if (row.getStartDate() == null && row.getPreviousStartDate() != null
402 && row.getEndDate() == null && row.getPreviousEndDate() != null) {
403 checkExistingSurveysInsideStrategy(row);
404 }
405
406
407 if (row.getStartDate() == null && row.getEndDate() != null) {
408 ReefDbBeans.addError(row, t("reefdb.program.location.startDate.null"), LocationsTableRowModel.PROPERTY_START_DATE);
409
410 } else if (row.getStartDate() != null && row.getEndDate() == null) {
411 ReefDbBeans.addError(row, t("reefdb.program.location.endDate.null"), LocationsTableRowModel.PROPERTY_END_DATE);
412
413 } else if (row.getStartDate() != null && row.getEndDate() != null) {
414
415 if (row.getStartDate().isAfter(row.getEndDate())) {
416 ReefDbBeans.addError(row, t("reefdb.program.location.endDate.before"), LocationsTableRowModel.PROPERTY_END_DATE);
417 } else {
418
419
420 checkExistingSurveysOutsideStrategy(row);
421 }
422 }
423 }
424 return row.getErrors().isEmpty();
425 }
426
427 private void checkExistingSurveysInsideStrategy(LocationsTableRowModel row) {
428 if (row.getAppliedStrategyId() != null && row.getId() != null) {
429 Long surveysCount = getContext().getObservationService().countSurveysWithProgramLocationAndInsideDates(
430 getProgramsUI().getProgramsTableUI().getModel().getSingleSelectedRow().getCode(),
431 row.getAppliedStrategyId(),
432 row.getId(),
433 row.getPreviousStartDate(),
434 row.getPreviousEndDate()
435 );
436 if (surveysCount != null && surveysCount > 0) {
437 ReefDbBeans.addError(row, t("reefdb.program.location.period.surveyInsidePeriod"),
438 LocationsTableRowModel.PROPERTY_START_DATE, LocationsTableRowModel.PROPERTY_END_DATE);
439 }
440 }
441 }
442
443 private void checkExistingSurveysOutsideStrategy(LocationsTableRowModel row) {
444 if (row.getAppliedStrategyId() != null && row.getId() != null) {
445 Long surveysCount = getContext().getObservationService().countSurveysWithProgramLocationAndOutsideDates(
446 getProgramsUI().getProgramsTableUI().getModel().getSingleSelectedRow().getCode(),
447 row.getAppliedStrategyId(),
448 row.getId(),
449 row.getStartDate(),
450 row.getEndDate()
451 );
452 if (surveysCount != null && surveysCount > 0) {
453 ReefDbBeans.addError(row, t("reefdb.program.location.period.surveyOutsidePeriod"),
454 LocationsTableRowModel.PROPERTY_START_DATE, LocationsTableRowModel.PROPERTY_END_DATE);
455 }
456 }
457 }
458
459
460 @Override
461 protected void onRowModified(int rowIndex, LocationsTableRowModel row, String propertyName, Integer propertyIndex, Object oldValue, Object newValue) {
462
463
464 if (getModel().isPeriodsEnabled()) {
465 if (LocationsTableRowModel.PROPERTY_START_DATE.equals(propertyName) || LocationsTableRowModel.PROPERTY_END_DATE.equals(propertyName)) {
466 if (row.getStartDate() == null && row.getEndDate() == null && row.getDepartment() != null) {
467 row.setDepartment(null);
468 }
469 }
470 }
471
472 saveToStrategy();
473 super.onRowModified(rowIndex, row, propertyName, propertyIndex, oldValue, newValue);
474 }
475
476
477
478
479 public void saveToStrategy() {
480
481 if (getModel().isLoading()) return;
482
483
484 getProgramsUI().getStrategiesTableUI().getHandler().keepModificationOnLocationsTable();
485 getProgramsUI().getProgramsTableUI().getHandler().keepModificationOnStrategiesTable();
486
487
488 recomputeRowsValidState();
489 getModel().firePropertyChanged(AbstractReefDbBeanUIModel.PROPERTY_MODIFY, null, true);
490 getModel().firePropertyChanged(AbstractReefDbBeanUIModel.PROPERTY_VALID, null, getModel().getRowCount() > 0);
491
492 }
493
494
495 @Override
496 public void recomputeRowsValidState() {
497 super.recomputeRowsValidState();
498
499
500 getProgramsUI().getStrategiesTableUI().getHandler().recomputeRowsValidState();
501 }
502
503
504
505
506
507
508 public void removeFromModels(List<Integer> locationIds) {
509
510
511 getProgramsUI().getProgramsTableUI().getHandler().removeLocations(locationIds);
512
513
514 for (StrategyDTO strategy : getProgramsUI().getStrategiesTableUI().getModel().getRows()) {
515 if (!strategy.isAppliedStrategiesEmpty()) {
516 strategy.getAppliedStrategies().removeIf(appliedStrategy -> locationIds.contains(appliedStrategy.getId()));
517 }
518 }
519 }
520
521
522
523
524 public void removeLocations() {
525
526 if (getModel().getSelectedRows().isEmpty()) {
527 LOG.warn("Aucun lieu de selectionne");
528 return;
529 }
530
531
532 ProgramsTableRowModel program = getProgramsUI().getProgramsTableUI().getModel().getSingleSelectedRow();
533 List<Integer> locationIds = Lists.newArrayList();
534 for (final AppliedStrategyDTO row : getModel().getSelectedRows()) {
535
536 locationIds.add(row.getId());
537 }
538
539
540 if (getModel().isPeriodsEnabled()) {
541
542
543 if (!askBeforeDelete(t("reefdb.program.location.delete.titre"), t("reefdb.program.location.delete.appliedStrategy.message"))) {
544 return;
545 }
546
547 } else {
548
549
550 Long surveysCount = getContext().getObservationService().countSurveysWithProgramAndLocations(program.getCode(), locationIds);
551 if (surveysCount > 0) {
552 getContext().getDialogHelper().showErrorDialog(
553 surveysCount == 1
554 ? t("reefdb.program.location.delete.usedInData")
555 : t("reefdb.program.location.delete.usedInData.many", surveysCount),
556 t("reefdb.program.location.delete.titre"));
557 return;
558 }
559
560
561 if (!askBeforeDelete(t("reefdb.program.location.delete.titre"), t("reefdb.program.location.delete.location.message"))) {
562 return;
563 }
564
565
566 Set<ProgStratDTO> usedStrategies = Sets.newHashSet();
567 for (Integer locationId : locationIds) {
568 List<ProgStratDTO> appliedStrategies = getContext().getProgramStrategyService().getStrategyUsageByProgramAndLocationId(program.getCode(), locationId);
569 usedStrategies.addAll(appliedStrategies);
570 }
571 if (!usedStrategies.isEmpty()) {
572 List<String> locationNames = Lists.newArrayList();
573 for (AppliedStrategyDTO row : getModel().getSelectedRows()) {
574 locationNames.add(decorate(row));
575 }
576 List<String> strategyNames = ReefDbBeans.collectProperties(usedStrategies, ProgStratDTO.PROPERTY_NAME);
577
578 String topPart = t("reefdb.program.location.delete.location.formStrategy");
579 String bottomMessage = t("reefdb.program.location.delete.location.fromStrategy.list", ReefDbUIs.formatHtmlList(strategyNames));
580
581 if (locationNames.size() > 8) {
582
583 if (getContext().getDialogHelper().showConfirmDialog(topPart, ReefDbUIs.getHtmlString(locationNames), bottomMessage, JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) {
584 return;
585 }
586
587 } else {
588
589 String message = String.format("%s\n%s\n%s", topPart, ReefDbUIs.formatHtmlList(locationNames), bottomMessage);
590 if (getContext().getDialogHelper().showConfirmDialog(message, JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) {
591 return;
592 }
593 }
594
595 }
596 }
597
598
599 getModel().deleteSelectedRows();
600
601 if (!getModel().isPeriodsEnabled()) {
602
603 removeFromModels(locationIds);
604 }
605
606 saveToStrategy();
607
608 }
609
610
611
612
613 public void updatePeriod() {
614
615 final UpdatePeriodUI dialogue = new UpdatePeriodUI(getUI());
616 dialogue.getModel().setTableModel(getModel());
617
618 if (!getModel().getSelectedProgram().isLocal()) {
619 dialogue.getHandler().forceIsLocal(false);
620 }
621
622 openDialog(dialogue, new Dimension(400, 180));
623
624 getModel().setModify(true);
625 saveToStrategy();
626 getTable().repaint();
627 }
628
629 }