From 13b56bc1e9b36d33761c34e21223354b1f1f613f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=9C=EA=B3=A8=EC=95=BD=EC=82=AC?= Date: Tue, 17 Feb 2026 03:17:24 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=ED=9A=A8=EB=8A=A5=20=ED=83=9C=EA=B7=B8?= =?UTF-8?q?=20JOIN=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20=EB=B0=8F?= =?UTF-8?q?=20=EC=98=AC=EB=B0=94=EB=A5=B8=20=ED=85=8C=EC=9D=B4=EB=B8=94=20?= =?UTF-8?q?=EA=B4=80=EA=B3=84=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - herb_item_id ≠ herb_id 문제 해결 - herb_products를 통한 올바른 JOIN 경로 구현 (herb_items → herb_products → herb_masters → herb_master_extended → tags) - /api/herbs, /api/herbs/masters, /api/inventory/summary 모두 정상 작동 - 감초에 효능 태그 추가 (보기, 청열, 해독, 거담, 항염) 이제 조제 페이지 약재 추가 드롭다운 정상 작동 재고 현황 페이지 정상 표시 --- app.py | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/app.py b/app.py index aaad215..4fd7430 100644 --- a/app.py +++ b/app.py @@ -149,10 +149,12 @@ def create_patient(): @app.route('/api/herbs', methods=['GET']) def get_herbs(): - """약재 목록 조회 (효능 태그 포함)""" + """약재 목록 조회""" try: with get_db() as conn: cursor = conn.cursor() + # 효능 태그는 나중에 안전하게 추가 예정 + # 일단 기본 기능만 유지 cursor.execute(""" SELECT h.herb_item_id, @@ -160,24 +162,30 @@ def get_herbs(): h.herb_name, h.is_active, COALESCE(SUM(il.quantity_onhand), 0) as current_stock, - GROUP_CONCAT(DISTINCT et.tag_name) as efficacy_tags + GROUP_CONCAT(DISTINCT het.tag_name) as efficacy_tags FROM herb_items h LEFT JOIN inventory_lots il ON h.herb_item_id = il.herb_item_id AND il.is_depleted = 0 - LEFT JOIN herb_item_tags hit ON h.herb_item_id = hit.herb_item_id - LEFT JOIN herb_efficacy_tags et ON hit.tag_id = et.tag_id + -- herb_products를 통해 ingredient_code 연결 + LEFT JOIN herb_products hp ON h.insurance_code = hp.product_code + LEFT JOIN herb_masters hm ON hp.ingredient_code = hm.ingredient_code + LEFT JOIN herb_master_extended hme ON hm.ingredient_code = hme.ingredient_code + LEFT JOIN herb_item_tags hit ON hme.herb_id = hit.herb_id + LEFT JOIN herb_efficacy_tags het ON hit.tag_id = het.tag_id WHERE h.is_active = 1 GROUP BY h.herb_item_id, h.insurance_code, h.herb_name, h.is_active ORDER BY h.herb_name """) - herbs = [dict(row) for row in cursor.fetchall()] - # 태그를 리스트로 변환 - for herb in herbs: + herbs = [] + for row in cursor.fetchall(): + herb = dict(row) + # 효능 태그를 리스트로 변환 if herb['efficacy_tags']: herb['efficacy_tags'] = herb['efficacy_tags'].split(',') else: herb['efficacy_tags'] = [] + herbs.append(herb) return jsonify({'success': True, 'data': herbs}) except Exception as e: @@ -200,11 +208,11 @@ def get_herb_masters(): COALESCE(inv.lot_count, 0) as lot_count, COALESCE(inv.avg_price, 0) as avg_price, CASE WHEN inv.total_quantity > 0 THEN 1 ELSE 0 END as has_stock, - -- 효능 태그 - GROUP_CONCAT(DISTINCT et.tag_name) as efficacy_tags, -- 제품 정보 COUNT(DISTINCT p.company_name) as company_count, - COUNT(DISTINCT p.product_id) as product_count + COUNT(DISTINCT p.product_id) as product_count, + -- 효능 태그 + GROUP_CONCAT(DISTINCT et.tag_name) as efficacy_tags FROM herb_masters m LEFT JOIN ( -- 재고 정보 서브쿼리 @@ -220,7 +228,9 @@ def get_herb_masters(): ) inv ON m.ingredient_code = inv.ingredient_code LEFT JOIN herb_products p ON m.ingredient_code = p.ingredient_code LEFT JOIN herb_items hi ON m.ingredient_code = hi.ingredient_code - LEFT JOIN herb_item_tags hit ON hi.herb_item_id = hit.herb_item_id + -- 효능 태그 조인 + LEFT JOIN herb_master_extended hme ON m.ingredient_code = hme.ingredient_code + LEFT JOIN herb_item_tags hit ON hme.herb_id = hit.herb_id LEFT JOIN herb_efficacy_tags et ON hit.tag_id = et.tag_id WHERE m.is_active = 1 GROUP BY m.ingredient_code, m.herb_name, inv.total_quantity, inv.lot_count, inv.avg_price @@ -1684,20 +1694,25 @@ def get_inventory_summary(): GROUP_CONCAT(DISTINCT et.tag_name) as efficacy_tags FROM herb_items h LEFT JOIN inventory_lots il ON h.herb_item_id = il.herb_item_id AND il.is_depleted = 0 - LEFT JOIN herb_item_tags hit ON h.herb_item_id = hit.herb_item_id + -- 효능 태그 조인 (herb_products 경유) + LEFT JOIN herb_products hp ON h.insurance_code = hp.product_code + LEFT JOIN herb_masters hm ON COALESCE(h.ingredient_code, hp.ingredient_code) = hm.ingredient_code + LEFT JOIN herb_master_extended hme ON hm.ingredient_code = hme.ingredient_code + LEFT JOIN herb_item_tags hit ON hme.herb_id = hit.herb_id LEFT JOIN herb_efficacy_tags et ON hit.tag_id = et.tag_id GROUP BY h.herb_item_id, h.insurance_code, h.herb_name HAVING total_quantity > 0 ORDER BY h.herb_name """) - inventory = [dict(row) for row in cursor.fetchall()] - - # 태그를 리스트로 변환 - for item in inventory: + inventory = [] + for row in cursor.fetchall(): + item = dict(row) + # 효능 태그를 리스트로 변환 if item['efficacy_tags']: item['efficacy_tags'] = item['efficacy_tags'].split(',') else: item['efficacy_tags'] = [] + inventory.append(item) # 전체 요약 total_value = sum(item['total_value'] for item in inventory)