fix(B08): 개소 구조물이 인계에 연장(m)으로 나가던 것
㉕ 타설 줄 실증 중에 드러남. 관측 원단위가 「개소당」인 종류(집수정 셋)를 인계 줄이 늘 「m · 연장」으로 내보내고 있었음. - 연장 2m 짜리 집수정이 「2.000 m」로 나가 값이 두 배로 실림 - 성분은 개소 기준으로 맞게 서는데 줄의 축만 어긋나 아무 시험도 안 잡았음 - billing_of() 로 관측표가 정한 단위·개수를 꺼내 전개 결과에 실음 - 인계 줄이 그 단위를 따름. 비어 있으면 종전대로 「m · 연장」 시험 셋 — 개소로 서는 것 · 연장이 길어도 한 개소 · ⚠ 정상 「m」 줄은 그대로일 것(좁게 고치는 짝 시험). 곁들여 타설 줄 실증: 옹벽 H=2.0(20m) + 집수정 Ø800 으로 돌리면 FP-12-01-01#철근구조물 32.840㎥ 가 인계에 섬(옹벽 27+3 · 집수정 2.84). 시험: 677 passed · 24 skipped (B05 코리도 1건 기존 깨짐, 무관). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -643,13 +643,22 @@ def _structure_rows(
|
||||
elif entry.get("class_from") in ("back_length", "bond") and class_key is None:
|
||||
unmatched.append(f"{wording_type_label(type_id)} — {class_basis}")
|
||||
length = float(structure.get("length_m") or 0.0)
|
||||
# ⚠ 관측 원단위가 「개소당」·「㎡당」인 종류는 **연장으로 세면 축이 어긋난다** —
|
||||
# 집수정 한 개소가 연장 2m 면 값이 두 배로 실린다(2026-09-08 ㉕ 실증).
|
||||
# 성분은 개소 기준으로 맞게 서는데 **줄의 축만** 틀렸던 자리다.
|
||||
bill_unit = str(structure.get("billing_unit") or "") or "m"
|
||||
bill_quantity = (
|
||||
float(structure.get("billing_quantity") or 0.0)
|
||||
if structure.get("billing_unit")
|
||||
else length
|
||||
)
|
||||
rows.append(
|
||||
{
|
||||
"work_item_code": code,
|
||||
"name": str(structure.get("name") or type_id),
|
||||
"spec": _spec_detail(structure),
|
||||
"unit": "m",
|
||||
"quantity": length,
|
||||
"unit": bill_unit,
|
||||
"quantity": bill_quantity,
|
||||
"quantity_gross": None,
|
||||
"application_ratio_pct": None,
|
||||
"application_ratio_breakdown": None,
|
||||
|
||||
@@ -131,6 +131,26 @@ def scale_for(entry: dict[str, Any], structure: dict[str, Any]) -> tuple[float,
|
||||
return 1.0, "1 개소"
|
||||
|
||||
|
||||
def billing_of(
|
||||
type_id: str,
|
||||
spec: dict[str, Any],
|
||||
structure: dict[str, Any],
|
||||
table: ObservedUnitTable | None = None,
|
||||
) -> tuple[str, float] | None:
|
||||
"""(내역 단위, 그 단위로 센 수량). 표에 없으면 `None`.
|
||||
|
||||
⚠ **왜 있나** — 관측 원단위는 「개소당」·「㎡당」으로도 온다. 그런데 인계 줄이 늘
|
||||
「m · 연장」으로 나가고 있어, **집수정 한 개소가 「연장 2m」면 값이 두 배로 실렸다**
|
||||
(2026-09-08 ㉕ 실증에서 드러남). 성분은 개소 기준으로 맞게 서는데 **줄의 축만
|
||||
어긋나** 있어서 아무 시험도 안 잡았다.
|
||||
"""
|
||||
found = (table or load_observed_table()).find(type_id, spec)
|
||||
if found is None:
|
||||
return None
|
||||
scale, _note = scale_for(found, structure)
|
||||
return str(found.get("unit") or "개소"), scale
|
||||
|
||||
|
||||
def expand_observed(
|
||||
type_id: str,
|
||||
spec: dict[str, Any],
|
||||
|
||||
@@ -38,6 +38,7 @@ from B08_Quantity.B08_Quantity_Engine_ObservedUnit import (
|
||||
BASIS_DERIVED,
|
||||
BASIS_OBSERVED,
|
||||
ObservedUnitTable,
|
||||
billing_of,
|
||||
expand_observed,
|
||||
load_observed_table,
|
||||
)
|
||||
@@ -139,6 +140,11 @@ class StructureQuantity:
|
||||
options: dict[str, Any] = field(default_factory=dict)
|
||||
components: list[Component] = field(default_factory=list)
|
||||
notes: list[str] = field(default_factory=list)
|
||||
#: 내역 줄이 설 **단위와 그 단위로 센 수량**. 관측 원단위가 「개소당」·「㎡당」인
|
||||
#: 종류는 연장(m)으로 세면 축이 어긋난다(2026-09-08 ㉕ 실증).
|
||||
#: 비어 있으면 종전대로 「m · 연장」으로 선다.
|
||||
billing_unit: str = ""
|
||||
billing_quantity: float = 0.0
|
||||
|
||||
|
||||
#: ⚠ **저장 제원의 실제 칸 이름**은 `back_len_cm` 이다(레지스트리 확인).
|
||||
@@ -499,6 +505,22 @@ def _observed_components(
|
||||
return expand_observed(type_id, spec, structure, observed)
|
||||
|
||||
|
||||
def _observed_billing(
|
||||
type_id: str,
|
||||
structure: dict[str, Any],
|
||||
observed: ObservedUnitTable | None,
|
||||
) -> tuple[str, float] | None:
|
||||
"""관측표가 정한 **내역 단위와 개수**. 규격 키가 없는 종류는 건드리지 않는다."""
|
||||
keys = OBSERVED_SPEC_KEYS.get(type_id)
|
||||
if keys is None:
|
||||
return None
|
||||
options = structure.get("options") or {}
|
||||
spec = {key: options[key] for key in keys if options.get(key) is not None}
|
||||
if not spec:
|
||||
return None
|
||||
return billing_of(type_id, spec, structure, observed)
|
||||
|
||||
|
||||
def expand(
|
||||
structure: dict[str, Any],
|
||||
names: dict[str, str] | None = None,
|
||||
@@ -538,6 +560,9 @@ def expand(
|
||||
if components or notes:
|
||||
result.components = [Component(**item) for item in components]
|
||||
result.notes.extend(notes)
|
||||
billing = _observed_billing(type_id, structure, observed)
|
||||
if billing is not None:
|
||||
result.billing_unit, result.billing_quantity = billing
|
||||
return result
|
||||
from B08_Quantity.B08_Quantity_Wording import type_label
|
||||
|
||||
@@ -601,6 +626,9 @@ def build_table(
|
||||
"height_m": item.height_m,
|
||||
"start_m": item.start_m,
|
||||
"end_m": item.end_m,
|
||||
# 내역 줄이 설 단위·수량 — 관측 원단위가 「개소당」인 종류는 연장으로 못 센다.
|
||||
"billing_unit": item.billing_unit,
|
||||
"billing_quantity": item.billing_quantity,
|
||||
# 저장된 제원 — 형식(반중력식…)처럼 **뒤 단계가 읽어야 하는** 값이 여기 있다.
|
||||
"options": item.options,
|
||||
"notes": item.notes,
|
||||
|
||||
Reference in New Issue
Block a user