/* ============================================================================= * B09_Estimation_UI_Tab_Machine.ts * B09 중기 탭 — 중기목록표 + 중기사용료 (실무 `중기목록표`·`중기사용료` 시트 · PLAN 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_MachineExpense"; import { L, el, hint, numberCell, plainTable, won } from "./B09_Estimation_UI_Sheet"; import { loadBill, type BillDto } from "./B09_Estimation_UI_Store"; let selected = ""; function draw(ctx: B09TabContext, bill: BillDto): void { const rows = bill.lists.machine; const { wrap, tbody } = plainTable([ L("B09_Sheet_Col_Sheet"), L("B09_Sheet_Col_Name"), L("B09_Sheet_Col_Spec"), L("B09_Sheet_Col_Unit"), L("B09_Sheet_Col_Total"), L("B09_Sheet_Col_Labor"), L("B09_Sheet_Col_Material"), L("B09_Sheet_Col_Expense"), L("B09_Sheet_Col_Note"), ]); for (const row of rows) { const tr = el("tr", `is-clickable${row.code === selected ? " is-selected" : ""}`); tr.append( el("td", "", String(row.number)), el("td", "", row.name), el("td", "", row.spec), el("td", "", row.unit), numberCell(won(row.unit_price_krw)), numberCell(won(row.unit_labor_krw)), numberCell(won(row.unit_material_krw)), numberCell(won(row.unit_expense_krw)), el("td", "b09s-note", row.note), ); tr.addEventListener("click", () => { selected = row.code; ctx.body.replaceChildren(); draw(ctx, bill); }); tbody.append(tr); } const detail = el("div", "b09s-split"); const expense = el("div", "b09s-split"); ctx.body.append(el("div", "b09s-title", L("B09_Sheet_MachineList")), wrap); if (rows.length === 0) ctx.body.append(hint(L("B09_Sheet_EmptyList"))); ctx.body.append(detail, expense); if (selected) { const picked = rows.find((row) => row.code === selected); const label = picked ? `${L("B09_Sheet_Col_Sheet")} ${picked.number}` : selected; renderDetail(ctx, detail, "machine", selected, label); } else { 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))); } } export const machineTab: B09Tab = { key: "machine", label: () => L("B09_Estimation_Tab_Machine"), render(ctx, arg) { if (!ctx.projectId) { ctx.body.append(hint(L("B09_Sheet_NoProject"))); return; } if (arg) selected = arg; ctx.body.append(hint(L("B09_Sheet_Loading"))); loadBill(ctx.projectId) .then((bill) => { ctx.body.replaceChildren(); draw(ctx, bill); }) .catch((error: Error) => { ctx.body.replaceChildren(hint(`${L("B09_Sheet_LoadFailed")} ${error.message}`, true)); }); }, };