feat(cupang): 센터에 담긴 혼합 박스 내용물 트리 표시
③ 센터 분배에서 혼합 박스 줄 아래에 무엇이 몇 개 들어가는지 트리로 펼쳐 보여준다. 2박스 이상이면 총 개수와 함께 "(4개 × 2박스)" 를 덧붙인다. 수량을 바꾸면 트리 수치도 즉시 갱신된다. 단일 제품 박스는 트리가 없다. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{% extends "erp_base.html" %}
|
{% extends "erp_base.html" %}
|
||||||
|
|
||||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260829h" />{% endblock %}
|
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260829i" />{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<section class="cpg">
|
<section class="cpg">
|
||||||
@@ -173,6 +173,7 @@
|
|||||||
// ── 상태 ─────────────────────────────────────────
|
// ── 상태 ─────────────────────────────────────────
|
||||||
var calc = { results: [], mixes: [] }; // 서버 계산 결과
|
var calc = { results: [], mixes: [] }; // 서버 계산 결과
|
||||||
var units = {}; // key -> 박스 1개당 상품 수
|
var units = {}; // key -> 박스 1개당 상품 수
|
||||||
|
var contents = {}; // key -> 혼합 박스 내용물 [{product_name, quantity}]
|
||||||
var labels = {}; // key -> 표시 이름
|
var labels = {}; // key -> 표시 이름
|
||||||
var openCenters = []; // ③ 에 추가한 센터 id (문자열)
|
var openCenters = []; // ③ 에 추가한 센터 id (문자열)
|
||||||
var alloc = {}; // centerId -> [{id, key, count}]
|
var alloc = {}; // centerId -> [{id, key, count}]
|
||||||
@@ -230,6 +231,7 @@
|
|||||||
calc.mixes = (data && data.mixes) || [];
|
calc.mixes = (data && data.mixes) || [];
|
||||||
units = {};
|
units = {};
|
||||||
labels = {};
|
labels = {};
|
||||||
|
contents = {};
|
||||||
calc.results.forEach(function (r) {
|
calc.results.forEach(function (r) {
|
||||||
units[prodKey(r.product_code)] = r.units_per_box;
|
units[prodKey(r.product_code)] = r.units_per_box;
|
||||||
labels[prodKey(r.product_code)] = r.product_name;
|
labels[prodKey(r.product_code)] = r.product_name;
|
||||||
@@ -240,6 +242,9 @@
|
|||||||
b.items.forEach(function (it) { n += it.quantity; });
|
b.items.forEach(function (it) { n += it.quantity; });
|
||||||
units[mixKey(m.box_name, i)] = n;
|
units[mixKey(m.box_name, i)] = n;
|
||||||
labels[mixKey(m.box_name, i)] = m.box_name + " 혼합 #" + (i + 1);
|
labels[mixKey(m.box_name, i)] = m.box_name + " 혼합 #" + (i + 1);
|
||||||
|
contents[mixKey(m.box_name, i)] = b.items.map(function (it) {
|
||||||
|
return { product_name: it.product_name, quantity: it.quantity };
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
var had = Object.keys(alloc).some(function (k) { return alloc[k].length; });
|
var had = Object.keys(alloc).some(function (k) { return alloc[k].length; });
|
||||||
@@ -388,6 +393,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 혼합 박스는 안에 무엇이 몇 개 들어가는지 트리로 펼쳐 보여준다.
|
||||||
|
function treeHtml(entry) {
|
||||||
|
var list = contents[entry.key];
|
||||||
|
if (!list || !list.length) return "";
|
||||||
|
return '<ul class="cpg-dist-tree">' + list.map(function (it) {
|
||||||
|
return '<li><span class="cpg-tree-name">' + esc(it.product_name) + "</span>" +
|
||||||
|
'<span class="cpg-tree-qty">' + (it.quantity * entry.count) + "개</span>" +
|
||||||
|
(entry.count > 1 ? '<span class="cpg-tree-per">(' + it.quantity + "개 × " + entry.count + "박스)</span>" : "") +
|
||||||
|
"</li>";
|
||||||
|
}).join("") + "</ul>";
|
||||||
|
}
|
||||||
|
|
||||||
// ── ③ 센터 분배 렌더 ──────────────────────────────
|
// ── ③ 센터 분배 렌더 ──────────────────────────────
|
||||||
function renderDist() {
|
function renderDist() {
|
||||||
if (!distList) return;
|
if (!distList) return;
|
||||||
@@ -402,10 +419,13 @@
|
|||||||
boxes += a.count;
|
boxes += a.count;
|
||||||
pieces += a.count * per;
|
pieces += a.count * per;
|
||||||
items += '<li class="cpg-dist-item" data-entry="' + a.id + '">' +
|
items += '<li class="cpg-dist-item" data-entry="' + a.id + '">' +
|
||||||
|
'<div class="cpg-dist-line">' +
|
||||||
'<span class="cpg-dist-name">' + esc(labels[a.key] || a.key) + "</span>" +
|
'<span class="cpg-dist-name">' + esc(labels[a.key] || a.key) + "</span>" +
|
||||||
'<input class="erp-input cpg-dist-qty" type="number" min="1" step="1" value="' + a.count + '" />' +
|
'<input class="erp-input cpg-dist-qty" type="number" min="1" step="1" value="' + a.count + '" />' +
|
||||||
'<span class="cpg-dist-unit">박스 · ' + (a.count * per) + "개</span>" +
|
'<span class="cpg-dist-unit">박스 · ' + (a.count * per) + "개</span>" +
|
||||||
'<button type="button" class="erp-btn erp-btn-danger cpg-dist-del" title="빼기" aria-label="빼기">✕</button>' +
|
'<button type="button" class="erp-btn erp-btn-danger cpg-dist-del" title="빼기" aria-label="빼기">✕</button>' +
|
||||||
|
"</div>" +
|
||||||
|
treeHtml(a) +
|
||||||
"</li>";
|
"</li>";
|
||||||
});
|
});
|
||||||
html += '<div class="cpg-dist-center' + (rows.length ? " has-items" : "") + '" data-drop-for="' + esc(cid) + '">' +
|
html += '<div class="cpg-dist-center' + (rows.length ? " has-items" : "") + '" data-drop-for="' + esc(cid) + '">' +
|
||||||
@@ -608,6 +628,8 @@
|
|||||||
if (want > max) { want = max; e.target.value = max; }
|
if (want > max) { want = max; e.target.value = max; }
|
||||||
entry.count = want;
|
entry.count = want;
|
||||||
li.querySelector(".cpg-dist-unit").textContent = "박스 · " + (want * (units[entry.key] || 0)) + "개";
|
li.querySelector(".cpg-dist-unit").textContent = "박스 · " + (want * (units[entry.key] || 0)) + "개";
|
||||||
|
var tree = li.querySelector(".cpg-dist-tree");
|
||||||
|
if (tree) tree.outerHTML = treeHtml(entry);
|
||||||
renderSummary();
|
renderSummary();
|
||||||
updateCenterTotals(cid);
|
updateCenterTotals(cid);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "erp_base.html" %}
|
{% extends "erp_base.html" %}
|
||||||
|
|
||||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260829h" />{% endblock %}
|
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260829i" />{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<section class="cpg">
|
<section class="cpg">
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "erp_base.html" %}
|
{% extends "erp_base.html" %}
|
||||||
|
|
||||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260829h" />{% endblock %}
|
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260829i" />{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<section class="cpg">
|
<section class="cpg">
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "erp_base.html" %}
|
{% extends "erp_base.html" %}
|
||||||
|
|
||||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260829h" />{% endblock %}
|
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260829i" />{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<section class="cpg">
|
<section class="cpg">
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "erp_base.html" %}
|
{% extends "erp_base.html" %}
|
||||||
|
|
||||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260829h" />{% endblock %}
|
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260829i" />{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<section class="cpg">
|
<section class="cpg">
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "erp_base.html" %}
|
{% extends "erp_base.html" %}
|
||||||
|
|
||||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260829h" />{% endblock %}
|
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260829i" />{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<section class="cpg">
|
<section class="cpg">
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "erp_base.html" %}
|
{% extends "erp_base.html" %}
|
||||||
|
|
||||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260829h" />{% endblock %}
|
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260829i" />{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<section class="cpg">
|
<section class="cpg">
|
||||||
|
|||||||
@@ -705,3 +705,28 @@ body.cpg-dragging { cursor: grabbing; user-select: none; }
|
|||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
.cpg-dlg-center-btn { padding: 4px 12px; }
|
.cpg-dlg-center-btn { padding: 4px 12px; }
|
||||||
|
|
||||||
|
/* 센터에 담긴 혼합 박스의 내용물 트리 */
|
||||||
|
.cpg-dist-item { display: block; }
|
||||||
|
.cpg-dist-line { display: flex; align-items: center; gap: 6px; }
|
||||||
|
.cpg-dist-tree {
|
||||||
|
list-style: none;
|
||||||
|
margin: 4px 0 2px;
|
||||||
|
padding: 0 0 0 10px;
|
||||||
|
border-left: 1px solid var(--color-subtle-ash);
|
||||||
|
}
|
||||||
|
.cpg-dist-tree li {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 1px 0;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--color-midtone-gray);
|
||||||
|
}
|
||||||
|
.cpg-dist-tree li::before {
|
||||||
|
content: "└";
|
||||||
|
color: var(--color-subtle-ash);
|
||||||
|
}
|
||||||
|
.cpg-tree-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||||
|
.cpg-tree-qty { font-weight: 600; color: var(--color-rich-black); }
|
||||||
|
.cpg-tree-per { font-size: 11px; }
|
||||||
|
|||||||
@@ -143,6 +143,12 @@ function dragCardTo(card, target) {
|
|||||||
$("#cpg-dlg-ok").click();
|
$("#cpg-dlg-ok").click();
|
||||||
check("혼합 박스가 센터에 담긴다", $$(".cpg-dist-item").length === 2);
|
check("혼합 박스가 센터에 담긴다", $$(".cpg-dist-item").length === 2);
|
||||||
check("혼합 담은 뒤 배분됨 표시", $(".cpg-box-card").className.includes("is-done"));
|
check("혼합 담은 뒤 배분됨 표시", $(".cpg-box-card").className.includes("is-done"));
|
||||||
|
check("혼합 박스 아래 내용물 트리", $$(".cpg-dist-tree li").length === 2,
|
||||||
|
String($$(".cpg-dist-tree li").length));
|
||||||
|
check("트리에 제품명·개수", text(".cpg-dist-tree li").includes("미라네 4호 세트") &&
|
||||||
|
text(".cpg-dist-tree li").includes("4개"), text(".cpg-dist-tree li"));
|
||||||
|
check("단일 제품 항목에는 트리 없음",
|
||||||
|
!$$(".cpg-dist-item")[0].querySelector(".cpg-dist-tree"));
|
||||||
|
|
||||||
// ── 항목 빼기 / 센터 빼기 ─────────────────────────
|
// ── 항목 빼기 / 센터 빼기 ─────────────────────────
|
||||||
$$(".cpg-dist-del")[1].click();
|
$$(".cpg-dist-del")[1].click();
|
||||||
|
|||||||
Reference in New Issue
Block a user