pharmacy-pos-qr-system/docs/SUIN_API_FIX.md
thug0bin 83ecf88bd4 feat(animal-chat): APC 코드 2024년 체계 지원 및 피부약 2단계 추천
## APC 코드 체계 확장
- 기존: 023%만 검색 (~2023년 제품만)
- 변경: 02% OR 92% + 13자리 검증
  - 02%: 2023년 이전 item_seq (9자리) 기반 APC
  - 92%: 2024년 이후 item_seq (10자리) 기반 APC
- 999% 등 청구프로그램 임의코드는 제외

## 동물약 챗봇 피부약 추천 개선
- 피부약 2단계 추천 구조 추가
  - 1차(치료): 의약품 (개시딘겔, 테르비덤 등)
  - 2차(보조케어): 의약외품 (스킨카솔 - 회복기 피부보호)
- 스킨카솔은 의약외품임을 명시하여 치료제로 오인 방지

## 기타
- RAG 테스트 스크립트 추가
- 수인약품 API 문서화
2026-03-11 14:20:44 +09:00

3.6 KiB
Raw Blame History

수인 API 주문 수량 파싱 문제 수정

날짜: 2026-03-09
문제: 라미실크림 15g 주문 시 1개 → 15개로 잘못 표시
원인: parse_spec 함수에서 용량 단위(g, ml)를 정량 단위(T, 정)로 착각

📋 문제 상황

도매상 제품 실제 주문 표시된 수량
동원 라미실크림 15g 1개 1개
수인 라미실크림 15g 1개 15개

🔍 원인 분석

문제 코드 위치

  • 파일: sooin_api.py (Flask Blueprint)
  • API: GET /api/sooin/orders/summary-by-kd
  • 함수: parse_spec()

기존 코드 (문제)

def parse_spec(spec: str) -> int:
    if not spec:
        return 1
    match = re.search(r'(\d+)', spec)
    return int(match.group(1)) if match else 1

문제점: 규격에서 숫자만 추출

  • '30T' → 30 (정제 30정)
  • '15g' → 15 🚨 문제! (튜브 15그램인데 15개로 계산)

계산 과정

수인 라미실크림 15g 1박스 주문
→ quantity = 1
→ per_unit = parse_spec('15g') = 15
→ total_units = 1 × 15 = 15개 ❌

동원 API는 정상인 이유

동원의 parse_spec() (wholesale/dongwon.py:1718-1720):

# mg/ml 등의 용량 단위는 1로 처리
if re.search(r'\d+\s*(mg|ml|g)\b', spec, re.IGNORECASE):
    return 1

수정 내용

수정된 코드

def parse_spec(spec: str) -> int:
    """
    규격에서 박스당 단위 수 추출
    
    정량 단위 (T, 정, 캡슐, C, PTP, 포 등): 숫자 추출
    용량 단위 (g, ml, mL, mg, L 등): 1 반환 (튜브/병 단위)
    
    예시:
    - '30T' → 30 (정제 30정)
    - '100정(PTP)' → 100
    - '15g' → 1 (튜브 1개)
    - '10ml' → 1 (병 1개)
    - '500mg' → 1 (용량 표시)
    """
    if not spec:
        return 1
    
    spec_lower = spec.lower()
    
    # 용량 단위 패턴: 숫자 + g/ml/mg/l (단독 또는 끝)
    # 이 경우 튜브/병 단위이므로 1 반환
    volume_pattern = r'^\d+\s*(g|ml|mg|l)(\s|$|\)|/)'
    if re.search(volume_pattern, spec_lower):
        return 1
    
    # 정량 단위 패턴: 숫자 + T/정/캡슐/C/PTP/포
    qty_pattern = r'(\d+)\s*(t|정|캡슐?|c|ptp|포|tab|cap)'
    qty_match = re.search(qty_pattern, spec_lower)
    if qty_match:
        return int(qty_match.group(1))
    
    # 기본: 숫자만 있으면 추출하되, 용량 단위 재확인
    # 끝에 g/ml이 있으면 1 반환
    if re.search(r'\d+(g|ml)$', spec_lower):
        return 1
    
    # 그 외 숫자 추출
    match = re.search(r'(\d+)', spec)
    return int(match.group(1)) if match else 1

수정 결과

규격 기존 결과 수정 후 결과
'30T' 30 30
'100정(PTP)' 100 100
'15g' 15 1
'10ml' 10 1
'500mg' 500 1

📁 관련 파일

파일 역할
backend/sooin_api.py Flask Blueprint (수정됨)
wholesale/sooin.py 수인약품 핵심 API 클래스
wholesale/dongwon.py 동원약품 API (참고)

🔄 적용 방법

# Flask 서버 재시작
pm2 restart flask-pharmacy

🧪 테스트

# 수인 주문 조회 API 테스트
curl "http://localhost:7001/api/sooin/orders/summary-by-kd?start_date=2026-03-01&end_date=2026-03-09"

📝 참고

  • 도매상 API 문서: docs/WHOLESALE_API_INTEGRATION.md
  • 수인 API 문서: docs/SOOIN_API.md
  • 동원 API: 이미 올바른 parse_spec 로직 적용됨