f137f2a6a6
- 신규 모듈 app/modules/malaysia (prefix /malaysia, 권한키 malaysia) - malaysia_stock_db: warehouses/malaysia_items/set_bom/stock_movement/ daily_stocktake/daily_stocktake_line (멱등 init SQL) - 낱개(MT/MX/MZ) 입출고·조정 movement, 세트(MY) BOM 관리, 세트 출고 BOM 분해 - 일일 재고조사: 세트→낱개 자동 분해(direct+from_set=total), 확정 시 차이만 STOCKTAKE - prefix 검증 이중화(DB CHECK + store.py 순수함수), MD- 전면 제외 - 상품명은 itemcode_db 읽기 전용 재사용(중복 마스터 없음) - 화면 4종 + JSON API, 순수로직 테스트 14건, README/docs 갱신 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
말레이시아 창고 재고관리 모듈 (malaysia)
말레이시아 현지 창고의 입고/출고/조정과 세트 BOM, 일일 재고조사를 관리한다.
cupang 모듈과 동일한 패턴: malaysia_stock_db(PostgreSQL) 전용, JSON 폴백 없음.
상품명은 기존 itemcode_db(읽기 전용)을 재사용한다.
- 경로(prefix):
/malaysia - 권한키:
malaysia(admin 은 항상 통과) - 환경변수:
MALAYSIA_STOCK_DB_URL(미설정 시 "설정 필요" 안내) - DB:
malaysia_stock_db/ 역할malaysia_app
재고 원칙
- 입고/출고/조정은 낱개 아이템(MT-/MX-/MZ-) 기준으로만 movement 저장.
- 세트(MY-)는 movement 불가. 세트는 ① 재고조사 입력, ② BOM 구성 계산에만 사용.
- 세트 주문 출고는
set_bom으로 분해해 구성품별OUTmovement 를 생성(/malaysia/movements/set-out). - 뚜껑(MD-)은 재고관리 대상에서 완전 제외(어디에도 사용 불가).
현재고 계산
현재고 = SUM(IN) - SUM(OUT) + SUM(ADJUST) + SUM(STOCKTAKE)
IN/OUTqty 는 양수만.ADJUST/STOCKTAKE는 음수(±) 허용.- 재고조사 확정 시 시스템 재고와 조사 최종치의 "차이"만
STOCKTAKEmovement 로 기록 → 이력 보존 + 계산 단순.
일일 재고조사 집계
낱개 최종 재고(total_qty)
= direct_qty(낱개 직접 조사)
+ from_set_qty(세트 수량을 set_bom 으로 분해한 합)
예) MT-0320 낱개 100 + MY-0002(MT-0320 1개 포함) 20세트 → MT-0320 total = 120.
낱개 입력 시 세트 안에 든 건 빼고 낱개 보관분만 입력한다. 세트 안 상품은 BOM 으로 자동 계산.
테이블 (scripts/sql/malaysia_stock_db_init.sql)
| 테이블 | 용도 |
|---|---|
warehouses |
창고. seed: MY-WH-01 / Malaysia Warehouse |
malaysia_items |
관리 대상 코드 스코프(낱개/세트) + 이름 스냅샷. seed: 낱개 12 + 세트 5 |
set_bom |
세트 구성표. UNIQUE(set_code, component_code). prefix CHECK 내장 |
stock_movement |
입고/출고/조정/조사 이력. item_code 는 낱개만(CHECK) |
daily_stocktake |
재고조사 헤더. 같은 날짜+창고 finalized 1건(부분 유니크) |
daily_stocktake_line |
조사 라인. sku_code 낱개+세트 허용, UNIQUE(stocktake_id, sku_code) |
검증 규칙(요구사항 8)은 DB CHECK + 서비스 레이어(store.py) 양쪽에 걸려 있다.
주요 화면 / API
화면: /malaysia/(재고 현황) · /malaysia/movements(입출고) · /malaysia/stocktakes(재고조사) · /malaysia/sets(세트 구성)
JSON API:
| Method | 경로 | 설명 |
|---|---|---|
| GET | /malaysia/api/warehouses |
창고 목록 |
| GET | /malaysia/api/items?kind=individual|set |
아이템 목록 |
| GET/POST | /malaysia/api/bom |
세트 구성 조회/등록 |
| GET | /malaysia/api/stock?wh= |
현재고 현황 |
| POST | /malaysia/api/movements |
낱개 movement 등록 |
| POST | /malaysia/api/movements/set-out |
세트 출고(BOM 분해) |
| GET | /malaysia/api/stocktakes/{id}/result |
재고조사 최종 계산 |
초기화 (운영, 1회 — 사용자 승인 후)
read -s -p "malaysia_app password: " APP_PWD; echo
docker exec -i postgres-db psql -U postgres \
-v app_password="$APP_PWD" \
< scripts/sql/malaysia_stock_db_init.sql
# main-app .env 에 추가:
# MALAYSIA_STOCK_DB_URL=postgresql://malaysia_app:<APP_PWD>@postgres-db:5432/malaysia_stock_db
cd /opt/www/main && docker compose up -d --build
멱등 스크립트. 기존 DB 가 있으면 DROP 하지 않음. itemcode_db 는 건드리지 않음.
테스트
python -m pytest tests/test_malaysia_stock.py -v # pytest 있으면
python tests/test_malaysia_stock.py # 없으면 standalone 폴백
순수 로직(코드 검증 / 세트 분해 / 재고조사 집계)만 검증하므로 DB 불필요.