Files
Aislo/resources/tester/test_b09_composite_partial_parts.py
eomsangdonandClaude Opus 5 607e7c0cd8 fix(b09): 묶음 줄 금액이 줄 수량만큼 부풀던 것 — 조각 수량은 이미 합계
까닭 — B08 인계의 조각 수량은 「합계」인데(그쪽 시험이 지킴: BOX 동바리 3.92×10 ·
포장 97.66㎥) B09 가 Σ(조각 단가 × 조각 수량) 을 1단위 단가로 보고 줄 수량을 또 곱했음.
평떼 718.14㎡ 가 720배(42억)로 섰음(2026-09-15 랩탑 서브 실측).

고침 — 계약은 그대로 두고 읽는 쪽을 고침. 합계를 그대로 금액으로 쓰고 단가는 나눠서 보임.
재·노·경 성분 셋도 같이. 계약을 코드 가까이 못박음 — 두 자리(composite_parts 칸 · _composite_row).

 시험도 고침 — 종전이 줄 수량 1 로만 재서 못 잡았음. _line(parts, quantity) 로 열고
수량 2·10·718.14 로 잼 · 성분 셋도 따로. 빨강 4 확인한 뒤 고쳤음.

⚠ 지금 검증 프로젝트엔 값이 선 묶음 줄이 0 이라 금액 변화는 안 드러남 —
  BOX·포장·집수정·녹화가 서면 그때 제 값으로 섬.

전체 시험 2136 통과 · 28 건너뜀 · 1 xfail ·
1 실패는 내 변경과 무관한 노임 신뢰도 시험(아래 보고).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Prk9BCHG1EMAywk9k8wegA
2026-09-15 05:33:34 +09:00

86 lines
3.7 KiB
Python
Raw Permalink 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.
"""조립(묶음) 줄이 조각의 「일부만」·「밑수 없음」 을 올림 — 2026-09-14 브레인 ㉱ 첫째(구조 결함).
종전 `_composite_row` 는 조각 제목이 **있기만 하면** 금액에 더했음 → 조각 단가가 일부 몫만 섰거나(인력만)
밑수를 모르는 표여도 조립 줄이 **온전한 금액처럼** 섰음. 보통 줄은 그 둘을 막는데 조립 줄만 새던 자리.
⇒ 조각마다 보통 줄과 같은 두 검사 — 걸리면 금액을 안 세우고 어느 조각이 왜인지 사유.
"""
from __future__ import annotations
import pytest
from B09_Estimation.B09_Estimation_BillOfQuantities import build_bill
from B09_Estimation.B09_Estimation_UnitPrice import cached_build
def _composite(parts: list[dict], quantity: str = "1") -> dict:
return {
"work_items": [
{
"work_item_code": None,
"name": "시험 묶음",
"spec": "",
"unit": "개소",
"quantity": quantity,
"in_bill": True,
"composite_parts": parts,
"composite_not_ready": [],
}
],
"materials": [],
}
def _line(parts: list[dict], quantity: str = "1"):
rows = build_bill(_composite(parts, quantity)).rows
return next(r for r in rows if r.code is None and r.name == "시험 묶음")
def test_일부만_선_조각이_있으면_묶음_금액을_안_세우고_까닭() -> None:
build = cached_build()
partial = next(c for c in build.partial_ratio if f"B-{c}" in build.book.titles)
line = _line([{"code": partial, "quantity": 1}])
assert line.amount_krw is None, (partial, line.amount_krw)
assert partial in line.note and "일부만" in line.note, line.note
def test_밑수_없는_조각도_같이_막음() -> None:
build = cached_build()
missing = next(c for c in build.basis_missing if f"B-{c}" in build.book.titles)
line = _line([{"code": missing, "quantity": 1}])
assert line.amount_krw is None and "밑수" in line.note, (missing, line.note)
def test_온전한_조각만이면_종전대로_금액() -> None:
line = _line([{"code": "FP-09-15-02", "quantity": 2}])
assert line.amount_krw and line.amount_krw > 0, line.note
# ── 줄 수량이 1 이 아닐 때 — 2026-09-15 랩탑 서브가 찾은 부풀음 ──
#: ⭐ **인계 조각 수량은 「합계」다** — B08 계약이고 그쪽 시험이 지킴
#: (BOX 동바리 3.92×10 · 포장 97.66㎥).
#: 그래서 `Σ(조각 단가 × 조각 수량)` 이 이미 **그 줄 전체 금액**이다.
#: 줄 수량을 또 곱하면 배로 부푼다. 종전 시험이 **줄 수량 1 로만 재서** 못 잡았다 —
#: 평떼 718.14㎡ 가 720배(42억)로 섰다.
_PART = {"code": "FP-09-15-02", "quantity": 2}
@pytest.mark.parametrize("quantity", ["2", "10", "718.14"])
def test_묶음_금액은_줄_수량을_다시_안_곱한다(quantity) -> None:
"""조각이 합계이므로 **줄 수량이 몇이든 금액은 같다**. 단가는 그 금액 ÷ 수량으로 보인다."""
one = _line([_PART])
many = _line([_PART], quantity)
assert one.amount_krw and many.amount_krw, (one.amount_krw, many.amount_krw)
assert many.amount_krw == one.amount_krw, (quantity, many.amount_krw, one.amount_krw)
assert many.unit_price_krw < one.unit_price_krw, (quantity, many.unit_price_krw)
def test_묶음_성분도_줄_수량만큼_안_부푼다() -> None:
"""재·노·경 셋도 같이 봐야 함 — 합계만 보면 성분이 부푼 것을 놓친다."""
one, many = _line([_PART]), _line([_PART], "10")
assert (many.material_krw, many.labor_krw, many.expense_krw) == (
one.material_krw,
one.labor_krw,
one.expense_krw,
)