feat(719-2): 공사 쪽 M02 단가산출(SK) — B09 대가 블록 · 산근 · [업데이트] · 내 자료집 SK
- Labor_Source: 굳힌 SK = 품셈 꼴 대가 블록(사본 단가.json 굳힌 키 줄 · M01 안 읽음) · 단가산출 속 일위대가 · SK 줄 = 그 대가 블록 부르는 줄 · 고정 줄 = fixed · 단가 고친 줄 = fixed(M02 셈 단가) · cover = P:+SK 이름표(SK 고쳐도 B09 덮개 그대로) · 줄 sk · poom(품셈 값) · 부르는 줄 수량 ÷ 굳힌 줄 배 · 사전조합 알약 = 굳힌 알약 · 서고 sangeun 사본 - Sangeun: SK 하위 로직 = 산근 · 단가산출 속 참조 걸음 · 결과단위 배 = 사본 줄에서(_unit(row) · unit_of(whole, code)) - Linked: 굳힌 SK 자원 키(굳힌 키 로직 줄 · 고정 이음) - Refresh: 미리 보기 단가산출(바뀌는 SK 줄) · 서고 사본 원본판 다르면 다시 굳힘 - Bill_Library: 종류 sangeun(내 자료집 SK 불러오기) · changed · refresh_copy(같은 폴더 · 값 그대로 · 원본판 없는 옛 사본 그대로) - Daega_Personal: 품셈 블록(굳힌 SK 포함) → 개인 층 SK(B09 품 · 단가 덮개 = SK 덮개 · 더한줄 수량 · 단가) - M02_Item_Sangeun: 굳힌 SK 정체(굳힌 줄 차례 → 원본 cid) - 화면: 일위대가 펼침 SK 줄 되돌림 [단가산출 값으로] · 곁 글 품셈 값 · 내 자료집 단가산출 글 · 업데이트 미리 보기 SK 줄 · 단가연결 내 것 단가산출(Labor_Api fetchLibrary 종류 넓힘) - 시험 test_719_2_sk_project 5 통과 + 1 건너뜀(715-1b 엔진 단가 · 값묶음 뒤 자동 실행) - test_155_5: _unit 인자 = 로직 줄로 바뀜(사본 줄에서 배 읽음) — 부르는 줄 고침 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,9 @@
|
||||
도면 · 면적 · 일위대가 · 단가 · 입력값 · 고른자재 첫 값)
|
||||
precombo 사전조합 = `일위대가.json` {줄: {담은로직: [{참조, 수량: {손: 1}}]}, 참조사본} ·
|
||||
`단가.json`(`M02_Item_Source.price_bundle` — 사본 단가 묶음 한 벌)
|
||||
sangeun 단가산출(SK · 내 자료집 · 719-2) = precombo 와 한 꼴(참조사본 = 풀어 굳힌 SK)
|
||||
[업데이트](719-2) = 원본판이 다른 사본만 같은 폴더에 다시 굳힘(`changed` · `refresh_copy` ·
|
||||
값 그대로 · 원본판 없는 옛 사본 = 그대로).
|
||||
사본 = 원본이 바뀌거나 지워져도 그대로(굳힘) ·
|
||||
대가 블록 = `Labor_Source.daega_inputs`(`libs` {폴더: 블록 id}) ·
|
||||
단가 수요 = `Linked.linked_resource_keys` · 줄 연결 = {tab: dg, key: 블록 id, lib: 폴더} ·
|
||||
@@ -58,11 +61,11 @@ from M02_MasterTemplete.M02_Item_Source import (
|
||||
)
|
||||
|
||||
LIBRARY = "library"
|
||||
KINDS = ("combo", "precombo")
|
||||
KINDS = ("combo", "precombo", "sangeun")
|
||||
#: 폴더 이름 — 종류 · 층(project = 불러온 공사 일위대가 · 707-7) · 주인 ·
|
||||
#: 키(영문 · 숫자 · `-` `_`) · 값 해시(263-2 · 없을 수 있음)
|
||||
NAME = re.compile(
|
||||
r"^(combo|precombo)@(system|company|personal|project)@[0-9-]+@[A-Za-z0-9_-]{1,40}(~[0-9a-f]{8})?$"
|
||||
r"^(combo|precombo|sangeun)@(system|company|personal|project)@[0-9-]+@[A-Za-z0-9_-]{1,40}(~[0-9a-f]{8})?$"
|
||||
)
|
||||
|
||||
|
||||
@@ -87,11 +90,11 @@ def folder_name(
|
||||
return name
|
||||
|
||||
|
||||
def _precombo_files(layer: str, owner: str | None, key: str) -> dict[str, Any]:
|
||||
def _precombo_files(layer: str, owner: str | None, key: str, kind: str = "precombo") -> dict:
|
||||
ref = {"층": layer, "주인": owner, "키": key}
|
||||
doc = refs.read_ref(ref)
|
||||
if doc is None or doc.get("종류") != refs.TITLE["precombo"]:
|
||||
raise LookupError(f"사전조합 {key} 이 {layer} 층에 없음")
|
||||
if doc is None or doc.get("종류") != refs.TITLE[kind]:
|
||||
raise LookupError(f"{refs.TITLE[kind]} {key} 이 {layer} 층에 없음")
|
||||
line = {"참조": ref, "수량": {"손": 1}}
|
||||
labor = labor_doc_rows({"이름": doc.get("이름"), "단위": doc.get("단위"), "담은로직": [line]})
|
||||
return {
|
||||
@@ -116,10 +119,43 @@ def _build(kind: str, layer: str, owner: str | None, key: str) -> tuple[dict, di
|
||||
item = {"layer": layer, "owner": owner, "key": key}
|
||||
item["name"] = item_name(item)
|
||||
return build_snapshot(item), origin_of(item)
|
||||
files = _precombo_files(layer, owner, key)
|
||||
files = _precombo_files(layer, owner, key, kind)
|
||||
return files, files.pop("_원본")
|
||||
|
||||
|
||||
def _source_of(manifest: dict[str, Any]) -> tuple[str, str, str | None, str]:
|
||||
"""manifest → (종류, 층, 주인, 키)."""
|
||||
kind, origin = str(manifest.get("종류")), manifest.get("원본") or {}
|
||||
if kind == "combo":
|
||||
return kind, origin.get("layer"), origin.get("owner"), origin.get("key")
|
||||
ref = origin.get("참조") or {}
|
||||
return kind, ref.get("층"), ref.get("주인"), ref.get("키")
|
||||
|
||||
|
||||
def changed(project_root: str | Path) -> list[tuple[Path, dict[str, Any], dict, dict]]:
|
||||
"""원본판이 지금 원본과 다른 사본 `(폴더, manifest, 새 파일들, 새 원본 표지)` — 원본판 없는 옛
|
||||
사본 · 원본 없음 = 뺌(그대로)."""
|
||||
out = []
|
||||
for folder, manifest in copies(project_root):
|
||||
if not manifest.get("원본판"):
|
||||
continue
|
||||
try:
|
||||
files, origin = _build(*_source_of(manifest))
|
||||
except (LookupError, ValueError, KeyError):
|
||||
continue
|
||||
if source_version(files) != manifest["원본판"]:
|
||||
out.append((folder, manifest, files, origin))
|
||||
return out
|
||||
|
||||
|
||||
def refresh_copy(project_root: str | Path, one: tuple) -> None:
|
||||
"""`changed` 한 줄 → 같은 폴더에 다시 굳힘(값 · 가져온이 그대로 · 원본판 새로)."""
|
||||
folder, manifest, files, origin = one
|
||||
keep = {k: v for k, v in manifest.items() if k not in ("값", "원값")}
|
||||
fresh = {**keep, "원본": origin, "원본판": source_version(files), "가져온날": now_text()}
|
||||
_write(project_root, folder.name, files, fresh, manifest.get("값") or {})
|
||||
|
||||
|
||||
# ── 운반 값 사본(263-2) ────────────────────────────────────────────────
|
||||
def _logic(code: str) -> dict[str, Any]:
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user