From a48770d11d9bc8eab08bb74ee36d0fb3a756f9a7 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Mon, 7 Sep 2026 20:23:16 +0900 Subject: [PATCH] =?UTF-8?q?fix(B09):=20=EA=B4=80=EA=B8=89=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EC=9D=80=20=E3=80=8C=EC=88=9C=EC=9E=90=EC=9E=AC?= =?UTF-8?q?=EB=8C=80=E3=80=8D=20=E2=80=94=20=EC=A1=B0=EB=8B=AC=EC=88=98?= =?UTF-8?q?=EC=88=98=EB=A3=8C=20=EC=B0=A8=EA=B0=90=20=EC=98=B5=EC=85=98=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `단수처리_규칙.md` §3 원문을 읽다 **입력 의미를 잘못 잡은 것**을 찾음. 실무 서류의 「관급자재대 69,850,000」은 이미 `ROUNDUP(순자재대 69,474,220 + 조달수수료 375,160, −3)` 한 값인데, 그 합계를 순자재대 자리에 넣고 있었음. 그래서 안전관리비 관급항이 부풀었고, 그 어긋남을 「조달수수료 차감 옵션」으로 덮고 있었음. - **입력을 순자재대·수수료로 나눠 넣는 것으로 정정.** 그러면 ㉮ 관급자재대 천원 올림 ㉯ 안전관리비 관급항 `순자재대 ÷ 1.1` 이 **둘 다 저절로 맞음**. - ⇒ `deduct_procurement_fee_for_safety` **옵션 제거**(엔진·법정경비·라우터). 8-10 의 「차감은 규정 문구가 아님」과 결론은 같되 이유가 더 단순함 — **애초에 수수료는 관급금액에 안 들어감.** - 잘못 넣는 사고를 테스트로 박음 — `test_owner_supplied_input_is_net_material_not_total` (합계를 넣으면 안전관리비가 8,629 원 = 375,160 ÷ 1.1 × 2.53 % 커짐). - 필드 주석에 「실무 서류의 관급자재대를 그대로 넣지 말 것」 경고 추가. 자체검증 — **관행 옵션 없이 기본값만으로** 두 벌 재현: 2024 요율 → 안전 16,586,996 · 총공사비 1,201,879,000 / 현행 요율 → 안전 **18,586,091**. 화면 실측(5174) — 안전관리비 A 18,586,091 채택 · 관급자재대 69,850,000. pytest 72 passed · ruff 통과 · tsc 통과 · 백엔드 재시작 후 200. Co-Authored-By: Claude Opus 5 (1M context) --- B09_Estimation/B09_Estimation_Engine_Cost.py | 10 +++++----- B09_Estimation/B09_Estimation_Router.py | 2 -- B09_Estimation/B09_Estimation_Statutory.py | 6 ++---- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/B09_Estimation/B09_Estimation_Engine_Cost.py b/B09_Estimation/B09_Estimation_Engine_Cost.py index 765914d1..2f749d3a 100644 --- a/B09_Estimation/B09_Estimation_Engine_Cost.py +++ b/B09_Estimation/B09_Estimation_Engine_Cost.py @@ -66,7 +66,11 @@ class CostInput: duration_days: int = 183 pension_year: int = 2026 - #: 관급자재 — 순자재대와 조달수수료를 나눠 받는다(순환 정의 방지, 원가계산_체계 §1). + #: 관급자재 — **순자재대**와 조달수수료를 나눠 받는다(순환 정의 방지, 원가계산_체계 §1). + #: ⚠ `owner_supplied_material_krw` 는 **수수료를 뺀 순자재대**다. 실무 서류의 + #: 「관급자재대」는 이미 `순자재대 + 수수료` 를 천원 올림한 값이므로 그대로 넣으면 안 된다 + #: (2026-09-07 실측 정정 — 울진 순자재대 69,474,220 + 수수료 375,160 = 69,849,380 → + #: 천원 올림 69,850,000). 안전관리비 관급항도 **순자재대만** 쓴다. owner_supplied_material_krw: Decimal = _ZERO procurement_fee_krw: Decimal = _ZERO include_fee_in_owner_material_total: bool = True @@ -75,10 +79,6 @@ class CostInput: owner_supplied_for_safety_krw: Decimal | None = None #: 그 금액이 부가세 포함인가 — 포함이면 1.1 로 나눈다(규정: 부가세 제외 기준). owner_supplied_includes_vat: bool = True - #: ★ 법대로(8-10) — 조달수수료 차감은 **규정 문구가 아니다.** 기본 꺼짐. - #: 옛 서류(울진 2024) 재현 검산에만 켠다. - deduct_procurement_fee_for_safety: bool = False - #: 규모 구간 판정에 쓸 **추정가격**. 주면 그 값으로 한 번만 판정한다. #: 없으면 직접공사비를 씨앗으로 **반복 수렴**한다 (`calculate_cost` 참조). #: 근거 — 국가계약법 시행령 제7조 1호 「공사계약의 경우에는 관급자재로 공급될 diff --git a/B09_Estimation/B09_Estimation_Router.py b/B09_Estimation/B09_Estimation_Router.py index 25a82e5f..df636e54 100644 --- a/B09_Estimation/B09_Estimation_Router.py +++ b/B09_Estimation/B09_Estimation_Router.py @@ -52,7 +52,6 @@ class CostRequest(BaseModel): include_fee_in_owner_material_total: bool = True owner_supplied_for_safety_krw: Decimal | None = None owner_supplied_includes_vat: bool = True - deduct_procurement_fee_for_safety: bool = False estimated_price_krw: Decimal | None = None profit_adjustment_krw: Decimal = Field(default=Decimal(0), ge=0) @@ -83,7 +82,6 @@ class CostRequest(BaseModel): include_fee_in_owner_material_total=self.include_fee_in_owner_material_total, owner_supplied_for_safety_krw=self.owner_supplied_for_safety_krw, owner_supplied_includes_vat=self.owner_supplied_includes_vat, - deduct_procurement_fee_for_safety=self.deduct_procurement_fee_for_safety, estimated_price_krw=self.estimated_price_krw, profit_adjustment_krw=self.profit_adjustment_krw, waste_disposal_krw=self.waste_disposal_krw, diff --git a/B09_Estimation/B09_Estimation_Statutory.py b/B09_Estimation/B09_Estimation_Statutory.py index db4f9f52..2fd37e8b 100644 --- a/B09_Estimation/B09_Estimation_Statutory.py +++ b/B09_Estimation/B09_Estimation_Statutory.py @@ -13,7 +13,8 @@ - **안전관리비는 A·B 두 값을 다 내고 작은 쪽** (고용노동부 고시 제2025-11호). ⚠ A 가 항상 작지 않다 — 관급을 넣어 대상액이 5억·50억 경계를 넘으면 뒤집힌다 (실증: 울진 A 채택 / 거창 B 채택). - - ★ **법대로**(8-10) — 조달수수료 차감은 규정 문구가 아니다. 기본은 **차감하지 않음**. + - ★ **법대로**(8-10) — 조달수수료 차감이라는 처리는 없다. 안전관리비 관급항은 + **순자재대**(수수료를 애초에 안 포함)를 부가세 제외로 환산해 쓴다. """ from __future__ import annotations @@ -170,9 +171,6 @@ def safety_management_cost( owner_supplied = data.owner_supplied_for_safety_krw if owner_supplied is None: owner_supplied = data.owner_supplied_material_krw - if data.deduct_procurement_fee_for_safety: - # ★ 법대로(8-10) — 규정 문구가 아니다. 옛 서류 재현용으로만 켠다. - owner_supplied = owner_supplied - data.procurement_fee_krw if data.owner_supplied_includes_vat: owner_supplied = owner_supplied / _VAT_DIVISOR