- 화면 확인: 옮기기 전후 같음 — 중기 탭 표 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
92 lines
3.7 KiB
TypeScript
92 lines
3.7 KiB
TypeScript
/* =============================================================================
|
|
* 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));
|
|
});
|
|
},
|
|
};
|