From f855fc59161f3f827546e429dff1ebfd5f556303 Mon Sep 17 00:00:00 2001 From: thug0bin Date: Sat, 14 Mar 2026 00:36:57 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20OTC=20=EB=9D=BC=EB=B2=A8=20=ED=94=84?= =?UTF-8?q?=EB=A6=AC=EC=85=8B=20=ED=99=95=EC=9D=B8=20API=20+=20=EC=9D=B8?= =?UTF-8?q?=EC=87=84=20=EC=A1=B0=EA=B1=B4=20=EA=B0=95=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - GET /api/otc-label-check - 바코드 배열로 프리셋 존재 여부 일괄 확인 - 인쇄 API: 프리셋 없으면 인쇄 안 함 (404 반환) - POS 장바구니에서 인쇄 버튼 활성화 판단용 --- backend/app.py | 131 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 87 insertions(+), 44 deletions(-) diff --git a/backend/app.py b/backend/app.py index c0141c6..aed4dde 100644 --- a/backend/app.py +++ b/backend/app.py @@ -7885,50 +7885,15 @@ def api_otc_label_print_by_barcode(barcode): dosage_instruction = preset['dosage_instruction'] or '' usage_tip = preset['usage_tip'] or '' else: - # 프리셋 없음 → MSSQL에서 약품명 조회 - try: - import pyodbc - mssql_conn = pyodbc.connect( - 'DRIVER={ODBC Driver 17 for SQL Server};' - 'SERVER=192.168.0.4\\PM2014;' - 'DATABASE=PM_DRUG;' - 'UID=sa;' - 'PWD=tmddls214!%(;' - 'TrustServerCertificate=yes', - timeout=10 - ) - mssql_cursor = mssql_conn.cursor() - - mssql_cursor.execute(""" - SELECT TOP 1 G.GoodsName - FROM CD_GOODS G - LEFT JOIN CD_ITEM_UNIT_MEMBER U ON G.DrugCode = U.DRUGCODE - WHERE G.BARCODE = ? OR U.CD_CD_BARCODE = ? - """, (barcode, barcode)) - - row = mssql_cursor.fetchone() - mssql_conn.close() - - if row: - drug_name = row.GoodsName - else: - response = jsonify({ - 'success': False, - 'error': f'바코드 {barcode}에 해당하는 제품을 찾을 수 없습니다. 프리셋을 먼저 등록해주세요.' - }) - response.headers['Access-Control-Allow-Origin'] = '*' - return response, 404 - - except Exception as e: - logging.error(f"MSSQL 조회 오류: {e}") - response = jsonify({'success': False, 'error': f'DB 조회 오류: {str(e)}'}) - response.headers['Access-Control-Allow-Origin'] = '*' - return response, 500 - - # 기본값으로 인쇄 (효능/용법 없음) - effect = '' - dosage_instruction = '' - usage_tip = '' + # 프리셋 없음 → 인쇄 안 함 + response = jsonify({ + 'success': False, + 'error': f'바코드 {barcode}에 등록된 라벨 프리셋이 없습니다.', + 'barcode': barcode, + 'has_preset': False + }) + response.headers['Access-Control-Allow-Origin'] = '*' + return response, 404 # 2. 인쇄 실행 success = print_otc_label(drug_name, effect, dosage_instruction, usage_tip) @@ -7976,6 +7941,84 @@ def api_otc_label_print_options(barcode): return response +@app.route('/api/otc-label-check', methods=['GET', 'POST']) +def api_otc_label_check(): + """ + OTC 라벨 프리셋 존재 여부 일괄 확인 API + + GET /api/otc-label-check?barcodes=8806436044814,8806436058613 + POST /api/otc-label-check {"barcodes": ["8806436044814", "8806436058613"]} + + - CORS 지원 (외부에서 호출 가능) + - 장바구니 등에서 인쇄 버튼 활성화 여부 판단용 + """ + try: + # 바코드 목록 파싱 + if request.method == 'POST': + data = request.get_json() or {} + barcodes = data.get('barcodes', []) + else: + barcodes_param = request.args.get('barcodes', '') + barcodes = [b.strip() for b in barcodes_param.split(',') if b.strip()] + + if not barcodes: + response = jsonify({'success': False, 'error': '바코드 목록이 필요합니다'}) + response.headers['Access-Control-Allow-Origin'] = '*' + return response, 400 + + # 프리셋 존재 여부 확인 + conn = db_manager.get_sqlite_connection() + cursor = conn.cursor() + + placeholders = ','.join(['?' for _ in barcodes]) + cursor.execute(f""" + SELECT barcode, display_name + FROM otc_label_presets + WHERE barcode IN ({placeholders}) + """, barcodes) + + preset_map = {row['barcode']: row['display_name'] for row in cursor.fetchall()} + + # 결과 생성 + results = [] + printable_count = 0 + for barcode in barcodes: + has_preset = barcode in preset_map + if has_preset: + printable_count += 1 + results.append({ + 'barcode': barcode, + 'has_preset': has_preset, + 'display_name': preset_map.get(barcode), + 'printable': has_preset + }) + + response = jsonify({ + 'success': True, + 'total': len(barcodes), + 'printable_count': printable_count, + 'results': results + }) + response.headers['Access-Control-Allow-Origin'] = '*' + return response + + except Exception as e: + logging.error(f"OTC 라벨 체크 오류: {e}") + response = jsonify({'success': False, 'error': str(e)}) + response.headers['Access-Control-Allow-Origin'] = '*' + return response, 500 + + +@app.route('/api/otc-label-check', methods=['OPTIONS']) +def api_otc_label_check_options(): + """CORS preflight 요청 처리""" + response = make_response() + response.headers['Access-Control-Allow-Origin'] = '*' + response.headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS' + response.headers['Access-Control-Allow-Headers'] = 'Content-Type' + return response + + @app.route('/api/admin/otc-labels/search-mssql', methods=['GET']) def api_search_mssql_drug(): """MSSQL에서 약품 검색 (바코드 또는 이름)"""