feat(b08): 덤프 운반마다 「덤프 적재」 짝 줄 — 10-12 「1. 적재」 · 거리 무관 · 수량은 운반량 그대로

- _haul_rows 한 곳: dump_truck 내역 줄 뒤에 haul_equipment dump_loading 짝 줄(갈래·수량 같음)
- 흙깎기 9-3-2(㎝ 20초·135°)에 싣기가 안 들어 있어 운반과 한 벌로 냄(브레인 판정)
- B09 운반토량 검산(운반 ≤ 절취)에서 적재 줄은 뺌 — 같은 흙을 두 번 세지 않게
- 시험 기대값: 운반표 줄 4 → 6(적재 둘) · 내역 줄 3 → 5 · 전체 1763 통과

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BW6Jdsh18WPtYUR6THZJqn
This commit is contained in:
2026-09-14 08:57:24 +09:00
co-authored by Claude Opus 5
parent a2b3ae698f
commit a440b4f919
3 changed files with 38 additions and 4 deletions
@@ -288,9 +288,28 @@ def _haul_rows(
"origin": ORIGIN_HAUL,
}
)
if equipment == "dump_truck" and in_bill:
# 덤프 운반은 **싣는 일이 따로** — 산림품셈 10-12 「1. 적재」
# (굴착기 0.7㎥ · ㎝ 22초·180°).
# 흙깎기 9-3-2(㎝ 20초·135°, 깎아 옆에 둠)에 안 들어 있어 운반과 한 벌로 짝 줄을 냄
# (2026-09-14 브레인 판정). 거리와 무관 · 수량은 운반량 그대로.
rows.append(
{
**rows[-1],
"name": "덤프 적재",
"haul_distance_m": None,
"haul_equipment": LOADING_EQUIPMENT,
"spec_detail": f"{state_note} · 덤프 운반량만큼 싣기(10-12 「1. 적재」)",
}
)
return rows, unmatched
#: 인계 「덤프 적재」 짝 줄의 수단 표지 —
#: B09 `MachineProductivity_Dump.LOADING_EQUIPMENT` 와 같은 글.
LOADING_EQUIPMENT = "dump_loading"
def blocked_of(
structure: dict[str, Any], class_basis: str = "", has_code: bool = False
) -> tuple[str | None, str]:
@@ -628,7 +628,15 @@ def build_bill(
),
_ZERO,
)
haul_total = sum((item.quantity for item in work_items if item.haul_equipment), _ZERO)
# 「덤프 적재」 짝 줄은 운반이 아니라 싣기 — 같은 흙을 운반량으로 두 번 세지 않게 뺌.
haul_total = sum(
(
item.quantity
for item in work_items
if item.haul_equipment and item.haul_equipment != "dump_loading"
),
_ZERO,
)
if cut_total > 0 and haul_total > 0:
check_haul_volume_within_cut(
haul_volume_total_m3=haul_total,
+10 -3
View File
@@ -188,6 +188,11 @@ def test_무대는_넘기되_내역에는_안_섬() -> None:
assert dump["in_bill"] is True
assert dump["work_item_code"] == "FP-10-12"
assert dump["haul_distance_m"] == pytest.approx(1200.0)
# 2026-09-14 — 덤프 운반마다 「덤프 적재」 짝 줄(10-12 「1. 적재」) · 거리 없음 · 수량 같음
loading = (handoff, "덤프 적재")
assert loading["haul_equipment"] == "dump_loading" and loading["haul_distance_m"] is None
assert loading["quantity"] == dump["quantity"] and loading["variant_value"] == "토사"
assert not any(r["name"] == "덤프 적재" and r["spec"] != "토사" for r in handoff["work_items"])
def test_합계_줄은_내역에_안_섬() -> None:
@@ -600,9 +605,11 @@ def 운반표() -> dict:
def test_운반계획이_있으면_네_줄이_실림() -> None:
handoff = build_handoff(haul_table=운반표())
haul_rows = [row for row in handoff["work_items"] if row["origin"] == "haul"]
assert len(haul_rows) == 4
# 운반 넷 + 덤프 운반 둘의 적재 짝 줄 둘(2026-09-14 · 10-12 「1. 적재」 — 거리 없음)
moves = [row for row in haul_rows if row["haul_equipment"] != "dump_loading"]
assert len(moves) == 4 and len(haul_rows) == 6
assert all(row["haul_equipment"] for row in haul_rows)
assert all(row["haul_distance_m"] for row in haul_rows)
assert all(row["haul_distance_m"] for row in moves)
def test_무대가_함께_와야_운반_검산이_걸림() -> None:
@@ -612,7 +619,7 @@ def test_무대가_함께_와야_운반_검산이_걸림() -> None:
assert free["in_bill"] is False
assert free["quantity"] == pytest.approx(871.0)
assert handoff["excluded_row_count"] == 1
assert handoff["bill_row_count"] == 3
assert handoff["bill_row_count"] == 5 # 도자 · 덤프 운반 둘 · 덤프 적재 짝 줄 둘
def test_운반계획이_없으면_줄이_없음() -> None: