/* ============================================================================= * M02_MasterTemplete_Sangeun_Unit.ts * 단가산출(SK) 단위 환산 칸(PLAN 728-2 · 요구서_내역19 3장 5) — 바탕 기준단위(「100본」) → SK 단위 근거 글 · * 같은 성격 = 배 자동(글만) · 성격 다름 = 환산 계수 칸 · 부피 ↔ 무게 = 단위중량 표(CC000337) 고르기. * 칸 보임 · 근거 글 = `swapUnit`(짝 `A00_Common/master_unit_swap.ts`) · 셈 = 서버(`M02_Sangeun_Calc.ratio_of`) * 문서 칸 `환산` {계수 | 단위중량 {종별, 형상}}(꼴 = 서버 `M02_Sangeun_Doc._swap_how`) · 바꿈 = 캐시 → [저장]. * ========================================================================== */ import { el } from "@ui/ui_template_elements"; import { createInputField, createSelectField } from "@ui/ui_template_input"; import { t as L } from "@ui/ui_template_locale"; import { createText } from "@ui/ui_template_text"; import { swapUnit } from "../A00_Common/master_unit_swap"; import { loadTable } from "../M01_MasterData/M01_MasterData_UI_Logic_Note"; export interface SwapHow { 계수?: number; 단위중량?: { 종별: string; 형상: string }; } const WEIGHT_TABLE = "CC000337"; /** 결과단위 「원/100본」 → 기준단위 「100본」(SK 단위 처음 값) */ export const baseUnitOf = (result: string): string => result.replace(/^원\s*\/\s*/, "").trim(); /** 단위중량 표 줄 → ㎏/㎥(위 끝 · 서버 `master_unit.unit_weight` 기본과 같음) */ const rhoOf = (row: Record | undefined): number | null => row && Number.isFinite(Number(row.위)) ? Number(row.위) : null; /** 환산 칸 — 「식」 · 빈 단위 · 바탕 없음 = null(옛 셈) */ export function buildUnitSwap(opt: { result: string; unit: string; how: SwapHow | undefined; edit: boolean; onChange: (how: SwapHow | undefined) => void; }): HTMLElement | null { const have = baseUnitOf(opt.result); if (!have || !opt.unit || opt.unit === "식") return null; const how = opt.how ?? {}; const probe = swapUnit(have, opt.unit, 1000, how.계수); const root = el("div", { className: "m02-sk__tags", attrs: { "data-sk-swap": "" } }); const note = createText("", "muted", 14); const say = (rho: number | null): void => { const got = swapUnit(have, opt.unit, rho, how.계수); note.textContent = got.근거; note.dataset.skSwapBlocked = got.배 === null ? "1" : ""; }; if (probe.계수 === "사용자") { const [, ua] = probe.가; const [, ub] = probe.나; const box = createInputField({ label: `${L("M02_SangeunSwapCoef")} — 1 ${ua} = ? ${ub}`, type: "number", value: how.계수 != null ? String(how.계수) : "", min: 0, compact: true, size: 28, }); box.input.dataset.skSwapCoef = ""; box.input.disabled = !opt.edit; box.input.addEventListener("change", () => { const v = Number(box.input.value); opt.onChange(Number.isFinite(v) && v > 0 ? { 계수: v } : undefined); }); root.append(box.root); } else if (probe.계수 === "단위중량") { const pick = how.단위중량; const value = pick ? `${pick.종별}|${pick.형상}` : ""; const select = createSelectField({ label: `${L("M02_SangeunSwapWeight")} (${WEIGHT_TABLE})`, options: [{ value: "", text: L("M02_SangeunSwapPick") }], value, compact: true, size: 28, disabled: !opt.edit, onChange: (v) => { const [종별, 형상] = v.split("|"); opt.onChange(v ? { 단위중량: { 종별, 형상 } } : undefined); }, }); select.select.dataset.skSwapWeight = ""; root.append(select.root); void loadTable(WEIGHT_TABLE).then((table) => { const rows = table?.줄 ?? []; select.setOptions( [ { value: "", text: L("M02_SangeunSwapPick") }, ...rows.map((r) => ({ value: `${String(r.종별)}|${String(r.형상)}`, text: `${String(r.종별)} · ${String(r.형상)} (${String(r.위)}㎏/㎥)`, })), ], value, ); say(rhoOf(rows.find((r) => r.종별 === pick?.종별 && r.형상 === pick?.형상))); }); } say(null); if (!root.childElementCount && !note.textContent) return null; root.append(note); return root; }