- 새 master_sheet_line.annotate — master_text.lines 답에 줄마다 덧칸(줄 차례 = 호표 _shares 비목 · 뒤 덧줄) · 머리 기준단위(결과단위 분모) - 쓰는입력 = 수량 식 · 요소 · 덧줄 식이 쓰는 로직 입력(중간값 거슬러 감) · 기준단위 = 줄이 찾는 표 기준(712-3 basis) · 환산근거 = 표 기준배 ↔ 결과단위 배 · 재료 품목 단위 ↔ 줄 단위(712-2 note) - M01 /text = 새 Store_Sheet 가 감쌈(Store.py · master_text.py 700 줄 근처라 안 늘림) · M02 /logic-lib/sheet 줄 칸에 같은 KEYS - 지킴 시험 test_714_1_sheet_line(두 길 같은 덧칸) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
63 lines
2.6 KiB
Python
63 lines
2.6 KiB
Python
"""714-1 지킴 — 계산서 줄 덧칸(쓰는 입력 · 묶음 · 기준단위 · 환산 근거) · M01 `/text` 와
|
|
M02 `/logic-lib/sheet` 가 같은 줄 꼴(`master_sheet_line`)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
sys.path.insert(0, str(ROOT))
|
|
|
|
from M01_MasterData import M01_MasterData_Store as store # noqa: E402
|
|
from M01_MasterData import M01_MasterData_Store_Sheet as sheet # noqa: E402
|
|
from M02_MasterTemplete import M02_Logic_Standard as standard # noqa: E402
|
|
|
|
msl = sheet.msl
|
|
|
|
|
|
def _text(key: str) -> dict:
|
|
auto = {k: v for k, v in store.auto(key)["값"].items() if v is not None}
|
|
return sheet.text(key, auto)
|
|
|
|
|
|
def _lines(got: dict, groups: str = "groups") -> list[dict]:
|
|
return [line for g in got[groups] for line in g["줄"]]
|
|
|
|
|
|
def test_line_keys_and_bundle():
|
|
got = _text("GF000103") # 구조물터파기 — 인력 + 굴착기 기계경비 줄
|
|
assert got["ok"] and got["기준단위"] == "㎥"
|
|
lines = _lines(got)
|
|
assert all({"쓰는입력", "묶음", "기준단위", "환산근거"} <= set(line) for line in lines)
|
|
machine = [line for line in lines if line.get("장비")]
|
|
assert machine and all(line["묶음"] == "경비" for line in machine)
|
|
assert {"지역", "보정작업"} <= set(machine[0]["쓰는입력"])
|
|
assert any(line["묶음"] == "인력" for line in lines)
|
|
|
|
|
|
def test_uses_follow_middle_values():
|
|
"""중간값을 거슬러 입력까지 — 돌쌓기 석공 품은 높이 · 쌓기 · 돌 입력을 씀."""
|
|
lines = _lines(_text("GF000219"))
|
|
assert {"높이", "쌓기", "돌"} <= set(lines[0]["쓰는입력"])
|
|
|
|
|
|
def test_basis_note_tenfold():
|
|
"""표 10㎡당 → 결과 원/㎡ 「÷10」 · 결과도 원/10㎡ 면 근거 없음."""
|
|
one = _lines(_text("GC000037"))
|
|
assert one[0]["기준단위"] == "10㎡" and one[0]["환산근거"] == "10㎡당 → 1㎡당 ÷10"
|
|
ten = _text("GF000124")
|
|
assert ten["기준단위"] == "10㎡" and all(not x["환산근거"] for x in _lines(ten))
|
|
|
|
|
|
def test_two_routes_same_shape():
|
|
"""M01 `/text` 와 M02 계산서 — 줄 차례 · 덧칸 값이 같음(금액 끝수만 다를 수 있음)."""
|
|
for key in ("GF000169", "GF000103", "GF000219"):
|
|
m01 = _lines(_text(key))
|
|
m02 = _lines(standard.sheet(key, {}), "묶음")
|
|
assert len(m01) == len(m02)
|
|
for a, b in zip(m01, m02):
|
|
assert set(b) == {"이름", "글", "금액", *msl.KEYS}
|
|
assert a["이름"] == b["이름"]
|
|
assert [a.get(k) for k in msl.KEYS] == [b.get(k) for k in msl.KEYS]
|