- wholesale 패키지 연동 (SooinSession, GeoYoungSession) - Flask Blueprint 분리 (sooin_api.py, geoyoung_api.py) - order_context 스키마 확장 (wholesaler_id, internal_code 등) - 수인약품 개별 취소 기능 (cancel_item, restore_item) - 문서 추가: WHOLESALE_API_INTEGRATION.md - 테스트 스크립트들
190 lines
5.1 KiB
Markdown
190 lines
5.1 KiB
Markdown
# 도매상 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 | **항목 취소** (신규) |
|
|
| POST | /cart/restore | **항목 복원** (신규) |
|
|
| POST | /confirm | 주문 전송 |
|
|
|
|
### 지오영 (/api/geoyoung/*)
|
|
|
|
| 메서드 | 경로 | 설명 |
|
|
|--------|------|------|
|
|
| GET | /stock | 재고 검색 |
|
|
| GET | /cart | 장바구니 조회 |
|
|
| POST | /order | 장바구니 추가 |
|
|
| POST | /cart/clear | 장바구니 비우기 |
|
|
| POST | /confirm | 주문 전송 |
|
|
|
|
---
|
|
|
|
## 📁 관련 문서
|
|
|
|
| 문서 | 위치 | 내용 |
|
|
|------|------|------|
|
|
| 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] 개별 취소 기능 (수인)
|
|
- [x] Flask Blueprint 통합
|
|
- [x] wholesale 패키지 분리
|
|
- [x] SQLite 스키마 업데이트
|
|
|
|
### 진행 예정
|
|
- [ ] daily_usage 자동 수집
|
|
- [ ] AI 규격 선택 모델
|
|
- [ ] AI 도매상 선택 모델
|
|
- [ ] 자동 주문 Level 1 (승인 후 실행)
|
|
|
|
---
|
|
|
|
*업데이트: 2026-03-06 by 용림 🐉*
|