pharmacy-pos-qr-system/backend/baekje_api.py
thug0bin 241e65aaf1 feat: 백제약품 잔고 API 엔드포인트 추가
GET /api/baekje/balance - 잔고액 조회
2026-03-06 15:00:15 +09:00

263 lines
6.6 KiB
Python

# -*- coding: utf-8 -*-
"""
백제약품 도매상 API - Flask Blueprint
핵심 로직은 wholesale 패키지에서 가져옴
이 파일은 Flask 웹 API 연동만 담당
"""
import time
import logging
from flask import Blueprint, jsonify, request as flask_request
# wholesale 패키지 경로 설정
import wholesale_path
# wholesale 패키지에서 핵심 클래스 가져오기
from wholesale import BaekjeSession
logger = logging.getLogger(__name__)
# Blueprint 생성
baekje_bp = Blueprint('baekje', __name__, url_prefix='/api/baekje')
# ========== 세션 관리 ==========
_baekje_session = None
_init_started = False
def get_baekje_session():
global _baekje_session
if _baekje_session is None:
_baekje_session = BaekjeSession()
return _baekje_session
def init_baekje_session():
"""앱 시작 시 백그라운드에서 로그인 시작"""
global _init_started
if _init_started:
return
_init_started = True
session = get_baekje_session()
# 저장된 토큰이 있으면 즉시 사용 가능
if session._logged_in:
logger.info(f"백제약품: 저장된 토큰 사용 중")
return
# 백그라운드 로그인 시작
session.start_background_login()
logger.info(f"백제약품: 백그라운드 로그인 시작됨")
# 모듈 로드 시 자동 시작
try:
init_baekje_session()
except Exception as e:
logger.warning(f"백제약품 초기화 오류: {e}")
def search_baekje_stock(keyword: str):
"""백제약품 재고 검색"""
try:
session = get_baekje_session()
result = session.search_products(keyword)
if result.get('success'):
return {
'success': True,
'keyword': keyword,
'count': result['total'],
'items': result['items']
}
else:
return result
except Exception as e:
logger.error(f"백제약품 검색 오류: {e}")
return {'success': False, 'error': 'SEARCH_ERROR', 'message': str(e)}
# ========== Flask API Routes ==========
@baekje_bp.route('/stock', methods=['GET'])
def api_baekje_stock():
"""
백제약품 재고 조회 API
GET /api/baekje/stock?kd_code=672300240
GET /api/baekje/stock?keyword=타이레놀
"""
kd_code = flask_request.args.get('kd_code', '').strip()
keyword = flask_request.args.get('keyword', '').strip()
search_term = kd_code or keyword
if not search_term:
return jsonify({
'success': False,
'error': 'MISSING_PARAM',
'message': 'kd_code 또는 keyword 파라미터가 필요합니다'
}), 400
try:
result = search_baekje_stock(search_term)
return jsonify(result)
except Exception as e:
logger.error(f"백제약품 API 오류: {e}")
return jsonify({
'success': False,
'error': 'API_ERROR',
'message': str(e)
}), 500
@baekje_bp.route('/session-status', methods=['GET'])
def api_session_status():
"""세션 상태 확인"""
session = get_baekje_session()
return jsonify({
'success': True,
'wholesaler': 'baekje',
'name': '백제약품',
'logged_in': session._logged_in,
'last_login': session._last_login,
'session_timeout': session.SESSION_TIMEOUT
})
@baekje_bp.route('/login', methods=['POST'])
def api_login():
"""수동 로그인"""
session = get_baekje_session()
success = session.login()
return jsonify({
'success': success,
'message': '로그인 성공' if success else '로그인 실패'
})
@baekje_bp.route('/cart', methods=['GET'])
def api_get_cart():
"""장바구니 조회"""
session = get_baekje_session()
result = session.get_cart()
return jsonify(result)
@baekje_bp.route('/cart', methods=['POST'])
def api_add_to_cart():
"""
장바구니 추가
POST /api/baekje/cart
{
"product_code": "672300240",
"quantity": 2
}
"""
data = flask_request.get_json() or {}
product_code = data.get('product_code', '').strip()
quantity = int(data.get('quantity', 1))
if not product_code:
return jsonify({
'success': False,
'error': 'MISSING_PARAM',
'message': 'product_code 필요'
}), 400
session = get_baekje_session()
result = session.add_to_cart(product_code, quantity)
return jsonify(result)
@baekje_bp.route('/order', methods=['POST'])
def api_submit_order():
"""
주문 등록
POST /api/baekje/order
{
"memo": "긴급 요청"
}
"""
data = flask_request.get_json() or {}
memo = data.get('memo', '')
session = get_baekje_session()
result = session.submit_order(memo)
return jsonify(result)
# ========== 프론트엔드 통합용 ==========
@baekje_bp.route('/search-for-order', methods=['POST'])
def api_search_for_order():
"""
발주용 재고 검색 (프론트엔드 통합용)
POST /api/baekje/search-for-order
{
"kd_code": "672300240",
"product_name": "타이레놀",
"specification": "500T"
}
"""
data = flask_request.get_json() or {}
kd_code = data.get('kd_code', '').strip()
product_name = data.get('product_name', '').strip()
specification = data.get('specification', '').strip()
search_term = kd_code or product_name
if not search_term:
return jsonify({
'success': False,
'error': 'MISSING_PARAM'
}), 400
result = search_baekje_stock(search_term)
if result.get('success') and specification:
# 규격 필터링
filtered = [
item for item in result.get('items', [])
if specification.lower() in item.get('spec', '').lower()
]
result['items'] = filtered
result['count'] = len(filtered)
return jsonify(result)
# ========== 잔고 조회 ==========
@baekje_bp.route('/balance', methods=['GET'])
def api_get_balance():
"""
잔고액 조회
GET /api/baekje/balance
GET /api/baekje/balance?year=2026
Returns:
{
"success": true,
"balance": 14193234,
"monthly": [
{"month": "2026-03", "sales": 6935133, "balance": 14193234, ...},
{"month": "2026-02", "sales": 18600692, "balance": 7258101, ...}
]
}
"""
year = flask_request.args.get('year', '').strip()
session = get_baekje_session()
result = session.get_balance(year if year else None)
return jsonify(result)