Tony CHEMIT pushed to branch develop at ultreiaio / ird-observe
Commits:
-
b2b08d40
by Tony Chemit at 2022-12-05T15:46:34+01:00
-
5f2d8458
by Tony Chemit at 2022-12-05T15:46:58+01:00
-
af99d895
by Tony Chemit at 2022-12-05T15:46:58+01:00
-
eaebe74a
by Tony Chemit at 2022-12-05T16:22:35+01:00
7 changed files:
- core/api/dto/src/main/resources/observe-reports.properties
- core/services/test/src/main/resources/fixtures/fr/ird/observe/services/service/ReportService-psObservationCatchByGroup.properties
- core/services/test/src/main/resources/fixtures/fr/ird/observe/services/service/ReportService-psObservationLengthsDistribution.properties
- toolkit/api/src/main/java/fr/ird/observe/dto/report/ReportBuilder.java
- toolkit/api/src/main/java/fr/ird/observe/dto/report/ReportVariable.java
- toolkit/api/src/main/java/fr/ird/observe/dto/report/operations/ComputeDynamicHeader.java
- toolkit/api/src/main/java/fr/ird/observe/spi/json/toolkit/ReportVariableAdapter.java
Changes:
| ... | ... | @@ -890,7 +890,7 @@ report.psObservationCatch.request.3.repeat=speciesId|column |
| 890 | 890 | ## Captures par groupe d'espèces
|
| 891 | 891 | ################################################################################
|
| 892 | 892 | report.psObservationCatchByGroup.modelType=PS
|
| 893 | -report.psObservationCatchByGroup.name=Observations - Dénombrement des captures par devenir, filtrés par groupe
|
|
| 893 | +report.psObservationCatchByGroup.name=Observations - Dénombrement des captures par type de banc et devenir, filtrés par groupe
|
|
| 894 | 894 | report.psObservationCatchByGroup.description=Afficher les nombres de captures par groupe d'espèce selon le type de banc et le devenir
|
| 895 | 895 | report.psObservationCatchByGroup.variable.speciesGroup=fr.ird.observe.dto.referential.common.SpeciesGroupDto|\
|
| 896 | 896 | Select distinct sg \
|
| ... | ... | @@ -914,16 +914,9 @@ Join ca.species e with e.speciesGroup.id = :speciesGroup \ |
| 914 | 914 | Where t.id In :tripId \
|
| 915 | 915 | Order By e.homeId
|
| 916 | 916 | report.psObservationCatchByGroup.repeatVariable.2.speciesFate=fr.ird.observe.entities.referential.ps.common.SpeciesFate|\
|
| 917 | -Select distinct sf \
|
|
| 918 | -From TripImpl t \
|
|
| 919 | -Join t.routeObs r \
|
|
| 920 | -Join r.activity a \
|
|
| 921 | -Join a.set c \
|
|
| 922 | -Join c.catches ca with ca.totalCount Is Not Null \
|
|
| 923 | -Join ca.species e with e.id In :species \
|
|
| 924 | -Join ca.speciesFate sf \
|
|
| 925 | -Where t.id In :tripId \
|
|
| 926 | -Order by sf.code
|
|
| 917 | +Select sf \
|
|
| 918 | +From SpeciesFateImpl sf \
|
|
| 919 | +Order by sf.discard, sf.code
|
|
| 927 | 920 | report.psObservationCatchByGroup.request.1=0,0|row|\
|
| 928 | 921 | Select \
|
| 929 | 922 | concat(\
|
| ... | ... | @@ -953,7 +946,7 @@ Join ca.species s with s.id In :species \ |
| 953 | 946 | Join ca.speciesFate sf with sf.id In :speciesFate \
|
| 954 | 947 | Where m.id In :tripId \
|
| 955 | 948 | Group by s, sf \
|
| 956 | -Order By s.homeId, sf.code
|
|
| 949 | +Order By s.homeId
|
|
| 957 | 950 | report.psObservationCatchByGroup.operations.2=ComputeDynamicHeader:Espèce,Total BL,Total BO|speciesFate
|
| 958 | 951 | report.psObservationCatchByGroup.operations.3=SumIntRow:1|3
|
| 959 | 952 | report.psObservationCatchByGroup.operations.4=SumIntColumn:1|1
|
| ... | ... | @@ -979,16 +972,10 @@ Join r.activity a \ |
| 979 | 972 | Join a.set.sample nts \
|
| 980 | 973 | Join nts.sampleMeasure ntl \
|
| 981 | 974 | Where t.id In :tripId
|
| 982 | -report.psObservationLengthsDistribution.repeatVariable.speciesFate=fr.ird.observe.entities.referential.ps.common.SpeciesFate|\
|
|
| 983 | -Select distinct sf \
|
|
| 984 | -From TripImpl t \
|
|
| 985 | -Join t.routeObs r \
|
|
| 986 | -Join r.activity a \
|
|
| 987 | -Join a.set.sample nts \
|
|
| 988 | -Join nts.sampleMeasure ntl with ntl.species.id = :species And ntl.sizeMeasureType.id = :sizeMeasureType \
|
|
| 989 | -Left Join ntl.speciesFate sf \
|
|
| 990 | -Where t.id In :tripId \
|
|
| 991 | -Order By sf.code
|
|
| 975 | +report.psObservationLengthsDistribution.repeatVariable.speciesFate=fr.ird.observe.entities.referential.ps.common.SpeciesFate|true|\
|
|
| 976 | +Select sf \
|
|
| 977 | +From SpeciesFateImpl sf \
|
|
| 978 | +Order by sf.discard, sf.code
|
|
| 992 | 979 | report.psObservationLengthsDistribution.repeatVariable.length=java.lang.Float|\
|
| 993 | 980 | Select distinct ntl.length \
|
| 994 | 981 | From TripImpl t \
|
| ... | ... | @@ -1006,7 +993,7 @@ Join t.routeObs r \ |
| 1006 | 993 | Join r.activity a \
|
| 1007 | 994 | Join a.set.sample nts \
|
| 1008 | 995 | Join nts.sampleMeasure ntl With ntl.species.id = :species And ntl.sizeMeasureType.id = :sizeMeasureType \
|
| 1009 | -Left Join ntl.speciesFate sf with sf.id In :speciesFate \
|
|
| 996 | +Left Join ntl.speciesFate sf \
|
|
| 1010 | 997 | Where t.id In :tripId \
|
| 1011 | 998 | Group By ntl.length, sf \
|
| 1012 | 999 | Order By ntl.length
|
| ... | ... | @@ -19,14 +19,14 @@ |
| 19 | 19 | # <http://www.gnu.org/licenses/gpl-3.0.html>.
|
| 20 | 20 | # #L%
|
| 21 | 21 | ###
|
| 22 | -syntax.name=Observations - Dénombrement des captures par devenir, filtrés par groupe
|
|
| 22 | +syntax.name=Observations - Dénombrement des captures par type de banc et devenir, filtrés par groupe
|
|
| 23 | 23 | syntax.description=Afficher les nombres de captures par groupe d'espèce selon le type de banc et le devenir
|
| 24 | 24 | syntax.rows=-1
|
| 25 | 25 | syntax.columns=-1
|
| 26 | 26 | syntax.columnsHeader=
|
| 27 | 27 | syntax.rowsHeader=
|
| 28 | 28 | syntax.nbRequests=1
|
| 29 | -result.columns=4
|
|
| 29 | +result.columns=19
|
|
| 30 | 30 | result.rows=2
|
| 31 | -result.0=Espèce^Total BL^Total BO^Echappe du filet (pour requin-baleine et cétacés)
|
|
| 32 | -result.1=[FAO]ALV [sc]Alopias vulpinus [fr]Renard^0^3^3 |
|
| \ No newline at end of file | ||
| 31 | +result.0=Espèce^Total BL^Total BO^Ailerons seulements^Partiellement conservé (ex: ailerons de requin, poisson séché)^Autres (à préciser dans les notes)^Conservé pour raisons scientifiques^Conservé pour le marché local ou poisson séché/salé à bord^Conservé à destination de la conserverie^Utilisé en cuisine du bord^Echappe du filet (pour requin-baleine et cétacés)^Rejeté, statut non observé^Rejeté suffocant^Rejeté suffocant blessé^Sortie vivant du filet (pour requin-baleine et cétacés)^Sortie mort du filet (pour requin-baleine et cétacés)^Rejeté vivant^Rejeté mort^Total
|
|
| 32 | +result.1=[FAO]ALV [sc]Alopias vulpinus [fr]Renard^0^3^null^null^null^null^null^null^null^3^null^null^null^null^null^null^null^3 |
| ... | ... | @@ -26,10 +26,10 @@ syntax.columns=-1 |
| 26 | 26 | syntax.columnsHeader=
|
| 27 | 27 | syntax.rowsHeader=
|
| 28 | 28 | syntax.nbRequests=0
|
| 29 | -result.columns=2
|
|
| 29 | +result.columns=18
|
|
| 30 | 30 | result.rows=5
|
| 31 | -result.0=Classe de taille (cm)^Aucun
|
|
| 32 | -result.1=50.0^2
|
|
| 33 | -result.2=54.0^1
|
|
| 34 | -result.3=68.0^1
|
|
| 35 | -result.4=70.0^1 |
|
| 31 | +result.0=Classe de taille (cm)^Ailerons seulements^Partiellement conservé (ex: ailerons de requin, poisson séché)^Autres (à préciser dans les notes)^Conservé pour raisons scientifiques^Conservé pour le marché local ou poisson séché/salé à bord^Conservé à destination de la conserverie^Utilisé en cuisine du bord^Echappe du filet (pour requin-baleine et cétacés)^Rejeté, statut non observé^Rejeté suffocant^Rejeté suffocant blessé^Sortie vivant du filet (pour requin-baleine et cétacés)^Sortie mort du filet (pour requin-baleine et cétacés)^Rejeté vivant^Rejeté mort^Aucun^Total
|
|
| 32 | +result.1=50.0^null^null^null^null^null^null^null^null^null^null^null^null^null^null^null^2^2
|
|
| 33 | +result.2=54.0^null^null^null^null^null^null^null^null^null^null^null^null^null^null^null^1^1
|
|
| 34 | +result.3=68.0^null^null^null^null^null^null^null^null^null^null^null^null^null^null^null^1^1
|
|
| 35 | +result.4=70.0^null^null^null^null^null^null^null^null^null^null^null^null^null^null^null^1^1 |
| ... | ... | @@ -345,7 +345,7 @@ public class ReportBuilder { |
| 345 | 345 | String typeStr = parts[0].trim();
|
| 346 | 346 | String request = parts[1].trim();
|
| 347 | 347 | Class<?> type = Objects2.forName(typeStr);
|
| 348 | - ReportVariable<?> variable = new ReportVariable<>(id, type, request);
|
|
| 348 | + ReportVariable<?> variable = new ReportVariable<>(id, type, request, false);
|
|
| 349 | 349 | log.debug(String.format("Detects a variable : [%s:%s] = %s (type = %s)", reportName, variable.getName(), variable.getRequest(), variable.getType().getName()));
|
| 350 | 350 | result.add(variable);
|
| 351 | 351 | itr.remove();
|
| ... | ... | @@ -381,13 +381,21 @@ public class ReportBuilder { |
| 381 | 381 | ids.add(id);
|
| 382 | 382 | String[] parts = operations.split("\\|");
|
| 383 | 383 | |
| 384 | - if (parts.length != 2) {
|
|
| 385 | - throw new IllegalArgumentException("La définition d'une variable de répétition doit etre de la forme 'type|hql' mais est : " + operations);
|
|
| 384 | + if (parts.length != 2 && parts.length != 3) {
|
|
| 385 | + throw new IllegalArgumentException("La définition d'une variable de répétition doit etre de la forme 'type|hql' ou 'type|true|hql' mais est : " + operations);
|
|
| 386 | 386 | }
|
| 387 | 387 | String typeStr = parts[0].trim();
|
| 388 | - String request = parts[1].trim();
|
|
| 388 | + boolean addNullValue;
|
|
| 389 | + String request;
|
|
| 390 | + if (parts.length == 3) {
|
|
| 391 | + addNullValue = Boolean.parseBoolean(parts[1]);
|
|
| 392 | + request = parts[2].trim();
|
|
| 393 | + } else {
|
|
| 394 | + addNullValue = false;
|
|
| 395 | + request = parts[1].trim();
|
|
| 396 | + }
|
|
| 389 | 397 | Class<?> type = Objects2.forName(typeStr);
|
| 390 | - ReportVariable<?> variable = new ReportVariable<>(id, type, request);
|
|
| 398 | + ReportVariable<?> variable = new ReportVariable<>(id, type, request, addNullValue);
|
|
| 391 | 399 | log.debug(String.format("Detects a variable : [%s:%s] = %s (type = %s)", reportName, variable.getName(), variable.getRequest(), variable.getType().getName()));
|
| 392 | 400 | result.add(variable);
|
| 393 | 401 | itr.remove();
|
| ... | ... | @@ -49,6 +49,7 @@ public class ReportVariable<V> implements Serializable, JsonAware { |
| 49 | 49 | public final static String PROPERTY_VALUES = "values";
|
| 50 | 50 | |
| 51 | 51 | public final static String PROPERTY_SELECTED_VALUE = "selectedValue";
|
| 52 | + public final static String PROPERTY_ADD_NULL_VALUE = "addNullValue";
|
|
| 52 | 53 | |
| 53 | 54 | private static final long serialVersionUID = 1L;
|
| 54 | 55 | |
| ... | ... | @@ -58,14 +59,17 @@ public class ReportVariable<V> implements Serializable, JsonAware { |
| 58 | 59 | |
| 59 | 60 | protected final String request;
|
| 60 | 61 | |
| 62 | + protected final boolean addNullValue;
|
|
| 63 | + |
|
| 61 | 64 | protected Set<V> values;
|
| 62 | 65 | |
| 63 | 66 | protected V selectedValue;
|
| 64 | 67 | |
| 65 | - public ReportVariable(String name, Class<V> type, String request) {
|
|
| 68 | + public ReportVariable(String name, Class<V> type, String request, boolean addNullValue) {
|
|
| 66 | 69 | this.name = name;
|
| 67 | 70 | this.type = type;
|
| 68 | 71 | this.request = request;
|
| 72 | + this.addNullValue = addNullValue;
|
|
| 69 | 73 | }
|
| 70 | 74 | |
| 71 | 75 | public String getName() {
|
| ... | ... | @@ -96,11 +100,15 @@ public class ReportVariable<V> implements Serializable, JsonAware { |
| 96 | 100 | this.selectedValue = selectedValue;
|
| 97 | 101 | }
|
| 98 | 102 | |
| 103 | + public boolean isAddNullValue() {
|
|
| 104 | + return addNullValue;
|
|
| 105 | + }
|
|
| 106 | + |
|
| 99 | 107 | public List<String> computeIndexList() {
|
| 100 | 108 | Set<V> tmp = new LinkedHashSet<>(values);
|
| 101 | 109 | boolean useNullValue = tmp.remove(null);
|
| 102 | 110 | List<String> result = tmp.stream().map(s -> s instanceof ToolkitId ? ((ToolkitId) s).getId() : String.valueOf(s)).collect(Collectors.toList());
|
| 103 | - if (useNullValue) {
|
|
| 111 | + if (useNullValue || addNullValue) {
|
|
| 104 | 112 | result.add("null");
|
| 105 | 113 | }
|
| 106 | 114 | return result;
|
| ... | ... | @@ -28,6 +28,7 @@ import fr.ird.observe.dto.report.DataMatrix; |
| 28 | 28 | import fr.ird.observe.dto.report.Report;
|
| 29 | 29 | import fr.ird.observe.dto.report.ReportOperationConsumer;
|
| 30 | 30 | import fr.ird.observe.dto.report.ReportRequestExecutor;
|
| 31 | +import fr.ird.observe.dto.report.ReportVariable;
|
|
| 31 | 32 | |
| 32 | 33 | import java.util.Set;
|
| 33 | 34 | |
| ... | ... | @@ -36,6 +37,8 @@ import java.util.Set; |
| 36 | 37 | * <p>
|
| 37 | 38 | * You can set as parameters an array of fixed column names + a repeat variable to complete the header.
|
| 38 | 39 | * <p>
|
| 40 | + * <b>Note:</b> The {@code null} value will be added at the last column (TODO maybe should we be able to customize this in the operation parameters...)
|
|
| 41 | + * <p>
|
|
| 39 | 42 | * Example:
|
| 40 | 43 | * <code>Col1,Col2,Col3|repeatVariableName</code>
|
| 41 | 44 | * <p>
|
| ... | ... | @@ -57,7 +60,8 @@ public class ComputeDynamicHeader implements ReportOperationConsumer { |
| 57 | 60 | }
|
| 58 | 61 | String[] fixedColumnNames = split[0].split("\\s*,\\s*");
|
| 59 | 62 | String repeatVariableName = split[1].trim();
|
| 60 | - Set<?> repeatVariableValues = report.getRepeatVariable(repeatVariableName).getValues();
|
|
| 63 | + ReportVariable<Object> repeatVariable1 = report.getRepeatVariable(repeatVariableName);
|
|
| 64 | + Set<?> repeatVariableValues = repeatVariable1.getValues();
|
|
| 61 | 65 | int columnIndex = 0;
|
| 62 | 66 | DataMatrix tmpMatrix = createTmpMatrix(0, 0, incoming.getWidth(), 1);
|
| 63 | 67 | boolean useNullRepeatVariableValue = false;
|
| ... | ... | @@ -75,7 +79,7 @@ public class ComputeDynamicHeader implements ReportOperationConsumer { |
| 75 | 79 | }
|
| 76 | 80 | }
|
| 77 | 81 | }
|
| 78 | - if (useNullRepeatVariableValue) {
|
|
| 82 | + if (useNullRepeatVariableValue || repeatVariable1.isAddNullValue()) {
|
|
| 79 | 83 | tmpMatrix.setValue(columnIndex, 0, "Aucun");
|
| 80 | 84 | }
|
| 81 | 85 | incoming.setY(1);
|
| ... | ... | @@ -59,8 +59,9 @@ public class ReportVariableAdapter implements JsonDeserializer<ReportVariable<?> |
| 59 | 59 | String name = context.deserialize(reportVariableJson.get(ReportVariable.PROPERTY_NAME), String.class);
|
| 60 | 60 | Class<?> type = context.deserialize(reportVariableJson.get(ReportVariable.PROPERTY_TYPE), Class.class);
|
| 61 | 61 | String request = context.deserialize(reportVariableJson.get(ReportVariable.PROPERTY_REQUEST), String.class);
|
| 62 | + boolean addNullValue = context.deserialize(reportVariableJson.get(ReportVariable.PROPERTY_ADD_NULL_VALUE), boolean.class);
|
|
| 62 | 63 | |
| 63 | - ReportVariable reportVariable = new ReportVariable<>(name, type, request);
|
|
| 64 | + ReportVariable reportVariable = new ReportVariable<>(name, type, request, addNullValue);
|
|
| 64 | 65 | |
| 65 | 66 | Class<?> valueType = type;
|
| 66 | 67 |