diff --git a/pom.xml b/pom.xml
index a58a4b38ac..f2d549f6fc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
net.sumaris
sumaris-pod
- 2.1.0
+ 2.1.1
pom
SUMARiS
SUMARiS :: Maven parent
@@ -51,6 +51,7 @@
sumaris-core-shared
sumaris-test-shared
+ sumaris-xml-query
sumaris-core
sumaris-importation
sumaris-extraction
@@ -120,7 +121,7 @@
3.3.0
3.8.1
1.18.24
- 1.8
+ 3.2
2.0.6
1.2.0
5.3.24
@@ -1182,6 +1183,7 @@
${project.build.sourceEncoding}
--enable-preview
+
@@ -1189,6 +1191,11 @@
lombok
${lombok.version}
+
diff --git a/src/scripts/release.sh b/src/scripts/release.sh
index 30dec9850f..a8c53f402d 100755
--- a/src/scripts/release.sh
+++ b/src/scripts/release.sh
@@ -51,7 +51,7 @@ echo "---- Prepare release [OK]"
echo ""
echo "---- Performing release..."
-mvn clean deploy -DperformRelease -DskipTests -Dspring.datasource.platform=hsqldb
+mvn clean deploy -DperformRelease -DskipTests -Dspring.sql.init.platform=hsqldb
[[ $? -ne 0 ]] && exit 1
echo "---- Perform release [OK]"
echo ""
diff --git a/sumaris-core-shared/pom.xml b/sumaris-core-shared/pom.xml
index 60f98dba4f..465a7a127e 100644
--- a/sumaris-core-shared/pom.xml
+++ b/sumaris-core-shared/pom.xml
@@ -4,7 +4,7 @@
net.sumaris
sumaris-pod
- 2.1.0
+ 2.1.1
sumaris-core-shared
diff --git a/sumaris-core-shared/src/main/java/net/sumaris/core/config/ApplicationConfigAliasProvider.java b/sumaris-core-shared/src/main/java/net/sumaris/core/config/ApplicationConfigAliasProvider.java
new file mode 100644
index 0000000000..653895bc3d
--- /dev/null
+++ b/sumaris-core-shared/src/main/java/net/sumaris/core/config/ApplicationConfigAliasProvider.java
@@ -0,0 +1,30 @@
+/*
+ * #%L
+ * SUMARiS
+ * %%
+ * Copyright (C) 2019 SUMARiS Consortium
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * .
+ * #L%
+ */
+
+package net.sumaris.core.config;
+
+import org.nuiton.config.ApplicationConfig;
+
+public interface ApplicationConfigAliasProvider {
+
+ void addAlias(ApplicationConfig applicationConfig);
+}
diff --git a/sumaris-core-shared/src/main/java/net/sumaris/core/config/SumarisConfiguration.java b/sumaris-core-shared/src/main/java/net/sumaris/core/config/SumarisConfiguration.java
index 90e15a9772..7c86c4cd19 100644
--- a/sumaris-core-shared/src/main/java/net/sumaris/core/config/SumarisConfiguration.java
+++ b/sumaris-core-shared/src/main/java/net/sumaris/core/config/SumarisConfiguration.java
@@ -184,6 +184,11 @@ protected SumarisConfiguration(ConfigurableEnvironment env,
// Define Alias
addAlias(applicationConfig);
+ for (ApplicationConfigProvider provider : providers) {
+ if (provider instanceof ApplicationConfigAliasProvider) {
+ ((ApplicationConfigAliasProvider)provider).addAlias(applicationConfig);
+ }
+ }
// parse config file and inline arguments
try {
diff --git a/sumaris-core-shared/src/main/java/net/sumaris/core/config/SumarisConfigurationOption.java b/sumaris-core-shared/src/main/java/net/sumaris/core/config/SumarisConfigurationOption.java
index 58b94e9418..b0a841e3c5 100644
--- a/sumaris-core-shared/src/main/java/net/sumaris/core/config/SumarisConfigurationOption.java
+++ b/sumaris-core-shared/src/main/java/net/sumaris/core/config/SumarisConfigurationOption.java
@@ -142,7 +142,7 @@ public enum SumarisConfigurationOption implements ConfigOptionDef {
DB_CREATE_SCRIPT_PATH(
"sumaris.persistence.db.script",
n("sumaris.config.option.db.script.description"),
- "classpath:net/sumaris/core/db/changelog/${spring.datasource.platform}/sumaris.script",
+ "classpath:net/sumaris/core/db/changelog/${spring.sql.init.platform}/sumaris.script",
String.class,
false),
diff --git a/sumaris-core-shared/src/main/java/net/sumaris/core/jms/JmsConfiguration.java b/sumaris-core-shared/src/main/java/net/sumaris/core/jms/JmsConfiguration.java
index 7521bcc1ad..7183c45049 100644
--- a/sumaris-core-shared/src/main/java/net/sumaris/core/jms/JmsConfiguration.java
+++ b/sumaris-core-shared/src/main/java/net/sumaris/core/jms/JmsConfiguration.java
@@ -73,6 +73,7 @@ public JmsListenerContainerFactory> jmsListenerContainerFactory(
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(jmsConnectionFactory);
factory.setMessageConverter(messageConverter);
+ factory.setPubSubDomain(true); // Use Topic instead of Queue
jmsListenerContainerFactoryConfigurer
.ifPresent(c -> c.configure(factory, jmsConnectionFactory));
diff --git a/sumaris-core-shared/src/main/java/net/sumaris/core/util/Dates.java b/sumaris-core-shared/src/main/java/net/sumaris/core/util/Dates.java
index 472866218c..9745508f85 100644
--- a/sumaris-core-shared/src/main/java/net/sumaris/core/util/Dates.java
+++ b/sumaris-core-shared/src/main/java/net/sumaris/core/util/Dates.java
@@ -50,6 +50,8 @@ public class Dates extends org.apache.commons.lang3.time.DateUtils{
public static String ISO_TIMESTAMP_SPEC = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
+ public static String CSV_DATE_TIME = "yyyy-MM-dd HH:mm:ss";
+
/**
* Remove a amount of month to a date
*
diff --git a/sumaris-core-shared/src/main/java/net/sumaris/core/util/sound/SoundUtils.java b/sumaris-core-shared/src/main/java/net/sumaris/core/util/sound/SoundUtils.java
index b658f615ea..4fa27d4419 100644
--- a/sumaris-core-shared/src/main/java/net/sumaris/core/util/sound/SoundUtils.java
+++ b/sumaris-core-shared/src/main/java/net/sumaris/core/util/sound/SoundUtils.java
@@ -101,6 +101,20 @@ public static void playWaiting(int count) {
}
}
+ public static void playFinished() {
+ try {
+ SoundUtils.tone(800, 100);
+ Thread.sleep(200);
+ SoundUtils.tone(800, 700, 0.7);
+ Thread.sleep(350);
+ SoundUtils.tone(800, 1000);
+ Thread.sleep(3000);
+ }
+ catch (Exception e) {
+ log.debug("Cannot play error sound: " + e.getMessage());
+ }
+ }
+
private void playSound(File f) {
Preconditions.checkArgument(f.exists());
diff --git a/sumaris-core/pom.xml b/sumaris-core/pom.xml
index c9741dbba5..e5cf6a1187 100644
--- a/sumaris-core/pom.xml
+++ b/sumaris-core/pom.xml
@@ -4,7 +4,7 @@
net.sumaris
sumaris-pod
- 2.1.0
+ 2.1.1
sumaris-core
@@ -34,7 +34,7 @@
AllTests
- hsqldb
+ hsqldb
@@ -377,7 +377,7 @@
true
- spring.datasource.platform
+ spring.sql.init.platform
hsqldb
@@ -391,7 +391,7 @@
org.hsqldb.jdbc.JDBCDriver
PUBLIC
- hsqldb
+ hsqldb
net.sumaris.core.dao.technical.hibernate.spatial.dialect.HSQLSpatialDialect
15
@@ -408,7 +408,7 @@
oracle
- spring.datasource.platform
+ spring.sql.init.platform
oracle
@@ -420,7 +420,7 @@
SUMARIS_TU
SUMARIS_TU
oracle.jdbc.driver.OracleDriver
- oracle
+ oracle
net.sumaris.core.dao.technical.hibernate.spatial.dialect.OracleSpatial10gDialect
15
@@ -437,7 +437,7 @@
pgsql
- spring.datasource.platform
+ spring.sql.init.platform
pgsql
@@ -449,7 +449,7 @@
sumaris
public
org.postgresql.Driver
- pgsql
+ pgsql
net.sumaris.core.dao.technical.hibernate.spatial.dialect.PostgreSQL10Dialect
15
diff --git a/sumaris-core/src/main/filtered-resources/application-hsqldb.properties b/sumaris-core/src/main/filtered-resources/application-hsqldb.properties
index 178e0fd632..5ed6e5793b 100644
--- a/sumaris-core/src/main/filtered-resources/application-hsqldb.properties
+++ b/sumaris-core/src/main/filtered-resources/application-hsqldb.properties
@@ -3,7 +3,7 @@ spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.url=@jdbc.url@
-spring.datasource.platform=@env@
+spring.sql.init.platform=@env@
spring.datasource.hikari.connectionTestQuery=SELECT 1 FROM STATUS WHERE ID=1
spring.datasource.hikari.initializationFailTimeout=-1
diff --git a/sumaris-core/src/main/filtered-resources/application-oracle.properties b/sumaris-core/src/main/filtered-resources/application-oracle.properties
index 974e890b66..0385b49a2f 100644
--- a/sumaris-core/src/main/filtered-resources/application-oracle.properties
+++ b/sumaris-core/src/main/filtered-resources/application-oracle.properties
@@ -6,7 +6,7 @@ spring.jpa.database-platform=net.sumaris.core.dao.technical.hibernate.spatial.di
spring.jpa.properties.hibernate.dialect=${spring.jpa.database-platform}
# Database connection
-spring.datasource.platform=oracle
+spring.sql.init.platform=oracle
spring.datasource.username=
spring.datasource.password=
spring.jpa.properties.hibernate.default_catalog=
diff --git a/sumaris-core/src/main/filtered-resources/application-pgsql.properties b/sumaris-core/src/main/filtered-resources/application-pgsql.properties
index d90afc8fce..f34f2fe0d9 100644
--- a/sumaris-core/src/main/filtered-resources/application-pgsql.properties
+++ b/sumaris-core/src/main/filtered-resources/application-pgsql.properties
@@ -6,7 +6,7 @@ spring.jpa.database-platform=net.sumaris.core.dao.technical.hibernate.spatial.di
spring.jpa.properties.hibernate.dialect=${spring.jpa.database-platform}
# Database connection
-spring.datasource.platform=pgsql
+spring.sql.init.platform=pgsql
spring.datasource.username=sumaris
spring.datasource.password=sumaris
spring.jpa.properties.hibernate.default_catalog=sumaristest
diff --git a/sumaris-core/src/main/filtered-resources/application.properties b/sumaris-core/src/main/filtered-resources/application.properties
index bb00118c33..81b0829a28 100644
--- a/sumaris-core/src/main/filtered-resources/application.properties
+++ b/sumaris-core/src/main/filtered-resources/application.properties
@@ -19,7 +19,7 @@ spring.datasource.driver-class-name=@jdbc.driver@
spring.datasource.username=@jdbc.username@
spring.datasource.password=@jdbc.password@
spring.datasource.url=@jdbc.url@
-spring.datasource.platform=@env@
+spring.sql.init.platform=@env@
spring.datasource.hikari.connectionTestQuery=SELECT 1 FROM STATUS WHERE ID=1
spring.datasource.hikari.initializationFailTimeout=-1
diff --git a/sumaris-core/src/main/java/net/sumaris/cli/action/data/DenormalizeTripsAction.java b/sumaris-core/src/main/java/net/sumaris/cli/action/data/DenormalizeTripsAction.java
index ed9b67f9cd..15bd4204ef 100644
--- a/sumaris-core/src/main/java/net/sumaris/cli/action/data/DenormalizeTripsAction.java
+++ b/sumaris-core/src/main/java/net/sumaris/cli/action/data/DenormalizeTripsAction.java
@@ -60,6 +60,6 @@ public void run() {
tripService.denormalizeByFilter(filterBuilder.build(), progression);
// Play a beep
- SoundUtils.playWaiting(2);
+ SoundUtils.playFinished();
}
}
diff --git a/sumaris-core/src/main/java/net/sumaris/core/dao/technical/JobSpecifications.java b/sumaris-core/src/main/java/net/sumaris/core/dao/technical/JobSpecifications.java
index 078c465ea3..a304679c2a 100644
--- a/sumaris-core/src/main/java/net/sumaris/core/dao/technical/JobSpecifications.java
+++ b/sumaris-core/src/main/java/net/sumaris/core/dao/technical/JobSpecifications.java
@@ -76,16 +76,17 @@ default Specification hasStatus(String... status) {
}
default Specification hasJobStatus(JobStatusEnum... jobStatus) {
- Integer[] statusIds = Arrays.stream(jobStatus)
+ if (ArrayUtils.isEmpty(jobStatus)) return null;
+ List statusIds = Arrays.stream(jobStatus)
.map(JobStatusEnum::getProcessingStatus)
.filter(Objects::nonNull)
.map(ProcessingStatusEnum::getId)
.filter(id -> id != null && id >= 0)
- .toArray(Integer[]::new);
- if (ArrayUtils.isEmpty(statusIds)) return null;
+ .toList();
+ if (CollectionUtils.isEmpty(statusIds)) return null;
return hasInnerJoinIds(
ProcessingHistory.Fields.PROCESSING_STATUS,
- statusIds);
+ statusIds.toArray(new Integer[0]));
}
List findAll(JobFilterVO filter);
diff --git a/sumaris-core/src/main/java/net/sumaris/core/dao/technical/schema/SumarisDatabaseMetadata.java b/sumaris-core/src/main/java/net/sumaris/core/dao/technical/schema/SumarisDatabaseMetadata.java
index 94835a8e25..1d581e65cf 100644
--- a/sumaris-core/src/main/java/net/sumaris/core/dao/technical/schema/SumarisDatabaseMetadata.java
+++ b/sumaris-core/src/main/java/net/sumaris/core/dao/technical/schema/SumarisDatabaseMetadata.java
@@ -198,9 +198,9 @@ public Set findTableNamesByPrefix(String tablePrefix, String schema, Str
if (tableName.toUpperCase().startsWith(tablePrefix.toUpperCase())) {
result.add(rs.getString("TABLE_NAME"));
}
- // JDBC meta return a bad tableName: should never occur !!
+ // JDBC meta return a bad tableName (e.g. because '_' special character) => ignore
else {
- log.warn("Invalid getTables() result: Table name '{}' should not be returned, because its not match the pattern '{}'. Please check like pattern, or Daos.getEscapedForLike() function", tableName, tablePrefix);
+ log.trace("Ignoring getTables() result, because table name '{}' not start with '{}'", tableName, tablePrefix);
}
}
return result;
diff --git a/sumaris-core/src/main/java/net/sumaris/core/model/data/PhysicalGear.java b/sumaris-core/src/main/java/net/sumaris/core/model/data/PhysicalGear.java
index 311e86a419..30bd713c09 100644
--- a/sumaris-core/src/main/java/net/sumaris/core/model/data/PhysicalGear.java
+++ b/sumaris-core/src/main/java/net/sumaris/core/model/data/PhysicalGear.java
@@ -59,7 +59,6 @@ public class PhysicalGear implements IRootDataEntity,
@ManyToOne(fetch = FetchType.LAZY, targetEntity = Gear.class)
@JoinColumn(name = "gear_fk", nullable = false)
-
private Gear gear;
@Column(length = LENGTH_COMMENTS)
diff --git a/sumaris-core/src/main/java/net/sumaris/core/model/referential/pmfm/PmfmEnum.java b/sumaris-core/src/main/java/net/sumaris/core/model/referential/pmfm/PmfmEnum.java
index 2c93a7c187..42d548d38c 100644
--- a/sumaris-core/src/main/java/net/sumaris/core/model/referential/pmfm/PmfmEnum.java
+++ b/sumaris-core/src/main/java/net/sumaris/core/model/referential/pmfm/PmfmEnum.java
@@ -77,6 +77,10 @@ public enum PmfmEnum implements IEntityEnum, Serializable {
BATCH_CALCULATED_WEIGHT_LENGTH(122, "BATCH_CALCULATED_WEIGHT_LENGTH"),
BATCH_CALCULATED_WEIGHT_LENGTH_SUM(123, "BATCH_CALCULATED_WEIGHT_LENGTH_SUM"),
BATCH_SORTING(176, "BATCH_SORTING"), // Adagio = 'SORTED' (id=200)
+ CHILD_GEAR(400, "CHILD_GEAR"),
+ CATCH_WEIGHT(57, "CATCH_WEIGHT"),
+ DISCARD_WEIGHT(56, "DISCARD_WEIGHT"),
+ BATCH_GEAR_POSITION(411, "BATCH_GEAR_POSITION"),
IS_DEAD(94, "IS_DEAD"),
DISCARD_REASON(95, "DISCARD_REASON"),
@@ -92,10 +96,11 @@ public enum PmfmEnum implements IEntityEnum, Serializable {
CONTROL_TYPE(130, "CONTROL_TYPE"),
+ SIZE_UNLI_CAT(141, "SIZE_UNLI_CAT"),
PRESERVATION(150, "PRESERVATION"),
DRESSING(151, "DRESSING"),
SIZE_CATEGORY(174, "SIZE_CATEGORY"),
-
+ TRAWL_SIZE_CAT(418, "TRAWL_SIZE_CAT"),
PACKAGING(177, "PACKAGING"),
TOTAL_PRICE(270, "TOTAL_PRICE"),
diff --git a/sumaris-core/src/main/java/net/sumaris/core/model/technical/extraction/rdb/ProductRdbSpeciesList.java b/sumaris-core/src/main/java/net/sumaris/core/model/technical/extraction/rdb/ProductRdbSpeciesList.java
index fdeb39aa8a..b4ceb791f9 100644
--- a/sumaris-core/src/main/java/net/sumaris/core/model/technical/extraction/rdb/ProductRdbSpeciesList.java
+++ b/sumaris-core/src/main/java/net/sumaris/core/model/technical/extraction/rdb/ProductRdbSpeciesList.java
@@ -61,7 +61,7 @@ public class ProductRdbSpeciesList implements Serializable, IEntity {
public static final String COLUMN_COMMERCIAL_SIZE_CATEGORY = "commercial_size_category";
public static final String COLUMN_SUBSAMPLING_CATEGORY = "subsampling_category";
public static final String COLUMN_WEIGHT= "weight";
- public static final String COLUMN_SUBSAMPLING_WEIGHT = "subsampling_weight";
+ public static final String COLUMN_SUBSAMPLE_WEIGHT = "subsample_weight";
public static final String COLUMN_LENGTH_CODE = "length_code";
@Id
@@ -119,8 +119,8 @@ public class ProductRdbSpeciesList implements Serializable, IEntity {
@Column(nullable = false, scale = 12, precision = 2, name = COLUMN_WEIGHT)
private Double weight;
- @Column( scale = 12, precision = 2, name = COLUMN_SUBSAMPLING_WEIGHT)
- private Double subsamplingWeight;
+ @Column( scale = 12, precision = 2, name = COLUMN_SUBSAMPLE_WEIGHT)
+ private Double subsampleWeight;
@Column(length = 5, name = COLUMN_LENGTH_CODE)
private String lengthCode;
diff --git a/sumaris-core/src/main/java/net/sumaris/core/service/data/denormalize/DenormalizeOperationServiceImpl.java b/sumaris-core/src/main/java/net/sumaris/core/service/data/denormalize/DenormalizeOperationServiceImpl.java
index c46c797070..f3b74431b2 100644
--- a/sumaris-core/src/main/java/net/sumaris/core/service/data/denormalize/DenormalizeOperationServiceImpl.java
+++ b/sumaris-core/src/main/java/net/sumaris/core/service/data/denormalize/DenormalizeOperationServiceImpl.java
@@ -105,6 +105,9 @@ public DenormalizedTripResultVO denormalizeByFilter(@NonNull OperationFilterVO o
// Select only operation that should be update (if not force)
operationFilter.setNeedBatchDenormalization(!baseOptions.isForce());
+ // DEBUG - force denormalization
+ //if (!this.production && !baseOptions.isForce()) operationFilter.setNeedBatchDenormalization(false);
+
long operationTotal = operationService.countByFilter(operationFilter);
boolean hasMoreData;
diff --git a/sumaris-core/src/main/java/net/sumaris/core/service/data/denormalize/DenormalizedBatchServiceImpl.java b/sumaris-core/src/main/java/net/sumaris/core/service/data/denormalize/DenormalizedBatchServiceImpl.java
index 90ac8d729a..7ce6d97177 100644
--- a/sumaris-core/src/main/java/net/sumaris/core/service/data/denormalize/DenormalizedBatchServiceImpl.java
+++ b/sumaris-core/src/main/java/net/sumaris/core/service/data/denormalize/DenormalizedBatchServiceImpl.java
@@ -149,7 +149,7 @@ public List denormalize(@NonNull BatchVO catchBatch, @NonNu
// Check options
Preconditions.checkNotNull(options.getDateTime(), "Required options.dateTime when RTP weight enabled");
- Preconditions.checkNotNull(options.getRoundWeightCountryLocationId(), "Required options.roundWeightCountryLocationId when RTP weight enabled");
+ Preconditions.checkNotNull(options.getAliveWeightCountryLocationId(), "Required options.roundWeightCountryLocationId when RTP weight enabled");
Preconditions.checkNotNull(options.getDefaultLandingDressingId(), "Required options.defaultLandingDressingId when RTP weight enabled");
Preconditions.checkNotNull(options.getDefaultDiscardDressingId(), "Required options.defaultDiscardDressingId when RTP weight enabled");
Preconditions.checkNotNull(options.getDefaultLandingPreservationId(), "Required options.defaultLandingPreservationId when RTP weight enabled");
@@ -163,104 +163,19 @@ public List denormalize(@NonNull BatchVO catchBatch, @NonNu
List result = TreeNodeEntities.streamAllAndMap(catchBatch, (source, p) -> {
TempDenormalizedBatchVO target = createTempVO(source);
TempDenormalizedBatchVO parent = p != null ? (TempDenormalizedBatchVO)p : null;
- boolean isLeaf = source.isLeaf(); // Do not use 'target', because children are added later
+ boolean isLeaf = parent != null && source.isLeaf(); // Do not use 'target', because children are added later
// Add to parent's children
if (parent != null) parent.addChildren(target);
- // Depth level
- if (parent == null) {
- target.setTreeLevel((short) 1); // First level
- if (target.getIsLanding() == null) target.setIsLanding(false);
- if (target.getIsDiscard() == null) target.setIsDiscard(false);
- } else {
- target.setTreeLevel((short) (parent.getTreeLevel() + 1));
- // Inherit taxon group
- if (target.getInheritedTaxonGroup() == null && parent.getInheritedTaxonGroup() != null) {
- target.setInheritedTaxonGroup(parent.getInheritedTaxonGroup());
- }
- // Inherit taxon name
- if (target.getInheritedTaxonName() == null && parent.getInheritedTaxonName() != null) {
- target.setInheritedTaxonName(parent.getInheritedTaxonName());
- }
- // Exhaustive inventory
- if (target.getExhaustiveInventory() == null) {
- // Always true, when:
- // - taxon name is defined
- // - taxon group is defined and taxon Name disable (in options)
- if (target.getInheritedTaxonName() != null) {
- target.setExhaustiveInventory(Boolean.TRUE);
- } else if (target.getInheritedTaxonGroup() != null && !options.isEnableTaxonName()) {
- target.setExhaustiveInventory(Boolean.TRUE);
- } else if (parent.getExhaustiveInventory() != null) {
- target.setExhaustiveInventory(parent.getExhaustiveInventory());
- }
- }
- // Inherit location
- if (parent.getLocationId() != null) {
- target.setLocationId(parent.getLocationId());
- }
- // Inherit landing / discard
- if (target.getIsLanding() == null) {
- target.setIsLanding(parent.getIsLanding());
- }
- if (target.getIsDiscard() == null) {
- target.setIsDiscard(parent.getIsDiscard());
- }
-
- // Inherit quality flag
- if (parent.getQualityFlagId() != null) {
- if (target.getQualityFlagId() == null) {
- target.setQualityFlagId(parent.getQualityFlagId());
- }
- // Keep the worst value, if current has a value
- else {
- target.setQualityFlagId(QualityFlags.worst(parent.getQualityFlagId(), target.getQualityFlagId()));
- }
- }
-
- // If current quality is invalid
- if (QualityFlags.isInvalid(target.getQualityFlagId())) {
- // Force both parent and current parent exhaustive inventory to FALSE
- // NOTE Allegro:
- // mantis Allegro #12951 - remontée des poids selon le niveau de qualité
- // Si un des lots fils (direct ou indirect) est invalide
- // (c'est à dire si le code du niveau de qualité appartient à la liste des niveaux invalides)
- // alors il faut considérer que l'inventaire exhaustif est non.
- // Le but est de stopper la remontée des poids calculés
- // s'il y a au moins un lot invalide parmi les fils, isExhaustive = false
- parent.setExhaustiveInventory(Boolean.FALSE);
- target.setExhaustiveInventory(Boolean.FALSE);
- }
-
- // Inherit sorting values
- Beans.getStream(parent.getSortingValues())
- .forEach(svSource -> {
- // Make sure sorting value not already exists
- Beans.getStream(target.getSortingValues())
- .filter(svTarget -> Objects.equals(svTarget.getPmfmId(), svSource.getPmfmId()))
- .findFirst()
- .ifPresentOrElse(svTarget -> {
- Beans.copyProperties(svSource, svTarget, IEntity.Fields.ID);
- svTarget.setIsInherited(true);
- svTarget.setRankOrder(svSource.getRankOrder() / 10);
- },
- () -> {
- DenormalizedBatchSortingValueVO svTarget = new DenormalizedBatchSortingValueVO();
- Beans.copyProperties(svSource, svTarget, IEntity.Fields.ID);
- svTarget.setIsInherited(true);
- svTarget.setRankOrder(svSource.getRankOrder() / 10);
- target.addSortingValue(svTarget);
- });
- });
-
- // Compute Alive weight, on leaf batch
- // (to be able to compute indirect alive weight later)
- if (isLeaf) {
- computeAliveWeightFactor(target, options, true)
- .ifPresent(target::setAliveWeightFactor);
- }
+ // Copy parent's values
+ computeInheritedValues(target, parent, options);
+ // Compute Alive weight, on leaf batch
+ // (to be able to compute indirect alive weight later)
+ if (isLeaf) {
+ computeAliveWeightFactor(target, options, true)
+ .ifPresent(target::setAliveWeightFactor);
}
return target;
@@ -427,10 +342,102 @@ protected DenormalizedBatchOptions createOptionsByProgram(@NonNull ProgramVO pro
.enableTaxonName(Programs.getPropertyAsBoolean(program, ProgramPropertyEnum.TRIP_BATCH_TAXON_NAME_ENABLE))
.enableTaxonGroup(Programs.getPropertyAsBoolean(program, ProgramPropertyEnum.TRIP_BATCH_TAXON_GROUP_ENABLE))
.enableRtpWeight(canEnableRtpWeight && Programs.getPropertyAsBoolean(program, ProgramPropertyEnum.TRIP_BATCH_LENGTH_WEIGHT_CONVERSION_ENABLE))
- .roundWeightCountryLocationId(roundWeightConversionCountryId)
+ .aliveWeightCountryLocationId(roundWeightConversionCountryId)
.build();
}
+ protected void computeInheritedValues(TempDenormalizedBatchVO target,
+ TempDenormalizedBatchVO parent,
+ DenormalizedBatchOptions options) {
+ // Special case for catch batch
+ if (parent == null) {
+ target.setTreeLevel((short) 1); // First level
+ if (target.getIsLanding() == null) target.setIsLanding(false);
+ if (target.getIsDiscard() == null) target.setIsDiscard(false);
+ return;
+ }
+
+ target.setTreeLevel((short) (parent.getTreeLevel() + 1));
+ // Inherit taxon group
+ if (target.getInheritedTaxonGroup() == null && parent.getInheritedTaxonGroup() != null) {
+ target.setInheritedTaxonGroup(parent.getInheritedTaxonGroup());
+ }
+ // Inherit taxon name
+ if (target.getInheritedTaxonName() == null && parent.getInheritedTaxonName() != null) {
+ target.setInheritedTaxonName(parent.getInheritedTaxonName());
+ }
+ // Exhaustive inventory
+ if (target.getExhaustiveInventory() == null) {
+ // Always true, when:
+ // - taxon name is defined
+ // - taxon group is defined and taxon Name disable (in options)
+ if (target.getInheritedTaxonName() != null) {
+ target.setExhaustiveInventory(Boolean.TRUE);
+ } else if (target.getInheritedTaxonGroup() != null && !options.isEnableTaxonName()) {
+ target.setExhaustiveInventory(Boolean.TRUE);
+ } else if (parent.getExhaustiveInventory() != null) {
+ target.setExhaustiveInventory(parent.getExhaustiveInventory());
+ }
+ }
+ // Inherit location
+ if (parent.getLocationId() != null) {
+ target.setLocationId(parent.getLocationId());
+ }
+ // Inherit landing / discard
+ if (target.getIsLanding() == null) {
+ target.setIsLanding(parent.getIsLanding());
+ }
+ if (target.getIsDiscard() == null) {
+ target.setIsDiscard(parent.getIsDiscard());
+ }
+
+ // Inherit quality flag
+ if (parent.getQualityFlagId() != null) {
+ if (target.getQualityFlagId() == null) {
+ target.setQualityFlagId(parent.getQualityFlagId());
+ }
+ // Keep the worst value, if current has a value
+ else {
+ target.setQualityFlagId(QualityFlags.worst(parent.getQualityFlagId(), target.getQualityFlagId()));
+ }
+ }
+
+ // If current quality is invalid
+ if (QualityFlags.isInvalid(target.getQualityFlagId())) {
+ // Force both parent and current parent exhaustive inventory to FALSE
+ // NOTE Allegro:
+ // mantis Allegro #12951 - remontée des poids selon le niveau de qualité
+ // Si un des lots fils (direct ou indirect) est invalide
+ // (c'est à dire si le code du niveau de qualité appartient à la liste des niveaux invalides)
+ // alors il faut considérer que l'inventaire exhaustif est non.
+ // Le but est de stopper la remontée des poids calculés
+ // s'il y a au moins un lot invalide parmi les fils, isExhaustive = false
+ parent.setExhaustiveInventory(Boolean.FALSE);
+ target.setExhaustiveInventory(Boolean.FALSE);
+ }
+
+ // Inherit sorting values
+ Beans.getStream(parent.getSortingValues())
+ .forEach(svSource -> {
+ // Make sure sorting value not already exists
+ Beans.getStream(target.getSortingValues())
+ .filter(svTarget -> Objects.equals(svTarget.getPmfmId(), svSource.getPmfmId()))
+ .findFirst()
+ .ifPresentOrElse(svTarget -> {
+ Beans.copyProperties(svSource, svTarget, IEntity.Fields.ID);
+ svTarget.setIsInherited(true);
+ svTarget.setRankOrder(svSource.getRankOrder() / 10);
+ },
+ () -> {
+ DenormalizedBatchSortingValueVO svTarget = new DenormalizedBatchSortingValueVO();
+ Beans.copyProperties(svSource, svTarget, IEntity.Fields.ID);
+ svTarget.setIsInherited(true);
+ svTarget.setRankOrder(svSource.getRankOrder() / 10);
+ target.addSortingValue(svTarget);
+ });
+ });
+ }
+
protected void computeRtpWeights(List batches, DenormalizedBatchOptions options) {
// Select leafs
List leafBatches = batches.stream()
@@ -492,6 +499,7 @@ protected void computeIndirectValues(List batches, Denormal
MutableInt changesCount = new MutableInt(0);
MutableInt loopCounter = new MutableInt(0);
+ int maxLoop = 1; // TODO check this
do {
changesCount.setValue(0);
loopCounter.increment();
@@ -521,15 +529,19 @@ protected void computeIndirectValues(List batches, Denormal
batch.setIndirectIndividualCountDecimal(indirectIndividualCount);
// Compute alive weight factor
- if (batch.isLeaf()) {
- Double aliveWeightFactor = computeAliveWeightFactor(batch, options, batch.isLeaf()).orElse(null);
- changed = changed || !Objects.equals(aliveWeightFactor, batch.getAliveWeightFactor());
- batch.setAliveWeightFactor(aliveWeightFactor);
+ if (options.isEnableAliveWeight() && options.getAliveWeightCountryLocationId() != null) {
+ if (batch.isLeaf()) {
+ Double aliveWeightFactor = computeAliveWeightFactor(batch, options, batch.isLeaf()).orElse(null);
+ changed = changed || !Objects.equals(aliveWeightFactor, batch.getAliveWeightFactor());
+ batch.setAliveWeightFactor(aliveWeightFactor);
+ } else {
+ Double aliveWeightFactor = computeIndirectAliveWeightFactor(batch, options);
+ changed = changed || !Objects.equals(aliveWeightFactor, batch.getAliveWeightFactor());
+ batch.setAliveWeightFactor(aliveWeightFactor);
+ }
}
else {
- Double aliveWeightFactor = computeIndirectAliveWeightFactor(batch, options);
- changed = changed || !Objects.equals(aliveWeightFactor, batch.getAliveWeightFactor());
- batch.setAliveWeightFactor(aliveWeightFactor);
+ batch.setAliveWeightFactor(1d);
}
if (changed) changesCount.increment();
@@ -539,7 +551,7 @@ protected void computeIndirectValues(List batches, Denormal
}
// Continue while changes has been applied on tree
- while (changesCount.intValue() > 0);
+ while (changesCount.intValue() > 0 && loopCounter.intValue() < maxLoop);
}
/**
@@ -592,6 +604,7 @@ protected void computeElevateFactor(List batches, Denormali
protected void computeElevatedValues(List batches, DenormalizedBatchOptions options) {
MutableInt changesCount = new MutableInt(0);
MutableInt loopCounter = new MutableInt(0);
+ int maxLoop = 1; // TODO check this
do {
changesCount.setValue(0);
@@ -702,7 +715,7 @@ protected void computeElevatedValues(List batches, Denormal
});
log.trace("Computing elevated values (pass #{}) [OK] - {} changes", loopCounter, changesCount);
- } while (changesCount.intValue() > 0);
+ } while (changesCount.intValue() > 0 && loopCounter.intValue() < maxLoop);
}
protected void computeIndirectElevatedValues(List batches, DenormalizedBatchOptions options) {
@@ -715,6 +728,8 @@ protected void computeIndirectElevatedValues(List batches,
MutableInt changesCount = new MutableInt(0);
MutableInt loopCounter = new MutableInt(0);
+ int maxLoop = 1; // TODO check this value
+
do {
changesCount.setValue(0);
loopCounter.increment();
@@ -761,7 +776,7 @@ protected void computeIndirectElevatedValues(List batches,
});
log.trace("Computing indirect elevated values (pass #{}) [OK] - {} changes", loopCounter, changesCount);
- } while (changesCount.intValue() > 0);
+ } while (changesCount.intValue() > 0 && loopCounter.intValue() < maxLoop);
}
protected Optional computeRtpContextWeight(TempDenormalizedBatchVO batch, DenormalizedBatchOptions options) {
@@ -1289,7 +1304,7 @@ protected Optional computeAliveWeightFactor(TempDenormalizedBatchVO batc
.taxonGroupIds(new Integer[]{taxonGroupId})
.dressingIds(new Integer[]{dressingId})
.preservingIds(new Integer[]{preservationId})
- .locationIds(new Integer[]{options.getRoundWeightCountryLocationId()})
+ .locationIds(new Integer[]{options.getAliveWeightCountryLocationId()})
.date(options.getDay())
.build());
@@ -1298,7 +1313,7 @@ protected Optional computeAliveWeightFactor(TempDenormalizedBatchVO batc
taxonGroupId,
dressingId,
preservationId,
- options.getRoundWeightCountryLocationId());
+ options.getAliveWeightCountryLocationId());
}
diff --git a/sumaris-core/src/main/java/net/sumaris/core/service/data/denormalize/DenormalizedTripServiceImpl.java b/sumaris-core/src/main/java/net/sumaris/core/service/data/denormalize/DenormalizedTripServiceImpl.java
index 7d3cd4c9d3..a0b71c954a 100644
--- a/sumaris-core/src/main/java/net/sumaris/core/service/data/denormalize/DenormalizedTripServiceImpl.java
+++ b/sumaris-core/src/main/java/net/sumaris/core/service/data/denormalize/DenormalizedTripServiceImpl.java
@@ -68,7 +68,8 @@ public DenormalizedTripResultVO denormalizeByFilter(@NonNull TripFilterVO filter
}
@Override
- public DenormalizedTripResultVO denormalizeByFilter(@NonNull TripFilterVO tripFilter, @NonNull IProgressionModel progression) {
+ public DenormalizedTripResultVO denormalizeByFilter(@NonNull TripFilterVO tripFilter,
+ @NonNull IProgressionModel progression) {
long startTime = System.currentTimeMillis();
progression.setCurrent(0);
@@ -111,8 +112,7 @@ public DenormalizedTripResultVO denormalizeByFilter(@NonNull TripFilterVO tripFi
}
// Denormalize each trip
- trips.stream().parallel()
- .forEach(trip -> {
+ trips.parallelStream().forEach(trip -> {
// Load denormalized options
DenormalizedBatchOptions programOptions = denormalizedOperationService.createOptionsByProgramId(trip.getProgram().getId());
diff --git a/sumaris-core/src/main/java/net/sumaris/core/service/technical/JobExecutionService.java b/sumaris-core/src/main/java/net/sumaris/core/service/technical/JobExecutionService.java
index c36c8de456..885b2900b2 100644
--- a/sumaris-core/src/main/java/net/sumaris/core/service/technical/JobExecutionService.java
+++ b/sumaris-core/src/main/java/net/sumaris/core/service/technical/JobExecutionService.java
@@ -30,13 +30,16 @@
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
+import java.util.function.BiFunction;
import java.util.function.Function;
public interface JobExecutionService {
- JobVO run(JobVO job, Callable