feat(malaysia): 재고조사 랙(rack) 박스 단위 입력
낱개/콤보 평면 수량 그리드를 창고 랙 그림(A/B 36칸) 입력으로 대체.
각 칸에 아이템·박스당 입수량·박스 수를 넣고 + 로 한 칸 여러 아이템 추가.
저장 시 SKU별 qty=SUM(입수량×박스수) 집계로 daily_stocktake_line 재생성.
이후 분해/확정 로직은 라인 기준 그대로 동작.
- DB: daily_stocktake_rack 테이블 + grant (멱등)
- store: rack_cell_codes/rack_layout/aggregate_rack 순수함수
- db: list_rack_entries/replace_rack(1 트랜잭션, draft만)
- router: rack 컨텍스트 + POST /stocktakes/{id}/rack/bulk
- UI: 랙 보드 템플릿 + malaysia_rack.js(행 추가/삭제·실시간 소계)
- 테스트 4건 추가(18 전부 통과)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -170,6 +170,51 @@ def test_missing_bom_sets():
|
||||
assert missing == ["MY-0005"]
|
||||
|
||||
|
||||
# ────────────────────────────────────────────────────────────
|
||||
# 랙 입력 — 레이아웃 / 집계
|
||||
# ────────────────────────────────────────────────────────────
|
||||
def test_rack_cell_codes_count_and_format():
|
||||
codes = store.rack_cell_codes()
|
||||
# A/B 2면 × 3행 × 3열 × 2분할 = 36칸
|
||||
assert len(codes) == 36
|
||||
assert len(set(codes)) == 36
|
||||
assert "A3-1-1" in codes
|
||||
assert "B1-3-2" in codes
|
||||
# 그림과 동일: 첫 칸은 A면 3행 1열 1분할
|
||||
assert codes[0] == "A3-1-1"
|
||||
|
||||
|
||||
def test_rack_layout_structure():
|
||||
layout = store.rack_layout()
|
||||
assert [s["side"] for s in layout] == ["A", "B"]
|
||||
side_a = layout[0]
|
||||
assert [r["row"] for r in side_a["rows"]] == [3, 2, 1]
|
||||
# 각 행 3열, 각 열 2분할
|
||||
first_row = side_a["rows"][0]
|
||||
assert len(first_row["cols"]) == 3
|
||||
assert first_row["cols"][0] == ["A3-1-1", "A3-1-2"]
|
||||
|
||||
|
||||
def test_aggregate_rack_sums_units_times_boxes():
|
||||
entries = [
|
||||
{"sku_code": "MT-0320", "units_per_box": 24, "box_count": 3}, # 72
|
||||
{"sku_code": "MT-0320", "units_per_box": 24, "box_count": 1}, # +24 (다른 칸)
|
||||
{"sku_code": "MY-0002", "units_per_box": 6, "box_count": 2}, # 12 (콤보도 집계)
|
||||
]
|
||||
out = store.aggregate_rack(entries)
|
||||
assert out == {"MT-0320": 96, "MY-0002": 12}
|
||||
|
||||
|
||||
def test_aggregate_rack_skips_incomplete():
|
||||
entries = [
|
||||
{"sku_code": "", "units_per_box": 10, "box_count": 2}, # 코드 없음
|
||||
{"sku_code": "MT-0550", "units_per_box": 0, "box_count": 5}, # 입수량 0
|
||||
{"sku_code": "MT-0750", "units_per_box": 5, "box_count": 0}, # 박스 0
|
||||
{"sku_code": "MT-0950", "units_per_box": "x", "box_count": 2}, # 정수 아님
|
||||
]
|
||||
assert store.aggregate_rack(entries) == {}
|
||||
|
||||
|
||||
# pytest 미설치 환경 폴백
|
||||
if __name__ == "__main__":
|
||||
import traceback
|
||||
|
||||
Reference in New Issue
Block a user