- 끝수 한 곳 `master_cut.py`(B09 `rounddown` 재사용) — 엔진 답에 입힘: 줄 비목마다 0.1 원 버림 · 하위 로직 줄 = 하위 끝수 계 × 수량 · 덧줄 = 버린 줄 합으로 다시 셈 · 비목 합 1 원 버림 · 중간 칸도 버린 값 - 쓰는 곳: M01 시험 계산(`check_master.calc`) · 읽는 식(`master_text.lines`) · 옛 조합 미리보기(`master_combo`) · M02 `run_line`(단가산출 · 일위대가 · 펼침) · 별도계상 뺀 기준 · 켜쌓기율 곱 뒤 · 일위대가 반영 · 반영합 · 비율 줄 · 사전조합 안 줄 - 일위대가 반영 TS 짝(`Labor_Calc.ts`) 같은 끝수 · 거울 헬퍼가 상대 경로 .ts 가져옴 - B09 = `run_line(raw=True)` 엔진 날 값(제 단가로 다시 버림 · % 덧줄 율 비 그대로) — 검증_sub3 B09 247 칸 전후 같음 - `master_text` 꼴 셋 = `common_util_money` 로 갈음(줄 금액 `fmt_line_money` · 식 안 금액 = 버린 0.1 원) - 화면: 상세 줄 금액 · 시험 계산 줄 · 중간 돈 = `formatLineMoney` · 일위대가 반영 칸 0.1 원 · 상세 바닥 · 박스 · 인력재료경비 비목 소계 = 줄 합 1 원 버림 - 테스트1 네 보기 · 서고 목록 = 124,419(옛 124,420 / 124,419.85) · 재료 줄 11,694.6 + 23,425.6 + 1,404.8 = 소계 36,525 - 새 지킴 시험 test_751_3_money_cut - 옛 날 금액(끝수 없음)을 대조하던 시험 24 파일 고침 — 까닭 = 금액 규칙이 줄 0.1 원 · 소계 1 원 버림으로 바뀜(고정 값 → 새 값 · 줄 합 = 계 → 줄 합 아래 비목마다 1 원 안 · 곱 비 = 끝수 폭 안) · 실무 xlsx 영월 엑셀 같음 22 → 23 · 이어 붙이는 TS 시험(704_3 · 717_2b)에 `rounddown` 같은 식 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
61 lines
3.0 KiB
Python
61 lines
3.0 KiB
Python
"""% 덧줄 표기(PLAN 149-4) — 식 「X * Y / 100」 덧줄 = 덧칸 율 · 규격 · 금액 · 단위 · 수량 그대로.
|
|
|
|
- M02 `run_line` → 큰돌쌓기 찰쌓기 제잡비 설치 9 · 안 함 3 · 「노무비의 %」
|
|
- 인력 줄 합 밑수 = 「인건비의 %」 · 호표 줄 밑수 = 「그 줄 이름의 %」 · 금액 식(기계손료) = 덧칸 없음
|
|
- M01 시험계산(`post_calc`) 도 같은 도우미 · 화면 두 곳은 `pctView` 한 벌
|
|
"""
|
|
|
|
from decimal import Decimal
|
|
from pathlib import Path
|
|
|
|
from M01_MasterData import M01_MasterData_Router as m01_router
|
|
from M01_MasterData import M01_MasterData_Store as m01
|
|
from M02_MasterTemplete import M02_Labor_Doc as labor
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
|
|
|
|
def _extra(code: str, given: dict | None = None, name: str | None = None) -> dict:
|
|
got = labor.run_line(m01.loaded()[1], code, given or {})
|
|
assert got["까닭"] is None
|
|
lines = [x for x in got["줄"] if x.get("단위") == "식" and (name is None or x["이름"] == name)]
|
|
assert lines, code
|
|
return {**lines[-1], "_기준": got["기준"]}
|
|
|
|
|
|
def test_큰돌쌓기_찰쌓기_제잡비_율_설치_9_안함_3_금액_그대로():
|
|
for pipe, rate in (("설치", 9), ("설치 안 함", 3)):
|
|
x = _extra("GF000227", {"물빼기파이프": pipe}, "제잡비")
|
|
assert x["율"] == Decimal(rate) and x["규격"] == "노무비의 %"
|
|
assert x["단위"] == "식" and x["수량"] == 1 # 엔진 줄은 그대로 · 표기는 화면
|
|
labor_sum = x["_기준"]["노무비"]
|
|
# 751-3 — % 밑 = 버린 줄 합(소계 1 원 버림 전) · 금액 0.1 원 버림
|
|
assert abs(x["금액"] - labor_sum * rate / 100) <= Decimal(rate) / 100 + Decimal("0.1")
|
|
|
|
|
|
def test_인건비_호표줄_밑수_금액식은_덧칸_없음():
|
|
x = _extra("GC000198")
|
|
assert x["율"] == 2 and x["규격"] == "인건비의 %"
|
|
x = _extra("GF000002", name="잡품")
|
|
assert x["규격"] == "휘발유(체인톱)의 %" and x["율"] > 0
|
|
mach = _extra("GC000267", name="기계손료")
|
|
assert "율" not in mach and "규격" not in mach
|
|
mat = _extra("GC000267", name="잡재료비")
|
|
assert mat["규격"] == "재료비의 %"
|
|
|
|
|
|
def test_M01_시험계산도_율_규격():
|
|
given = {"물빼기파이프": "설치", "직경": "60", "지역": "전국평균", "보정작업": "해당 없음"}
|
|
got = m01_router.post_calc(m01_router.CalcBody(key="GF000227", inputs=given))
|
|
extra = [x for x in got["lines"] if x["이름"] == "제잡비"][0]
|
|
assert extra["율"] == 9 and extra["규격"] == "노무비의 %"
|
|
|
|
|
|
def test_화면_두_곳_pctView_한_벌():
|
|
api = (ROOT / "M01_MasterData/M01_MasterData_UI_Logic_Api.ts").read_text("utf-8")
|
|
assert "x.율 == null" in api and 'qty: x.율, unit: "%"' in api
|
|
rows = (ROOT / "M02_MasterTemplete/M02_MasterTemplete_Labor_Rows.ts").read_text("utf-8")
|
|
assert "const shown = pctView(x);" in rows and "qty: shown.qty," in rows
|
|
calc = (ROOT / "M01_MasterData/M01_MasterData_UI_Logic_Calc.ts").read_text("utf-8")
|
|
assert "formatNumber(pctView(line).qty)" in calc
|