/* 말레이시아 창고 랙 보기 — 드래그 재배치 + 저장 + 인쇄 미리보기. * * - 각 .rv-cell 의 data-entries(JSON)가 진실원천. 드래그 드롭으로 두 칸의 * 구성(entries)을 맞교환(빈 칸이면 이동). 칸 번호(cell)는 그대로. * - 저장: 모든 칸의 현재 구성을 rk_cell/rk_sku/rk_upb/rk_box 병렬배열 hidden * 으로 만들어 POST /malaysia/rack/save (서버 reposition_rack). * - 인쇄: 체크한 칸을 칸마다 A4 가로 1장으로 미리보기 후 window.print(). * - 언어: localStorage('mys_lang'). 셀/미리보기 텍스트를 현재 언어로 렌더. */ (function () { "use strict"; function lang() { return localStorage.getItem("mys_lang") === "en" ? "en" : "ko"; } function t(ko, en) { return lang() === "en" ? en : ko; } function fmt(n) { return Number(n || 0).toLocaleString(); } function nameOf(e) { return (lang() === "en" ? e.en : e.ko) || e.sku; } function getEntries(cell) { try { return JSON.parse(cell.getAttribute("data-entries") || "[]"); } catch (_) { return []; } } function setEntries(cell, arr) { cell.setAttribute("data-entries", JSON.stringify(arr)); } function renderCell(cell) { var items = cell.querySelector(".rv-items"); if (!items) return; var arr = getEntries(cell); items.innerHTML = ""; if (!arr.length) { cell.classList.add("is-empty"); var s = document.createElement("span"); s.className = "rv-empty-note"; s.textContent = "—"; items.appendChild(s); return; } cell.classList.remove("is-empty"); arr.forEach(function (e) { var total = (Number(e.upb) || 0) * (Number(e.box) || 0); var wrap = document.createElement("div"); wrap.className = "rv-item"; var nm = document.createElement("span"); nm.className = "rv-name"; nm.textContent = nameOf(e); var calc = document.createElement("span"); calc.className = "rv-calc"; calc.innerHTML = fmt(e.upb) + t("개", "ea") + " × " + fmt(e.box) + t("박스", "box") + " = " + fmt(total) + ""; wrap.appendChild(nm); wrap.appendChild(document.createElement("br")); wrap.appendChild(calc); items.appendChild(wrap); }); } function renderAll() { document.querySelectorAll(".rv-cell").forEach(renderCell); } // ── 드래그 재배치 ── var dragSrc = null; var dirty = false; function markDirty() { dirty = true; var b = document.getElementById("rv-save-btn"); if (b) b.classList.add("is-dirty"); } function cleanup() { if (dragSrc) dragSrc.classList.remove("dragging"); dragSrc = null; document.querySelectorAll(".rv-cell.is-dragover") .forEach(function (c) { c.classList.remove("is-dragover"); }); } function onDragStart(e) { var cell = e.target.closest(".rv-cell"); if (!cell) return; dragSrc = cell; cell.classList.add("dragging"); e.dataTransfer.effectAllowed = "move"; try { e.dataTransfer.setData("text/plain", cell.getAttribute("data-cell")); } catch (_) {} } function onDragOver(e) { if (!dragSrc) return; e.preventDefault(); e.dataTransfer.dropEffect = "move"; var cell = e.target.closest(".rv-cell"); if (cell && cell !== dragSrc) cell.classList.add("is-dragover"); } function onDragLeave(e) { var cell = e.target.closest(".rv-cell"); if (cell) cell.classList.remove("is-dragover"); } function onDrop(e) { e.preventDefault(); var dst = e.target.closest(".rv-cell"); if (!dst || !dragSrc || dst === dragSrc) { cleanup(); return; } var a = getEntries(dragSrc); var b = getEntries(dst); setEntries(dragSrc, b); setEntries(dst, a); renderCell(dragSrc); renderCell(dst); markDirty(); cleanup(); } // ── 인쇄 선택(체크박스) → 셀 강조 ── function onChange(e) { var cb = e.target; if (!cb.classList || !cb.classList.contains("rv-pick")) return; var cell = cb.closest(".rv-cell"); if (cell) cell.classList.toggle("is-selected", cb.checked); } // ── 저장 ── function addHidden(parent, name, val) { var i = document.createElement("input"); i.type = "hidden"; i.name = name; i.value = val; parent.appendChild(i); } function save() { var fields = document.getElementById("rv-save-fields"); var form = document.getElementById("rv-save-form"); if (!fields || !form) return; fields.innerHTML = ""; document.querySelectorAll(".rv-cell").forEach(function (cell) { var cc = cell.getAttribute("data-cell"); getEntries(cell).forEach(function (e) { addHidden(fields, "rk_cell", cc); addHidden(fields, "rk_sku", e.sku); addHidden(fields, "rk_upb", e.upb); addHidden(fields, "rk_box", e.box); }); }); dirty = false; form.submit(); } // ── 인쇄 미리보기 ── function openPreview() { var picked = [].slice.call(document.querySelectorAll(".rv-cell")).filter(function (c) { var cb = c.querySelector(".rv-pick"); return cb && cb.checked; }); if (!picked.length) { alert(t("인쇄할 칸을 먼저 선택하세요.", "Select cells to print first.")); return; } var pages = document.getElementById("rvp-pages"); pages.innerHTML = ""; picked.forEach(function (cell) { var arr = getEntries(cell); var sheet = document.createElement("div"); sheet.className = "rvp-sheet"; var code = document.createElement("div"); code.className = "rvp-cell-code"; code.textContent = cell.getAttribute("data-cell"); sheet.appendChild(code); var list = document.createElement("div"); list.className = "rvp-list"; if (!arr.length) { var em = document.createElement("div"); em.className = "rvp-empty"; em.textContent = t("(비어 있음)", "(empty)"); list.appendChild(em); } else { arr.forEach(function (e) { var total = (Number(e.upb) || 0) * (Number(e.box) || 0); var line = document.createElement("div"); line.className = "rvp-line"; var nm = document.createElement("span"); nm.className = "rvp-name"; nm.textContent = nameOf(e); var calc = document.createElement("span"); calc.className = "rvp-calc"; calc.textContent = fmt(e.upb) + t("개", "ea") + " × " + fmt(e.box) + t("박스", "box") + " = " + fmt(total); line.appendChild(nm); line.appendChild(calc); list.appendChild(line); }); } sheet.appendChild(list); pages.appendChild(sheet); }); document.getElementById("rvp-overlay").classList.add("is-open"); } function closePreview() { document.getElementById("rvp-overlay").classList.remove("is-open"); } document.addEventListener("DOMContentLoaded", function () { renderAll(); var board = document.getElementById("rv-board"); if (board) { board.addEventListener("dragstart", onDragStart); board.addEventListener("dragover", onDragOver); board.addEventListener("dragleave", onDragLeave); board.addEventListener("drop", onDrop); board.addEventListener("dragend", cleanup); board.addEventListener("change", onChange); } var sb = document.getElementById("rv-save-btn"); if (sb) sb.addEventListener("click", save); var pb = document.getElementById("rv-print-btn"); if (pb) pb.addEventListener("click", openPreview); var pc = document.getElementById("rvp-close"); if (pc) pc.addEventListener("click", closePreview); var pp = document.getElementById("rvp-print"); if (pp) pp.addEventListener("click", function () { window.print(); }); var lt = document.getElementById("mys-lang-toggle"); if (lt) lt.addEventListener("click", function () { setTimeout(renderAll, 0); }); window.addEventListener("beforeunload", function (ev) { if (dirty) { ev.preventDefault(); ev.returnValue = ""; } }); }); })();