feat(b09): 연결고리 표를 읽는 한 자리 — 산림·건설 어느 품을 쓸지 표가 정함(고시 총칙 7 · 표 policy both_precedence) · B09 인계 입구에서 둘 다 있는 공종은 표가 고른 열쇠·목차 코드로 · 미판정은 안 고르고 막음(link_undecided · 사유 그대로 · 금액에 안 듦) · 열쇠 빈 미판정 행도 내역서 요약에 목록 · 지금 인계 코드 57 판정 안 달라짐 = 금액 불변 · Z01 목록에 줄 구실(총칙) 표시 칸(코덱스 크로스체크 ①② · 브레인)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BW6Jdsh18WPtYUR6THZJqn
This commit is contained in:
@@ -14,7 +14,11 @@ from dataclasses import dataclass
|
||||
from decimal import Decimal
|
||||
from typing import Any
|
||||
|
||||
from common_util.common_util_work_item_key import work_item_key
|
||||
from common_util.common_util_work_item_key import work_item_code_of, work_item_key
|
||||
from common_util.common_util_work_item_link import choose
|
||||
|
||||
#: 연결고리 표 미판정 — 산림·건설 어느 품을 쓸지 근거가 없어 **안 고른** 줄(금액에 안 듦).
|
||||
BLOCKED_LINK_UNDECIDED = "link_undecided"
|
||||
|
||||
_ZERO = Decimal(0)
|
||||
|
||||
@@ -121,6 +125,23 @@ def _decimal(value: Any, default: Decimal | None = _ZERO) -> Decimal | None:
|
||||
return Decimal(str(value))
|
||||
|
||||
|
||||
def _linked(row: dict[str, Any]) -> dict[str, Any]:
|
||||
"""열쇠 길목 + **연결고리 표** — 산림·건설 어느 품을 쓸지 표가 정함(고시 총칙 7 · 표 `policy`).
|
||||
|
||||
둘 다 있는 공종이면 표가 적은 우선 품셈 열쇠·목차 코드로 바꿈 · 미판정이면 막음(사유 그대로).
|
||||
⚠ 이미 B08 이 막아 보낸 줄은 그 까닭을 덮지 않음.
|
||||
"""
|
||||
edition = row.get("pum_edition") or None
|
||||
key = row.get("work_item_key") or work_item_key(row.get("work_item_code"), edition)
|
||||
choice = choose(key)
|
||||
out = {"work_item_key": key or "", "work_item_code": row.get("work_item_code")}
|
||||
if choice.blocked and not row.get("blocked_reason"):
|
||||
out.update(blocked_reason=choice.blocked, blocked_kind=BLOCKED_LINK_UNDECIDED)
|
||||
elif choice.key and choice.key != key:
|
||||
out.update(work_item_key=choice.key, work_item_code=work_item_code_of(choice.key, edition))
|
||||
return out
|
||||
|
||||
|
||||
def parse_handoff(payload: dict[str, Any]) -> tuple[list[HandoffWorkItem], list[HandoffMaterial]]:
|
||||
"""인계 응답을 우리 자료형으로 옮긴다. **모르는 칸을 채우지 않는다.**"""
|
||||
if "work_items" not in payload or "materials" not in payload:
|
||||
@@ -128,7 +149,7 @@ def parse_handoff(payload: dict[str, Any]) -> tuple[list[HandoffWorkItem], list[
|
||||
|
||||
work_items = [
|
||||
HandoffWorkItem(
|
||||
work_item_code=row.get("work_item_code"),
|
||||
work_item_code=linked["work_item_code"],
|
||||
name=row.get("name", ""),
|
||||
spec=row.get("spec") or "",
|
||||
unit=row.get("unit") or "",
|
||||
@@ -147,19 +168,18 @@ def parse_handoff(payload: dict[str, Any]) -> tuple[list[HandoffWorkItem], list[
|
||||
composite_parts=tuple(row.get("composite_parts") or ()),
|
||||
composite_not_ready=tuple(row.get("composite_not_ready") or ()),
|
||||
structure_kind=row.get("structure_kind") or "",
|
||||
blocked_reason=row.get("blocked_reason") or "",
|
||||
blocked_kind=row.get("blocked_kind") or "",
|
||||
blocked_reason=row.get("blocked_reason") or linked.get("blocked_reason") or "",
|
||||
blocked_kind=row.get("blocked_kind") or linked.get("blocked_kind") or "",
|
||||
variant_axis=row.get("variant_axis") or "",
|
||||
variant_value=str(row.get("variant_value") or ""),
|
||||
spec_class=row.get("spec_class") or "",
|
||||
spec_class_basis=row.get("spec_class_basis") or "",
|
||||
pum_edition=str(row.get("pum_edition") or ""),
|
||||
# 옛 인계(열쇠 없음)도 같은 길목으로 채움
|
||||
work_item_key=row.get("work_item_key")
|
||||
or work_item_key(row.get("work_item_code"), row.get("pum_edition") or None)
|
||||
or "",
|
||||
# 옛 인계(열쇠 없음)도 같은 길목으로 채움 · 연결고리 표가 고른 열쇠
|
||||
work_item_key=linked["work_item_key"],
|
||||
)
|
||||
for row in payload["work_items"]
|
||||
for linked in (_linked(row),)
|
||||
]
|
||||
materials = [
|
||||
HandoffMaterial(
|
||||
|
||||
Reference in New Issue
Block a user