5d84ae4874
③ 센터 분배 헤더에 [분배 확정] 을 두고, 조건이 갖춰질 때만 활성화한다. 조건은 두 가지다. 남은 박스가 0 이어야 하고, 담긴 센터마다 출고방식 (택배/파렛트)이 골라져 있어야 한다. 비활성일 때는 버튼 툴팁에 막힌 사유를 적는다(남은 박스 수, 출고방식 미선택 센터명). 확정을 누르면 달력이 바로 뜨는 팝업에서 출고일자를 고르고, 확인 시 센터마다 출고 묶음 1건(status=출고준비)을 만들어 쿠팡 달력의 그 날짜로 이동한다. 혼합 박스는 내용물 제품으로 풀어 담고 같은 제품끼리 합산한다. 박스 수는 화면 값을 믿지 않고 저장 시 서버가 수량·입수량으로 다시 계산한다. - router: POST /cupang/api/box-calc/confirm - box_calc.html: 센터 헤더 출고방식 select(미선택은 빨간 배경), 확정 팝업 달력 - 임시 저장 스냅샷에 출고방식 포함 - 센터입고일은 출고일과 같게 저장(상세에서 수정)
107 lines
4.3 KiB
HTML
107 lines
4.3 KiB
HTML
{% extends "erp_base.html" %}
|
|
|
|
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260831g" />{% endblock %}
|
|
|
|
{% block content %}
|
|
<section class="cpg">
|
|
|
|
<div class="erp-page-actions">
|
|
<a class="erp-btn erp-btn-primary" href="/cupang/">◀◀ 달력</a>
|
|
</div>
|
|
|
|
<div class="cpg-brule-layout">
|
|
|
|
<!-- 왼쪽: 추가/수정 (product_code UNIQUE → upsert) -->
|
|
<div class="erp-card cpg-form-card cpg-brule-add">
|
|
<div class="cpg-card-head">
|
|
<h2>박스 입수량 추가 / 수정</h2>
|
|
<span class="erp-muted">같은 제품코드는 덮어씁니다.</span>
|
|
</div>
|
|
<form method="post" action="/cupang/box-rules">
|
|
<input type="hidden" name="product_name_snapshot" id="brule-name-snap" />
|
|
<div class="cpg-brule-fields">
|
|
<div class="cpg-brule-row">
|
|
<label class="erp-field"><span>제품명 *</span>
|
|
<select class="erp-select cpg-brule-name" id="brule-name" required>
|
|
<option value="">— 제품명 선택 —</option>
|
|
{% for p in products %}
|
|
<option value="{{ p.product_code }}" data-name="{{ p.product_name }}">{{ p.product_name }}</option>
|
|
{% endfor %}
|
|
</select></label>
|
|
<label class="erp-field"><span>제품코드</span>
|
|
<input class="erp-input cpg-brule-code" type="text" name="product_code" id="brule-code" required placeholder="자동" /></label>
|
|
</div>
|
|
<div class="cpg-brule-row">
|
|
<label class="erp-field"><span>박스이름</span>
|
|
<input class="erp-input cpg-brule-box" type="text" name="box_name" value="쿠팡박스" /></label>
|
|
<label class="erp-field"><span>박스당 입수량 *</span>
|
|
<span class="cpg-upb-wrap">
|
|
<input class="erp-input cpg-brule-upb" type="number" name="units_per_box" min="1" required />
|
|
<span class="cpg-upb-unit">개</span>
|
|
</span></label>
|
|
</div>
|
|
<div class="cpg-brule-row">
|
|
<label class="erp-field cpg-brule-memo-field"><span>메모</span>
|
|
<input class="erp-input cpg-brule-memo" type="text" name="memo" /></label>
|
|
</div>
|
|
</div>
|
|
<div class="erp-page-actions" style="margin-top:12px;">
|
|
<button type="submit" class="erp-btn erp-btn-primary">저장</button>
|
|
</div>
|
|
</form>
|
|
{% if not products %}
|
|
<p class="erp-muted"><a href="/cupang/products">설정에서 제품명을 먼저 등록</a>하면 드롭다운에 표시됩니다.</p>
|
|
{% endif %}
|
|
|
|
<script>
|
|
(function () {
|
|
var sel = document.getElementById("brule-name");
|
|
var code = document.getElementById("brule-code");
|
|
var snap = document.getElementById("brule-name-snap");
|
|
if (!sel) return;
|
|
sel.addEventListener("change", function () {
|
|
var opt = sel.options[sel.selectedIndex];
|
|
code.value = sel.value;
|
|
snap.value = opt ? (opt.getAttribute("data-name") || "") : "";
|
|
});
|
|
})();
|
|
</script>
|
|
</div>
|
|
|
|
<!-- 오른쪽: 목록 -->
|
|
<div class="erp-card cpg-form-card cpg-brule-list">
|
|
<div class="cpg-card-head"><h2>입수량 규칙 ({{ box_rules|length }})</h2></div>
|
|
<div class="erp-table-wrap">
|
|
<table class="erp-table">
|
|
<thead>
|
|
<tr><th>제품명</th><th>제품코드</th><th>박스명</th><th>입수량</th><th>메모</th><th>동작</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for r in box_rules %}
|
|
<tr>
|
|
<td>{{ r.product_name_snapshot or '—' }}</td>
|
|
<td>{{ r.product_code }}</td>
|
|
<td>{{ r.box_name }}</td>
|
|
<td>{{ r.units_per_box }}개</td>
|
|
<td>{{ r.memo or '—' }}</td>
|
|
<td>
|
|
<form method="post" action="/cupang/box-rules/{{ r.id }}/delete" class="cpg-inline-form"
|
|
onsubmit="return confirm('이 규칙을 삭제합니다. 계속할까요?');">
|
|
<button type="submit" class="erp-btn erp-btn-danger">삭제</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
{% if not box_rules %}
|
|
<tr><td colspan="6" class="erp-muted">등록된 입수량 규칙이 없습니다.</td></tr>
|
|
{% endif %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
</div><!-- /cpg-brule-layout -->
|
|
|
|
</section>
|
|
{% endblock %}
|