// 원본 주요심사내용 창(TfrmInvest) 자동입력 — 심사평가결과(0x10bf3xx)·주요심사내용(0x10bfc98). // 심사평가결과: 원가계산서에서 이름(빈칸·| 제거)에 「총공사비」가 든 첫 행의 Cost_(설계)·Cost(심사), 절감액 = 심사 − 설계, // 절감율 = Trunc(절감액 / 설계 × 10000) × 0.01 %(둘 다 0 아닐 때), 숫자는 cp949 바이트 16칸 오른쪽 맞춤, 증액에만 「+」. // 주요심사내용: 노임·자재·표준시장·견적·기계경비·단가산출·일위대가 차례로 NewItem 행이 있으면 // 「○○ 조정 : 이름(규격) 외N 종」(N = 첫 행을 포함한 전체 개수, 원본 셈 그대로) 한 줄씩. const EstReviewAuto = (() => { const num = (value) => Number(value) || 0; const strip = (text) => String(text ?? "").replace(/[\s|]/g, ""); const bytes = (text) => [...text].reduce((n, ch) => n + (ch.charCodeAt(0) > 0x7f ? 2 : 1), 0); const right16 = (text) => " ".repeat(Math.max(0, 16 - bytes(text))) + text; const fmt = (value) => Number(value).toLocaleString("en-US", { maximumFractionDigits: 9, useGrouping: true }); function result(project) { const row = (project.tables.Wonga || []).find((r) => strip(r.Name).includes("총공사비")); if (!row) return null; const design = num(row.Cost_), review = num(row.Cost), d = review - design, sign = d > 0 ? "+" : ""; const lines = [ `o 설계금액 : ${right16(fmt(design))} 원`, `o 심사금액 : ${right16(fmt(review))} 원`, `o 절 감 액 : ${right16(sign + fmt(d))} 원`, ]; if (d && design) { const r = Math.trunc((d / design) * 10000) * 0.01; lines.push(`o 절 감 율 : ${right16(sign + fmt(Number(r.toFixed(2))))} %`); } return lines.join("\n"); } const tables = [ ["LaborcDat", "노임단가", false], ["StuffcDat", "자재단가", true], ["SilJukDat", "표준시장단가", true], ["EstiMateDat", "견적단가", true], ["MachTitleDat", "기계경비", true], ["CostTitleDat", "단가산출", true], ["HeadTitleDat", "일위대가", true], ]; function content(project) { return tables .map(([table, label, size]) => { const rows = (project.tables[table] || []).filter((r) => r.NewItem); if (!rows.length) return ""; const first = rows[0]; return `${label} 조정 : ${strip(first.Name)}${size ? `(${strip(first.Size)})` : ""} 외${rows.length} 종`; }) .filter(Boolean) .join("\n"); } function handle(name, state) { if (name !== "review-auto-result" && name !== "review-auto-content") return false; const key = name === "review-auto-result" ? "173-result" : "173", text = name === "review-auto-result" ? result(state.project) : content(state.project); if (text == null) throw Error("원가계산서에 총공사비 행이 없습니다."); const old = state.project.documents?.[key]; if (old && !confirm("기존 내용을 지우고 자동입력하시겠습니까?")) return true; EstApp.change((project) => { project.documents ||= {}; project.documents[key] = text; }, false); return true; } return { result, content, handle }; })();