- 서버 `M02_Material_Own`: M01 자재품목과 이름 · 규격 · 단위 같음 = 409(빈칸 · 대소문자 · ㎏ = kg 무시) · 고치기 · 지우기(쓰는 곳 있으면 409 · 밑줄 폴더 보관본 뺌) · 목록 줄마다 쓰는 곳 - 셈 색인: 단가산출 사본 색인 · 사본 모으기 · 빈틈 채우기에 내 재료 줄을 내 기계처럼 얹음 → 개인 층 단가산출은 값 바뀌면 836-2 길로 따라옴 · 프로젝트 층 = 사본 값 - 화면: 개인관리 › 자재 위 「내 재료」 표 + 고침 칸(`M02_MyMaterial_View` · `M02_MyMaterial_Api`) · 아래 「값을 바로 적은 재료」 모아 보기는 읽기 그대로 · 찾아 넣기 재료 탭 M01 위 「내 재료」 묶음(줄 쌓기 개인 층) - M01 재료를 본떠 값만 바꾼 내 재료를 만드는 길 = 없었음(걷을 것 없음) 낡은 시험 고침: test_m02_material_own 목록 줄에 「쓰는곳」 칸 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
84 lines
3.3 KiB
Python
84 lines
3.3 KiB
Python
"""M02 단가산출(SK) 수식 사본 빈틈(PLAN 822-1 · 요구 797-1) — 서버 단독.
|
|
|
|
빈틈 = 문서 셈이 읽은 M01 요소 · 표 줄 가운데 값 사본에 없는 것(줄 쌓기 기계 · 바꿔 끼운 기계 ·
|
|
더한 자원 줄 · 단가산출 참조가 읽는 노임 · 유가 · 내 기계 …) — 사본 색인이 지금 M01 로 흘러
|
|
M01 이 바뀌면 금액이 바로 따라 바뀜.
|
|
`gaps` = 빈틈 키(셈 한 번 · 읽은 줄 적기) · `fill` = 빈틈을 지금 M01 닫힌 묶음으로 값 사본에 더함
|
|
(있는 줄 그대로 — `skc.grow`) — [저장] · [단가 갱신] 때만(열기 · 미리 셈은 지금 값으로 셈 + 표지).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from M02_MasterTemplete import M02_Doc_Copy as dc
|
|
from M02_MasterTemplete import M02_Material_Own as own
|
|
from M02_MasterTemplete import M02_MyMachine as mym
|
|
from M02_MasterTemplete import M02_Sangeun_Copy as skc
|
|
|
|
|
|
class _Seen:
|
|
"""셈 색인 겉 — `get` · `value` · `logic` 이 내준 줄 키를 적음(그 밖 = 속 색인 그대로)."""
|
|
|
|
def __init__(self, inner: Any) -> None:
|
|
self._inner, self.keys = inner, set()
|
|
|
|
def get(self, ref: str) -> dict:
|
|
return self._note(self._inner.get(ref))
|
|
|
|
def value(self, ref: str):
|
|
self.get(ref)
|
|
return self._inner.value(ref)
|
|
|
|
def logic(self, key: str) -> dict:
|
|
return self._note(self._inner.logic(key))
|
|
|
|
def _note(self, row: Any) -> Any:
|
|
if isinstance(row, dict) and row.get("키"):
|
|
self.keys.add(str(row["키"]))
|
|
return row
|
|
|
|
def __getattr__(self, name: str) -> Any:
|
|
return getattr(self._inner, name)
|
|
|
|
|
|
def _have(copy: dict) -> set[str]:
|
|
return {str(r.get("키")) for r in [*(copy.get("로직") or []), *(copy.get("단가") or [])]}
|
|
|
|
|
|
def gaps(copy: dict) -> list[str]:
|
|
"""값 사본에 없는데 문서 셈이 읽은 M01 줄 키 + 문서의 내 기계 · 내 재료(840-4) 키(셈 틀림 = 읽은 데까지)."""
|
|
if "로직" not in copy or not isinstance(copy.get("문서"), dict):
|
|
return []
|
|
seen = _Seen(dc.over(copy))
|
|
try:
|
|
dc.mc.calc(copy["문서"], dc.ml.Links(seen, dc.docs_of(copy)))
|
|
except dc._ERR:
|
|
pass
|
|
have = _have(copy)
|
|
return sorted({*seen.keys, *mym.keys_in(copy["문서"]), *own.keys_in(copy["문서"])} - have)
|
|
|
|
|
|
def fill(copy: dict) -> dict:
|
|
"""빈틈을 지금 M01(+ 지금 층 내 기계) 닫힌 묶음으로 값 사본에 더함 · 빈틈 없음 = 그대로."""
|
|
keys = gaps(copy)
|
|
if not keys:
|
|
return copy
|
|
return {**copy, **skc.grow(dc.values_of(copy), skc.snap([], keys))}
|
|
|
|
|
|
def fill_imported(sk: dict, doc: Any) -> dict:
|
|
"""가져온 식 SK(823-1) — 문서 셈(단가기준 · 바꿔 끼운 줄)이 읽은 줄 가운데
|
|
SK 로직 사본에 없는 것 + 내 기계 = 지금 값으로 로직 사본에 더함 ·
|
|
사본 없음 · 빈틈 없음 = 그대로."""
|
|
from M02_MasterTemplete import M02_Doc_Import as dim
|
|
|
|
if not skc.has(sk) or not isinstance(doc, dict):
|
|
return sk
|
|
seen = _Seen(dim._index(sk, None, doc))
|
|
dim.run(doc, sk, index=seen) # 셈 틀림 = 읽은 데까지(run 이 받음)
|
|
keys = sorted({*seen.keys, *mym.keys_in(doc), *own.keys_in(doc)} - _have(sk[skc.KEY]))
|
|
if not keys:
|
|
return sk
|
|
return {**sk, skc.KEY: skc.grow(sk[skc.KEY], skc.snap([], keys))}
|