Files
dbx-main/docs/DISPATCH_MODULE.md
T
king 99eea01fc1 feat(dispatch): 말레이시아 TikTok 출고관리 모듈 추가
03_TikTok_Order_Export.xlsx 업로드 → 1박스=1카드 출고 작업 리스트,
SKU 피킹 요약, Kagayaku 전달표(A4 인쇄)를 자동 생성.

- 1박스 묶음 기준: Package ID > Tracking ID > Order ID, 같은 박스 같은 SKU 합산
- 작업 상태 5단계 토글(AJAX 즉시 저장) + dispatch_logs 기록
- 고객 이름/주소/전화 미저장(파싱 시 폐기, 스키마에 컬럼 없음)
- 엑셀은 openpyxl 파싱(pandas 미사용), DB는 dispatch_db 전용
- 인증은 기존 Google OAuth + 신규 권한키 dispatch 재사용
- scripts/sql/dispatch_db_init.sql, docs/DISPATCH_MODULE.md 동봉

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 15:11:43 +09:00

134 lines
4.8 KiB
Markdown

# 말레이시아 배송 모듈 (dispatch) — TikTok 출고관리
> 초보 물류 직원이 엑셀을 열지 않고 웹 화면만 보고 출고 작업을 하도록 만든 모듈.
> main-app ERP 에 편입된 **모듈**이다(별도 앱/포트 아님). 인증은 기존 Google
> OAuth + 권한키 `dispatch` 를 재사용한다.
---
## 1. 무엇을 하나
TikTok Seller Center 에서 매일 받는 3개 파일을 업로드하면, 직원용 **출고 작업
리스트(04_Daily_Dispatch_List)** 를 웹에서 자동 생성한다(엑셀 파일로 만들 필요 없음).
| 파일 | 용도 | 업로드 |
| --- | --- | --- |
| 01_Picking_List.pdf | 전체 상품 피킹 참고용 | 선택(보관) |
| 02_Shipping_Label_Packing_Slip.pdf | 실제 포장/라벨 부착 원본 | 선택(보관) |
| 03_TikTok_Order_Export.xlsx | **자동 출고 리스트 기준 데이터** | **필수** |
작업 기준은 고객정보가 아니라 **Order ID / Package ID / Tracking ID / Seller SKU /
Quantity** 뿐이다. 고객 이름·주소·전화는 파싱 단계에서 버려 **DB 에 저장하지 않는다.**
### 1박스 묶음 규칙
엑셀 1줄 ≠ 1박스. 아래 우선순위로 1박스를 묶는다.
1. **Package ID** → 2. **Tracking ID** → 3. **Order ID**
같은 박스 안 같은 SKU 는 수량을 합산한다. 결과는 "1박스 = 1카드".
---
## 2. 화면
| 경로 | 화면 |
| --- | --- |
| `GET /dispatch/` | 출고 배치 목록 |
| `GET /dispatch/batches/new` | 업로드(날짜·플랫폼·파일 3개) |
| `POST /dispatch/batches` | 업로드 + 배치 생성 + 파싱 + 박스 저장 |
| `GET /dispatch/batches/{id}` | 출고 작업 리스트(1박스=1카드, 상태 토글·필터·검색) |
| `GET /dispatch/batches/{id}/picking` | SKU별 피킹 요약 |
| `GET /dispatch/batches/{id}/handover` | Kagayaku 전달 리스트(A4 인쇄용) |
| `POST /dispatch/parcels/{id}/toggle` | 작업 상태 1개 토글(AJAX, 즉시 저장) |
작업 상태(카드 버튼, 누르면 초록색): 상품준비 완료 → 포장완료 → 라벨부착 완료 →
Kagayaku 전달 완료 → 택배스캔 확인. 모든 변경은 `dispatch_logs` 에 기록된다.
---
## 3. 설치 / 실행
### 3-1. DB 초기화 (superuser 로 1회)
```bash
read -s -p "dispatch_app password: " APP_PWD; echo
docker exec -i postgres-db psql -U postgres \
-v app_password="$APP_PWD" \
< scripts/sql/dispatch_db_init.sql
```
생성물: DB `dispatch_db`, 역할 `dispatch_app`(CRUD only), 테이블
`dispatch_batches / dispatch_parcels / dispatch_items / dispatch_logs`.
멱등 스크립트라 여러 번 실행해도 기존 데이터를 지우지 않는다.
### 3-2. .env 등록
```
DISPATCH_DB_URL=postgresql://dispatch_app:<APP_PWD>@postgres-db:5432/dispatch_db
```
미설정 시 모듈은 "설정 필요" 안내만 보여주고 앱은 정상 기동한다(JSON 폴백 없음).
### 3-3. 재배포
```bash
cd /opt/www/main && docker compose up -d --build web
```
> `git pull` 후 반드시 `--build`. `restart` 만으로는 코드가 안 바뀐다.
### 3-4. 권한 부여
`/admin` 에서 대상 사용자에게 권한키 `dispatch`(라벨 "말레이시아 배송")를 켠다.
관리자(admin)는 항상 통과.
---
## 4. 업로드 원본 보관
업로드한 PDF/XLSX 원본은 아래에 저장되고 DB 에는 경로만 기록한다.
```
$DATA_DIR/dispatch/2026-06-19/<배치slug>_<HHMMSS>/
01_Picking_List.pdf
02_Shipping_Label_Packing_Slip.pdf
03_TikTok_Order_Export.xlsx
```
같은 날짜/플랫폼이라도 batch_name 으로 구분해 **새 배치**로 생성된다(덮어쓰지 않음).
예: "2026-06-19 TikTok 오전 출고", "2026-06-19 TikTok 오후 출고".
---
## 5. 파싱 예외 처리
- 필수 컬럼이 없으면 **어떤 컬럼이 없는지** 화면에 표시한다.
- Quantity 가 비면 1 로 처리한다.
- Tracking ID 가 숫자로 읽혀도 문자열로 보존한다(과학표기/`.0` 제거).
- NaN/None 은 빈 문자열로 처리한다.
- 고객 이름/주소/전화 컬럼은 매핑하지 않아 **읽는 즉시 버린다**(미저장).
가능한 헤더(앞뒤 공백·대소문자 무시): Order ID, Package ID, Tracking ID,
Shipping Provider Name, Seller SKU, Product Name, Quantity.
---
## 6. 테스트
박스 묶기/SKU 합산/컬럼 검증 순수 로직 테스트:
```bash
python -m app.modules.dispatch.tests.test_grouping # 앱 의존성 설치 환경에서
```
---
## 7. 기술 메모
- 스택: FastAPI · PostgreSQL(psycopg3) · Jinja2 · 기존 ERP CSS(Bootstrap 미사용,
레포 공통 `erp.css` 재사용) · **openpyxl**(스펙의 pandas 대신, 레포 의존성 경량 유지).
- 코드: `app/modules/dispatch/` (`store.py` 순수 로직 / `parser.py` 엑셀 / `db.py`
DB I/O / `router.py` 라우팅 / `templates/dispatch/` 화면).
- 개인정보 미보관: 스키마에 이름/주소/전화 컬럼 자체가 없다.