diff --git a/app/modules/cupang/templates/cupang/box_calc.html b/app/modules/cupang/templates/cupang/box_calc.html index 133f701..00ae37b 100644 --- a/app/modules/cupang/templates/cupang/box_calc.html +++ b/app/modules/cupang/templates/cupang/box_calc.html @@ -1,6 +1,6 @@ {% extends "erp_base.html" %} -{% block head_extra %}{% endblock %} +{% block head_extra %}{% endblock %} {% block content %}
@@ -351,7 +351,6 @@ var had = Object.keys(alloc).some(function (k) { return alloc[k].length; }); alloc = {}; stamped = {}; - pool = {}; allStamped = false; // 계산이 바뀌면 이전 배분은 근거가 사라지므로 비운다. var skipped = restore ? applyRestore(restore) : 0; render(); @@ -433,7 +432,7 @@ units: units, labels: labels, contents: contents, openCenters: openCenters.slice(), alloc: alloc, methods: methods, stamped: stamped, allStamped: allStamped, - mixType: mixType, mixOwner: mixOwner, pool: pool + mixType: mixType, mixOwner: mixOwner }; } @@ -450,7 +449,6 @@ alloc = st.alloc; methods = st.methods; stamped = st.stamped; allStamped = st.allStamped; mixType = st.mixType || {}; mixOwner = st.mixOwner || {}; - pool = st.pool || {}; tbody.innerHTML = ""; (st.items || []).forEach(function (it) { addRow(it.product_code, it.quantity); }); @@ -482,7 +480,7 @@ units: {}, labels: {}, contents: {}, openCenters: [], alloc: {}, methods: {}, stamped: {}, allStamped: false, - mixType: {}, mixOwner: {}, pool: {} + mixType: {}, mixOwner: {} }; function put(cid, key, count) { @@ -691,8 +689,6 @@ // ── 혼합 상자 편집 ──────────────────────────────── // 상자 용량은 부피 합으로 본다: 제품 1개 = 1/입수량 상자. // 빼낸 수량은 센터별 "미배치 자투리" 풀에 남고, 거기서 다시 담는다. - var pool = {}; // centerId -> [{product_code, product_name, quantity}] - function upbOf(code) { var hit = calc.results.filter(function (r) { return r.product_code === code; })[0]; return hit ? (hit.units_per_box || 0) : 0; @@ -766,36 +762,6 @@ .map(function (a) { return a.key; }); } - function poolOf(cid) { - cid = String(cid); - if (!pool[cid]) pool[cid] = []; - return pool[cid]; - } - - function poolAdd(cid, code, name, qty) { - if (qty <= 0) return; - var list = poolOf(cid); - var hit = list.filter(function (it) { return it.product_code === code; })[0]; - if (hit) { hit.quantity += qty; return; } - list.push({ product_code: code, product_name: name, quantity: qty }); - } - - function poolTake(cid, code, qty) { - var list = poolOf(cid); - var hit = list.filter(function (it) { return it.product_code === code; })[0]; - if (!hit) return 0; - var take = Math.min(hit.quantity, qty); - hit.quantity -= take; - pool[String(cid)] = list.filter(function (it) { return it.quantity > 0; }); - return take; - } - - function poolTotal(cid) { - var n = 0; - poolOf(cid).forEach(function (it) { n += it.quantity; }); - return n; - } - function mixItem(key, code) { return (contents[key] || []).filter(function (it) { return it.product_code === code; })[0]; } @@ -812,19 +778,48 @@ return put; } - // 상자에서 빼기 — 뺀 수량은 그 센터의 미배치 풀로. - function mixTake(key, code, qty) { + // 상자에서 덜어내기(내부용) — 호출한 쪽이 곧바로 다른 상자에 담는다. + function mixPull(key, code, qty) { var hit = mixItem(key, code); if (!hit) return 0; var take = Math.min(hit.quantity, qty); if (take <= 0) return 0; - var cid = centerOfKey(key); hit.quantity -= take; syncMix(key); - if (cid) poolAdd(cid, code, hit.product_name, take); return take; } + // 자리가 있는 다른 상자 찾기 (없으면 "") + function boxWithRoom(cid, code, exceptKey) { + var found = ""; + mixKeysOf(cid).forEach(function (k) { + if (found || k === exceptKey) return; + if (mixRoomFor(k, code) > 0) found = k; + }); + return found; + } + + // 그 제품이 담겨 있는 다른 상자 찾기 (없으면 "") + function boxHaving(cid, code, exceptKey) { + var found = ""; + mixKeysOf(cid).forEach(function (k) { + if (found || k === exceptKey) return; + if (mixItem(k, code)) found = k; + }); + 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); + if (!pulled) return 0; + mixPut(toKey, code, name, pulled); + return pulled; + } + // 새 혼합 상자 (같은 센터, 비어 있는 상태로 추가) function newMixBox(cid, boxName) { var name = boxName || (calc.mixes[0] && calc.mixes[0].box_name) || MIX_TYPES[0]; @@ -983,7 +978,6 @@ esc(labels[k] || k) + (room ? " (여유 " + room + "개)" : " (가득)") + ""; }); opts += ''; - opts += ''; return opts; } @@ -1000,15 +994,16 @@ (entry.count > 1 ? '(' + it.quantity + "개 × " + entry.count + "상자)" : "") + ""; } - var canAdd = mixRoomFor(entry.key, it.product_code) > 0; + var canAdd = mixRoomFor(entry.key, it.product_code) > 0 && + !!boxHaving(cid, it.product_code, entry.key); return '
  • ' + esc(it.product_name) + "" + '' + '' + + '" data-code="' + esc(it.product_code) + '" title="다른 상자로 1개 옮기기">−' + '' + qty + "개" + '' + + ' title="다른 상자에서 1개 가져오기">+' + '' + opts + "" + - "
  • "; - }).join(""); - return '
    ' + - '
    미배치 자투리 ' + poolTotal(cid) + "개" + - '' + - "
    " + - '" + - "
    "; - } - // ── ③ 센터 분배 렌더 ────────────────────────────── function renderDist() { if (!distList) return; @@ -1090,7 +1057,6 @@ (rows.length ? '" : '

    여기로 상자를 끌어다 놓기

    ') + - poolHtml(cid) + (rows.length ? '
    ' + '