feat(cupang): 등록된 제품 수정 팝업
- 동작 열에 [수정] 버튼 → 제품명/제품코드/쿠팡상품코드 수정 팝업
- POST /cupang/api/products/{id}/edit (JSON), 제품코드 중복은 400
- 제품코드 변경 시 cupang_box_rules 의 product_code/스냅샷도 함께 이동
(같은 코드 규칙이 이미 있으면 이동하지 않음). 출고 라인은 과거 기록이라 유지
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -81,6 +81,8 @@
|
||||
</td>
|
||||
<td>
|
||||
<div class="cpg-row-actions">
|
||||
<button type="button" class="erp-btn erp-btn-outline cpg-prod-edit"
|
||||
data-edit-id="{{ p.id }}">수정</button>
|
||||
<form method="post" action="/cupang/products/{{ p.id }}/delete" class="cpg-inline-form"
|
||||
onsubmit="return confirm('완전 삭제합니다. 계속할까요?');">
|
||||
<button type="submit" class="erp-btn erp-btn-danger">삭제</button>
|
||||
@@ -137,6 +139,90 @@
|
||||
})();
|
||||
</script>
|
||||
|
||||
<!-- 등록된 제품 수정 팝업 -->
|
||||
<div class="cpg-modal" id="cpg-edit-dlg" hidden>
|
||||
<div class="cpg-modal-back" data-edit-close></div>
|
||||
<div class="cpg-modal-box" role="dialog" aria-modal="true" aria-labelledby="cpg-edit-title">
|
||||
<h3 id="cpg-edit-title">제품 수정</h3>
|
||||
<label class="erp-field"><span>제품명 *</span>
|
||||
<input class="erp-input" type="text" id="cpg-edit-name" /></label>
|
||||
<label class="erp-field"><span>제품코드 *</span>
|
||||
<input class="erp-input" type="text" id="cpg-edit-code" /></label>
|
||||
<label class="erp-field"><span>쿠팡상품코드</span>
|
||||
<input class="erp-input" type="text" id="cpg-edit-cpcode" placeholder="비우면 지워집니다" /></label>
|
||||
<p class="erp-muted" id="cpg-edit-msg" style="margin:0;font-size:12px;"></p>
|
||||
<div class="cpg-dlg-actions erp-page-actions">
|
||||
<button type="button" class="erp-btn erp-btn-outline" data-edit-close>취소</button>
|
||||
<button type="button" class="erp-btn erp-btn-primary" id="cpg-edit-save">저장</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 등록된 제품 수정 — [수정] 클릭 → 팝업에서 제품명/제품코드/쿠팡상품코드 변경.
|
||||
(function () {
|
||||
var tbody = document.getElementById("cpg-prod-tbody");
|
||||
var dlg = document.getElementById("cpg-edit-dlg");
|
||||
if (!tbody || !dlg) return;
|
||||
var elName = document.getElementById("cpg-edit-name");
|
||||
var elCode = document.getElementById("cpg-edit-code");
|
||||
var elCp = document.getElementById("cpg-edit-cpcode");
|
||||
var elMsg = document.getElementById("cpg-edit-msg");
|
||||
var saveBtn = document.getElementById("cpg-edit-save");
|
||||
var editingId = null;
|
||||
|
||||
function close() { dlg.hidden = true; editingId = null; saveBtn.disabled = false; }
|
||||
|
||||
tbody.addEventListener("click", function (e) {
|
||||
var btn = e.target.closest(".cpg-prod-edit");
|
||||
if (!btn) return;
|
||||
var row = btn.closest("tr");
|
||||
editingId = btn.getAttribute("data-edit-id");
|
||||
elName.value = row.getAttribute("data-name") || "";
|
||||
elCode.value = row.getAttribute("data-code") || "";
|
||||
elCp.value = row.getAttribute("data-cpcode") || "";
|
||||
elMsg.textContent = "";
|
||||
dlg.hidden = false;
|
||||
elName.focus();
|
||||
});
|
||||
|
||||
Array.prototype.forEach.call(dlg.querySelectorAll("[data-edit-close]"), function (el) {
|
||||
el.addEventListener("click", close);
|
||||
});
|
||||
document.addEventListener("keydown", function (e) {
|
||||
if (e.key === "Escape" && !dlg.hidden) close();
|
||||
});
|
||||
|
||||
saveBtn.addEventListener("click", function () {
|
||||
if (!editingId) return;
|
||||
var body = {
|
||||
product_name: (elName.value || "").trim(),
|
||||
product_code: (elCode.value || "").trim(),
|
||||
coupang_item_code: (elCp.value || "").trim()
|
||||
};
|
||||
if (!body.product_name || !body.product_code) {
|
||||
elMsg.textContent = "제품명과 제품코드는 필수입니다."; return;
|
||||
}
|
||||
saveBtn.disabled = true;
|
||||
elMsg.textContent = "저장 중…";
|
||||
fetch("/cupang/api/products/" + editingId + "/edit", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(body)
|
||||
}).then(function (r) {
|
||||
return r.json().then(function (d) {
|
||||
if (!r.ok) throw new Error((d && d.detail) || "저장 실패");
|
||||
return d;
|
||||
});
|
||||
}).then(function () { location.reload(); })
|
||||
.catch(function (err) {
|
||||
saveBtn.disabled = false;
|
||||
elMsg.textContent = err.message || "저장 실패";
|
||||
});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// 상태 배지 클릭 → 활성/비활성 토글 (페이지 새로고침 없음).
|
||||
(function () {
|
||||
|
||||
Reference in New Issue
Block a user