Files
Aislo/M02_MasterTemplete/M02_Copy_Slim.py
T
eomsangdonandClaude Opus 5.5 55b20510fd fix(826-3-1): 사본 · 수식 두 칸을 같은 읽은 줄로 줄임
- 수식 길 저장(따로 문서)은 옛 셈이 안 돌아 사본 칸이 1 줄로 줄던 것 — 두 칸 사본 줄 묶음 안에 드는 색인이 읽은 줄로 함께 줄임 · 사본 칸 빈 줄은 수식 칸 값 먼저

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 20:24:16 +09:00

108 lines
4.5 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.
"""사본 = 셈이 실제로 읽은 줄만(PLAN 826-3 · 요구 806 · 808 · 조사 804 5 절) — 서버 단독.
[저장] 관문(`M02_MasterTemplete_Store._server` — SK · 일위대가 · 사전조합 · 층 복사 · 열 복사)에서:
`saved` 동안 사본 셈 색인(`skc.Copy.get`)이 내준 줄 키를 그 색인의 사본 줄 묶음별로 적음
(`skc.READS`) → 문서 사본(`사본` · `수식` 값 몫)을 이 문서 셈이 읽은 줄만 남김 · 읽었는데
사본에 없는 줄(옵션 · 기계 · 지역을 바꿔 새로 읽은 줄) = 지금 M01(+ 층 내 기계) 값으로 더함.
이 문서 셈 = 사본 줄 묶음이 이 문서 사본 안에 드는 색인(남의 SK · SC 참조 셈 = 제 사본 → 안 셈).
파일 꼴 그대로 — 옛 코드는 사본에 없는 줄을 지금 M01 로 읽음(지금 옵션에서 안 읽는 줄 = 금액 같음).
읽은 줄 없음(셈 안 돎) · 프로젝트 층 = 그대로 · 이미 저장된 파일은 다음 [저장] 때 줄어듦.
"""
from __future__ import annotations
from typing import Any, Callable
from M02_MasterTemplete import M02_Doc_Copy as dc
from M02_MasterTemplete import M02_Item_Prices as prices
from M02_MasterTemplete import M02_MyMachine as mym
from M02_MasterTemplete import M02_Sangeun_Copy as skc
def _keys(rows: list[dict]) -> set[str]:
return {str(r.get("키")) for r in rows}
def _rows(copy: dict) -> list[dict]:
return [*copy["로직"], *(copy.get("단가") or [])]
def cut(copy: Any, keys: set[str], pool: dict | None = None) -> Any:
"""값 사본(`skc` 꼴) → `keys` 줄만 · 사본 없는 줄 = `pool`(다른 칸 사본) › 지금 M01(+ 내 기계) ·
판은 바뀐 몫만 다시."""
if not skc.has({skc.KEY: copy}) or not keys:
return copy
rows = _rows(copy)
have = _keys(rows)
whole = skc.whole_()
add = [
(pool or {}).get(k) or prices.to_json(whole.index[k[:2]][k])
for k in sorted(keys - have)
if k in (pool or {}) or k in whole.index.get(k[:2], {})
]
keep = [r for r in rows if str(r.get("키")) in keys] + add
logic = [r for r in keep if str(r.get("키"))[:2] not in skc.RES]
cost = [r for r in keep if str(r.get("키"))[:2] in skc.RES]
out = {**copy, "로직": logic, "단가": cost}
if logic != copy["로직"]:
out["판"] = skc._fp(logic)
if cost != (copy.get("단가") or []):
out["단가판"] = skc._fp(cost)
return out
def cut_doc(doc: Any, reads: dict) -> Any:
"""문서의 로직 사본(`사본`) · 수식 사본 값 몫(`수식`)을 두 칸 같은 줄로 줄임 —
줄 = 사본 줄 묶음이 두 칸 안에 드는 색인이 읽은 것 + 문서 안 내 기계 키(822-1) ·
읽은 줄 없음 = 그대로."""
if not isinstance(doc, dict):
return doc
old = doc[skc.KEY] if skc.has(doc) else None
form = doc[dc.KEY] if dc.has(doc) and isinstance(doc[dc.KEY].get("로직"), list) else None
mine = {str(r.get("키")): r for c in (form, old) if c for r in _rows(c)}
keys = {k for box, got in reads.items() if box <= mine.keys() for k in got}
if not keys:
return doc # 셈이 이 사본을 안 읽음 — 그대로
keys |= set(mym.keys_in({k: v for k, v in doc.items() if k not in (skc.KEY, dc.KEY)}))
out = dict(doc)
if form:
out[dc.KEY] = {**form, **cut(dc.values_of(form), keys)}
if old:
pool = {str(r.get("키")): r for r in _rows(out[dc.KEY])} if form else None
out[skc.KEY] = cut(old, keys, pool)
return out
def _project() -> bool:
from M02_MasterTemplete import M02_Labor_Ref as refs
return refs.here()[0] == "project"
def _record(kind: str, out: Any) -> None:
"""저장 길이 이 문서 셈을 안 돌린 몫만 한 번 셈(읽은 줄 적기) — 사전조합 · 수식 길로 고친 SK."""
if not isinstance(out, dict):
return
if kind == "precombo" and skc.has(out):
from M02_MasterTemplete import M02_Labor_Doc as labor
labor.calc(out, {})
elif kind == "sangeun" and dc.has(out) and out[dc.KEY].get("따로"):
from M02_MasterTemplete import M02_Doc_Sk as dsk
dsk.run(out, out[dc.KEY])
def saved(kind: str, make: Callable[[], Any]) -> Any:
"""[저장] 관문 — `make()`(정리 · 셈 · 사본 정함) 동안 읽은 줄을 적고 사본을 그 줄로 줄임."""
if _project():
return make()
reads: dict = {}
token = skc.READS.set(reads)
try:
out = make()
_record(kind, out)
finally:
skc.READS.reset(token)
return cut_doc(out, reads)