feat(master_data): 산림품셈 6장·7장·8장 로직 37줄

- 로직_산림품셈_06장: 12줄(비료주기 · 둘레베기 · 줄베기 · 모두베기 · 맹아제거 · 덩굴걷기 · 덩굴 약제 · 어린나무 가꾸기 · 가지치기 · 관목·초본류 시비 · 목재칩)
- 로직_산림품셈_07장: 15줄(인력집재 · 아키야윈치 · 소형가선 · 트랙터부착형 · 스윙야더 · HAM200 · 타워야더 · 동력상하차기 · 부산물 · 포워더 · 소형트럭 · 지조운반)
- 로직_산림품셈_08장: 10줄(방제 벌목조재 · 소운반 · 소각 · 매몰 · 페르몬 트랩 · 유인헬기 · 실행 등록 · 훈증더미 제거 · 잔가지줍기)
- 2장 연료 · 잡품 · 손료 · 소모성경비를 변수로 · 공시 없는 재료 셋은 재료:자체:이름
- 시험 둘 더함(20 통과)

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:21:00 +09:00
co-authored by Claude Opus 5
parent a43e78b703
commit ec903249f9
4 changed files with 1854 additions and 0 deletions
+30
View File
@@ -19,6 +19,7 @@ SAMPLES = [
"로직_산림품셈_03장.json",
"로직_산림품셈_04장.json",
"로직_산림품셈_05장.json",
"로직_산림품셈_07장.json",
"로직_산림품셈_10장.json",
"로직_산림품셈_11장.json",
"로직_산림품셈_13장.json",
@@ -167,6 +168,35 @@ def test_작업안전_보조_올림(whole):
assert qty == [1, 1, 2, 2]
def test_동력상하차기_잔존목_할증(whole):
"""7-11 — 40m · 41∼60㎥ · 1.2m = 22.03㎥ · 잔존목 10% · 소모성경비 0.02105×380만/50."""
given = {
"최대집재거리": 40,
"집재재적": 50,
"원목길이": 1.2,
"잔존목": "잔존목 100본 이상 130본 이하",
"지역": "전국평균",
}
got = mf.run(whole, "산림품셈:7-11 동력상하차기 집재", given)
assert got["줄"][0]["수량"] == Decimal("1.1") / Decimal("22.03")
assert got["중간"]["소모성경비"] == Decimal("1599.8")
def test_방제_벌목조재_감_할증(whole):
"""8-3 — 경급 6 = 1.13㎥/인 · 소군락 −30% · 잣나무 +20% · 벌목부 50%."""
given = {
"경급": 6,
"소군락": "소군락 모두베기",
"방제수종": "잣나무",
"체인톱가격": 1200000,
"체인오일단가": 5000,
"지역": "전국평균",
}
got = mf.run(whole, "산림품셈:8-3 벌목조재", given)
want = Decimal("0.7") * Decimal("1.2") * Decimal("0.5") / Decimal("1.13")
assert got["줄"][0]["수량"].quantize(Decimal("0.000001")) == want.quantize(Decimal("0.000001"))
def test_범위_입력은_막음(whole):
with pytest.raises(mf.FormulaError):
mf.run(