feat(malaysia): 창고 랙 보기 페이지

최근(취소 제외) 재고조사의 랙 입력을 칸별로 한눈에 보는 읽기전용 메뉴.
각 칸에 상품명·박스수×입수량=총개수, 칸 합계(∑) 표시.

- nav: '창고 랙 보기' 탭 추가(active_tab='rack')
- router: GET /malaysia/rack — latest_stocktake → list_rack_entries 칸별 그룹
- 템플릿 rack_view.html — Side A/B 세로 적층, 칸별 아이템 목록
- i18n 키 추가(Rack View 등)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-14 16:48:07 +09:00
parent 4c7eb9467f
commit 1e0e69fcbe
5 changed files with 125 additions and 1 deletions
@@ -2,4 +2,4 @@
<div style="display:flex;justify-content:flex-end;margin-bottom:8px;">
<button type="button" id="mys-lang-toggle" class="erp-btn erp-btn-outline">ENG</button>
</div>
<script src="/static/malaysia.js?v=20260614a"></script>
<script src="/static/malaysia.js?v=20260614b"></script>
@@ -3,6 +3,7 @@
<a class="erp-btn {% if active_tab=='status' %}erp-btn-primary{% else %}erp-btn-outline{% endif %}" href="/malaysia/?wh={{ selected_wh }}">재고 현황</a>
<a class="erp-btn {% if active_tab=='move' %}erp-btn-primary{% else %}erp-btn-outline{% endif %}" href="/malaysia/movements?wh={{ selected_wh }}">입출고</a>
<a class="erp-btn {% if active_tab=='stocktake' %}erp-btn-primary{% else %}erp-btn-outline{% endif %}" href="/malaysia/stocktakes?wh={{ selected_wh }}">일일 재고조사</a>
<a class="erp-btn {% if active_tab=='rack' %}erp-btn-primary{% else %}erp-btn-outline{% endif %}" href="/malaysia/rack?wh={{ selected_wh }}">창고 랙 보기</a>
<span style="flex:1 1 auto"></span>
@@ -0,0 +1,85 @@
{% extends "erp_base.html" %}
{% block head_extra %}
<style>
.rv-board { display:flex; flex-direction:column; gap:18px; }
.rv-side { width:100%; }
.rv-side h3 { text-align:center; margin:0 0 8px; }
.rv-row { display:grid; grid-template-columns:repeat(6, 1fr); gap:6px; margin-bottom:6px; }
.rv-cell {
border:1px solid #cbd5e1; border-radius:6px; padding:5px;
background:#f8fafc; min-height:80px; display:flex; flex-direction:column; min-width:0;
}
.rv-cell.is-empty { background:#fff; }
.rv-cell-head {
display:flex; align-items:center; justify-content:space-between;
font-size:11px; font-weight:600; color:#475569; margin-bottom:4px;
border-bottom:1px solid #e2e8f0; padding-bottom:3px;
}
.rv-cell-head .rv-total { color:#0f172a; white-space:nowrap; }
.rv-items { display:flex; flex-direction:column; gap:3px; }
.rv-item { font-size:11px; line-height:1.25; }
.rv-item .rv-name { font-weight:600; color:#0f172a; }
.rv-item .rv-calc { color:#475569; }
.rv-item .rv-qty { color:#2563eb; font-weight:600; }
.rv-empty-note { font-size:11px; color:#cbd5e1; }
</style>
{% endblock %}
{% block content %}
<section class="mys mys-compact">
{% include "malaysia/_i18n.html" %}
{% set active_tab = 'rack' %}
{% include "malaysia/_nav.html" %}
<div class="erp-card">
<div class="cpg-card-head" style="display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:8px;">
<h2>창고 랙 보기</h2>
<span class="erp-muted">
{% if stocktake %}
<span class="i18n">기준 재고조사</span>: #{{ stocktake.id }} · {{ stocktake.stocktake_date }}
{% if stocktake.status=='finalized' %}<span class="erp-badge erp-badge-success">확정</span>
{% elif stocktake.status=='cancelled' %}<span class="erp-badge erp-badge-neutral">취소</span>
{% else %}<span class="erp-badge erp-badge-inverse">작성중</span>{% endif %}
{% else %}
<span class="i18n">표시할 재고조사가 없습니다.</span>
{% endif %}
</span>
</div>
<div class="rv-board" style="margin-top:10px;">
{% for side in rack_layout %}
<div class="rv-side">
<h3>Side {{ side.side }}</h3>
{% for row in side.rows %}
<div class="rv-row">
{% for col in row.cols %}
{% for cell in col %}
{% set entries = rack_by_cell.get(cell, []) %}
{% set ns = namespace(total=0) %}
{% for e in entries %}{% set ns.total = ns.total + e.total %}{% endfor %}
<div class="rv-cell {% if not entries %}is-empty{% endif %}">
<div class="rv-cell-head">
<span>{{ cell }}</span>
<span class="rv-total">∑ {{ ns.total }}</span>
</div>
<div class="rv-items">
{% for e in entries %}
<div class="rv-item">
<span class="rv-name" data-en="{{ e.item_name }}" data-ko="{{ ko_names.get(e.sku_code, e.item_name) }}">{{ e.item_name }}</span><br>
<span class="rv-calc">{{ e.box_count }}<span class="i18n">박스</span> × {{ e.units_per_box }} = <span class="rv-qty">{{ e.total }}</span></span>
</div>
{% endfor %}
{% if not entries %}<span class="rv-empty-note"></span>{% endif %}
</div>
</div>
{% endfor %}
{% endfor %}
</div>
{% endfor %}
</div>
{% endfor %}
</div>
</div>
</section>
{% endblock %}