1 package fr.ifremer.dali.dao.data.survey;
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.ImmutableList;
27 import com.google.common.collect.Lists;
28 import com.google.common.collect.Sets;
29 import fr.ifremer.dali.config.DaliConfiguration;
30 import fr.ifremer.dali.dao.administration.program.DaliProgramDao;
31 import fr.ifremer.dali.dao.administration.strategy.DaliStrategyDao;
32 import fr.ifremer.dali.dao.administration.user.DaliDepartmentDao;
33 import fr.ifremer.dali.dao.administration.user.DaliQuserDao;
34 import fr.ifremer.dali.dao.data.measurement.DaliMeasurementDao;
35 import fr.ifremer.dali.dao.data.photo.DaliPhotoDao;
36 import fr.ifremer.dali.dao.data.samplingoperation.DaliSamplingOperationDao;
37 import fr.ifremer.dali.dao.referential.DaliReferentialDao;
38 import fr.ifremer.dali.dao.referential.monitoringLocation.DaliMonitoringLocationDao;
39 import fr.ifremer.dali.dao.referential.pmfm.DaliPmfmDao;
40 import fr.ifremer.dali.dao.technical.Daos;
41 import fr.ifremer.dali.dao.technical.Geometries;
42 import fr.ifremer.dali.dto.DaliBeanFactory;
43 import fr.ifremer.dali.dto.DaliBeans;
44 import fr.ifremer.dali.dto.configuration.programStrategy.PmfmStrategyDTO;
45 import fr.ifremer.dali.dto.data.measurement.MeasurementDTO;
46 import fr.ifremer.dali.dto.data.photo.PhotoDTO;
47 import fr.ifremer.dali.dto.data.sampling.SamplingOperationDTO;
48 import fr.ifremer.dali.dto.data.survey.CampaignDTO;
49 import fr.ifremer.dali.dto.data.survey.OccasionDTO;
50 import fr.ifremer.dali.dto.data.survey.SurveyDTO;
51 import fr.ifremer.dali.dto.enums.StateValues;
52 import fr.ifremer.dali.dto.enums.SynchronizationStatusValues;
53 import fr.ifremer.dali.dto.referential.PersonDTO;
54 import fr.ifremer.dali.dto.referential.pmfm.PmfmDTO;
55 import fr.ifremer.dali.dto.system.QualificationHistoryDTO;
56 import fr.ifremer.dali.dto.system.ValidationHistoryDTO;
57 import fr.ifremer.dali.service.administration.program.ProgramStrategyService;
58 import fr.ifremer.quadrige3.core.dao.administration.program.Program;
59 import fr.ifremer.quadrige3.core.dao.administration.program.ProgramImpl;
60 import fr.ifremer.quadrige3.core.dao.administration.user.DepartmentImpl;
61 import fr.ifremer.quadrige3.core.dao.administration.user.Quser;
62 import fr.ifremer.quadrige3.core.dao.administration.user.QuserImpl;
63 import fr.ifremer.quadrige3.core.dao.data.survey.CampaignImpl;
64 import fr.ifremer.quadrige3.core.dao.data.survey.OccasionImpl;
65 import fr.ifremer.quadrige3.core.dao.data.survey.Survey;
66 import fr.ifremer.quadrige3.core.dao.data.survey.SurveyDaoImpl;
67 import fr.ifremer.quadrige3.core.dao.referential.*;
68 import fr.ifremer.quadrige3.core.dao.referential.monitoringLocation.MonitoringLocation;
69 import fr.ifremer.quadrige3.core.dao.referential.monitoringLocation.MonitoringLocationImpl;
70 import fr.ifremer.quadrige3.core.dao.referential.monitoringLocation.PositionningSystemImpl;
71 import fr.ifremer.quadrige3.core.dao.referential.pmfm.PmfmImpl;
72 import fr.ifremer.quadrige3.core.dao.system.*;
73 import fr.ifremer.quadrige3.core.dao.system.synchronization.SynchronizationStatus;
74 import fr.ifremer.quadrige3.core.dao.technical.Assert;
75 import fr.ifremer.quadrige3.core.dao.technical.Dates;
76 import org.apache.commons.collections4.CollectionUtils;
77 import org.apache.commons.collections4.IterableUtils;
78 import org.apache.commons.lang3.StringUtils;
79 import org.hibernate.Query;
80 import org.hibernate.Session;
81 import org.hibernate.SessionFactory;
82 import org.hibernate.type.DateType;
83 import org.hibernate.type.IntegerType;
84 import org.hibernate.type.StringType;
85 import org.springframework.beans.factory.InitializingBean;
86 import org.springframework.beans.factory.annotation.Autowired;
87 import org.springframework.dao.DataRetrievalFailureException;
88 import org.springframework.stereotype.Repository;
89
90 import javax.annotation.Resource;
91 import java.math.BigDecimal;
92 import java.sql.Timestamp;
93 import java.util.*;
94 import java.util.stream.Collectors;
95
96 import static org.nuiton.i18n.I18n.t;
97
98
99
100
101
102
103 @Repository("daliSurveyDao")
104 public class DaliSurveyDaoImpl extends SurveyDaoImpl implements DaliSurveyDao, InitializingBean {
105
106 @Resource(name = "daliReferentialDao")
107 private DaliReferentialDao referentialDao;
108
109 @Resource(name = "daliMonitoringLocationDao")
110 private DaliMonitoringLocationDao monitoringLocationDao;
111
112 @Resource(name = "daliDepartmentDao")
113 protected DaliDepartmentDao departmentDao;
114
115 @Resource(name = "daliProgramDao")
116 private DaliProgramDao programDao;
117
118 @Resource(name = "daliStrategyDao")
119 private DaliStrategyDao strategyDao;
120
121 @Resource(name = "daliSamplingOperationDao")
122 private DaliSamplingOperationDao samplingOperationDao;
123
124 @Resource(name = "daliMeasurementDao")
125 private DaliMeasurementDao measurementDao;
126
127 @Resource(name = "daliPhotoDao")
128 private DaliPhotoDao photoDao;
129
130 @Resource(name = "daliQuserDao")
131 private DaliQuserDao quserDao;
132
133 @Resource(name = "objectTypeDao")
134 private ObjectTypeDao objectTypeDao;
135
136 @Resource(name = "validationHistoryDao")
137 private ValidationHistoryExtendDao validationHistoryDao;
138
139 @Resource(name = "qualificationHistoryDao")
140 private QualificationHistoryDao qualificationHistoryDao;
141
142 @Resource(name = "daliPmfmDao")
143 protected DaliPmfmDao pmfmDao;
144
145 @Resource(name = "daliProgramStrategyService")
146 protected ProgramStrategyService programStrategyService;
147
148 @Resource
149 protected DaliConfiguration config;
150
151 private int pmfmIdSurveyCalculatedLength;
152 private int unitIdMeter;
153 private List<Integer[]> trawlAreaPmfmIdsTriplets;
154
155
156
157
158
159
160 @Autowired
161 public DaliSurveyDaoImpl(SessionFactory sessionFactory) {
162 super(sessionFactory);
163 }
164
165
166
167
168 @Override
169 public void afterPropertiesSet() {
170 initConstants();
171 }
172
173 private void initConstants() {
174
175 pmfmIdSurveyCalculatedLength = config.getSurveyCalculatedLengthPmfmId();
176 unitIdMeter = UnitId.METER.getValue();
177 trawlAreaPmfmIdsTriplets = config.getCalculatedTrawlAreaPmfmTriplets();
178
179 if (config.isDbCheckConstantsEnable()) {
180 Session session = getSessionFactory().openSession();
181 try {
182 if (pmfmIdSurveyCalculatedLength > 0) {
183 Assert.notNull(session.get(PmfmImpl.class, pmfmIdSurveyCalculatedLength));
184 }
185 Assert.notNull(session.get(UnitImpl.class, unitIdMeter));
186 trawlAreaPmfmIdsTriplets.forEach(
187 triplet -> Arrays.stream(triplet).forEach(
188 pmfmId -> Assert.notNull(session.get(PmfmImpl.class, pmfmId)))
189 );
190 } finally {
191 Daos.closeSilently(session);
192 }
193
194 }
195
196 }
197
198
199
200
201 @Override
202 @SuppressWarnings("unchecked")
203 public List<SurveyDTO> getSurveysByCriteria(Integer campaignId, Collection<String> programCodes, Integer locationId, String name, String comment, Integer stateId, Integer synchronizationStatusId,
204 Date startDate, Date endDate, boolean strictDate) {
205
206 Assert.notEmpty(programCodes, "programCodes must not be empty");
207
208
209 StringBuilder queryString = new StringBuilder(getSession().getNamedQuery("surveysByCriteria").getQueryString());
210
211
212 if (stateId != null) {
213 if (stateId.equals(StateValues.CONTROLLED.ordinal())) {
214 queryString.append(System.lineSeparator());
215 queryString.append("AND s.surveyControlDt is not null AND s.surveyValidDt is null");
216 } else if (stateId.equals(StateValues.VALIDATED.ordinal())) {
217 queryString.append(System.lineSeparator());
218 queryString.append("AND s.surveyValidDt is not null AND s.surveyQualifDt is null");
219 } else if (stateId.equals(StateValues.QUALIFIED.ordinal())) {
220 queryString.append(System.lineSeparator());
221 queryString.append("AND s.surveyQualifDt is not null");
222 }
223 }
224
225
226 if (synchronizationStatusId != null) {
227 SynchronizationStatusValues synchronizationStatus = SynchronizationStatusValues.fromOrdinal(synchronizationStatusId);
228
229 if (synchronizationStatus == SynchronizationStatusValues.DIRTY) {
230 queryString.append(System.lineSeparator())
231 .append("AND s.synchronizationStatus IN ('")
232 .append(synchronizationStatus.getCode())
233 .append("','")
234 .append(SynchronizationStatusValues.READY_TO_SYNCHRONIZE.getCode())
235 .append("')");
236 } else {
237 queryString.append(System.lineSeparator())
238 .append("AND s.synchronizationStatus = '")
239 .append(synchronizationStatus.getCode())
240 .append('\'');
241 }
242 } else {
243
244 queryString.append(System.lineSeparator())
245 .append("AND s.synchronizationStatus <> '")
246 .append(SynchronizationStatus.DELETED.getValue())
247 .append('\'');
248 }
249
250 if (startDate != null && endDate != null) {
251 if (startDate == endDate) {
252
253 queryString.append(System.lineSeparator());
254 queryString.append("AND s.surveyDt = ");
255 queryString.append(Daos.convertDateOnlyToSQLString(startDate));
256 } else {
257
258 queryString.append(System.lineSeparator());
259 queryString.append("AND s.surveyDt >= ");
260 queryString.append(Daos.convertDateOnlyToSQLString(startDate));
261 queryString.append("AND s.surveyDt <= ");
262 queryString.append(Daos.convertDateOnlyToSQLString(endDate));
263 }
264 } else if (startDate != null) {
265
266 queryString.append(System.lineSeparator());
267 queryString.append("AND s.surveyDt ");
268 queryString.append((strictDate ? "> " : ">= "));
269 queryString.append(Daos.convertDateOnlyToSQLString(startDate));
270 } else if (endDate != null) {
271
272 queryString.append(System.lineSeparator());
273 queryString.append("AND s.surveyDt ");
274 queryString.append((strictDate ? "< " : "<= "));
275 queryString.append(Daos.convertDateOnlyToSQLString(endDate));
276 }
277
278
279 Query q = getSession().createQuery(queryString.toString());
280 setQueryParams(q, "surveysByCriteria",
281 "campaignId", IntegerType.INSTANCE, campaignId,
282 "locationId", IntegerType.INSTANCE, locationId,
283 "name", StringType.INSTANCE, name,
284 "comment", StringType.INSTANCE, comment);
285 q.setParameterList("programCodes", programCodes);
286
287 Iterator<Object[]> it = q.iterate();
288
289 List<SurveyDTO> result = Lists.newArrayList();
290 while (it.hasNext()) {
291 Object[] source = it.next();
292 result.add(toSurveyDTO(Arrays.asList(source).iterator()));
293 }
294
295 return result;
296 }
297
298
299
300
301 @Override
302 public long countSurveysWithProgramAndLocations(String programCode, List<Integer> locationIds) {
303
304 Query query;
305 Set<Integer> locationIdsSet = locationIds != null ? locationIds.stream().filter(Objects::nonNull).collect(Collectors.toSet()) : null;
306 if (CollectionUtils.isNotEmpty(locationIdsSet)) {
307 query = createQuery("countSurveysByProgramAndLocations", "programCode", StringType.INSTANCE, programCode);
308 query.setParameterList("locationIds", locationIdsSet);
309 } else {
310 query = createQuery("countSurveysByProgram", "programCode", StringType.INSTANCE, programCode);
311 }
312 return queryCount(query);
313 }
314
315 @Override
316 public long countSurveysWithProgramLocationAndOutsideDates(String programCode, int appliedStrategyId, int locationId, Date startDate, Date endDate) {
317
318 return queryCount("countSurveysByProgramLocationAndOutsideDates",
319 "programCode", StringType.INSTANCE, programCode,
320 "locationId", IntegerType.INSTANCE, locationId,
321 "appliedStrategyId", IntegerType.INSTANCE, appliedStrategyId,
322 "startDate", DateType.INSTANCE, startDate,
323 "endDate", DateType.INSTANCE, endDate,
324 "synchronizationStatusToIgnore", StringType.INSTANCE, SynchronizationStatus.DELETED.getValue()
325 );
326 }
327
328 @Override
329 public long countSurveysWithProgramLocationAndInsideDates(String programCode, int appliedStrategyId, int locationId, Date startDate, Date endDate) {
330
331 return queryCount("countSurveysByProgramLocationAndInsideDates",
332 "programCode", StringType.INSTANCE, programCode,
333 "locationId", IntegerType.INSTANCE, locationId,
334 "appliedStrategyId", IntegerType.INSTANCE, appliedStrategyId,
335 "startDate", DateType.INSTANCE, startDate,
336 "endDate", DateType.INSTANCE, endDate,
337 "synchronizationStatusToIgnore", StringType.INSTANCE, SynchronizationStatus.DELETED.getValue()
338 );
339 }
340
341
342
343
344 @Override
345 public SurveyDTO getSurveyById(int surveyId, boolean dontExcludePmfm) {
346
347 Object[] row = queryUnique("surveyById",
348 "surveyId", IntegerType.INSTANCE, surveyId);
349
350 if (row == null) {
351 throw new DataRetrievalFailureException("can't load survey with id = " + surveyId);
352 }
353
354 SurveyDTO survey = toSurveyDTO(Arrays.asList(row).iterator());
355
356
357 survey.setObservers(getObservers(survey.getId()));
358 survey.setObserversLoaded(true);
359
360
361 loadMeasurements(survey);
362
363
364 survey.setSamplingOperations(samplingOperationDao.getSamplingOperationsBySurveyId(survey.getId(), true));
365 survey.setSamplingOperationsLoaded(true);
366
367
368 survey.setPhotos(photoDao.getPhotosBySurveyId(survey.getId()));
369 survey.setPhotosLoaded(true);
370
371
372 if (!survey.isPhotosEmpty() && !survey.isSamplingOperationsEmpty()) {
373 Map<Integer, SamplingOperationDTO> samplingOperationMap = DaliBeans.mapById(survey.getSamplingOperations());
374 for (PhotoDTO photo : survey.getPhotos()) {
375 if (photo.getSamplingOperation() != null && photo.getSamplingOperation().getId() != null) {
376
377 SamplingOperationDTO samplingOperation = samplingOperationMap.get(photo.getSamplingOperation().getId());
378 if (samplingOperation == null) {
379 throw new DataRetrievalFailureException(
380 String.format("the sampling operation (id=%s) associated with the photo (id=%s) has not been loaded",
381 photo.getSamplingOperation().getId(), photo.getId()));
382 }
383 photo.setSamplingOperation(samplingOperation);
384 }
385 }
386 }
387
388 return survey;
389 }
390
391 private void loadMeasurements(SurveyDTO survey, Integer... excludePmfmId) {
392
393 List<MeasurementDTO> allMeasurements = measurementDao.getMeasurementsBySurveyId(survey.getId(), excludePmfmId);
394 if (CollectionUtils.isNotEmpty(allMeasurements)) {
395
396
397 for (MeasurementDTO measurement : allMeasurements) {
398
399 if (measurement.getIndividualId() != null) {
400
401 survey.addIndividualMeasurements(measurement);
402 } else {
403 survey.addMeasurements(measurement);
404 }
405 }
406 }
407
408 survey.setMeasurementsLoaded(true);
409 }
410
411
412
413
414 @Override
415 public List<PersonDTO> getObservers(int surveyId) {
416
417 List<PersonDTO> observers = Lists.newArrayList();
418 Iterator<Integer> it = queryIteratorTyped("quserIdsBySurveyId", "surveyId", IntegerType.INSTANCE, surveyId);
419 while (it.hasNext()) {
420 Integer quserId = it.next();
421 if (quserId != null) {
422 observers.add(quserDao.getUserById(quserId));
423 }
424 }
425 return observers;
426 }
427
428
429
430
431 @Override
432 public SurveyDTO save(SurveyDTO bean) {
433 Assert.notNull(bean);
434 Assert.notNull(bean.getLocation());
435 Assert.notNull(bean.getLocation().getId());
436 Assert.notNull(bean.getDepartment());
437 Assert.notNull(bean.getDepartment().getId());
438 Assert.notNull(bean.getProgram());
439 Assert.notNull(bean.getProgram().getCode());
440 Assert.notNull(bean.getDate());
441
442 Survey entity;
443 boolean programChanged = false;
444 if (bean.getId() == null) {
445 entity = Survey.Factory.newInstance();
446 } else {
447 entity = get(bean.getId());
448 if (entity == null) {
449 throw new DataRetrievalFailureException("Could not retrieve survey with id=" + bean.getId());
450 }
451
452
453 programChanged = !hasSameProgram(bean, entity);
454 }
455
456 beanToEntity(bean, entity);
457 update(entity);
458
459
460 boolean geometrySaved = saveGeometry(bean, entity);
461
462
463 if (geometrySaved && pmfmIdSurveyCalculatedLength > 0) {
464
465
466 Set<PmfmStrategyDTO> pmfmStrategies = strategyDao.getPmfmStrategiesByProgramCodeAndLocation(
467 bean.getProgram().getCode(), bean.getLocation().getId(), bean.getDate());
468
469
470 if (pmfmStrategies.stream().anyMatch(pmfmStrategy ->
471 pmfmStrategy.getPmfm().getId() == pmfmIdSurveyCalculatedLength
472 && pmfmStrategy.isSurvey() && !pmfmStrategy.isSampling() && !pmfmStrategy.isGrouping())) {
473
474
475 if (!bean.isMeasurementsLoaded())
476 loadMeasurements(bean);
477
478 calculateLength(bean, pmfmIdSurveyCalculatedLength);
479 }
480 }
481
482
483 if (CollectionUtils.isNotEmpty(trawlAreaPmfmIdsTriplets)) {
484
485 for (Integer[] triplet : trawlAreaPmfmIdsTriplets) {
486
487 int trawlAreaPmfmId = triplet[0];
488 int lengthPmfmId = triplet[1];
489 int trawlOpeningPmfmId = triplet[2];
490
491 if (!isPmfmUnitValidForAreaCalculation(trawlAreaPmfmId, ImmutableList.of(lengthPmfmId, trawlOpeningPmfmId))) {
492
493 continue;
494 }
495
496
497 Set<PmfmStrategyDTO> pmfmStrategies = strategyDao.getPmfmStrategiesByProgramCodeAndLocation(
498 bean.getProgram().getCode(), bean.getLocation().getId(), bean.getDate());
499 List<PmfmStrategyDTO> surveyStrategies = pmfmStrategies.stream()
500 .filter(pmfmStrategy -> pmfmStrategy.isSurvey() && !pmfmStrategy.isSampling() && !pmfmStrategy.isGrouping()).collect(Collectors.toList());
501
502 if (surveyStrategies.stream().anyMatch(pmfmStrategy -> pmfmStrategy.getPmfm().getId() == trawlAreaPmfmId)
503 && surveyStrategies.stream().anyMatch(pmfmStrategy -> pmfmStrategy.getPmfm().getId() == lengthPmfmId)
504 && surveyStrategies.stream().anyMatch(pmfmStrategy -> pmfmStrategy.getPmfm().getId() == trawlOpeningPmfmId)) {
505
506
507 if (!bean.isMeasurementsLoaded())
508 loadMeasurements(bean);
509
510
511 calculateArea(bean, trawlAreaPmfmId, lengthPmfmId, trawlOpeningPmfmId);
512
513
514 break;
515 }
516 }
517 }
518
519
520 if (bean.isMeasurementsLoaded()) {
521 List<MeasurementDTO> allMeasurements = Lists.newArrayList();
522 allMeasurements.addAll(bean.getMeasurements());
523 allMeasurements.addAll(bean.getIndividualMeasurements());
524 measurementDao.saveMeasurementsBySurveyId(bean.getId(), allMeasurements);
525 }
526
527
528 if (bean.isSamplingOperationsLoaded()) {
529 samplingOperationDao.saveSamplingOperationsBySurveyId(bean.getId(), bean.getSamplingOperations());
530 }
531
532
533 if (bean.isPhotosLoaded()) {
534 photoDao.savePhotosBySurveyId(bean.getId(), bean.getPhotos());
535 }
536
537
538 if (programChanged) {
539 applySurveyProgramsToChildren(bean.getId());
540 }
541
542 getSession().flush();
543 getSession().clear();
544
545
546 updateHasMeasFlag(bean.getId());
547 samplingOperationDao.updateHasMeasFlagBySurveyId(bean.getId());
548
549 return bean;
550 }
551
552
553
554
555 @Override
556 public void remove(List<Integer> surveyIds) {
557 if (CollectionUtils.isNotEmpty(surveyIds)) {
558 for (Integer surveyId : surveyIds) {
559 remove(surveyId);
560 }
561 }
562 }
563
564
565
566
567 @Override
568 public void remove(Integer surveyId) {
569
570 if (surveyId != null) {
571
572
573 photoDao.removeBySurveyId(surveyId);
574 measurementDao.removeAllMeasurementsBySurveyId(surveyId);
575 samplingOperationDao.removeBySurveyId(surveyId);
576
577 super.remove(surveyId);
578 getSession().flush();
579 getSession().clear();
580 }
581 }
582
583
584
585
586 @Override
587 public void validate(int surveyId, String validationComment, Date validationDate, Integer validatorId, boolean readyToSynchronize) {
588 Survey survey = get(surveyId);
589
590
591 survey.setSurveyValidDt(validationDate);
592
593
594 String oldSurveyValidCm = survey.getSurveyValidCm();
595 if (StringUtils.isBlank(oldSurveyValidCm)) {
596
597 oldSurveyValidCm = validationHistoryDao.getLastValidationComment(surveyId, ObjectTypeCode.SURVEY.getValue());
598 }
599 survey.setSurveyValidCm(validationComment);
600
601
602 survey.setSynchronizationStatus(readyToSynchronize
603 ? SynchronizationStatus.READY_TO_SYNCHRONIZE.getValue()
604 : SynchronizationStatus.DIRTY.getValue());
605
606
607 survey.setSurveyScope(Daos.convertToString(true));
608
609
610 survey.setSurveyGeometryValidDt(validationDate);
611
612
613 ValidationHistory history = ValidationHistory.Factory.newInstance(
614 surveyId,
615 objectTypeDao.get(ObjectTypeCode.SURVEY.getValue()),
616 quserDao.get(validatorId)
617 );
618 history.setValidHistPreviousCm(oldSurveyValidCm);
619 history.setValidHistOperationCm(validationComment);
620 history.setUpdateDt(new Timestamp(validationDate.getTime()));
621
622 validationHistoryDao.create(history);
623
624 update(survey);
625 getSession().flush();
626 getSession().clear();
627 }
628
629
630
631
632 @Override
633 public void unvalidate(int surveyId, String unvalidationComment, Date unvalidationDate, Integer validatorId) {
634 Survey survey = get(surveyId);
635
636
637 survey.setSurveyValidDt(null);
638
639
640 survey.setSurveyQualifDt(null);
641 survey.setSurveyQualifCm(null);
642
643
644 QualityFlag oldQualityFlag = survey.getQualityFlag();
645 survey.setQualityFlag(getDefaultQualityFlag());
646
647 String oldSurveyValidCm = survey.getSurveyValidCm();
648 survey.setSurveyValidCm(null);
649
650
651 survey.setSynchronizationStatus(SynchronizationStatus.DIRTY.getValue());
652
653
654 survey.setSurveyGeometryValidDt(null);
655
656
657 ValidationHistory validationHistory = ValidationHistory.Factory.newInstance(
658 surveyId,
659 objectTypeDao.get(ObjectTypeCode.SURVEY.getValue()),
660 quserDao.get(validatorId)
661 );
662 validationHistory.setValidHistPreviousCm(oldSurveyValidCm);
663 validationHistory.setValidHistOperationCm(unvalidationComment);
664 validationHistory.setUpdateDt(new Timestamp(unvalidationDate.getTime()));
665 validationHistoryDao.create(validationHistory);
666
667
668 QualificationHistory qualificationHistory = QualificationHistory.Factory.newInstance(String.valueOf(surveyId),
669 objectTypeDao.get(ObjectTypeCode.SURVEY.getValue()),
670 quserDao.get(validatorId));
671 qualificationHistory.setQualHistOperationCm("Dévalidation");
672
673 qualificationHistory.setQualityFlag(oldQualityFlag);
674 qualificationHistory.setUpdateDt(new Timestamp(unvalidationDate.getTime()));
675
676 qualificationHistoryDao.create(qualificationHistory);
677
678 update(survey);
679 }
680
681 @Override
682 public void qualify(int surveyId, String qualificationComment, Date qualificationDate, Integer validatorId, String qualityFlagCode) {
683 Survey survey = get(surveyId);
684
685
686 survey.setSurveyQualifDt(qualificationDate);
687
688
689 String oldSurveyQualifCm = survey.getSurveyQualifCm();
690 survey.setSurveyQualifCm(qualificationComment);
691
692
693 QualityFlag qualifiedQualityFlag = load(QualityFlagImpl.class, qualityFlagCode);
694 survey.setQualityFlag(qualifiedQualityFlag);
695
696
697 survey.setSynchronizationStatus(SynchronizationStatus.READY_TO_SYNCHRONIZE.getValue());
698
699
700 survey.setSurveyScope(Daos.convertToString(true));
701
702
703 QualificationHistory history = QualificationHistoryImpl.Factory.newInstance(String.valueOf(surveyId),
704 objectTypeDao.get(ObjectTypeCode.SURVEY.getValue()),
705 quserDao.get(validatorId));
706 history.setQualHistPreviousCm(oldSurveyQualifCm);
707 history.setQualHistOperationCm(qualificationComment);
708 history.setUpdateDt(new Timestamp(qualificationDate.getTime()));
709 history.setQualityFlag(qualifiedQualityFlag);
710
711 qualificationHistoryDao.create(history);
712
713 update(survey);
714 getSession().flush();
715 getSession().clear();
716 }
717
718 @Override
719 public List<ValidationHistoryDTO> getValidationHistory(int surveyId) {
720 List<ValidationHistoryDTO> result = new ArrayList<>();
721 Iterator<Object[]> rows = queryIterator("validationHistoryBySurveyId",
722 "objectTypeCd", StringType.INSTANCE, ObjectTypeCode.SURVEY.getValue(),
723 "surveyId", IntegerType.INSTANCE, surveyId);
724 while (rows.hasNext()) {
725 result.add(toValidationHistoryDTO(Arrays.asList(rows.next()).iterator()));
726 }
727 return result;
728 }
729
730 @Override
731 public List<QualificationHistoryDTO> getQualificationHistory(int surveyId) {
732 List<QualificationHistoryDTO> result = new ArrayList<>();
733 Iterator<Object[]> rows = queryIterator("qualificationHistoryBySurveyId",
734 "objectTypeCd", StringType.INSTANCE, ObjectTypeCode.SURVEY.getValue(),
735 "surveyId", StringType.INSTANCE, String.valueOf(surveyId));
736 while (rows.hasNext()) {
737 result.add(toQualificationHistoryDTO(Arrays.asList(rows.next()).iterator()));
738 }
739 return result;
740 }
741
742
743
744
745 @Override
746 public void updateSurveysControlDate(Collection<Integer> surveyIds, Date controlDate) {
747 createQuery("updateSurveyControlDate")
748 .setParameterList("surveyIds", surveyIds)
749 .setParameter("controlDate", controlDate).executeUpdate();
750 }
751
752
753
754
755 private SurveyDTO toSurveyDTO(Iterator<Object> source) {
756 SurveyDTO result = DaliBeanFactory.newSurveyDTO();
757 result.setId((Integer) source.next());
758
759
760 Integer locationId = (Integer) source.next();
761 result.setLocation(monitoringLocationDao.getLocationById(locationId));
762
763
764 Integer departmentId = (Integer) source.next();
765 result.setDepartment(departmentDao.getDepartmentById(departmentId));
766
767
768 result.setDate(Dates.convertToLocalDate(Daos.convertToDate(source.next()), config.getDbTimezone()));
769
770 result.setTime(Daos.convertToInteger((Number) source.next()));
771 result.setName((String) source.next());
772 result.setComment((String) source.next());
773 result.setControlDate(Daos.convertToDate(source.next()));
774 result.setValidationDate(Daos.convertToDate(source.next()));
775 result.setValidationComment((String) source.next());
776 result.setQualificationDate(Daos.convertToDate(source.next()));
777 result.setQualificationComment((String) source.next());
778 result.setUpdateDate(Daos.convertToDate(source.next()));
779 result.setBottomDepth(Daos.convertToDouble((Float) source.next()));
780
781
782 String programCode = (String) source.next();
783 if (StringUtils.isNotBlank(programCode)) {
784 result.setProgram(programDao.getProgramByCode(programCode));
785 }
786
787
788 CampaignDTO campaign = DaliBeanFactory.newCampaignDTO();
789 campaign.setId((Integer) source.next());
790 campaign.setName((String) source.next());
791 campaign.setStartDate(Daos.convertToDate(source.next()));
792 campaign.setEndDate(Daos.convertToDate(source.next()));
793 if (campaign.getId() != null) {
794 result.setCampaign(campaign);
795 }
796
797
798 Integer positioningSystemId = (Integer) source.next();
799
800 result.setPositioningComment((String) source.next());
801
802
803 OccasionDTO occasion = DaliBeanFactory.newOccasionDTO();
804 occasion.setId((Integer) source.next());
805 occasion.setName((String) source.next());
806 if (occasion.getId() != null) {
807 result.setOccasion(occasion);
808 }
809
810
811 boolean isActualPosition = Daos.safeConvertToBoolean(source.next(), false);
812
813
814
815 String geometryStr = (String) source.next();
816 if (isActualPosition) {
817 result.setCoordinate(Geometries.getCoordinate(geometryStr));
818
819 if (positioningSystemId != null) {
820 result.setPositioning(referentialDao.getPositioningSystemById(positioningSystemId));
821 }
822 }
823
824
825 result.setSynchronizationStatus(SynchronizationStatusValues.toSynchronizationStatusDTO((String) source.next()));
826
827
828 result.setQualityLevel(referentialDao.getQualityFlagByCode((String) source.next()));
829
830 return result;
831 }
832
833 private ValidationHistoryDTO toValidationHistoryDTO(Iterator<Object> source) {
834 ValidationHistoryDTO result = DaliBeanFactory.newValidationHistoryDTO();
835 result.setDate(Daos.convertToDate(source.next()));
836 result.setComment((String) source.next());
837 result.setRecorderPerson(quserDao.getUserById((Integer) source.next()));
838 return result;
839 }
840
841 private QualificationHistoryDTO toQualificationHistoryDTO(Iterator<Object> source) {
842 QualificationHistoryDTO result = DaliBeanFactory.newQualificationHistoryDTO();
843 result.setDate(Daos.convertToDate(source.next()));
844 result.setComment((String) source.next());
845 String qualityCode = (String) source.next();
846 if (qualityCode != null) result.setQualityLevel(referentialDao.getQualityFlagByCode(qualityCode));
847 result.setRecorderPerson(quserDao.getUserById((Integer) source.next()));
848 return result;
849 }
850
851 private void beanToEntity(SurveyDTO bean, Survey entity) {
852
853
854
855
856 if (entity.getQualityFlag() == null) {
857
858 entity.setQualityFlag(getDefaultQualityFlag());
859 }
860
861
862 if (entity.getMonitoringLocation() == null
863 || entity.getMonitoringLocation().getMonLocId() == null
864 || !entity.getMonitoringLocation().getMonLocId().equals(bean.getLocation().getId())) {
865 entity.setMonitoringLocation(load(MonitoringLocationImpl.class, bean.getLocation().getId()));
866 }
867
868
869
870
871
872
873
874
875
876
877
878
879
880 entity.setSurveyUtFormat(entity.getMonitoringLocation().getMonLocUtFormat());
881
882
883 if (entity.getRecorderDepartment() == null) {
884 entity.setRecorderDepartment(load(DepartmentImpl.class, bean.getDepartment().getId()));
885 }
886
887
888 Date beanDate = Dates.convertToDate(bean.getDate(), config.getDbTimezone());
889 if (entity.getSurveyDt() == null || !entity.getSurveyDt().equals(beanDate)) {
890 entity.setSurveyDt(beanDate);
891 }
892
893
894 if (bean.getProgram() != null) {
895
896 Set<Program> remainingPrograms = Sets.newHashSet(entity.getPrograms());
897
898 Program program = load(ProgramImpl.class, bean.getProgram().getCode());
899 if (!entity.getPrograms().contains(program)) {
900 entity.addPrograms(program);
901 }
902 remainingPrograms.remove(program);
903
904 entity.getPrograms().removeAll(remainingPrograms);
905 } else {
906 entity.getPrograms().clear();
907 }
908
909
910 entity.setSynchronizationStatus(SynchronizationStatus.DIRTY.getValue());
911
912 bean.setSynchronizationStatus(SynchronizationStatusValues.DIRTY.toSynchronizationStatusDTO());
913
914
915 if (entity.getSurveyId() == null) {
916 create(entity);
917 bean.setId(entity.getSurveyId());
918 }
919
920
921 entity.setSurveyTime(bean.getTime());
922 entity.setSurveyLb(bean.getName());
923 entity.setSurveyCm(bean.getComment());
924 entity.setSurveyControlDt(bean.getControlDate());
925
926
927 if (bean.getBottomDepth() == null) {
928 entity.setSurveyBottomDepth(null);
929
930 entity.setBottomDepthUnit(null);
931 } else {
932
933 entity.setSurveyBottomDepth(bean.getBottomDepth().floatValue());
934
935
936 entity.setBottomDepthUnit(load(UnitImpl.class, unitIdMeter));
937 }
938
939
940 if (bean.getCampaign() != null) {
941 entity.setCampaign(load(CampaignImpl.class, bean.getCampaign().getId()));
942 } else {
943 entity.setCampaign(null);
944 }
945
946
947 if (bean.getPositioning() != null) {
948 entity.setPositionningSystem(load(PositionningSystemImpl.class, bean.getPositioning().getId()));
949 } else {
950 entity.setPositionningSystem(null);
951 }
952 entity.setSurveyPositionCm(bean.getPositioningComment());
953
954
955 if (bean.getOccasion() != null) {
956 entity.setOccasion(load(OccasionImpl.class, bean.getOccasion().getId()));
957 } else {
958 entity.setOccasion(null);
959 }
960
961
962 if (bean.isObserversLoaded()) {
963 if (!bean.isObserversEmpty()) {
964
965 Map<Integer, Quser> remainingUsers = DaliBeans.mapByProperty(entity.getQusers(), "quserId");
966
967 for (PersonDTO observer : bean.getObservers()) {
968 if (remainingUsers.remove(observer.getId()) == null) {
969
970 Quser quser = load(QuserImpl.class, observer.getId());
971 entity.addQusers(quser);
972 }
973 }
974
975 if (!remainingUsers.isEmpty()) {
976 entity.getQusers().removeAll(remainingUsers.values());
977 }
978
979 } else if (entity.getQusers() != null) {
980 entity.getQusers().clear();
981 }
982 }
983 }
984
985 private boolean hasSameProgram(SurveyDTO bean, Survey entity) {
986
987 String beanProgCd = bean.getProgram() != null ? bean.getProgram().getCode() : null;
988
989 List<String> entityProgCds = CollectionUtils.isNotEmpty(entity.getPrograms())
990 ? DaliBeans.collectProperties(entity.getPrograms(), "progCd")
991 : null;
992
993 return (beanProgCd == null && entityProgCds == null)
994 || (CollectionUtils.size(entityProgCds) == 1 && Objects.equals(beanProgCd, IterableUtils.get(entityProgCds, 0)));
995 }
996
997 private boolean saveGeometry(SurveyDTO bean, Survey entity) {
998
999 boolean geometrySaved = false;
1000
1001
1002 if (Geometries.isValid(bean.getCoordinate())) {
1003
1004 if (Geometries.isPoint(bean.getCoordinate())) {
1005
1006
1007 if (CollectionUtils.size(entity.getSurveyPoints()) == 1) {
1008
1009 SurveyPoint surveyPointToUpdate = CollectionUtils.extractSingleton(entity.getSurveyPoints());
1010 if (!Geometries.equals(bean.getCoordinate(), surveyPointToUpdate.getSurveyPosition())) {
1011 surveyPointToUpdate.setSurveyPosition(Geometries.getPosition(bean.getCoordinate()));
1012 getSession().update(surveyPointToUpdate);
1013 }
1014
1015 } else {
1016
1017 SurveyPoint surveyPoint = SurveyPoint.Factory.newInstance();
1018 surveyPoint.setSurvey(entity);
1019 surveyPoint.setSurveyPosition(Geometries.getPosition(bean.getCoordinate()));
1020 getSession().save(surveyPoint);
1021 entity.getSurveyPoints().clear();
1022 entity.addSurveyPoints(surveyPoint);
1023 }
1024
1025
1026 entity.getSurveyLines().clear();
1027
1028 }
1029
1030
1031 else {
1032
1033
1034 if (CollectionUtils.size(entity.getSurveyLines()) == 1) {
1035
1036 SurveyLine surveyLine = CollectionUtils.extractSingleton(entity.getSurveyLines());
1037 if (!Geometries.equals(bean.getCoordinate(), surveyLine.getSurveyPosition())) {
1038 surveyLine.setSurveyPosition(Geometries.getPosition(bean.getCoordinate()));
1039 getSession().update(surveyLine);
1040 }
1041 }
1042
1043
1044 else {
1045
1046 SurveyLine surveyLine = SurveyLine.Factory.newInstance();
1047 surveyLine.setSurvey(entity);
1048 surveyLine.setSurveyPosition(Geometries.getPosition(bean.getCoordinate()));
1049 getSession().save(surveyLine);
1050 entity.getSurveyLines().clear();
1051 entity.addSurveyLines(surveyLine);
1052 }
1053
1054
1055 entity.getSurveyPoints().clear();
1056 }
1057
1058
1059 entity.setSurveyActualPosition(Daos.convertToString(true));
1060
1061
1062 entity.getSurveyAreas().clear();
1063
1064 geometrySaved = true;
1065 }
1066
1067
1068 else if (bean.getLocation() != null && bean.getLocation().getId() != null) {
1069
1070
1071 geometrySaved = saveGeometryAndPositioningFromLocation(entity, bean.getLocation().getId());
1072 }
1073
1074
1075 else {
1076 removeGeometry(entity);
1077 }
1078
1079
1080
1081 update(entity);
1082
1083 return geometrySaved;
1084 }
1085
1086 private boolean saveGeometryAndPositioningFromLocation(Survey entity, int monLocId) {
1087
1088 boolean geometrySaved = false;
1089
1090
1091 MonitoringLocation location = load(MonitoringLocationImpl.class, monLocId);
1092
1093
1094 if (CollectionUtils.size(location.getMonLocPoints()) == 1) {
1095 MonLocPoint locationPoint = CollectionUtils.extractSingleton(location.getMonLocPoints());
1096
1097
1098 if (CollectionUtils.size(entity.getSurveyPoints()) == 1) {
1099 SurveyPoint surveyPoint = CollectionUtils.extractSingleton(entity.getSurveyPoints());
1100 if (!Objects.equals(locationPoint.getMonLocPosition(), surveyPoint.getSurveyPosition())) {
1101 surveyPoint.setSurveyPosition(locationPoint.getMonLocPosition());
1102 getSession().update(surveyPoint);
1103 geometrySaved = true;
1104 }
1105 }
1106
1107
1108 else {
1109 SurveyPoint surveyPoint = SurveyPoint.Factory.newInstance();
1110 surveyPoint.setSurvey(entity);
1111 surveyPoint.setSurveyPosition(locationPoint.getMonLocPosition());
1112 getSession().save(surveyPoint);
1113 entity.getSurveyPoints().clear();
1114 entity.addSurveyPoints(surveyPoint);
1115 geometrySaved = true;
1116 }
1117
1118
1119 entity.getSurveyLines().clear();
1120 entity.getSurveyAreas().clear();
1121 }
1122
1123
1124 else if (CollectionUtils.size(location.getMonLocLines()) == 1) {
1125 MonLocLine locationLine = CollectionUtils.extractSingleton(location.getMonLocLines());
1126
1127
1128 if (CollectionUtils.size(entity.getSurveyLines()) == 1) {
1129 SurveyLine surveyLine = CollectionUtils.extractSingleton(entity.getSurveyLines());
1130 if (!Objects.equals(locationLine.getMonLocPosition(), surveyLine.getSurveyPosition())) {
1131 surveyLine.setSurveyPosition(locationLine.getMonLocPosition());
1132 getSession().update(surveyLine);
1133 geometrySaved = true;
1134 }
1135 }
1136
1137
1138 else {
1139 SurveyLine surveyLine = SurveyLine.Factory.newInstance();
1140 surveyLine.setSurvey(entity);
1141 surveyLine.setSurveyPosition(locationLine.getMonLocPosition());
1142 getSession().save(surveyLine);
1143 entity.getSurveyLines().clear();
1144 entity.addSurveyLines(surveyLine);
1145 geometrySaved = true;
1146 }
1147
1148
1149 entity.getSurveyPoints().clear();
1150 entity.getSurveyAreas().clear();
1151 }
1152
1153
1154 else if (CollectionUtils.size(location.getMonLocAreas()) == 1) {
1155 MonLocArea locationArea = CollectionUtils.extractSingleton(location.getMonLocAreas());
1156
1157
1158 if (CollectionUtils.size(entity.getSurveyAreas()) == 1) {
1159 SurveyArea surveyArea = CollectionUtils.extractSingleton(entity.getSurveyAreas());
1160 if (!Objects.equals(locationArea.getMonLocPosition(), surveyArea.getSurveyPosition())) {
1161 surveyArea.setSurveyPosition(locationArea.getMonLocPosition());
1162 getSession().update(surveyArea);
1163 geometrySaved = true;
1164 }
1165 }
1166
1167
1168 else {
1169 SurveyArea surveyArea = SurveyArea.Factory.newInstance();
1170 surveyArea.setSurvey(entity);
1171 surveyArea.setSurveyPosition(locationArea.getMonLocPosition());
1172 getSession().save(surveyArea);
1173 entity.getSurveyAreas().clear();
1174 entity.addSurveyAreas(surveyArea);
1175 geometrySaved = true;
1176 }
1177
1178
1179 entity.getSurveyPoints().clear();
1180 entity.getSurveyLines().clear();
1181 }
1182
1183
1184 entity.setSurveyActualPosition(Daos.convertToString(false));
1185
1186
1187 entity.setPositionningSystem(location.getPositionningSystem());
1188
1189 return geometrySaved;
1190 }
1191
1192 private void removeGeometry(Survey entity) {
1193
1194 entity.getSurveyPoints().clear();
1195 entity.getSurveyLines().clear();
1196 entity.getSurveyAreas().clear();
1197
1198
1199 entity.setSurveyActualPosition(Daos.convertToString(false));
1200 }
1201
1202 private void calculateLength(SurveyDTO survey, int calculatedLengthPmfmId) {
1203
1204 PmfmDTO pmfm = pmfmDao.getPmfmById(calculatedLengthPmfmId);
1205 Assert.notNull(pmfm);
1206 BigDecimal length = null;
1207
1208 Double lengthInMeter = Geometries.getDistanceInMeter(survey.getCoordinate());
1209 if (lengthInMeter != null) {
1210
1211 length = DaliBeans.convertLengthValue(
1212 BigDecimal.valueOf(lengthInMeter),
1213 UnitId.METER.getValue(),
1214 pmfm.getUnit().getId());
1215 }
1216
1217
1218 MeasurementDTO measurement = DaliBeans.getMeasurementByPmfmId(survey, calculatedLengthPmfmId);
1219
1220 if (length != null) {
1221 if (measurement == null) {
1222
1223 measurement = DaliBeanFactory.newMeasurementDTO();
1224 measurement.setPmfm(pmfm);
1225 survey.addMeasurements(measurement);
1226 }
1227
1228
1229 if (Objects.equals(pmfm.getUnit().getId(), UnitId.METER.getValue())
1230 || Objects.equals(pmfm.getUnit().getId(), UnitId.CENTIMENTER.getValue())
1231 || Objects.equals(pmfm.getUnit().getId(), UnitId.MILLIMETER.getValue())
1232 || Objects.equals(pmfm.getUnit().getId(), UnitId.MICROMETER.getValue())) {
1233
1234
1235 length = length.setScale(0, BigDecimal.ROUND_HALF_EVEN);
1236 measurement.setDigitNb(0);
1237
1238 } else {
1239
1240 length = length.setScale(3, BigDecimal.ROUND_HALF_EVEN);
1241 measurement.setDigitNb(3);
1242 }
1243
1244
1245 measurement.setNumericalValue(length);
1246 measurement.setComment(t("dali.service.data.survey.calculatedLength.comment"));
1247
1248
1249 measurement.setAnalyst(programStrategyService.getAnalysisDepartmentOfAppliedStrategyBySurvey(survey));
1250
1251 } else if (measurement != null) {
1252
1253
1254 survey.removeMeasurements(measurement);
1255 }
1256 }
1257
1258 private void calculateArea(SurveyDTO survey, int areaPmfmId, int lengthPmfmId, int openingPmfmId) {
1259
1260 MeasurementDTO lengthMeasurement = DaliBeans.getMeasurementByPmfmId(survey, lengthPmfmId);
1261 MeasurementDTO openingMeasurement = DaliBeans.getMeasurementByPmfmId(survey, openingPmfmId);
1262
1263 BigDecimal area = null;
1264 if (!DaliBeans.isNumericalMeasurementEmpty(lengthMeasurement) && !DaliBeans.isNumericalMeasurementEmpty(openingMeasurement)) {
1265
1266 area = lengthMeasurement.getNumericalValue().multiply(openingMeasurement.getNumericalValue());
1267 }
1268
1269
1270 MeasurementDTO measurement = DaliBeans.getMeasurementByPmfmId(survey, areaPmfmId);
1271
1272 if (area != null) {
1273
1274 if (measurement == null) {
1275
1276 measurement = DaliBeanFactory.newMeasurementDTO();
1277 measurement.setPmfm(pmfmDao.getPmfmById(areaPmfmId));
1278 survey.addMeasurements(measurement);
1279 }
1280
1281
1282 area = area.setScale(0, BigDecimal.ROUND_HALF_EVEN);
1283 measurement.setDigitNb(0);
1284
1285
1286 measurement.setNumericalValue(area);
1287 measurement.setComment(t("dali.service.data.survey.calculatedArea.comment"));
1288
1289
1290 measurement.setAnalyst(programStrategyService.getAnalysisDepartmentOfAppliedStrategyBySurvey(survey));
1291
1292 } else if (measurement != null) {
1293
1294
1295 survey.removeMeasurements(measurement);
1296 }
1297 }
1298
1299 private boolean isPmfmUnitValidForAreaCalculation(Integer areaPmfmId, Collection<Integer> lengthPmfmIds) {
1300
1301 Assert.notNull(areaPmfmId);
1302 Assert.notEmpty(lengthPmfmIds);
1303
1304 List<PmfmDTO> pmfms = pmfmDao.getPmfmsByIds(ImmutableList.of(areaPmfmId));
1305 if (pmfms.isEmpty()) {
1306
1307 return false;
1308 }
1309
1310 Integer areaUnitId = pmfms.get(0).getUnit().getId();
1311 Assert.notNull(areaUnitId);
1312
1313
1314 Map<Integer, Integer> compatibleUnits = config.getCompatibleLengthUnitIdByAreaUnitId();
1315
1316 if (!compatibleUnits.containsKey(areaUnitId)) {
1317 return false;
1318 }
1319
1320 pmfms = pmfmDao.getPmfmsByIds(lengthPmfmIds);
1321 if (pmfms.size() != lengthPmfmIds.size()) {
1322 return false;
1323 }
1324
1325
1326 if (pmfms.stream().map(pmfmDTO -> pmfmDTO.getUnit().getId()).distinct().count() > 1) {
1327 return false;
1328 }
1329
1330 Integer lengthUnitId = pmfms.get(0).getUnit().getId();
1331 Assert.notNull(lengthUnitId);
1332
1333
1334 return lengthUnitId.equals(compatibleUnits.get(areaUnitId));
1335
1336 }
1337
1338
1339
1340
1341 private QualityFlag getDefaultQualityFlag() {
1342 return load(QualityFlagImpl.class, QualityFlagCode.NOT_QUALIFIED.getValue());
1343 }
1344
1345 }