@@ -53,22 +53,17 @@
@@ -83,7 +78,10 @@
var resetBtn = document.getElementById("cpg-calc-reset");
var msg = document.getElementById("cpg-calc-msg");
var sumCard = document.getElementById("cpg-calc-sum-card");
- var sumRows = document.getElementById("cpg-calc-sum-rows");
+ var sumKpis = document.getElementById("cpg-sum-kpis");
+ var sumProds = document.getElementById("cpg-sum-prods");
+ var sumBoxes = document.getElementById("cpg-sum-boxes");
+ var sumMixNote = document.getElementById("cpg-sum-mix-note");
var rules = [];
try { rules = JSON.parse(document.getElementById("cpg-calc-rules").textContent || "[]"); } catch (e) {}
@@ -124,7 +122,10 @@
tr.classList.remove("cpg-calc-warn");
});
sumCard.hidden = true;
- sumRows.innerHTML = "";
+ sumKpis.innerHTML = "";
+ sumProds.innerHTML = "";
+ sumBoxes.innerHTML = "";
+ sumMixNote.textContent = "";
}
function collect() {
@@ -167,26 +168,95 @@
tr.classList.add("cpg-calc-warn");
}
});
- var totals = (data && data.totals) || [];
- if (totals.length) {
- var html = "";
- totals.forEach(function (t) {
- html += "| " + esc(t.box_name || "—") + " | " +
- '' + t.full_boxes + "박스 | " +
- '' + t.remainder_units + "개 | " +
- '' + t.required_boxes + "박스 |
";
- });
- sumRows.innerHTML = html;
- sumCard.hidden = false;
- } else {
- sumCard.hidden = true;
- }
+ renderSummary(results, (data && data.mixes) || [], (data && data.grand_total_boxes) || 0);
msg.textContent = "계산 완료 (" + results.length + "건)";
})
.catch(function () { msg.textContent = "계산 실패 — 새로고침 후 다시 시도하세요."; })
.then(function () { runBtn.disabled = false; });
}
+ // ── 요약 렌더 ─────────────────────────────────────────
+ // 상자 그림: fill(0~100) 만큼 안쪽이 차오르고, 뚜껑이 살짝 열린 채 표시.
+ function boxSvg(fill) {
+ var f = Math.max(0, Math.min(100, fill || 0));
+ var h = 40 * f / 100;
+ return '' +
+ '';
+ }
+
+ function renderSummary(results, mixes, grandTotal) {
+ var ok = results.filter(function (r) { return r.configured; });
+ if (!ok.length) { sumCard.hidden = true; return; }
+
+ var fullSum = 0, mixSum = 0, leftoverSum = 0;
+ ok.forEach(function (r) { fullSum += r.full_boxes; leftoverSum += r.remainder_units; });
+ mixes.forEach(function (m) { mixSum += m.box_count; });
+
+ sumKpis.innerHTML =
+ kpi("총 박스", (grandTotal || (fullSum + mixSum)) + "박스", "제품별 박스 + 혼합 박스") +
+ kpi("제품별 박스", fullSum + "박스", "한 제품만 가득 채운 박스") +
+ kpi("혼합 박스", mixSum + "박스", "자투리 " + leftoverSum + "개를 모아 담음");
+
+ // 제품별
+ var ph = "";
+ ok.forEach(function (r) {
+ ph += '' +
+ '
' +
+ '' + esc(r.product_name) + "" +
+ '' + esc(r.box_name) + "" +
+ "
" +
+ '
' +
+ '' + r.full_boxes + "박스" +
+ '' + r.quantity + "개 ÷ " + r.units_per_box + "개" +
+ (r.remainder_units
+ ? '자투리 ' + r.remainder_units + "개"
+ : '딱 맞음') +
+ "
" +
+ "
";
+ });
+ sumProds.innerHTML = ph;
+
+ // 자투리 혼합 박스
+ if (!mixes.length) {
+ sumMixNote.textContent = "— 자투리 없음";
+ sumBoxes.innerHTML = '남는 낱개가 없습니다. 모든 박스가 딱 맞습니다.
';
+ } else {
+ sumMixNote.textContent = "— 같은 박스명끼리만 섞습니다";
+ var bh = "", n = 0;
+ mixes.forEach(function (m) {
+ m.boxes.forEach(function (b, i) {
+ var items = b.items.map(function (it) {
+ return '' + esc(it.product_name) + "" + it.quantity + "개";
+ }).join("");
+ bh += '' +
+ '
' + boxSvg(b.fill_percent) + "
" +
+ '
' +
+ '
' + esc(m.box_name) + " 혼합 #" + (i + 1) + "
" +
+ '
" +
+ '
' +
+ '
' + b.fill_percent + "% 채움
" +
+ "
" +
+ "
";
+ n += 1;
+ });
+ });
+ sumBoxes.innerHTML = bh;
+ }
+ sumCard.hidden = false;
+ }
+
+ function kpi(label, value, hint) {
+ return '' + esc(label) + "" +
+ '' + esc(value) + "" +
+ '' + esc(hint) + "
";
+ }
+
tbody.addEventListener("click", function (e) {
var del = e.target.closest(".cpg-calc-del");
if (!del) return;
diff --git a/app/modules/cupang/templates/cupang/box_rules.html b/app/modules/cupang/templates/cupang/box_rules.html
index 44b7752..b6769db 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 711a3a2..3e9cca3 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 8c7e6c6..3aead7a 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 69799e1..e258325 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 a835994..1ef8ad3 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 b41afad..f36f2a2 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 c52413e..f64eb3a 100644
--- a/app/static/cupang.css
+++ b/app/static/cupang.css
@@ -335,3 +335,157 @@
.cpg-calc-row.cpg-calc-warn { background: color-mix(in srgb, var(--color-callout-red) 8%, transparent); }
.cpg-calc-actions { margin-top: 12px; gap: 8px; align-items: center; }
.cpg-calc-sum { margin-top: 16px; }
+
+/* ── 박스 계산 요약 ─────────────────────────────── */
+.cpg-sum-h3 {
+ margin: 20px 0 10px;
+ font-size: 15px;
+ font-weight: 700;
+}
+.cpg-sum-h3 .erp-muted { font-weight: 400; font-size: 13px; }
+
+.cpg-sum-kpis {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
+ gap: 10px;
+}
+.cpg-kpi {
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
+ padding: 12px 14px;
+ border: 1px solid var(--color-subtle-ash);
+ border-radius: 10px;
+ background: var(--color-ghost-gray);
+}
+.cpg-kpi-label { font-size: 12px; color: var(--color-midtone-gray); }
+.cpg-kpi-value { font-size: 24px; line-height: 1.2; }
+.cpg-kpi-hint { font-size: 12px; color: var(--color-midtone-gray); }
+
+.cpg-sum-prods {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
+ gap: 8px;
+}
+.cpg-sum-prod {
+ padding: 10px 12px;
+ border: 1px solid var(--color-subtle-ash);
+ border-radius: 10px;
+}
+.cpg-sum-prod-head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 8px;
+ margin-bottom: 6px;
+}
+.cpg-sum-prod-name { font-weight: 600; }
+.cpg-sum-prod-nums {
+ display: flex;
+ align-items: baseline;
+ gap: 8px;
+ flex-wrap: wrap;
+ font-size: 13px;
+}
+.cpg-sum-prod-nums strong { font-size: 17px; }
+.cpg-sum-left { color: var(--color-callout-red); font-weight: 600; }
+.cpg-sum-exact { color: var(--color-success-green); font-weight: 600; }
+
+/* 혼합 박스 카드 */
+.cpg-sum-boxes {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
+ gap: 12px;
+}
+.cpg-box-card {
+ display: flex;
+ gap: 12px;
+ padding: 12px;
+ border: 1px solid var(--color-subtle-ash);
+ border-radius: 12px;
+ background: var(--color-canvas-white);
+ opacity: 0;
+ animation: cpg-box-in .38s ease-out forwards;
+}
+@keyframes cpg-box-in {
+ from { opacity: 0; transform: translateY(10px) scale(.96); }
+ to { opacity: 1; transform: none; }
+}
+.cpg-box-art { flex: 0 0 auto; }
+.cpg-box-svg { width: 72px; height: 64px; }
+.cpg-box-body {
+ fill: #f6e2c3;
+ stroke: #b98a4a;
+ stroke-width: 2;
+}
+.cpg-box-flapL, .cpg-box-flapR {
+ fill: #e8cfa6;
+ stroke: #b98a4a;
+ stroke-width: 2;
+ transform-origin: 36px 20px;
+ animation: cpg-flap .5s ease-out both;
+}
+.cpg-box-flapL { animation-delay: .12s; }
+.cpg-box-flapR { animation-delay: .2s; }
+@keyframes cpg-flap {
+ from { transform: rotate(0deg) translateY(6px); opacity: .3; }
+ to { transform: none; opacity: 1; }
+}
+.cpg-box-fill {
+ fill: var(--color-rich-black);
+ opacity: .16;
+ animation: cpg-fill-up .55s ease-out both;
+ transform-origin: 36px 54px;
+}
+@keyframes cpg-fill-up {
+ from { transform: scaleY(0); }
+ to { transform: scaleY(1); }
+}
+.cpg-box-seam { stroke: #b98a4a; stroke-width: 1.5; opacity: .5; }
+
+.cpg-box-info { min-width: 0; flex: 1 1 auto; }
+.cpg-box-title { font-weight: 700; margin-bottom: 6px; }
+.cpg-box-items {
+ list-style: none;
+ margin: 0 0 8px;
+ padding: 0;
+ font-size: 13px;
+}
+.cpg-box-items li {
+ display: flex;
+ justify-content: space-between;
+ gap: 8px;
+ padding: 2px 0;
+ border-bottom: 1px dashed var(--color-subtle-ash);
+}
+.cpg-box-items li:last-child { border-bottom: 0; }
+.cpg-box-bar {
+ height: 6px;
+ border-radius: 3px;
+ background: var(--color-ghost-gray);
+ overflow: hidden;
+}
+.cpg-box-bar span {
+ display: block;
+ height: 100%;
+ background: var(--color-rich-black);
+ animation: cpg-bar-grow .6s ease-out both;
+ transform-origin: left center;
+}
+@keyframes cpg-bar-grow {
+ from { transform: scaleX(0); }
+ to { transform: scaleX(1); }
+}
+.cpg-box-fillnum {
+ margin-top: 4px;
+ font-size: 12px;
+ color: var(--color-midtone-gray);
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .cpg-box-card, .cpg-box-fill, .cpg-box-flapL, .cpg-box-flapR, .cpg-box-bar span {
+ animation: none;
+ opacity: 1;
+ }
+ .cpg-box-fill { opacity: .16; }
+}