fix(cupang): 혼합 상자 이동은 용량 제한 없이, ③ 목록 max-height 로 스크롤 보장
- mixPut/moveUnits 에서 용량 제한 제거. 이동 목록도 "가득"이어도 선택 가능 (채움률이 100% 를 넘으면 빨간색으로 표시만) - 부모 flex 높이 계산에 기대던 스크롤을 max-height 로 직접 지정 (③ 72vh, ① 표 64vh, ② 목록 64vh) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{% extends "erp_base.html" %}
|
||||
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260901q" />{% endblock %}
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260901r" />{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="cpg">
|
||||
@@ -766,10 +766,9 @@
|
||||
return (contents[key] || []).filter(function (it) { return it.product_code === code; })[0];
|
||||
}
|
||||
|
||||
// 상자에 담기 — 용량만큼만 들어간다. 담은 수량을 돌려준다.
|
||||
// 상자에 담기 — 용량은 표시용일 뿐, 이동은 막지 않는다(넘치면 100% 초과 표시).
|
||||
function mixPut(key, code, name, qty) {
|
||||
var room = mixRoomFor(key, code);
|
||||
var put = Math.min(room, qty);
|
||||
var put = qty;
|
||||
if (put <= 0) return 0;
|
||||
var hit = mixItem(key, code);
|
||||
if (hit) { hit.quantity += put; }
|
||||
@@ -809,12 +808,9 @@
|
||||
return found;
|
||||
}
|
||||
|
||||
// 상자 → 상자 이동. 실제로 옮긴 수량을 돌려준다(자리만큼만).
|
||||
// 상자 → 상자 이동. 용량과 무관하게 요청한 수량을 옮긴다.
|
||||
function moveUnits(fromKey, toKey, code, name, qty) {
|
||||
var room = mixRoomFor(toKey, code);
|
||||
var move = Math.min(qty, room);
|
||||
if (move <= 0) return 0;
|
||||
var pulled = mixPull(fromKey, code, move);
|
||||
var pulled = mixPull(fromKey, code, qty);
|
||||
if (!pulled) return 0;
|
||||
mixPut(toKey, code, name, pulled);
|
||||
return pulled;
|
||||
@@ -974,7 +970,7 @@
|
||||
mixKeysOf(cid).forEach(function (k) {
|
||||
if (k === fromKey) return;
|
||||
var room = mixRoomFor(k, code);
|
||||
opts += '<option value="' + esc(k) + '"' + (room ? "" : " disabled") + ">" +
|
||||
opts += '<option value="' + esc(k) + '">' +
|
||||
esc(labels[k] || k) + (room ? " (여유 " + room + "개)" : " (가득)") + "</option>";
|
||||
});
|
||||
opts += '<option value="__new__">+ 새 상자로</option>';
|
||||
@@ -994,8 +990,7 @@
|
||||
(entry.count > 1 ? '<span class="cpg-tree-per">(' + it.quantity + "개 × " + entry.count + "상자)</span>" : "") +
|
||||
"</li>";
|
||||
}
|
||||
var canAdd = mixRoomFor(entry.key, it.product_code) > 0 &&
|
||||
!!boxHaving(cid, it.product_code, entry.key);
|
||||
var canAdd = !!boxHaving(cid, it.product_code, entry.key);
|
||||
return '<li><span class="cpg-tree-name">' + esc(it.product_name) + "</span>" +
|
||||
'<span class="cpg-mix-ctl">' +
|
||||
'<button type="button" class="cpg-mix-step" data-mix-dec data-key="' + esc(entry.key) +
|
||||
@@ -1026,11 +1021,13 @@
|
||||
boxes += a.count;
|
||||
pieces += a.count * per;
|
||||
var isMix = a.key.indexOf("m:") === 0;
|
||||
var fillTxt = isMix ? Math.round(mixFill(a.key) * 100) + "% 채움" : "";
|
||||
var fillPct = isMix ? Math.round(mixFill(a.key) * 100) : 0;
|
||||
var fillTxt = isMix ? fillPct + "% 채움" : "";
|
||||
var fillCls = fillPct > 100 ? " is-over" : "";
|
||||
items += '<li class="cpg-dist-item' + (isMix ? " is-mix" : "") + '" data-entry="' + a.id + '">' +
|
||||
'<div class="cpg-dist-line">' +
|
||||
'<span class="cpg-dist-name">' + esc(labels[a.key] || a.key) +
|
||||
(fillTxt ? ' <em class="cpg-mix-fill">' + fillTxt + "</em>" : "") + "</span>" +
|
||||
(fillTxt ? ' <em class="cpg-mix-fill' + fillCls + '">' + fillTxt + "</em>" : "") + "</span>" +
|
||||
'<input class="erp-input cpg-dist-qty" type="number" min="1" max="999" step="1" inputmode="numeric" value="' + a.count + '" />' +
|
||||
'<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>' +
|
||||
@@ -1273,13 +1270,9 @@
|
||||
if (entry && entry.key.indexOf("m:") === 0) {
|
||||
e.stopImmediatePropagation(); // 뒤 핸들러가 또 지우지 않게
|
||||
(contents[entry.key] || []).slice().forEach(function (it) {
|
||||
var left = it.quantity;
|
||||
while (left > 0) {
|
||||
var dest = boxWithRoom(dcid, it.product_code, entry.key) || newMixBox(dcid);
|
||||
var moved = moveUnits(entry.key, dest, it.product_code, it.product_name, left);
|
||||
if (!moved) break;
|
||||
left -= moved;
|
||||
}
|
||||
var rest = mixKeysOf(dcid).filter(function (k) { return k !== entry.key; });
|
||||
var dest = boxWithRoom(dcid, it.product_code, entry.key) || rest[0] || newMixBox(dcid);
|
||||
moveUnits(entry.key, dest, it.product_code, it.product_name, it.quantity);
|
||||
});
|
||||
syncMix(entry.key);
|
||||
render();
|
||||
@@ -1295,7 +1288,8 @@
|
||||
var cid = centerOfKey(key);
|
||||
var item = mixItem(key, code);
|
||||
if (!item) return;
|
||||
var to = boxWithRoom(cid, code, key) || newMixBox(cid);
|
||||
var others = mixKeysOf(cid).filter(function (k) { return k !== key; });
|
||||
var to = boxWithRoom(cid, code, key) || others[0] || newMixBox(cid);
|
||||
var n = moveUnits(key, to, code, item.product_name, 1);
|
||||
if (!n) { msg.textContent = "옮길 자리가 없습니다."; return; }
|
||||
render();
|
||||
@@ -1308,9 +1302,6 @@
|
||||
var ikey = inc.getAttribute("data-key");
|
||||
var icode = inc.getAttribute("data-code");
|
||||
var icid = centerOfKey(ikey);
|
||||
if (mixRoomFor(ikey, icode) <= 0) {
|
||||
msg.textContent = "이 상자에 더 들어갈 자리가 없습니다."; return;
|
||||
}
|
||||
var from = boxHaving(icid, icode, ikey);
|
||||
if (!from) { msg.textContent = "다른 상자에 이 제품이 없습니다."; return; }
|
||||
var src = mixItem(from, icode);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "erp_base.html" %}
|
||||
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260901q" />{% endblock %}
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260901r" />{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="cpg">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "erp_base.html" %}
|
||||
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260901q" />{% endblock %}
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260901r" />{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="cpg">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "erp_base.html" %}
|
||||
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260901q" />{% endblock %}
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260901r" />{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="cpg">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "erp_base.html" %}
|
||||
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260901q" />{% endblock %}
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260901r" />{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="cpg">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "erp_base.html" %}
|
||||
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260901q" />{% endblock %}
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260901r" />{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{# 출고 묶음 보기 — 상자 계산 화면과 같은 3열 구성. 읽기 전용(수정 없음). #}
|
||||
|
||||
@@ -1453,3 +1453,15 @@ body.cpg-dragging { cursor: grabbing; user-select: none; }
|
||||
flex: 1 1 auto; min-height: 0;
|
||||
overflow-y: auto; overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* ③ 목록 스크롤 — 부모 높이 계산에 기대지 않도록 최대 높이를 직접 준다 */
|
||||
.cpg-dist-card .cpg-dist-list {
|
||||
max-height: min(72vh, 820px);
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
/* ①② 도 같은 방식으로 안전장치 */
|
||||
.cpg-calc-card .erp-table-wrap { max-height: min(64vh, 720px); }
|
||||
.cpg-calc-sum .cpg-sum-scroll { max-height: min(64vh, 720px); }
|
||||
/* 용량 초과 표시 */
|
||||
.cpg-mix-fill.is-over { color: var(--color-callout-red); font-weight: 600; }
|
||||
|
||||
Reference in New Issue
Block a user