feat(master_data): 관경이 든 재료 참조를 고르기 조건으로 · 조건 값의 입력 자리 채움
- 엔진 — 고르기 조건 값의 `{입력}` 을 계산 때 채움(관경) · 검사에서는 그 칸을 뺌(`static`)
- 흄관 · 파형강관 두 줄을 고르기 조건으로 바꿈
- VR관(자재품목 단위 「본」 · 호표 「m」 환산 필요) · 고무링 · 커플링밴드 셋은 옛 참조 유지 — 조건만으로 줄이 안 좁혀짐
- 시험 하나 더함
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JgUhN55Z3BCYhUJTjwTNfj
This commit is contained in:
@@ -479,7 +479,12 @@ def run(master: Master, ref: str, given: dict, depth: int = 0) -> dict:
|
||||
)
|
||||
else:
|
||||
# 고르기 조건 묶음은 그대로 넘김 — `element` 가 대표 줄·첫 줄로 풂
|
||||
ref = item["요소"] if isinstance(item["요소"], dict) else fill(item["요소"], env)
|
||||
# 조건 값의 `{입력}`(관경 등)도 채움 — 규격이 입력 따라 바뀌는 관 줄
|
||||
ref = (
|
||||
{k: fill(v, env) if isinstance(v, str) else v for k, v in item["요소"].items()}
|
||||
if isinstance(item["요소"], dict)
|
||||
else fill(item["요소"], env)
|
||||
)
|
||||
try:
|
||||
price, source = element(master, ref, env, item.get("단위"))
|
||||
except FormulaError:
|
||||
@@ -704,6 +709,7 @@ from master_material import ( # noqa: E402, F401
|
||||
candidates,
|
||||
check_pick,
|
||||
check_unit,
|
||||
static,
|
||||
cond_text,
|
||||
element,
|
||||
pick,
|
||||
|
||||
@@ -106,6 +106,11 @@ def _candidates(master: mf.Master, ref: str, row: dict, env: dict) -> list[str]:
|
||||
|
||||
|
||||
# ── 재료 고르기 ────────────────────────────────────────────────────────
|
||||
def static(cond: dict) -> dict:
|
||||
"""검사용 조건 — 값에 `{입력}` 이 든 칸은 뺌(계산 때 채워짐)."""
|
||||
return {k: v for k, v in cond.items() if not (isinstance(v, str) and "{" in v)}
|
||||
|
||||
|
||||
def cond_text(cond: dict) -> str:
|
||||
"""고르기 조건 한 글자 열쇠 — 「구분|상세구분|규격|대표」 · 화면 단가 미리보기가 줄을 찾는 이름."""
|
||||
return "|".join(str(cond.get(k) or "") for k in PICK_KEYS)
|
||||
@@ -147,6 +152,7 @@ def pick(master: mf.Master, cond: dict, env: dict, unit: str | None = None) -> s
|
||||
def check_unit(master: mf.Master, where: str, cond: dict, unit: str | None) -> list[str]:
|
||||
"""단위 경고 — 호표 줄·품셈재료 줄 단위와 맞는 후보가 없거나 대표 줄 단위가 다름.
|
||||
틀린 데이터가 아니라 좁혀야 할 조건이라 `check_pick` 과 따로 봄(`check_master 단위`)."""
|
||||
cond = static(cond)
|
||||
rows = master.index.get(MARKET, {})
|
||||
rep = str(cond.get("대표") or "")
|
||||
if not unit or set(cond) - set(PICK_KEYS) or not cond.get("구분"):
|
||||
@@ -163,9 +169,11 @@ def check_unit(master: mf.Master, where: str, cond: dict, unit: str | None) -> l
|
||||
|
||||
|
||||
def check_pick(master: mf.Master, where: str, cond: dict, unit: str | None = None) -> list[str]:
|
||||
"""고르기 조건 검사 — 칸 이름 · 구분·상세구분이 자재품목에 있는지 · 대표 줄 · 후보 0."""
|
||||
"""고르기 조건 검사 — 칸 이름 · 구분·상세구분이 자재품목에 있는지 · 대표 줄 · 후보 0.
|
||||
값에 `{입력}` 이 든 칸(관경 등)은 계산 때 채워지므로 검사에서 뺌."""
|
||||
if set(cond) - set(PICK_KEYS) or not cond.get("구분"):
|
||||
return [f"{where} · 재료 고르기 조건 모양 「{cond}」 — {' · '.join(PICK_KEYS)}"]
|
||||
cond = static(cond)
|
||||
out, rows = [], master.index.get(MARKET, {})
|
||||
for slot in ("구분", "상세구분"):
|
||||
if cond.get(slot) and not any(r.get(slot) == cond[slot] for r in rows.values()):
|
||||
|
||||
@@ -1989,7 +1989,11 @@
|
||||
},
|
||||
{
|
||||
"종류": "재료",
|
||||
"요소": "MP:흄관 ∅{관경}㎜",
|
||||
"요소": {
|
||||
"구분": "관·이음관",
|
||||
"상세구분": "흄관",
|
||||
"규격": "{관경}"
|
||||
},
|
||||
"이름": "흄관",
|
||||
"단위": "m",
|
||||
"수량": "찾기(QF000371, 구분='흄관', 관경=관경).적용",
|
||||
@@ -2133,7 +2137,11 @@
|
||||
"호표": [
|
||||
{
|
||||
"종류": "재료",
|
||||
"요소": "MP:파형강관 ∅{관경}㎜",
|
||||
"요소": {
|
||||
"구분": "관·이음관",
|
||||
"상세구분": "파형강관",
|
||||
"규격": "{관경}"
|
||||
},
|
||||
"이름": "파형강관",
|
||||
"단위": "m",
|
||||
"수량": "찾기(QF000373, 구분='파형강관', 관경=관경).적용",
|
||||
|
||||
@@ -952,3 +952,12 @@ def test_단위_경고는_로직_검사와_따로():
|
||||
assert cm.check_logics(files, whole) == []
|
||||
warned = cm.check_units(files, whole)
|
||||
assert warned and all("단위" in x for x in warned)
|
||||
|
||||
|
||||
def test_고르기_조건의_입력_자리_채움(whole):
|
||||
"""관경 같은 입력이 규격에 든 고르기 조건 — 계산 때 채워지고, 검사에서는 그 칸을 뺌."""
|
||||
cond = {"구분": "관·이음관", "상세구분": "파형강관", "규격": "{관경}"}
|
||||
assert mm.static(cond) == {"구분": "관·이음관", "상세구분": "파형강관"}
|
||||
assert mf.check_pick(whole, "시험", cond) == []
|
||||
채움 = {k: mf.fill(v, {"관경": Decimal(800)}) for k, v in cond.items()}
|
||||
assert mm.candidates(whole, 채움, None, "m")
|
||||
|
||||
Reference in New Issue
Block a user