- [수정] 모달 = 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>
99 lines
5.2 KiB
Python
99 lines
5.2 KiB
Python
"""M02 엑셀 불러오기 [수정] 보기(PLAN 809-1 · 요구 702 · 703) — 호표 하나 → 일위대가 문서 미리보기 + 줄 표지 · 읽기만.
|
|
|
|
경쟁사 로직 인정 · 요소만 연결 — 문서 줄 = 엑셀 줄 하나씩 고정 줄(엑셀 숫자 그대로 · `Fixed.line_of` ·
|
|
[내 일위대가로] 와 같은 이음 규칙 · 금액 = 엑셀). 줄 표지:
|
|
· 로직 줄 = 단산 N 참조 → 「단가산출」(번 · 가져온 식 SK 로 엶) · 일위 N 참조 → 「일위대가」(번 · 하위 호표 보기)
|
|
· 요소 줄 = 그 밖(인력 · 재료 · 기계 · 유가 · 율 · 고정 수) — 이음 있음 = 「연결됨」(이음) ·
|
|
후보 있음 = 「후보」(키 · 이름) · 없음 = 「못 이음」(엑셀 값 그대로)
|
|
· 엑셀 = 줄 금액(노무비 · 재료비 · 경비 · 계)
|
|
기초 판정 · 2차 풀이 없음 · 저장 없음.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
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_Store as hopyo_store
|
|
from M02_MasterTemplete import M02_Labor_Ref as refs
|
|
from M02_MasterTemplete import M02_MasterTemplete_Store as store
|
|
|
|
LOGIC, ELEMENT = "로직", "요소"
|
|
SK, SC = "단가산출", "일위대가"
|
|
LINKED, NEAR, NONE = "연결됨", "후보", "못 이음"
|
|
MONEY = ("노무비", "재료비", "경비", "계")
|
|
|
|
|
|
def _name(linker: hfix.Linker, code: str) -> str:
|
|
row = (linker.whole.numbers.get(code[:2]) or {}).get(code) or {}
|
|
return str(row.get("이름") or "")
|
|
|
|
|
|
def mark(line: dict[str, Any], one: dict[str, Any], linker: hfix.Linker) -> dict[str, Any]:
|
|
"""엑셀 줄 하나 표지 — 로직(단가산출 · 일위대가) / 요소(연결됨 · 후보 · 못 이음)."""
|
|
ref = line.get("참조") or {}
|
|
money = line.get("금액") or {}
|
|
out: dict[str, Any] = {
|
|
"차례": int(line.get("차례", 0)),
|
|
"엑셀": {k: money.get(k) for k in MONEY},
|
|
}
|
|
if ref.get("종류") == "단산" and ref.get("번"):
|
|
return {**out, "갈래": LOGIC, "표지": SK, "번": int(ref["번"])}
|
|
if ref.get("종류") == "일위" or hfix.kind_of(line) == "호표":
|
|
return {**out, "갈래": LOGIC, "표지": SC, "번": int(ref.get("번") or 0) or None}
|
|
fx = one.get("고정") or {}
|
|
if hfix.linked(one):
|
|
link = {k: v for k, v in (fx.get("이음") or {}).items() if v}
|
|
rate = fx.get("비율")
|
|
return {**out, "갈래": ELEMENT, "표지": LINKED, "이음": link or {"비율": rate["기준"]}}
|
|
near = [{"키": c, "이름": _name(linker, c)} for c in linker.candidates(line)]
|
|
if near:
|
|
return {**out, "갈래": ELEMENT, "표지": NEAR, "후보": near}
|
|
return {**out, "갈래": ELEMENT, "표지": NONE}
|
|
|
|
|
|
def view(source: str | Path, key: str, no: int) -> dict[str, Any]:
|
|
"""파일 층 HP 의 호표 하나 보기(`of`)."""
|
|
return of(hopyo_store.read(Path(source), key), no)
|
|
|
|
|
|
def of(book: dict[str, Any], no: int, linker: hfix.Linker | None = None) -> dict[str, Any]:
|
|
"""호표 하나 → `{번, 이름, 규격, 단위, 금액, 문서 {이름, 단위, 담은로직, 자재}, 줄 [표지]}` — 문서 줄 차례 = 엑셀 줄 차례."""
|
|
hopyo = next((h for h in book.get("호표") or [] if int(h["번"]) == int(no)), None)
|
|
if hopyo is None:
|
|
raise store.StoreError(404, f"없는 호표 「제{no}호표」")
|
|
rows = hopyo.get("줄") or []
|
|
linker, taken = linker or hfix.Linker(True), set()
|
|
where = {"파일": book.get("파일") or "", "호표": int(no)}
|
|
lines, marks = [], []
|
|
for line in rows:
|
|
one = hfix.line_of(line, [x for x in rows if x is not line], where, taken, linker)
|
|
lines.append(one)
|
|
marks.append(mark(line, one, linker))
|
|
name = " ".join(x for x in (hopyo.get("이름"), hopyo.get("규격")) if x)
|
|
doc = {"이름": name, "단위": hopyo.get("단위") or None, "담은로직": lines, "자재": []}
|
|
head = {k: hopyo.get(k) for k in ("번", "이름", "규격", "단위", "금액")}
|
|
return {**head, "문서": doc, "줄": marks}
|
|
|
|
|
|
def listing(folder: str | Path, key: str, to: str | Path) -> dict[str, Any]:
|
|
"""엑셀 보기 머리 · 목록 — 파일 줄 + 검산 · 호표마다 `맞춤` [연결됨 + 로직 줄, 줄 수] ·
|
|
`줄상태 [[차례, 표지, 이어짐]]` · `만든` SC(만들 층 `to` · 이 파일 층 것만)."""
|
|
book = hopyo_store.read(Path(folder), key)
|
|
made = hbuild.confirmed(to, refs.where(Path(folder)))
|
|
linker, units = hfix.Linker(True), []
|
|
for h in book.get("호표") or []:
|
|
no = int(h["번"])
|
|
marks = of(book, no, linker)["줄"]
|
|
state = [
|
|
[i, m["표지"], m["갈래"] == LOGIC or m["표지"] == LINKED] for i, m in enumerate(marks)
|
|
]
|
|
head = {k: h.get(k) for k in ("번", "이름", "규격", "단위", "금액", "행") if k in h}
|
|
units.append({**head, "맞춤": [sum(x[2] for x in state), len(state)], "줄상태": state,
|
|
"만든": made.get(hbuild.mark(key, no))}) # fmt: skip
|
|
ready = [sum(h["맞춤"][0] for h in units), sum(h["맞춤"][1] for h in units)]
|
|
head = {**hopyo_store.brief(book), "검산": book.get("검산"), "셈": {"끝": True}}
|
|
return {**head, "호표": units, "맞춤": ready}
|