/* ============================================================================= * logic/M02_Hopyo_Imported_Model.ts * 불러오기 단산 블록 = 가져온 식 단가산출(PLAN 793-3b · 809-1 · 요구 646 · 702) — 꼴 · 읽기만. * · SK `가져온` 덧칸 꼴(793-2 `M02_Sangeun_Imported.py` 머리) · 경쟁사 로직 그대로(기초로 바꾸기 없음 · 요구 703) * 화면 · fetch · sessionStorage 없음(`CLAUDE.md` 4장). * ========================================================================== */ export type Money4 = Record<"노무비" | "재료비" | "경비" | "계", number>; export interface CheckLine { 자리: string; 행?: number | null; 셈?: number | null; 엑셀?: number | null; 같음: boolean; 까닭?: string; } /** SK 문서 덧칸 `가져온` */ export interface ImportedMeta { 로직?: { 이름?: string; 호표?: { 이름?: string; 이음?: string | null }[] }; 단가기준?: "엑셀" | "우리"; 원본?: { 파일?: string; 시트?: string; 행?: number[]; 갈래?: string; 엑셀금액?: Money4; 글줄?: { 행?: number | null; 글?: string; 자리?: string; 값?: number | null }[]; }; 검산?: { 같음: boolean; 까닭?: string | null; 셈?: Money4 | null; 엑셀?: Money4; 줄: CheckLine[]; }; } export interface ImportedDoc { 이름?: string; 단위?: string; 입력값?: Record; 가져온?: ImportedMeta; [k: string]: unknown; } /** 가져온 식(경쟁사 로직이 든 SK) */ export const isImported = (d: ImportedDoc | null | undefined): boolean => !!d?.가져온?.로직; /** 검산 다른 줄 */ export const wrongLines = (d: ImportedDoc): CheckLine[] => (d.가져온?.검산?.줄 ?? []).filter((x) => !x.같음); /** 금액 차이 글(후 − 전) */ export function gapText( before: Money4 | null | undefined, after: Money4 | null | undefined, ): string { if (!before || !after) return "—"; const d = after.계 - before.계; return `${d > 0 ? "+" : ""}${d.toLocaleString("ko-KR")}`; }