# 도매상 API 통합 가이드

> 작성일: 2026-03-06  
> 버전: 1.0

## 📦 패키지 구조

```
pharmacy-wholesale-api/           # 별도 리포지토리
├── wholesale/
│   ├── __init__.py              # SooinSession, GeoYoungSession 노출
│   ├── base.py                  # WholesaleSession 공통 인터페이스
│   ├── sooin.py                 # 수인약품 API
│   └── geoyoung.py              # 지오영 API
└── docs/
    └── SOOIN.md                 # 수인약품 상세 문서

pharmacy-pos-qr-system/backend/   # 기존 프로젝트
├── wholesale_path.py            # 패키지 경로 설정
├── sooin_api.py                 # Flask Blueprint (wholesale 사용)
└── geoyoung_api.py              # Flask Blueprint (wholesale 사용)
```

---

## 🔌 도매상별 API 특성

| 항목 | 지오영 | 수인약품 |
|------|--------|----------|
| 웹사이트 | gwn.geoweb.kr | sooinpharm.co.kr |
| 인증 방식 | Playwright → requests | Playwright → requests |
| 세션 유효시간 | 30분 | 30분 |
| 검색 코드 | 보험코드 (KD) | KD코드 + 내부코드 (pc) |
| 장바구니 추가 | productCode 필요 | internal_code (pc) 필요 |
| **개별 삭제** | ❌ 없음 | ✅ 체크박스 soft delete |
| 장바구니 조회 | PartialProductCart | Bag.asp |

---

## 🔑 핵심 발견: 코드 체계

### 지오영
```
보험코드 (KD코드) → 검색 → productCode (내부) → 장바구니 추가
```

### 수인약품
```
KD코드 → 검색 → internal_code (pc) → 장바구니 추가
                     ↓
              PhysicInfo.asp?pc=32495 에서 추출
```

**⚠️ 중요:** `internal_code`가 없으면 장바구니 추가 불가!

---

## 🛒 수인약품 개별 취소 (Soft Delete)

### 발견 과정
- `kind=delOne` API 존재하지만 작동 안 함
- 체크박스가 실제 "취소" 역할
- `ControlBag.asp` AJAX 엔드포인트 발견

### API 사용법
```python
from wholesale import SooinSession

session = SooinSession()
session.login()

# 장바구니 조회 (체크 상태 포함)
cart = session.get_cart()
# cart['items'][0]['checked'] = False (활성)
# cart['items'][0]['active'] = True

# 항목 취소 (체크)
session.cancel_item(row_index=0)
# 또는
session.cancel_item(product_code="32495")

# 취소 복원 (체크 해제)
session.restore_item(row_index=0)
```

### 내부 동작
```
POST /Service/Order/ControlBag.asp
Content-Type: application/x-www-form-urlencoded; charset=euc-kr
X-Requested-With: XMLHttpRequest

vc=50911        (거래처코드)
pc=32495        (내부 제품코드)
f=true          (true=취소, false=복원)
pg=             (제품구분, 빈값)
pdno=           (제품번호, 빈값)
tmdt=           (기한, 빈값)
```

---

## 📊 SQLite 스키마 연동

### order_context (AI 학습용)

```sql
-- 새로 추가된 필드 (2026-03-06)
wholesaler_id TEXT,        -- 'geoyoung' 또는 'sooin'
wholesaler_price INTEGER,  -- 도매상 가격
internal_code TEXT,        -- 도매상 내부 코드
was_cancelled BOOLEAN,     -- 취소 여부 (수인 soft delete)
```

### 도매상별 주문 시 기록할 데이터

```python
order_context = {
    'drug_code': 'D12345',
    'product_name': '아세탑정',
    'wholesaler_id': 'sooin',
    'internal_code': '32495',        # 수인 내부코드
    'ordered_spec': '30T',
    'ordered_qty': 2,
    'wholesaler_price': 4800,
    'available_specs': '["30T", "500T"]',
    'spec_stocks': '{"30T": 0, "500T": 0}',  # 재고 상황
    'selection_reason': 'only_option',
    'was_cancelled': False
}
```

---

## 🔄 Flask API 엔드포인트

### 수인약품 (/api/sooin/*)

| 메서드 | 경로 | 설명 |
|--------|------|------|
| GET | /stock | 재고 검색 |
| GET | /cart | 장바구니 조회 |
| POST | /order | 장바구니 추가 |
| POST | /cart/clear | 장바구니 비우기 |
| POST | /cart/cancel | **항목 취소 (soft delete)** |
| POST | /cart/restore | **항목 복원** |
| POST | /confirm | 주문 전송 |

### 지오영 (/api/geoyoung/*)

| 메서드 | 경로 | 설명 |
|--------|------|------|
| GET | /stock | 재고 검색 |
| GET | /cart | 장바구니 조회 |
| POST | /order | 장바구니 추가 |
| POST | /cart/clear | 장바구니 비우기 |
| POST | /cart/cancel | **항목 삭제 (hard delete)** |
| POST | /cart/restore | ❌ NOT_SUPPORTED |
| POST | /confirm | 주문 전송 |

### 개별 삭제 API 차이

| 도매상 | cancel 동작 | restore 가능 | 내부 API |
|--------|-------------|-------------|----------|
| 수인 | 체크박스 soft delete | ✅ 가능 | ControlBag.asp |
| 지오영 | 완전 삭제 | ❌ 불가 | DataCart/del |

---

## 📁 관련 문서

| 문서 | 위치 | 내용 |
|------|------|------|
| AI ERP 자동주문 기획 | `docs/AI_ERP_AUTO_ORDER_SYSTEM.md` | 전체 시스템 설계 |
| 지오영 API 분석 | `docs/GEOYOUNG_API_REVERSE_ENGINEERING.md` | 지오영 리버스 엔지니어링 |
| 수인 API 분석 | `pharmacy-wholesale-api/docs/SOOIN.md` | 수인 리버스 엔지니어링 |
| 사용량 조회 가이드 | `docs/RX_USAGE_GEOYOUNG_GUIDE.md` | 처방 사용량 조회 |

---

## ✅ 체크리스트

### 완료
- [x] 지오영 API 연동
- [x] 수인약품 API 연동
- [x] 개별 취소 기능 (수인) - soft delete
- [x] 개별 삭제 기능 (지오영) - hard delete
- [x] Flask Blueprint 통합
- [x] wholesale 패키지 분리
- [x] SQLite 스키마 업데이트

### 진행 예정
- [ ] daily_usage 자동 수집
- [ ] AI 규격 선택 모델
- [ ] AI 도매상 선택 모델
- [ ] 자동 주문 Level 1 (승인 후 실행)

---

*업데이트: 2026-03-06 by 용림 🐉*
