diff --git a/M01_MasterData/M01_MasterData_UI_LogicLab_Detail.ts b/M01_MasterData/M01_MasterData_UI_LogicLab_Detail.ts index d4f51430..3fcc3c13 100644 --- a/M01_MasterData/M01_MasterData_UI_LogicLab_Detail.ts +++ b/M01_MasterData/M01_MasterData_UI_LogicLab_Detail.ts @@ -18,7 +18,7 @@ import type { TextPiece, } from "./M01_MasterData_UI_Logic_Api"; import { buildEditor, qtyKind } from "./M01_MasterData_UI_Logic_Edit"; -import { formatMoney } from "./M01_MasterData_UI_Logic_Money"; +import { formatMoney, formatPrice } from "./M01_MasterData_UI_Logic_Money"; import { openPicker } from "./M01_MasterData_UI_Logic_Pick"; import { tx } from "./M01_MasterData_UI_Logic_Text"; import { buildFormula } from "./M01_MasterData_UI_LogicLab_Formula"; @@ -206,7 +206,7 @@ const spread = (e: Entry, line?: CalcLine): Entry[] => { share: k, // 몫 줄 단가 = 단가 × (몫 금액 ÷ 줄 금액) — 곱하기 수량이 몫 금액과 맞게 ...(line && line.금액 && line.단가 != null - ? { price: formatMoney((line.단가 * v) / line.금액) } + ? { price: formatPrice((line.단가 * v) / line.금액) } : {}), } : {}), @@ -230,7 +230,7 @@ function entries(ctx: DetailContext): Entry[] { qty: item.수량, qtyTag: qtyKind(item.수량) === tx("Ho_QtyTable") ? tl("Tag_Table") : qtyKind(item.수량), qtyFrag: [{ text: item.수량 }], - price: price === undefined || price === null ? "" : formatMoney(price), + price: price === undefined || price === null ? "" : formatPrice(price), amount: line ? line.금액 : null, extra: false, open: (self) => diff --git a/M01_MasterData/M01_MasterData_UI_LogicLab_Modal.ts b/M01_MasterData/M01_MasterData_UI_LogicLab_Modal.ts index 9e6375bb..4af2d533 100644 --- a/M01_MasterData/M01_MasterData_UI_LogicLab_Modal.ts +++ b/M01_MasterData/M01_MasterData_UI_LogicLab_Modal.ts @@ -16,7 +16,7 @@ import { type NamedFormula, } from "./M01_MasterData_UI_Logic_Api"; import { formatNumber } from "./M01_MasterData_UI_Logic_Edit"; -import { formatMoney } from "./M01_MasterData_UI_Logic_Money"; +import { formatMoney, formatPrice } from "./M01_MasterData_UI_Logic_Money"; import { explain, loadTable, type TableRow } from "./M01_MasterData_UI_Logic_Note"; import { jumpToMaster, type MasterJump } from "./M01_MasterData_UI_Side"; import { fragmentRow, type Fragment } from "./M01_MasterData_UI_LogicLab_Pill"; @@ -176,7 +176,7 @@ function priceView(ref: string, brief: ElementBrief): HTMLElement { ? [el("dt", { text: tl("Modal_Spec") }), el("dd", { text: brief.규격 })] : []), el("dt", { text: tl("Modal_Value") }), - el("dd", { className: "m01-logic__money", text: formatMoney(brief.값) }), + el("dd", { className: "m01-logic__money", text: formatPrice(brief.값) }), ...(brief.file ? [el("dt", { text: tl("Modal_Source") }), el("dd", { text: brief.file })] : []), @@ -247,7 +247,7 @@ function candidateView( el("td", { text: it.이름 ?? it.ref }), el("td", { text: it.규격 ?? "" }), el("td", { text: String(it.단위 ?? "") }), - el("td", { className: "m01-logic__money", text: formatMoney(it.값) }), + el("td", { className: "m01-logic__money", text: formatPrice(it.값) }), ], }), ); @@ -307,7 +307,7 @@ export function openMaterialModal(target: ModalTarget): void { const logicKey = /^로직\((\w+)/.exec(element)?.[1] ?? ""; const sum = el("p", { className: "m01lab__sum" }); const setSum = (price: ElementBrief | null | undefined): void => { - const unit = price ? `${tl("Modal_UnitPrice")} ${formatMoney(price.값)} × ` : ""; + const unit = price ? `${tl("Modal_UnitPrice")} ${formatPrice(price.값)} × ` : ""; if (target.qtyFrag) { sum.replaceChildren(`${target.title} = ${unit}`, fragmentRow(target.qtyFrag)); } else sum.textContent = `${target.title} = ${unit}${explain(target.expr)}`; diff --git a/M01_MasterData/M01_MasterData_UI_Logic_Money.ts b/M01_MasterData/M01_MasterData_UI_Logic_Money.ts index ca28a43f..f89b7475 100644 --- a/M01_MasterData/M01_MasterData_UI_Logic_Money.ts +++ b/M01_MasterData/M01_MasterData_UI_Logic_Money.ts @@ -9,3 +9,11 @@ export const formatMoney = (value: unknown): string => typeof value === "number" ? value.toLocaleString("ko-KR", { maximumFractionDigits: 0 }) : formatNumber(value); + +/** 단가 모양 — 정수로 보이되 200 원 미만은 반올림 오차가 커서 소수 넷째 자리·유효숫자 4 자리 중 많은 쪽(뒤 0 뗌) */ +export const formatPrice = (value: unknown): string => + typeof value === "number" && value !== 0 && Math.abs(value) < 200 + ? value.toLocaleString("ko-KR", { + maximumFractionDigits: Math.max(4, 3 - Math.floor(Math.log10(Math.abs(value)))), + }) + : formatMoney(value);