Files
Aislo/resources/tester/test_b09_material_prices.py
T

93 lines
4.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""자재 수동 단가(PLAN 1장 Ⓐ · 2026-09-14 브레인 판정).
지키는 것
① 키 = 코드(`AR-M-…`) · 코드 없는 자재만 「이름 규격」 — 조립엔 코드 키만 얹음
② 0 이하·수 아님은 안 받음 · 비우면 지움 · 값·출처가 같으면 넣은 날 그대로
③ 넣으면 자재 제목(6번 슬롯)이 서고 자원 축 자재 줄이 붙어 재료비가 섬 — 안 넣으면 종전 벌 그대로
④ 수동 단가가 닿은 내역 줄 = 금액은 서되 「미확정 N건」
"""
from __future__ import annotations
import sys
from decimal import Decimal
from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(ROOT))
from B09_Estimation.B09_Estimation_MaterialPrices import ( # noqa: E402
MaterialPriceError,
build_key,
listing,
merge,
)
from B09_Estimation.B09_Estimation_UnitPrice import cached_build # noqa: E402
STAKE = "AR-M-dce99e46" # 말뚝 직경4~6㎝ — FP-05-15 에 2개/단위
def test_키와_넣은_날() -> None:
first = merge({}, [{"key": STAKE, "price_krw": "1,500", "source": "견적 A"}], "2026-09-14")
assert first[STAKE]["price_krw"] == "1500" and first[STAKE]["entered_at"] == "2026-09-14"
same = merge(first, [{"key": STAKE, "price_krw": "1500", "source": "견적 A"}], "2026-09-20")
assert same[STAKE]["entered_at"] == "2026-09-14" # 다시 저장해도 안 바뀜
moved = merge(first, [{"key": STAKE, "price_krw": "1600", "source": "견적 A"}], "2026-09-20")
assert moved[STAKE]["entered_at"] == "2026-09-20"
assert merge(first, [{"key": STAKE, "price_krw": ""}], "2026-09-20") == {}
for bad in ("0", "-3", "abc"):
with pytest.raises(MaterialPriceError):
merge({}, [{"key": STAKE, "price_krw": bad}], "2026-09-14")
named = merge(first, [{"key": "각재 50×50", "price_krw": "900000"}], "2026-09-14")
assert build_key(named) == ((STAKE, "1500", "견적 A"),) # 이름 키는 조립에 안 얹음
def test_넣으면_재료비가_서고_안_넣으면_종전_그대로() -> None:
base = cached_build()
assert base.book.resolve("B-FP-05-15").material == 0
assert STAKE not in base.book.titles and not base.manual_materials
built = cached_build(material_prices=((STAKE, "1500", "견적 A"),))
title = built.book.titles[STAKE]
assert (title.slots[5], title.slot_pages[5], title.unit) == (Decimal("1500"), "견적 A", "개")
assert built.book.resolve("B-FP-05-15").material == Decimal("3000") # 2개 × 1,500
assert built.book.resolve("B-FP-05-15").labor == base.book.resolve("B-FP-05-15").labor
assert "FP-05-15" in built.material_uses[STAKE]
def test_내역_줄은_미확정으로_선다() -> None:
from B09_Estimation.B09_Estimation_BillOfQuantities import build_bill
built = cached_build(material_prices=((STAKE, "1500", "견적 A"),))
payload = {
"work_items": [
{
"work_item_code": "FP-05-15",
"name": "말뚝박기",
"unit": built.book.titles["B-FP-05-15"].unit,
"quantity": 10,
"in_bill": True,
}
],
"materials": [],
}
row = next(r for r in build_bill(payload, build=built).rows if r.name == "말뚝박기")
assert row.material_krw == Decimal("30000") and row.unconfirmed == 1
result = build_bill(payload, build=built)
assert result.unconfirmed == [{"name": "말뚝박기", "code": "B-FP-05-15", "count": 1}]
plain = build_bill(payload, build=cached_build())
assert not plain.unconfirmed
def test_목록은_자원_축_자재와_사라진_저장_줄() -> None:
built = cached_build()
stored = {
STAKE: {"price_krw": "1500"},
"AR-M-00000000": {"price_krw": "7", "name": "옛 자재"},
}
rows = {row["key"]: row for row in listing(built, stored)}
assert rows[STAKE]["name"] == "말뚝" and rows[STAKE]["price_krw"] == "1500"
assert rows["AR-M-00000000"]["missing"] is True # 조용히 안 버림
assert rows["AR-M-b0853497"]["price_krw"] is None