# -*- 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)