refactor(b09): 옛 탭 옮기기 ④ 중기경비계산서 — 옛 BaseData 에서 UI_MachineExpense 로
- 화면 확인: 옮기기 전후 같음 — 중기 탭 표 19 · 줄 171 · 계산서 18 장(불도저 19 손료계수 1811 · 시간당 손료 35,884.965) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
/* =============================================================================
|
||||
* B09_Estimation_UI_MachineExpense.ts
|
||||
* 각종 중기경비계산서 — 기종마다 한 장(별표2 (5)(가) 아홉째) · 중기 탭 아래에 붙음
|
||||
*
|
||||
* - 옛 `B09_Estimation_UI_BaseData.ts` 의 중기경비계산서를 그대로 옮김(PLAN 12장 옛 탭 옮기기).
|
||||
* - ⚠ 목록표가 「얼마」라면 이 장은 **왜 그 값인가** — 계산 과정을 감추지 않음.
|
||||
* ========================================================================== */
|
||||
|
||||
import { API_BASE_URL } from "@config/config_frontend";
|
||||
import { el } from "./B09_Estimation_UI_Sheet";
|
||||
import { head, infoTable, money, note } from "./B09_Estimation_UI_Table";
|
||||
|
||||
export interface MachineExpenseDto {
|
||||
summary: string;
|
||||
notes: string[];
|
||||
sheets: Array<{
|
||||
machine_code: string;
|
||||
name: string;
|
||||
spec: string;
|
||||
price_thousand_krw: string | null;
|
||||
economic_life_hours: number | null;
|
||||
annual_standard_hours: number | null;
|
||||
depreciation_coefficient: number | null;
|
||||
maintenance_coefficient: number | null;
|
||||
management_coefficient: number | null;
|
||||
loss_coefficient: number | null;
|
||||
loss_krw_per_hour: string | null;
|
||||
fuel_liters_per_hour: string | null;
|
||||
fuel_price_per_liter: string | null;
|
||||
fuel_scope: string;
|
||||
misc_material_percent: string | null;
|
||||
operator_code: string;
|
||||
operator_daily_wage: string | null;
|
||||
operator_krw_per_hour: string | null;
|
||||
material_krw: string | null;
|
||||
labor_krw: string | null;
|
||||
expense_krw: string | null;
|
||||
total_krw: string | null;
|
||||
variant: string;
|
||||
attachment: boolean;
|
||||
attachment_note: string;
|
||||
gaps: string[];
|
||||
}>;
|
||||
}
|
||||
|
||||
export async function fetchMachineExpense(projectId: string): Promise<MachineExpenseDto> {
|
||||
const response = await fetch(
|
||||
`${API_BASE_URL}/projects/${encodeURIComponent(projectId)}/estimation/machine-expense`,
|
||||
{ credentials: "include" },
|
||||
);
|
||||
if (!response.ok) throw new Error(`machine-expense ${response.status}`);
|
||||
return (await response.json()) as MachineExpenseDto;
|
||||
}
|
||||
|
||||
/** 기종 한 장 — 손료·운전경비·시간당 사용료를 차례로. */
|
||||
function machineExpenseSheet(sheet: MachineExpenseDto["sheets"][number]): HTMLElement {
|
||||
const box = el("div", "b09s-group");
|
||||
box.append(
|
||||
el(
|
||||
"div",
|
||||
"b09s-head",
|
||||
`${sheet.machine_code} ${sheet.name} ${sheet.spec}`.trim() +
|
||||
(sheet.variant ? ` — ${sheet.variant}` : ""),
|
||||
),
|
||||
);
|
||||
const coefficient = (value: number | null) => (value === null ? "—" : String(value));
|
||||
box.append(
|
||||
infoTable(
|
||||
["구 분", "내 용", "값"],
|
||||
[
|
||||
["① 손료", "취득가격(천원)", money(sheet.price_thousand_krw)],
|
||||
[
|
||||
"",
|
||||
"내용시간 / 연간표준가동시간",
|
||||
`${coefficient(sheet.economic_life_hours)} / ${coefficient(sheet.annual_standard_hours)}`,
|
||||
],
|
||||
[
|
||||
"",
|
||||
"상각비·정비비·관리비 계수 (10⁻⁷)",
|
||||
`${coefficient(sheet.depreciation_coefficient)} + ${coefficient(sheet.maintenance_coefficient)} + ${coefficient(sheet.management_coefficient)} = ${coefficient(sheet.loss_coefficient)}`,
|
||||
],
|
||||
["", "시간당 손료(원)", money(sheet.loss_krw_per_hour)],
|
||||
[
|
||||
"② 운전경비",
|
||||
`주연료(L/hr) × 유가(${sheet.fuel_scope})`,
|
||||
`${sheet.fuel_liters_per_hour ?? "—"} × ${money(sheet.fuel_price_per_liter)}`,
|
||||
],
|
||||
["", "잡재료(주연료의 %)", sheet.misc_material_percent ?? "—"],
|
||||
[
|
||||
"",
|
||||
`조종원(${sheet.operator_code || "—"}) 일당 → 시간당`,
|
||||
`${money(sheet.operator_daily_wage)} → ${money(sheet.operator_krw_per_hour)}`,
|
||||
],
|
||||
[
|
||||
"③ 시간당 사용료",
|
||||
"재료비 / 노무비 / 경비",
|
||||
`${money(sheet.material_krw)} / ${money(sheet.labor_krw)} / ${money(sheet.expense_krw)}`,
|
||||
],
|
||||
["", "합 계", money(sheet.total_krw)],
|
||||
],
|
||||
[0, 1],
|
||||
),
|
||||
);
|
||||
if (sheet.variant) {
|
||||
box.append(
|
||||
note(
|
||||
"같은 기종이라도 조합 사용이면 잡재료가 16% 로 줄어 재료비가 달라집니다 —" +
|
||||
" 그래서 층이 따로 섭니다(건설품셈 제8장 [주]⑤).",
|
||||
),
|
||||
);
|
||||
}
|
||||
if (sheet.attachment_note) box.append(note(sheet.attachment_note));
|
||||
for (const gap of sheet.gaps) box.append(note(`⚠ ${gap}`));
|
||||
return box;
|
||||
}
|
||||
|
||||
export function drawMachineExpense(body: HTMLElement, data: MachineExpenseDto): void {
|
||||
body.append(head(`각종 중기경비계산서 (${data.sheets.length})`));
|
||||
body.append(note(data.summary));
|
||||
for (const line of data.notes) body.append(note(line));
|
||||
for (const sheet of data.sheets) body.append(machineExpenseSheet(sheet));
|
||||
}
|
||||
@@ -5,12 +5,12 @@
|
||||
* - 목록표 = 내역이 쓴 시간당 중기만, 처음 쓰인 차례(서버 `lists.machine`).
|
||||
* - 줄을 누르면 아래에 그 기종의 중기사용료 호표 — 손료(경비) · 운전원(노무) · 주연료(재료) · 잡품(재료).
|
||||
* ⚠ 잡품은 「주연료비 × 율」 가산 행 — 수량 칸에 율(%), 단가 칸에 밑수(주연료비)가 옴(실무 표 그대로).
|
||||
* - 그 아래 중기경비계산서(취득가·손료계수·연료·조종원 과정)는 옛 표를 그대로 이어 보임.
|
||||
* - 그 아래 중기경비계산서(취득가·손료계수·연료·조종원 과정) — _UI_MachineExpense.
|
||||
* ========================================================================== */
|
||||
|
||||
import type { B09Tab, B09TabContext } from "./B09_Estimation_UI_Shell_Types";
|
||||
import { renderDetail } from "./B09_Estimation_UI_Detail";
|
||||
import { drawMachineExpense, fetchMachineExpense } from "./B09_Estimation_UI_BaseData";
|
||||
import { drawMachineExpense, fetchMachineExpense } from "./B09_Estimation_UI_MachineExpense";
|
||||
import { L, el, hint, numberCell, plainTable, won } from "./B09_Estimation_UI_Sheet";
|
||||
import { loadBill, type BillDto } from "./B09_Estimation_UI_Store";
|
||||
|
||||
@@ -62,7 +62,7 @@ function draw(ctx: B09TabContext, bill: BillDto): void {
|
||||
detail.append(hint(L("B09_Sheet_PickSheet")));
|
||||
}
|
||||
if (ctx.projectId) {
|
||||
// 중기경비계산서 — 「그 값이 왜 나왔나」(옛 표 그대로, 옛 파일을 걷을 때 함께 옮김).
|
||||
// 중기경비계산서 — 「그 값이 왜 나왔나」(옛 표를 옮겨 온 _UI_MachineExpense).
|
||||
void fetchMachineExpense(ctx.projectId)
|
||||
.then((data) => drawMachineExpense(expense, data))
|
||||
.catch(() => expense.append(hint(L("B09_Sheet_LoadFailed"), true)));
|
||||
|
||||
Reference in New Issue
Block a user