feat(dispatch): 말레이시아 재고 차감 버튼(날짜 1회성)
- 달력 다운로드 아래 '말레이시아 재고 차감' 버튼. 선택 날짜 출고를 말레이시아 재고관리에 OUT 으로 반영(movement_date=해당 날짜) · 낱개(MT/MX/MZ)=낱개 OUT, 콤보(MY-)=세트 OUT(재고관리가 BOM 분해) · _N 배수 반영, MD-(뚜껑) 제외 - 날짜당 1회만: dispatch_stock_deductions 마커로 재차감 차단(이중 출고 방지) · 마커 선점 후 반영, 콤보 BOM 누락은 사전검증으로 차단 - export.split_singles_combos, db 차감 가드 메서드, 라우터 POST /dispatch/stock-deduct - 스키마: dispatch_stock_deductions (init + 마이그레이션 dispatch_add_deductions.sql) - 이미 차감된 날짜는 버튼 비활성 + 안내 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -109,6 +109,10 @@
|
||||
<a id="dsp-cal-dl" class="erp-btn erp-btn-primary" href="#"
|
||||
data-ko="📥 사방넷 출고 엑셀 다운로드" data-en="📥 Download Sabangnet Outbound Excel"
|
||||
style="pointer-events:none;opacity:.5;">📥 사방넷 출고 엑셀 다운로드</a>
|
||||
<button id="dsp-cal-deduct" type="button" class="erp-btn erp-btn-outline" onclick="dspDeduct()"
|
||||
data-ko="📦 말레이시아 재고 차감" data-en="📦 Deduct Malaysia Stock"
|
||||
style="pointer-events:none;opacity:.5;">📦 말레이시아 재고 차감</button>
|
||||
<div id="dsp-cal-deduct-note" class="erp-muted" style="font-size:12px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -120,6 +124,8 @@
|
||||
(function () {
|
||||
// 배치가 있는 날짜(YYYY-MM-DD)
|
||||
var BATCH_DATES = {{ batch_dates|tojson }};
|
||||
var DEDUCTED = {};
|
||||
({{ deducted_dates|tojson }}).forEach(function (d) { DEDUCTED[d] = true; });
|
||||
var dateSet = {};
|
||||
BATCH_DATES.forEach(function (d) { dateSet[d] = true; });
|
||||
|
||||
@@ -127,6 +133,8 @@
|
||||
var title = document.getElementById('dsp-cal-title');
|
||||
var selLabel = document.getElementById('dsp-cal-sel');
|
||||
var dlBtn = document.getElementById('dsp-cal-dl');
|
||||
var dedBtn = document.getElementById('dsp-cal-deduct');
|
||||
var dedNote = document.getElementById('dsp-cal-deduct-note');
|
||||
var selected = null;
|
||||
|
||||
// 초기 표시 월: 가장 최근 배치 날짜 기준(없으면 오늘)
|
||||
@@ -169,16 +177,62 @@
|
||||
dlBtn.href = '/dispatch/stock-export?date=' + encodeURIComponent(iso);
|
||||
dlBtn.style.pointerEvents = '';
|
||||
dlBtn.style.opacity = '';
|
||||
updateDeductBtn();
|
||||
render();
|
||||
}
|
||||
|
||||
function updateDeductBtn() {
|
||||
var en = (window.dspLang && window.dspLang() === 'en');
|
||||
if (!selected) {
|
||||
dedBtn.style.pointerEvents = 'none'; dedBtn.style.opacity = '.5';
|
||||
dedNote.textContent = '';
|
||||
return;
|
||||
}
|
||||
if (DEDUCTED[selected]) {
|
||||
dedBtn.style.pointerEvents = 'none'; dedBtn.style.opacity = '.5';
|
||||
dedNote.textContent = en ? 'Already deducted (cannot run again).' : '이미 차감됨 (재실행 불가).';
|
||||
} else {
|
||||
dedBtn.style.pointerEvents = ''; dedBtn.style.opacity = '';
|
||||
dedNote.textContent = '';
|
||||
}
|
||||
}
|
||||
|
||||
window.dspDeduct = function () {
|
||||
if (!selected || DEDUCTED[selected]) return;
|
||||
var en = (window.dspLang && window.dspLang() === 'en');
|
||||
var msg = en
|
||||
? ('Deduct Malaysia stock for ' + selected + '? This runs ONCE only and cannot be undone.')
|
||||
: (selected + ' 출고를 말레이시아 재고에서 차감할까요?\n한 번만 실행되며 되돌릴 수 없습니다.');
|
||||
if (!confirm(msg)) return;
|
||||
dedBtn.style.pointerEvents = 'none'; dedBtn.style.opacity = '.5';
|
||||
dedNote.textContent = en ? 'Processing…' : '처리 중…';
|
||||
var body = new URLSearchParams(); body.set('date', selected);
|
||||
fetch('/dispatch/stock-deduct', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
body: body.toString(),
|
||||
})
|
||||
.then(function (r) { return r.json().then(function (j) { return { ok: r.ok, j: j }; }); })
|
||||
.then(function (res) {
|
||||
if (!res.ok) throw new Error((res.j && res.j.detail) || '실패');
|
||||
DEDUCTED[selected] = true;
|
||||
updateDeductBtn();
|
||||
alert((en ? 'Done. singles ' : '완료. 낱개 ') + res.j.singles + (en ? ', combos ' : '종, 콤보 ') + res.j.combos + (en ? '' : '종 반영'));
|
||||
})
|
||||
.catch(function (e) {
|
||||
dedNote.textContent = (e && e.message) || '실패';
|
||||
updateDeductBtn();
|
||||
alert((en ? 'Failed: ' : '실패: ') + ((e && e.message) || ''));
|
||||
});
|
||||
};
|
||||
|
||||
document.getElementById('dsp-cal-prev').onclick = function () {
|
||||
viewM--; if (viewM < 0) { viewM = 11; viewY--; } render();
|
||||
};
|
||||
document.getElementById('dsp-cal-next').onclick = function () {
|
||||
viewM++; if (viewM > 11) { viewM = 0; viewY++; } render();
|
||||
};
|
||||
document.addEventListener('dsp:lang', render);
|
||||
document.addEventListener('dsp:lang', function () { render(); updateDeductBtn(); });
|
||||
render();
|
||||
})();
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user