Author: blavenier Date: 2013-02-07 16:51:23 +0100 (Thu, 07 Feb 2013) New Revision: 358 Url: http://forge.codelutin.com/projects/tutti/repository/revisions/358 Log: Fix : - save fishingOperation.name in DB with <gear.name><N_OP> - save Program, fill the description in databse, when comment is not filled in the UI Add : - SpeciesBatchFrequency persistence : save, and getAllxxx Change : - move pmfmId2SampleCategory into ReferentialPersistenceService.getSampleCategoryByPmfmId() - remove speciesBatchPersistenceService.getSpeciesBatch() (not used in the UI, no more in Unit Test) - remove used HQL queries on speciesBatchs - Unit test on species batch and frequency Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceImpl.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ProgramPersistenceServiceImpl.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ReferentialPersistenceService.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ReferentialPersistenceServiceImpl.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceService.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceServiceImpl.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/measure/MeasurementPersistenceHelper.java trunk/tutti-persistence/src/main/resources/queries-override.hbm.xml trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceServiceTest.java Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceImpl.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceImpl.java 2013-02-07 11:20:45 UTC (rev 357) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceImpl.java 2013-02-07 15:51:23 UTC (rev 358) @@ -555,9 +555,9 @@ gearPhysicalFeatures.setOperations(Sets.newHashSet((Operation) target)); } else { gearPhysicalFeatures.getOperations().add(target); - } - nameBuffer.append(source.getGear().getLabel()); + } } + nameBuffer.append(source.getGear().getLabel()); // Retrieve entities : Fishing Area FishingArea fishingArea; Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ProgramPersistenceServiceImpl.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ProgramPersistenceServiceImpl.java 2013-02-07 11:20:45 UTC (rev 357) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ProgramPersistenceServiceImpl.java 2013-02-07 15:51:23 UTC (rev 358) @@ -158,6 +158,10 @@ protected void beanToEntity(Program source, fr.ifremer.adagio.core.dao.administration.programStrategy.Program target, boolean copyIfNull) { + // If target.description is a fake value (see bottom in this method), restore the null value + if (target.getDescription() != null && target.getDescription().equals(target.getName())) { + target.setDescription(null); + } // Code : compute with : <prefixe><name> if (target.getCode() == null && source.getName() != null) { @@ -196,12 +200,11 @@ target.setName(source.getName()); } - // Description (=source.comment) - if (copyIfNull && source.getComment() == null) { - target.setDescription(null); - } else if (source.getComment() != null) { - target.setDescription(source.getComment()); - } + // Description (mandatory in database) + // If empty, use name (will be replace in the next save() - see upper in this method) + if (target.getDescription() == null) { + target.setDescription(source.getName()); + } // Zone if (copyIfNull && source.getZone() == null) { Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ReferentialPersistenceService.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ReferentialPersistenceService.java 2013-02-07 11:20:45 UTC (rev 357) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ReferentialPersistenceService.java 2013-02-07 15:51:23 UTC (rev 358) @@ -27,6 +27,7 @@ import fr.ifremer.tutti.persistence.TuttiPersistenceServiceImplementor; import fr.ifremer.tutti.persistence.entities.data.Cruise; import fr.ifremer.tutti.persistence.entities.data.Program; +import fr.ifremer.tutti.persistence.entities.data.SampleCategoryEnum; import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; import fr.ifremer.tutti.persistence.entities.referential.Country; @@ -205,4 +206,14 @@ */ @Transactional(readOnly = false) List<Gear> importTemporaryGear(List<Gear> gears); + + + /** + * Convert a PMFM ID into a SampleCategoryEnum.<br/> + * This method will typically use enumeration values, to compare with the given pmfmId. + * + * @param pmfmId a Id of a PMFM + * @return a SampleCategoryEnum, or null if the PMFM is not mapped + */ + SampleCategoryEnum getSampleCategoryByPmfmId(Integer pmfmId); } Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ReferentialPersistenceServiceImpl.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ReferentialPersistenceServiceImpl.java 2013-02-07 11:20:45 UTC (rev 357) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ReferentialPersistenceServiceImpl.java 2013-02-07 15:51:23 UTC (rev 358) @@ -31,6 +31,7 @@ import fr.ifremer.adagio.core.dao.referential.taxon.TaxonNameExtendDao; import fr.ifremer.adagio.core.dao.referential.taxon.TaxonRefTaxVO; import fr.ifremer.tutti.persistence.entities.TuttiEntities; +import fr.ifremer.tutti.persistence.entities.data.SampleCategoryEnum; import fr.ifremer.tutti.persistence.entities.referential.AbstractTuttiReferentialEntity; import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; @@ -658,4 +659,22 @@ || pmfmId.equals(enumeration.PMFM_ID_TRAWL_DISTANCE); } + @Override + public SampleCategoryEnum getSampleCategoryByPmfmId(Integer pmfmId) { + if (pmfmId == null) return null; + SampleCategoryEnum sampleCategory = null; + if (pmfmId.intValue() == enumeration.PMFM_ID_SORTED_UNSORTED.intValue()) { + sampleCategory = SampleCategoryEnum.sortedUnsorted; + } else if (enumeration.PMFM_ID_SIZE_CATEGORY.equals(pmfmId)) { + sampleCategory = SampleCategoryEnum.size; + } else if (enumeration.PMFM_ID_MATURITY.equals(pmfmId)) { + sampleCategory = SampleCategoryEnum.maturity; + } else if (enumeration.PMFM_ID_SEX.equals(pmfmId)) { + sampleCategory = SampleCategoryEnum.sex; + } else if (enumeration.PMFM_ID_AGE.equals(pmfmId)) { + sampleCategory = SampleCategoryEnum.age; + } + return sampleCategory; + } + } Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceService.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceService.java 2013-02-07 11:20:45 UTC (rev 357) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceService.java 2013-02-07 15:51:23 UTC (rev 358) @@ -43,8 +43,6 @@ List<SpeciesBatch> getAllRootSpeciesBatch(String fishingOperationId); - SpeciesBatch getSpeciesBatch(String id); - List<SpeciesBatchFrequency> getAllSpeciesBatchFrequency( String speciesBatchId); Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceServiceImpl.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceServiceImpl.java 2013-02-07 11:20:45 UTC (rev 357) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceServiceImpl.java 2013-02-07 15:51:23 UTC (rev 358) @@ -24,8 +24,30 @@ * #L% */ +import java.io.Serializable; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.annotation.Resource; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.FlushMode; +import org.hibernate.type.IntegerType; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.dao.DataRetrievalFailureException; +import org.springframework.stereotype.Service; + import com.google.common.base.Preconditions; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + import fr.ifremer.adagio.core.dao.data.batch.CatchBatchDao; import fr.ifremer.adagio.core.dao.data.batch.CatchBatchImpl; import fr.ifremer.adagio.core.dao.data.batch.SortingBatch; @@ -45,23 +67,7 @@ import fr.ifremer.tutti.persistence.entities.referential.CaracteristicType; import fr.ifremer.tutti.persistence.entities.referential.Species; import fr.ifremer.tutti.persistence.service.measure.MeasurementPersistenceHelper; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.hibernate.FlushMode; -import org.hibernate.type.IntegerType; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.dao.DataRetrievalFailureException; -import org.springframework.stereotype.Service; -import javax.annotation.Resource; -import java.io.Serializable; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - /** * @author tchemit <chemit@codelutin.com> * @since 0.3 @@ -91,82 +97,73 @@ @Override public List<SpeciesBatch> getAllRootSpeciesBatch(String fishingOperationId) { - Iterator<Object[]> list = queryList("allRootSpeciesBatch", - "fishingOperationId", IntegerType.INSTANCE, Integer.valueOf(fishingOperationId), - "qualitativeIdSortingType", IntegerType.INSTANCE, enumeration.QUALITATIVE_ID_SORTING_TYPE_SPECIES); + Iterator<Object[]> list = queryList("allSpeciesBatch", + "fishingOperationId", IntegerType.INSTANCE, Integer.valueOf(fishingOperationId)); List<SpeciesBatch> result = new ArrayList<SpeciesBatch>(); + List<SpeciesBatch> rootBatchs = new ArrayList<SpeciesBatch>(); + + Map<String, SpeciesBatch> batchMapById = new HashMap<String, SpeciesBatch>(); + //TODO BLA : uncomment if a property speciesBatch.speciesBatchFrequency exists + //Map<String, List<SpeciesBatchFrequency>> batchFrequenciesMapByParentId = new HashMap<String, List<SpeciesBatchFrequency>>(); + Map<String, String> parentBatchMapById = new HashMap<String, String>(); while (list.hasNext()) { Object[] source = list.next(); - SpeciesBatch speciesBatch = loadSpeciesBatch(source, true); - result.add(speciesBatch); + + Integer parentbatchId = (Integer) source[11]; + + // If row is not a species batch, load as batch frequency + if (couldBeASpeciesBatchFrequency(source)){ + //TODO BLA : uncomment if a property speciesBatch.speciesBatchFrequency exists + //loadSpeciesBatchFrequency(source, batchFrequenciesMapByParentId); + } + else { + // In all case, load row as species batch + SpeciesBatch speciesBatch = loadSpeciesBatch(source); + + // Add result into a maps + batchMapById.put(speciesBatch.getId(), speciesBatch); + if (parentbatchId != null) { + parentBatchMapById.put(speciesBatch.getId(), parentbatchId.toString()); + } + } } - return result; - } + // Retrieve the parent links for all batchs + for (Iterator<SpeciesBatch> iterator = batchMapById.values().iterator(); iterator.hasNext(); ) { + SpeciesBatch speciesBatch = (SpeciesBatch) iterator.next(); -// @Override -// public List<SpeciesBatch> getAllSpeciesBatch(String fishingOperationId) { -// Iterator<Object[]> list = queryList("allSpeciesBatch", -// "fishingOperationId", IntegerType.INSTANCE, Integer.valueOf(fishingOperationId)); -// -// List<SpeciesBatch> result = new ArrayList<SpeciesBatch>(); -// List<SpeciesBatch> rootBatchs = new ArrayList<SpeciesBatch>(); -// -// Map<String, SpeciesBatch> batchMapById = new HashMap<String, SpeciesBatch>(); -// Map<String, String> parentBatchMapById = new HashMap<String, String>(); -// while (list.hasNext()) { -// Object[] source = list.next(); -// SpeciesBatch speciesBatch = loadSpeciesBatch(source, false); -// batchMapById.put(speciesBatch.getId(), speciesBatch); -// -// Integer parentbatchId = (Integer) source[11]; -// if (parentbatchId != null) { -// parentBatchMapById.put(speciesBatch.getId(), parentbatchId.toString()); -// } -// } -// -// for (Iterator iterator = batchMapById.values().iterator(); iterator.hasNext(); ) { -// SpeciesBatch speciesBatch = (SpeciesBatch) iterator.next(); -// -// // Retrieve the parent SpeciesBatch -// String parentbatchId = parentBatchMapById.get(speciesBatch.getId()); -// if (parentbatchId != null) { -// SpeciesBatch parentSpeciesBatch = batchMapById.get(parentbatchId); -// -// // If found, link the batch with its parent : -// if (parentSpeciesBatch != null) { -// speciesBatch.setParentBatch(parentSpeciesBatch); -// if (parentSpeciesBatch.getChildBatchs() == null) { -// parentSpeciesBatch.setChildBatchs(Lists.newArrayList(speciesBatch)); -// } else { -// parentSpeciesBatch.addChildBatchs(speciesBatch); -// } -// } -// -// // If no parent found = batch is a child of the catch batch -// else { -// rootBatchs.add(speciesBatch); -// } -// } -// } -// -// // Apply inheritance, starting with the catch batch children -// applyInheritedProperties(rootBatchs, null, null, result); -// -// return result; -// } -// - @Override - public SpeciesBatch getSpeciesBatch(String id) { - Object[] source = queryUnique("speciesBatch", - "batchId", IntegerType.INSTANCE, Integer.valueOf(id)); + // If retrieve the parent from the parent map + String parentbatchId = parentBatchMapById.get(speciesBatch.getId()); + if (parentbatchId != null) { + SpeciesBatch parentSpeciesBatch = batchMapById.get(parentbatchId); - if (source == null) { - throw new DataRetrievalFailureException("Could not retrieve speciesBatch with id=" + id); + // If found, link the batch with its parent : + if (parentSpeciesBatch != null) { + speciesBatch.setParentBatch(parentSpeciesBatch); + if (parentSpeciesBatch.getChildBatchs() == null) { + parentSpeciesBatch.setChildBatchs(Lists.newArrayList(speciesBatch)); + } else { + parentSpeciesBatch.addChildBatchs(speciesBatch); + } + } + + // If no parent found, the batch should be a direct child of the catch batch + else { + rootBatchs.add(speciesBatch); + } + + //TODO BLA : uncomment if a property speciesBatch.speciesBatchFrequency exists + //List<SpeciesBatchFrequency> batchFrequencies = batchFrequenciesMapByParentId.get(speciesBatch.getId()); + //if (batchFrequencies != null) { + // speciesBatch.setSpeciesBatchFrequency(batchFrequencies) + //} + } } - SpeciesBatch result = loadSpeciesBatch(source, true); + // Apply inheritance, starting with the catch batch children + applyInheritedProperties(rootBatchs, null, null, result); + return result; } @@ -195,7 +192,9 @@ Preconditions.checkNotNull(bean); Preconditions.checkNotNull(bean.getId()); - getCurrentSession().clear(); + // TODO BL : pourquoi un clear() ? => pas nécessaire. + //getCurrentSession().clear(); + getCurrentSession().enableFetchProfile("batch-with-measurements"); getCurrentSession().setFlushMode(FlushMode.COMMIT); SortingBatch batch = sortingBatchDao.load(Integer.valueOf(bean.getId())); @@ -234,15 +233,98 @@ @Override public List<SpeciesBatchFrequency> getAllSpeciesBatchFrequency( String speciesBatchId) { + Iterator<Object[]> list = queryList("allSpeciesBatchFrequency", + "parentBatchId", IntegerType.INSTANCE, Integer.valueOf(speciesBatchId)); + List<SpeciesBatchFrequency> results = Lists.newArrayList(); - // TODO + + while (list.hasNext()) { + Object[] source = list.next(); + SpeciesBatchFrequency target = new SpeciesBatchFrequency(); + + int colIndex = 0; + target.setId(source[colIndex++].toString()); + + target.setNumber((Integer)source[colIndex++]); + target.setWeight((Float)source[colIndex++]); + target.setComment((String)source[colIndex++]); + + // Length step category + Integer lengthPmfmId = (Integer)source[colIndex++]; + Caracteristic lengthStepCaracteristic = referentialService.getCaracteristic(lengthPmfmId); + target.setLengthStepCaracteristic(lengthStepCaracteristic); + + // Length + target.setLengthStep((Float)source[colIndex++]); + results.add(target); + } return results; } - @Override + + @Override public List<SpeciesBatchFrequency> saveSpeciesBatchFrequency( String speciesBatchId, List<SpeciesBatchFrequency> frequencies) { - //TODO + Preconditions.checkNotNull(speciesBatchId); + Preconditions.checkNotNull(frequencies); + + if (frequencies.size() == 0) { + return frequencies; + } + getCurrentSession().setFlushMode(FlushMode.COMMIT); + getCurrentSession().enableFetchProfile("batch-with-measurements"); + + // Retirve parent + SortingBatch parentBatch = sortingBatchDao.load(Integer.valueOf(speciesBatchId)); + + short rankOrder = 0; + String pmfmId = null; + Map<SortingBatch, SpeciesBatchFrequency> batchsToCreate = Maps.newHashMap(); + List<SortingBatch> batchsToUpdate= Lists.newArrayList(); + for (Iterator iterator = frequencies.iterator(); iterator.hasNext();) { + SpeciesBatchFrequency source = (SpeciesBatchFrequency) iterator.next(); + rankOrder++; + + // Check that all frequencies have the same length PMFM + if (pmfmId == null) { + source.getLengthStepCaracteristic().getId(); + } + else if (!pmfmId.equals(source.getLengthStepCaracteristic().getId())) { + throw new DataIntegrityViolationException("Batch frequencies under one Speciesbatch must have all the same lengthStepCaracteristic"); + } + + // Not existing batch + SortingBatch target = null; + if (source.getId() == null) { + target = SortingBatch.Factory.newInstance(); + + // Fill the sorting batch from the source + beanToEntity(source, target, parentBatch, rankOrder, true); + + // Create the targeted batch, then update the source id + sortingBatchDao.create(target); + source.setId(target.getId().toString()); + } + + // Existing batch + else { + target = sortingBatchDao.load(Integer.valueOf(source.getId())) ; + + // Fill the sorting batch from the source + beanToEntity(source, target, parentBatch, rankOrder, true); + + // Add the batch into a list (will be update later, using this list) + batchsToUpdate.add(target); + } + } + + // If some batchs need to be update, do it + if (batchsToUpdate.size() > 0) { + sortingBatchDao.update(batchsToUpdate); + } + + getCurrentSession().flush(); + return frequencies; } @@ -406,7 +488,7 @@ } } - protected SpeciesBatch loadSpeciesBatch(Object[] source, boolean sourceHasPmfmGrandParent) { + protected SpeciesBatch loadSpeciesBatch(Object[] source) { int colIndex = 0; SpeciesBatch result = new SpeciesBatch(); @@ -415,22 +497,13 @@ // Individual count result.setNumber((Integer) source[colIndex++]); - // Weight & sampleCategory Weight - Float sampleWeight = (Float) source[colIndex++]; - Float samplingRatio = (Float) source[colIndex++]; - String samplingRatioText = (String) source[colIndex++]; - if (samplingRatio == null) { - result.setWeight(sampleWeight); - } else if (sampleWeight != null) { - String startStr = sampleWeight.toString().replace(',', '.') + "/"; - if (samplingRatioText != null && samplingRatioText.startsWith(startStr)) { - String weightStr = samplingRatioText.substring(startStr.length()); - if (weightStr != null && !weightStr.isEmpty()) { - result.setSampleCategoryWeight(sampleWeight); - result.setWeight(Float.parseFloat(weightStr)); - } - } - } + // Convert database weight (and sampling ratio) into UI weight and sampleCategoryWeight + Float sourceWeight = (Float) source[colIndex++]; + Float sourceSamplingRatio = (Float) source[colIndex++]; + String sourceSamplingRatioText = (String) source[colIndex++]; + UIWeight uiWeight = convertDatabase2UI(sourceWeight, sourceSamplingRatio, sourceSamplingRatioText); + result.setWeight(uiWeight.weight); + result.setSampleCategoryWeight(uiWeight.sampleWeight); // Comments result.setComment((String) source[colIndex++]); @@ -442,7 +515,10 @@ Integer qvValue = (Integer) source[colIndex++]; Float numValue = (Float) source[colIndex++]; String alphaValue = (String) source[colIndex++]; - + if (pmfmId != null) { + setSampleCategoryQualitative(result, pmfmId, numValue, alphaValue, qvValue); + } + // Species Integer referenceTaxonId = (Integer) source[colIndex++]; if (referenceTaxonId != null) { @@ -450,59 +526,49 @@ Species species = referentialService.getSpecies(referenceTaxonId.toString()); result.setSpecies(species); } - - if (sourceHasPmfmGrandParent && colIndex == source.length - 2) { - Integer pmfmIdGrandFather = (Integer) source[colIndex++]; - Integer qualitativeIdGrandFather = (Integer) source[colIndex++]; - - if (pmfmId != null) { - setSampleCategoryQualitative(result, pmfmId, numValue, alphaValue, qvValue); - } - // When no sorting measurement found, retrieve the sorted/unsorted from an ancestor batch - else { - if (referenceTaxonId != null - && enumeration.PMFM_ID_SORTED_UNSORTED.equals(pmfmIdGrandFather) - && qualitativeIdGrandFather != null) { - setSampleCategoryQualitative(result, pmfmIdGrandFather, null, null, qualitativeIdGrandFather); - } else { - // TODO TC : manage this exception in the UI => 'format des captures incompatibles avec tutti...' - // TODO TC : add a throws 'InvalidBatchTreeException' in the interface method ? - throw new DataRetrievalFailureException("Invalid batch tree found in database (no sample category Vrac/HorsVrac found in parents) : could not be load batch with id=" + result.getId()); - } - } - } - + return result; } - protected void applyInheritedProperties(List<SpeciesBatch> speciesBatchs, Serializable inheritedSampleCategoryValue, Species inheritedSpecies, List<SpeciesBatch> result) { + protected void applyInheritedProperties(List<SpeciesBatch> speciesBatchs, CaracteristicQualitativeValue inheritedSortedUnsortedValue, Species inheritedSpecies, List<SpeciesBatch> results) { if (speciesBatchs == null || speciesBatchs.size() == 0) { return; } - boolean hasAppliedCategoryValue = false; - for (Iterator iterator = speciesBatchs.iterator(); iterator.hasNext(); ) { - SpeciesBatch speciesBatch = (SpeciesBatch) iterator.next(); + for (Iterator<SpeciesBatch> iterator = speciesBatchs.iterator(); iterator.hasNext(); ) { + SpeciesBatch speciesBatch = iterator.next(); + + // If batch store a species (in the database) + if (speciesBatch.getSpecies() != null) { + // Remove the link to the parent (not need in UI) + speciesBatch.setParentBatch(null); + // Store into result list only if species has been set (=species root batch) + results.add(speciesBatch); + } - if (speciesBatch.getSpecies() != null && speciesBatch.getSampleCategoryType() == null) { + // Apply sampleCategoryValue inheritance, if need + if (inheritedSortedUnsortedValue != null && speciesBatch.getSampleCategoryType() == null) { speciesBatch.setSampleCategoryType(SampleCategoryEnum.sortedUnsorted); - speciesBatch.setSampleCategoryValue(inheritedSampleCategoryValue); - hasAppliedCategoryValue = true; - - // Remove the link to the parent (not need after inheritance) - speciesBatch.setParentBatch(null); - } else if (speciesBatch.getSpecies() == null && inheritedSpecies != null) { + speciesBatch.setSampleCategoryValue(inheritedSortedUnsortedValue); + } + + // Apply species inheritance, if need + if (speciesBatch.getSpecies() == null && inheritedSpecies != null) { speciesBatch.setSpecies(inheritedSpecies); } - // Store into result list only if species has been set (ignore upper batch) - if (speciesBatch.getSpecies() != null) { - result.add(speciesBatch); + // Compute the inheritance sorted/unsorted value for children + if (speciesBatch.getSampleCategoryType() == SampleCategoryEnum.sortedUnsorted) { + inheritedSortedUnsortedValue = (CaracteristicQualitativeValue)speciesBatch.getSampleCategoryValue(); } - - // Recursive call : propage species but not category if already applied + else { + inheritedSortedUnsortedValue = null; + } + + // Recursive call : propagate species and sorted/unsorted value applyInheritedProperties(speciesBatch.getChildBatchs(), - (hasAppliedCategoryValue ? null : inheritedSampleCategoryValue), - speciesBatch.getSpecies(), result); + inheritedSortedUnsortedValue, + speciesBatch.getSpecies(), + results); } } @@ -519,10 +585,14 @@ } protected void setSampleCategoryQualitative(SpeciesBatch target, Integer pmfmId, Float numericalvalue, String alphanumericalValue, Integer qualitativeValueId) { - if (pmfmId == null) { + // skip if null or corresponding to the SORTING_TYPE PMFM (Expèce, Benthos, Plancton, etc.) + if (pmfmId == null || pmfmId.equals(enumeration.PMFM_ID_SORTING_TYPE)) { return; } - SampleCategoryEnum sampleCategory = measurementHelper.pmfmId2SampleCategory(pmfmId); + + SampleCategoryEnum sampleCategory = referentialService.getSampleCategoryByPmfmId(pmfmId); + Preconditions.checkNotNull(sampleCategory, "Unable to find corresponding SampleCategoryEnum for PMFM.ID : " + pmfmId); + target.setSampleCategoryType(sampleCategory); if (numericalvalue != null) { target.setSampleCategoryValue(numericalvalue); @@ -566,5 +636,171 @@ batch.getQuantificationMeasurements().clear(); sortingBatchDao.remove(batch); } + + protected void beanToEntity(SpeciesBatchFrequency source, SortingBatch target, SortingBatch parentBatch, short rankOrder, boolean copyIfNull) { + Preconditions.checkNotNull(source.getBatch()); + Preconditions.checkNotNull(source.getBatch().getId()); + // Retrieve recorder department + // TODO BLA : prendre le service du 1er saisisseur ? + Integer recorderDepartmentId = enumeration.DEPARTMENT_ID_UNKNOWN_RECORDER_DEPARTMENT; + + // Create lists to store all updates, then remove not updated items + Set<QuantificationMeasurement> notChangedQuantificationMeasurements = new HashSet<QuantificationMeasurement>(); + if (target.getQuantificationMeasurements() != null) { + notChangedQuantificationMeasurements.addAll(target.getQuantificationMeasurements()); + } + Set<SortingMeasurement> notChangedSortingMeasurements = new HashSet<SortingMeasurement>(); + if (target.getSortingMeasurements() != null) { + notChangedSortingMeasurements.addAll(target.getSortingMeasurements()); + } + + // If parent and root need to be set + if (target.getId() == null + || target.getRootBatch() == null + || (target.getParentBatch() != null && !target.getParentBatch().getId().equals(parentBatch.getId()))) { + + target.setParentBatch(parentBatch); + target.setRootBatch(parentBatch.getRootBatch()); + } + + // RankOrder + target.setRankOrder(rankOrder); + + // Weight or SampleCategoryWeight + if (copyIfNull && source.getWeight() == null) { + // Nothing to do : will be removed later, using notChangedSortingMeasurements + } else if (source.getWeight() != null) { + QuantificationMeasurement quantificationMeasurement = measurementHelper.setQuantificationMeasurement(target, enumeration.PMFM_ID_WEIGHT_MEASURED, recorderDepartmentId, source.getWeight(), true); + notChangedQuantificationMeasurements.remove(quantificationMeasurement); + } + + // Sorting measurement + if (copyIfNull && (source.getLengthStepCaracteristic() == null || source.getLengthStep() == null)) { + // Nothing to do : will be removed later, using notChangedSortingMeasurements + } else if (source.getLengthStepCaracteristic() != null && source.getLengthStep() != null) { + Integer pmfmId = Integer.valueOf(source.getLengthStepCaracteristic().getId()); + SortingMeasurement sortingMeasurement = measurementHelper.setSortingMeasurement(target, recorderDepartmentId, pmfmId, source.getLengthStep()); + notChangedSortingMeasurements.remove(sortingMeasurement); + } + + // Individual count + if (copyIfNull && source.getNumber() == null) { + target.setIndividualCount(null); + } else if (source.getNumber() != null) { + target.setIndividualCount(source.getNumber()); + } + + // Species + target.setReferenceTaxon(null); + + // QualityFlag + target.setQualityFlag(parentBatch.getQualityFlag()); + + // Comments + if (copyIfNull && source.getComment() == null) { + target.setComments(null); + } else if (source.getComment() != null) { + target.setComments(source.getComment()); + } + + // Removed not changed measurements (in sorting and quantification measurement lists) + if (target.getQuantificationMeasurements() != null && notChangedQuantificationMeasurements.size() > 0) { + for (QuantificationMeasurement qm : notChangedQuantificationMeasurements) { + target.getQuantificationMeasurements().remove(qm); + } + } + if (target.getSortingMeasurements() != null && notChangedSortingMeasurements.size() > 0) { + for (SortingMeasurement sm : notChangedSortingMeasurements) { + target.getSortingMeasurements().remove(sm); + } + } + } + + private SpeciesBatchFrequency loadSpeciesBatchFrequency(Object[] source, Map<String, List<SpeciesBatchFrequency>> batchFrequenciesMapByParentId) { + SpeciesBatchFrequency target = new SpeciesBatchFrequency(); + + int colIndex = 0; + target.setId(source[colIndex++].toString()); + + // Individual count + target.setNumber((Integer)source[colIndex++]); + + // Covert database weight (and sampling ratio) into UI weight + Float sourceWeight = (Float) source[colIndex++]; + Float sourceSamplingRatio = (Float) source[colIndex++]; + String sourceSamplingRatioText = (String) source[colIndex++]; + UIWeight uiWeight = convertDatabase2UI(sourceWeight, sourceSamplingRatio, sourceSamplingRatioText); + target.setWeight(uiWeight.weight); + + target.setComment((String)source[colIndex++]); + + // Length step category + Integer lengthPmfmId = (Integer)source[colIndex++]; + Caracteristic lengthStepCaracteristic = referentialService.getCaracteristic(lengthPmfmId); + target.setLengthStepCaracteristic(lengthStepCaracteristic); + + // Qualitative value (should be null) + Preconditions.checkState(source[colIndex++] == null, "Invalid batch tree format : batch frequency could not have a qualitative value."); + + // Length (skip qvValue and alphaValue column) + target.setLengthStep((Float) source[colIndex++]); + + // Alphanumerical value (should be null) + Preconditions.checkState(source[colIndex++] == null, "Invalid batch tree format : batch frequency could not have a alphanumerical value."); + + // Taxon (should be null) + Preconditions.checkState(source[colIndex++] == null, "Invalid batch tree format : taxon frequency could not have species."); + + Integer parentBatchId = (Integer)source[colIndex++]; + + // Add target into the result map + List<SpeciesBatchFrequency> parentBatchFrequencies = batchFrequenciesMapByParentId.get(parentBatchId.toString()); + if (parentBatchFrequencies == null) { + parentBatchFrequencies = Lists.newArrayList(); + batchFrequenciesMapByParentId.put(parentBatchId.toString(), parentBatchFrequencies); + } + parentBatchFrequencies.add(target); + + return target; + } + + protected boolean couldBeASpeciesBatchFrequency(Object[] source) { + Integer pmfmId = (Integer)source[6]; + Integer referenceTaxonId = (Integer) source[10]; + Float numericalValue = (Float) source[8]; + Integer parentbatchId = (Integer) source[11]; + SampleCategoryEnum sampleCategory = referentialService.getSampleCategoryByPmfmId(pmfmId); + + // Batch frequency is a batch with : + // - a numerical value + // - a parent + // - no species + // - no corresponding sample category + return numericalValue != null && parentbatchId != null && referenceTaxonId == null && sampleCategory == null; + } + + protected UIWeight convertDatabase2UI(Float weight, Float samplingRatio, String samplingRatioText) { + UIWeight result = new UIWeight(); + + // Weight & sampleCategory Weight + if (samplingRatio == null) { + result.weight = weight; + } else if (weight != null) { + String startStr = weight.toString().replace(',', '.') + "/"; + if (samplingRatioText != null && samplingRatioText.startsWith(startStr)) { + String weightStr = samplingRatioText.substring(startStr.length()); + if (weightStr != null && !weightStr.isEmpty()) { + result.sampleWeight=weight; + result.weight=Float.parseFloat(weightStr); + } + } + } + return result; + } + + class UIWeight { + Float sampleWeight=null; + Float weight=null; + } } Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/measure/MeasurementPersistenceHelper.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/measure/MeasurementPersistenceHelper.java 2013-02-07 11:20:45 UTC (rev 357) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/measure/MeasurementPersistenceHelper.java 2013-02-07 15:51:23 UTC (rev 358) @@ -226,24 +226,6 @@ return pmfmId; } - public SampleCategoryEnum pmfmId2SampleCategory(Integer pmfmId) { - SampleCategoryEnum sampleCategory = null; - if (pmfmId.intValue() == enumeration.PMFM_ID_SORTED_UNSORTED.intValue()) { - sampleCategory = SampleCategoryEnum.sortedUnsorted; - } else if (enumeration.PMFM_ID_SIZE_CATEGORY.equals(pmfmId)) { - sampleCategory = SampleCategoryEnum.size; - } else if (enumeration.PMFM_ID_MATURITY.equals(pmfmId)) { - sampleCategory = SampleCategoryEnum.maturity; - } else if (enumeration.PMFM_ID_SEX.equals(pmfmId)) { - sampleCategory = SampleCategoryEnum.sex; - } else if (enumeration.PMFM_ID_AGE.equals(pmfmId)) { - sampleCategory = SampleCategoryEnum.age; - } - if (sampleCategory == null) { - throw new IllegalArgumentException("Unable to find corresponding SampleCategoryEnum for PMFM.ID : " + pmfmId); - } - return sampleCategory; - } public GearPhysicalFeatures getGearPhysicalfeatures(FishingTrip fishingTrip, Integer gearId) { return getGearPhysicalfeatures(fishingTrip, gearId, false); Modified: trunk/tutti-persistence/src/main/resources/queries-override.hbm.xml =================================================================== --- trunk/tutti-persistence/src/main/resources/queries-override.hbm.xml 2013-02-07 11:20:45 UTC (rev 357) +++ trunk/tutti-persistence/src/main/resources/queries-override.hbm.xml 2013-02-07 15:51:23 UTC (rev 358) @@ -306,44 +306,6 @@ <query-param name="pmfmIdSortingType" type="java.lang.Integer"/> </query> - <query name="allRootSpeciesBatch"> - <![CDATA[ - SELECT - b.id as batchId, - b.individualCount AS individualCount, - qm.numericalValue AS weight, - b.samplingRatio AS samplingRatio, - b.samplingRatioText AS samplingRatioText, - b.comments AS comments, - sm.pmfm.id AS pmfmId, - sm.qualitativeValue.id as qvValue, - sm.numericalValue AS numValue, - sm.alphanumericalValue AS alphaValue, - b.referenceTaxon.id AS referenceTaxonId, - smSorted.pmfm.id AS pmfmIdGrandFather, - smSorted.qualitativeValue.id AS qualitativeIdGrandFather - FROM - CatchBatchImpl cb - INNER JOIN cb.childBatchs batchSorted - INNER JOIN batchSorted.childBatchs batchSortingType - INNER JOIN batchSortingType.childBatchs b - INNER JOIN batchSortingType.sortingMeasurements smSortingType - LEFT OUTER JOIN batchSorted.sortingMeasurements smSorted - LEFT OUTER JOIN b.sortingMeasurements sm - LEFT OUTER JOIN b.quantificationMeasurements qm - WHERE - cb.fishingOperation.id=:fishingOperationId - AND ( - qm is null - OR qm.isReferenceQuantification=true - ) - AND smSortingType.qualitativeValue.id=:qualitativeIdSortingType - ORDER BY b.id - ]]> - <query-param name="fishingOperationId" type="java.lang.Integer"/> - <query-param name="qualitativeIdSortingType" type="java.lang.Integer"/> - </query> - <query name="allSpeciesBatch"> <![CDATA[ SELECT @@ -402,50 +364,44 @@ <query-param name="qualitativeIdSortingType" type="java.lang.Integer"/> </query> - <query name="speciesBatch"> + <query name="speciesBatchChildren"> <![CDATA[ SELECT - b.id AS batchId, + cb.id + FROM + SortingBatchImpl b + INNER JOIN b.childBatchs cb + WHERE + b.id = :batchId + ]]> + <query-param name="batchId" type="java.lang.Integer"/> + </query> + + <query name="allSpeciesBatchFrequency"> + <![CDATA[ + SELECT + b.id as batchId, b.individualCount AS individualCount, qm.numericalValue AS weight, - b.samplingRatio AS samplingRatio, - b.samplingRatioText AS samplingRatioText, b.comments AS comments, sm.pmfm.id AS pmfmId, - sm.qualitativeValue.id as qvValue, - sm.numericalValue AS numValue, - sm.alphanumericalValue AS alphaValue, - b.referenceTaxon.id AS referenceTaxonId, - smSorted.pmfm.id AS pmfmIdGrandFather, - smSorted.qualitativeValue.id AS qualitativeIdGrandFather + sm.numericalValue AS numValue FROM SortingBatchImpl b - INNER JOIN b.parentBatch batchSortingType - INNER JOIN batchSortingType.parentBatch batchSorted - LEFT OUTER JOIN batchSorted.sortingMeasurements smSorted LEFT OUTER JOIN b.sortingMeasurements sm LEFT OUTER JOIN b.quantificationMeasurements qm WHERE - b.id = :batchId + b.parentBatch.id=:parentBatchId AND ( qm is null OR qm.isReferenceQuantification=true - ) - ]]> - <query-param name="batchId" type="java.lang.Integer"/> - </query> - - <query name="speciesBatchChildren"> - <![CDATA[ - SELECT - cb.id - FROM - SortingBatchImpl b - INNER JOIN b.childBatchs cb - WHERE - b.id = :batchId - ]]> - <query-param name="batchId" type="java.lang.Integer"/> + ) + AND sm.numericalValue is not null + AND sm.pmfm.parameter.isAlphanumeric=false + AND sm.pmfm.parameter.isQualitative=false + ORDER BY sm.numericalValue + ]]> + <query-param name="parentBatchId" type="java.lang.Integer"/> </query> <!-- ===================================================================== --> Modified: trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceServiceTest.java =================================================================== --- trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceServiceTest.java 2013-02-07 11:20:45 UTC (rev 357) +++ trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceServiceTest.java 2013-02-07 15:51:23 UTC (rev 358) @@ -30,8 +30,10 @@ import fr.ifremer.tutti.persistence.entities.data.FishingOperation; import fr.ifremer.tutti.persistence.entities.data.SampleCategoryEnum; import fr.ifremer.tutti.persistence.entities.data.SpeciesBatch; +import fr.ifremer.tutti.persistence.entities.data.SpeciesBatchFrequency; import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; +import fr.ifremer.tutti.persistence.entities.referential.CaracteristicType; import fr.ifremer.tutti.persistence.entities.referential.Species; import org.junit.Before; import org.junit.ClassRule; @@ -39,15 +41,20 @@ import org.junit.Test; import org.springframework.dao.DataRetrievalFailureException; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; +import java.util.Iterator; import java.util.List; +import java.util.Map; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; /** * @author tchemit <chemit@codelutin.com> @@ -94,6 +101,7 @@ protected CaracteristicQualitativeValue unkQualitativeValue; + protected Caracteristic frequencyPMFM; protected String speciesBacthId = null; @@ -149,13 +157,27 @@ maleQualitativeValue = sexPMFM.getQualitativeValue(1); femaleQualitativeValue = sexPMFM.getQualitativeValue(2); unkQualitativeValue = sexPMFM.getQualitativeValue(3); + + + List<Caracteristic> cara = referentialService.getAllCaracteristic(); + for (Iterator iterator = cara.iterator(); iterator.hasNext();) { + Caracteristic caracteristic = (Caracteristic) iterator.next(); + if (caracteristic.getCaracteristicType() == CaracteristicType.NUMBER + && caracteristic.getPrecision() != null + && caracteristic.getPrecision().floatValue() == 0.5f) { + frequencyPMFM = caracteristic; + break; + } + } + assertNotNull("no numerical PMFM with a precision has been found. Could not define a PMFM for batch frequencies.", frequencyPMFM); } @Test public void createSpeciesBatch(/*SpeciesBatch bean, String parentBatchId*/) { - SpeciesBatch esp1Batch; - SpeciesBatch esp2Batch; - SpeciesBatch batch; + SpeciesBatch esp1Batch = null; + SpeciesBatch esp2Batch = null; + SpeciesBatch frequenciesParentBatch = null; + SpeciesBatch batch = null; Species taxon1 = species.get(0); Species taxon2 = species.get(1); @@ -233,7 +255,7 @@ batch = new SpeciesBatch(); batch.setId(null); batch.setParentBatch(esp2Batch); - batch.setSpecies(taxon1); + batch.setSpecies(taxon2); batch.setComment("ESP2 - Vrac/7 UNK/2 ss-ech/1 Nombre/11"); batch.setSampleCategoryType(SampleCategoryEnum.maturity); batch.setSampleCategoryValue(firstMaturityQualitativeValue); @@ -258,8 +280,11 @@ // Save and reload, then check SpeciesBatch savedBatch = service.saveSpeciesBatch(batch); assertSpeciesBatch(savedBatch, batch, false); - SpeciesBatch reloadedBatch = service.getSpeciesBatch(savedBatch.getId()); + SpeciesBatch reloadedBatch = getSpeciesBatch(fishingOperation.getId(), savedBatch.getId()); assertSpeciesBatch(reloadedBatch, savedBatch, true); + + // Save batch for later + frequenciesParentBatch = batch; // ----------------------------------------------------------------------------- // 6. Test get all root species @@ -267,13 +292,43 @@ List<SpeciesBatch> rootSpeciesBatch = service.getAllRootSpeciesBatch(fishingOperation.getId()); assertNotNull(rootSpeciesBatch); assertEquals(2, rootSpeciesBatch.size()); - -// // ----------------------------------------------------------------------------- -// // 4. Test get all species -// // ----------------------------------------------------------------------------- -// List<SpeciesBatch> allSpeciesBatch = service.getAllSpeciesBatch(fishingOperation.getId()); -// assertNotNull(allSpeciesBatch); -// assertEquals(5, allSpeciesBatch.size()); + assertNotNull(rootSpeciesBatch.get(0).getChildBatchs()); + assertEquals(2,rootSpeciesBatch.get(0).getChildBatchs().size()); + assertNotNull(rootSpeciesBatch.get(1).getChildBatchs()); + assertEquals(1,rootSpeciesBatch.get(1).getChildBatchs().size()); + + // ----------------------------------------------------------------------------- + // 8. Test batch frequency creation + // ----------------------------------------------------------------------------- + + List<SpeciesBatchFrequency> frequencies = Lists.newArrayList(); + float lengthStep = 0.5f; + for (float length = lengthStep; length < lengthStep * 20; length+=lengthStep) { + SpeciesBatchFrequency frequency = new SpeciesBatchFrequency(); + frequency.setLengthStep(length); + frequency.setNumber((int)(length*2)); + frequency.setWeight(0.01f*length*2); + frequency.setLengthStepCaracteristic(frequencyPMFM); + frequency.setBatch(frequenciesParentBatch); + frequency.setComment("comments"); + frequencies.add(frequency); + } + List<SpeciesBatchFrequency> createdFrequencies = assertCreateAndReloadSpeciesBatchFrequency(frequencies, frequenciesParentBatch.getId()); + + // ----------------------------------------------------------------------------- + // 9. Test batch frequency update + // ----------------------------------------------------------------------------- + // Update some batchs (1cm, 2cm, etc) + for (Iterator iterator = createdFrequencies.iterator(); iterator.hasNext();) { + SpeciesBatchFrequency speciesBatchFrequency = (SpeciesBatchFrequency) iterator.next(); + float length = speciesBatchFrequency.getLengthStep(); + if ((float)(int)length == length) { + speciesBatchFrequency.setNumber(12); + speciesBatchFrequency.setComment(null); + } + } + List<SpeciesBatchFrequency> savedFrequencies = service.saveSpeciesBatchFrequency(frequenciesParentBatch.getId(), frequencies); + assertBatchFrequencies(createdFrequencies, savedFrequencies, true); } @Test @@ -282,23 +337,13 @@ } - @Test - @Ignore - public void getSpeciesBatch(/*String id*/) { - if (speciesBacthId == null) return; - SpeciesBatch batch = service.getSpeciesBatch(speciesBacthId); - assertNotNull(batch); + public void saveSpeciesBatchFrequency() { + } @Test @Ignore - public void getAllSpeciesBatch(/*String fishingOperationId*/) { - - } - - @Test - @Ignore public void getAllRootSpeciesBatch(/*String fishingOperationId*/) { } @@ -362,12 +407,18 @@ // Create batch SpeciesBatch createdBatch = service.createSpeciesBatch(batch, parentBatchId); - assertSpeciesBatch(createdBatch, batch, false); + assertSpeciesBatch(batch, createdBatch, false); // then reload (for round trip check) - SpeciesBatch reloadedBatch = service.getSpeciesBatch(createdBatch.getId()); - assertNull(reloadedBatch.getParentBatch()); - assertSpeciesBatch(reloadedBatch, batch, false); + SpeciesBatch reloadedBatch = getSpeciesBatch(fishingOperation.getId(), createdBatch.getId()); + if (parentBatchId == null) { + assertNull(reloadedBatch.getParentBatch()); + } + else { + assertNotNull(reloadedBatch.getParentBatch()); + assertEquals(parentBatchId, reloadedBatch.getParentBatch().getId()); + } + assertSpeciesBatch(createdBatch, reloadedBatch, false); batch.setId(createdBatch.getId()); } @@ -380,14 +431,100 @@ } assertEquals(expectedBatch.getWeight(), actualBatch.getWeight()); assertEquals(expectedBatch.getSampleCategoryType(), actualBatch.getSampleCategoryType()); - assertEquals(expectedBatch.getSampleCategoryValue(), actualBatch.getSampleCategoryValue()); + if (expectedBatch.getSampleCategoryValue() != null && expectedBatch.getSampleCategoryValue() instanceof CaracteristicQualitativeValue) { + assertNotNull("Bad sampleCategoryValue : expected <" + ((CaracteristicQualitativeValue)expectedBatch.getSampleCategoryValue()).getId() +"> but was <null>", + actualBatch.getSampleCategoryValue()); + assertEquals( + ((CaracteristicQualitativeValue)expectedBatch.getSampleCategoryValue()).getId(), + ((CaracteristicQualitativeValue)actualBatch.getSampleCategoryValue()).getId()); + } + else { + assertEquals(expectedBatch.getSampleCategoryValue(), actualBatch.getSampleCategoryValue()); + } assertEquals(expectedBatch.getSampleCategoryWeight(), actualBatch.getSampleCategoryWeight()); assertEquals(expectedBatch.getNumber(), actualBatch.getNumber()); assertEquals(expectedBatch.getComment(), actualBatch.getComment()); - if (expectedBatch.getSpecies() != null) { + + // Check species only if Vrac/HorsVrac or if batch has been load throw getAllxxx method + // (Because getSpeciesBatch(id) could not always retrieve the species) + if (expectedBatch.getSpecies() != null && ( + expectedBatch.getSampleCategoryType() == SampleCategoryEnum.sortedUnsorted + || actualBatch.getSpecies() != null)) { assertNotNull(actualBatch.getSpecies()); assertEquals(expectedBatch.getSpecies().getId(), actualBatch.getSpecies().getId()); } } + + protected List<SpeciesBatchFrequency> assertCreateAndReloadSpeciesBatchFrequency(List<SpeciesBatchFrequency> frequencies, String parentBatchId) { + // Create batch + List<SpeciesBatchFrequency> createdFrequencies = service.saveSpeciesBatchFrequency(parentBatchId, frequencies); + assertBatchFrequencies(frequencies, createdFrequencies, false); + + // then reload (for round trip check) + List<SpeciesBatchFrequency> reloadedFrequencies = service.getAllSpeciesBatchFrequency(parentBatchId); + assertBatchFrequencies(createdFrequencies, reloadedFrequencies, true); + + return createdFrequencies; + } + + protected void assertBatchFrequencies(List<SpeciesBatchFrequency> expectedFrequencies, List<SpeciesBatchFrequency> actualFrequencies, boolean assertIdEquals) { + assertNotNull(actualFrequencies); + assertEquals(expectedFrequencies.size(), actualFrequencies.size()); + + // Store actual batches into a map, using the length as key + Map<Float, SpeciesBatchFrequency> expectedLengthMap = Maps.newHashMap(); + for (Iterator iterator = expectedFrequencies.iterator(); iterator.hasNext();) { + SpeciesBatchFrequency speciesBatchFrequency = (SpeciesBatchFrequency) iterator.next(); + expectedLengthMap.put(speciesBatchFrequency.getLengthStep(), speciesBatchFrequency); + } + + // Store expected batches into a map, using the length as key + Map<Float, SpeciesBatchFrequency> actualLengthMap = Maps.newHashMap(); + for (Iterator iterator = actualFrequencies.iterator(); iterator.hasNext();) { + SpeciesBatchFrequency speciesBatchFrequency = (SpeciesBatchFrequency) iterator.next(); + assertFalse("Duplicate lengthStep found in batchFrequencies, for length="+speciesBatchFrequency.getLengthStep(), actualLengthMap.containsKey(speciesBatchFrequency.getLengthStep())); + actualLengthMap.put(speciesBatchFrequency.getLengthStep(), speciesBatchFrequency); + assertNotNull(speciesBatchFrequency.getId()); + } + + for (Iterator iterator = expectedLengthMap.keySet().iterator(); iterator.hasNext();) { + Float lengthStep = (Float) iterator.next(); + SpeciesBatchFrequency expectedBatchFrequency = expectedLengthMap.get(lengthStep); + SpeciesBatchFrequency actualBatchFrequency = actualLengthMap.get(lengthStep); + if (assertIdEquals) { + assertEquals(expectedBatchFrequency.getId(), actualBatchFrequency.getId()); + } + assertNotNull(expectedBatchFrequency.getLengthStepCaracteristic()); + assertEquals(expectedBatchFrequency.getLengthStepCaracteristic().getId(), actualBatchFrequency.getLengthStepCaracteristic().getId()); + assertEquals(expectedBatchFrequency.getNumber(), actualBatchFrequency.getNumber()); + assertEquals(expectedBatchFrequency.getWeight(), actualBatchFrequency.getWeight()); + assertEquals(expectedBatchFrequency.getComment(), actualBatchFrequency.getComment()); + //assertNotNull(expectedBatchFrequency.getBatch()); + //assertEquals(expectedBatchFrequency.getBatch().getId(), actualBatchFrequency.getBatch().getId()); + } + } + + protected SpeciesBatch getSpeciesBatch(String fishingOperationId, String speciesBatchId) { + return getSpeciesBatch(speciesBatchId, service.getAllRootSpeciesBatch(fishingOperationId)); + } + + protected SpeciesBatch getSpeciesBatch(String speciesBatchId, List<SpeciesBatch> speciesBatchs) { + if (speciesBatchs == null) { + return null; + } + for (Iterator iterator = speciesBatchs.iterator(); iterator.hasNext();) { + SpeciesBatch speciesBatch = (SpeciesBatch) iterator.next(); + if (speciesBatchId.equals(speciesBatch.getId())) { + return speciesBatch; + } + if (speciesBatch.getChildBatchs() != null) { + speciesBatch = getSpeciesBatch(speciesBatchId, speciesBatch.getChildBatchs()); + if (speciesBatch != null) { + return speciesBatch; + } + } + } + return null; + } }