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

This commit is contained in:
2026-11-01 21:45:51 +09:00
9 changed files with 506 additions and 139 deletions
+10 -9
View File
@@ -27,20 +27,21 @@ def test_sk_list_layer_order_and_ref_shape():
order = re.search(r"LAYER_ORDER = \[([^\]]+)\]", pick).group(1)
assert [x.strip().strip('"') for x in order.split(",")] == ["system", "company", "personal"]
assert "[...scopes].sort((a, b) => rank(a) - rank(b))" in pick
assert "r.종류 === SANGEUN_KIND" in pick and 'SANGEUN_KIND = "sangeun"' in pick
assert "r.종류 === kind" in pick and 'SANGEUN_KIND = "sangeun"' in pick
assert "listLayerDocs(scopes, SANGEUN_KIND)" in pick
assert 'ref: { 층: at.층, 주인: at.층 === "system" ? null : at.주인, 키: r.이름 }' in pick
labor = _text(M02 / "M02_MasterTemplete_Labor_Pick.ts")
assert "lib?.pick(x.ref, x.제목 || x.이름);" in labor # SK 탭 줄 누름 = 참조
assert 'if (tab === "sk") return findSangeun(q);' in labor
# 721-2 — SK · 일위대가 탭은 찾아 넣기 창(Find_Pick) · 줄 누름 = 참조
find = _text(M02 / "M02_MasterTemplete_Find_Pick.ts")
assert "go: take(() => opt.ref?.(x.ref, x.제목 || x.이름))" in find
assert "sangeun: true," in _text(
M02 / "M02_MasterTemplete_Hopyo_Pick.ts"
) # 일위대가 [로직 추가]
) # 일위대가 [로직 추가] → 찾아 넣기 창
store_ts = _text(ROOT / "B09_Estimation" / "B09_Estimation_UI_Store.ts")
assert '["sangeun", "단가산출"],' in store_ts and "sangeun: sangeunItems," in store_ts
# 더한줄 고르기 — 715 이음 꼴 셋
assert 'done({ 종류: "로직", 로직: x.키, 입력값: {}, 수량: 1 })' in pick
assert "done({ 참조: ref, 수량: 1 })" in pick
assert 'done({ 종류: "재료", 요소: m.코드, 이름: m.이름, 단위: m.단위, 수량: 1 })' in pick
# 더한줄 고르기 — 715 이음 꼴 셋(인력 · 재료 = 요소 키)
assert 'logic: (x) => done({ 종류: "로직", 로직: x.키, 입력값: {}, 수량: 1 })' in pick
assert "ref: (ref) => done({ 참조: ref, 수량: 1 })" in pick
assert "done({ 종류: e.종류, 요소: e.코드, 이름: e.이름, 단위: e.단위, 수량: 1 })" in pick
def _sk(folder, name):
+106
View File
@@ -0,0 +1,106 @@
"""721 M02 찾아 넣기 창 — 단추 이름 · 자리 · 부르는 곳 · 인력 · 재료 줄 꼴(요구서_내역16 1장 5~7 · 2장 1 · 2 · 8).
- 721-1 단가산출 상세 = [기본 로직 선택]이 둘째 줄 [항목 추가] 왼쪽
- 721-2 M02 세 곳(기본 로직 선택 · 항목 추가 · 일위대가 [로직 추가])만 새 창 · B09 · 불러오기는 옛 창
- M01 전체 = 로직 · 인력(job) · 재료(price) · 기계 · 실무 호표 없음
- 고른 인력 · 재료 = 단가산출 더한줄 `{종류, 요소}` · 일위대가 고정 줄(705-1 이음 꼴) — 둘 다 서버가 받아 노임 · 자재 값으로 셈
"""
from __future__ import annotations
from pathlib import Path
import pytest
from M02_MasterTemplete import M02_Labor_Doc as labor
from M02_MasterTemplete import M02_Sangeun_Calc as calc
ROOT = Path(__file__).resolve().parents[2]
M02 = ROOT / "M02_MasterTemplete"
LB, MT = "LB000033", "MT000018" # 석공 · 합판(내수) — M01 에 있음
def _text(path: Path) -> str:
return path.read_text(encoding="utf-8")
def test_721_1_단추_이름과_자리():
detail = _text(M02 / "M02_MasterTemplete_Sangeun_Detail.ts")
assert "children: [views.root, pick, addButton, baseHint]" in detail
assert " pick,\n );" not in detail # 머리 줄에서 뺌
locale = _text(ROOT / "ui_template" / "ui_template_locale_m2.ts")
assert 'M02_SangeunPickBase: ["기본 로직 선택"' in locale
assert 'M02_SangeunAddLine: ["항목 추가"' in locale
def test_721_2_부르는_곳_셋만_새_창():
find = _text(M02 / "M02_MasterTemplete_Find_Pick.ts")
labor_pick = _text(M02 / "M02_MasterTemplete_Labor_Pick.ts")
assert 'if (lib?.sangeun && lib.layer !== "project")' in labor_pick
assert "return openFindPicker({" in labor_pick
assert "findSangeun" not in labor_pick # 옛 창의 단가산출 탭 걷음
assert "logicOnly: true," in _text(M02 / "M02_MasterTemplete_Sangeun_Detail.ts")
assert "openFindPicker({" in _text(M02 / "M02_MasterTemplete_Sangeun_Pick.ts")
assert "sangeun: true," in _text(M02 / "M02_MasterTemplete_Hopyo_Pick.ts") # 일위대가
# 옛 창 그대로 — B09 · 불러오기는 sangeun 없이 부름
for f in (
ROOT / "B09_Estimation" / "B09_Estimation_UI_Link.ts",
ROOT / "B09_Estimation" / "B09_Estimation_UI_Tabs_Bill_Link.ts",
M02 / "M02_MasterTemplete_Hopyo_Choose.ts",
M02 / "M02_MasterTemplete_Hopyo_Ledger.ts",
):
text = _text(f)
assert "openLogicPicker(" in text and "sangeun:" not in text, f.name
# 탭 셋 · 찾기 칸 하나 · 거름 고르기 없음 · M01 = 로직 · 인력 · 재료(기계 · 호표 없음)
for key in ('key: "m01"', 'key: "sk"', 'key: "pre"'):
assert key in find
assert "createSelectField" not in find and "Hopyo" not in find
assert '(kind: "job" | "price")' in find and "/elements" not in find
def test_721_2_고정_줄_꼴():
find = _text(M02 / "M02_MasterTemplete_Find_Pick.ts")
assert "이음: { 노임: labor ? e.코드 : null, 자재: labor ? null : e.코드, 기계: null }" in find
assert "go: put ? take(() => put(e))" in find
assert "dim: !put," in find # 받는 쪽 없으면 회색 막힘
def _fx(name: str, unit: str, code: str) -> dict:
"""`fixedOf` 꼴 — 인력 = 노임 이음 · 재료 = 자재 이음 · 단가 = 고를 때 값(셈은 단가 책)"""
labor_ = code.startswith("LB")
return {
"이름": name,
"규격": "",
"단위": unit,
"단가": {"노무비": 1 if labor_ else 0, "재료비": 0 if labor_ else 1, "경비": 0},
"이음": {"노임": code if labor_ else None, "자재": None if labor_ else code, "기계": None},
}
def test_721_2_인력_재료_서버가_받아_셈():
whole = labor.m01.loaded()[1]
wage = whole.get(LB)["값"]
sk = calc.calc_doc(
{
"키": "SK-000001",
"이름": "시험",
"단위": "㎡",
"바탕": None,
"더한줄": [
{"종류": "인력", "요소": LB, "이름": "석공", "단위": "인", "수량": 1},
{"종류": "재료", "요소": MT, "이름": "합판", "단위": "㎡", "수량": 1},
],
}
)["1단위"]
doc = labor.clean(
{
"담은로직": [
{"로직": "", "고정": _fx("석공", "인", LB), "수량": {"손": 1}},
{"로직": "", "고정": _fx("합판", "㎡", MT), "수량": {"손": 1}},
]
}
)
got = labor.calc(doc, {})
assert sk["노무비"] == pytest.approx(wage) and sk["재료비"] > 0
assert got["반영합"]["계"] == pytest.approx(sk["계"])
assert [ln["이은"] for ln in got["줄"]] == [["노무비"], ["재료비"]]