ui(malaysia): 이동이력 날짜필터+요일, Ref열 제거, 헤딩 변경(낱개/콤보 상품)

- 이동 이력에 날짜 선택 필터(요일 포함 표시), 날짜+종류 조합 유지
- 이력 Ref 컬럼 삭제
- "낱개 아이템"→"낱개 상품", "세트 아이템 — 출고(OUT)"→"콤보 상품"
- 안내 문구 삭제

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-11 16:05:50 +09:00
parent 300f4e23c8
commit 9039d1d80b
2 changed files with 43 additions and 17 deletions
+27 -5
View File
@@ -40,6 +40,21 @@ def _bom_map(request: Request) -> dict[str, list[dict[str, Any]]]:
return r.set_bom_map() if r else {}
_WEEKDAYS_KO = ("", "", "", "", "", "", "")
def _date_label(iso: str | None) -> str:
"""'2026-06-11''2026-06-11 (목)'. 파싱 실패 시 원문."""
from datetime import date as _date # noqa: WPS433
s = (iso or "").strip()
try:
d = _date.fromisoformat(s[:10])
except (ValueError, TypeError):
return s
return f"{d.isoformat()} ({_WEEKDAYS_KO[d.weekday()]})"
def _require_user(request: Request) -> dict[str, Any]:
from app.main import get_current_user_record # noqa: WPS433
from app.store import has_module # noqa: WPS433
@@ -151,6 +166,16 @@ async def movements_page(request: Request) -> HTMLResponse:
st, user = guard
wh = _selected_wh(request, st)
mtype = (request.query_params.get("type") or "").strip().upper()
fdate = (request.query_params.get("date") or "").strip()
movements = st.list_movements(
warehouse_code=wh,
movement_type=mtype if mtype in store.MOVEMENT_TYPES else None,
date_from=fdate or None,
date_to=fdate or None,
limit=300,
)
for m in movements:
m["date_label"] = _date_label(m.get("movement_date"))
ctx = _base_ctx(request, user, st, wh=wh)
ctx.update(
{
@@ -158,13 +183,10 @@ async def movements_page(request: Request) -> HTMLResponse:
"page_subtitle": f"{wh} · 입고/출고/조정 일괄 등록",
"individual_items": st.list_items(kind="individual"),
"set_items": st.list_items(kind="set"),
"movements": st.list_movements(
warehouse_code=wh,
movement_type=mtype if mtype in store.MOVEMENT_TYPES else None,
limit=200,
),
"movements": movements,
"today": today_kst().isoformat(),
"filter_type": mtype if mtype in store.MOVEMENT_TYPES else "",
"filter_date": fdate,
}
)
return render_template(request, "malaysia/movements.html", ctx)
@@ -34,7 +34,6 @@
<label class="erp-field"><span>메모</span>
<input class="erp-input" type="text" name="memo" /></label>
</div>
<p class="erp-muted" style="margin-top:10px;">세트는 항상 <b>출고(OUT)</b> · BOM 분해. 빈칸/0 제외.</p>
<div class="erp-page-actions" style="margin-top:12px;">
<button type="submit" class="erp-btn erp-btn-primary">일괄 적용</button>
</div>
@@ -42,7 +41,7 @@
<!-- 중: 낱개 -->
<div class="erp-card">
<div class="cpg-card-head"><h2>낱개 아이템</h2></div>
<div class="cpg-card-head"><h2>낱개 상품</h2></div>
<div class="erp-table-wrap" style="margin-top:8px;">
<table class="erp-table">
<thead><tr><th>Code</th><th>Name</th><th style="width:100px">Qty</th></tr></thead>
@@ -61,7 +60,7 @@
<!-- 우: 세트 -->
<div class="erp-card">
<div class="cpg-card-head"><h2>세트 아이템 — 출고(OUT)</h2></div>
<div class="cpg-card-head"><h2>콤보 상품</h2></div>
<div class="erp-table-wrap" style="margin-top:8px;">
<table class="erp-table">
<thead><tr><th>Set Code</th><th>Set Name</th><th style="width:100px">Qty (OUT)</th></tr></thead>
@@ -82,32 +81,37 @@
<!-- 이동 이력 -->
<div class="erp-card" style="margin-top:16px;">
<div class="cpg-card-head" style="display:flex;justify-content:space-between;align-items:center;">
<h2>최근 이동 이력</h2>
<span>
<a class="erp-btn erp-btn-outline" href="/malaysia/movements?wh={{ selected_wh }}">전체</a>
<div class="cpg-card-head" style="display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:8px;">
<h2>이동 이력{% if filter_date %} · {{ filter_date }}{% endif %}</h2>
<span style="display:flex;gap:6px;align-items:center;flex-wrap:wrap;">
<form method="get" style="display:flex;gap:6px;align-items:center;">
<input type="hidden" name="wh" value="{{ selected_wh }}" />
{% if filter_type %}<input type="hidden" name="type" value="{{ filter_type }}" />{% endif %}
<input class="erp-input" type="date" name="date" value="{{ filter_date }}" onchange="this.form.submit()" />
{% if filter_date %}<a class="erp-btn erp-btn-outline" href="/malaysia/movements?wh={{ selected_wh }}{% if filter_type %}&type={{ filter_type }}{% endif %}">날짜해제</a>{% endif %}
</form>
<a class="erp-btn erp-btn-outline" href="/malaysia/movements?wh={{ selected_wh }}{% if filter_date %}&date={{ filter_date }}{% endif %}">전체</a>
{% for t in ['IN','OUT','ADJUST','STOCKTAKE'] %}
<a class="erp-btn {% if filter_type==t %}erp-btn-primary{% else %}erp-btn-outline{% endif %}" href="/malaysia/movements?wh={{ selected_wh }}&type={{ t }}">{{ t }}</a>
<a class="erp-btn {% if filter_type==t %}erp-btn-primary{% else %}erp-btn-outline{% endif %}" href="/malaysia/movements?wh={{ selected_wh }}&type={{ t }}{% if filter_date %}&date={{ filter_date }}{% endif %}">{{ t }}</a>
{% endfor %}
</span>
</div>
<div class="erp-table-wrap">
<table class="erp-table">
<thead><tr><th>Date</th><th>Type</th><th>Item</th><th style="text-align:right">Qty</th><th>Ref</th><th>Memo</th><th>By</th></tr></thead>
<thead><tr><th>Date</th><th>Type</th><th>Item</th><th style="text-align:right">Qty</th><th>Memo</th><th>By</th></tr></thead>
<tbody>
{% for m in movements %}
<tr>
<td>{{ m.movement_date }}</td>
<td>{{ m.date_label }}</td>
<td>{{ m.movement_type }}</td>
<td>{{ m.item_code }}</td>
<td style="text-align:right">{{ m.qty }}</td>
<td>{{ m.ref_type }}{% if m.ref_no %} / {{ m.ref_no }}{% endif %}</td>
<td>{{ m.memo or '—' }}</td>
<td>{{ m.created_by or '—' }}</td>
</tr>
{% endfor %}
{% if not movements %}
<tr><td colspan="7" class="erp-muted">이동 이력이 없습니다.</td></tr>
<tr><td colspan="6" class="erp-muted">이동 이력이 없습니다.</td></tr>
{% endif %}
</tbody>
</table>