feat(cupang): 출고 박스 구성(box_plan) 저장 + 달력 상세를 센터 분배 형식으로
- 마이그레이션 005: cupang_shipments.box_plan JSONB (확정 당시 박스 구성) 확정 payload 에서 제품별/혼합 상자와 내용물·상자 종류를 받아 저장 - 달력 오른쪽 목록을 ③ 센터 분배 카드 형식으로 변경 — 혼합 상자는 내용물 트리까지 표시. box_plan 이 없는 예전 출고는 기존 합계 표시로 폴백 - 출고 보기(view.html) ③ 목록도 동일하게 box_plan 기준 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=20260901m" />{% endblock %}
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260901n" />{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="cpg">
|
||||
@@ -1254,11 +1254,39 @@
|
||||
return t + ", " + byType[t] + "개";
|
||||
}).join(" / ");
|
||||
|
||||
// 확정 후 상세 화면에서 "어느 상자에 무엇이" 를 보여주기 위한 스냅샷
|
||||
var boxPlan = rows.map(function (a) {
|
||||
if (a.key.indexOf("m:") === 0) {
|
||||
return {
|
||||
kind: "mix",
|
||||
name: labels[a.key] || a.key,
|
||||
box_type: mixTypeOf(a.key),
|
||||
count: a.count,
|
||||
units: units[a.key] || 0,
|
||||
items: (contents[a.key] || []).map(function (it) {
|
||||
return {
|
||||
product_code: it.product_code,
|
||||
product_name: it.product_name,
|
||||
quantity: it.quantity * a.count
|
||||
};
|
||||
})
|
||||
};
|
||||
}
|
||||
return {
|
||||
kind: "product",
|
||||
name: labels[a.key] || a.key,
|
||||
product_code: a.key.slice(2),
|
||||
count: a.count,
|
||||
units: units[a.key] || 0
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
center_id: cid,
|
||||
ship_method: methods[String(cid)] || "",
|
||||
boxes: boxes,
|
||||
box_summary: boxSummary,
|
||||
box_plan: boxPlan,
|
||||
items: items
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "erp_base.html" %}
|
||||
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260901m" />{% endblock %}
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260901n" />{% 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=20260901m" />{% endblock %}
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260901n" />{% 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=20260901m" />{% endblock %}
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260901n" />{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="cpg">
|
||||
@@ -91,27 +91,51 @@
|
||||
{% if sel_shipments %}
|
||||
<ul class="cpg-list">
|
||||
{% for s in sel_shipments %}
|
||||
<li class="cpg-list-item">
|
||||
<div class="cpg-ship-card">
|
||||
<div class="cpg-ship-head">
|
||||
<a class="cpg-ship-name" href="/cupang/{{ s.id }}">{{ s.center_name_snapshot or '센터 미지정' }}</a>
|
||||
<span class="erp-badge erp-badge-neutral cpg-mini">{{ s.ship_method }}</span>
|
||||
{# ③ 센터 분배 카드와 같은 형식 — 혼합 상자는 내용물까지 펼쳐 보여준다 #}
|
||||
<li class="cpg-list-item cpg-dist-center has-items">
|
||||
<div class="cpg-dist-head">
|
||||
<a class="cpg-ship-name" href="/cupang/{{ s.id }}">{{ s.center_name_snapshot or '센터 미지정' }}</a>
|
||||
<span class="erp-badge erp-badge-neutral">{{ s.ship_method }}</span>
|
||||
<span class="cpg-dist-sum">
|
||||
<span class="erp-badge erp-badge-neutral">{{ s.total_boxes }}박스</span>
|
||||
<span class="erp-badge erp-badge-neutral">{{ s.total_qty }}개</span>
|
||||
<button type="button" class="cpg-icon-btn is-danger" title="이 출고 삭제"
|
||||
data-del="{{ s.id }}" data-name="{{ s.center_name_snapshot }}">삭제</button>
|
||||
</div>
|
||||
<div class="cpg-ship-meta erp-muted">
|
||||
출고 {{ s.ship_date }} · {{ s.total_boxes }}박스 · {{ s.total_qty }}개
|
||||
</div>
|
||||
<ul class="cpg-ship-items">
|
||||
{% for it in s['items'] %}
|
||||
<li>
|
||||
<span class="cpg-ship-iname">{{ it.name }}</span>
|
||||
<span class="cpg-ship-iqty">{{ it.qty }}개</span>
|
||||
<span class="cpg-ship-ibox">{{ it.boxes }}박스</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<ul class="cpg-dist-items">
|
||||
{% if s.box_plan %}
|
||||
{% for e in s.box_plan %}
|
||||
<li class="cpg-dist-item{% if e.kind == 'mix' %} is-mix{% endif %}">
|
||||
<div class="cpg-dist-line">
|
||||
<span class="cpg-dist-name">{{ e.name }}</span>
|
||||
<span class="cpg-dist-unit">{{ e.count }}박스 · {{ e.quantity }}개</span>
|
||||
</div>
|
||||
{% if e.kind == 'mix' and e['items'] %}
|
||||
<ul class="cpg-dist-tree">
|
||||
{% for it in e['items'] %}
|
||||
<li><span class="cpg-tree-name">{{ it.product_name }}</span>
|
||||
<span class="cpg-tree-qty">{{ it.quantity }}개</span></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% else %}
|
||||
{# 예전에 만든 출고(박스 구성 미저장) — 제품 합계만 표시 #}
|
||||
{% for it in s['items'] %}
|
||||
<li class="cpg-dist-item">
|
||||
<div class="cpg-dist-line">
|
||||
<span class="cpg-dist-name">{{ it.name }}</span>
|
||||
<span class="cpg-dist-unit">{{ it.boxes }}박스 · {{ it.qty }}개</span>
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
||||
<div class="cpg-ship-meta erp-muted">출고 {{ s.ship_date }} · 센터입고 {{ s.center_arrival_date }}</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "erp_base.html" %}
|
||||
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260901m" />{% endblock %}
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260901n" />{% 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=20260901m" />{% endblock %}
|
||||
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260901n" />{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{# 출고 묶음 보기 — 박스 계산 화면과 같은 3열 구성. 읽기 전용(수정 없음). #}
|
||||
@@ -140,14 +140,33 @@
|
||||
</span>
|
||||
</div>
|
||||
<ul class="cpg-dist-items">
|
||||
{% for it in items %}
|
||||
<li class="cpg-dist-item">
|
||||
<div class="cpg-dist-line">
|
||||
<span class="cpg-dist-name">{{ it.product_name }}</span>
|
||||
<span class="cpg-dist-unit">{{ it.quantity }}개</span>
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% if shipment.box_plan %}
|
||||
{% for e in shipment.box_plan %}
|
||||
<li class="cpg-dist-item{% if e.kind == 'mix' %} is-mix{% endif %}">
|
||||
<div class="cpg-dist-line">
|
||||
<span class="cpg-dist-name">{{ e.name }}</span>
|
||||
<span class="cpg-dist-unit">{{ e.count }}박스 · {{ e.quantity }}개</span>
|
||||
</div>
|
||||
{% if e.kind == 'mix' and e['items'] %}
|
||||
<ul class="cpg-dist-tree">
|
||||
{% for it in e['items'] %}
|
||||
<li><span class="cpg-tree-name">{{ it.product_name }}</span>
|
||||
<span class="cpg-tree-qty">{{ it.quantity }}개</span></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for it in items %}
|
||||
<li class="cpg-dist-item">
|
||||
<div class="cpg-dist-line">
|
||||
<span class="cpg-dist-name">{{ it.product_name }}</span>
|
||||
<span class="cpg-dist-unit">{{ it.quantity }}개</span>
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user