Files
Aislo/M02_MasterTemplete/M02_Hopyo_Make.py
T
eomsangdonandClaude Opus 5.5 c5067aa2b6 feat(809-1a): 일위대가 불러오기 = 경쟁사 로직 인정 · 요소만 연결 · [수정] 모달 = 일위대가 컨테이너 부품 · 기초 판정 걷음
- [수정] 모달 = Labor_Table(읽기 · 덧칸 표지 · 엑셀 금액) · 줄 = 로직(단가산출 · 일위대가) / 요소(연결됨 · 후보 · 못 이음) · 단가산출 줄 = 가져온 식 SK 수식 탭 모달(Labor_SkEdit) · 서버 hopyo-view(M02_Hopyo_View)
- 엑셀 보기 목록 · 칠 = 줄 표지(View.listing) · 단가산출 탭 = 블록 목록 + [가져온 식으로 열기] · [내 단가산출로]
- 걷음(요구 703): 판정 체계 785(Judge · Solve · Bind · San_Basis 다섯 · Make.Move · Row 1차 판정 · 화면 Check · CheckRows · Rows · Block · JudgeApi · Picks · Judge.css) · [우리 기초로 바꾸기](to-base) · 근거 기초 제안 · Clause 기초 판정
- 시험 지움: 642_2(Bind · Solve) · 642_3(Row 1차 판정) · 642_5(옮기기 Move) · 642_6(판정 화면) · 786_2(옛 [수정] 모달) · 793_3a(근거 → 기초 제안) — 모두 걷은 기초 판정 길 몫
- 시험 고침: 642_1 · 794_2a2 · 794_2b(근거 제안 부분만 뺌) · 793_2 · 793_3b(기초 바꾸기 기대 → 없음) · 627 · 779_2 · 785_4 · 807_1 · m02_hopyo_excel · grid · stmate(judge 길 → view 길)
- 새 시험 test_809_1_import_labor(기초 길 0 · 표지 1,350 줄 · 가져온 식 SK · 모달 = Labor_Table · 금액 = 엑셀)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 19:17:58 +09:00

