Files
Aislo/old_code/B09_Estimation/B09_Estimation_UI_Tab_Supply.ts
T
eomsangdonandClaude Opus 5 8472fc9f40 refactor(B08,B09): 폴더째 old_code 로 옮기고 빈 화면 둘만 남김 (PLAN 7-3)
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
2026-09-22 12:27:45 +09:00

86 lines
3.3 KiB
TypeScript

/* =============================================================================
* B09_Estimation_UI_Tab_Supply.ts
* B09 관급·사급 탭 — 자재대: B08 수량·할증에 단가를 붙인 표 (PLAN 8-7 「금액은 B09」)
*
* - 옛 `B09_Estimation_UI_Page.ts` 의 자재대 탭을 그대로 옮김(PLAN 12장 옛 탭 옮기기).
* - 사급(도급 재료비) · 관급(총원가 밖 별도 표기) · 안 갈린 것(어느 합계에도 안 넣음) 세 무리.
* ⚠ 「안 갈린 것」은 못 세운 것이 아니라 **세면 안 되는 것** — 채우면 이중계상(PLAN 8-36 ㉱).
* - 자료는 설계내역서 응답 한 벌(`summary.material_sheet`) — 내역 탭들과 같은 응답을 봄.
* ========================================================================== */
import type { ui_locales } from "@ui/ui_template_locale";
import type { B09Tab } from "./B09_Estimation_UI_Shell_Types";
import { L, hint, quantity } from "./B09_Estimation_UI_Sheet";
import { infoTable, note } from "./B09_Estimation_UI_Table";
import { loadBill, type BillDto, type MaterialSheetRowDto } from "./B09_Estimation_UI_Store";
const MATERIAL_KEYS = [
"name",
"spec",
"unit",
"total_amount",
"unit_price_krw",
"amount_krw",
"note",
];
function draw(body: HTMLElement, bill: BillDto): void {
const sheet = bill.summary.material_sheet;
if (!sheet) {
body.append(hint(L("B09_Estimation_Mat_Empty")));
return;
}
// 자재가 아예 없으면 **빈 표 셋을 늘어놓지 않음** — 「없다」 한 줄이면 됨(2026-09-08 화면 전수).
if (sheet.contractor.length === 0 && sheet.owner.length === 0 && sheet.unknown.length === 0) {
body.append(hint(L("B09_Estimation_Mat_None")));
return;
}
const groups: Array<[keyof typeof ui_locales, MaterialSheetRowDto[], string | null, string]> = [
["B09_Estimation_Mat_Contractor", sheet.contractor, sheet.contractor_total_krw, "material"],
["B09_Estimation_Mat_Owner", sheet.owner, sheet.owner_total_krw, "material"],
["B09_Estimation_Mat_Unknown", sheet.unknown, null, "material_unknown"],
];
for (const [labelKey, rows, total, sheetName] of groups) {
body.append(note(`${L(labelKey)} (${rows.length})` + (total === null ? "" : ` — ${total}`)));
if (rows.length === 0) continue;
body.append(
infoTable(
["자재", "규격", "단위", "수량", "단가", "금액", "비고"],
rows.map((row) => [
row.name,
row.spec,
row.unit,
quantity(row.total_amount, 2),
row.unit_price_krw ?? "",
row.amount_krw ?? "",
row.note,
]),
[0, 1, 2, 6],
MATERIAL_KEYS,
bill.provenance?.sheets?.[sheetName],
),
);
}
for (const line of sheet.notes) body.append(note(line.replace(/\*\*/g, "")));
}
export const supplyTab: B09Tab = {
key: "supply",
label: () => L("B09_Estimation_Tab_Supply"),
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.body, bill);
})
.catch((error: Error) => {
ctx.body.replaceChildren(hint(`${L("B09_Sheet_LoadFailed")} ${error.message}`, true));
});
},
};