fix(b09): 조종원 시간당 노임을 식 좌→우 순차 + 절사로 — 골든셋 시험 첫 벌
- 계수로 미리 접으면 267,360 → 55,699 로 1원 틀림 — 식 1/8*16/12*25/20 을 차례로 풀어 55,700 - 중기 호표 운전원 줄은 시간당 노임 제목(#시간) × 인수로 부름(STmate 운전원 1 × 55,700 모양) - 골든셋 시험 test_b09_golden_stmate — 실무 6건 환율및기초자료 시간당 칸 전수 재현 (다섯 건 원 미만 절사 · 2025 울진 소광 0.1원 미만 절사 — 자리는 설정값) - 28자리 끝 반올림 차례만 다른 합 비교 시험을 허용 오차로 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq
This commit is contained in:
@@ -27,7 +27,8 @@ from typing import Any
|
||||
|
||||
from B09_Estimation.B09_Estimation_Guards import check_column_sums, check_surcharge_once
|
||||
from B09_Estimation.B09_Estimation_MachineCost import (
|
||||
OPERATOR_ALLOWANCE_FACTOR,
|
||||
OPERATOR_WAGE_FORMULA,
|
||||
hourly_operator_wage,
|
||||
load_machine_catalog,
|
||||
)
|
||||
from B09_Estimation.B09_Estimation_MachineProductivity import (
|
||||
@@ -68,6 +69,8 @@ from B09_Estimation.B09_Estimation_Rounding import OutputPlace, round_at
|
||||
from B09_Estimation.B09_Estimation_Transport import parse_distance_km
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
#: 조종원 **시간당 노임** 제목 꼬리 — 일 노임 제목(`L…`)과 갈라 둠. 노무비목록표엔 안 실림(일당만).
|
||||
HOURLY_WAGE_SUFFIX = "#시간"
|
||||
_RE_EMPHASIS = re.compile(r"\*\*(.+?)\*\*")
|
||||
_ZERO = Decimal(0)
|
||||
#: 연료는 자재 카탈로그에 없어 합성 코드로 세운다 — 코드가 있어야 조인이 성립한다.
|
||||
@@ -385,22 +388,26 @@ def _add_machine_layers(
|
||||
|
||||
wage_code = record.operator_occupation_code
|
||||
if wage_code and wage_code in wages and record.operator_person_days is not None:
|
||||
# ㉣ 나눗수는 8시간 — `PriceDetail` 수량이 「1시간분 인」이 된다.
|
||||
# 여기에 **제수당·상여금·퇴직급여충당금 계수**(1.667배)를 곱한다. 공표 노임이
|
||||
# 기본급여액뿐이라 별도 계상해야 하는 몫이다(`MachineCost` 상수 주석에 근거).
|
||||
per_hour_person = (record.operator_person_days / Decimal(8)) * OPERATOR_ALLOWANCE_FACTOR
|
||||
if wage_code not in book.titles:
|
||||
# ㉣ 나눗수는 8시간 + **제수당·상여금·퇴직급여충당금 계수**(16/12×25/20) — 공표 노임이
|
||||
# 기본급여액뿐이라 별도 계상하는 몫(`MachineCost` 상수 주석에 근거).
|
||||
# ⚠⚠ 계수를 **수량에 접지 않음** — `일당 × 0.20833…` 은 55,699.99… 로 1원 틀림.
|
||||
# 시간당 노임을 식 좌→우 + 원 미만 절사로 **따로 세운 제목**(`#시간`)을 1시간분 인수로 부름
|
||||
# (STmate 중기사용료 호표 「운전원 1 × 55,700」 모양, 명세 7장).
|
||||
per_hour_person = record.operator_person_days
|
||||
hourly_wage_code = f"{wage_code}{HOURLY_WAGE_SUFFIX}"
|
||||
if hourly_wage_code not in book.titles:
|
||||
book.add_title(
|
||||
PriceTitle(
|
||||
code=wage_code,
|
||||
code=hourly_wage_code,
|
||||
kind=PriceKind.LABOR,
|
||||
name="조종원",
|
||||
unit="인",
|
||||
slots=_slots(wages[wage_code]),
|
||||
name="조종원(시간당)",
|
||||
unit="hr",
|
||||
slots=_slots(hourly_operator_wage(wages[wage_code])),
|
||||
# ⚠ 조종원도 노임이다 — 같은 플래그가 붙어야 한다.
|
||||
reliability=load_labor_reliability().get(wage_code, ""),
|
||||
)
|
||||
)
|
||||
wage_code = hourly_wage_code
|
||||
# 조합 층에도 조종원을 같이 단다 — 본체를 모는 사람은 하나뿐이다.
|
||||
combined_code = f"{hourly_code}#조합"
|
||||
if combined_code in book.titles:
|
||||
@@ -409,7 +416,7 @@ def _add_machine_layers(
|
||||
combined_code,
|
||||
wage_code,
|
||||
per_hour_person,
|
||||
note="조종원 (1일 8시간 × 제수당·상여·퇴직충당 16/12 × 25/20)",
|
||||
note=f"조종원 (일당 × {OPERATOR_WAGE_FORMULA} 좌→우 · 원 미만 절사)",
|
||||
)
|
||||
)
|
||||
book.add_detail(
|
||||
@@ -417,7 +424,7 @@ def _add_machine_layers(
|
||||
hourly_code,
|
||||
wage_code,
|
||||
per_hour_person,
|
||||
note="조종원 (1일 8시간 × 제수당·상여·퇴직충당 16/12 × 25/20)",
|
||||
note=f"조종원 (일당 × {OPERATOR_WAGE_FORMULA} 좌→우 · 원 미만 절사)",
|
||||
)
|
||||
)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user