diff --git a/app/modules/malaysia/router.py b/app/modules/malaysia/router.py
index 52b4a00..a978844 100644
--- a/app/modules/malaysia/router.py
+++ b/app/modules/malaysia/router.py
@@ -174,6 +174,40 @@ async def index(request: Request) -> HTMLResponse:
return render_template(request, "malaysia/index.html", ctx)
+@router.get("/rack", response_class=HTMLResponse)
+async def rack_view(request: Request) -> HTMLResponse:
+ """창고 랙 보기 — 최근(취소 제외) 재고조사의 랙 입력을 칸별로 한눈에.
+
+ 읽기 전용. 각 칸에 어떤 상품이 몇 박스(× 입수량 = 총개수) 있는지 표시.
+ """
+ from app.main import render_template # noqa: WPS433
+
+ guard = _guard(request)
+ if not isinstance(guard, tuple):
+ return guard
+ st, user = guard
+ wh = _selected_wh(request, st)
+ latest = st.latest_stocktake(warehouse_code=wh)
+ rack_by_cell: dict[str, list[dict[str, Any]]] = {}
+ names = st.item_name_map()
+ if latest:
+ for e in st.list_rack_entries(stocktake_id=latest["id"]):
+ e["item_name"] = names.get(e["sku_code"], e["sku_code"])
+ e["total"] = int(e["units_per_box"]) * int(e["box_count"])
+ rack_by_cell.setdefault(e["cell_code"], []).append(e)
+ ctx = _base_ctx(request, user, st, wh=wh)
+ ctx.update(
+ {
+ "page_title": "말레이시아 재고관리 — 창고 랙",
+ "page_subtitle": f"{wh} · 랙 보기",
+ "rack_layout": store.rack_layout(),
+ "rack_by_cell": rack_by_cell,
+ "stocktake": latest,
+ }
+ )
+ return render_template(request, "malaysia/rack_view.html", ctx)
+
+
@router.post("/reset")
async def reset_data(
request: Request, user: dict[str, Any] = Depends(_require_user)
diff --git a/app/modules/malaysia/templates/malaysia/_i18n.html b/app/modules/malaysia/templates/malaysia/_i18n.html
index 99b29e7..6fedbb0 100644
--- a/app/modules/malaysia/templates/malaysia/_i18n.html
+++ b/app/modules/malaysia/templates/malaysia/_i18n.html
@@ -2,4 +2,4 @@
ENG
-
+
diff --git a/app/modules/malaysia/templates/malaysia/_nav.html b/app/modules/malaysia/templates/malaysia/_nav.html
index 6e5cf66..6817ada 100644
--- a/app/modules/malaysia/templates/malaysia/_nav.html
+++ b/app/modules/malaysia/templates/malaysia/_nav.html
@@ -3,6 +3,7 @@
재고 현황
입출고
일일 재고조사
+ 창고 랙 보기
diff --git a/app/modules/malaysia/templates/malaysia/rack_view.html b/app/modules/malaysia/templates/malaysia/rack_view.html
new file mode 100644
index 0000000..3303186
--- /dev/null
+++ b/app/modules/malaysia/templates/malaysia/rack_view.html
@@ -0,0 +1,85 @@
+{% extends "erp_base.html" %}
+
+{% block head_extra %}
+
+{% endblock %}
+
+{% block content %}
+
+ {% include "malaysia/_i18n.html" %}
+ {% set active_tab = 'rack' %}
+ {% include "malaysia/_nav.html" %}
+
+
+
+
창고 랙 보기
+
+ {% if stocktake %}
+ 기준 재고조사 : #{{ stocktake.id }} · {{ stocktake.stocktake_date }}
+ {% if stocktake.status=='finalized' %}확정
+ {% elif stocktake.status=='cancelled' %}취소
+ {% else %}작성중 {% endif %}
+ {% else %}
+ 표시할 재고조사가 없습니다.
+ {% endif %}
+
+
+
+
+ {% for side in rack_layout %}
+
+
Side {{ side.side }}
+ {% for row in side.rows %}
+
+ {% 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 %}
+
+
+ {{ cell }}
+ ∑ {{ ns.total }}
+
+
+ {% for e in entries %}
+
+ {{ e.item_name }}
+ {{ e.box_count }}박스 × {{ e.units_per_box }} = {{ e.total }}
+
+ {% endfor %}
+ {% if not entries %}
— {% endif %}
+
+
+ {% endfor %}
+ {% endfor %}
+
+ {% endfor %}
+
+ {% endfor %}
+
+
+
+{% endblock %}
diff --git a/app/static/malaysia.js b/app/static/malaysia.js
index ed73957..eb3db03 100644
--- a/app/static/malaysia.js
+++ b/app/static/malaysia.js
@@ -17,6 +17,10 @@
"재고 현황": "Stock Status",
"입출고": "In / Out",
"일일 재고조사": "Daily Stocktake",
+ "창고 랙 보기": "Rack View",
+ "기준 재고조사": "Based on stocktake",
+ "표시할 재고조사가 없습니다.": "No stocktake to display.",
+ "박스": "box",
"창고": "Warehouse",
"날짜": "Date",
"메모": "Memo",