1 package fr.ifremer.tutti.service.catches;
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.LinkedHashMultimap;
27 import com.google.common.collect.Multimap;
28 import fr.ifremer.tutti.persistence.entities.data.BatchContainer;
29 import fr.ifremer.tutti.persistence.entities.data.FishingOperation;
30 import fr.ifremer.tutti.persistence.entities.data.SampleCategoryModel;
31 import fr.ifremer.tutti.persistence.entities.data.SampleCategoryModelEntry;
32 import fr.ifremer.tutti.persistence.entities.data.SpeciesBatch;
33 import fr.ifremer.tutti.persistence.entities.data.SpeciesBatchFrequency;
34 import fr.ifremer.tutti.persistence.entities.referential.Species;
35 import fr.ifremer.tutti.service.AbstractTuttiService;
36 import fr.ifremer.tutti.service.DecoratorService;
37 import fr.ifremer.tutti.service.PersistenceService;
38 import fr.ifremer.tutti.service.TuttiServiceContext;
39 import fr.ifremer.tutti.type.WeightUnit;
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42
43 import java.util.ArrayList;
44 import java.util.Collection;
45 import java.util.HashSet;
46 import java.util.List;
47 import java.util.Set;
48
49 import static fr.ifremer.tutti.service.PersistenceService.FrequencyFunction;
50 import static org.nuiton.i18n.I18n.t;
51
52
53
54
55
56
57
58
59
60 public class WeightCleaningService extends AbstractTuttiService {
61
62 private static final Log log = LogFactory.getLog(WeightCleaningService.class);
63
64 protected PersistenceService persistenceService;
65
66 protected DecoratorService decoratorService;
67
68 protected SampleCategoryModel sampleCategoryModel;
69
70 protected FrequencyFunction speciesFrequencyFunction;
71
72 protected FrequencyFunction benthosFrequencyFunction;
73
74 protected WeightUnit benthosWeightUnit;
75
76 protected WeightUnit speciesWeightUnit;
77
78 private String speciesBatchPrefix;
79
80 private String benthosBatchPrefix;
81
82 @Override
83 public void setServiceContext(TuttiServiceContext context) {
84 super.setServiceContext(context);
85 persistenceService = getService(PersistenceService.class);
86 decoratorService = getService(DecoratorService.class);
87 sampleCategoryModel = context.getSampleCategoryModel();
88 speciesFrequencyFunction = persistenceService.newSpeciesFrequenciesFunction();
89 benthosFrequencyFunction = persistenceService.newBenthosFrequenciesFunction();
90 benthosWeightUnit = context.getConfig().getBenthosWeightUnit();
91 speciesWeightUnit = context.getConfig().getSpeciesWeightUnit();
92 speciesBatchPrefix = t("tutti.service.operations.cleanWeights.species.batch");
93 benthosBatchPrefix = t("tutti.service.operations.cleanWeights.benthos.batch");
94 }
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143 public String errorsToString(Multimap<String, String> errors) {
144 StringBuilder errorsStr = new StringBuilder("<ul style=\"font-size:11\">");
145 for (String error : errors.keySet()) {
146
147 errorsStr.append("<li>");
148 Collection<String> strings = errors.get(error);
149 errorsStr.append(error);
150 if (strings.size() == 1) {
151 errorsStr.append(" ").append(strings.iterator().next());
152 } else {
153 errorsStr.append("<ul>");
154 for (String s : strings) {
155 errorsStr.append("<li>");
156 errorsStr.append(s);
157 errorsStr.append("</li>");
158 }
159 errorsStr.append("</ul>");
160 }
161 errorsStr.append("</li>");
162 }
163 errorsStr.append("</ul>");
164
165 return errorsStr.toString();
166 }
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191 public Multimap<String, String> checkFishingOperation(Integer fishingOperationId) {
192
193 if (log.isDebugEnabled()) {
194 log.debug("Will check fishingOperation: " + fishingOperationId);
195 }
196 Multimap<String, String> result = LinkedHashMultimap.create();
197
198 boolean withCatchBatch = persistenceService.isFishingOperationWithCatchBatch(fishingOperationId);
199
200 if (withCatchBatch) {
201
202
203
204 BatchContainer<SpeciesBatch> speciesBatch = persistenceService.getRootSpeciesBatch(fishingOperationId, true);
205
206 for (SpeciesBatch batch : speciesBatch.getChildren()) {
207
208 checkBatch(speciesBatchPrefix,
209 speciesWeightUnit,
210 batch,
211 result,
212 speciesFrequencyFunction);
213 }
214
215
216
217 BatchContainer<SpeciesBatch> benthosBatch = persistenceService.getRootBenthosBatch(fishingOperationId, true);
218
219 for (SpeciesBatch batch : benthosBatch.getChildren()) {
220
221 checkBatch(benthosBatchPrefix,
222 benthosWeightUnit,
223 batch,
224 result,
225 benthosFrequencyFunction);
226 }
227
228 } else {
229
230
231
232 if (log.isWarnEnabled()) {
233 log.warn("Skip fishing operation " + fishingOperationId + " since no catchBatch associated.");
234 }
235 }
236
237 return result;
238 }
239
240
241
242
243
244
245
246
247 public boolean cleanFishingOperation(Integer fishingOperationId) {
248
249 if (log.isDebugEnabled()) {
250 log.debug("Will clean fishingOperation: " + fishingOperationId);
251 }
252
253 boolean withCatchBatch = persistenceService.isFishingOperationWithCatchBatch(fishingOperationId);
254
255 boolean result = false;
256
257 if (withCatchBatch) {
258
259
260
261 Set<SpeciesBatch> speciesToSave = new HashSet<>();
262 BatchContainer<SpeciesBatch> speciesBatch = persistenceService.getRootSpeciesBatch(fishingOperationId, true);
263
264 for (SpeciesBatch batch : speciesBatch.getChildren()) {
265
266 cleanBatch(speciesBatchPrefix,
267 speciesWeightUnit,
268 batch,
269 speciesToSave,
270 speciesFrequencyFunction);
271 }
272
273
274
275 Set<SpeciesBatch> benthosToSave = new HashSet<>();
276 BatchContainer<SpeciesBatch> benthosBatch = persistenceService.getRootBenthosBatch(fishingOperationId, true);
277
278 for (SpeciesBatch batch : benthosBatch.getChildren()) {
279
280 cleanBatch(benthosBatchPrefix,
281 benthosWeightUnit,
282 batch,
283 benthosToSave,
284 benthosFrequencyFunction);
285 }
286
287 if (!(speciesToSave.isEmpty() && benthosToSave.isEmpty())) {
288
289
290
291 result = true;
292
293 FishingOperation fishingOperation = persistenceService.getFishingOperation(fishingOperationId);
294
295 for (SpeciesBatch toSave : speciesToSave) {
296 toSave.setFishingOperation(fishingOperation);
297 persistenceService.saveSpeciesBatch(toSave);
298 }
299
300 for (SpeciesBatch toSave : benthosToSave) {
301 toSave.setFishingOperation(fishingOperation);
302 persistenceService.saveBenthosBatch(toSave);
303 }
304 }
305
306 } else {
307
308
309
310 if (log.isWarnEnabled()) {
311 log.warn("Skip fishing operation " + fishingOperationId + " since no catchBatch associated.");
312 }
313 }
314
315 return result;
316
317 }
318
319 protected void checkBatch(String batchPrefix, WeightUnit weightUnit, SpeciesBatch batch, Multimap<String, String> result, FrequencyFunction frequencyFunction) {
320
321 if (!batch.isChildBatchsEmpty()) {
322
323
324 for (SpeciesBatch childBatch : batch.getChildBatchs()) {
325
326
327 String message = checkSampleCategoryWeightRedundant(weightUnit, batch, childBatch);
328 addMessageIfNotExist(message, batchPrefix, weightUnit, childBatch, result);
329
330
331 checkBatch(batchPrefix, weightUnit, childBatch, result, frequencyFunction);
332 }
333 } else {
334
335 {
336 String message = checkWeightRedundant(weightUnit, batch);
337 addMessageIfNotExist(message, batchPrefix, weightUnit, batch, result);
338 }
339
340 {
341 String message = checkFrequencyWeightRedundant(weightUnit, batch, frequencyFunction);
342 addMessageIfNotExist(message, batchPrefix, weightUnit, batch, result);
343 }
344 }
345 }
346
347 protected void cleanBatch(String batchPrefix,
348 WeightUnit weightUnit,
349 SpeciesBatch batch,
350 Set<SpeciesBatch> result,
351 FrequencyFunction frequencyFunction) {
352
353 if (!batch.isChildBatchsEmpty()) {
354
355
356 for (SpeciesBatch childBatch : batch.getChildBatchs()) {
357
358
359 String message = checkSampleCategoryWeightRedundant(weightUnit, batch, childBatch);
360
361
362 cleanBatch(batchPrefix, weightUnit, childBatch, result, frequencyFunction);
363
364 if (message != null) {
365
366
367 buildLabelAndLogMessage(message, batchPrefix, weightUnit, childBatch);
368 batch.setSampleCategoryWeight(null);
369 result.add(batch);
370 }
371 }
372 } else {
373
374 boolean removeWeight = false;
375
376 {
377 String message = checkFrequencyWeightRedundant(weightUnit, batch, frequencyFunction);
378
379 if (message != null) {
380 buildLabelAndLogMessage(message, batchPrefix, weightUnit, batch);
381 removeWeight = true;
382
383 }
384 }
385
386 {
387 String message = checkWeightRedundant(weightUnit, batch);
388
389 if (message != null) {
390 buildLabelAndLogMessage(message, batchPrefix, weightUnit, batch);
391 removeWeight = true;
392 }
393 }
394
395 if (removeWeight) {
396
397
398 batch.setWeight(null);
399 result.add(batch);
400 }
401 }
402
403 }
404
405 protected String checkSampleCategoryWeightRedundant(WeightUnit weightUnit, SpeciesBatch parentBatch, SpeciesBatch batch) {
406
407 Preconditions.checkNotNull(parentBatch);
408
409 String result = null;
410
411
412 Float sampleCategoryWeight = batch.getSampleCategoryWeight();
413 Float parentSampleCategoryWeight = parentBatch.getSampleCategoryWeight();
414
415 if (sampleCategoryWeight != null && parentSampleCategoryWeight != null && WeightUnit.KG.isEquals(parentSampleCategoryWeight, sampleCategoryWeight)) {
416
417 result = t("tutti.service.operations.cleanWeights.error.redundant.sampleCategoryWeight",
418 weightUnit.fromEntity(sampleCategoryWeight) + weightUnit.getShortLabel(),
419 getCategoryLabel(batch),
420 getCategoryLabel(parentBatch)
421 );
422
423 }
424 return result;
425 }
426
427
428 protected String checkFrequencyWeightRedundant(WeightUnit weightUnit,
429 SpeciesBatch batch,
430 FrequencyFunction frequencyFunction) {
431 Preconditions.checkState(batch.isChildBatchsEmpty());
432
433 String result = null;
434
435
436 Float weight = batch.getWeight();
437 if (weight != null) {
438
439
440 List<SpeciesBatchFrequency> frequencies = frequencyFunction.apply(batch);
441 Float frequenciesWeigth = persistenceService.countFrequenciesWeight(frequencies, true);
442
443 if (frequenciesWeigth != null && WeightUnit.KG.isEquals(weight, frequenciesWeigth)) {
444 result = t("tutti.service.operations.cleanWeights.error.redundant.frequencyWeight",
445 weightUnit.fromEntity(weight) + weightUnit.getShortLabel(),
446 getCategoryLabel(batch));
447 }
448 }
449
450 return result;
451 }
452
453 protected String checkWeightRedundant(WeightUnit weightUnit, SpeciesBatch batch) {
454
455 Preconditions.checkState(batch.isChildBatchsEmpty());
456
457 String result = null;
458
459
460 Float weight = batch.getWeight();
461 Float sampleCategoryWeight = batch.getSampleCategoryWeight();
462 if (weight != null && sampleCategoryWeight != null && WeightUnit.KG.isEquals(weight, sampleCategoryWeight)) {
463
464 result = t("tutti.service.operations.cleanWeights.error.redundant.weight",
465 weightUnit.fromEntity(weight) + weightUnit.getShortLabel(),
466 getCategoryLabel(batch));
467 }
468
469 return result;
470 }
471
472 protected String getBatchLabel(String type, WeightUnit weightUnit, SpeciesBatch batch) {
473 StringBuilder sb = new StringBuilder("[ " + type);
474
475 String species = decoratorService.getDecoratorByType(Species.class).toString(batch.getSpecies());
476 sb.append(" ").append(species);
477
478 List<String> categories = new ArrayList<>();
479 SpeciesBatch b = batch;
480 while (b.getParentBatch() != null) {
481 String categoryValue = decoratorService.getDecorator(b.getSampleCategoryValue())
482 .toString(b.getSampleCategoryValue());
483 categories.add(0, categoryValue + " / " + weightUnit.fromEntity(b.getSampleCategoryWeight()));
484 b = b.getParentBatch();
485 }
486
487 for (String category : categories) {
488 sb.append(" - ").append(category);
489 }
490 sb.append(" ]");
491 return sb.toString();
492 }
493
494 protected String getCategoryLabel(SpeciesBatch batch) {
495 SampleCategoryModelEntry category = sampleCategoryModel.getCategoryById(batch.getSampleCategoryId());
496 return category.getLabel();
497 }
498
499
500 protected String buildLabelAndLogMessage(String message, String batchPrefix, WeightUnit weightUnit, SpeciesBatch b) {
501 String label = getBatchLabel(batchPrefix, weightUnit, b);
502 if (log.isInfoEnabled()) {
503 log.info(label + " " + message);
504 }
505 return label;
506 }
507
508 protected void addMessageIfNotExist(String message, String batchPrefix, WeightUnit weightUnit, SpeciesBatch b, Multimap<String, String> result) {
509
510 if (message != null) {
511
512 String label = buildLabelAndLogMessage(message, batchPrefix, weightUnit, b);
513 if (!result.containsEntry(label, message)) {
514 result.put(label, message);
515 }
516 }
517
518 }
519
520 }