feat(814-1 3·4·6·7·8·9·10): 불러오기 결정 반영 — 세 줄 묶기 · 꼬리 뗀 맞대기 · 유가 · 재료 · 까닭 · 가벼움

- 3 연결 찾기 = 엑셀 이름 규격 · 단위 꼬리 뗀 이름으로 맞댐(`M02_Doc_Match_Note.bare` · 보이는 이름 그대로) · STmate 블록 규격도 가져온 칸에
- 4 기계 세 줄 = 기계 한 줄 — STmate X 코드 노 · 재 · 경 세 참조 줄(같은 수량 · 번지) 묶음(묶어서 셈 못 하는 세 줄만 그대로) ·
  문서 단계 묶기 넓힘(차례 아무렇게 · 시간당 경비 이음 없으면 엑셀 값 묶음 · 번지 같을 때) · 조합 다음 줄 = 세 줄 뒤 · 같은 기계 한 항목
- 6 공구손료 율 비목 차이(재료비 ↔ 경비) = 참고(`M02_Doc_Match_Value.tool_cost`) — 확정 안 막음
- 7 못 이은 줄 까닭(`M02_San_Link.why` — 자재 없음 · 운임표 없음 · 기계 표에 없음 · 별칭 대기 · 후보 여럿 · 시간당 경비 없음 · 조합) =
  문서 설명 · 이음 없는 자원 띠 · 연결 「없음」 띠 = 「우리 기초 없음 — 우리 정보로 셈 n/m 줄」 · 형제만 = 「조합」
- 8 유가 = 전국평균 줄 + 지역 옵션(`MO:경유:{S_지역}`) · 전력 = 일반용(갑)Ⅰ 저압 + 계약종별 옵션 · 엑셀 값 = 검산 칸
- 9 재료 = 지역 꼬리 뗀 이름 · 규격 정확 일치면 이음(지역 여럿 = 줄 지역 › 서울)
- 10 조합 첫 줄 규격 = 그 기계 · 얼린 줄도 소계 식에(북부청임도 33) · 기계 줄 찾기 판정 늘 붙음 · 올린 직후 409(HP 보이기 전 산근 보관) ·
  엑셀 블록 「엑셀 읽기 확정」 글 · 전수 도우미 str() 뗌 · 줄 쌓기 이름에 규격이 들면 한 번만
- M02_San_Link 새 파일(San_Emit 700 줄 막음 — 요소 잇기 · 시간당 · 조합 · 까닭)
- 시험: 새 test_814_1 · 812-2 · 810-4 거푸집 41 = 근접 → 확정(공구손료 비목 = 값 · 요구 744 C1) · 바꾸기 거절 견본 = 19 ·
  812-9 조합 첫 줄 규격 「0.7+브레이카」 → 「0.7」(칩 글 · 요구 738 흠 12)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-10 14:47:08 +09:00
co-authored by Claude Opus 5.5
parent 8914b21bad
commit bed35e3bc3
26 changed files with 786 additions and 127 deletions
+23 -6
View File
@@ -299,7 +299,7 @@ class Block:
self.got["확정"] += bool(got)
self.register(ln, f"줄.'{name}'")
def triple(self, rows: list[dict], total: dict | None) -> None:
def triple(self, rows: list[dict], total: dict | None, back: int = 0) -> None:
"""기계 · 산근 · 견적 세 줄 → 로직 값묶음 한 줄(수량 식 · 자리 같을 때) · 아니면 줄마다."""
got = [self.money(ln) for ln in rows]
parts = [ln["비목"] for ln in rows]
@@ -307,8 +307,8 @@ class Block:
if not same:
for ln, g in zip(rows, got):
self.machine_line(ln, g)
if total:
self.subtotal(total, [call for _, call, _ in self.done[-len(rows) :]])
if total: # 소계 = 세 줄 + 바로 앞 같은 기계 낱 줄(`back`)
self.subtotal(total, [call for _, call, _ in self.done[-(len(rows) + back) :]])
return
qty, place = got[0]
prices = {ln["비목"]: (ln.get("연결단가") or [0])[0] for ln in rows}
@@ -325,8 +325,10 @@ class Block:
title = head.get("품명") or r.get("원이름") or r.get("이름") or "줄"
name = self.o.names.item(title)
one = {"이름": name, "규격": r.get("규격") or "", "단위": r.get("단위") or "", "수량": qty}
link = em.hourly_text(parts[0]["키"]) if parts else None
one |= {"종류": "로직", "값묶음": em.bundle(r), "이음": link, "자원": r}
one |= {"종류": "로직", "값묶음": em.bundle(r), "이음": None, "자원": r}
em.first_spec(one, parts)
if parts: # 814-1 조합(굴착기 + 브레이커 · 집게) = 우리 조합 식 한 줄
one["이음"] = em.combo_link(one, parts) or em.hourly_text(parts[0]["키"])
one |= {"자리": place} if place else {}
value = total["결과"][-1] if total and total.get("결과") else None
for ln in rows: # 노 · 재 · 경 글 = 펼침(맞댈 값은 한 줄 계 — 소계 글 · 없으면 첫 줄)
@@ -362,6 +364,7 @@ class Block:
r |= {"찾기": parts[0]} if parts else {}
r |= {"조합첫": True} if len(parts) > 1 else {}
one = em.resource(name, r.get("단위"), qty, r, parts[0]["키"] if parts else None)
em.first_spec(one, parts)
one |= {"자리": place} if place else {}
self.o.add_line(one, True, ln["행"], ln.get("보임") or "", ln["결과"][-1])
self.got["확정"] += bool(got)
@@ -548,8 +551,22 @@ class Block:
rows.append(lines[i + len(rows)])
nxt = lines[i + len(rows)] if i + len(rows) < len(lines) else None
total = nxt if nxt and nxt.get("연결") == link and nxt.get("비목") == "T" else None
back, seen = (
0,
{r.get("비목") for r in rows},
) # 바로 앞 같은 기계 낱 줄(얼린 줄 · 814-1)
while i - back > 0 and len(seen) < 3:
b = lines[i - back - 1]
if (
(b.get("자원") or {}).get("코드") != code
or b.get("비목") in seen
or not b.get("결과")
):
break
seen.add(b.get("비목"))
back += 1
if all(r.get("결과") for r in rows):
self.triple(rows, total)
self.triple(rows, total, back)
else:
for r in rows:
self.mark(r, "결과 없는 세 줄")