feat(b08): 사토 운반에도 「덤프 적재」 짝 줄 · 사토 줄이 갈래를 실어 보냄 — 종전 갈래 미지정으로 덤프 잎을 못 고르던 것
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BW6Jdsh18WPtYUR6THZJqn
This commit is contained in:
@@ -23,6 +23,7 @@ from B08_Quantity.B08_Quantity_Engine_Handoff_Mapping import (
|
||||
ORIGIN_HAUL,
|
||||
WorkItemMapping,
|
||||
)
|
||||
from B08_Quantity.B08_Quantity_Engine_Handoff_Rows import LOADING_EQUIPMENT
|
||||
|
||||
SPOIL_NAME = "사토 운반"
|
||||
#: ⚠ **사토장 사면 물량은 안 센다**(2026-09-09 세 창 확인). 교본 6장 3절은 「완료 구간 비탈면을
|
||||
@@ -127,8 +128,33 @@ def spoil_haul_rows(
|
||||
extra=GROUND_UNKNOWN,
|
||||
)
|
||||
)
|
||||
return rows
|
||||
return [_spoil_row(code, volume, distance, blocked, reason, note, None, GROUND_UNKNOWN)]
|
||||
return _with_loading(rows)
|
||||
return _with_loading(
|
||||
[_spoil_row(code, volume, distance, blocked, reason, note, None, GROUND_UNKNOWN)]
|
||||
)
|
||||
|
||||
|
||||
def _with_loading(rows: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||
"""사토도 싣는 일이 따로 — 흙깎기 운반과 같은 「덤프 적재」 짝 줄(10-12 「1. 적재」).
|
||||
|
||||
내역에 서는 운반 줄에만 붙음 · 거리 무관 · 수량은 운반량 그대로(2026-09-14 브레인 판정).
|
||||
운반토량 검산은 `dump_loading` 을 빼므로 두 번 안 셈.
|
||||
"""
|
||||
out: list[dict[str, Any]] = []
|
||||
for row in rows:
|
||||
out.append(row)
|
||||
if row["in_bill"]:
|
||||
out.append(
|
||||
{
|
||||
**row,
|
||||
"name": "덤프 적재",
|
||||
"spec": row["ground_class"] or "",
|
||||
"haul_distance_m": None,
|
||||
"haul_equipment": LOADING_EQUIPMENT,
|
||||
"spec_detail": f"{row['spec_detail']} · 사토량만큼 싣기(10-12 「1. 적재」)",
|
||||
}
|
||||
)
|
||||
return out
|
||||
|
||||
|
||||
def _spoil_row(
|
||||
@@ -165,8 +191,10 @@ def _spoil_row(
|
||||
"structure_kind": None,
|
||||
"blocked_kind": BLOCKED_INPUT_MISSING if blocked else None,
|
||||
"blocked_reason": reason,
|
||||
"variant_axis": None,
|
||||
"variant_value": None,
|
||||
# 갈래는 `variant_value` 한 통로로 — 덤프 운반·적재 단가가 토사·암으로 갈림
|
||||
# (종전 None 이라 B09 가 10-12 잎을 못 골라 사토 운반이 「갈래 미지정」으로 막힘).
|
||||
"variant_axis": "ground_class" if ground else None,
|
||||
"variant_value": ground,
|
||||
"secondary_axes": None,
|
||||
"spec_class": None,
|
||||
"spec_class_basis": "",
|
||||
|
||||
@@ -167,6 +167,37 @@ def test_사토도_자연상태로_선다() -> None:
|
||||
assert "자연상태" in rows[0]["spec_detail"]
|
||||
|
||||
|
||||
def test_사토에도_적재_짝_줄이_서고_단가가_선다() -> None:
|
||||
"""사토도 싣는 일이 따로(10-12 「1. 적재」) — 내역에 서는 운반 줄에만 붙고, 검산엔 안 셈."""
|
||||
from B09_Estimation.B09_Estimation_BillOfQuantities import build_bill
|
||||
from B09_Estimation.B09_Estimation_MachineProductivity_Dump import dump_haul_distances
|
||||
from B09_Estimation.B09_Estimation_UnitPrice import cached_build
|
||||
|
||||
payload = build_handoff(
|
||||
haul_table={
|
||||
"rows": [],
|
||||
"spoil": {
|
||||
"volume_m3": 100.0,
|
||||
"distance_m": 800.0,
|
||||
"by_ground_m3": {"ea_m3": 70.0},
|
||||
"ground_unknown_m3": 30.0,
|
||||
},
|
||||
}
|
||||
)
|
||||
rows = payload["work_items"]
|
||||
loads = [row for row in rows if row["name"] == "덤프 적재"]
|
||||
assert [(row["variant_value"], row["quantity"]) for row in loads] == [("토사", 70.0)]
|
||||
assert loads[0]["haul_distance_m"] is None and loads[0]["haul_equipment"] == "dump_loading"
|
||||
# 갈래 못 붙인 몫은 막힌 줄이라 짝 줄이 없음
|
||||
assert len([row for row in rows if row["name"] == "사토 운반"]) == 2
|
||||
|
||||
bill = build_bill(payload, build=cached_build(dump_haul_m=dump_haul_distances(payload)))
|
||||
got = {row.name: row for row in bill.rows if row.name in ("사토 운반", "덤프 적재")}
|
||||
assert got["사토 운반"].price_code.startswith("B-FP-10-12-01#L800")
|
||||
assert got["덤프 적재"].price_code == "B-FP-10-12-01#적재"
|
||||
assert got["사토 운반"].amount_krw > 0 and got["덤프 적재"].amount_krw > 0
|
||||
|
||||
|
||||
def test_되돌린_값이_없으면_다짐_그대로_두고_사유() -> None:
|
||||
rows = 줄들(volume_m3=61.88, distance_m=800.0, by_ground_m3={"rr_m3": 61.88})
|
||||
assert rows[0]["quantity"] == 61.88
|
||||
|
||||
Reference in New Issue
Block a user