Files
Aislo/M02_MasterTemplete/M02_MyMachine_Sheet.py
T
eomsangdonandClaude Opus 5.5 c8cd98dec1 feat(846-2): 기계 줄 시간당 작업량 화면 — 산출근거 「시간당 작업량」 줄 먼저 · 비목 ÷ 시간당 작업량 · 제어 구역 일당 / 시간당 식 고르기 · 변수 칸 · 기계 보기 작업량 식
- 산출근거: 일당 「시간당 작업량 = 시공량 560 ㎥/일 ÷ (1 대 × 8 시간) = 70 ㎥/시간」 · 시간당 식 = q · K · f · E · cm 값 줄 + 한 층 분수 Q 식 · 비목 줄 「59,020 원/시간 ÷ 70 ㎥/시간 = 843.1 원」(금액 그대로)
- 제어 구역: 「시간당 작업량」 묶음 맨 위 — 방식 고르기(식 없는 기계 = 잠김 + 까닭) · 시간당 = 작업량 틀 변수 칸(고침 · 원래 값) · 덮음 = 기계덮음.<기계>.작업량
- 기계 보기: 왼쪽 작업량 카드(기계 정본 변수) · 오른쪽 풀이 · 서버가 작업량 틀 연결을 실음(M02_MyMachine_Sheet._work)
- 시험: test_846_2_work_view 새로 · test_845_2 GC000088 비목 줄 기대값을 새 꼴로 고침(846-2 표시 변경) · 헬퍼 가짜 DOM 이 진짜 DOM 처럼 요소를 옮김(같은 요소 두 줄 재사용 흠을 잡게)

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

112 lines
4.9 KiB
Python

"""기계 보기 서버 몫(PLAN 840-2 · 요구 853 · 862) — M01 기계 상세 · 내 기계가 같이 씀 · 쓰기 없음.
`sheet(줄, 본, 덮음, 개인)` → {키, 이름, 까닭, 문서, 값, 연결, 직종}
- 식 고름 = `M02_Machine_Hourly.pick`(지금 줄 · 내 기계 = 셈 꼴 `M02_MyMachine.engine`) · 못 고름 = 키 없음 + 까닭
- 문서 = 그 식 수식 문서(그대로) · 값 = `본`(처음 줄 · 없으면 줄)의 셈 꼴 값 칸 — 셈 차례 = 덮음(`기계덮음` 꼴 ·
836-1) 얹음 → 값 박음(`bind` — 남은 요소 `EQ:{S_기계}` 칸 → 숫자 · 저장 전 새 기계 · 내 기계도 같은 계산기로 셈)
- 파이썬 · TS 짝 — `bind` ↔ `common_util/common_util_machine_sheet.ts` `bindDoc` · 거울 시험 test_840_2_machine_sheet.py
- 연결 = 덮음 얹은 문서 셈이 쓴 요소 · 표 · 문서(`master_doc_record`) — 화면이 같은 계산기로 즉시 다시 셈
- 바탕 = 처음 줄 인력 · 잡품 목록(842-3 · `master_doc_cover.row_entry`) — 덮음(지금 줄 목록)이 그 위에 · 값 박음은
목록 → 조종원 수 · 직종 · 잡재료율(`master_machine_crew.view`)
- 직종 = 노임 요소 코드 → 인력 원문번호(인력 줄 키 `LB:원문번호`)
- 작업량(846-2) = 지금 줄 `값.작업량` 식마다 작업량 틀 문서 · 표를 연결에 더함(오른쪽 풀이)
"""
from __future__ import annotations
import copy
import json
from decimal import Decimal
from typing import Any
from M01_MasterData import M01_MasterData_Store as m01
from M02_MasterTemplete import M02_MyMachine as mym
def _plain(v: Any) -> Any:
if isinstance(v, Decimal):
return int(v) if v == v.to_integral_value() else float(v)
return v
def bind(doc: dict, vals: dict) -> dict:
"""식 문서 → 기계 값 칸을 숫자로 박은 새 문서(그 칸이 없는 줄은 요소 그대로 · 목록 = `view`)."""
import master_machine_crew as mcrew
out = copy.deepcopy(doc)
vals = mcrew.view(vals)
for v in out.get("변수") or []:
link = v.get("연결") or {}
key = str(link.get("키") or "")
col = link.get("칸")
if (
link.get("갈래") == "요소"
and key.startswith("EQ:")
and "{S_기계}" in key
and col in vals
):
v["연결"] = {"갈래": "숫자", "값": vals[col]}
return out
def _shape(row: dict, mine: bool) -> dict:
if mine:
return mym.engine(row)
return {**row, "값": m01._dec(row.get("값") or {})}
def _jobs() -> dict[str, str]:
rows = (m01.loaded()[0].get("인력.json") or {}).get("줄") or []
return {str(r["키"]): str(r.get("원문번호")) for r in rows if r.get("키")}
def _work(cur: dict, rec, mc) -> None:
"""기계 작업량 줄 → 작업량 틀 문서 · 표 연결(못 읽는 식 = 건너뜀 · 화면이 「불러오는 중」)."""
for spec in (cur.get("값") or {}).get("작업량") or []:
key = str(spec.get("식") or "") if isinstance(spec, dict) else ""
try:
tpl = rec.doc(key) if key else None
if tpl:
rec.prefetch(tpl)
mc.calc(tpl, rec, dict(spec.get("변수") or {}))
except Exception: # noqa: BLE001 — 그림 연결만(셈 정본 아님)
continue
def sheet(row: Any, base: Any = None, cover: Any = None, mine: bool = False) -> dict:
import master_doc_calc as mc
import master_doc_cover as mcv
import master_doc_link as ml
import master_doc_record as mr
from M01_MasterData import M01_MasterData_Doc as m01doc
from M02_MasterTemplete import M02_Machine_Hourly as mh
if not isinstance(row, dict):
raise m01.StoreError(400, "기계 줄이 묶음 아님")
cur = _shape(row, mine)
logic = mh.pick(cur)
out: dict[str, Any] = {"직종": _jobs()}
doc = m01doc.docs().get(str(logic["키"])) if logic else None
if doc is None:
why = mh.why(cur, logic) or ("식 문서 없음" if logic else "식 없음")
return out | {"키": None, "까닭": why, "문서": None, "값": {}, "연결": {}}
vals = _shape(base if isinstance(base, dict) else row, mine).get("값") or {}
no = str(row.get("원문번호") or row.get("키") or "새 기계")
given = {"기계": no}
entry = cover if isinstance(cover, dict) and cover else None
try:
cover = mcv.clean({no: m01._dec(entry)}) if entry else None
covered = mcv.cover_doc(doc, given, cover, mcv.row_entry(doc, vals))
except ValueError as e:
raise m01.StoreError(400, str(e)) from None
shaped = bind(covered, vals)
links = ml.Links(mym.whole(), m01doc.docs())
rec = mr.Rec(links)
rec.prefetch(shaped)
mc.calc(shaped, rec, given)
_work(cur, rec, mc)
got = {"키": logic["키"], "이름": logic.get("이름"), "까닭": mh.why(cur, logic), "문서": doc,
"값": vals, "연결": rec.out()} # fmt: skip
return json.loads(json.dumps(out | got, ensure_ascii=False, default=_plain))