Files
Aislo/resources/tester/test_786_2_check_modal.py
eomsangdonandClaude Opus 5.5 e91fd4398e feat(786-2): 불러오기 [수정] → 모달 「확인 — 제N호표」 옛 꼴 되살림 · 새 기능 「새」 배지
- 새 Hopyo_Check(모달 껍데기 · 머리 = 호표 · 엑셀 단가 · 제안 n / 줄 m · 확인 n · 만든 일위대가 ·
  [호표 제안 모두 확인](새) · [일위대가 생성] = 옮기기 길 이 호표만 · [구조물 조합으로] · [엑셀 보기])
- 새 Hopyo_CheckRows(로직 표 + 자재 표 = 구조물 조합 상세 꼴 · Labor_Rows moneyCell · PRICE_SLOTS ·
  Labor_MatMarks 빌려 씀 · 칸마다 엑셀 / 우리 단가 · 품 비교 · [고르기] · [원문 보기] · [옵션] · 추가 / 로직없음)
- 새 Hopyo_ToItem(구조물 조합 나무 add-item → 그 일위대가 문서에 SC 참조 한 줄 · 옮겨진 뒤만 켬)
- Hopyo_Rows: 시트 아래 줄 판 몸 걷음 → 줄 칸 부품 createRowKit(판정 · 고름 칩 · 블록 풀이 · 단위 환산 · [확인]) ·
  옮기기 한 번 runMove(오른쪽 [옮기기] · 모달 [일위대가 생성] 한 벌)
- Router: POST /hopyo/{키}/price 우리 금액 미리 셈(저장 없음 · Make.Move.pick · Lines.picks → Labor_Doc.calc 재사용)
- Sheet: [수정] = openHopyoCheck · 시트 아래 자리는 단가산출 블록 판(SheetSk) 몫으로 남김
- 안 살림: 맞음·별칭 일괄 체크 · 품셈으로 바꾸기 · 모두 고정으로(지운 서버 길 몫) · 사용안함(새 옮기기 길에 뺌 없음)
- 시험: 새 test_786_2_check_modal(우리 금액 예시 1 = 94,227 · 예시 3 입력 필요 → 0 · 쓰기 0 · 모달 · 새 배지 ·
  공용 import 만 · 날 button/input 0) · test_642_6 단언 = 줄 판 createJudgeRows → 모달 openHopyoCheck(까닭: 줄 판 몸 걷음)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 07:26:37 +09:00

124 lines
6.0 KiB
Python

