Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XWh5wNNycMkbwMpACz1rte
97 lines
4.3 KiB
TypeScript
97 lines
4.3 KiB
TypeScript
/* =============================================================================
|
|
* B09_Draft_Print_Cost.ts
|
|
* 인쇄 미리보기(PLAN 302-4 · 초안) 「원가계산」 영역 — B09 18장을 실무 내역서 차례로 모음.
|
|
* 차례 · 이름 · 방향 = 기번3 내역서 xlsx 시트(목차 · 안내 빼고 · page_setup.orientation)
|
|
* 값 = GET …/estimation + 화면 캐시(`b09-estimation`) → `computeSheets` = B09 화면과 같은 값
|
|
* 표 = 화면 표 짜기(`…_UI_Builders`) 그대로 · 링크 · 강조 · 고칠 칸 표시 · 단가연결 칸만 뺌
|
|
* 공기 초안 탭(공기집계 · 공기산출) = 내역서 차례 밖 → 안 넣음
|
|
* ========================================================================== */
|
|
|
|
import { API_BASE_URL } from "@config/config_frontend";
|
|
import type { DataTableOptions } from "@ui/ui_template_data_table";
|
|
import { readState } from "../../A00_Common/b_page_state";
|
|
import type { Row } from "../B09_Estimation_Calc_Base";
|
|
import { tableOptionsOf, tabTableOf } from "../B09_Estimation_UI_Builders";
|
|
import { computeSheets } from "../B09_Estimation_UI_Shell";
|
|
import type { TabContext, TabId } from "../B09_Estimation_UI_Tabs";
|
|
import type { CollectSheets, PrintSheet } from "./B09_Draft_Print_Types";
|
|
|
|
type Orientation = NonNullable<PrintSheet["orientation"]>;
|
|
|
|
/** 기번3 내역서 시트 차례 — [탭, 시트 이름, 인쇄 방향] */
|
|
export const COST_SHEETS: Array<[TabId, string, Orientation]> = [
|
|
["cost", "공사원가계산서", "landscape"],
|
|
["total", "총괄설계내역서", "landscape"],
|
|
["bill", "설계내역서", "landscape"],
|
|
["dg_list", "일위대가목록표", "landscape"],
|
|
["dg", "일위대가표", "landscape"],
|
|
["sg_list", "단가산출근거목록표", "landscape"],
|
|
["sg", "단가산출근거", "landscape"],
|
|
["basis", "환율및기초자료", "landscape"],
|
|
["machine", "중기목록표", "landscape"],
|
|
["machine_blocks", "중기사용료", "landscape"],
|
|
["material", "재료비목록표", "landscape"],
|
|
["labor", "노무비목록표", "landscape"],
|
|
["expense", "경비목록표", "landscape"],
|
|
["compare", "자재단가대비표", "landscape"],
|
|
["sum_material", "재료비수량금액집계표", "landscape"],
|
|
["sum_labor", "노무비수량금액집계표", "landscape"],
|
|
["sum_expense", "경비수량금액집계표", "landscape"],
|
|
["sum_machine", "중기시간금액집계표", "landscape"],
|
|
];
|
|
|
|
/** 화면 조작 전용 칸(설계내역서 「단가연결 ▾」) */
|
|
const UI_COLUMNS = new Set(["connect"]);
|
|
/** 인쇄에 남길 줄 꼴(제목 줄 굵게) — 손 줄 · 고른 줄 표시는 뺌 */
|
|
const KEEP_ROW = new Set(["is-title"]);
|
|
|
|
/** 화면 표 옵션 → 인쇄 표(값 · 머리 · 레벨 · 합계 · 병합 그대로 · 누름 · 고침 · 강조 뺌) */
|
|
export function printTable(options: DataTableOptions, caption: string): DataTableOptions {
|
|
const { columns, rows, total, frozen, empty, level, mergeSame, rowClass } = options;
|
|
return {
|
|
columns: columns.filter((c) => !UI_COLUMNS.has(c.key)),
|
|
rows,
|
|
total,
|
|
frozen,
|
|
empty,
|
|
caption,
|
|
mergeSame,
|
|
level: level && { ...level, tree: false },
|
|
rowClass:
|
|
rowClass &&
|
|
((i) =>
|
|
rowClass(i)
|
|
?.split(" ")
|
|
.filter((c) => KEEP_ROW.has(c))
|
|
.join(" ") || null),
|
|
};
|
|
}
|
|
|
|
/** 받은 자료 + 사용자 값 → 18장(차례 그대로 · 표가 없는 탭 = 빈 표) */
|
|
export function costSheetsOf(payload: Row, user: Row): PrintSheet[] {
|
|
const ctx: TabContext = {
|
|
sheets: computeSheets(payload, user),
|
|
payload,
|
|
user,
|
|
setUser: () => {},
|
|
};
|
|
return COST_SHEETS.map(([id, name, orientation]) => {
|
|
const spec = tabTableOf(id, ctx);
|
|
const table =
|
|
!spec || typeof spec === "string"
|
|
? { columns: [], rows: [], caption: name }
|
|
: printTable(tableOptionsOf(spec, id), name);
|
|
return { id, name, orientation, table };
|
|
});
|
|
}
|
|
|
|
export const collectCostSheets: CollectSheets = async (projectId) => {
|
|
const response = await fetch(`${API_BASE_URL}/projects/${projectId}/estimation`, {
|
|
credentials: "include",
|
|
});
|
|
if (!response.ok) throw new Error(`원가 자료를 불러오지 못했습니다 — HTTP ${response.status}`);
|
|
const payload = (await response.json()) as Row;
|
|
const user = readState<Row>("b09-estimation", projectId) ?? payload.user ?? {};
|
|
return costSheetsOf(payload, user);
|
|
};
|