diff --git a/build.gradle b/build.gradle index d0ffe05c7..c89e6e69f 100644 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ tasks.withType(JavaCompile).configureEach { allprojects { group = 'fr.insee.eno' - version = '3.21.3-SNAPSHOT' + version = '3.21.4-SNAPSHOT' } subprojects { diff --git a/eno-core/src/main/java/fr/insee/eno/core/EnoToLunatic.java b/eno-core/src/main/java/fr/insee/eno/core/EnoToLunatic.java index 577ae1940..83b4390fb 100644 --- a/eno-core/src/main/java/fr/insee/eno/core/EnoToLunatic.java +++ b/eno-core/src/main/java/fr/insee/eno/core/EnoToLunatic.java @@ -22,7 +22,7 @@ public static Questionnaire transform(EnoQuestionnaire enoQuestionnaire, EnoPara Questionnaire lunaticQuestionnaire = new Questionnaire(); lunaticMapper.mapQuestionnaire(enoQuestionnaire, lunaticQuestionnaire); // - LunaticProcessing lunaticProcessing = new LunaticProcessing(enoParameters.getLunaticParameters()); + LunaticProcessing lunaticProcessing = new LunaticProcessing(enoParameters); lunaticProcessing.applyProcessing(lunaticQuestionnaire, enoQuestionnaire); // return lunaticQuestionnaire; diff --git a/eno-core/src/main/java/fr/insee/eno/core/processing/out/LunaticProcessing.java b/eno-core/src/main/java/fr/insee/eno/core/processing/out/LunaticProcessing.java index 3b4892c1a..a41f5ee1a 100644 --- a/eno-core/src/main/java/fr/insee/eno/core/processing/out/LunaticProcessing.java +++ b/eno-core/src/main/java/fr/insee/eno/core/processing/out/LunaticProcessing.java @@ -1,6 +1,7 @@ package fr.insee.eno.core.processing.out; import fr.insee.eno.core.model.EnoQuestionnaire; +import fr.insee.eno.core.parameter.EnoParameters; import fr.insee.eno.core.parameter.LunaticParameters; import fr.insee.eno.core.processing.ProcessingPipeline; import fr.insee.eno.core.processing.out.steps.lunatic.*; @@ -15,10 +16,12 @@ public class LunaticProcessing { - private final LunaticParameters parameters; + private final EnoParameters enoParameters; + private final LunaticParameters lunaticParameters; - public LunaticProcessing(LunaticParameters parameters) { - this.parameters = parameters; + public LunaticProcessing(EnoParameters enoParameters) { + this.enoParameters = enoParameters; + this.lunaticParameters = enoParameters.getLunaticParameters(); } /** @@ -43,18 +46,22 @@ public void applyProcessing(Questionnaire lunaticQuestionnaire, EnoQuestionnaire .then(new LunaticInsertUniqueChoiceDetails(enoQuestionnaire)) .then(new LunaticSuggestersConfiguration(enoQuestionnaire)) .then(new LunaticVariablesDimension(enoQuestionnaire)) - .thenIf(parameters.isMissingVariables(), new LunaticAddMissingVariables(enoCatalog, parameters.isMissingVariables())) + .thenIf(lunaticParameters.isMissingVariables(), + new LunaticAddMissingVariables(enoCatalog, lunaticParameters.isMissingVariables())) .then(new LunaticAddResizing(enoQuestionnaire)) .then(new LunaticAddHierarchy()) - .then(new LunaticAddPageNumbers(parameters.getLunaticPaginationMode())) + .then(new LunaticAddPageNumbers(lunaticParameters.getLunaticPaginationMode())) .then(new LunaticResponseTimeQuestionPagination()) .then(new LunaticAddCleaningVariables()) - .thenIf(parameters.isControls(), new LunaticAddControlFormat()) + .thenIf(lunaticParameters.isControls(), new LunaticAddControlFormat()) .then(new LunaticReverseConsistencyControlLabel()) .then(new LunaticAddShapeToCalculatedVariables(enoQuestionnaire, shapefromAttributeRetrieval)) .then(new LunaticFinalizePairwise(enoQuestionnaire)) - .thenIf(parameters.isFilterResult(), new LunaticFilterResult(enoQuestionnaire, shapefromAttributeRetrieval)) - .thenIf(parameters.isLunaticV3(), new LunaticQuestionComponent()); + .thenIf(lunaticParameters.isFilterResult(), + new LunaticFilterResult(enoQuestionnaire, shapefromAttributeRetrieval)) + + .thenIf(lunaticParameters.isLunaticV3(), new LunaticInputNumberDescription(enoParameters.getLanguage())) + .thenIf(lunaticParameters.isLunaticV3(), new LunaticQuestionComponent()); } } diff --git a/eno-core/src/main/java/fr/insee/eno/core/processing/out/steps/lunatic/LunaticInputNumberDescription.java b/eno-core/src/main/java/fr/insee/eno/core/processing/out/steps/lunatic/LunaticInputNumberDescription.java new file mode 100644 index 000000000..c70996823 --- /dev/null +++ b/eno-core/src/main/java/fr/insee/eno/core/processing/out/steps/lunatic/LunaticInputNumberDescription.java @@ -0,0 +1,67 @@ +package fr.insee.eno.core.processing.out.steps.lunatic; + +import fr.insee.eno.core.parameter.EnoParameters; +import fr.insee.eno.core.processing.ProcessingStep; +import fr.insee.lunatic.model.flat.*; + +import java.util.List; +import java.util.Map; + +/** + * Generate a description for input number components. + * Note: this processing must be called before wrapping components in Question components. + */ +public class LunaticInputNumberDescription implements ProcessingStep { + + private static final Map INPUT_NUMBER_DESCRIPTION_CANVAS = Map.of( + EnoParameters.Language.FR, "Format attendu : un nombre%s entre %s et %s", + EnoParameters.Language.EN, "Expected format: a number%s between %s and %s"); + private static final Map UNIT_DESCRIPTION_PREFIX = Map.of( + EnoParameters.Language.FR, " en ", + EnoParameters.Language.EN, " in "); + private static final Map NUMBER_COMMA = Map.of( + EnoParameters.Language.FR, ",", + EnoParameters.Language.EN, "."); + + private final EnoParameters.Language language; + + public LunaticInputNumberDescription(EnoParameters.Language language) { + this.language = language; + } + + @Override + public void apply(Questionnaire lunaticQuestionnaire) { + // + generateInputNumberDescription(lunaticQuestionnaire.getComponents()); + // + lunaticQuestionnaire.getComponents().stream() + .filter(Loop.class::isInstance).map(Loop.class::cast) + .map(Loop::getComponents) + .forEach(this::generateInputNumberDescription); + } + + private void generateInputNumberDescription(List lunaticComponents) { + lunaticComponents.stream() + .filter(InputNumber.class::isInstance).map(InputNumber.class::cast) + .forEach(this::generateInputNumberDescription); + } + + private void generateInputNumberDescription(InputNumber inputNumber) { + // + String unit = inputNumber.getUnit(); + int decimals = inputNumber.getDecimals() != null ? inputNumber.getDecimals().intValue() : 0; + int minValue = inputNumber.getMin().intValue(); + int maxValue = inputNumber.getMax().intValue(); + // + String unitDescription = unit != null ? UNIT_DESCRIPTION_PREFIX.get(language) + unit : ""; + String afterComma = decimals > 0 ? NUMBER_COMMA.get(language) + "0".repeat(decimals) : ""; + String generatedDescription = String.format(INPUT_NUMBER_DESCRIPTION_CANVAS.get(language), + unitDescription, minValue + afterComma, maxValue + afterComma); + // + LabelType description = new LabelType(); + description.setValue(generatedDescription); + description.setType(LabelTypeEnum.VTL_MD); + inputNumber.setDescription(description); + } + +} diff --git a/eno-core/src/test/java/fr/insee/eno/core/processing/out/steps/lunatic/LunaticInputNumberDescriptionTest.java b/eno-core/src/test/java/fr/insee/eno/core/processing/out/steps/lunatic/LunaticInputNumberDescriptionTest.java new file mode 100644 index 000000000..fd43a06f1 --- /dev/null +++ b/eno-core/src/test/java/fr/insee/eno/core/processing/out/steps/lunatic/LunaticInputNumberDescriptionTest.java @@ -0,0 +1,67 @@ +package fr.insee.eno.core.processing.out.steps.lunatic; + +import fr.insee.eno.core.parameter.EnoParameters; +import fr.insee.lunatic.model.flat.InputNumber; +import fr.insee.lunatic.model.flat.Questionnaire; +import org.junit.jupiter.api.Test; + +import java.math.BigInteger; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class LunaticInputNumberDescriptionTest { + + @Test + void noUnitNoDecimals() { + // + Questionnaire lunaticQuestionnaire = new Questionnaire(); + InputNumber inputNumber = new InputNumber(); + inputNumber.setMin(0d); + inputNumber.setMax(100d); + inputNumber.setDecimals(BigInteger.ZERO); + lunaticQuestionnaire.getComponents().add(inputNumber); + // + LunaticInputNumberDescription processing = new LunaticInputNumberDescription(EnoParameters.Language.FR); + processing.apply(lunaticQuestionnaire); + // + assertEquals("Format attendu : un nombre entre 0 et 100", + lunaticQuestionnaire.getComponents().getFirst().getDescription().getValue()); + } + + @Test + void withUnitAndDecimal() { + // + Questionnaire lunaticQuestionnaire = new Questionnaire(); + InputNumber inputNumber = new InputNumber(); + inputNumber.setMin(0d); + inputNumber.setMax(10d); + inputNumber.setDecimals(BigInteger.ONE); + inputNumber.setUnit("€"); + lunaticQuestionnaire.getComponents().add(inputNumber); + // + LunaticInputNumberDescription processing = new LunaticInputNumberDescription(EnoParameters.Language.FR); + processing.apply(lunaticQuestionnaire); + // + assertEquals("Format attendu : un nombre en € entre 0,0 et 10,0", + lunaticQuestionnaire.getComponents().getFirst().getDescription().getValue()); + } + + @Test + void withUnitNoDecimal() { + // + Questionnaire lunaticQuestionnaire = new Questionnaire(); + InputNumber inputNumber = new InputNumber(); + inputNumber.setMin(20d); + inputNumber.setMax(1000d); + inputNumber.setDecimals(BigInteger.ZERO); + inputNumber.setUnit("k€"); + lunaticQuestionnaire.getComponents().add(inputNumber); + // + LunaticInputNumberDescription processing = new LunaticInputNumberDescription(EnoParameters.Language.FR); + processing.apply(lunaticQuestionnaire); + // + assertEquals("Format attendu : un nombre en k€ entre 20 et 1000", + lunaticQuestionnaire.getComponents().getFirst().getDescription().getValue()); + } + +}