Files
Aislo/resources/tester/test_b09_design_doc_index.py
T
eomsangdonandClaude Opus 5 23f9656e91 feat(B09): 각종 중기경비계산서 — 기종마다 한 장
별표2 (5)(가) 아홉째. 중기목록표가 「얼마」라면 이 장은 「왜 그 값인가」임.
원가계산 → 중기 탭의 목록표 아래에 붙음.

- 기종마다 취득가·내용시간·손료계수(상각·정비·관리) → 시간당 손료 · 주연료와 유가 ·
  조종원 일당과 시간당 환산 · 시간당 사용료 3분할을 차례로 보임.
- 내역에 실제로 선 기종만 냄(카탈로그 613 을 다 뿌리지 않음).
- 부착 장비(브레이커·콤팩터·집게)는 손료만 드는 것이 정상이라 결함으로 안 셈
  — 제 엔진이 없어 연료·조종원이 본체에 듦(건설품셈 제8장 [주]⑤).
- 수송비는 이 장에 안 붙임 — 「회당」으로 서는 별개 공종이라 자리만 가리킴.
- 계산서 합계가 일위대가가 실제로 쓰는 값과 같은지 시험으로 못 박음(두 벌 방지).

⇒ 「설계서 구성」의 중기경비계산서가 반쪽 → 있음으로 바뀜(법이 정한 13 중 8 이 섬).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 23:45:54 +09:00

96 lines
3.5 KiB
Python

"""설계서 구성표 — 법이 정한 목차와 우리가 내는 것 (2026-09-09).
산림자원법 시행규칙 [별표2] (5)(가) 가 **설계서 작성 순서를 열셋으로 못 박아** 두었다.
그 목록과 우리 화면을 맞대 두지 않으면 「무엇을 못 내는가」가 계획서에만 남는다.
⚠ 겨누는 것 넷
① 법이 적은 **차례 그대로**다 — 순서를 우리가 바꾸지 않는다
② **「없음」과 「우리 몫 아님」을 가른다** — 시방서·예정공정표는 설계자가 쓰는 문서다
③ 「반쪽」은 반쪽이라 적는다 — 중기경비계산서·산출기초
④ 못 내는 것에는 **무엇을 받아야 내는지**가 적혀 있다
"""
from __future__ import annotations
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(ROOT))
from B09_Estimation.B09_Estimation_DesignDocIndex import ( # noqa: E402
DESIGN_DOC_ITEMS,
OWNER_DESIGNER,
OWNER_PROGRAM,
STATUS_MISSING,
STATUS_PARTIAL,
STATUS_READY,
design_doc_index,
)
#: 별표2 (5)(가) 원문 차례.
_LAW_ORDER = (
"목차",
"공사설명서",
"일반시방서",
"특별시방서",
"예정공정표",
"예산내역서",
"일위대가표",
"단가산출서",
"각종 중기경비계산서",
"공종별 수량계산서",
"각종 소요자재총괄표",
"토적표",
"산출기초",
)
def test_법이_적은_차례_그대로다() -> None:
assert tuple(item["name"] for item in DESIGN_DOC_ITEMS) == _LAW_ORDER
assert [item["order"] for item in DESIGN_DOC_ITEMS] == list(range(1, 14))
def test_설계자_몫과_우리_몫을_가른다() -> None:
"""② 「없음」 넷 가운데 셋은 **애초에 우리가 만들 것이 아니다.**"""
theirs = {item["name"] for item in DESIGN_DOC_ITEMS if item["owner"] == OWNER_DESIGNER}
assert theirs == {"일반시방서", "특별시방서", "예정공정표"}
for item in DESIGN_DOC_ITEMS:
if item["owner"] == OWNER_DESIGNER:
assert item["status"] == STATUS_MISSING
def test_반쪽은_반쪽이라_적는다() -> None:
"""⚠ 2026-09-09 밤 — 중기경비계산서를 세우면서 **반쪽이 하나 줄었다**(기종마다 한 장).
남은 반쪽은 산출기초 하나 — 근거 문구는 줄마다 있으나 한 장으로 묶는 자리가 없다.
"""
partial = {item["name"] for item in DESIGN_DOC_ITEMS if item["status"] == STATUS_PARTIAL}
assert partial == {"산출기초"}
def test_서는_것은_어디서_나오는지_적혀_있다() -> None:
for item in DESIGN_DOC_ITEMS:
if item["status"] == STATUS_READY:
assert item["where"], f"{item['name']}: 어느 화면인지 안 적혀 있음"
def test_못_내는_것에는_무엇이_필요한지_적혀_있다() -> None:
"""④ 「없음」으로만 두면 다음 사람이 무엇부터 해야 할지 모른다."""
for item in DESIGN_DOC_ITEMS:
if item["status"] != STATUS_READY:
assert item["note"].strip(), f"{item['name']}: 사유가 비어 있음"
def test_요약이_셈과_맞는다() -> None:
data = design_doc_index()
assert data["counts"][STATUS_READY] == 8
assert sum(data["counts"].values()) == len(DESIGN_DOC_ITEMS)
ours_missing = [
item["name"]
for item in DESIGN_DOC_ITEMS
if item["owner"] == OWNER_PROGRAM and item["status"] != STATUS_READY
]
for name in ours_missing:
assert name in data["summary"]