123 lines
6.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""M02 일위대가 실무자료 → 우리 SC 줄 몸(PLAN 785-5 · 809-1) — `M02_Hopyo_Build.Builder` 가 줄 차례대로 부름.
`Lines.put` = 대상 하나(`{로직|자재|호표|전국|이음|참조, 입력값, 배, 몫}` · 붙여넣기 · 구조물 조합으로 길) →
우리 줄 · 자재(같은 로직 둘째 = 한 줄 SC 사본 · 재료 = 자재 목록 · 이음 = 고정 줄).
확인 안 한 줄 = Builder 가 고정 길(`Fixed.line_of`)로. 옛 판정 고른 것 · [옮기기](785-5 `Move`)는 809-1 에서 지움 —
불러오기 옮기기 = [내 일위대가로](`Build.build_all only` · 경쟁사 로직 인정 · 요구 703).
"""
from __future__ import annotations
from decimal import Decimal
from typing import Any
from M02_MasterTemplete import M02_Hopyo_Build as hbuild
from M02_MasterTemplete import M02_Hopyo_Fixed as hfix
from M02_MasterTemplete import M02_Hopyo_Kids as hkids
from M02_MasterTemplete import M02_Hopyo_Material as hmat
from M02_MasterTemplete import M02_Hopyo_Sangeun as sangeun
from M02_MasterTemplete import M02_Labor_Doc as labor
from M02_MasterTemplete import M02_Labor_Ref as refs
def _num(value: Decimal) -> int | float:
return hbuild._num(value)
# ── 확인한 줄 몸(SC) ─────────────────────────────────────────────────────
class Lines:
"""한 호표 줄 모음 — `Builder.build` 가 줄 차례대로 부름 · 확인 안 한 줄은 Builder 가 고정 길로."""
def __init__(self, b: Any, rows: list[dict], where: dict, stamp: str, linker: Any) -> None:
self.b, self.rows, self.where, self.stamp, self.linker = b, rows, where, stamp, linker
self.lines: list[dict] = []
self.mats: dict[str, dict] = {}
self.missing: list[dict] = []
self.used: set[str] = set()
self.mat_lines: dict[str, dict] = {}
self.nation: dict[tuple, dict] = {}
self.taken: set[str] = set()
self.kids: set[int] = set()
self.left: list[dict] = []
def put(self, line: dict, one: dict, alias: str | None, qty: Decimal | None = None,
mark: dict | None = None) -> None: # fmt: skip
"""대상 하나 → 줄 · 자재 — 옛 꼴 `{로직|자재|호표|전국|이음, 입력값, 배, 몫}` · `qty` = 새 길 수량
(엑셀 × 몫 × 배) · `mark` = 새 길 줄 `본뜬`."""
keep = len(self.lines)
if "이음" in one:
others = [x for x in self.rows if x is not line]
fx = hfix.line_of(line, others, self.where, self.taken, self.linker, one["이음"])
self.lines.append(fx)
else:
qty = (
qty
if qty is not None
else Decimal(str(line.get("수량") or 0)) * Decimal(str(one["배"]))
)
self._put(line, one, alias, qty, mark is not None)
for row in self.lines[keep:]:
row.update({"본뜬": mark} if mark else {})
def _put(self, line: dict, one: dict, alias: str | None, qty: Decimal, new: bool) -> None:
b = self.b
memo = hbuild._memo(line, one)
if "전국" in one:
at = (one["이름"], one["규격"], one["단위"])
have = self.nation.get(at)
hand = qty + Decimal(str(have["수량"]["손"])) if have else qty
head = {"이름": at[0], "규격": at[1], "단위": at[2], "수량": {"손": _num(hand)}}
self.nation[at] = {**head, **(hmat.marks(line, at[0]) if not have else {
k: have[k] for k in labor.MARKS if k in have
})} # fmt: skip
self.missing.append(hbuild._missing(line, hbuild.NATIONAL))
return
if "자재" in one:
code = one["자재"]
have = self.mats.get(code)
hand = qty + Decimal(str(have["수량"]["손"])) if have else qty
name = b.mat_names.get(code, "")
marks = (
have and {k: have[k] for k in labor.MARKS if k in have} or hmat.marks(line, name)
)
if one.get("별도계상") is not None: # 세 칸 값(빈 칸 = 기본 「별도계상」)
marks = {**marks, "별도계상": "별도계상" if one["별도계상"] else "직접계산"}
self.mats[code] = {"코드": code, "수량": {"손": _num(hand)}, **marks}
if not have:
self.mat_lines[code] = line
return
if "호표" in one or "참조" in one:
if "호표" in one:
self.kids.add(one["호표"])
key = b.done.get(hbuild.mark(b.key, one["호표"]), "SC-미리")
ref = {"층": refs.here()[0], "주인": refs.here()[1], "키": key}
else:
ref = one["참조"]
self.lines.append({"참조": ref, "별칭": alias, "메모": memo, "수량": {"손": _num(qty)}})
return
row = {"로직": one["로직"], "입력값": one["입력값"], "메모": memo}
if not new:
kept, why = sangeun.kept(b, line, one, qty, alias, memo)
if why:
self.left.append(sangeun.left(line, why))
if kept is not None:
self.lines.append(kept)
return
if one["로직"] not in self.used:
self.used.add(one["로직"])
self.lines.append({**row, "별칭": alias, "수량": {"손": _num(qty)}})
return
at = int(line.get("차례", 0))
hopyo, file = b.hopyo, b.doc.get("파일") or ""
wrap = { # 같은 로직 둘째 — 한 줄 사전조합으로 감쌈
"이름": f"{hopyo['이름']} — {line.get('이름')}",
"단위": line.get("단위") or None,
"구분": hbuild.ORIGIN,
"상세구분": file,
"담은로직": [{**row, "별칭": alias, "수량": {"손": 1}}],
"자재": [],
"본뜬": b._origin(f"{hbuild.mark(b.key, b.no, at)} {one['로직']}", self.stamp),
}
ref = {"키": "SC-미리"} if b.dry else hkids.save(wrap, b.same)[0] # 미리 보기 = 쓰기 없음
self.lines.append({"참조": ref, "별칭": alias, "메모": memo, "수량": {"손": _num(qty)}})