feat(M02): 산출근거 표번 — 도번과 같은 규칙 자동 채번 · 좌측 「산출근거」 목록
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168FQuoV7vDh5nhnSowW5cp
This commit is contained in:
@@ -31,6 +31,7 @@ _BASIS_HEAD_STYLE = {
|
||||
"테두리": {side: {"선": "thin"} for side in ("위", "아래", "왼", "오른")},
|
||||
}
|
||||
_NUMBER = re.compile(r"^구-(\d+)$")
|
||||
_TABLE_NUMBER = re.compile(r"^표-(\d+)$")
|
||||
_BAD_NAME = re.compile(r'[\\/:*?"<>|\x00-\x1f]|\.\.')
|
||||
# 도각 없는 빈 CAD 문서의 기본 도면층 — 없으면 B07 CAD 가 못 엶("Cannot read properties
|
||||
# of undefined (reading 'length')") · CAD 쪽도 없으면 새로 채우지만(2026-09-27 sub1 고침)
|
||||
@@ -221,16 +222,47 @@ def basis_doc(column: str, old: Any = None) -> dict[str, Any]:
|
||||
}
|
||||
|
||||
|
||||
def _basis_docs() -> list[tuple[str, Any]]:
|
||||
folder = FOLDER / "basis"
|
||||
return [(p.stem, json.loads(p.read_bytes())) for p in sorted(folder.glob("[!.]*.json"))]
|
||||
|
||||
|
||||
def _table_number(doc: Any) -> int:
|
||||
found = _TABLE_NUMBER.match(str(doc.get("표번") or "")) if isinstance(doc, dict) else None
|
||||
return int(found.group(1)) if found else 0
|
||||
|
||||
|
||||
def ensure_basis(column: str, old: Any = None) -> bool:
|
||||
"""산출근거 파일이 없으면 만듦(식 없는 새 문서라 `계산값` 없음 · 첫 [저장] 때 서버가 적음)."""
|
||||
"""산출근거 파일이 없으면 만듦(식 없는 새 문서라 `계산값` 없음 · 첫 [저장] 때 서버가 적음).
|
||||
표번 = 도번과 같은 규칙(있는 것 중 가장 큰 번호 + 1) · 만든 뒤로는 안 바뀜."""
|
||||
path = _path("basis", column)
|
||||
with _LOCK:
|
||||
if path.is_file():
|
||||
return False
|
||||
atomic_write_json(path, basis_doc(column, old))
|
||||
number = max((_table_number(doc) for _name, doc in _basis_docs()), default=0) + 1
|
||||
doc = {**basis_doc(column, old), "표번": f"표-{number:02d}"}
|
||||
atomic_write_json(path, doc)
|
||||
return True
|
||||
|
||||
|
||||
def basis_numbers() -> dict[str, str | None]:
|
||||
"""`{열 id: 표번}` — 좌측 산출근거 줄이 한 번에 받음.
|
||||
표번이 없는 옛 파일은 여기서 만나는 순서로 채움(도번 규칙과 같음)."""
|
||||
docs = _basis_docs()
|
||||
missing = [name for name, doc in docs if not (isinstance(doc, dict) and doc.get("표번"))]
|
||||
if missing:
|
||||
with _LOCK:
|
||||
docs = _basis_docs() # 잠금 안에서 다시 읽음 — 그 사이 누가 채웠을 수 있음
|
||||
number = max((_table_number(doc) for _name, doc in docs), default=0)
|
||||
for name, doc in docs:
|
||||
if isinstance(doc, dict) and not doc.get("표번"):
|
||||
number += 1
|
||||
doc["표번"] = f"표-{number:02d}"
|
||||
atomic_write_json(_path("basis", name), doc)
|
||||
docs = _basis_docs()
|
||||
return {name: (doc.get("표번") if isinstance(doc, dict) else None) for name, doc in docs}
|
||||
|
||||
|
||||
def _server_values(doc: Any) -> dict[str, Any]:
|
||||
try:
|
||||
return spreadsheet.with_server_values(doc)
|
||||
|
||||
Reference in New Issue
Block a user