Merge remote-tracking branch 'origin/dev' into sub_laptop_1

This commit is contained in:
2026-09-14 09:21:31 +09:00
3 changed files with 26 additions and 4 deletions
@@ -207,6 +207,7 @@ def attach_dump_hauls(build: Any, master: dict[str, Any], distances_m: tuple[Dec
f"×{_LOADING_E0[code]}/22 = {output}㎥/hr · {_LOADING_NOTES[code]}",
output=output,
)
build.formula_variants[title_code] = "산림품셈 10-12 「1. 적재」 본문 식"
if not distances_m:
return
hourly = f"X-{DUMP_TRUCK_CODE}"
@@ -236,6 +237,7 @@ def attach_dump_hauls(build: Any, master: dict[str, Any], distances_m: tuple[Dec
haul.formula_text + " · " + " · ".join(material.notes),
output=haul.hourly_output,
)
build.formula_variants[title_code] = "산림품셈 10-12 「2. 운반」 본문 식 · 운반거리"
def dump_haul_distances(payload: dict[str, Any]) -> tuple[str, ...]:
@@ -141,6 +141,10 @@ class UnitPriceBuild:
parent_modes: dict[str, str] = field(default_factory=dict)
#: 합산형 부모 → (갈래, 근거) — 내역 줄의 갈래가 표에 없을 때 **원문이 정한** 갈래(9-4-1 [주]① 평균).
default_variants: dict[str, tuple[str, str]] = field(default_factory=dict)
#: 갈래가 **어디서 왔나** — 표가 아니라 **식이 낸** 갈래 제목 → 그 식(2026-09-14 브레인 판정).
#: 표에서 온 갈래는 마스터 갈래 키에 있어야 하고(짝 시험), 식이 낸 갈래는 여기 적혀 있어야 함
#: (덤프 운반·적재 10-12 `#L…m`·`#적재` — 본문 식이라 마스터 표에 갈래가 없음).
formula_variants: dict[str, str] = field(default_factory=dict)
def _add_labor_titles(book: PriceBook, wages: dict[str, Decimal]) -> None:
@@ -18,14 +18,18 @@ def _nodes() -> dict[str, dict]:
def test_단가표_갈래_제목은_전부_마스터_갈래_키에_있다() -> None:
"""갈래를 **어디서 왔나**로 가름(2026-09-14 브레인 판정) — 표에서 온 갈래만 마스터에 있어야 함.
식이 낸 갈래(덤프 운반·적재 10-12)는 마스터가 낼 수 없어 검사 대상이 아니되
`formula_variants` 에 「식이 냈다」가 적혀 있어야 함(아래 짝 시험).
"""
nodes = _nodes()
missing = []
for code in cached_build().book.titles:
build = cached_build(dump_haul_m=("164.23",))
for code in build.book.titles:
if not code.startswith("B-") or "#" not in code:
continue
if code.startswith("B-FP-10-12-"):
# 덤프 운반·적재(10-12)는 **표가 아니라 본문 식**이라 마스터 표에 갈래가 없음 —
# 갈래(`#적재`·`#L…m`)는 식이 냄(2026-09-14 · `MachineProductivity_Dump`).
if code in build.formula_variants:
continue
work_item, variant = code[2:].split("#", 1)
keys = {
@@ -36,6 +40,18 @@ def test_단가표_갈래_제목은_전부_마스터_갈래_키에_있다() -> N
assert not missing, f"마스터를 다시 뽑을 것(B08_Quantity_Build_WorkItemMaster): {missing[:5]}"
def test_식이_낸_갈래는_출처가_적히고_마스터엔_없다() -> None:
build = cached_build(dump_haul_m=("164.23",))
formula = build.formula_variants
assert "B-FP-10-12-01#적재" in formula and "B-FP-10-12-02#L164.23m" in formula
assert all(code in build.book.titles and why for code, why in formula.items())
nodes = _nodes()
for code in formula:
work_item, variant = code[2:].split("#", 1)
keys = {normalize_variant_key(k) for k in nodes[work_item].get("variant_keys") or []}
assert variant not in keys # 마스터에 있으면 「표에서 옴」이라 여기 적을 까닭이 없음
def test_표_모양대로_갈래를_가르고_못_가르면_빈칸() -> None:
nodes = _nodes()
felling = nodes["FP-04-02-02"]["tables"][0]["variant_key"]