@@ -249,7 +249,8 @@
});
var had = Object.keys(alloc).some(function (k) { return alloc[k].length; });
alloc = {};
- stamped = {}; // 계산이 바뀌면 이전 배분은 근거가 사라지므로 비운다.
+ stamped = {};
+ allStamped = false; // 계산이 바뀌면 이전 배분은 근거가 사라지므로 비운다.
render();
msg.textContent = "계산 완료 (" + calc.results.length + "건)" + (had ? " — 센터 분배 초기화됨" : "");
})
@@ -312,10 +313,13 @@
return '배분 완료';
}
- function kpi(label, value, hint) {
+ var allStamped = false; // 전체 배분 완료 도장이 이미 찍혀 있었는지
+
+ function kpi(label, value, hint, extra) {
return '' + esc(label) + "" +
'' + esc(value) + "" +
- '' + esc(hint) + "
";
+ '' + esc(hint) + "" +
+ (extra || "") + "";
}
function renderSummary() {
@@ -342,9 +346,19 @@
});
var assigned = (totalProd + totalMix) - (remainProd + remainMix);
+ // 모든 박스를 센터에 배분하면 "센터 배분" 칸에 전체 완료 도장을 찍는다.
+ var totalBoxes = totalProd + totalMix;
+ var allDone = totalBoxes > 0 && (remainProd + remainMix) === 0;
+ var allStamp = "";
+ if (allDone) {
+ allStamp = '전체 배분 완료';
+ }
+ allStamped = allDone;
+
sumKpis.innerHTML =
- kpi("총 박스", (totalProd + totalMix) + "박스", "제품별 " + totalProd + " + 혼합 " + totalMix) +
- kpi("센터 배분", assigned + "박스", "③ 에 담긴 수량") +
+ kpi("총 박스", totalBoxes + "박스", "제품별 " + totalProd + " + 혼합 " + totalMix) +
+ kpi("센터 배분", assigned + "박스", "③ 에 담긴 수량", allStamp) +
kpi("미배분 잔여", (remainProd + remainMix) + "박스", "자투리 " + leftoverUnits + "개 포함");
var ph = "";
diff --git a/app/modules/cupang/templates/cupang/box_rules.html b/app/modules/cupang/templates/cupang/box_rules.html
index 1444663..bdc8375 100644
--- a/app/modules/cupang/templates/cupang/box_rules.html
+++ b/app/modules/cupang/templates/cupang/box_rules.html
@@ -1,6 +1,6 @@
{% extends "erp_base.html" %}
-{% block head_extra %}{% endblock %}
+{% block head_extra %}{% endblock %}
{% block content %}
diff --git a/app/modules/cupang/templates/cupang/centers.html b/app/modules/cupang/templates/cupang/centers.html
index 94b9de5..fc1cf95 100644
--- a/app/modules/cupang/templates/cupang/centers.html
+++ b/app/modules/cupang/templates/cupang/centers.html
@@ -1,6 +1,6 @@
{% extends "erp_base.html" %}
-{% block head_extra %}{% endblock %}
+{% block head_extra %}{% endblock %}
{% block content %}
diff --git a/app/modules/cupang/templates/cupang/detail.html b/app/modules/cupang/templates/cupang/detail.html
index 985bfbb..4585196 100644
--- a/app/modules/cupang/templates/cupang/detail.html
+++ b/app/modules/cupang/templates/cupang/detail.html
@@ -1,6 +1,6 @@
{% extends "erp_base.html" %}
-{% block head_extra %}{% endblock %}
+{% block head_extra %}{% endblock %}
{% block content %}
diff --git a/app/modules/cupang/templates/cupang/form.html b/app/modules/cupang/templates/cupang/form.html
index 82b994e..1610fdf 100644
--- a/app/modules/cupang/templates/cupang/form.html
+++ b/app/modules/cupang/templates/cupang/form.html
@@ -1,6 +1,6 @@
{% extends "erp_base.html" %}
-{% block head_extra %}{% endblock %}
+{% block head_extra %}{% endblock %}
{% block content %}
diff --git a/app/modules/cupang/templates/cupang/index.html b/app/modules/cupang/templates/cupang/index.html
index b6b0e9e..a9980cb 100644
--- a/app/modules/cupang/templates/cupang/index.html
+++ b/app/modules/cupang/templates/cupang/index.html
@@ -1,6 +1,6 @@
{% extends "erp_base.html" %}
-{% block head_extra %}{% endblock %}
+{% block head_extra %}{% endblock %}
{% block content %}
diff --git a/app/modules/cupang/templates/cupang/products.html b/app/modules/cupang/templates/cupang/products.html
index 1d5db97..6265fbb 100644
--- a/app/modules/cupang/templates/cupang/products.html
+++ b/app/modules/cupang/templates/cupang/products.html
@@ -1,6 +1,6 @@
{% extends "erp_base.html" %}
-{% block head_extra %}{% endblock %}
+{% block head_extra %}{% endblock %}
{% block content %}
diff --git a/app/static/cupang.css b/app/static/cupang.css
index 08340c9..ecd62dd 100644
--- a/app/static/cupang.css
+++ b/app/static/cupang.css
@@ -768,3 +768,27 @@ body.cpg-dragging { cursor: grabbing; user-select: none; }
.cpg-box-card.is-done .cpg-box-bar { opacity: .4; }
/* 도장은 카드가 흐려져도 또렷하게 유지 */
.cpg-sum-prod.is-done .cpg-stamp, .cpg-box-card.is-done .cpg-stamp { opacity: 1; }
+
+/* 전체 배분 완료 도장 (센터 배분 KPI 칸) */
+.cpg-kpi { position: relative; overflow: hidden; }
+.cpg-stamp-all {
+ --stamp: var(--color-callout-red);
+ position: absolute;
+ top: 50%;
+ right: 10px;
+ margin-top: -14px;
+ padding: 4px 10px;
+ font-size: 13px;
+ letter-spacing: 2px;
+ border-width: 3px;
+ border-radius: 8px;
+ opacity: .9;
+ transform: rotate(-12deg);
+ box-shadow: inset 0 0 0 1px rgba(194, 43, 16, .25);
+}
+.cpg-stamp-all.is-new { animation: cpg-stamp-all-in .3s cubic-bezier(.2, 1.4, .4, 1); }
+@keyframes cpg-stamp-all-in {
+ 0% { opacity: 0; transform: rotate(-12deg) scale(2.4); }
+ 60% { opacity: .95; transform: rotate(-12deg) scale(.92); }
+ 100% { opacity: .9; transform: rotate(-12deg) scale(1); }
+}
diff --git a/tests/js/box_calc_ui.test.js b/tests/js/box_calc_ui.test.js
index 7ffcc9e..77190a3 100644
--- a/tests/js/box_calc_ui.test.js
+++ b/tests/js/box_calc_ui.test.js
@@ -217,6 +217,25 @@ function dragCardTo(card, target) {
$("#cpg-dlg-ok").click();
check("클릭으로 담긴다", $$(".cpg-dist-item").length === 1);
+ // ── 전체 배분 완료 도장 ───────────────────────────
+ check("잔여가 남아 있으면 전체 도장 없음", !$(".cpg-stamp-all"));
+ while ($(".cpg-sum-prod.is-draggable")) { // 제품 박스 전량 담기
+ $(".cpg-sum-prod.is-draggable").click();
+ $("#cpg-dlg-all").click();
+ }
+ while ($(".cpg-box-card.is-draggable")) { // 혼합 박스까지 담기
+ $(".cpg-box-card.is-draggable").click();
+ $("#cpg-dlg-all").click();
+ }
+ check("미배분 잔여 0", $$(".cpg-kpi")[2].querySelector(".cpg-kpi-value").textContent === "0박스",
+ $$(".cpg-kpi")[2].querySelector(".cpg-kpi-value").textContent);
+ check("전체 배분 완료 도장 표시", !!$(".cpg-stamp-all"));
+ check("전체 도장 위치 = 센터 배분 칸", !!$$(".cpg-kpi")[1].querySelector(".cpg-stamp-all"));
+ check("전체 도장 첫 등장은 애니메이션", $(".cpg-stamp-all").classList.contains("is-new"));
+
+ $(".cpg-dist-del").click(); // 하나 빼면
+ check("잔여가 생기면 전체 도장 제거", !$(".cpg-stamp-all"));
+
console.log("\n" + (fails.length ? "FAILED: " + fails.join(" | ") : "ALL PASS"));
process.exit(fails.length ? 1 : 0);
})();