feat(master_data): 산림품셈 3장·4장·5장 로직 48줄

- 로직_산림품셈_03장: 10줄(경계표시 · 작업로 설치+체인톱 · 운반로 신설 작업량+돈 · 보수 · 상용인부 · 예정지정리 할증 · 임내정리 · 재해산물 수집 · 드론 촬영)
- 로직_산림품셈_04장: 5줄(하베스터 벌도·조재 · 조재 · 가지정리 · 위험목 점검 · 작업안전 보조)
- 로직_산림품셈_05장: 33줄(떼채취 · 나무식재 · 파종 · 움싹 · 생태보완 · 큰나무 · 해안 · 사방 · 사초 · 떼 · 새 · 바자 · 씨뿌리기 · 표토 · 뿜어붙이기 · 거적 · 짚망 · 복사이식 · 표시봉 · 지주목 · 대절 · 가식 · 소운반)
- 1-4 할증은 1-4-10 토양상태 · 1-4-14 집재방향만(나머지는 칸 이름 문법 막힘)
- 시험 둘 더함(18 통과)

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 17:06:52 +09:00
co-authored by Claude Opus 5
parent f5aa8f907c
commit 03d8c4daa3
4 changed files with 1588 additions and 0 deletions
+26
View File
@@ -16,6 +16,9 @@ SAMPLES = [
"계수_산림품셈_9장.json",
"기계_건설품셈.json",
"로직_건설품셈_공통8장.json",
"로직_산림품셈_03장.json",
"로직_산림품셈_04장.json",
"로직_산림품셈_05장.json",
"로직_산림품셈_10장.json",
"로직_산림품셈_11장.json",
"로직_산림품셈_13장.json",
@@ -141,6 +144,29 @@ def test_중기운반_트레일러_횟수(whole):
assert got["줄"][0]["수량"].quantize(Decimal("0.0001")) == Decimal("1.3041")
def test_예정지정리_할증_합산(whole):
"""3-5 — 바이오매스 10 + 침엽수림 10 + 개벌지 10 + 산불 5×2/10 = 31% · 2.4×50%×1.31."""
given = {
"작업내용": "보완사업지 정리",
"정리량": 120,
"임상": "침엽수림",
"개벌지": "700㎡ 이하(또는 벌채폭 30m)",
"산불피해면적": 2,
"조림면적": 10,
}
got = mf.run(whole, "산림품셈:3-5 예정지정리", given)
assert [line["수량"] for line in got["줄"]] == [Decimal("1.572"), Decimal("1.572")]
def test_작업안전_보조_올림(whole):
"""4-6 — 벌목부 4인당 보통인부 1인 · 5인이면 2인."""
qty = [
mf.run(whole, "산림품셈:4-6 벌목부 작업안전 보조", {"벌목부": n})["줄"][0]["수량"]
for n in (3, 4, 5, 8)
]
assert qty == [1, 1, 2, 2]
def test_범위_입력은_막음(whole):
with pytest.raises(mf.FormulaError):
mf.run(