feat(master_data): 노임 준용 칸 · ESTX 다른 조사 다섯 갈래 노임 파일 · 인력_자체 → 새 노임 열쇠와 인력_미확보
- 역산: ESTX 미공표 추정 = 마지막 공표값 × 전체직종 평균 증가율 공표일마다 이어 곱·원 미만 버림 (5 직종 원 단위 일치 · 9 직종 앞 값 없음) - 건설노임 미공표 14 줄에 준용 칸(null) · 엔진은 값이 비면 준용 직종 값 · 호표 출처 「준용: <직종>」 · M01 계산표에 표시 - 새 파일: 엔지니어링노임 59 · 측량노임 20 · 건설사업관리노임 7 · SW노임 17 · 산림노임 2 (줄 수·값 합 ESTX 와 같음) - 인력_자체 49 → 새 노임 열쇠 18 · 인력_미확보 31 · 로직 참조 526 곳 - 로직 일괄 시험 계산: 통과 1011 → 1088 · 인력 값 없음 멈춤 176 → 84 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PAdA5ThqmtVSsbzjusk1cJ
This commit is contained in:
@@ -239,6 +239,16 @@ class Master:
|
||||
raise FormulaError(f"없는 요소 「{ref}」")
|
||||
return row
|
||||
|
||||
def value(self, ref: str):
|
||||
"""요소 값 · 준용 이름 — 값이 비고 「준용」(같은 원문 열쇠 또는 `그룹:원문:열쇠`)이 있으면 그 요소 값."""
|
||||
row = self.get(ref)
|
||||
alias = row.get("준용")
|
||||
if row.get("값") is not None or alias in (None, ""):
|
||||
return row.get("값"), None
|
||||
alias = str(alias)
|
||||
target = self.get(alias if ":" in alias else ":".join(ref.split(":", 2)[:2] + [alias]))
|
||||
return target.get("값"), target.get("이름") or alias
|
||||
|
||||
def logic(self, ref: str) -> dict:
|
||||
return self.get(f"로직:{ref}")
|
||||
|
||||
@@ -311,7 +321,7 @@ def evaluate(node, env: dict, master: Master, depth: int = 0):
|
||||
raise FormulaError(f"모르는 이름 「{node[1]}」")
|
||||
return env[node[1]]
|
||||
if kind == "ref":
|
||||
value = master.get(fill(node[1], env)).get("값")
|
||||
value = master.value(fill(node[1], env))[0]
|
||||
if value is None:
|
||||
raise FormulaError(f"「{node[1]}」 값 없음 — 관리자가 채울 값")
|
||||
if isinstance(value, list):
|
||||
@@ -416,6 +426,7 @@ def run(master: Master, ref: str, given: dict, depth: int = 0) -> dict:
|
||||
sums = dict.fromkeys(COST_ITEMS, Decimal(0))
|
||||
lines = []
|
||||
for item in row.get("호표", []):
|
||||
alias = None
|
||||
qty = evaluate(parse(item["수량"]), env, master, depth)
|
||||
if item["종류"] == "로직":
|
||||
bundle = evaluate(parse(item["요소"]), env, master, depth)
|
||||
@@ -430,7 +441,7 @@ def run(master: Master, ref: str, given: dict, depth: int = 0) -> dict:
|
||||
if node[0] == "field": # 값 묶음 요소의 칸 — 「재료:시중물가:M….채택」
|
||||
price = master.get(fill(node[1][1], env))["값"][node[2]]
|
||||
else:
|
||||
price = master.get(fill(item["요소"], env))["값"]
|
||||
price, alias = master.value(fill(item["요소"], env))
|
||||
if price is None and qty == 0:
|
||||
price = Decimal(0) # 안 쓰는 재료 줄 — 값이 비어도 금액 0
|
||||
if price is None:
|
||||
@@ -446,6 +457,7 @@ def run(master: Master, ref: str, given: dict, depth: int = 0) -> dict:
|
||||
"단가": price,
|
||||
"금액": qty * price,
|
||||
"비목": split,
|
||||
**({"출처": f"준용: {alias}"} if alias else {}),
|
||||
}
|
||||
)
|
||||
for extra in row.get("덧줄", []):
|
||||
|
||||
Reference in New Issue
Block a user