"""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_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 줄 키 + 문서의 내 기계 키(셈 틀림 = 읽은 데까지).""" 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["문서"])} - 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)} - _have(sk[skc.KEY])) if not keys: return sk return {**sk, skc.KEY: skc.grow(sk[skc.KEY], skc.snap([], keys))}