# -*- coding: utf-8 -*-
"""786-2 불러오기 [수정] 모달 지킴 — 「확인 — 제N호표」 옛 꼴 되살림 + 새 기능 「새」 표지
(요구 644 · 645).
- 우리 금액 길(`/hopyo/{키}/price` · 저장 없음) — 옮기기와 같은 길로 한 줄 문서 →
`Labor_Doc.calc`: 예시 1 야면석소운반(단산10 · GC001140 · 입력 필요 0 · 엑셀 1 단위 94,227) ·
예시 3 합판거푸집(GC000211 · 높이감률 · 구멍땜 입력 필요 → 0 넣으면 노무 38,291) ·
쓰기 0(SC · SK 수 그대로)
- 화면 소스 — [수정] = 모달(`openHopyoCheck` · 부품 상자 모달) · 시트 아래 호표 줄 판 몸 없음 ·
「새」 배지 · 구조물 조합 공용 부품(`Labor_Rows` · `Labor_MatMarks` · `Labor_Input` ·
`Labor_Pick`)은 import 만 · 날 button · input · select 0 · 700 줄
임시 storage(`client` 마당) · M01 원본 그대로.
"""
import re
from pathlib import Path
from M02_MasterTemplete import M02_Hopyo_Judge as judge
from M02_MasterTemplete import M02_Template_Layers as layers
# ruff: noqa: F811
from resources.tester.test_m02_hopyo_excel import _post, client, master_hash # noqa: F401
ROOT = Path(__file__).resolve().parents[2]
M02 = ROOT / "M02_MasterTemplete"
API = "/api/m02/layers/personal"
KEY = "HP-000001"
MINE = ("Check", "CheckRows", "ToItem", "Rows")
SHARED = ("Labor_Rows", "Labor_MatMarks", "Labor_Input", "Labor_Pick", "Labor_Detail", "Structure")
def _src(name: str) -> str:
return (M02 / f"M02_MasterTemplete_{name}.ts").read_text(encoding="utf-8")
def _at(unit, no):
return next(r for r in unit["줄"] if r.get("번") == no and "단가산출" in r["갈래"])
def _base(row):
part = row["풀이"]["절"][0]
cand = next(c for c in part["후보"] if c["키"] == part["고름"])
return {"갈래": "기초", "키": cand["키"], "입력값": cand["바인딩"]["입력값"]}
def _count(kind):
folder = layers.personal_dir(7, 42) / kind
return len(list(folder.glob("*.json"))) if folder.exists() else 0
def test_우리금액_옮기기와_같은_길_저장없음(client):
before = master_hash()
assert _post(client).status_code == 200
judge.solve_all(layers.personal_dir(7, 42), KEY)
made = (_count("precombo"), _count("sangeun"))
url = f"{API}/hopyo/{KEY}/price"
two = client.get(f"{API}/hopyo-judge/{KEY}/2").json()
ten = _at(two, 10) # 예시 1 야면석소운반
got = client.post(
url, json={"층": "personal", "호표": 2, "줄": {str(ten["차례"]): [_base(ten)]}}
)
assert got.status_code == 200, got.text
line = got.json()["줄"][str(ten["차례"])]
assert line["까닭"] == [] and line["칸"] == []
assert int(line["금액"]["계"] / ten["수량"]["엑셀"]) == 94227 == ten["단가"]["계"]
one = client.get(f"{API}/hopyo-judge/{KEY}/1").json()
form = _at(one, 24) # 예시 3 합판거푸집
ex3 = _base(form)
need = client.post(url, json={"층": "personal", "호표": 1, "줄": {str(form["차례"]): [ex3]}})
stuck = need.json()["줄"][str(form["차례"])]
assert stuck["금액"] is None and stuck["칸"] == ["높이감률", "구멍땜"]
ex3["입력값"] = {**ex3["입력값"], "높이감률": 0, "구멍땜": 0}
ok = client.post(url, json={"층": "personal", "호표": 1, "줄": {str(form["차례"]): [ex3]}})
money = ok.json()["줄"][str(form["차례"])]["금액"]
assert abs(money["노무비"] / form["수량"]["엑셀"] - 38291) <= 2 # 엑셀 노무 38,291(줄 0.1 원 끝수)
bad = client.post(
url, json={"층": "personal", "호표": 2, "줄": {"0": [{**_base(ten), "금액": 1}]}}
)
assert bad.status_code == 422 # 금액 칸 = 서버가 셈
assert (_count("precombo"), _count("sangeun")) == made # 쓰기 0
assert master_hash() == before
def test_수정은_모달_줄판몸_없음():
sheet = _src("Hopyo_Sheet")
edit = sheet.split("const editButton")[1].split("function paintList")[0]
assert "openHopyoCheck({" in edit and "openLines" not in edit
assert "createJudgeRows" not in sheet + _src("Hopyo_Rows")
check = _src("Hopyo_Check")
assert 'from "@ui/ui_template_modal"' in check and "openModal({" in check
assert 'L("M02_CheckTitle")' in check and "confirmSuggested(" in check # [호표 제안 모두 확인]
assert "runMove(" in check and "[String(no)]: mine" in check # [사전조합 생성] = 이 호표만
assert "h.만든" in check.split("const item = ")[1].split(";")[0] # 옮겨진 뒤만
locale = (ROOT / "ui_template/ui_template_locale_m2_judge.ts").read_text(encoding="utf-8")
assert 'M02_CheckTitle: ["확인 — 제{n}호표"' in locale and 'M02_CheckNew: ["새"' in locale
def test_새_배지_옛_표_꼴():
rows = _src("Hopyo_CheckRows")
assert "createBadge(" in rows and "newBadge()" in rows and "dataset.checkNew" in rows
assert "newBadge()" in _src("Hopyo_Check")
for part in ("moneyCell(", "PRICE_SLOTS", "markCells(", "markHeads()", '"logic"', '"mat"'):
assert part in rows, part
assert "M02_CheckApart" in _src("Hopyo_Rows") # 별도계상 줄 = 고름 칩 없이 글
def test_공용파일_import_만_부품상자만_700줄():
texts = {n: _src(f"Hopyo_{n}") for n in MINE}
joined = "\n".join(texts.values())
for name in ("Labor_Rows", "Labor_MatMarks", "Labor_Input", "Labor_Pick"):
assert f'from "./M02_MasterTemplete_{name}"' in joined, name
for name in SHARED: # 공용 쪽은 새 모달을 모름(거꾸로 이음 없음)
assert "Hopyo_Check" not in _src(name) and "Hopyo_ToItem" not in _src(name), name
for name, text in texts.items():
assert len(text.splitlines()) <= 700, name
assert not re.search(r"""\bel\(\s*["'](button|input|select)["']""", text), name
assert not re.search(r"""createElement\(\s*["'](button|input|select)["']""", text), name
assert "<button" not in text and "<input" not in text, name
assert not re.search(r"#[0-9a-fA-F]{3,6}\b|rgba?\(", text), name
assert len(_src("Hopyo_Sheet").splitlines()) <= 402 # 늘리지 않음