feat(b08): 구조물도 줄마다 반올림 칸 — 엑셀 함수 이름을 함께, 원단위도 m당 반올림 × 연장
- 식 칸 옆 반올림 고르개·자리수 · 고르개에 「버림 — 엑셀 ROUNDDOWN」처럼 엑셀 이름과 음수 보기 - 고친 반올림은 고친 식과 같은 자리(양식 + 프로젝트)에 저장 · 양식과 같으면 지움 · [양식대로]로 식·반올림 함께 되돌림 - build_table 도 양식을 m당(L=1)으로 풀고 연장을 곱함 — 실무 시트처럼 뒷줄이 반올림한 값을 보고 구조물도와 안 갈림 - 「대안 후보」(물구멍 2.5㎡ 등) 표 밑에 보임 · UI 700줄 넘어 식 칸 표를 _Formula.ts 로 뗌 - 시험 2개 추가 · 전체 1533 통과 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq
This commit is contained in:
@@ -167,6 +167,76 @@ def test_식을_고쳐_저장하면_서버가_다시_풀고_되돌릴_수_있다
|
||||
assert stored["quantity"]["structure_formula_overrides"] == {}
|
||||
|
||||
|
||||
def test_줄마다_반올림을_고치면_m당에서_반올림하고_뒷줄이_그_값을_본다(
|
||||
client: TestClient, project: Path
|
||||
) -> None:
|
||||
"""PLAN 3장 반올림 칸 — 실무 구조물도처럼 m당 값을 반올림 · 원단위는 m당 × 연장."""
|
||||
sheet = _sheet(client)
|
||||
rows = {row["name"]: row for row in sheet["rows"]}
|
||||
area = rows["돌쌓기"]["unit_amount"] # 2.5 × √1.09 ≈ 2.61
|
||||
saved = client.put(
|
||||
f"{SHEETS}/formulas",
|
||||
json={
|
||||
"sheet_key": sheet["key"],
|
||||
"rows": [
|
||||
{
|
||||
"seq": rows["돌쌓기"]["no"],
|
||||
"formula": None,
|
||||
"rounding": {"mode": "floor", "digits": 0},
|
||||
}
|
||||
],
|
||||
},
|
||||
)
|
||||
assert saved.status_code == 200 and saved.json()["changed"] == 1, saved.text
|
||||
after = {row["name"]: row for row in _sheet(client)["rows"]}
|
||||
assert after["돌쌓기"]["unit_amount"] == pytest.approx(2.0) and area > 2.5
|
||||
assert after["돌쌓기"]["source"] == "user"
|
||||
assert after["돌쌓기"]["formula"] == rows["돌쌓기"]["formula"] # 식은 그대로
|
||||
assert after["돌쌓기"]["default_rounding"] == {"mode": "none", "digits": 0}
|
||||
# 뒷줄(모르터 = A × 0.009)이 반올림한 A 를 봄.
|
||||
assert after["모르터"]["unit_amount"] == pytest.approx(2.0 * 0.009)
|
||||
stored = json.loads((project / "project_settings.json").read_text(encoding="utf-8"))
|
||||
assert stored["quantity"]["structure_formula_overrides"]["masonry_wet"] == {
|
||||
str(rows["돌쌓기"]["no"]): {"rounding": {"mode": "floor", "digits": 0}}
|
||||
}
|
||||
|
||||
# 원단위(build_table) = m당 반올림 값 × 연장 10m — 합계를 반올림하지 않음.
|
||||
from B08_Quantity.B08_Quantity_Engine_UnitQuantity import build_table
|
||||
from B08_Quantity.B08_Quantity_Router_Material import _collect_structures
|
||||
|
||||
structures, names, _ = _collect_structures(str(project))
|
||||
table = build_table(
|
||||
structures, names, structure_formulas=stored["quantity"]["structure_formula_overrides"]
|
||||
)
|
||||
parts = {c["name"]: c for c in table["structures"][0]["components"]}
|
||||
assert parts["돌쌓기"]["amount"] == pytest.approx(20.0)
|
||||
assert parts["모르터"]["amount"] == pytest.approx(0.18)
|
||||
assert parts["돌쌓기"]["basis"] == "사용자 반올림 = INT 0자리 (양식 안 함)"
|
||||
|
||||
# 되돌리기 — 반올림 null 이면 양식대로, 저장 칸에서도 지워짐.
|
||||
client.put(
|
||||
f"{SHEETS}/formulas",
|
||||
json={"sheet_key": sheet["key"], "rows": [{"seq": rows["돌쌓기"]["no"], "rounding": None}]},
|
||||
)
|
||||
stored = json.loads((project / "project_settings.json").read_text(encoding="utf-8"))
|
||||
assert stored["quantity"]["structure_formula_overrides"] == {}
|
||||
# 모르는 갈래는 받지 않음.
|
||||
bad = client.put(
|
||||
f"{SHEETS}/formulas",
|
||||
json={
|
||||
"sheet_key": sheet["key"],
|
||||
"rows": [{"seq": 1, "rounding": {"mode": "bankers", "digits": 0}}],
|
||||
},
|
||||
)
|
||||
assert bad.status_code == 422
|
||||
|
||||
|
||||
def test_대안_후보를_싣는다(client: TestClient) -> None:
|
||||
candidates = {item["name"]: item for item in _sheet(client)["var_candidates"]}
|
||||
assert candidates["HOLE_AREA"]["value"] == 2
|
||||
assert candidates["HOLE_AREA"]["candidates"][0]["value"] == 2.5
|
||||
|
||||
|
||||
def test_제원을_고쳐도_고친_식이_따라간다(client: TestClient) -> None:
|
||||
"""고친 식은 양식 + 프로젝트에 묶임 — 뒷길이를 고쳐 장 이름이 바뀌어도 사용자 식이 남음."""
|
||||
sheet = _sheet(client)
|
||||
|
||||
Reference in New Issue
Block a user