- 서버: inputs · combo_logics · _num 몸을 M02_Labor_Inputs.py 로(logic_inputs = 로직 키들 입력 + 자동값) · M02_MasterTemplete_Inputs.py 는 그것을 부름 - 길: GET /api/m02/logic-lib/inputs?keys= (로그인 · 일위대가 입력 모달용) - 화면: 값 카드(createInputsValueCard) · 값 함수 → M02_Labor_Values.ts · M02_Labor_Values_Model.ts · 값 칸 하나(createValueControl)를 떼어 값 카드와 입력 모달이 같이 씀 · CSS 도 옮김 - 옛 자리(M02_MasterTemplete_Inputs.ts · _Inputs_Model.ts)는 새 파일을 다시 내보냄 — B05 고르기 모달 그대로 - 시험: 새 test_m02_labor_values.py · 옮긴 자리 따라 test_item_picker_detail · test_m02_card_shell · helper_m02_inputs 고침 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MgChuAcyBqUkhHMTXomQC7
95 lines
3.7 KiB
Python
95 lines
3.7 KiB
Python
"""M02 일위대가 입력 목록(39-3 · 옛 선택 입력 `M02_MasterTemplete_Inputs` 에서 옮김).
|
|
|
|
담은 단가산출 로직마다 입력 전부 · 로직마다 갈라 보이고 이름이 같아도 합치지 않음 · 입력 목록은
|
|
그 로직 줄의 `입력` 그대로(하위 로직으로 넘겨지는 입력은 맨 위 로직 입력으로만) · 자동값 =
|
|
`master_auto.values`(보기용 · 저장 안 함). 일위대가 입력 모달(`GET /api/m02/logic-lib/inputs`)과
|
|
옛 선택 입력 길(`inputs`)이 같이 씀. M01 은 읽기만 · 권한은 부르는 쪽 몫.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from decimal import Decimal
|
|
from typing import Any
|
|
|
|
from M01_MasterData import M01_MasterData_Store as m01
|
|
from M01_MasterData import M01_MasterData_Store_Combo as combo_store
|
|
from M02_MasterTemplete import M02_MasterTemplete_Combo_Store as combos
|
|
|
|
_SPEC = ("이름", "설명", "단위", "고르기", "범위")
|
|
|
|
|
|
def _num(value: Any) -> Any:
|
|
"""Decimal → JSON 수(M01 길과 같은 규칙) · 목록 · 묶음 안까지."""
|
|
if isinstance(value, Decimal):
|
|
return int(value) if value == value.to_integral_value() else float(value)
|
|
if isinstance(value, list):
|
|
return [_num(v) for v in value]
|
|
if isinstance(value, dict):
|
|
return {k: _num(v) for k, v in value.items()}
|
|
return value
|
|
|
|
|
|
def _logics(codes: list[str]) -> tuple[list[dict], list[str]]:
|
|
"""([로직 줄 …], 빠진 로직 키) — 키 차례 그대로."""
|
|
whole = m01.loaded()[1]
|
|
found, missing = [], []
|
|
for code in codes:
|
|
try:
|
|
found.append(whole.logic(code))
|
|
except combo_store.cm.mf.FormulaError:
|
|
missing.append(code)
|
|
return found, missing
|
|
|
|
|
|
def combo_logics(ua: str | None) -> tuple[dict[str, Any] | None, list[dict], list[str]]:
|
|
"""(조합 줄, [로직 줄 …], 빠진 로직 키) — 조합이 없거나 못 찾으면 (None, [], [])."""
|
|
if not ua:
|
|
return None, [], []
|
|
row = combos.find(str(ua)) # 마스터 UA · 회사 UC · 개인 UP(27-2c)
|
|
if row is None:
|
|
return None, [], []
|
|
found, missing = _logics(combo_store.mcb.logic_keys(row))
|
|
return row, found, missing
|
|
|
|
|
|
def _listed(logics: list[dict]) -> list[dict[str, Any]]:
|
|
"""로직 줄마다 `{로직, 이름, 결과단위, 입력: [{이름, 설명, 단위, 고르기?, 범위?, 자동값}]}`."""
|
|
whole = m01.loaded()[1]
|
|
out = []
|
|
for logic in logics:
|
|
auto = m01.mau.values(whole, logic)
|
|
specs = []
|
|
for spec in logic.get("입력") or []:
|
|
one = {k: spec[k] for k in _SPEC if k in spec}
|
|
one.setdefault("설명", None)
|
|
one.setdefault("단위", None)
|
|
specs.append({**one, "자동값": auto.get(spec["이름"])})
|
|
out.append(
|
|
{
|
|
"로직": logic.get("키"),
|
|
"이름": logic.get("이름"),
|
|
"결과단위": logic.get("결과단위"),
|
|
"입력": specs,
|
|
}
|
|
)
|
|
return out
|
|
|
|
|
|
def logic_inputs(codes: list[str]) -> dict[str, Any]:
|
|
"""일위대가 입력 모달 — 로직 키들의 입력 목록 `{로직: [...], 빠진로직}`(키 차례 · 겹침 한 번)"""
|
|
found, missing = _logics(list(dict.fromkeys(c for c in codes if c)))
|
|
return _num({"로직": _listed(found), "빠진로직": missing})
|
|
|
|
|
|
def inputs_of(ua: str | None) -> dict[str, Any]:
|
|
"""옛 선택 입력 목록 — `{일위대가, 이름, 로직: [...], 빠진로직}` · 일위대가 없으면 로직 없음."""
|
|
row, logics, missing = combo_logics(ua)
|
|
return _num(
|
|
{
|
|
"일위대가": ua or None,
|
|
"이름": row.get("이름") if row else None,
|
|
"로직": _listed(logics),
|
|
"빠진로직": missing,
|
|
}
|
|
)
|