feat(B09 원가계산서 · 708-2): 현행 비목 다섯 셈 — 퇴직공제 · 임금채권 · 석면 · 하도급 요율 셈 · 공사이행보증 금액 손입력

- 셈 짝(Calc_Total py ↔ ts) — STmate 일반형식 식 · 자리(지식DB 12 · 35 분석) · 경비 묶음 안 · 나.소계에 듦
  퇴직공제부금비 = 직접노무비 × 율 · 임금채권 · 석면 = (직노 + 간노) × 율 · 하도급 = 순공사비 × 율 ·
  공사이행보증 = 금액 직접 입력(performance_fee) · 자동 요율 없음 · 요율 빈칸 = 해당 없음(0)
- 요율 출처 「불러옴」 = rates_imported(707-2 불러오기가 실음 · 요율 고치면 사용자)
- 707-2 불러오기 — 「셈 없음」 알림 뺌 · 공사이행보증 줄 금액 = 손입력 칸
- 총괄 · 원가계산서 탭 · 인쇄 미리보기 = 같은 줄 짜기
- 낡은 시험 고침 — 현행 비목 기대값 빈칸 → 0 · 퇴직공제 요율 칸 고침 가능 · 거창 총공사비 = 엑셀

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-31 21:27:40 +09:00
co-authored by Claude Opus 5.5
parent a5179e4dfe
commit 472bf98ba2
9 changed files with 161 additions and 79 deletions
+7 -11
View File
@@ -12,11 +12,11 @@
indirect_material · scrap = 그 줄 금액 ·
profit_adjust = ROUNDDOWN((순공사원가 − 재료비 + 일반관리비) × 율) − 엑셀 이윤 ·
vat_adjust = 엑셀 부가세 − ROUNDDOWN(총원가 × 율) ·
procurement_fee_pct = 관급 조달수수료 ÷ 순자재대(소수 2~4 자리 중 수수료를 그대로 내는 첫 값).
procurement_fee_pct = 관급 조달수수료 ÷ 순자재대(소수 2~4 자리 중 수수료를 그대로 내는 첫 값) ·
performance_fee = 공사이행보증수수료 줄 금액(708-2 · 율 셈 없음).
대조(`check`) = 엑셀 비목 합 + 실은 값으로 우리 식(`compute_total`)을 돌려 줄마다 엑셀 금액과 견줌 —
1 원 넘게 다른 줄 = 「식 다름」(노인장기요양 · 산업안전보건관리비 A/B 등 식 꼴이 다른 비목) ·
우리 표에 없는 행(폐기물처리 · 국가지점번호판 …) · 셈 없는 현행 비목(퇴직공제부금비 …)
= 「짝 없음」 · 「셈 없음」.
우리 표에 없는 행(폐기물처리 · 국가지점번호판 …) = 「짝 없음」.
"""
from __future__ import annotations
@@ -27,7 +27,6 @@ from typing import Any
from B09_Estimation.B09_Estimation_Calc_Base import num, rounddown
from B09_Estimation.B09_Estimation_Calc_Total import (
CURRENT_ONLY,
RATE_LINES,
TAIL_LINES,
compute_total,
@@ -68,7 +67,6 @@ ROWS: tuple[tuple[str, str], ...] = (
("소계", "subtotal"),
)
RATE_KEYS = {key: (name, rt) for key, name, rt, _ in (*RATE_LINES, *TAIL_LINES)}
NO_CALC = {key: (name, rt) for key, name, rt in CURRENT_ONLY}
_PCT = re.compile(r"[x×*]\s*([\d.]+)\s*%")
_BASE = re.compile(r"%\s*\+\s*([\d,]+)")
_HANGUL = re.compile(r"[가-힣]")
@@ -204,16 +202,14 @@ def read_rates(name: str, data: bytes) -> dict[str, Any]:
excel[key] = min(excel[key], amount or excel[key])
continue
excel[key] = amount if amount is not None else excel.get(key, 0.0)
if key in RATE_KEYS or key in NO_CALC:
if key == "performance": # 공사이행보증 = 금액 손입력(율 셈 없음)
if amount:
estimate["performance_fee"] = amount
elif key in RATE_KEYS:
if row["rate"] is not None:
rates[key] = row["rate"]
elif amount:
notes.append(f"율 없음 — 「{row['name']}」 산출근거 빈칸 · 지금 율 그대로")
if key in NO_CALC and amount:
notes.append(
f"셈 없음 — 「{row['name']}」 {amount:,.0f} 원 · 율 {row['rate']}% 만 실음"
"(우리 원가계산서 줄만 · 총액에 안 듦)"
)
if key == "safety" and row["text"]:
got = _BASE.search(row["text"])
estimate["safety_base"] = float(got.group(1).replace(",", "")) if got else 0.0