feat(m02-df): 36-2 덧 — 재료 조건 찾기 「검색어」 틀 · 표 범위 경계 규칙 칸
- Model CfMaterialRule field 「검색어」 + template(「레미콘 {a}-{b}-{c}」) + slots(자리마다 알약) · materialSources · depends · 흐름 따라가기에 자리 알약도
- Compute 재료 조건 찾기 검색어 = 틀에 자리 알약 값을 끼운 글(옛 fill)을 dv.slot_price 값으로 넘김(서버 찾기는 sub4)
- 표 찾기: 표 블록 「·범위규칙」 칸(줄마다 초과·이하 · 이상·이하 · 이상·미만 · 이하)을 Rule lookup · Compute _lookup 이 따름 · 없으면 초과·이하
- 변환: 재료 검색어 자리 = 검색어 틀 · scope 구분 · 상세구분 · 조건 찾기 요소로 들어가는 선은 안 만듦(depends 로 이음)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VBToTCGk5dqDKeXCEP3vhk
This commit is contained in:
@@ -103,10 +103,10 @@ class _Flow:
|
||||
|
||||
# ── 바깥 값 알약 ──────────────────────────────────────────────────
|
||||
def element(
|
||||
self, group: str, ref: str, unit: str, label: str, rule: dict | None = None
|
||||
self, group: str, ref: str, unit: str, label: str, rule: dict | None = None, **more: Any
|
||||
) -> dict:
|
||||
"""그룹 입력 상자의 요소 알약 — 그룹마다 상자 하나 · 같은 ref · 단위 · 조건이면 알약 하나
|
||||
· rule = 조건 찾기(field 「키」 — ref 의 {…} 에 알약 값을 끼운 요소 · CfMaterialRule)."""
|
||||
· rule = 조건 찾기(CfMaterialRule · 알약 값은 Model depends 로 · 선 없음) · more = scope."""
|
||||
key = f"el|{group}|{ref}|{unit}|{json.dumps(rule, ensure_ascii=False, sort_keys=True)}"
|
||||
if key in self.cache:
|
||||
return self.cache[key]
|
||||
@@ -120,8 +120,7 @@ class _Flow:
|
||||
name += "·"
|
||||
one = {"ref": ref, "name": name, "spec": "", "unit": unit or "-", "mode": "fixed"}
|
||||
if rule:
|
||||
one |= {"mode": "rule", "rule": rule, "slot": name}
|
||||
self.link(rule["from"], {"box": self.cache[gkey]["id"], "name": name})
|
||||
one |= {"mode": "rule", "rule": rule, "slot": name, **more}
|
||||
els.append(one)
|
||||
self.cache[key] = {"box": self.cache[gkey]["id"], "name": name}
|
||||
return self.cache[key]
|
||||
@@ -139,14 +138,20 @@ class _Flow:
|
||||
if len(texts) > 1:
|
||||
raise Unsupported(f"자리 표시가 여러 칸에 낀 요소 「{ref}」")
|
||||
((at, text),) = texts.items()
|
||||
if at == "검색어": # 재료 검색어 틀 — 자리마다 알약 · 서버는 옛 검색어 찾기(정함 · sub4)
|
||||
names = list(dict.fromkeys(_HOLE.findall(text)))
|
||||
slots = [{"name": n, "from": self.hole(n)} for n in names]
|
||||
rule = {"field": "검색어", "op": "같음", "from": slots[0]["from"]}
|
||||
rule |= {"template": text, "slots": slots}
|
||||
scope = {k: str(v) for k, v in ref.items() if k in ("구분", "상세구분") and v}
|
||||
tpl = json.dumps(plain(ref), ensure_ascii=False)
|
||||
return ("@port", self.element(group, tpl, unit, f"{label} 자리", rule, scope=scope))
|
||||
# 찾는 값 = 원문번호(「EQ:{기계}」 → 기계 · 「MO:경유:{지역}」 → "경유:"&지역)
|
||||
want = text.partition(":")[2] if at is None and ":" in text else text
|
||||
if _HOLE.fullmatch(want):
|
||||
src = self.hole(want[1:-1])
|
||||
else:
|
||||
src = self.func(f"{label} 찾는 말", ("@text", want))
|
||||
if at is not None:
|
||||
self.notes.append(f"재료 검색어에 입력이 낌 「{text}」 — 조건 찾기(키 같음)로 옮김")
|
||||
tpl = text if at is None else json.dumps(plain(ref), ensure_ascii=False)
|
||||
tpl += f"#{field}" if field else ""
|
||||
rule = {"field": "키", "op": "같음", "from": src}
|
||||
@@ -383,6 +388,11 @@ def _layout(f: _Flow) -> None:
|
||||
for ln in f.links:
|
||||
srcs = [ln["from"], *[c["from"] for c in (ln.get("rule") or {}).get("conds", [])]]
|
||||
feeds.setdefault(ln["to"]["box"], set()).update(s["box"] for s in srcs)
|
||||
for bid, b in f.boxes.items(): # 조건 찾기 요소 — 값을 주는 알약 상자 뒤
|
||||
for e in (b.get("input") or {}).get("elements") or []:
|
||||
rule = e.get("rule") or {}
|
||||
srcs = [rule.get("from"), *[x["from"] for x in rule.get("slots") or []]]
|
||||
feeds.setdefault(bid, set()).update(p["box"] for p in srcs if p)
|
||||
depth: dict[str, int] = {}
|
||||
|
||||
def level(bid: str, path: frozenset = frozenset()) -> int:
|
||||
|
||||
Reference in New Issue
Block a user