diff --git a/M02_MasterTemplete/CostFlow/M02_CF_InputPanel.ts b/M02_MasterTemplete/CostFlow/M02_CF_InputPanel.ts index 168a14005..bcaed88ba 100644 --- a/M02_MasterTemplete/CostFlow/M02_CF_InputPanel.ts +++ b/M02_MasterTemplete/CostFlow/M02_CF_InputPanel.ts @@ -31,6 +31,7 @@ import { elementOf, machineFields, queryOf, + reconcileUnit, removeElement, setKind, valueOf, @@ -143,6 +144,9 @@ export function renderInputPanel( host.replaceChildren(el("p", { className: "m02-cfip__muted", text: t("NotInput") })); return; } + // 상자 단위가 고른 요소 · 변수 단위와 다르면(견본 등) 맞춰 다시 그림 — 맞으면 바로 지나감 + const fixed = reconcileUnit(lg, boxId); + if (fixed !== lg) return on.change(fixed); const input = box.input ?? { mode: "variable" as const, elements: [], variables: [] }; const kind: CfGroup | "변수" = input.mode === "variable" ? "변수" : (input.group ?? "인력"); const body = el("div", { className: "m02-cfip__body" }); diff --git a/M02_MasterTemplete/CostFlow/M02_CF_InputPanel_Build.ts b/M02_MasterTemplete/CostFlow/M02_CF_InputPanel_Build.ts index ce2f0799b..1e392059b 100644 --- a/M02_MasterTemplete/CostFlow/M02_CF_InputPanel_Build.ts +++ b/M02_MasterTemplete/CostFlow/M02_CF_InputPanel_Build.ts @@ -282,3 +282,13 @@ export function removeVariable(lg: CfLogic, id: string, name: string, pills?: Pi pills, ); } + +/** 상자 단위를 요소 · 변수 단위에 맞춤 — 이미 맞으면 받은 것 그대로(견본처럼 단위가 안 맞게 저장된 상자를 열 때 바로잡음) */ +export function reconcileUnit(lg: CfLogic, id: string): CfLogic { + const box = lg.boxes.find((b) => b.id === id); + if (!box?.input) return lg; + const want = unitOfInput(box.input); + return box.unit === want + ? lg + : { ...lg, boxes: lg.boxes.map((b) => (b.id === id ? { ...b, unit: want } : b)) }; +} diff --git a/resources/tester/test_m02_cf_inputpanel_build.py b/resources/tester/test_m02_cf_inputpanel_build.py index 890b0639d..79aa5cb05 100644 --- a/resources/tester/test_m02_cf_inputpanel_build.py +++ b/resources/tester/test_m02_cf_inputpanel_build.py @@ -219,3 +219,36 @@ def test_환율_유가전력_알약_이름에_날짜가_안_들어감(): "값": 1900, } assert call("elementOf", "유가전력", oil)["name"] == "휘발유 서울" + + +def test_단위가_안_맞게_저장된_상자는_열_때_맞춤(): + el1, el2 = call("elementOf", "인력", LABOR), call("elementOf", "인력", LABOR2) + lg = logic() + lg["boxes"][0]["input"] = { + "mode": "group", + "group": "인력", + "elements": [el1, el2], + "variables": [], + } + assert lg["boxes"][0]["unit"] == "-" + fixed = run([{"op": "fn", "name": "reconcileUnit", "args": [lg, "b1"]}])[0] + assert fixed["boxes"][0]["unit"] == "원/일" + again = run([{"op": "fn", "name": "reconcileUnit", "args": [fixed, "b1"]}])[0] + assert again == fixed + oil = {"ref": "X", "name": "경유", "spec": "", "unit": "원/L"} + lg["boxes"][0]["input"]["elements"].append(oil) + lg["boxes"][0]["unit"] = "원/일" + assert ( + run([{"op": "fn", "name": "reconcileUnit", "args": [lg, "b1"]}])[0]["boxes"][0]["unit"] + == "-" + ) + one = { + "mode": "variable", + "elements": [], + "variables": [{"name": "면적", "type": "number", "unit": "㎡", "example": 1}], + } + lg["boxes"][0]["input"] = one + assert ( + run([{"op": "fn", "name": "reconcileUnit", "args": [lg, "b1"]}])[0]["boxes"][0]["unit"] + == "㎡" + )