Files
Aislo/common_util/common_util_pum_edition.py
T
eomsangdonandClaude Opus 5 66d57bb630 feat(axis): 품셈 판 pum_edition 칸 — 자원·공종 쪽, 판이 다르면 값을 안 씀
공종 마스터·자원 축 줄·B08 인계 줄마다 공종 코드가 본 판을 실음(명세 17장 규칙 3).
판이 다른 인계 줄은 내역서에서 「확인 대기」로 빠지고, 코드에 박힌 절 번호(합산 단계·표 형태 판정·가드 목록)는
마스터 판과 다르면 마스터 빌드·단가 조립을 멈춤(규칙 4). 판 기준은 common_util_pum_edition 한 곳.

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

44 lines
2.4 KiB
Python

"""품셈 판(`pum_edition`) — `FP-*` 참조가 **어느 판을 보고 적혔나** (명세 17장 규칙 3·4).
`FP-*` 는 절 번호라 **판 안에서만 유일**하다. 판이 바뀌면 같은 번호가 다른 공종일 수 있다.
공종 마스터 `effective_date` = 그 판
자원 축 줄 · 인계 줄 `pum_edition` 칸 — 그 줄이 본 판
코드에 박힌 절 번호 `CODE_PUM_EDITION` 한 곳 — 합산 단계·표 형태 판정·표 읽기 선언·가드 목록
⛔ 판이 다르면 **값을 쓰지 않는다** — 줄은 「확인 대기」로 세우고, 코드에 박힌 선언은 조립을 멈춘다.
조용히 이웃 절에 붙으면 품이 통째로 달라진다(규칙 4). 판을 넘어 잇는 것은 대응표 몫이다.
⚠ 라이브러리 항목의 `pum_edition` 은 랩탑 서브가 붙였다(구조물도 양식).
"""
from __future__ import annotations
#: 코드 안에 박힌 `FP-*` 가 본 판 — 산림사업 표준품셈(산림청고시 제2025-82호, 2026-01-01 시행).
#: ⚠ 판을 올리는 날 이 값만 바꾸지 말 것 — 박힌 선언을 대응표로 옮긴 **뒤에** 바꿀 것.
CODE_PUM_EDITION = "2026-01-01"
class PumEditionError(RuntimeError):
"""코드에 박힌 절 번호의 판과 공종 마스터의 판이 다를 때. 값을 쓰지 않고 멈춘다."""
def require_code_edition(master_edition: str, where: str) -> None:
"""코드에 박힌 선언을 쓰기 전에 부른다 — 판이 다르면 멈춘다."""
if str(master_edition) != CODE_PUM_EDITION:
raise PumEditionError(
f"{where}: 코드에 박힌 절 번호는 {CODE_PUM_EDITION} 판을 보고 적혔는데 공종 마스터는 "
f"{master_edition or '(판 없음)'} 판입니다 — 판 대응표로 옮기기 전에는 쓰지 않습니다 "
"(명세 17장 규칙 4)"
)
def edition_waiting_reason(row_edition: str | None, master_edition: str) -> str:
"""판이 다른 줄의 「확인 대기」 사유. 어느 한쪽이 판을 안 적었거나 같으면 빈 글."""
if not row_edition or not master_edition or str(row_edition) == str(master_edition):
return ""
return (
f"품셈 판 확인 대기 — 이 줄의 공종 코드는 {row_edition} 판,"
f" 공종 마스터는 {master_edition} 판 · 절 번호가 같아도"
" 같은 공종이라는 보장이 없어 값을 안 씀(명세 17장)"
)