feat(malaysia): 슈퍼관리자 재고 데이터 초기화
- 재고 현황 하단 '위험 구역' 카드(슈퍼관리자만 표시) - POST /malaysia/reset: stock_movement + daily_stocktake(+line) 전체 삭제 → 전체 창고 현재고/조사값 0. 마스터(창고/아이템) 보존. - 권한: is_super_admin 아니면 403 (버튼 숨김 + 서버 이중 검사) - 2단 확인(confirm + RESET 타이핑) - i18n 추가, malaysia.js 캐시 버전 bump Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -688,6 +688,24 @@ class MalaysiaStockStore:
|
||||
head = self.get_stocktake(stocktake_id=stocktake_id, with_lines=True)
|
||||
return {"stocktake": head, "adjustments": adjustments, "rows": rows}
|
||||
|
||||
# ════════════════════════════════════════════════════════════
|
||||
# 데이터 초기화 (슈퍼관리자 전용 — 라우터에서 권한 검사)
|
||||
# ════════════════════════════════════════════════════════════
|
||||
def reset_all_data(self) -> dict[str, int]:
|
||||
"""전체 창고의 재고 수량 데이터 초기화.
|
||||
|
||||
삭제 대상: stock_movement(입고/출고/조정/조사반영) +
|
||||
daily_stocktake/daily_stocktake_line(재고조사).
|
||||
보존 대상: warehouses, malaysia_items(마스터).
|
||||
한 트랜잭션으로 처리. 반환: 삭제 건수.
|
||||
"""
|
||||
with self._pool.connection() as conn:
|
||||
with conn.transaction():
|
||||
mv = conn.execute("DELETE FROM stock_movement").rowcount or 0
|
||||
ln = conn.execute("DELETE FROM daily_stocktake_line").rowcount or 0
|
||||
hd = conn.execute("DELETE FROM daily_stocktake").rowcount or 0
|
||||
return {"movements": mv, "stocktake_lines": ln, "stocktakes": hd}
|
||||
|
||||
# ════════════════════════════════════════════════════════════
|
||||
# 직렬화
|
||||
# ════════════════════════════════════════════════════════════
|
||||
|
||||
@@ -174,6 +174,24 @@ async def index(request: Request) -> HTMLResponse:
|
||||
return render_template(request, "malaysia/index.html", ctx)
|
||||
|
||||
|
||||
@router.post("/reset")
|
||||
async def reset_data(
|
||||
request: Request, user: dict[str, Any] = Depends(_require_user)
|
||||
) -> RedirectResponse:
|
||||
"""전체 창고 재고 수량 데이터 초기화 — 슈퍼관리자 전용.
|
||||
|
||||
stock_movement + daily_stocktake(+line) 전체 삭제(현재고/조사값 0).
|
||||
마스터(warehouses, malaysia_items)는 보존.
|
||||
"""
|
||||
if not user.get("is_super_admin"):
|
||||
raise HTTPException(status_code=403, detail="재고 데이터 초기화는 슈퍼관리자만 가능합니다.")
|
||||
st = _store(request)
|
||||
if st is None:
|
||||
raise HTTPException(status_code=503, detail="malaysia_stock_db 미설정")
|
||||
st.reset_all_data()
|
||||
return RedirectResponse(url="/malaysia/", status_code=303)
|
||||
|
||||
|
||||
# ════════════════════════════════════════════════════════════
|
||||
# 입고 / 출고 등록 (그리드 일괄)
|
||||
# ════════════════════════════════════════════════════════════
|
||||
|
||||
@@ -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=20260612"></script>
|
||||
<script src="/static/malaysia.js?v=20260612b"></script>
|
||||
|
||||
@@ -80,5 +80,26 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if is_super %}
|
||||
<div class="erp-card" style="margin-top:16px;border:1px solid #fecaca;background:#fef2f2;">
|
||||
<div class="cpg-card-head"><h2 style="color:#b91c1c;">위험 구역 (슈퍼관리자)</h2></div>
|
||||
<p class="erp-muted" style="margin:4px 0 12px;">
|
||||
전체 창고의 입출고 이력·재고조사 데이터를 모두 삭제해 재고 수량을 0으로 초기화합니다.
|
||||
창고/아이템 마스터는 유지됩니다. <strong>되돌릴 수 없습니다.</strong>
|
||||
</p>
|
||||
<form method="post" action="/malaysia/reset" onsubmit="return mysConfirmReset()">
|
||||
<button type="submit" class="erp-btn" style="background:#b91c1c;color:#fff;">재고 초기화</button>
|
||||
</form>
|
||||
</div>
|
||||
<script>
|
||||
function mysConfirmReset() {
|
||||
if (!confirm('전체 창고의 입출고 이력과 재고조사 데이터를 모두 삭제합니다.\n재고 수량이 0으로 초기화되며 되돌릴 수 없습니다.\n\n계속하시겠습니까?')) return false;
|
||||
var t = prompt('정말 초기화하려면 RESET 을 입력하세요.');
|
||||
if (t !== 'RESET') { alert('초기화가 취소되었습니다.'); return false; }
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
"재고조사 입력 없음": "No stocktake input",
|
||||
"표시할 재고가 없습니다.": "No stock to display.",
|
||||
"콤보 재고 입력이 없습니다.": "No combo stock input.",
|
||||
"위험 구역 (슈퍼관리자)": "Danger Zone (Super Admin)",
|
||||
"재고 초기화": "Reset Stock",
|
||||
// 입출고
|
||||
"등록 옵션": "Options",
|
||||
"이동 종류 (낱개)": "Type (single)",
|
||||
|
||||
Reference in New Issue
Block a user