fix(b09): 구조물도 호표 내역 단가를 호표 계금으로 — 화면과 1원 갈림 없앰
- 내역 단가 = 구조물도 일위대가 표 계금(성분 칸 0.1원 절사 합의 1원 절사), 금액 = 성분 소계 × 연장 - 명세 7장 「호표 안 성분 소계는 절사」 — 안 자른 값을 쓰면 192,429 ↔ 192,430 으로 갈렸음 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq
This commit is contained in:
@@ -130,11 +130,16 @@ def price_sheets(
|
||||
library: Iterable[dict[str, Any]],
|
||||
manual_all: dict[str, Any] | None = None,
|
||||
) -> dict[str, dict[str, Any]]:
|
||||
"""B09 내역이 쓸 호표 금액 `{B-AX-ST-…#키: {money, blocked, unconfirmed, reasons}}`.
|
||||
"""B09 내역이 쓸 호표 금액 `{B-AX-ST-…#키: {money, total, blocked, unconfirmed, reasons}}`.
|
||||
|
||||
`money` 는 **안 자른** 단위(m)당 3분할 — 자르기는 내역 줄 자리 규칙(B09)이 함.
|
||||
⚠ `money` 는 **호표 표의 성분 소계**(칸마다 0.1원 절사한 합) · `total` 은 계금(1원 절사) —
|
||||
명세 7장 「호표 안 성분 소계는 절사」. 안 자른 값을 쓰면 구조물도 화면(192,429)과
|
||||
내역 단가(192,430)가 1원 갈림(2026-09-13 검증 프로젝트 실측).
|
||||
"""
|
||||
from decimal import Decimal
|
||||
|
||||
from B08_Quantity.B08_Quantity_Engine_StructureUnitPrice import unit_price_money
|
||||
from B09_Estimation.B09_Estimation_PriceBook import Money3
|
||||
|
||||
prices: dict[str, dict[str, Any]] = {}
|
||||
library = list(library)
|
||||
@@ -149,9 +154,10 @@ def price_sheets(
|
||||
)
|
||||
if assembled is None:
|
||||
continue
|
||||
table, money = assembled
|
||||
table, _exact = assembled
|
||||
prices[structure_price_code(entry["code"], entry["key"])] = {
|
||||
"money": money,
|
||||
"money": Money3(*(Decimal(str(table[k])) for k in ("material", "labor", "expense"))),
|
||||
"total": Decimal(str(table["total"])),
|
||||
"blocked": table["blocked"],
|
||||
"unconfirmed": table["unconfirmed"],
|
||||
"reasons": [
|
||||
|
||||
@@ -140,9 +140,9 @@ def _structure_price_row(
|
||||
)
|
||||
return row
|
||||
|
||||
money = entry["money"]
|
||||
line = money.scaled(item.quantity)
|
||||
row.unit_price_krw = round_at(money.total, OutputPlace.UNIT_PRICE_ROW)
|
||||
# 단가 = 호표 계금(구조물도 화면과 같은 값) · 금액 = 호표 성분 소계 × 수량(명세 7장).
|
||||
line = entry["money"].scaled(item.quantity)
|
||||
row.unit_price_krw = entry["total"]
|
||||
row.amount_krw = round_at(line.total, OutputPlace.BOQ_ROW)
|
||||
row.material_krw = line.material
|
||||
row.labor_krw = line.labor
|
||||
|
||||
@@ -104,8 +104,19 @@ def test_내역은_호표_금액에_연장을_곱한다() -> None:
|
||||
row = next(r for r in bill.rows if r.code == entries[0]["code"])
|
||||
# 모르터 공종 코드가 선 뒤(랩탑 메인 AX-WK) 찰쌓기 호표 세 줄이 다 섬.
|
||||
assert not entry["blocked"], entry["reasons"]
|
||||
assert row.unit_price_krw == round_at(entry["money"].total, OutputPlace.UNIT_PRICE_ROW)
|
||||
assert row.amount_krw == round_at(entry["money"].scaled(Decimal(10)).total, OutputPlace.BOQ_ROW)
|
||||
# 단가 = 구조물도 일위대가 표 계금 그대로(화면과 한 값) · 금액 = 성분 소계 × 연장.
|
||||
from B08_Quantity.B08_Quantity_Engine_StructureUnitPrice import unit_price_table
|
||||
|
||||
table = unit_price_table(
|
||||
entries[0]["template"],
|
||||
entries[0]["sheet"],
|
||||
_build().book,
|
||||
lambda code, value: find_variant_code(code, value, _build()),
|
||||
[load_template("masonry_wet")],
|
||||
)
|
||||
assert row.unit_price_krw == Decimal(str(table["total"]))
|
||||
cells = sum(Decimal(str(table[k])) for k in ("material", "labor", "expense"))
|
||||
assert row.amount_krw == round_at(cells * Decimal(10), OutputPlace.BOQ_ROW)
|
||||
assert row.quantity == Decimal(10) and f"호표 {ref}" in row.note
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user