From 120f56bb236953f1ae10e4fc36739887eab0edb3 Mon Sep 17 00:00:00 2001 From: Manus Date: Sun, 12 Apr 2026 14:40:18 -0400 Subject: [PATCH] =?UTF-8?q?Checkpoint:=20Ajout=20d'un=20champ=20texte=20li?= =?UTF-8?q?bre=20qui=20s'affiche=20quand=20"Autre..."=20est=20s=C3=A9lecti?= =?UTF-8?q?onn=C3=A9=20dans=20les=20selects=20typeAchat,=20serviceConcerne?= =?UTF-8?q?=20et=20ventilationComptable=20des=20r=C3=A8gles=20d'automatism?= =?UTF-8?q?e.=20Le=20texte=20saisi=20remplace=20"AUTRE"=20dans=20le=20tamp?= =?UTF-8?q?on=20BAP.=20Disponible=20dans=20les=20deux=20modes=20(wizard=20?= =?UTF-8?q?et=20avanc=C3=A9).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/pages/AutomationRules.tsx | 126 +++++++++++++++++++++++++-- 1 file changed, 118 insertions(+), 8 deletions(-) diff --git a/client/src/pages/AutomationRules.tsx b/client/src/pages/AutomationRules.tsx index 4b5d986..1f52697 100644 --- a/client/src/pages/AutomationRules.tsx +++ b/client/src/pages/AutomationRules.tsx @@ -68,6 +68,21 @@ export default function AutomationRules() { const [conditionsLogic, setConditionsLogic] = useState<"AND" | "OR">("AND"); const [conditions, setConditions] = useState([{ field: "supplierName", operator: "contains", value: "" }]); const [actions, setActions] = useState({}); + // Textes personnalisés quand "Autre" est sélectionné + const [customTypeAchat, setCustomTypeAchat] = useState(""); + const [customServiceConcerne, setCustomServiceConcerne] = useState(""); + const [customVentilation, setCustomVentilation] = useState(""); + + // Helper : détecte si une valeur est "Autre" (insensible à la casse) + const isAutre = (val?: string) => val?.toUpperCase() === "AUTRE"; + + // Helper : résout la valeur finale (si Autre + texte perso, retourne le texte perso) + const resolveAction = (val?: string, custom?: string) => { + if (!val || val === "__NONE__") return undefined; + if (isAutre(val) && custom?.trim()) return custom.trim().toUpperCase(); + if (isAutre(val)) return "AUTRE"; + return val; + }; const createMutation = trpc.automationRules.create.useMutation({ onSuccess: (rule) => { @@ -149,6 +164,9 @@ export default function AutomationRules() { setConditionsLogic("AND"); setConditions([{ field: "supplierName", operator: "contains", value: "" }]); setActions({}); + setCustomTypeAchat(""); + setCustomServiceConcerne(""); + setCustomVentilation(""); setDialogOpen(true); }; @@ -162,9 +180,36 @@ export default function AutomationRules() { setConditions([{ field: "supplierName", operator: "contains", value: "" }]); } try { - setActions(JSON.parse(rule.actions)); + const parsedActions = JSON.parse(rule.actions); + // Détecter si les valeurs stockées ne correspondent pas aux valeurs fixes + // (ce qui signifie qu'un texte personnalisé avait été saisi) + const knownTypeAchat = ["CAPEX", "OPEX", "AUTRE", undefined]; + const deptNames = departments?.map(d => d.name) || []; + const allocNames = allocations?.map(a => a.name) || []; + if (parsedActions.typeAchat && !knownTypeAchat.includes(parsedActions.typeAchat)) { + setCustomTypeAchat(parsedActions.typeAchat); + parsedActions.typeAchat = "AUTRE"; + } else { + setCustomTypeAchat(""); + } + if (parsedActions.serviceConcerne && !deptNames.includes(parsedActions.serviceConcerne) && parsedActions.serviceConcerne !== "AUTRE") { + setCustomServiceConcerne(parsedActions.serviceConcerne); + parsedActions.serviceConcerne = "AUTRE"; + } else { + setCustomServiceConcerne(""); + } + if (parsedActions.ventilationComptable && !allocNames.includes(parsedActions.ventilationComptable) && parsedActions.ventilationComptable !== "AUTRE") { + setCustomVentilation(parsedActions.ventilationComptable); + parsedActions.ventilationComptable = "AUTRE"; + } else { + setCustomVentilation(""); + } + setActions(parsedActions); } catch { setActions({}); + setCustomTypeAchat(""); + setCustomServiceConcerne(""); + setCustomVentilation(""); } setDialogOpen(true); }; @@ -181,7 +226,17 @@ export default function AutomationRules() { } const conditionsJSON = JSON.stringify(conditions); - const actionsJSON = JSON.stringify(actions); + // Résoudre les valeurs finales (remplacer AUTRE par le texte personnalisé si fourni) + const resolvedActions: Actions = { + typeAchat: resolveAction(actions.typeAchat, customTypeAchat), + serviceConcerne: resolveAction(actions.serviceConcerne, customServiceConcerne), + ventilationComptable: resolveAction(actions.ventilationComptable, customVentilation), + }; + // Supprimer les clés undefined + if (!resolvedActions.typeAchat) delete resolvedActions.typeAchat; + if (!resolvedActions.serviceConcerne) delete resolvedActions.serviceConcerne; + if (!resolvedActions.ventilationComptable) delete resolvedActions.ventilationComptable; + const actionsJSON = JSON.stringify(resolvedActions); if (editingRule) { updateMutation.mutate({ @@ -476,7 +531,7 @@ export default function AutomationRules() { + {isAutre(actions.typeAchat) && ( + setCustomTypeAchat(e.target.value)} + placeholder="Texte à afficher sur le BAP (ex: INVESTISSEMENT)" + className="mt-1 border-orange-300 focus:border-orange-500" + /> + )}
+ {isAutre(actions.serviceConcerne) && ( + setCustomServiceConcerne(e.target.value)} + placeholder="Texte à afficher sur le BAP (ex: LOGISTIQUE)" + className="mt-1 border-orange-300 focus:border-orange-500" + /> + )}
+ {isAutre(actions.ventilationComptable) && ( + setCustomVentilation(e.target.value)} + placeholder="Texte à afficher sur le BAP (ex: SANITAIRE)" + className="mt-1 border-orange-300 focus:border-orange-500" + /> + )}
@@ -667,7 +749,7 @@ export default function AutomationRules() { + {isAutre(actions.typeAchat) && ( + setCustomTypeAchat(e.target.value)} + placeholder="Saisir le texte à afficher sur le BAP (ex: INVESTISSEMENT)" + className="mt-1 border-orange-300 focus:border-orange-500" + autoFocus + /> + )}
+ {isAutre(actions.serviceConcerne) && ( + setCustomServiceConcerne(e.target.value)} + placeholder="Saisir le texte à afficher sur le BAP (ex: LOGISTIQUE)" + className="mt-1 border-orange-300 focus:border-orange-500" + /> + )}
+ {isAutre(actions.ventilationComptable) && ( + setCustomVentilation(e.target.value)} + placeholder="Saisir le texte à afficher sur le BAP (ex: SANITAIRE)" + className="mt-1 border-orange-300 focus:border-orange-500" + /> + )}