Files
Aislo/resources/tester/test_b09_rock_loss.py
eomsangdonandClaude Opus 5 a842766658 feat(b09): 661 암석 작업 기계손료 보정(건설품셈 8-1-7 1) — 암 공종의 굴착기(무한궤도)·로더·불도저·덤프 줄을 「암석」 호표로
· 암석 손료계수 = (상각 + 정비) × (1 + 가산) + 관리 · 1e-7 정수 아래 버림 · 가산율은 mach_rock_adj(원문 파싱) 한 벌
· 실무 봉화 2024 암석 계수 셋 재현 — 굴착기 1.0 0.2405 · 덤프 2.5 0.3533 · 덤프 15 0.2679
· 거는 자리 — 자기·부모 이름이나 갈래가 연암·보통암·경암·발파암·파쇄암·암절취·암석인 일위대가의 대상 기계 줄
· 안 거는 것 — [주]① 19톤 이상 불도저·18톤 이상 덤프(줄 비고에 까닭) · 브레이커 조합 본체(봉화 조합 손료가 비암석) · 풍화암·호박돌 · 전석섞인토사(혼입율 입력 없음 · 칸 안 만듦)
· 손료율 원천은 이미 8-3 원천표(387건) — 봉화 25 중 보통 조건 16종 전부 일치라 「실측을 기본으로」 물음은 닫힘

바뀐 제목 17(암 집토·암 면고르기·암 덤프 운반/적재 · 2~3.4% 오름) · 나머지 458 그대로 · 프로젝트 내역 그대로 · 잴 시험 넷 빨강→초록 · 끄기 넷 빨강 · 전체 시험 1691 + 323 통과

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BW6Jdsh18WPtYUR6THZJqn
2026-09-14 22:07:48 +09:00

80 lines
4.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""암석 작업 기계손료 보정 — 건설품셈 8-1-7 1 (2026-09-14 브레인 661 ①②).
원문: 「암석굴착, 암석적재, 암석운반 등의 가혹한 작업에 사용되는 경우에는 손료(관리비 제외)를 보정 가산」
불도저(19톤 이상 제외) 25 · 굴착기(무한궤도) 및 로더(무한궤도) 20 · 덤프트럭 25 (%)
[주]① 전용덤프트럭(18톤 이상)과 불도저(19톤 이상)는 보정하지 않음(타이어·습지 불도저는 보정)
실무 봉화 2024 중기목록 「(암석)」 줄 셋이 (상각 + 정비) × (1 + 가산) + 관리 로 역산됨 —
굴착기 1.0 0.2405 · 덤프 2.5 0.3533 · 덤프 15 0.2679. B09 는 이 보정을 한 번도 안 걸고 있었음.
⚠ 브레이커 조합 본체(`#조합`)는 안 걺 — 봉화 「굴삭기 0.7 브레이커조합」 손료 = 비암석 23,128 + 브레이커.
⚠ 전석섞인토사 10% 는 혼입율 입력이 없어 안 걺(② · 칸도 안 만듦).
"""
from __future__ import annotations
from decimal import ROUND_FLOOR, Decimal
from B09_Estimation.B09_Estimation_UnitPrice import cached_build
HAUL = ("164.23",)
def _rows(book, code: str) -> list:
"""그 제목과 제 단가산출(D) 줄."""
own = book.details.get(code) or []
return [
*own,
*(r for d in own if d.ref_code.startswith("D-") for r in book.details[d.ref_code]),
]
def _machines(book, code: str) -> set[str]:
"""그 제목과 제 단가산출(D) 줄이 부르는 기계 호표."""
return {r.ref_code for r in _rows(book, code) if r.ref_code.startswith("X-")}
def test_실무_암석_손료계수_셋이_원천표로_역산됨() -> None:
from B09_Estimation.B09_Estimation_RockLoss import rock_coefficient
# 실무 표기는 취득가 천원당 — 우리 계수는 원당(× 1000 이 실무 값)
assert rock_coefficient("0201-0100") * 1000 == Decimal("0.2405") # 굴착기 1.0 (900+700)×1.2+485
assert rock_coefficient("0602-0025") * 1000 == Decimal("0.3533") # 덤프 2.5 3533.75 버림
assert rock_coefficient("0602-0150") * 1000 == Decimal("0.2679") # 덤프 15
assert rock_coefficient("0101-0019") is None # 불도저 19톤 — [주]① 보정 안 함
assert rock_coefficient("0602-0240") is None # 덤프 24톤 — [주]① 18톤 이상
assert rock_coefficient("0211-0060") is None # 굴착기(타이어) — 표에 없음
def test_암_공종의_대상_기계는_암석_호표를_부름() -> None:
book = cached_build(dump_haul_m=HAUL).book
assert "X-0201-0070#암석" in _machines(book, "B-FP-10-12-02#적재")
assert "X-0602-0150#암석" in _machines(book, "B-FP-10-12-02#L164.23m")
assert "X-0602-0150#암석" in _machines(book, "B-FP-10-12-03#L164.23m")
assert "X-0201-0070#암석" in _machines(book, "B-FP-09-04-02") # 암절취 집토
assert "X-0201-0070#암석" in _machines(book, "B-FP-09-19-02") # 비탈면 면고르기(암절취)
def test_토사_공종과_브레이커_조합_본체는_그대로() -> None:
book = cached_build(dump_haul_m=HAUL).book
assert _machines(book, "B-FP-10-12-01#적재") == {"X-0201-0070"}
assert "X-0602-0150" in _machines(book, "B-FP-10-12-01#L164.23m")
assert "X-0201-0070#조합" in _machines(book, "B-FP-09-04-01#연암")
assert not any(m.endswith("#암석") for m in _machines(book, "B-FP-09-19-01#절토면·풍화암"))
def test_불도저_19톤_발파암_운반은_보정_안_하고_까닭을_남김() -> None:
book = cached_build(dump_haul_m=HAUL).book
rows = [r for r in _rows(book, "B-FP-10-11#발파암") if r.ref_code == "X-0101-0019"]
assert rows and "8-1-7" in rows[0].note and "19톤" in rows[0].note, rows
def test_암석_호표_손료는_취득가_곱하기_보정_계수() -> None:
from B09_Estimation.B09_Estimation_MachineCost import load_machine_catalog
book = cached_build(dump_haul_m=HAUL).book
price = load_machine_catalog().machines["0201-0070"].price_thousand_krw * 1000
rock = book.resolve("X-0201-0070#암석").expense
plain = book.resolve("X-0201-0070").expense
assert rock == (price * Decimal("0.0002405")).quantize(Decimal(1), rounding=ROUND_FLOOR)
assert plain == (price * Decimal("0.0002085")).quantize(Decimal(1), rounding=ROUND_FLOOR)
assert book.resolve("X-0201-0070#암석").labor == book.resolve("X-0201-0070").labor