c07d3301e4
- 재고현황 헤더 "전산 재고 현황", Last Stocktake 옆 조사수량+차이(±) 표기 (차이 = 마지막 재고조사 낱개 total − 전산재고) - 재고조사 확정(전산 반영)은 관리자(is_admin)만 가능, 비관리자 안내 - 슈퍼관리자만 재고조사 완전 삭제(목록/상세 버튼 + /delete 라우트) - "◀◀ 조사 목록" 버튼 검정 바탕(primary) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
140 lines
6.3 KiB
HTML
140 lines
6.3 KiB
HTML
{% extends "erp_base.html" %}
|
|
|
|
{% block head_extra %}
|
|
<style>
|
|
.mys-compact .erp-table th,
|
|
.mys-compact .erp-table td { padding-top:4px; padding-bottom:4px; }
|
|
.mys-compact .erp-input { padding-top:4px; padding-bottom:4px; }
|
|
.mys-compact td.nm { white-space:nowrap; }
|
|
.mys-compact th.ccol, .mys-compact td.ccol { white-space:nowrap; width:88px; }
|
|
.mys-compact .qcol { width:110px; }
|
|
.mys-compact .qcol .erp-input { width:100px; }
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<section class="mys mys-compact">
|
|
<div class="erp-page-actions">
|
|
<a class="erp-btn erp-btn-primary" href="/malaysia/stocktakes?wh={{ stocktake.warehouse_code }}">◀◀ 조사 목록</a>
|
|
</div>
|
|
|
|
<form method="post" action="/malaysia/stocktakes/{{ stocktake.id }}/lines/bulk">
|
|
<div style="display:grid;grid-template-columns:280px 1fr 1fr;gap:16px;align-items:start;">
|
|
|
|
<!-- 좌: 정보 + 동작 -->
|
|
<div class="erp-card">
|
|
<div class="cpg-card-head"><h2>재고조사 #{{ stocktake.id }}</h2></div>
|
|
<div style="margin-top:8px;display:flex;flex-direction:column;gap:6px;">
|
|
<div><span class="erp-muted">날짜</span><br>{{ stocktake.stocktake_date }}</div>
|
|
<div><span class="erp-muted">창고</span><br>{{ stocktake.warehouse_code }}</div>
|
|
<div><span class="erp-muted">상태</span><br>
|
|
{% 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 %}
|
|
</div>
|
|
{% if stocktake.finalized_at %}<div><span class="erp-muted">확정시각</span><br>{{ stocktake.finalized_at }}</div>{% endif %}
|
|
</div>
|
|
|
|
{% if missing_bom %}
|
|
<p style="color:#b91c1c;font-weight:600;margin-top:10px;">⚠ BOM 없는 콤보: {{ missing_bom|join(', ') }}</p>
|
|
{% endif %}
|
|
|
|
{% if is_draft %}
|
|
<div class="erp-page-actions" style="margin-top:12px;">
|
|
<button type="submit" class="erp-btn erp-btn-primary">입력 저장</button>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- 중: 낱개 -->
|
|
<div class="erp-card">
|
|
<div class="cpg-card-head"><h2>낱개 상품</h2></div>
|
|
<div class="erp-table-wrap" style="margin-top:8px;">
|
|
<table class="erp-table">
|
|
<thead><tr><th class="ccol">Code</th><th>Name</th><th class="qcol">Qty</th></tr></thead>
|
|
<tbody>
|
|
{% for it in individual_items %}
|
|
<tr>
|
|
<td class="ccol">{{ it.item_code }}</td>
|
|
<td class="nm">{{ it.item_name }}</td>
|
|
<td class="qcol"><input class="erp-input" type="number" min="0" name="qty_{{ it.item_code }}"
|
|
value="{{ entered.get(it.item_code, '') }}" placeholder="—" {% if not is_draft %}disabled{% endif %} /></td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 우: 콤보 -->
|
|
<div class="erp-card">
|
|
<div class="cpg-card-head"><h2>콤보 상품</h2></div>
|
|
<div class="erp-table-wrap" style="margin-top:8px;">
|
|
<table class="erp-table">
|
|
<thead><tr><th class="ccol">Set Code</th><th>Set Name</th><th class="qcol">Qty</th></tr></thead>
|
|
<tbody>
|
|
{% for it in set_items %}
|
|
<tr>
|
|
<td class="ccol">{{ it.item_code }}</td>
|
|
<td class="nm">{{ it.item_name }}</td>
|
|
<td class="qcol"><input class="erp-input" type="number" min="0" name="qty_{{ it.item_code }}"
|
|
value="{{ entered.get(it.item_code, '') }}" placeholder="—" {% if not is_draft %}disabled{% endif %} /></td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
<!-- 확정/취소/삭제 -->
|
|
<div class="erp-page-actions" style="margin-top:12px;display:flex;gap:8px;flex-wrap:wrap;">
|
|
{% if is_draft %}
|
|
{% if is_admin %}
|
|
<form method="post" action="/malaysia/stocktakes/{{ stocktake.id }}/finalize"
|
|
onsubmit="return confirm('확정하면 전산 재고와의 차이가 STOCKTAKE 이동으로 기록되고, 이후 수정 불가합니다. 계속?');">
|
|
<button type="submit" class="erp-btn erp-btn-primary" {% if missing_bom %}disabled title="BOM 누락 콤보 해결 필요"{% endif %}>확정 (전산 반영)</button>
|
|
</form>
|
|
{% else %}
|
|
<span class="erp-muted">전산 재고 반영(확정)은 관리자만 가능합니다.</span>
|
|
{% endif %}
|
|
<form method="post" action="/malaysia/stocktakes/{{ stocktake.id }}/cancel" onsubmit="return confirm('이 조사를 취소합니다. 계속?');">
|
|
<button type="submit" class="erp-btn erp-btn-danger">취소</button>
|
|
</form>
|
|
{% endif %}
|
|
{% if is_super %}
|
|
<form method="post" action="/malaysia/stocktakes/{{ stocktake.id }}/delete"
|
|
onsubmit="return confirm('이 재고조사를 완전 삭제합니다(되돌릴 수 없음). 계속?');">
|
|
<button type="submit" class="erp-btn erp-btn-danger">삭제 (슈퍼관리자)</button>
|
|
</form>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- 최종 계산 결과 (낱개 기준) -->
|
|
<div class="erp-card" style="margin-top:16px;">
|
|
<div class="cpg-card-head"><h2>최종 계산 (낱개 기준)</h2></div>
|
|
<span class="erp-muted">total_qty = direct_qty(낱개 직접) + from_set_qty(콤보 분해)</span>
|
|
<div class="erp-table-wrap">
|
|
<table class="erp-table">
|
|
<thead><tr><th>Item Code</th><th>Product Name</th><th style="text-align:right">Direct</th><th style="text-align:right">From Set</th><th style="text-align:right">Total</th></tr></thead>
|
|
<tbody>
|
|
{% for r in result_rows %}
|
|
<tr>
|
|
<td>{{ r.item_code }}</td>
|
|
<td>{{ r.item_name }}</td>
|
|
<td style="text-align:right">{{ r.direct_qty }}</td>
|
|
<td style="text-align:right">{{ r.from_set_qty }}</td>
|
|
<td style="text-align:right;font-weight:600;">{{ r.total_qty }}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
{% if not result_rows %}
|
|
<tr><td colspan="5" class="erp-muted">입력된 수량이 없습니다.</td></tr>
|
|
{% endif %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
{% endblock %}
|