feat(master_data): 없는 직종으로 막혔던 절을 인력_자체로 세움 — 공통 3-7-2 · 3-11 · 토목 4장 · 5-1-1 제작도 · 6-7-5

- 공통 3-11-1~3-11-5 장비조립·해체 5줄 · 3-11-5 시험시공 및 다짐관리 기준 수립 1줄 새로 · 3-7-2 중급기술자
- 토목 4-2-1 · 4-2-2 · 4-3-1~4-3-3 · 4-4-1 · 4-4-2 측량중급기술자 · 6-7-5 갱부
- 토목 5-1-1 제작도(5-1-3 주①) 고르기 — 이 품에 포함이면 중급숙련기술자 0.4·0.56인/톤 × 본체 보정계수
- 인력_자체 +2(측량중급기술자 · 갱부)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JgUhN55Z3BCYhUJTjwTNfj
This commit is contained in:
2026-09-19 20:09:35 +09:00
co-authored by Claude Opus 5
parent a6fe666259
commit df8d3c2c3e
6 changed files with 422 additions and 19 deletions
+38 -2
View File
@@ -49,6 +49,16 @@ def whole():
return cm.master()
@pytest.fixture(scope="module")
def faked():
"""자체 인력 값이 빈 칸 — 시험용 가짜 값(파일엔 안 씀)."""
files = cm.load()
for row in files["인력_자체.json"]["줄"]:
if row["값"] is None:
row["값"] = Decimal(1000)
return mf.Master(files)
def cents(x) -> str:
return str(Decimal(x).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP))
@@ -327,10 +337,10 @@ def test_토목_터널굴착_장대할증(whole):
assert got["줄"][0]["수량"] == Decimal("1.2")
def test_토목_궤광조립_직결형_단선감(whole):
def test_토목_궤광조립_직결형_단선감(faked):
"""토목 4-3-1 — 직결형 시공량은 분리형 250m(병합 칸) · 단선 5% 감 = 궤도공 16 ÷ 237.5."""
given = {"단선감": 5, "구분": "침목매립식(직결형)", "지역": "전국평균", "보정작업": "해당 없음"}
got = mf.run(whole, "건설품셈:4-3-1 궤광조립(콘크리트)", given)
got = mf.run(faked, "건설품셈:4-3-1 궤광조립(콘크리트)", given)
assert got["줄"][0]["수량"] == Decimal(16) / Decimal("237.5")
@@ -346,6 +356,7 @@ def test_토목_강교_제작공수_보정(whole):
"사각": 60,
"곡률반경": 200,
"높이곡선변화": "있음",
"제작도": "별도 계상",
}
got = mf.run(whole, "건설품셈:5-1-1 기본제작공수", given)
# 0.95 × (1 + 0.25×0.5) × 0.97 × 0.95 × (1 − 0.03 − 0.02 + 0.25 + 0.11)
@@ -353,6 +364,31 @@ def test_토목_강교_제작공수_보정(whole):
assert got["줄"][0]["수량"] == want
def test_자체_직종으로_세운_절(faked):
"""없는 직종(고급·중급기술자 · 중급숙련기술자)을 인력_자체로 세운 줄."""
def qty(ref, given):
return {x["이름"]: x["수량"] for x in mf.run(faked, "건설품셈:" + ref, given)["줄"]}
# 3-11-1 조립 1일 + 해체 1일 — 인 × 2
got = qty("3-11-1 머신 가이던스(MG) 굴착기 장비조립・해체", {})
assert [got[w] for w in ("고급기술자", "중급기술자", "용접공")] == [2, 2, 2]
# 5-1-3 주① 제작도 — 박스거더 0.4인/톤 × 본체 보정계수 1.31
given = {
"형식": "박스거더",
"고강도강비율": 0,
"대형단품평균중량": 12,
"부품평균중량": 120,
"연수": 2,
"총중량": 600,
"사각": 60,
"곡률반경": 200,
"높이곡선변화": "있음",
"제작도": "이 품에 포함",
}
assert qty("5-1-1 기본제작공수", given)["중급숙련기술자"] == Decimal("0.4") * Decimal("1.31")
def test_토목_배송관_철거_크레인_규격(whole):
"""토목 7-4-1 — 관경 760 이상은 15톤 크레인 · 철거 감률은 인력·장비 모두."""
given = {