/* 쿠팡 밀크런 — 출고 폼 동적 라인.
제품명 드롭다운(설정에서 등록한 카탈로그) 선택 → 제품코드 자동 입력.
수량 입력 시 박스 수 미리보기(서버가 저장 시 store.compute_boxes 로 재계산). */
(function () {
"use strict";
var CFG = window.CPG || {};
var body = document.getElementById("cpg-lines-body");
var form = document.getElementById("cpg-form");
if (!body || !form) return;
// 입수량 규칙: product_code -> units_per_box
var ruleMap = {};
try {
var rules = JSON.parse(document.getElementById("cpg-box-rules").textContent || "[]");
rules.forEach(function (r) { if (r.active !== false) ruleMap[r.product_code] = r.units_per_box; });
} catch (e) {}
// 제품 카탈로그: [{product_code, product_name}]
var products = [];
try { products = JSON.parse(document.getElementById("cpg-products").textContent || "[]"); } catch (e) {}
var nameByCode = {};
products.forEach(function (p) { nameByCode[p.product_code] = p.product_name; });
var initLines = [];
try { initLines = JSON.parse(document.getElementById("cpg-init-lines").textContent || "[]"); } catch (e) {}
function ceilDiv(a, b) { return Math.ceil(a / b); }
function recalc(row) {
var qty = parseInt(row.querySelector(".cpg-qty").value, 10) || 0;
var upb = parseInt(row.querySelector(".cpg-upb").value, 10);
var cell = row.querySelector(".cpg-line-calc");
if (!upb || upb <= 0) { cell.textContent = "미설정"; cell.classList.add("cpg-warn"); return; }
cell.classList.remove("cpg-warn");
if (qty <= 0) { cell.textContent = "—"; return; }
var boxes = ceilDiv(qty, upb), rem = qty % upb;
cell.textContent = boxes + "박스" + (rem ? " +" + rem : " (딱맞음)");
}
function buildNameSelect(selectedCode) {
var sel = document.createElement("select");
sel.className = "erp-select cpg-name-sel";
var opt0 = document.createElement("option");
opt0.value = ""; opt0.textContent = "— 제품명 선택 —";
sel.appendChild(opt0);
var found = false;
products.forEach(function (p) {
var o = document.createElement("option");
o.value = p.product_code;
o.textContent = p.product_name;
o.setAttribute("data-name", p.product_name);
if (p.product_code === selectedCode) { o.selected = true; found = true; }
sel.appendChild(o);
});
// 카탈로그에 없는 기존 라인 코드 → 임시 옵션으로 표시
if (selectedCode && !found) {
var o = document.createElement("option");
o.value = selectedCode;
o.textContent = (nameByCode[selectedCode] || selectedCode) + " (미등록)";
o.setAttribute("data-name", nameByCode[selectedCode] || selectedCode);
o.selected = true;
sel.appendChild(o);
}
return sel;
}
function makeRow(data) {
data = data || {};
var tr = document.createElement("tr");
// 컬럼: # / 제품명(select) / 제품코드 / 수량 / 입수량 / 박스계산 / 라인메모 / 삭제
tr.innerHTML =
'
| ' +
' | ' +
' | ' +
' | ' +
' | ' +
'— | ' +
' | ';
var code = data.product_code || "";
var nameSel = buildNameSelect(code);
tr.querySelector(".cpg-cell-name").appendChild(nameSel);
var codeInput = tr.querySelector(".cpg-code");
codeInput.value = code;
tr.querySelector(".cpg-qty").value = data.quantity || "";
var upb = data.units_per_box;
if (upb == null && code && ruleMap[code] != null) upb = ruleMap[code];
tr.querySelector(".cpg-upb").value = (upb != null ? upb : "");
// 제품명 선택 → 코드 자동 입력 + 입수량 자동
nameSel.addEventListener("change", function () {
var c = nameSel.value;
codeInput.value = c;
if (c && ruleMap[c] != null) tr.querySelector(".cpg-upb").value = ruleMap[c];
recalc(tr);
});
// 코드 직접 입력 시 입수량 규칙 자동
codeInput.addEventListener("input", function () {
var c = codeInput.value.trim();
if (c && ruleMap[c] != null && !tr.querySelector(".cpg-upb").value) {
tr.querySelector(".cpg-upb").value = ruleMap[c];
}
});
tr.querySelector(".cpg-qty").addEventListener("input", function () { recalc(tr); });
tr.querySelector(".cpg-upb").addEventListener("input", function () { recalc(tr); });
body.appendChild(tr);
recalc(tr);
renumber();
return tr;
}
function renumber() {
Array.prototype.forEach.call(body.querySelectorAll("tr"), function (tr, i) {
tr.querySelector(".cpg-line-no").textContent = i + 1;
});
}
// 초기 라인
if (initLines.length) { initLines.forEach(makeRow); } else { makeRow(); }
document.getElementById("cpg-add-line").addEventListener("click", function () { makeRow(); });
// 마지막 라인 삭제 (최소 1줄 유지)
var delBtn = document.getElementById("cpg-del-line");
if (delBtn) {
delBtn.addEventListener("click", function () {
var rows = body.querySelectorAll("tr");
if (rows.length <= 1) { alert("최소 1개 라인은 필요합니다."); return; }
rows[rows.length - 1].remove();
renumber();
});
}
// 제출: 라인 직렬화
form.addEventListener("submit", function (e) {
var lines = [];
Array.prototype.forEach.call(body.querySelectorAll("tr"), function (tr) {
var code = tr.querySelector(".cpg-code").value.trim();
var qty = parseInt(tr.querySelector(".cpg-qty").value, 10) || 0;
if (!code || qty <= 0) return;
var upb = parseInt(tr.querySelector(".cpg-upb").value, 10);
var sel = tr.querySelector(".cpg-name-sel");
var name = "";
if (sel && sel.selectedIndex >= 0) {
var opt = sel.options[sel.selectedIndex];
name = opt ? (opt.getAttribute("data-name") || "") : "";
}
if (!name) name = nameByCode[code] || code;
lines.push({
product_code: code,
product_name_snapshot: name,
quantity: qty,
units_per_box: (upb > 0 ? upb : null),
memo: tr.querySelector(".cpg-memo").value.trim()
});
});
if (!lines.length) {
e.preventDefault();
alert("품목 라인을 최소 1개 입력하세요 (제품명/코드 + 수량).");
return;
}
document.getElementById("cpg-lines-json").value = JSON.stringify(lines);
});
// 입고센터 select → 스냅샷 hidden 동기화
var centerSel = document.getElementById("cpg-center-select");
var centerName = document.getElementById("cpg-center-name");
if (centerSel && centerName) {
function syncCenter() {
var opt = centerSel.options[centerSel.selectedIndex];
if (opt && opt.value) centerName.value = opt.getAttribute("data-name") || opt.text;
}
centerSel.addEventListener("change", syncCenter);
if (!centerName.value) syncCenter();
}
})();