B08_Quantity 86 · B09_Estimation 111 파일을 old_code/ 로 옮김(지우지 않음). 화면은 메뉴·주소·단계 막대만 남은 빈 틀 둘 — main.py 라우터 13 개는 끊음. B07 이 빌려 쓰던 비탈 길이·면적은 필요한 함수만 B07_DesignDetail_Engine_SlopeGeometry 로 옮겨 적음(면적 적분·노면 면적·측점 묶음은 안 옮김) · 시험 하나를 새로 둠. B07 구조물도 조립(Cad_StandardSheet)은 2026-09-13 에 이미 도면 목록에서 빠져 부르는 곳이 없어 old_code 로 같이 보냄 — 구조물 그림은 되살리지 않음. B06 구조물 몫 조회는 빈 값으로 두어 화면이 그대로 서게 함. B08·B09 를 부르던 시험 25 개도 old_code/resources/tester 로 옮김. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PAdA5ThqmtVSsbzjusk1cJ
119 lines
3.9 KiB
TypeScript
119 lines
3.9 KiB
TypeScript
/* =============================================================================
|
|
* B09_Estimation_UI_Tab_Summary.ts
|
|
* B09 집계표 탭 — 재료비·노무비·경비 수량금액집계표 + 중기시간금액집계표 (실무 시트 · PLAN 12장)
|
|
*
|
|
* - 칸은 실무 시트 그대로:
|
|
* 재료비·노무비·경비 호표 · 명칭 · 규격 · 수량 · 단위 · 단가 · 금액 · 비고
|
|
* 중기 호표 · 명칭 · 규격 · 수량 · 단위 · 합계 · 노무비 · 재료비 · 경비 · 비고 (⚠ 단가 열 없음)
|
|
* - 값은 서버가 내역에서 되모은 것(`resources`) — 집계표는 **반올림**이라 내역서 본체(절사)와 원 단위로
|
|
* 어긋나는 것이 정상(그 문구를 표 아래에 함께 보임).
|
|
* - 줄을 누르면 중기는 그 기종의 중기사용료로 들어감.
|
|
* ========================================================================== */
|
|
|
|
import type { B09Tab, B09TabContext } from "./B09_Estimation_UI_Shell_Types";
|
|
import {
|
|
L,
|
|
el,
|
|
hint,
|
|
numberCell,
|
|
plainTable,
|
|
quantity,
|
|
segmented,
|
|
won,
|
|
} from "./B09_Estimation_UI_Sheet";
|
|
import { loadBill, type BillDto, type ResourceGroup } from "./B09_Estimation_UI_Store";
|
|
|
|
let group: ResourceGroup = "material";
|
|
|
|
const GROUPS: Array<[ResourceGroup, Parameters<typeof L>[0]]> = [
|
|
["material", "B09_Sheet_Sum_Material"],
|
|
["labor", "B09_Sheet_Sum_Labor"],
|
|
["expense", "B09_Sheet_Sum_Expense"],
|
|
["machine", "B09_Sheet_Sum_Machine"],
|
|
];
|
|
|
|
function draw(ctx: B09TabContext, bill: BillDto): void {
|
|
ctx.body.append(
|
|
segmented(
|
|
GROUPS.map(([key, label]) => [key, L(label)]),
|
|
group,
|
|
(key) => {
|
|
group = key as ResourceGroup;
|
|
ctx.body.replaceChildren();
|
|
draw(ctx, bill);
|
|
},
|
|
),
|
|
);
|
|
const machine = group === "machine";
|
|
const front = [
|
|
L("B09_Sheet_Col_Sheet"),
|
|
L("B09_Sheet_Col_Name"),
|
|
L("B09_Sheet_Col_Spec"),
|
|
L("B09_Sheet_Col_Quantity"),
|
|
L("B09_Sheet_Col_Unit"),
|
|
];
|
|
const money = machine
|
|
? [
|
|
L("B09_Sheet_Col_Total"),
|
|
L("B09_Sheet_Col_Labor"),
|
|
L("B09_Sheet_Col_Material"),
|
|
L("B09_Sheet_Col_Expense"),
|
|
]
|
|
: [L("B09_Sheet_Col_UnitPrice"), L("B09_Sheet_Col_Amount")];
|
|
const { wrap, tbody } = plainTable([...front, ...money, L("B09_Sheet_Col_Note")]);
|
|
const rows = bill.resources.groups[group];
|
|
for (const row of rows) {
|
|
const tr = el("tr");
|
|
tr.append(
|
|
el("td", "", String(row.number)),
|
|
el("td", "", row.name),
|
|
el("td", "", row.spec),
|
|
numberCell(quantity(row.quantity, null)),
|
|
el("td", "", row.unit),
|
|
);
|
|
if (machine) {
|
|
tr.append(
|
|
numberCell(won(row.amount_krw)),
|
|
numberCell(won(row.labor_krw)),
|
|
numberCell(won(row.material_krw)),
|
|
numberCell(won(row.expense_krw)),
|
|
);
|
|
tr.classList.add("is-clickable");
|
|
tr.title = L("B09_Sheet_Drill");
|
|
tr.addEventListener("click", () => ctx.open("machine", row.code));
|
|
} else {
|
|
tr.append(numberCell(won(row.unit_price_krw)), numberCell(won(row.amount_krw)));
|
|
}
|
|
tr.append(el("td", "b09s-note", row.note));
|
|
tbody.append(tr);
|
|
}
|
|
ctx.body.append(wrap);
|
|
if (rows.length === 0) ctx.body.append(hint(L("B09_Sheet_EmptyGroup")));
|
|
ctx.body.append(hint(bill.resources.note));
|
|
if (bill.resources.missing.length > 0) {
|
|
ctx.body.append(
|
|
hint(`${L("B09_Sheet_SumMissing")} ${bill.resources.missing.join(", ")}`, true),
|
|
);
|
|
}
|
|
}
|
|
|
|
export const summaryTab: B09Tab = {
|
|
key: "summary",
|
|
label: () => L("B09_Sheet_Tab_Summary"),
|
|
render(ctx) {
|
|
if (!ctx.projectId) {
|
|
ctx.body.append(hint(L("B09_Sheet_NoProject")));
|
|
return;
|
|
}
|
|
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));
|
|
});
|
|
},
|
|
};
|