Merge remote-tracking branch 'origin/sub_laptop_3' into main_laptop_1

# Conflicts:
#	M01_MasterData/M01_MasterData_Router.py
This commit is contained in:
2026-11-01 16:05:01 +09:00
17 changed files with 582 additions and 54 deletions
+2 -1
View File
@@ -18,6 +18,7 @@ from M01_MasterData import M01_MasterData_Store_Flow as flow
from M01_MasterData import M01_MasterData_Store_List as store_list
from M01_MasterData import M01_MasterData_Store_Make as make
from M01_MasterData import M01_MasterData_Store_Revise as revise
from M01_MasterData import M01_MasterData_Store_Sheet as sheet
import master_basis as mbs # noqa: E402 (`store` 가 scripts 를 길에 둠)
@@ -275,7 +276,7 @@ def post_text(body: CalcBody) -> dict:
if got is not None:
return got
with store.cm.mf.mp.choosing(body.고름):
return _call(store.text, body.key, body.inputs, body.row, body.file)
return _call(sheet.text, body.key, body.inputs, body.row, body.file) # 줄 덧칸(714-1)
@router.post("/save")
+5 -7
View File
@@ -17,6 +17,7 @@ from config import config_system
from M01_MasterData import M01_MasterData_Store as store
cm, mk, mcb = store.cm, store.mk, store.mcb
import master_unit as mu # noqa: E402 — `store` 가 scripts 를 길에 둔 뒤(712-2)
FILE = mcb.FILE
OWNERS = mcb.OWNERS
@@ -150,9 +151,6 @@ def combo(key: str) -> dict:
}
_PER = re.compile(
r"원\s*/\s*(\d[\d,]*\.?\d*|\.\d+)?\s*([^\s·(\d,.][^\s·(]*)"
) # 「원/1,000본」 = 배 1000
_TAIL = re.compile(r"\s*\([^()]*\)\s*$")
@@ -177,7 +175,7 @@ def combo_pills(row: dict) -> dict:
got = whole.logic(code)
except cm.mf.FormulaError:
continue
per = _PER.findall(str(got.get("결과단위") or ""))
per = mu.per(got.get("결과단위")) # 결과단위 배 읽기 한 벌(712-2)
if not per:
continue
# ponytail: 분모가 여럿(「원/㎡ · 원/㎥(단위당 따름)」)이면 「㎡ · ㎥」 한 글 — 입력이 고름
@@ -187,9 +185,9 @@ def combo_pills(row: dict) -> dict:
(name, unit), {"키": f"{name}|{unit}", "이름": name, "단위": unit, "로직": []}
)
pill["로직"].append(code)
times = per[0][0].replace(",", "")
if len(per) == 1 and times and float(times) != 1:
pill["배"] = float(times) if "." in times else int(times)
times = per[0][0]
if len(per) == 1 and times != 1:
pill["배"] = int(times) if times == times.to_integral_value() else float(times)
return {"키": row.get("키"), "이름": row.get("이름"), "물량": list(pills.values()), "조건": []}
@@ -0,0 +1,27 @@
"""M01 `/text` 계산서 줄 덧칸(PLAN 714-1) — `store.text` 답에 줄마다 쓰는 입력 · 묶음 · 기준단위 ·
환산 근거(`master_sheet_line.annotate` — M02 `/logic-lib/sheet` 와 한 벌) · 서버 단독(③) · 저장 안 함.
`M01_MasterData_Store.py` 는 700 줄 근처라 여기서 감쌈."""
from __future__ import annotations
from M01_MasterData import M01_MasterData_Store as store
mf = store.cm.mf
import master_sheet_line as msl # noqa: E402 — `store` 가 scripts 를 길에 둔 뒤
def text(key: str, inputs: dict, row: dict | None = None, file: str | None = None) -> dict:
got = store.text(key, inputs, row, file)
if not isinstance(got, dict) or not got.get("ok"):
return got
given = {k: store._dec(v) for k, v in inputs.items()}
try:
if row is None:
master = store.loaded()[1]
else: # 저장 전 시험 — `store.text` 와 같은 메모리 사본
files = store.cm.load(folder=store.FOLDER)
key = store._swap(files, str(row.get("키") or key), row, file)
master = mf.Master(files)
return msl.annotate(master, key, mf.fill_empty(master.logic(key), given), got)
except (mf.FormulaError, ArithmeticError, KeyError, TypeError, ValueError):
return got