View Javadoc
1   package fr.ifremer.tutti.service.genericformat.producer;
2   
3   /*
4    * #%L
5    * Tutti :: Service
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2012 - 2015 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU General Public License as
13   * published by the Free Software Foundation, either version 3 of the
14   * License, or (at your option) any later version.
15   * 
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * 
21   * You should have received a copy of the GNU General Public
22   * License along with this program.  If not, see
23   * <http://www.gnu.org/licenses/gpl-3.0.html>.
24   * #L%
25   */
26  
27  import fr.ifremer.tutti.persistence.entities.data.BatchContainer;
28  import fr.ifremer.tutti.persistence.entities.data.SampleCategoryModel;
29  import fr.ifremer.tutti.persistence.entities.data.SampleCategoryModelEntry;
30  import fr.ifremer.tutti.persistence.entities.data.SpeciesBatch;
31  import fr.ifremer.tutti.persistence.entities.data.SpeciesBatchFrequency;
32  import fr.ifremer.tutti.persistence.entities.referential.Caracteristic;
33  import fr.ifremer.tutti.service.csv.CsvProducer;
34  import fr.ifremer.tutti.service.genericformat.GenericFormatExportOperationContext;
35  import fr.ifremer.tutti.service.genericformat.csv.CatchModel;
36  import fr.ifremer.tutti.service.genericformat.csv.CatchRow;
37  import fr.ifremer.tutti.service.genericformat.csv.ExportSampleCategory;
38  import fr.ifremer.tutti.type.WeightUnit;
39  import fr.ifremer.tutti.util.Numbers;
40  import fr.ifremer.tutti.util.Weights;
41  import org.apache.commons.collections4.CollectionUtils;
42  import org.apache.commons.logging.Log;
43  import org.apache.commons.logging.LogFactory;
44  
45  import java.io.Serializable;
46  import java.nio.file.Path;
47  import java.util.ArrayList;
48  import java.util.LinkedHashSet;
49  import java.util.List;
50  import java.util.Set;
51  
52  /**
53   * Created on 2/6/15.
54   *
55   * @author Tony Chemit - chemit@codelutin.com
56   * @since 3.13
57   */
58  public class CsvProducerForCatch extends CsvProducer<CatchRow, CatchModel> {
59  
60      /** Logger. */
61      private static final Log log = LogFactory.getLog(CsvProducerForCatch.class);
62  
63      public CsvProducerForCatch(Path file, CatchModel model) {
64          super(file, model);
65      }
66  
67      public List<CatchRow> getDataToExport(GenericFormatExportOperationContext operationExportContext,
68                                            Float speciesCatchRaisingFactor,
69                                            Float benthosCatchRaisingFactor) {
70  
71          List<CatchRow> rows = new ArrayList<>();
72  
73          BatchContainer<SpeciesBatch> rootSpeciesBatch = operationExportContext.getRootSpeciesBatch();
74  
75          BatchContainer<SpeciesBatch> rootBenthosBatch = operationExportContext.getRootBenthosBatch();
76  
77          Caracteristic weightMeasuredCaracteristic = operationExportContext.getWeightMeasuredCaracteristic();
78          String batchWeightUnit = weightMeasuredCaracteristic.getUnit();
79  
80          addSpeciesBatches(operationExportContext, rootSpeciesBatch, speciesCatchRaisingFactor, batchWeightUnit, rows);
81          addBenthosBatches(operationExportContext, rootBenthosBatch, benthosCatchRaisingFactor, batchWeightUnit, rows);
82  
83          // compute final raising factor
84          // see http://forge.codelutin.com/issues/4135
85          // see http://forge.codelutin.com/issues/5110
86          for (CatchRow row : rows) {
87  
88              Float raisingFactor = row.isBenthos() ? benthosCatchRaisingFactor : speciesCatchRaisingFactor;
89  
90              float finalRaisingFactor = computeFinalRaisingFactor(row, raisingFactor);
91              row.setFinalRaisingFactor(finalRaisingFactor);
92  
93          }
94  
95          return rows;
96  
97      }
98  
99      public List<CatchRow> getBenthosOnlyDataToExport(GenericFormatExportOperationContext operationExportContext,
100                                                      Float benthosCatchRaisingFactor) {
101 
102         List<CatchRow> rows = new ArrayList<>();
103 
104         BatchContainer<SpeciesBatch> rootBenthosBatch = operationExportContext.getRootBenthosBatch();
105 
106         Caracteristic weightMeasuredCaracteristic = operationExportContext.getWeightMeasuredCaracteristic();
107         String batchWeightUnit = weightMeasuredCaracteristic.getUnit();
108 
109         addBenthosBatches(operationExportContext, rootBenthosBatch, benthosCatchRaisingFactor, batchWeightUnit, rows);
110 
111         for (CatchRow row : rows) {
112 
113             float finalRaisingFactor = computeFinalRaisingFactor(row, benthosCatchRaisingFactor);
114             row.setFinalRaisingFactor(finalRaisingFactor);
115 
116         }
117 
118         return rows;
119 
120     }
121 
122     public List<CatchRow> getSpeciesOnlyDataToExport(GenericFormatExportOperationContext operationExportContext,
123                                                      Float speciesCatchRaisingFactor) {
124 
125         List<CatchRow> rows = new ArrayList<>();
126 
127         BatchContainer<SpeciesBatch> rootSpeciesBatch = operationExportContext.getRootSpeciesBatch();
128 
129         Caracteristic weightMeasuredCaracteristic = operationExportContext.getWeightMeasuredCaracteristic();
130         String batchWeightUnit = weightMeasuredCaracteristic.getUnit();
131 
132         addSpeciesBatches(operationExportContext, rootSpeciesBatch, speciesCatchRaisingFactor, batchWeightUnit, rows);
133 
134         for (CatchRow row : rows) {
135 
136             float finalRaisingFactor = computeFinalRaisingFactor(row, speciesCatchRaisingFactor);
137             row.setFinalRaisingFactor(finalRaisingFactor);
138 
139         }
140 
141         return rows;
142 
143     }
144 
145     protected void addBenthosBatches(GenericFormatExportOperationContext operationExportContext,
146                                      BatchContainer<SpeciesBatch> rootBenthosBatch,
147                                      Float benthosCatchRaisingFactor,
148                                      String batchWeightUnit,
149                                      List<CatchRow> rows) {
150 
151         for (SpeciesBatch benthosBatch : rootBenthosBatch.getChildren()) {
152 
153             boolean vracBatch = operationExportContext.isVracBatch(benthosBatch);
154 
155             CatchRow row = new CatchRow();
156             row.setVrac(vracBatch);
157             row.setBenthos(true);
158             row.setCruise(operationExportContext.getCruise());
159             row.setFishingOperation(operationExportContext.getOperation());
160             row.setSpecies(benthosBatch.getSpecies());
161             row.setSpeciesToConfirm(benthosBatch.isSpeciesToConfirm());
162             row.setBatchWeightUnit(batchWeightUnit);
163 
164             float raisingFactor = benthosCatchRaisingFactor;
165 
166             if (!vracBatch) {
167 
168                 // for HV, always use a 1.0 raising factor
169                 raisingFactor = 1.f;
170             }
171 
172             Float batchWeight = Numbers.getValueOrComputedValue(
173                     benthosBatch.getSampleCategoryWeight(),
174                     benthosBatch.getSampleCategoryComputedWeight());
175 
176             float totalBatchWeight = batchWeight == null ? 0 : raisingFactor * batchWeight;
177 
178             addBenthosBatch(operationExportContext,
179                             row,
180                             rows,
181                             benthosBatch,
182                             totalBatchWeight);
183 
184         }
185 
186     }
187 
188     protected void addSpeciesBatches(GenericFormatExportOperationContext operationExportContext,
189                                      BatchContainer<SpeciesBatch> rootSpeciesBatch,
190                                      Float speciesCatchRaisingFactor,
191                                      String batchWeightUnit,
192                                      List<CatchRow> rows) {
193 
194         for (SpeciesBatch speciesBatch : rootSpeciesBatch.getChildren()) {
195 
196             boolean vracBatch = operationExportContext.isVracBatch(speciesBatch);
197 
198             CatchRow row = new CatchRow();
199             row.setVrac(vracBatch);
200             row.setBenthos(false);
201             row.setCruise(operationExportContext.getCruise());
202             row.setFishingOperation(operationExportContext.getOperation());
203             row.setSpecies(speciesBatch.getSpecies());
204             row.setSpeciesToConfirm(speciesBatch.isSpeciesToConfirm());
205             row.setBatchWeightUnit(batchWeightUnit);
206 
207             float raisingFactor = speciesCatchRaisingFactor;
208 
209             if (!vracBatch) {
210 
211                 // for HV, always use a 1.0 raising factor
212                 raisingFactor = 1.f;
213             }
214 
215             Float batchWeight = Numbers.getValueOrComputedValue(
216                     speciesBatch.getSampleCategoryWeight(),
217                     speciesBatch.getSampleCategoryComputedWeight());
218 
219             float totalBatchWeight = batchWeight == null ? 0 : raisingFactor * batchWeight;
220 
221             addSpeciesBatch(operationExportContext,
222                             row,
223                             rows,
224                             speciesBatch,
225                             totalBatchWeight);
226 
227         }
228     }
229 
230     protected void addSpeciesBatch(GenericFormatExportOperationContext operationExportContext,
231                                    CatchRow currentRow,
232                                    List<CatchRow> rows,
233                                    SpeciesBatch speciesBatch,
234                                    float totalBatchWeight) {
235 
236         Integer number = Numbers.getValueOrComputedValue(speciesBatch.getNumber(),
237                                                          speciesBatch.getComputedNumber());
238         Boolean numberComputed = Numbers.getValueOrComputedValueComputed(speciesBatch.getNumber(),
239                                                                          speciesBatch.getComputedNumber());
240 
241         Integer rankOrder = speciesBatch.getRankOrder();
242 
243         addBatchSampleCategory(operationExportContext.getSampleCategoryModel(),
244                                currentRow,
245                                speciesBatch.getIdAsInt(),
246                                speciesBatch.getSampleCategoryId(),
247                                speciesBatch.getSampleCategoryValue(),
248                                speciesBatch.getSampleCategoryWeight(),
249                                speciesBatch.getSampleCategoryComputedWeight(),
250                                speciesBatch.getWeight(),
251                                speciesBatch.getComment(),
252                                number,
253                                numberComputed,
254                                rankOrder);
255 
256         if (speciesBatch.isChildBatchsEmpty()) {
257 
258             // on a leaf, get frequencies
259 
260             List<SpeciesBatchFrequency> speciesBatchFrequency =
261                     operationExportContext.getAllSpeciesBatchFrequency(speciesBatch.getIdAsInt());
262 
263             if (CollectionUtils.isEmpty(speciesBatchFrequency)) {
264 
265                 // no frequency
266 
267                 CatchRow row = currentRow.copy();
268 
269                 // Get reference weight
270 
271                 Float referenceWeight = Numbers.getValueOrComputedValue(
272                         speciesBatch.getWeight(),
273                         speciesBatch.getComputedWeight());
274 
275                 if (referenceWeight == null) {
276 
277                     referenceWeight = Numbers.getValueOrComputedValue(
278                             speciesBatch.getSampleCategoryWeight(),
279                             speciesBatch.getSampleCategoryComputedWeight());
280                 }
281                 setRaisingFactor(row, totalBatchWeight, referenceWeight);
282                 rows.add(row);
283             } else {
284 
285                 // there is some frequencies
286 
287                 boolean withNoWeightOnFrequencies =
288                         speciesBatchFrequency.get(0).getWeight() == null;
289 
290                 Float referenceWeight = null;
291 
292                 if (withNoWeightOnFrequencies) {
293 
294                     // no weight on frequencies use upper reference weight
295 
296                     referenceWeight = Numbers.getValueOrComputedValue(
297                             speciesBatch.getWeight(),
298                             speciesBatch.getComputedWeight());
299 
300                     if (referenceWeight == null) {
301                         referenceWeight = Numbers.getValueOrComputedValue(
302                                 speciesBatch.getSampleCategoryWeight(),
303                                 speciesBatch.getSampleCategoryComputedWeight());
304                     }
305                 }
306 
307                 float frequencyWeights = 0f;
308                 Set<CatchRow> frequencyRows = new LinkedHashSet<>();
309                 for (SpeciesBatchFrequency batchFrequency : speciesBatchFrequency) {
310                     CatchRow row = currentRow.copy();
311                     row.setFrequency(batchFrequency);
312                     frequencyRows.add(row);
313                     rows.add(row);
314 
315                     if (!withNoWeightOnFrequencies) {
316 
317                         // use concrete frequency weight
318                         referenceWeight = batchFrequency.getWeight();
319                         frequencyWeights += referenceWeight;
320                     }
321 
322                     setRaisingFactor(row, totalBatchWeight, referenceWeight);
323                 }
324 
325                 if (!withNoWeightOnFrequencies) {
326                     float computedFrequencyTotalWeight = frequencyWeights;
327                     frequencyRows.forEach(catchRow -> {
328                         catchRow.getLastSampleCategoryFilled().setSampleComputedWeight(computedFrequencyTotalWeight);
329                         catchRow.setComputedFrequencyTotalWeight(computedFrequencyTotalWeight);
330                     });
331                 }
332             }
333 
334         } else {
335 
336             float sampleComputedWeight = 0f;
337 
338             for (SpeciesBatch childBatch : speciesBatch.getChildBatchs()) {
339                 // always use a copy, otherwise sample categories can be shared by brothers
340                 CatchRow childRow = currentRow.copy();
341                 addSpeciesBatch(operationExportContext,
342                                 childRow,
343                                 rows,
344                                 childBatch,
345                                 totalBatchWeight);
346 
347                 ExportSampleCategory exportSampleCategory = childRow.getLastSampleCategoryFilled();
348                 if (exportSampleCategory != null) {
349                     Float categoryWeight = Numbers.getValueOrComputedValue(
350                             exportSampleCategory.getCategoryWeight(),
351                             exportSampleCategory.getComputedWeight());
352 
353                     if (categoryWeight == null) {
354 
355                         if (log.isWarnEnabled()) {
356                             log.warn(String.format("Campagne %s - Trait %s : Il existe une catégorie de poids non renseignée (lot espèce %s)", operationExportContext.getCruise().getName(), operationExportContext.getOperationLabel(), childBatch.getId()));
357                         }
358                         categoryWeight = 0f;
359 
360                     }
361 
362                     sampleComputedWeight += categoryWeight;
363                 }
364             }
365             currentRow.getLastSampleCategoryFilled().setSampleComputedWeight(sampleComputedWeight);
366         }
367     }
368 
369     protected void addBenthosBatch(GenericFormatExportOperationContext operationExportContext,
370                                    CatchRow currentRow,
371                                    List<CatchRow> rows,
372                                    SpeciesBatch benthosBatch,
373                                    float totalBatchWeight) {
374 
375         Integer number = Numbers.getValueOrComputedValue(benthosBatch.getNumber(),
376                                                          benthosBatch.getComputedNumber());
377         Boolean numberComputed = Numbers.getValueOrComputedValueComputed(benthosBatch.getNumber(),
378                                                                          benthosBatch.getComputedNumber());
379 
380         Integer rankOrder = benthosBatch.getRankOrder();
381 
382         addBatchSampleCategory(operationExportContext.getSampleCategoryModel(),
383                                currentRow,
384                                benthosBatch.getIdAsInt(),
385                                benthosBatch.getSampleCategoryId(),
386                                benthosBatch.getSampleCategoryValue(),
387                                benthosBatch.getSampleCategoryWeight(),
388                                benthosBatch.getSampleCategoryComputedWeight(),
389                                benthosBatch.getWeight(),
390                                benthosBatch.getComment(),
391                                number,
392                                numberComputed,
393                                rankOrder);
394 
395         if (benthosBatch.isChildBatchsEmpty()) {
396 
397             // on a leaf, get frequencies
398 
399             List<SpeciesBatchFrequency> benthosBatchFrequency =
400                     operationExportContext.getAllBenthosBatchFrequency(benthosBatch.getIdAsInt());
401 
402             if (CollectionUtils.isEmpty(benthosBatchFrequency)) {
403 
404                 // no frequency
405 
406                 CatchRow row = currentRow.copy();
407 
408                 // Get reference weight
409 
410                 Float referenceWeight = Numbers.getValueOrComputedValue(
411                         benthosBatch.getWeight(),
412                         benthosBatch.getComputedWeight());
413 
414                 if (referenceWeight == null) {
415                     referenceWeight = Numbers.getValueOrComputedValue(
416                             benthosBatch.getSampleCategoryWeight(),
417                             benthosBatch.getSampleCategoryComputedWeight());
418                 }
419 
420                 setRaisingFactor(row, totalBatchWeight, referenceWeight);
421                 rows.add(row);
422             } else {
423 
424                 // there is some frequencies
425 
426                 Float referenceWeight = null;
427 
428                 boolean withNoWeightOnFrequencies =
429                         benthosBatchFrequency.get(0).getWeight() == null;
430 
431                 if (withNoWeightOnFrequencies) {
432 
433                     // no weight on frequencies use upper reference weight
434 
435                     referenceWeight = Numbers.getValueOrComputedValue(
436                             benthosBatch.getWeight(),
437                             benthosBatch.getComputedWeight());
438 
439                     if (referenceWeight == null) {
440                         referenceWeight = Numbers.getValueOrComputedValue(
441                                 benthosBatch.getSampleCategoryWeight(),
442                                 benthosBatch.getSampleCategoryComputedWeight());
443                     }
444                 }
445 
446                 float frequencyWeights = 0f;
447                 Set<CatchRow> frequencyRows = new LinkedHashSet<>();
448                 for (SpeciesBatchFrequency batchFrequency : benthosBatchFrequency) {
449                     CatchRow row = currentRow.copy();
450                     row.setFrequency(batchFrequency);
451                     frequencyRows.add(row);
452                     rows.add(row);
453 
454                     if (!withNoWeightOnFrequencies) {
455 
456                         // use concrete frequency weight
457                         referenceWeight = batchFrequency.getWeight();
458                         frequencyWeights += referenceWeight;
459                     }
460 
461                     setRaisingFactor(row, totalBatchWeight, referenceWeight);
462                 }
463 
464                 if (!withNoWeightOnFrequencies) {
465                     float computedFrequencyTotalWeight = frequencyWeights;
466                     frequencyRows.forEach(catchRow -> {
467                         catchRow.getLastSampleCategoryFilled().setSampleComputedWeight(computedFrequencyTotalWeight);
468                         catchRow.setComputedFrequencyTotalWeight(computedFrequencyTotalWeight);
469                     });
470                 }
471 
472             }
473 
474         } else {
475 
476             float sampleComputedWeight = 0f;
477 
478             for (SpeciesBatch childBatch : benthosBatch.getChildBatchs()) {
479                 // always use a copy, otherwise sample categories can be shared by brothers
480                 CatchRow childRow = currentRow.copy();
481                 addBenthosBatch(operationExportContext,
482                                 childRow,
483                                 rows,
484                                 childBatch,
485                                 totalBatchWeight);
486 
487                 ExportSampleCategory exportSampleCategory = childRow.getLastSampleCategoryFilled();
488                 Float categoryWeight = Numbers.getValueOrComputedValue(
489                         exportSampleCategory.getCategoryWeight(),
490                         exportSampleCategory.getComputedWeight());
491 
492                 if (categoryWeight == null) {
493 
494                     if (log.isWarnEnabled()) {
495                         log.warn(String.format("Campagne %s - Trait %s : Il existe une catégorie de poids non renseignée (lot benthos %s)", operationExportContext.getCruise().getName(), operationExportContext.getOperationLabel(), childBatch.getId()));
496                     }
497                     categoryWeight = 0f;
498 
499                 }
500 
501                 sampleComputedWeight += categoryWeight;
502             }
503             currentRow.getLastSampleCategoryFilled().setSampleComputedWeight(sampleComputedWeight);
504         }
505     }
506 
507     protected float computeFinalRaisingFactor(CatchRow row, Float raisingFactor) {
508 
509         float finalRaisingFactor;
510 
511         if (row.isVrac()) {
512 
513             finalRaisingFactor = raisingFactor;
514 
515         } else {
516 
517             finalRaisingFactor = 1f;
518 
519         }
520 
521         for (ExportSampleCategory exportSampleCategory : row.getSampleCategory()) {
522 
523             if (exportSampleCategory != null) {
524                 Float totalWeight = exportSampleCategory.getCategoryWeight();
525                 Float sampleWeight = Numbers.getValueOrComputedValue(
526                         exportSampleCategory.getSampleWeight(),
527                         exportSampleCategory.getSampleComputedWeight());
528 
529                 if (totalWeight != null && sampleWeight != null && sampleWeight != 0f) {
530 
531 
532                     float currentRate = totalWeight / sampleWeight;
533                     if (WeightUnit.KG.isNotEquals(1.0f, currentRate)) {
534 
535                         // the only case which can change the final rate
536                         finalRaisingFactor *= currentRate;
537                     }
538                 }
539             }
540         }
541 
542         if (row.isFrequencyWithWeight()) {
543 
544             Float frequencyWeight = row.getFrequencyWeight();
545             Float computedFrequencyTotalWeight = row.getComputedFrequencyTotalWeight();
546             float currentRate = computedFrequencyTotalWeight / frequencyWeight;
547             if (WeightUnit.KG.isNotEquals(1.0f, currentRate)) {
548 
549                 // the only case which can change the final rate
550                 finalRaisingFactor *= currentRate;
551             }
552 
553         }
554         return finalRaisingFactor;
555 
556     }
557 
558     protected void setRaisingFactor(CatchRow row, float totalBatchWeight, Float referenceWeight) {
559         row.setReferenceWeight(referenceWeight);
560         row.setRaisingFactor(referenceWeight == null ? 1.0f : (totalBatchWeight / referenceWeight));
561     }
562 
563     protected void addBatchSampleCategory(SampleCategoryModel sampleCategoryModel,
564                                           CatchRow currentRow,
565                                           Integer batchId,
566                                           Integer sampleCategoryId,
567                                           Serializable sampleCategoryValue,
568                                           Float sampleCategoryWeight,
569                                           Float sampleCategoryComputedWeight,
570                                           Float batchWeight,
571                                           String comment,
572                                           Integer batchNumber,
573                                           Boolean batchNumberComputed,
574                                           Integer batchRankOrder) {
575         currentRow.setBatchNumber(batchNumber);
576         currentRow.setBatchNumberComputed(batchNumberComputed);
577 
578         ExportSampleCategory<Serializable> sampleCategory = new ExportSampleCategory<>();
579         sampleCategory.setBatchId(batchId);
580         SampleCategoryModelEntry categoryById = sampleCategoryModel.getCategoryById(sampleCategoryId);
581         sampleCategory.setCategoryDef(categoryById);
582         sampleCategory.setCategoryValue(sampleCategoryValue);
583         sampleCategory.setCategoryWeight(sampleCategoryWeight);
584         sampleCategory.setSampleWeight(batchWeight);
585         sampleCategory.setComment(comment);
586 
587         sampleCategory.setComputedWeight(sampleCategoryComputedWeight);
588         sampleCategory.setWeightOrVolType(CatchModel.WEIGHT_OR_VOL_TYPE);
589         sampleCategory.setRankOrder(batchRankOrder);
590 
591         currentRow.addSampleCategory(sampleCategory);
592     }
593 
594 
595 }