- 확인 창 표 가름(`tableOf`): 전국 대상도 자재 표(코드 칸 「전국」) · 미리 셈 문서엔 안 넣음(키 · 단가 없음) - 변형 차례: 「전지역」 낱말 든 지역 품목이 접힌 목록 앞에 오던 것 → (전국) 먼저는 지역 없는 품목에만 - 시험: 화면 도우미 전국 표 · 미리 셈 없음 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XWh5wNNycMkbwMpACz1rte
58 lines
3.2 KiB
TypeScript
58 lines
3.2 KiB
TypeScript
/* =============================================================================
|
|
* M02_MasterTemplete/logic/M02_MasterTemplete_Hopyo_Draft.ts
|
|
* 확인 창 금액 미리 보기 꼴(PLAN 359-3) — 엑셀 줄 하나 + 지금 대상 → 일위대가 문서 한 벌(서버 `/labor/{열}/calc` 에
|
|
* 보냄 · 저장 안 함 · 금액은 서버가 셈) · 줄이 들어갈 표(로직 표 · 자재 표).
|
|
* 정본 = 서버 `M02_Hopyo_Build.Builder.build` 의 `put`([사전조합 생성] 때 다시 셈) — 같은 규칙:
|
|
* 우리 수량 = 엑셀 수량 × 배 · 로직 = {로직, 입력값, 수량 {손}} · 자재 = {코드, 수량 {손}, 별도계상 =
|
|
* 갈래 별도계상이면 「별도계상」 아니면 「직접계산」} · 같은 자재 = 수량 더함.
|
|
* 「전국」 자재(361-1 · 키 · 단가 없음) = 자재 표 · 문서엔 안 넣음(Build = 본뜬.전국자재 · 금액 없음).
|
|
* 미리 보기만 다른 것: 호표 대상(하위 사전조합 — 만든 뒤 셈) · 배 없는 대상은 뺌 ·
|
|
* 같은 로직 둘째는 뺌(Build = 한 줄 사전조합으로 감쌈 · 한 문서에 같은 로직 둘 = 서버 400).
|
|
* 화면 · fetch · sessionStorage 없음(`CLAUDE.md` 4장).
|
|
* ========================================================================== */
|
|
|
|
import type { HopyoLine, HopyoPart } from "../M02_MasterTemplete_Hopyo_Api";
|
|
import type { LaborDoc, LaborMat, LaborRow } from "../M02_MasterTemplete_Labor_Api";
|
|
|
|
export type CheckTable = "logic" | "mat";
|
|
|
|
/** 엑셀 갈래 중 자재 표로 가는 것(대상 없을 때) */
|
|
const MAT_KINDS = ["자재", "별도계상"];
|
|
|
|
/** 줄이 들어갈 표 — 대상이 모두 자재(전국 포함)면 자재 표 · 대상 없으면 갈래(자재 · 별도계상) · 그 밖 로직 표 */
|
|
export function tableOf(line: Pick<HopyoLine, "갈래">, parts: HopyoPart[]): CheckTable {
|
|
if (parts.length) return parts.every((p) => !!p.자재 || !!p.전국) ? "mat" : "logic";
|
|
return MAT_KINDS.includes(line.갈래) ? "mat" : "logic";
|
|
}
|
|
|
|
/** 엑셀 줄 + 대상 → 미리 셈 문서 · 셀 것이 없으면 null(호표 대상뿐 · 배 없음 · 대상 없음) */
|
|
export function draftDoc(
|
|
line: Pick<HopyoLine, "수량" | "갈래">,
|
|
parts: HopyoPart[],
|
|
): LaborDoc | null {
|
|
const rows: LaborRow[] = [];
|
|
const mats = new Map<string, LaborMat>();
|
|
const apart = line.갈래 === "별도계상" ? "별도계상" : "직접계산";
|
|
for (const p of parts) {
|
|
if (p.배 === null || p.호표 !== undefined) continue;
|
|
const qty = (line.수량 ?? 0) * p.배;
|
|
if (p.자재) {
|
|
const have = mats.get(p.자재)?.수량;
|
|
const hand = (have ? have.손 : 0) + qty;
|
|
mats.set(p.자재, {
|
|
코드: p.자재,
|
|
이름: null,
|
|
규격: null,
|
|
단위: null,
|
|
수량: { 손: hand },
|
|
별도계상: apart,
|
|
});
|
|
} else if (p.로직 && !rows.some((r) => r.로직 === p.로직)) {
|
|
const values = (p.입력값 ?? {}) as LaborRow["입력값"];
|
|
rows.push({ 로직: p.로직, 별칭: null, 메모: null, 입력값: values, 수량: { 손: qty } });
|
|
}
|
|
}
|
|
if (!rows.length && !mats.size) return null;
|
|
return { 종류: "일위대가", 열: "", 단위: null, 담은로직: rows, 자재: [...mats.values()] };
|
|
}
|