1 package fr.ifremer.tutti.persistence.service;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import com.google.common.base.Preconditions;
26 import com.google.common.collect.ArrayListMultimap;
27 import com.google.common.collect.Iterables;
28 import com.google.common.collect.Lists;
29 import com.google.common.collect.Multimap;
30 import com.google.common.collect.Sets;
31 import fr.ifremer.adagio.core.dao.data.batch.Batch;
32 import fr.ifremer.adagio.core.dao.data.batch.CatchBatch;
33 import fr.ifremer.adagio.core.dao.data.batch.SortingBatch;
34 import fr.ifremer.adagio.core.dao.data.measure.SortingMeasurement;
35 import fr.ifremer.adagio.core.dao.referential.QualityFlag;
36 import fr.ifremer.adagio.core.dao.referential.QualityFlagCode;
37 import fr.ifremer.adagio.core.dao.referential.QualityFlagImpl;
38 import fr.ifremer.adagio.core.dao.referential.pmfm.Pmfm;
39 import fr.ifremer.adagio.core.dao.referential.pmfm.PmfmId;
40 import fr.ifremer.adagio.core.dao.referential.taxon.ReferenceTaxon;
41 import fr.ifremer.adagio.core.dao.referential.taxon.ReferenceTaxonImpl;
42 import fr.ifremer.tutti.persistence.InvalidBatchModelException;
43 import fr.ifremer.tutti.persistence.entities.TuttiEntities;
44 import fr.ifremer.tutti.persistence.entities.data.BatchContainer;
45 import fr.ifremer.tutti.persistence.entities.data.FishingOperation;
46 import fr.ifremer.tutti.persistence.entities.data.SampleCategoryModel;
47 import fr.ifremer.tutti.persistence.entities.data.SpeciesBatch;
48 import fr.ifremer.tutti.persistence.entities.data.SpeciesBatchFrequency;
49 import fr.ifremer.tutti.persistence.entities.data.SpeciesBatchs;
50 import fr.ifremer.tutti.persistence.entities.referential.Caracteristic;
51 import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue;
52 import fr.ifremer.tutti.persistence.entities.referential.CaracteristicType;
53 import fr.ifremer.tutti.persistence.entities.referential.Species;
54 import fr.ifremer.tutti.persistence.service.referential.CaracteristicPersistenceService;
55 import fr.ifremer.tutti.persistence.service.referential.SpeciesPersistenceService;
56 import fr.ifremer.tutti.persistence.service.util.BatchPersistenceHelper;
57 import fr.ifremer.tutti.persistence.service.util.MeasurementPersistenceHelper;
58 import fr.ifremer.tutti.persistence.service.util.tree.SpeciesBatchTreeHelperSupport;
59 import fr.ifremer.tutti.persistence.service.util.SynchronizationStatusHelper;
60 import org.apache.commons.collections4.CollectionUtils;
61 import org.apache.commons.logging.Log;
62 import org.apache.commons.logging.LogFactory;
63 import org.springframework.dao.DataIntegrityViolationException;
64
65 import javax.annotation.Resource;
66 import java.io.Serializable;
67 import java.text.DateFormat;
68 import java.text.SimpleDateFormat;
69 import java.util.ArrayList;
70 import java.util.Collection;
71 import java.util.Collections;
72 import java.util.List;
73 import java.util.Objects;
74 import java.util.Set;
75 import java.util.function.Supplier;
76 import java.util.stream.Collectors;
77
78 import static org.nuiton.i18n.I18n.t;
79
80
81
82
83
84
85
86 public abstract class SpeciesBatchPersistenceServiceSupport extends AbstractPersistenceService {
87
88
89 private static final Log log = LogFactory.getLog(SpeciesBatchPersistenceServiceSupport.class);
90
91 @Resource(name = "speciesPersistenceService")
92 private SpeciesPersistenceService speciesService;
93
94 @Resource(name = "fishingOperationPersistenceService")
95 private FishingOperationPersistenceService fishingOperationPersistenceService;
96
97 @Resource(name = "caracteristicPersistenceService")
98 private CaracteristicPersistenceService caracteristicService;
99
100 @Resource(name = "batchPersistenceHelper")
101 protected BatchPersistenceHelper batchHelper;
102
103 @Resource(name = "measurementPersistenceHelper")
104 protected MeasurementPersistenceHelper measurementPersistenceHelper;
105
106 @Resource(name = "synchronizationStatusHelper")
107 private SynchronizationStatusHelper synchronizationStatusHelper;
108
109 private final String prefix;
110
111 private final Supplier<SpeciesBatch> batchFactory;
112 private final Supplier<SpeciesBatchFrequency> frequencyFactory;
113
114 protected SpeciesBatchPersistenceServiceSupport(String prefix, Supplier<SpeciesBatch> batchFactory, Supplier<SpeciesBatchFrequency> frequencyFactory) {
115 this.prefix = prefix;
116 this.batchFactory = batchFactory;
117 this.frequencyFactory = frequencyFactory;
118 }
119
120 public Set<Integer> getBatchChildIds(Integer id) {
121 return batchHelper.getBatchIds(id);
122 }
123
124
125
126
127
128 protected abstract SpeciesBatchTreeHelperSupport getBatchTreeHelper();
129
130 protected abstract void validate(BatchPersistenceHelper batchHelper, SampleCategoryModel sampleCategoryModel, BatchContainer<SpeciesBatch> result);
131
132 protected final BatchContainer<SpeciesBatch> getRootSpeciesBatch0(Integer fishingOperationId, boolean validateTree) throws InvalidBatchModelException {
133
134 Objects.requireNonNull(fishingOperationId);
135
136 DateFormat df = new SimpleDateFormat("dd/MM/yyy");
137
138 CatchBatch catchBatch = batchHelper.getRootCatchBatchByFishingOperationId(fishingOperationId, false);
139
140
141 SortingBatch vracSpeciesBatch = getBatchTreeHelper().getVracAliveItemizedRootBatch(catchBatch);
142
143
144
145 BatchContainer<SpeciesBatch> result = new BatchContainer<>();
146
147 SampleCategoryModel sampleCategoryModel = getSampleCategoryModel();
148
149 if (vracSpeciesBatch != null) {
150
151 result.setId(vracSpeciesBatch.getId());
152
153 for (Batch batch : vracSpeciesBatch.getChildBatchs()) {
154 SortingBatch source = (SortingBatch) batch;
155 ReferenceTaxon referenceTaxon = source.getReferenceTaxon();
156 Objects.requireNonNull(referenceTaxon, "Can't have a rootSpeciesBatch with a null taxon, but was for " + batch.getId());
157 if (log.isTraceEnabled()) {
158 log.trace("Loading CatchBatch Vrac > " + prefix + " > Alive Itemized > " + referenceTaxon.getId() + " - " + " (batch:" + source.getId() + ")");
159 }
160 Species species = speciesService.getSpeciesByReferenceTaxonId(referenceTaxon.getId());
161 if (species == null) {
162 FishingOperation fishingOperation = fishingOperationPersistenceService.getFishingOperation(fishingOperationId);
163 String fishingOperationName = fishingOperation.getStationNumber() + " - " + fishingOperation.getFishingOperationNumber() + " - " + df.format(fishingOperation.getGearShootingStartDate());
164 throw new InvalidBatchModelException(t("tutti.persistence.speciesBatch.validation.unkonwn.taxon", fishingOperationName, source.getId(), referenceTaxon.getId()));
165 }
166 SpeciesBatch target = batchFactory.get();
167 target.setSpecies(species);
168
169 entityToBean(sampleCategoryModel, source, target);
170 result.addChildren(target);
171
172 if (log.isDebugEnabled()) {
173 log.debug("Loaded CatchBatch Vrac > " + prefix + " > Alive Itemized > " + target.getSpecies().getReferenceTaxonId() + ": " + target.getId());
174 }
175 }
176 }
177
178
179 SortingBatch horsVracSpeciesBatch = getBatchTreeHelper().getHorsVracRootBatch(catchBatch);
180
181 if (horsVracSpeciesBatch != null) {
182 for (Batch batch : horsVracSpeciesBatch.getChildBatchs()) {
183 SortingBatch source = (SortingBatch) batch;
184 ReferenceTaxon referenceTaxon = source.getReferenceTaxon();
185 Objects.requireNonNull(referenceTaxon, "Can't have a rootSpeciesBatch with a null taxon, but was for " + source.getId());
186 if (log.isTraceEnabled()) {
187 log.trace("Loading CatchBatch Hors Vrac > " + prefix + " > " + referenceTaxon.getId() + " - " + " (batch:" + source.getId() + ")");
188 }
189 Species species = speciesService.getSpeciesByReferenceTaxonId(referenceTaxon.getId());
190 if (species == null) {
191 FishingOperation fishingOperation = fishingOperationPersistenceService.getFishingOperation(fishingOperationId);
192 String fishingOperationName = fishingOperation.getStationNumber() + " - " + fishingOperation.getFishingOperationNumber() + " - " + df.format(fishingOperation.getGearShootingStartDate());
193 throw new InvalidBatchModelException(t("tutti.persistence.speciesBatch.validation.unkonwn.taxon", fishingOperationName, source.getId(), referenceTaxon.getId()));
194 }
195 SpeciesBatch target = batchFactory.get();
196 target.setSpecies(species);
197 entityToBean(sampleCategoryModel, source, target);
198 result.addChildren(target);
199 if (log.isDebugEnabled()) {
200 log.debug("Loaded CatchBatch Hors Vrac > " + prefix + " > " + target.getSpecies().getReferenceTaxonId() + ": " + target.getId());
201 }
202 }
203 }
204
205 if (validateTree) {
206
207
208 validate(batchHelper, sampleCategoryModel, result);
209 }
210
211 return result;
212 }
213
214 protected SpeciesBatch createSpeciesBatch0(SpeciesBatch bean, Integer parentBatchId, boolean computeRankOrder) {
215 Objects.requireNonNull(bean);
216 Preconditions.checkArgument(TuttiEntities.isNew(bean));
217 Objects.requireNonNull(bean.getSpecies());
218 Objects.requireNonNull(bean.getSpecies().getId());
219 Objects.requireNonNull(bean.getFishingOperation());
220 Objects.requireNonNull(bean.getFishingOperation().getId());
221
222 CatchBatch catchBatch = batchHelper.getRootCatchBatchByFishingOperationId(bean.getFishingOperation().getIdAsInt(), false);
223
224 return createSpeciesBatch0(bean, parentBatchId, catchBatch, computeRankOrder);
225 }
226
227
228 protected Collection<SpeciesBatch> createSpeciesBatches0(Integer fishingOperationId, Collection<SpeciesBatch> beans) {
229
230 Objects.requireNonNull(beans);
231 Objects.requireNonNull(fishingOperationId);
232
233 CatchBatch catchBatch = batchHelper.getRootCatchBatchByFishingOperationId(fishingOperationId, false);
234
235 Collection<SpeciesBatch> result = new ArrayList<>();
236 for (SpeciesBatch bean : beans) {
237
238 SpeciesBatch created = createSpeciesBatch0(bean, null, catchBatch, true);
239 result.add(created);
240
241 }
242 return result;
243
244 }
245
246 protected SpeciesBatch createSpeciesBatch0(SpeciesBatch bean, Integer parentBatchId, CatchBatch catchBatch, boolean computeRankOrder) {
247
248 Objects.requireNonNull(bean);
249 Preconditions.checkArgument(TuttiEntities.isNew(bean));
250 Objects.requireNonNull(bean.getSpecies());
251 Objects.requireNonNull(bean.getSpecies().getId());
252 Objects.requireNonNull(bean.getFishingOperation());
253 Objects.requireNonNull(bean.getFishingOperation().getId());
254
255 SortingBatch batch = SortingBatch.Factory.newInstance();
256 beanToEntity0(bean, batch, parentBatchId, catchBatch, computeRankOrder);
257 bean = batchHelper.createSortingBatch(bean, catchBatch, batch);
258
259 return bean;
260 }
261
262 protected SpeciesBatch saveSpeciesBatch0(SpeciesBatch bean) {
263 Objects.requireNonNull(bean);
264 Preconditions.checkArgument(!TuttiEntities.isNew(bean));
265
266 Integer batchId = bean.getIdAsInt();
267
268 CatchBatch catchBatch = batchHelper.getRootCatchBatchByBatchId(batchId);
269 SortingBatch batch = batchHelper.getSortingBatchById(catchBatch, batchId);
270 Integer parentBatchId = null;
271 if (bean.getParentBatch() != null) {
272 parentBatchId = bean.getParentBatch().getIdAsInt();
273 }
274 beanToEntity0(bean, batch, parentBatchId, catchBatch, true);
275 batchHelper.updateSortingBatch(batch, catchBatch);
276
277 return bean;
278 }
279
280 protected void deleteSpeciesBatch0(Integer id) {
281 Objects.requireNonNull(id);
282 batchHelper.deleteBatch(id);
283 }
284
285 protected void deleteSpeciesSubBatch0(Integer id) {
286 Objects.requireNonNull(id);
287 deleteSpeciesSubBatch(id);
288 }
289
290 protected void changeSpeciesBatchSpecies0(Integer id, Species species) {
291 Objects.requireNonNull(id);
292 Objects.requireNonNull(species);
293 Objects.requireNonNull(species.getReferenceTaxonId());
294 changeBatchSpecies(id, species);
295 }
296
297 protected List<SpeciesBatch> getAllSpeciesBatchToConfirm0(Integer fishingOperationId) throws InvalidBatchModelException {
298 List<SpeciesBatch> batchesToConfirm = new ArrayList<>();
299
300 BatchContainer<SpeciesBatch> rootSpeciesBatch = getRootSpeciesBatch0(fishingOperationId, false);
301 for (SpeciesBatch speciesBatch : rootSpeciesBatch.getChildren()) {
302 findSpeciesBatchesToConfirm(speciesBatch, batchesToConfirm);
303 }
304
305 return batchesToConfirm;
306 }
307
308 private void findSpeciesBatchesToConfirm(SpeciesBatch speciesBatch, List<SpeciesBatch> batchesToConfirm) {
309 if (speciesBatch.isSpeciesToConfirm()) {
310 batchesToConfirm.add(speciesBatch);
311
312 } else if (!speciesBatch.isChildBatchsEmpty()) {
313 for (SpeciesBatch batch : speciesBatch.getChildBatchs()) {
314 findSpeciesBatchesToConfirm(batch, batchesToConfirm);
315 }
316 }
317 }
318
319
320
321
322
323 protected List<SpeciesBatchFrequency> getAllSpeciesBatchFrequency0(Integer speciesBatchId) {
324 Objects.requireNonNull(speciesBatchId);
325
326 List<SortingBatch> frequencyChilds = getFrequencies(speciesBatchId);
327 List<SpeciesBatchFrequency> results = new ArrayList<>();
328 for (SortingBatch child : frequencyChilds) {
329 SpeciesBatchFrequency target = frequencyFactory.get();
330
331 entityToBatchFrequency(child, target);
332 results.add(target);
333 }
334 return Collections.unmodifiableList(results);
335 }
336
337 protected Multimap<Species, SpeciesBatchFrequency> getAllSpeciesBatchFrequencyForBatch0(BatchContainer<SpeciesBatch> batchContainer) {
338 Multimap<Species, SpeciesBatchFrequency> result = ArrayListMultimap.create();
339 for (SpeciesBatch speciesBatch : batchContainer.getChildren()) {
340 getAllSpeciesBatchFrequencyForBatch(speciesBatch, result);
341 }
342 return result;
343 }
344
345 private void getAllSpeciesBatchFrequencyForBatch(SpeciesBatch batch, Multimap<Species, SpeciesBatchFrequency> result) {
346
347 List<SpeciesBatchFrequency> speciesBatchFrequency = getAllSpeciesBatchFrequency0(batch.getIdAsInt());
348 result.putAll(batch.getSpecies(), speciesBatchFrequency);
349
350 if (!batch.isChildBatchsEmpty()) {
351 for (SpeciesBatch child : batch.getChildBatchs()) {
352 getAllSpeciesBatchFrequencyForBatch(child, result);
353 }
354 }
355 }
356
357 protected List<SpeciesBatchFrequency> saveSpeciesBatchFrequency0(Integer speciesBatchId, List<SpeciesBatchFrequency> frequencies) {
358 Objects.requireNonNull(speciesBatchId);
359 Objects.requireNonNull(frequencies);
360
361 List<SpeciesBatchFrequency> notNullFrequencies = new ArrayList<>();
362
363
364
365 String pmfmId = null;
366 for (SpeciesBatchFrequency source : frequencies) {
367
368 if (source.getLengthStepCaracteristic() != null) {
369 if (pmfmId == null) {
370 pmfmId = source.getLengthStepCaracteristic().getId();
371 } else if (!pmfmId.equals(source.getLengthStepCaracteristic().getId())) {
372 throw new DataIntegrityViolationException("Batch frequencies under one SpeciesBatch must have all the same lengthStepCaracteristic");
373 }
374 notNullFrequencies.add(source);
375 }
376 }
377
378 CatchBatch catchBatch = batchHelper.getRootCatchBatchByBatchId(speciesBatchId);
379
380 if (catchBatch == null) {
381 return notNullFrequencies;
382 }
383
384
385 synchronizationStatusHelper.setDirty(catchBatch);
386
387
388 SortingBatch parentBatch = batchHelper.getSortingBatchById(catchBatch, speciesBatchId);
389
390
391 List<Integer> notUpdatedChildIds = new ArrayList<>();
392 List<SortingBatch> frequencyChilds = getFrequencyChilds(parentBatch);
393 notUpdatedChildIds.addAll(frequencyChilds.stream().map(SortingBatch::getId).collect(Collectors.toList()));
394
395 short rankOrder = 0;
396 List<SortingBatch> batchsToUpdate = new ArrayList<>();
397 for (SpeciesBatchFrequency source : notNullFrequencies) {
398 rankOrder++;
399
400 SortingBatch target;
401 if (source.getId() == null) {
402
403
404 target = SortingBatch.Factory.newInstance();
405
406
407 beanToEntity0(source, target, parentBatch, rankOrder);
408
409
410 batchHelper.createSortingBatch(source, catchBatch, target);
411
412
413 source.setId(target.getId());
414
415 if (log.isDebugEnabled()) {
416 log.debug("Create frequency sortingBatch(" + rankOrder + "): " + target.getId());
417 }
418 } else {
419
420
421 target = batchHelper.loadSortingBatch(source.getIdAsInt(), catchBatch);
422
423
424 beanToEntity0(source, target, parentBatch, rankOrder);
425
426
427 batchsToUpdate.add(target);
428
429
430 notUpdatedChildIds.remove(target.getId());
431
432 if (log.isDebugEnabled()) {
433 log.debug("Update frequency sortingBatch(" + rankOrder + "): " + target.getId());
434 }
435 }
436 }
437
438 if (CollectionUtils.isNotEmpty(batchsToUpdate)) {
439
440
441 batchHelper.updateSortingBatch(batchsToUpdate, catchBatch);
442 }
443
444 if (CollectionUtils.isNotEmpty(notUpdatedChildIds)) {
445
446
447 for (Integer batchId : notUpdatedChildIds) {
448
449 if (log.isDebugEnabled()) {
450 log.debug("Remove obsolete frequency sortingBatch: " + batchId);
451 }
452 batchHelper.removeWithChildren(batchId, catchBatch);
453 }
454 }
455
456 return Collections.unmodifiableList(notNullFrequencies);
457 }
458
459
460
461
462
463 protected void beanToEntity0(SpeciesBatch source,
464 SortingBatch target,
465 Integer parentBatchId,
466 CatchBatch catchBatch,
467 boolean computeRankOrder) {
468
469 Objects.requireNonNull(source.getFishingOperation());
470 Objects.requireNonNull(source.getFishingOperation().getId());
471
472
473 if (target.getId() == null
474 || target.getRootBatch() == null
475 || (target.getParentBatch() != null && !target.getParentBatch().getId().equals(parentBatchId))) {
476
477 getBatchTreeHelper().setBatchParents(source.getSampleCategoryId(),
478 source.getSampleCategoryValue(),
479 target,
480 parentBatchId,
481 catchBatch);
482 }
483
484
485 {
486 if (target.getRankOrder() == null) {
487
488 short rankOrder;
489
490 if (computeRankOrder) {
491
492
493 rankOrder = (short) 1;
494
495
496 if (source.getParentBatch() != null && CollectionUtils.isNotEmpty(source.getParentBatch().getChildBatchs())) {
497 int maxRankOrder = 0;
498 for (SpeciesBatch batch : source.getParentBatch().getChildBatchs()) {
499 Integer r = batch.getRankOrder();
500 if (r != null && r > maxRankOrder) {
501 maxRankOrder = r;
502 }
503 }
504 rankOrder += (short) maxRankOrder;
505
506 } else {
507
508 rankOrder = batchHelper.computeRankOrder(target);
509
510 }
511
512 } else {
513
514 Preconditions.checkState(source.getRankOrder() != null, "Not using computeRankOrder requires source rankOrder to be not null, but was on batch: " + source);
515 rankOrder = (short) (int) source.getRankOrder();
516
517 }
518
519 target.setRankOrder(rankOrder);
520
521 }
522 }
523
524
525 target.setSubgroupCount(1f);
526
527
528 target.setIndividualCount(source.getNumber());
529
530
531 target.setComments(source.getComment());
532
533
534 target.setExhaustiveInventory(true);
535
536
537 {
538 ReferenceTaxon referenceTaxon;
539 if (source.getSpecies() == null || parentBatchId != null) {
540 referenceTaxon = null;
541 } else {
542 referenceTaxon = load(ReferenceTaxonImpl.class, source.getSpecies().getReferenceTaxonId());
543 }
544 target.setReferenceTaxon(referenceTaxon);
545 }
546
547
548 {
549 String qualityFlag;
550 if (source.isSpeciesToConfirm()) {
551 qualityFlag = QualityFlagCode.DOUBTFUL.getValue();
552 } else {
553 qualityFlag = QualityFlagCode.NOTQUALIFIED.getValue();
554 }
555 target.setQualityFlag(load(QualityFlagImpl.class, qualityFlag));
556 }
557
558 Float weight = source.getWeight();
559 Float sampleCategoryWeight = source.getSampleCategoryWeight();
560
561
562 getBatchTreeHelper().setWeightAndSampleRatio(target, weight, sampleCategoryWeight);
563
564
565 {
566 Collection<SortingMeasurement> sortingMeasurements = target.getSortingMeasurements();
567 Set<SortingMeasurement> notChangedSortingMeasurements = Sets.newHashSet();
568 if (sortingMeasurements != null) {
569 notChangedSortingMeasurements.addAll(sortingMeasurements);
570 }
571
572 if (source.getSampleCategoryId() != null && source.getSampleCategoryValue() != null) {
573 Integer pmfmId = source.getSampleCategoryId();
574
575 if (!pmfmId.equals(PmfmId.SORTED_UNSORTED.getValue())) {
576 SortingMeasurement sortingMeasurement = measurementPersistenceHelper.setSortingMeasurement(
577 target,
578 pmfmId,
579 source.getSampleCategoryValue());
580 notChangedSortingMeasurements.remove(sortingMeasurement);
581 }
582 }
583 if (sortingMeasurements != null) {
584 sortingMeasurements.removeAll(notChangedSortingMeasurements);
585 }
586 }
587
588 }
589
590 private void beanToEntity0(SpeciesBatchFrequency source,
591 SortingBatch target,
592 SortingBatch parentBatch,
593 short rankOrder) {
594 Preconditions.checkNotNull(source.getBatch());
595 Preconditions.checkNotNull(source.getBatch().getId());
596
597
598 if (target.getId() == null
599 || target.getRootBatch() == null
600 || (target.getParentBatch() != null && !target.getParentBatch().getId().equals(parentBatch.getId()))) {
601
602 target.setParentBatch(parentBatch);
603 target.setRootBatch(parentBatch.getRootBatch());
604 }
605
606
607 target.setRankOrder(rankOrder);
608
609
610 target.setIndividualCount(source.getNumber());
611
612
613 target.setReferenceTaxon(null);
614
615
616 target.setQualityFlag(parentBatch.getQualityFlag());
617
618
619 target.setExhaustiveInventory(true);
620
621
622 getBatchTreeHelper().setWeightAndSampleRatio(target, source.getWeight(), null);
623
624
625 {
626 Collection<SortingMeasurement> sortingMeasurements = target.getSortingMeasurements();
627 Set<SortingMeasurement> notChangedSortingMeasurements = Sets.newHashSet();
628 if (sortingMeasurements != null) {
629 notChangedSortingMeasurements.addAll(sortingMeasurements);
630 }
631 if ((source.getLengthStepCaracteristic() != null && source.getLengthStep() != null)) {
632 Integer pmfmId = source.getLengthStepCaracteristic().getIdAsInt();
633 SortingMeasurement sortingMeasurement = measurementPersistenceHelper.setSortingMeasurement(target, pmfmId,
634 source.getLengthStep());
635 notChangedSortingMeasurements.remove(sortingMeasurement);
636 }
637 if (sortingMeasurements != null) {
638 sortingMeasurements.removeAll(notChangedSortingMeasurements);
639 }
640 }
641
642 }
643
644
645 private SpeciesBatch entityToBean(SampleCategoryModel sampleCategoryModel,
646 SortingBatch source,
647 SpeciesBatch target) {
648
649 Preconditions.checkNotNull(target.getSpecies());
650
651 target.setId(source.getId().toString());
652
653
654 target.setRankOrder(Integer.valueOf(source.getRankOrder()));
655
656
657 target.setNumber(source.getIndividualCount());
658
659
660 if (source.getWeight() != null && source.getWeightBeforeSampling() == null) {
661 target.setSampleCategoryWeight(source.getWeight());
662 } else {
663 target.setWeight(source.getWeight());
664 target.setSampleCategoryWeight(source.getWeightBeforeSampling());
665
666
667
668
669
670
671
672
673 }
674
675
676
677
678
679
680
681
682
683
684
685 target.setComment(source.getComments());
686
687
688 SortingMeasurement sm = null;
689 if (source.getSortingMeasurements().size() == 1) {
690 sm = source.getSortingMeasurements().iterator().next();
691 } else if (source.getReferenceTaxon() != null && source.getReferenceTaxon().getId() != null) {
692 sm = measurementPersistenceHelper.getInheritedSortingMeasurement(source);
693 }
694 if (sm != null) {
695
696 boolean isFrequency = isFrequencyBatch(sampleCategoryModel, source);
697
698 if (!isFrequency) {
699 Integer qualitativeId = null;
700 if (sm.getQualitativeValue() != null) {
701 qualitativeId = sm.getQualitativeValue().getId();
702 }
703 setSampleCategoryQualitative(
704 target,
705 sm.getPmfm().getId(),
706 sm.getNumericalValue(),
707 sm.getAlphanumericalValue(),
708 qualitativeId);
709 }
710 }
711
712 if (target.getSampleCategoryId() != null) {
713 List<SpeciesBatch> targetChilds = Lists.newArrayList();
714 for (Batch batch : source.getChildBatchs()) {
715 SortingBatch sourceChild = (SortingBatch) batch;
716 SpeciesBatch targetChild = SpeciesBatchs.newInstance(target);
717 targetChild.setSpecies(target.getSpecies());
718 entityToBean(sampleCategoryModel, sourceChild, targetChild);
719 if (log.isDebugEnabled()) {
720 log.debug("Loaded CatchBatch (Vrac|Hors Vrac) > Species > " + targetChild.getSpecies().getReferenceTaxonId() + " : " + target.getId());
721 }
722 if (targetChild.getSampleCategoryValue() != null) {
723 targetChilds.add(targetChild);
724 targetChild.setParentBatch(target);
725 }
726 }
727 target.setChildBatchs(targetChilds);
728
729 }
730
731
732
733
734
735 if (CollectionUtils.isNotEmpty(source.getChildBatchs()) && target.getWeight() != null) {
736
737 SortingBatch childBatch = (SortingBatch) Iterables.get(source.getChildBatchs(), 0);
738
739 boolean isFrequency = isFrequencyBatch(sampleCategoryModel, childBatch);
740
741 if (!isFrequency) {
742
743
744
745
746
747 target.setWeight(null);
748
749 }
750
751 }
752
753 QualityFlag qualityFlag = source.getQualityFlag();
754 target.setSpeciesToConfirm(qualityFlag != null && QualityFlagCode.DOUBTFUL.getValue().equals(qualityFlag.getCode()));
755
756 return target;
757
758 }
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778 private void setSampleCategoryQualitative(SpeciesBatch target,
779 Integer pmfmId,
780 Float numericalvalue,
781 String alphanumericalValue,
782 Integer qualitativeValueId) {
783
784 if (pmfmId == null || pmfmId.equals(SpeciesBatchTreeHelperSupport.SORTING_TYPE_ID)) {
785 return;
786 }
787 SampleCategoryModel sampleCategoryModel = getSampleCategoryModel();
788
789 boolean isSamplingCategory = sampleCategoryModel.containsCategoryId(pmfmId);
790 Preconditions.checkNotNull(isSamplingCategory, "Unable to find corresponding SampleCategoryEnum for PMFM.ID : " + pmfmId);
791
792 target.setSampleCategoryId(pmfmId);
793 Serializable categoryValue = getSampleCategoryQualitative(
794 pmfmId,
795 numericalvalue,
796 alphanumericalValue,
797 qualitativeValueId);
798 target.setSampleCategoryValue(categoryValue);
799 }
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815 private boolean isFrequencyBatch(SampleCategoryModel sampleCategoryModel, SortingBatch sortingBatch) {
816 boolean result = false;
817 if (sortingBatch.getSortingMeasurements().size() == 1) {
818 SortingMeasurement sm
819 = sortingBatch.getSortingMeasurements().iterator().next();
820 Pmfm pmfm = sm.getPmfm();
821
822 result = sortingBatch.getIndividualCount() != null &&
823 !sampleCategoryModel.containsCategoryId(pmfm.getId());
824 }
825 return result;
826 }
827
828 private Serializable getSampleCategoryQualitative(Integer pmfmId,
829 Float numericalvalue,
830 String alphanumericalValue,
831 Integer qualitativeValueId) {
832
833 if (numericalvalue != null) {
834 return numericalvalue;
835 }
836 if (alphanumericalValue != null) {
837 return alphanumericalValue;
838 }
839
840 Caracteristic caracteristic = caracteristicService.getCaracteristic(pmfmId);
841 if (caracteristic == null || caracteristic.getCaracteristicType() != CaracteristicType.QUALITATIVE) {
842 return null;
843 }
844 CaracteristicQualitativeValue value = null;
845 for (CaracteristicQualitativeValue qv : caracteristic.getQualitativeValue()) {
846 if (qualitativeValueId.equals(qv.getIdAsInt())) {
847 value = qv;
848 break;
849 }
850 }
851
852 return value;
853 }
854
855 private void entityToBatchFrequency(SortingBatch source,
856 SpeciesBatchFrequency target) {
857
858 target.setId(source.getId());
859
860
861 target.setRankOrder(Integer.valueOf(source.getRankOrder()));
862
863 target.setNumber(source.getIndividualCount());
864 target.setWeight(source.getWeight());
865
866 Preconditions.checkState(source.getSortingMeasurements().size() == 1, "SortingBatch [" + source.getId() + "] need exactly one sortingMeasurement (to store the length step category), but had " + source.getSortingMeasurements().size());
867 SortingMeasurement sm = source.getSortingMeasurements().iterator().next();
868 Preconditions.checkNotNull(sm.getPmfm(), "SortingMeasurement [" + sm.getId() + "] can not have a null pmfm");
869 Preconditions.checkNotNull(sm.getPmfm().getId(), "SortingMeasurement [" + sm.getId() + "] can not have a pmfm with null id");
870
871
872 Caracteristic lengthStepCaracteristic = caracteristicService.getCaracteristic(sm.getPmfm().getId());
873 target.setLengthStepCaracteristic(lengthStepCaracteristic);
874
875
876 target.setLengthStep(sm.getNumericalValue());
877 }
878
879 private List<SortingBatch> getFrequencyChilds(SortingBatch sortingBatch) {
880 List<SortingBatch> result = Lists.newArrayList();
881
882 SampleCategoryModel sampleCategoryModel = getSampleCategoryModel();
883
884 for (Batch batch : sortingBatch.getChildBatchs()) {
885 SortingBatch child = (SortingBatch) batch;
886 if (isFrequencyBatch(sampleCategoryModel, child)) {
887 result.add(child);
888 }
889 }
890 return result;
891 }
892
893 private List<SortingBatch> getFrequencies(Integer batchId) {
894 Preconditions.checkNotNull(batchId);
895 CatchBatch catchBatch = batchHelper.getRootCatchBatchByBatchId(batchId);
896 SortingBatch sortingBatch = batchHelper.getSortingBatchById(catchBatch, batchId);
897
898 return getFrequencyChilds(sortingBatch);
899 }
900
901 private void deleteSpeciesSubBatch(Integer speciesBatchId) {
902 Preconditions.checkNotNull(speciesBatchId);
903
904 CatchBatch catchBatch = batchHelper.getRootCatchBatchByBatchId(speciesBatchId);
905 synchronizationStatusHelper.setDirty(catchBatch);
906
907 SortingBatch sortingBatch = batchHelper.getSortingBatchById(catchBatch, speciesBatchId);
908
909
910 Collection<Batch> childBatchs = sortingBatch.getChildBatchs();
911
912 if (CollectionUtils.isNotEmpty(childBatchs)) {
913
914 for (Batch childBatch : childBatchs) {
915
916
917 Integer childBatchId = childBatch.getId();
918
919 if (log.isDebugEnabled()) {
920 log.debug("Delete child [" + childBatchId + "] of species batch: " + speciesBatchId);
921 }
922 batchHelper.removeWithChildren(childBatchId);
923 }
924 }
925 }
926
927 private void changeBatchSpecies(Integer batchId, Species species) {
928
929 Preconditions.checkNotNull(batchId);
930 Preconditions.checkNotNull(species);
931 Preconditions.checkNotNull(species.getReferenceTaxonId());
932
933 CatchBatch catchBatch = batchHelper.getRootCatchBatchByBatchId(batchId);
934 synchronizationStatusHelper.setDirty(catchBatch);
935
936 batchHelper.setSortingBatchReferenceTaxon(batchId, species);
937 }
938 }