- PS_sub_pharm.DrugCode → PM_DRUG.CD_GOODS.GoodsName - 용량(QUAN), 횟수(QUAN_TIME), 일수(Days) 매핑
322 lines
12 KiB
Python
322 lines
12 KiB
Python
# pmr_api.py - 조제관리(PMR) Blueprint API
|
|
# PharmaIT3000 MSSQL 연동 (192.168.0.4)
|
|
|
|
from flask import Blueprint, jsonify, request, render_template
|
|
import pyodbc
|
|
from datetime import datetime, date
|
|
import logging
|
|
|
|
pmr_bp = Blueprint('pmr', __name__, url_prefix='/pmr')
|
|
|
|
# ─────────────────────────────────────────────────────────────
|
|
# MSSQL 연결 설정 (PharmaIT3000 - 192.168.0.4)
|
|
# ─────────────────────────────────────────────────────────────
|
|
MSSQL_CONFIG = {
|
|
'server': '192.168.0.4\\PM2014',
|
|
'username': 'sa',
|
|
'password': 'tmddls214!%(',
|
|
'driver': 'ODBC Driver 17 for SQL Server'
|
|
}
|
|
|
|
def get_mssql_connection(database='PM_PRES'):
|
|
"""MSSQL 연결 획득"""
|
|
conn_str = (
|
|
f"DRIVER={{{MSSQL_CONFIG['driver']}}};"
|
|
f"SERVER={MSSQL_CONFIG['server']};"
|
|
f"DATABASE={database};"
|
|
f"UID={MSSQL_CONFIG['username']};"
|
|
f"PWD={MSSQL_CONFIG['password']};"
|
|
"TrustServerCertificate=yes;"
|
|
"Connection Timeout=10"
|
|
)
|
|
return pyodbc.connect(conn_str, timeout=10)
|
|
|
|
|
|
# ─────────────────────────────────────────────────────────────
|
|
# 조제관리 페이지
|
|
# ─────────────────────────────────────────────────────────────
|
|
@pmr_bp.route('/')
|
|
def pmr_index():
|
|
"""조제관리 메인 페이지"""
|
|
return render_template('pmr.html')
|
|
|
|
|
|
# ─────────────────────────────────────────────────────────────
|
|
# API: 날짜별 처방전 목록
|
|
# ─────────────────────────────────────────────────────────────
|
|
@pmr_bp.route('/api/prescriptions', methods=['GET'])
|
|
def get_prescriptions_by_date():
|
|
"""
|
|
날짜별 처방전 목록 조회
|
|
Query Params:
|
|
- date: YYYY-MM-DD (기본값: 오늘)
|
|
"""
|
|
try:
|
|
date_str = request.args.get('date', date.today().strftime('%Y-%m-%d'))
|
|
# YYYYMMDD 형식으로 변환
|
|
date_yyyymmdd = date_str.replace('-', '')
|
|
|
|
conn = get_mssql_connection('PM_PRES')
|
|
cursor = conn.cursor()
|
|
|
|
cursor.execute("""
|
|
SELECT
|
|
PreSerial,
|
|
Day_Serial,
|
|
PassDay,
|
|
Paname,
|
|
PaNum,
|
|
CusCode,
|
|
InsName,
|
|
Drname,
|
|
PresTime,
|
|
PreGubun,
|
|
PRICE_T,
|
|
PRICE_P,
|
|
PRICE_C
|
|
FROM PS_MAIN
|
|
WHERE PassDay = ?
|
|
ORDER BY Day_Serial ASC
|
|
""", (date_yyyymmdd,))
|
|
|
|
prescriptions = []
|
|
for row in cursor.fetchall():
|
|
# 주민번호에서 나이/성별 추출
|
|
panum = row.PaNum or ''
|
|
age = None
|
|
gender = None
|
|
if len(panum) >= 7:
|
|
try:
|
|
birth_year = int(panum[:2])
|
|
gender_code = panum[6] if len(panum) > 6 else ''
|
|
|
|
# 성별 및 세기 판단
|
|
if gender_code in ['1', '2', '5', '6']:
|
|
birth_year += 1900
|
|
elif gender_code in ['3', '4', '7', '8']:
|
|
birth_year += 2000
|
|
else:
|
|
birth_year += 1900
|
|
|
|
gender = '남' if gender_code in ['1', '3', '5', '7'] else '여'
|
|
age = datetime.now().year - birth_year
|
|
except:
|
|
pass
|
|
|
|
prescriptions.append({
|
|
'prescription_id': row.PreSerial,
|
|
'order_number': row.Day_Serial,
|
|
'date': row.PassDay,
|
|
'patient_name': row.Paname,
|
|
'patient_id': row.PaNum[:6] + '******' if row.PaNum and len(row.PaNum) > 6 else row.PaNum,
|
|
'patient_code': row.CusCode,
|
|
'hospital': row.InsName,
|
|
'doctor': row.Drname,
|
|
'time': row.PresTime,
|
|
'type': '급여' if row.PreGubun == '0' else '비급여' if row.PreGubun == '9' else row.PreGubun,
|
|
'age': age,
|
|
'gender': gender,
|
|
'price_total': row.PRICE_T,
|
|
'price_patient': row.PRICE_P,
|
|
'price_claim': row.PRICE_C
|
|
})
|
|
|
|
conn.close()
|
|
|
|
return jsonify({
|
|
'success': True,
|
|
'date': date_str,
|
|
'count': len(prescriptions),
|
|
'prescriptions': prescriptions
|
|
})
|
|
|
|
except Exception as e:
|
|
logging.error(f"PMR 처방전 목록 조회 오류: {e}")
|
|
return jsonify({'success': False, 'error': str(e)}), 500
|
|
|
|
|
|
# ─────────────────────────────────────────────────────────────
|
|
# API: 처방전 상세 (약품 목록)
|
|
# ─────────────────────────────────────────────────────────────
|
|
@pmr_bp.route('/api/prescription/<prescription_id>', methods=['GET'])
|
|
def get_prescription_detail(prescription_id):
|
|
"""
|
|
처방전 상세 정보 (약품 목록 포함)
|
|
"""
|
|
try:
|
|
conn = get_mssql_connection('PM_PRES')
|
|
cursor = conn.cursor()
|
|
|
|
# 처방전 기본 정보
|
|
cursor.execute("""
|
|
SELECT
|
|
PreSerial,
|
|
Day_Serial,
|
|
PassDay,
|
|
Paname,
|
|
PaNum,
|
|
CusCode,
|
|
InsName,
|
|
Drname,
|
|
PresTime,
|
|
PreGubun,
|
|
PRICE_T,
|
|
PRICE_P,
|
|
PRICE_C
|
|
FROM PS_MAIN
|
|
WHERE PreSerial = ?
|
|
""", (prescription_id,))
|
|
|
|
rx_row = cursor.fetchone()
|
|
if not rx_row:
|
|
conn.close()
|
|
return jsonify({'success': False, 'error': '처방전을 찾을 수 없습니다'}), 404
|
|
|
|
# 처방 약품 목록 (PS_sub_pharm + PM_DRUG.CD_GOODS JOIN)
|
|
medications = []
|
|
cursor.execute("""
|
|
SELECT
|
|
s.DrugCode,
|
|
s.Days,
|
|
s.QUAN,
|
|
s.QUAN_TIME,
|
|
s.PS_Type,
|
|
s.INV_QUAN,
|
|
g.GoodsName,
|
|
g.SUNG_CODE
|
|
FROM PS_sub_pharm s
|
|
LEFT JOIN PM_DRUG.dbo.CD_GOODS g ON s.DrugCode = g.DrugCode
|
|
WHERE s.PreSerial = ?
|
|
ORDER BY s.SUB_SERIAL
|
|
""", (prescription_id,))
|
|
|
|
for row in cursor.fetchall():
|
|
medications.append({
|
|
'medication_code': row.DrugCode or '',
|
|
'med_name': row.GoodsName or row.DrugCode or '',
|
|
'dosage': float(row.QUAN) if row.QUAN else 0,
|
|
'frequency': row.QUAN_TIME or 0,
|
|
'duration': row.Days or 0,
|
|
'total_qty': float(row.INV_QUAN) if row.INV_QUAN else 0,
|
|
'type': '급여' if row.PS_Type in ['0', '4'] else '비급여' if row.PS_Type == '1' else row.PS_Type,
|
|
'sung_code': row.SUNG_CODE or ''
|
|
})
|
|
|
|
conn.close()
|
|
|
|
# 나이/성별 계산
|
|
panum = rx_row.PaNum or ''
|
|
age = None
|
|
gender = None
|
|
if len(panum) >= 7:
|
|
try:
|
|
birth_year = int(panum[:2])
|
|
gender_code = panum[6]
|
|
if gender_code in ['1', '2', '5', '6']:
|
|
birth_year += 1900
|
|
elif gender_code in ['3', '4', '7', '8']:
|
|
birth_year += 2000
|
|
gender = '남' if gender_code in ['1', '3', '5', '7'] else '여'
|
|
age = datetime.now().year - birth_year
|
|
except:
|
|
pass
|
|
|
|
return jsonify({
|
|
'success': True,
|
|
'prescription': {
|
|
'prescription_id': rx_row.PreSerial,
|
|
'order_number': rx_row.Day_Serial,
|
|
'date': rx_row.PassDay,
|
|
'time': rx_row.PresTime,
|
|
'hospital': rx_row.InsName,
|
|
'doctor': rx_row.Drname,
|
|
'type': '급여' if rx_row.PreGubun == '0' else '비급여',
|
|
'price_total': rx_row.PRICE_T,
|
|
'price_patient': rx_row.PRICE_P
|
|
},
|
|
'patient': {
|
|
'name': rx_row.Paname,
|
|
'code': rx_row.CusCode,
|
|
'age': age,
|
|
'gender': gender
|
|
},
|
|
'medications': medications,
|
|
'medication_count': len(medications)
|
|
})
|
|
|
|
except Exception as e:
|
|
logging.error(f"PMR 처방전 상세 조회 오류: {e}")
|
|
return jsonify({'success': False, 'error': str(e)}), 500
|
|
|
|
|
|
# ─────────────────────────────────────────────────────────────
|
|
# API: 통계 (당일 요약)
|
|
# ─────────────────────────────────────────────────────────────
|
|
@pmr_bp.route('/api/stats', methods=['GET'])
|
|
def get_daily_stats():
|
|
"""당일 조제 통계"""
|
|
try:
|
|
date_str = request.args.get('date', date.today().strftime('%Y-%m-%d'))
|
|
date_yyyymmdd = date_str.replace('-', '')
|
|
|
|
conn = get_mssql_connection('PM_PRES')
|
|
cursor = conn.cursor()
|
|
|
|
# 처방전 수
|
|
cursor.execute("""
|
|
SELECT COUNT(*) as cnt
|
|
FROM PS_MAIN
|
|
WHERE PassDay = ?
|
|
""", (date_yyyymmdd,))
|
|
total_prescriptions = cursor.fetchone()[0]
|
|
|
|
# 총 금액
|
|
cursor.execute("""
|
|
SELECT
|
|
ISNULL(SUM(PRICE_T), 0) as total,
|
|
ISNULL(SUM(PRICE_P), 0) as patient,
|
|
ISNULL(SUM(PRICE_C), 0) as claim
|
|
FROM PS_MAIN
|
|
WHERE PassDay = ?
|
|
""", (date_yyyymmdd,))
|
|
price_row = cursor.fetchone()
|
|
|
|
conn.close()
|
|
|
|
return jsonify({
|
|
'success': True,
|
|
'date': date_str,
|
|
'stats': {
|
|
'total_prescriptions': total_prescriptions,
|
|
'total_amount': price_row[0] if price_row else 0,
|
|
'patient_amount': price_row[1] if price_row else 0,
|
|
'claim_amount': price_row[2] if price_row else 0
|
|
}
|
|
})
|
|
|
|
except Exception as e:
|
|
logging.error(f"PMR 통계 조회 오류: {e}")
|
|
return jsonify({'success': False, 'error': str(e)}), 500
|
|
|
|
|
|
# ─────────────────────────────────────────────────────────────
|
|
# API: DB 연결 테스트
|
|
# ─────────────────────────────────────────────────────────────
|
|
@pmr_bp.route('/api/test', methods=['GET'])
|
|
def test_connection():
|
|
"""DB 연결 테스트"""
|
|
try:
|
|
conn = get_mssql_connection('PM_PRES')
|
|
cursor = conn.cursor()
|
|
cursor.execute("SELECT @@VERSION")
|
|
version = cursor.fetchone()[0]
|
|
conn.close()
|
|
|
|
return jsonify({
|
|
'success': True,
|
|
'server': MSSQL_CONFIG['server'],
|
|
'version': version[:100] + '...'
|
|
})
|
|
except Exception as e:
|
|
return jsonify({'success': False, 'error': str(e)}), 500
|