diff --git a/backend/app.py b/backend/app.py index d7f5a6c..57f40b0 100644 --- a/backend/app.py +++ b/backend/app.py @@ -2672,7 +2672,8 @@ def api_products(): WHEN SET_CHK.is_set = 1 THEN N'세트상품' ELSE '' END as supplier, - CASE WHEN SET_CHK.is_set = 1 THEN 1 ELSE 0 END as is_set + CASE WHEN SET_CHK.is_set = 1 THEN 1 ELSE 0 END as is_set, + G.POS_BOON as pos_boon FROM CD_GOODS G OUTER APPLY ( SELECT TOP 1 CD_CD_BARCODE @@ -2706,7 +2707,8 @@ def api_products(): 'sale_price': float(row.sale_price) if row.sale_price else 0, 'cost_price': float(row.cost_price) if row.cost_price else 0, 'supplier': row.supplier or '', - 'is_set': bool(row.is_set) + 'is_set': bool(row.is_set), + 'is_animal_drug': row.pos_boon == '010103' }) return jsonify({ diff --git a/backend/scripts/tag_animal_drugs.py b/backend/scripts/tag_animal_drugs.py new file mode 100644 index 0000000..a553ed7 --- /dev/null +++ b/backend/scripts/tag_animal_drugs.py @@ -0,0 +1,175 @@ +""" +동물약 태깅 및 MSSQL 동기화 +1. 키워드로 CD_GOODS에서 동물약 검색 +2. SQLite drug_tags.db에 태깅 +3. MSSQL CD_GOODS.POS_BOON = '010103' 업데이트 +""" +import sqlite3 +from pathlib import Path +import sys + +sys.path.insert(0, str(Path(__file__).parent.parent)) +from db.dbsetup import db_manager +from sqlalchemy import text + +# SQLite DB 경로 +DB_PATH = Path(__file__).parent.parent / 'db' / 'drug_tags.db' + +# 동물약 키워드 +ANIMAL_KEYWORDS = [ + '동물', '반려', '애견', '강아지', '고양이', '반려견', + '넥스가드', '브라벡토', '심파리카', '크레델리오', '컴포티스', + '하트세이버', '하트가드', '다이로하트', '하트웜', '하트캅', + '안텔민', '파라캅', '제스타제', + '캐치원', '셀라이트', '가드닐', '리펠로', '심피드독', + '세레니아', '아포퀄', '갈리프란트', '클라펫', + '펫팜', '동물약품', '애니팜' +] + +# 제외 키워드 (사람용 약) +EXCLUDE_KEYWORDS = [ + '헤리펫사', '토피라펫', '메타트레이스', '페리돈', '세파라캅' +] + +def init_sqlite_db(): + """SQLite DB 초기화""" + DB_PATH.parent.mkdir(parents=True, exist_ok=True) + conn = sqlite3.connect(DB_PATH) + cursor = conn.cursor() + + cursor.execute(''' + CREATE TABLE IF NOT EXISTS drug_tags ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + drug_code TEXT NOT NULL, + drug_name TEXT, + barcode TEXT, + tag_type TEXT NOT NULL, + tag_value TEXT, + note TEXT, + source TEXT DEFAULT 'keyword', + confidence REAL DEFAULT 0.8, + is_active BOOLEAN DEFAULT 1, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + UNIQUE(drug_code, tag_type) + ) + ''') + conn.commit() + conn.close() + print(f"✅ SQLite DB 준비: {DB_PATH}") + +def search_animal_drugs(): + """MSSQL에서 동물약 키워드 검색""" + print("🔍 CD_GOODS에서 동물약 검색 중...") + + session = db_manager.get_session('PM_DRUG') + + # 키워드 조건 생성 + conditions = ' OR '.join([f"GoodsName LIKE '%{kw}%'" for kw in ANIMAL_KEYWORDS]) + + query = text(f""" + SELECT DrugCode, GoodsName, BARCODE, POS_BOON + FROM CD_GOODS + WHERE ({conditions}) + AND GoodsSelCode = 'B' + """) + + result = session.execute(query) + drugs = result.fetchall() + print(f"✅ 발견: {len(drugs)}개") + return drugs + +def tag_to_sqlite(drugs): + """SQLite에 동물약 태깅""" + print("\n📝 SQLite 태깅 중...") + + conn = sqlite3.connect(DB_PATH) + cursor = conn.cursor() + + added = 0 + skipped = 0 + excluded = 0 + + for drug in drugs: + drug_code = drug[0] + drug_name = drug[1] or '' + barcode = drug[2] + + # 제외 키워드 체크 + if any(ex in drug_name for ex in EXCLUDE_KEYWORDS): + excluded += 1 + print(f" ⛔ 제외: {drug_code} - {drug_name}") + continue + + try: + cursor.execute(''' + INSERT INTO drug_tags (drug_code, drug_name, barcode, tag_type, tag_value, note) + VALUES (?, ?, ?, 'animal_drug', 'all', '키워드 자동 태깅') + ''', (drug_code, drug_name, barcode)) + added += 1 + print(f" ✅ {drug_code}: {drug_name}") + except sqlite3.IntegrityError: + skipped += 1 + + conn.commit() + conn.close() + + print(f"\n📊 태깅 결과: 추가 {added}개, 중복 {skipped}개, 제외 {excluded}개") + return added + +def sync_to_mssql(): + """SQLite 태그를 MSSQL POS_BOON에 동기화""" + print("\n🔄 MSSQL 동기화 중...") + + # SQLite에서 동물약 목록 가져오기 + conn = sqlite3.connect(DB_PATH) + cursor = conn.cursor() + cursor.execute(''' + SELECT drug_code, drug_name FROM drug_tags + WHERE tag_type = 'animal_drug' AND is_active = 1 + ''') + animal_drugs = cursor.fetchall() + conn.close() + + print(f" 동물약 {len(animal_drugs)}개 → POS_BOON='010103' 업데이트") + + # MSSQL 업데이트 + session = db_manager.get_session('PM_DRUG') + updated = 0 + + for drug_code, drug_name in animal_drugs: + try: + result = session.execute(text(''' + UPDATE CD_GOODS SET POS_BOON = '010103' WHERE DrugCode = :dc + '''), {'dc': drug_code}) + session.commit() + if result.rowcount > 0: + updated += 1 + print(f" ✅ {drug_code}: {drug_name}") + except Exception as e: + print(f" ❌ {drug_code}: {e}") + + print(f"\n🎉 완료! MSSQL 업데이트: {updated}개") + +def main(): + print("=" * 50) + print("🐾 동물약 태깅 시스템") + print("=" * 50) + + # 1. SQLite 초기화 + init_sqlite_db() + + # 2. 동물약 검색 + drugs = search_animal_drugs() + + # 3. SQLite 태깅 + tag_to_sqlite(drugs) + + # 4. MSSQL 동기화 + sync_to_mssql() + + print("\n" + "=" * 50) + print("✅ 모든 작업 완료!") + print("=" * 50) + +if __name__ == '__main__': + main() diff --git a/backend/templates/admin_products.html b/backend/templates/admin_products.html index 691d5ce..dcd6144 100644 --- a/backend/templates/admin_products.html +++ b/backend/templates/admin_products.html @@ -469,7 +469,10 @@ tbody.innerHTML = productsData.map((item, idx) => `