- 첫 탭 = 설계내역서(빈 원가계산서 아님) · 엑셀 탭 차례는 그대로 - 빈 줄 = 설계내역서 금액 모르는 직접공사 항목 줄(blankRows) — 설계내역서 안내 · 데이터 점검 · 집계표 넷이 같은 수 · 같은 낱말 - 데이터 점검 = 「빈 줄 n」(줄마다 하나 · 까닭 모음) + 「그 밖 확인 n곳」(호표 · 재료 · 탭 · 키마다 하나) - test_203_1 낡은 값(첫 탭 · 「연결 없음 n곳」) 갱신 · helper 에 593-1 시각 글 stub(dateTimeText 없어 깨져 있던 것) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
93 lines
3.6 KiB
TypeScript
93 lines
3.6 KiB
TypeScript
/* =============================================================================
|
|
* B09_Estimation_UI_Tabs_Summary.ts
|
|
* B09 집계표 넷(PLAN 145-5) — 재료비 · 노무비 · 경비 수량금액집계표 · 중기시간금액집계표(실무 엑셀 꼴).
|
|
*
|
|
* 값 = 서버 단독 역전개(`B09_Estimation_Summary` · GET 응답 `summary`) — 조작 중엔 안 바뀜 · [저장] 뒤 정본
|
|
* 끝수 = 총수량 ROUND 2 · 금액 ROUND(수량 × 단가, 0) · 줄 누름 = 단가를 낸 목록표 줄
|
|
* 경비 집계표 빈 까닭(166-5) = 산근 · 대가 어느 길도 경비 자원 줄을 안 냄(기계 → 중기 · 구역화물 → 자재)
|
|
* ========================================================================== */
|
|
|
|
import type { DataRow } from "@ui/ui_template_data_table";
|
|
import type { Row } from "./B09_Estimation_Calc_Base";
|
|
import {
|
|
blankRows,
|
|
money,
|
|
qty,
|
|
text,
|
|
type TabBuild,
|
|
type TabId,
|
|
type TabTable,
|
|
} from "./B09_Estimation_UI_Tabs";
|
|
|
|
const HINT = "줄을 누르면 목록표로 이동";
|
|
|
|
/** 안내 + 「빈 줄 n」(설계내역서와 같은 수 · 701-2 — 금액 모르는 줄은 집계에서 빠짐) */
|
|
const hint = (sheets: Row, extra = ""): string => {
|
|
const n = blankRows(sheets).length;
|
|
return `${HINT}${extra}${n ? ` · 빈 줄 ${n} — 집계에서 빠짐(좌측 데이터 점검)` : ""}`;
|
|
};
|
|
|
|
/** 줄이 없을 때 표 위 맨 앞 안내 */
|
|
const EXPENSE_NONE = "경비 자원 없음";
|
|
|
|
function resourceTab(id: string, list: TabId, unitPrice: string, none = ""): TabBuild {
|
|
return ({ payload, sheets }): TabTable => {
|
|
const rows: DataRow[] = ((payload.summary || {})[id] || []).map((r: Row) => ({ ...r }));
|
|
const sum = rows.reduce((acc, r) => acc + (typeof r.amount === "number" ? r.amount : 0), 0);
|
|
return {
|
|
columns: [
|
|
qty("no", "호표", 0),
|
|
text("name", "명칭", 200),
|
|
text("spec", "규격", 140),
|
|
qty("qty", "수량", 2),
|
|
text("unit", "단위", 56),
|
|
money("price", unitPrice),
|
|
money("amount", "금액"),
|
|
text("note", "비고", 120),
|
|
],
|
|
rows,
|
|
total: rows.length ? { name: "계", amount: sum } : null,
|
|
frozen: 2,
|
|
hint: !rows.length && none ? `${none} · ${hint(sheets)}` : hint(sheets),
|
|
link: (i) => (rows[i] ? { tab: list, key: String(rows[i].key) } : null),
|
|
};
|
|
};
|
|
}
|
|
|
|
export const buildSumMaterial = resourceTab("sum_material", "material", "단가");
|
|
export const buildSumLabor = resourceTab("sum_labor", "labor", "단가");
|
|
export const buildSumExpense = resourceTab("sum_expense", "expense", "단가", EXPENSE_NONE);
|
|
|
|
export const buildSumMachine: TabBuild = ({ payload, sheets }): TabTable => {
|
|
const rows: DataRow[] = ((payload.summary || {}).sum_machine || []).map((r: Row) => ({ ...r }));
|
|
const add = (key: string) =>
|
|
rows.reduce((acc, r) => acc + (typeof r[key] === "number" ? (r[key] as number) : 0), 0);
|
|
return {
|
|
columns: [
|
|
qty("no", "호표", 0),
|
|
text("name", "명칭", 200),
|
|
text("spec", "규격", 120),
|
|
qty("qty", "수량", 2),
|
|
text("unit", "단위", 56),
|
|
money("sum", "합계"),
|
|
money("labor", "노무비"),
|
|
money("material", "재료비"),
|
|
money("expense", "경비"),
|
|
text("note", "비고", 120),
|
|
],
|
|
rows,
|
|
total: rows.length
|
|
? {
|
|
name: "계",
|
|
sum: add("sum"),
|
|
labor: add("labor"),
|
|
material: add("material"),
|
|
expense: add("expense"),
|
|
}
|
|
: null,
|
|
frozen: 2,
|
|
hint: hint(sheets),
|
|
link: (i) => (rows[i] ? { tab: "machine", key: String(rows[i].key) } : null),
|
|
};
|
|
};
|