- master_machine_coef.py · common_util_machine_coef.ts — 건설품셈 8-1-5 계수(정수 반올림 · 손료계수 = 합) · 시간당 미리보기(줄 0.1 원 버림 · 잡품 = 버린 주연료 × % · 비목 합 원 버림) - 계수 전수 대조 600 줄 중 598 같음 · 다른 2 줄 = 점보드릴 원문 표 값(777 · 셈 777.8) - 미리보기 = 서버 기계경비식 619 대 중 602 같음 · 견본 스무 대 시험 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
93 lines
3.5 KiB
TypeScript
93 lines
3.5 KiB
TypeScript
/* =============================================================================
|
|
* common_util_machine_coef.ts
|
|
* 기계 손료계수 · 시간당 경비 미리보기(PLAN 821-2 · 요구서 796 1 장) — 기계 양식 즉시 셈.
|
|
*
|
|
* ⚠ 짝: `resources/master_data/scripts/master_machine_coef.py` — 같은 셈 · 같은 차례
|
|
* (거울 시험 `resources/tester/test_821_2_machine_coef.py`). 한쪽만 고치면 화면과 저장이 갈림.
|
|
* 계수 = 건설품셈 공통 8-1-5(계수마다 정수 반올림 · 손료계수 = 합) · 미리보기 끝수 = 서버
|
|
* 기계경비식(줄 0.1 원 아래 버림 · 잡품 = 버린 주연료 × % · 비목 합 원 미만 버림) · 정본은 서버 식.
|
|
* ========================================================================== */
|
|
|
|
export const MACHINE_INPUTS = [
|
|
"내용시간",
|
|
"연간표준가동시간",
|
|
"상각비율",
|
|
"정비비율",
|
|
"연간관리비율",
|
|
] as const;
|
|
export const MACHINE_COEFS = ["상각비계수", "정비비계수", "관리비계수", "손료계수"] as const;
|
|
|
|
export type MachineCoefs = Record<(typeof MACHINE_COEFS)[number], number>;
|
|
|
|
const E = 1e-6; // 끊는 경계 부동소수 흔들림 막음
|
|
|
|
const num = (v: unknown): number => (typeof v === "number" && Number.isFinite(v) ? v : 0);
|
|
const halfUp = (x: number): number => Math.floor(x + 0.5 + E);
|
|
/** 줄 금액 = 0.1 원 아래 버림(B09 끝수 줄 자리). */
|
|
const tenth = (x: number): number => Math.floor(x * 10 + E) / 10;
|
|
|
|
/** (내용시간 · 연간표준가동시간 · 상각비율 · 정비비율 · 연간관리비율) → 계수 넷 · 못 셈 = null. */
|
|
export function machineCoef(
|
|
life: unknown,
|
|
yearly: unknown,
|
|
dep: unknown,
|
|
rep: unknown,
|
|
mgmt: unknown,
|
|
): MachineCoefs | null {
|
|
const [t, h, a, m, k] = [life, yearly, dep, rep, mgmt].map(num);
|
|
if (t <= 0 || h <= 0) return null;
|
|
const n = t / h;
|
|
const s = halfUp((a / t) * 1e7);
|
|
const j = halfUp((m / t) * 1e7);
|
|
const g = halfUp(((k * (1.1 * n + 0.9)) / (2 * n) / h) * 1e7);
|
|
return { 상각비계수: s, 정비비계수: j, 관리비계수: g, 손료계수: s + j + g };
|
|
}
|
|
|
|
/** 값 묶음에서 품셈 입력 다섯이 다 수일 때만 계수 넷. */
|
|
export function machineCoefOf(values: Record<string, unknown>): MachineCoefs | null {
|
|
if (!MACHINE_INPUTS.every((k) => typeof values[k] === "number")) return null;
|
|
return machineCoef(
|
|
...(MACHINE_INPUTS.map((k) => values[k]) as [number, number, number, number, number]),
|
|
);
|
|
}
|
|
|
|
export interface MachineHourly {
|
|
손료: number;
|
|
주연료: number;
|
|
잡품: number;
|
|
전력: number;
|
|
조종원: number;
|
|
노무비: number;
|
|
재료비: number;
|
|
경비: number;
|
|
계: number;
|
|
}
|
|
|
|
/** 값 묶음 + 유가(원/ℓ) · 노임(원/일) · 전력(원/kWh) · 시간환산 → 시간당 줄 · 비목 · 계. */
|
|
export function machineHourly(
|
|
values: Record<string, unknown>,
|
|
fuel: number,
|
|
wage: number,
|
|
power = 0,
|
|
hour = 1 / 8,
|
|
): MachineHourly {
|
|
const loss = Math.floor((num(values["가격"]) * 1000 * num(values["손료계수"])) / 1e7 + E);
|
|
const oil = tenth(num(values["주연료"]) * num(fuel));
|
|
const misc = tenth((oil * num(values["잡재료율"])) / 100);
|
|
const elec = tenth(num(values["전력"]) * num(power));
|
|
const crew = tenth(num(values["조종원"]) * hour * num(wage));
|
|
const labor = Math.floor(crew + E);
|
|
const material = Math.floor(oil + misc + elec + E);
|
|
return {
|
|
손료: loss,
|
|
주연료: oil,
|
|
잡품: misc,
|
|
전력: elec,
|
|
조종원: crew,
|
|
노무비: labor,
|
|
재료비: material,
|
|
경비: loss,
|
|
계: labor + material + loss,
|
|
};
|
|
}
|