feat(B08): B군 줄에 「어디부터 어디까지」를 실음 — spans 받음

랩탑이 spans 를 넣어 줘서 B군 산출근거가 채워짐.
겹침을 지운 뒤의 구간이라 그 합이 곧 length_m 임.

- station_from/to 에 처음 시작·끝 끝을 싣고
- 비고에 구간을 전부 적음 「구간 10~20m · 50~60m · 90~100m」
  ⚠ 사이가 빈 것을 숨기지 않음 — 처음과 끝만 보면 10~100 을 통으로 오해함
- 겹친 경우는 그 설명이 뒤에 붙음
  「구간 80~140m · 입력 구간 합 80m 에서 겹친 20m 를 뺀 값」

⚠ 측점 표기(NO.4+0.0)는 만들지 않음 — 측점 간격을 아는 화면 몫이고,
  두 벌로 짜면 간격이 바뀔 때 한쪽만 고쳐짐

시험 넷 — 구간이 비고에 적히고 측점이 실림 · 여럿이면 처음·끝을 싣고 전부는 비고에 ·
⚠ 구간 합이 수량과 같음(갈리면 어딘가 틀림) · ⚠ spans 가 없어도 줄은 섬(옛 자료)

시험: 713 passed · 24 skipped (B05 코리도 1건 기존 깨짐, 무관).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-08 10:28:35 +09:00
co-authored by Claude Opus 5
parent 9b7dc0796b
commit dbe761a303
+15 -4
View File
@@ -941,9 +941,19 @@ def _length_rows(
code = (found or {}).get("work_item_code")
length = float(entry.get("length_m") or 0.0)
raw = float(entry.get("raw_length_m") or length)
note = ""
# 구간 목록 — **겹침을 지운 뒤**의 것이라 그 합이 곧 `length_m` 이다
# (80~120 과 100~140 은 80~140 한 줄로 합쳐져 온다, 2026-09-08 랩탑 창).
# ⚠ 표기(`NO.4+0.0`)는 만들지 않는다 — 측점 간격을 아는 화면 몫이다.
spans = [
span
for span in (entry.get("spans") or [])
if span.get("start_m") is not None and span.get("end_m") is not None
]
span_note = " · ".join(f"{s['start_m']:g}~{s['end_m']:g}m" for s in spans)
note = f"구간 {span_note}" if span_note else ""
if abs(raw - length) > 1e-9:
note = f"입력 구간 합 {raw:g}m 에서 겹친 {raw - length:g}m 를 뺀 값"
겹침 = f"입력 구간 합 {raw:g}m 에서 겹친 {raw - length:g}m 를 뺀 값"
note = f"{note} · {겹침}" if note else 겹침
# ⚠ 겹침 설명은 **비고**이지 막힌 사유가 아니다 — `blocked_reason` 에 넣으면
# 받는 쪽이 「막힌 줄」로 읽어 금액을 안 붙인다(2026-09-08 실측에서 그랬다).
reason = ""
@@ -965,8 +975,9 @@ def _length_rows(
"ground_class": None,
"haul_distance_m": None,
"haul_equipment": None,
"station_from": None,
"station_to": None,
# 여러 구간이면 **처음과 끝**만 싣는다 — 사이 구간은 비고에 다 적혀 있다.
"station_from": spans[0]["start_m"] if spans else None,
"station_to": spans[-1]["end_m"] if spans else None,
"excavation_method": None,
"spec_detail": f"{entry.get('count')}개소",
"composite_parts": None,