From 3ae114ad52afeb72e72c244b02ff36ab7c9c5150 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois?= <francois.grand@irstea.fr>
Date: Fri, 13 Jul 2018 14:42:44 +0200
Subject: [PATCH] =?UTF-8?q?=20#42=20passe=20=C3=A0=20cloisons=20:=20correc?=
 =?UTF-8?q?tion=20d'un=20bug=20quand=20on=20change=20le=20type=20de=20stru?=
 =?UTF-8?q?cture=20de=20orifice=20=C3=A0=20seuil=20rectangulaire=20context?=
 =?UTF-8?q?e=20:=20quand=20on=20changeait=20le=20type=20de=20structure,=20?=
 =?UTF-8?q?on=20recherchait=20la=201=C3=A8re=20loi=20de=20d=C3=A9bit=20com?=
 =?UTF-8?q?patible=20avec=20la=20nouvelle=20valeur,=20mais=20sans=20tenir?=
 =?UTF-8?q?=20compte=20des=20valeurs=20possibles=20dans=20le=20select=20'l?=
 =?UTF-8?q?oi=20de=20d=C3=A9bit'.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../concrete/form-parallel-structures.ts      | 116 ++++++++++++++++--
 src/app/formulaire/fieldset.ts                |   6 +-
 2 files changed, 109 insertions(+), 13 deletions(-)

diff --git a/src/app/formulaire/definition/concrete/form-parallel-structures.ts b/src/app/formulaire/definition/concrete/form-parallel-structures.ts
index d629a2cf9..5606c737e 100644
--- a/src/app/formulaire/definition/concrete/form-parallel-structures.ts
+++ b/src/app/formulaire/definition/concrete/form-parallel-structures.ts
@@ -193,25 +193,117 @@ export class FormulaireParallelStructure extends FormulaireDefinition {
     }
 
     /**
-     * après une modification, détermine si les propriétés sont compatibles entre elles et les ajuste au besoin
+     * recherche dans une config le 1er select avec une entrée "enum" avec une valeur donnée
+     */
+    private findSelectWithEnum(conf: {}, enumName: string, enumVal: string): {
+        "select": { [key: string]: string; },
+        "entry": { [key: string]: string; }
+    } {
+        let select; // select 
+        let selectEntry; // entrée du select correspondant à la valeur de l'enum
+
+        for (const k in conf) {
+            const kid = conf[k];
+            if (kid.type === "select") {
+                // entrées
+                for (const e of kid.select) {
+                    if (e.enum !== undefined) {
+                        const tmp = e.enum.split(".");
+                        const found = tmp[0] === enumName && tmp[1] === enumVal;
+                        if (found) {
+                            select = kid;
+                            selectEntry = e;
+                            break;
+                        }
+                    }
+                }
+                if (select !== undefined)
+                    break;
+            }
+        }
+
+        if (select === undefined)
+            return undefined;
+
+        return { "select": select, "entry": selectEntry };
+    }
+
+    /**
+     * recherche dans une config le 1er objet avec dépendance donnée
+     */
+    private findObjectWithDependency(conf: {}, refid: string, refvalue: string): {} {
+        for (const k in conf) {
+            const kid = conf[k];
+            if (kid.dep_exist !== undefined) {
+                for (const dep of kid.dep_exist)
+                    if (dep.refid === refid && dep.refvalue === refvalue)
+                        return kid;
+            }
+        }
+
+        return undefined;
+    }
+
+    /**
+     * trouve une loi de débit compatible avec un type de structure dans un Fieldset en tenant compte des dépendances entre selects
+     * @param fs 
+     * @param structType
+     */
+    private adjustLoiDebit(fs: FieldSet, structType: StructureType): Props {
+        const res: Props = fs.properties.clone();
+
+        // recherche du select "type de structure"
+
+        const structSelect = this.findSelectWithEnum(fs.jsonConfig["fields"], "StructureType", StructureType[structType]);
+        if (structSelect === undefined)
+            throw new Error(`pas de select trouvé pour la propriété StructureType=${StructureType[structType]}`);
+
+        // recherche du select dépendant (lois de débit)
+
+        const loidebitSelect = this.findObjectWithDependency(fs.jsonConfig["fields"], structSelect.select.id, structSelect.entry.id);
+        if (loidebitSelect === undefined || loidebitSelect["type"] !== "select")
+            throw new Error(`pas de select trouvé avec une dépendance au select 'type de structure' pour la valeur ${structSelect.select.id}=${structSelect.entry.id} (1)`);
+
+        // liste des enums du select dépendant
+
+        const loisDebit = [];
+        for (const e of loidebitSelect["select"])
+            if (e.enum !== undefined) {
+                const tmp = e.enum.split(".");
+                loisDebit.push(LoiDebit[tmp[1]]);
+            }
+
+        if (loisDebit.length === 0)
+            throw new Error(`pas de select trouvé avec une dépendance au select 'type de structure' pour la valeur ${structSelect.select.id}=${structSelect.entry.id} (2)`);
+
+        res.setPropValue("loiDebit", StructureProperties.findCompatibleLoiDebit(structType, loisDebit));
+
+        return res;
+    }
+
+    // private adjustTypeStruct(fs: FieldSet, loiDebit: LoiDebit): Props {
+    //     return undefined;
+    // }
+
+    /**
+     * après une modification, détermine si les propriétés d'un Fieldset sont compatibles entre elles et les ajuste au besoin
      * @param props propriétés à vérifier
      * @param name nom de la propriété qui vient de changer
      * @param val nouvelle valeur de la propriété
      */
-    private adjustProperties(props: Props, name: string, val: any) {
-        const res: Props = props.clone();
-
-        // si prop=type d'ouvrage, on prend une loi de débit compatible avec (spécifique aux ouvrages //) comme valeur par défaut
+    private adjustProperties(fs: FieldSet, name: string, val: any): Props {
+        // si prop=type d'ouvrage, on prend la 1ère loi de débit compatible avec (spécifique aux ouvrages //), en tenant compte des dépendances.
+        // (par ex, s'il existe un select de lois de débit dépendant du select de types d'ouvrage, on prend la 1ère entrée du select de lois de débit compatible)
         if (name === "structureType") {
-            if (!StructureProperties.isCompatibleValues(val, res.getPropValue("loiDebit")))
-                res.setPropValue("loiDebit", StructureProperties.findCompatibleLoiDebit(val));
+            if (!StructureProperties.isCompatibleValues(val, fs.properties.getPropValue("loiDebit")))
+                return this.adjustLoiDebit(fs, val);
         }
         // si prop=loi débit, on prend un type d'ouvrage compatible
-        else if (name === "loiDebit")
-            if (!StructureProperties.isCompatibleValues(res.getPropValue("structureType"), val))
-                res.setPropValue("structureType", StructureProperties.findCompatibleStructure(val));
+        // else if (name === "loiDebit")
+        //     if (!StructureProperties.isCompatibleValues(fs.properties.getPropValue("structureType"), val))
+        //         return this.adjustTypeStruct(fs, val);
 
-        return res;
+        return fs.properties;
     }
 
     /**
@@ -251,7 +343,7 @@ export class FormulaireParallelStructure extends FormulaireDefinition {
         else if (sender instanceof FieldSet && data.action == "propertyChange") {
             switch (sender.id) {
                 case "fs_ouvrage":
-                    const props = this.adjustProperties(sender.properties, data["name"], data["value"]);
+                    const props = this.adjustProperties(sender, data["name"], data["value"]);
                     const newNub = this.replaceSessionNub(sender.sessionNub, props);
                     sender.setSessionNub(newNub);
                     this.reset();
diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts
index a4777cecf..cfcd138fa 100644
--- a/src/app/formulaire/fieldset.ts
+++ b/src/app/formulaire/fieldset.ts
@@ -112,6 +112,10 @@ export class FieldSet extends FormulaireElement implements Observer {
         return this._sessionNub.nub.getParameter(symbol);
     }
 
+    public get jsonConfig(): {} {
+        return this._jsonConfig;
+    }
+
     /**
      * crée un input
      * @param json definition de l'input, extrait du fichier de conf de la calculette
@@ -332,7 +336,7 @@ export class FieldSet extends FormulaireElement implements Observer {
                         case "select_ouvrage": // ouvrages parallèles
                             this.setPropValue("structureType", data.value.value);
                             break;
-                        case "select_loidebit": // ouvrages parallèles et dérivées
+                        case "select_loidebit": // ouvrages parallèles et dérivés
                             this.setPropValue("loiDebit", data.value.value);
                             break;
                         case "select_resolution": // courbes de remous, méthode de résolution
-- 
GitLab