Initial commit: Flask stats API (v1 PharmIT3000, v2 PMPLUS20)
This commit is contained in:
308
app.py
Normal file
308
app.py
Normal file
@@ -0,0 +1,308 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Pharmacy Stats API - Flask 서버
|
||||
|
||||
QT-POS 통계 다이얼로그 API 버전
|
||||
v1: PharmIT3000
|
||||
v2: PMPLUS20
|
||||
"""
|
||||
from flask import Flask, jsonify, request, render_template
|
||||
from datetime import date, timedelta
|
||||
|
||||
from queries import v1_pharmit3000 as v1
|
||||
from queries import v2_pmplus20 as v2
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
# 보험구분 라벨
|
||||
GUBUN_LABEL = {
|
||||
'0': '건강보험', '1': '의료급여', '2': '산재', '3': '자동차',
|
||||
'4': '보훈', '5': '공상', '6': '본인', '7': '차상위1',
|
||||
'8': '희귀', '9': '비급여', 'E': '차상위2', 'F': '차상위2',
|
||||
}
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
return render_template('stats.html')
|
||||
|
||||
|
||||
# ============== v1 API (PharmIT3000) ==============
|
||||
|
||||
@app.route('/v1/api/stats')
|
||||
def v1_stats():
|
||||
"""v1 전체 통계"""
|
||||
date_from = request.args.get('from', _default_from())
|
||||
date_to = request.args.get('to', _default_to())
|
||||
|
||||
try:
|
||||
result = v1.get_sales_stats(date_from, date_to)
|
||||
result['version'] = 'v1'
|
||||
result['source'] = 'PharmIT3000'
|
||||
result['date_from'] = date_from
|
||||
result['date_to'] = date_to
|
||||
return jsonify(result)
|
||||
except Exception as e:
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
|
||||
@app.route('/v1/api/stats/insurance')
|
||||
def v1_stats_insurance():
|
||||
"""v1 보험별 통계"""
|
||||
date_from = request.args.get('from', _default_from())
|
||||
date_to = request.args.get('to', _default_to())
|
||||
|
||||
result = v1.get_sales_stats(date_from, date_to)
|
||||
|
||||
by_gubun = []
|
||||
for code, data in result.get('by_gubun', {}).items():
|
||||
by_gubun.append({
|
||||
'code': code,
|
||||
'label': GUBUN_LABEL.get(code, code),
|
||||
**data
|
||||
})
|
||||
|
||||
return jsonify({
|
||||
'version': 'v1',
|
||||
'source': 'PharmIT3000',
|
||||
'date_from': date_from,
|
||||
'date_to': date_to,
|
||||
'total': result['total'],
|
||||
'by_gubun': sorted(by_gubun, key=lambda x: x['code'])
|
||||
})
|
||||
|
||||
|
||||
@app.route('/v1/api/stats/time')
|
||||
def v1_stats_time():
|
||||
"""v1 시간가산별 통계"""
|
||||
date_from = request.args.get('from', _default_from())
|
||||
date_to = request.args.get('to', _default_to())
|
||||
|
||||
result = v1.get_sales_stats(date_from, date_to)
|
||||
|
||||
return jsonify({
|
||||
'version': 'v1',
|
||||
'source': 'PharmIT3000',
|
||||
'date_from': date_from,
|
||||
'date_to': date_to,
|
||||
'total': result['total'],
|
||||
'by_time': result['by_time']
|
||||
})
|
||||
|
||||
|
||||
@app.route('/v1/api/stats/payment')
|
||||
def v1_stats_payment():
|
||||
"""v1 결제수단별 통계"""
|
||||
date_from = request.args.get('from', _default_from())
|
||||
date_to = request.args.get('to', _default_to())
|
||||
|
||||
result = v1.get_sales_stats(date_from, date_to)
|
||||
|
||||
return jsonify({
|
||||
'version': 'v1',
|
||||
'source': 'PharmIT3000',
|
||||
'date_from': date_from,
|
||||
'date_to': date_to,
|
||||
'total': result['total'],
|
||||
'by_pay': result['by_pay']
|
||||
})
|
||||
|
||||
|
||||
@app.route('/v1/api/stats/hospital')
|
||||
def v1_stats_hospital():
|
||||
"""v1 병원별 통계"""
|
||||
date_from = request.args.get('from', _default_from())
|
||||
date_to = request.args.get('to', _default_to())
|
||||
|
||||
result = v1.get_sales_stats(date_from, date_to)
|
||||
|
||||
by_hosp = []
|
||||
for name, data in result.get('by_hosp', {}).items():
|
||||
by_hosp.append({'name': name, **data})
|
||||
|
||||
return jsonify({
|
||||
'version': 'v1',
|
||||
'source': 'PharmIT3000',
|
||||
'date_from': date_from,
|
||||
'date_to': date_to,
|
||||
'total': result['total'],
|
||||
'by_hosp': sorted(by_hosp, key=lambda x: -x['cnt'])[:50] # 상위 50개
|
||||
})
|
||||
|
||||
|
||||
# ============== v2 API (PMPLUS20) ==============
|
||||
|
||||
@app.route('/v2/api/stats')
|
||||
def v2_stats():
|
||||
"""v2 전체 통계"""
|
||||
date_from = request.args.get('from', _default_from())
|
||||
date_to = request.args.get('to', _default_to())
|
||||
|
||||
try:
|
||||
result = v2.get_sales_stats(date_from, date_to)
|
||||
result['version'] = 'v2'
|
||||
result['source'] = 'PMPLUS20'
|
||||
result['date_from'] = date_from
|
||||
result['date_to'] = date_to
|
||||
return jsonify(result)
|
||||
except Exception as e:
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
|
||||
@app.route('/v2/api/stats/insurance')
|
||||
def v2_stats_insurance():
|
||||
"""v2 보험별 통계"""
|
||||
date_from = request.args.get('from', _default_from())
|
||||
date_to = request.args.get('to', _default_to())
|
||||
|
||||
result = v2.get_sales_stats(date_from, date_to)
|
||||
|
||||
if 'error' in result:
|
||||
return jsonify(result), 500
|
||||
|
||||
by_gubun = []
|
||||
for code, data in result.get('by_gubun', {}).items():
|
||||
by_gubun.append({
|
||||
'code': code,
|
||||
'label': GUBUN_LABEL.get(code, code),
|
||||
**data
|
||||
})
|
||||
|
||||
return jsonify({
|
||||
'version': 'v2',
|
||||
'source': 'PMPLUS20',
|
||||
'date_from': date_from,
|
||||
'date_to': date_to,
|
||||
'total': result['total'],
|
||||
'by_gubun': sorted(by_gubun, key=lambda x: x['code'])
|
||||
})
|
||||
|
||||
|
||||
@app.route('/v2/api/stats/time')
|
||||
def v2_stats_time():
|
||||
"""v2 시간가산별 통계"""
|
||||
date_from = request.args.get('from', _default_from())
|
||||
date_to = request.args.get('to', _default_to())
|
||||
|
||||
result = v2.get_sales_stats(date_from, date_to)
|
||||
if 'error' in result:
|
||||
return jsonify(result), 500
|
||||
|
||||
return jsonify({
|
||||
'version': 'v2',
|
||||
'source': 'PMPLUS20',
|
||||
'date_from': date_from,
|
||||
'date_to': date_to,
|
||||
'total': result['total'],
|
||||
'by_time': result['by_time']
|
||||
})
|
||||
|
||||
|
||||
@app.route('/v2/api/stats/payment')
|
||||
def v2_stats_payment():
|
||||
"""v2 결제수단별 통계"""
|
||||
date_from = request.args.get('from', _default_from())
|
||||
date_to = request.args.get('to', _default_to())
|
||||
|
||||
result = v2.get_sales_stats(date_from, date_to)
|
||||
if 'error' in result:
|
||||
return jsonify(result), 500
|
||||
|
||||
return jsonify({
|
||||
'version': 'v2',
|
||||
'source': 'PMPLUS20',
|
||||
'date_from': date_from,
|
||||
'date_to': date_to,
|
||||
'total': result['total'],
|
||||
'by_pay': result['by_pay']
|
||||
})
|
||||
|
||||
|
||||
@app.route('/v2/api/stats/hospital')
|
||||
def v2_stats_hospital():
|
||||
"""v2 병원별 통계"""
|
||||
date_from = request.args.get('from', _default_from())
|
||||
date_to = request.args.get('to', _default_to())
|
||||
|
||||
result = v2.get_sales_stats(date_from, date_to)
|
||||
if 'error' in result:
|
||||
return jsonify(result), 500
|
||||
|
||||
by_hosp = []
|
||||
for name, data in result.get('by_hosp', {}).items():
|
||||
by_hosp.append({'name': name, **data})
|
||||
|
||||
return jsonify({
|
||||
'version': 'v2',
|
||||
'source': 'PMPLUS20',
|
||||
'date_from': date_from,
|
||||
'date_to': date_to,
|
||||
'total': result['total'],
|
||||
'by_hosp': sorted(by_hosp, key=lambda x: -x['cnt'])[:50]
|
||||
})
|
||||
|
||||
|
||||
# ============== 비교 API ==============
|
||||
|
||||
@app.route('/api/compare')
|
||||
def compare():
|
||||
"""v1 vs v2 비교"""
|
||||
date_from = request.args.get('from', _default_from())
|
||||
date_to = request.args.get('to', _default_to())
|
||||
|
||||
v1_result = v1.get_sales_stats(date_from, date_to)
|
||||
v2_result = v2.get_sales_stats(date_from, date_to)
|
||||
|
||||
# 차이 계산
|
||||
diff = {}
|
||||
if 'total' in v1_result and 'total' in v2_result:
|
||||
v1_total = v1_result['total']
|
||||
v2_total = v2_result['total']
|
||||
for key in v1_total:
|
||||
v1_val = v1_total.get(key, 0)
|
||||
v2_val = v2_total.get(key, 0)
|
||||
diff[key] = v2_val - v1_val
|
||||
|
||||
return jsonify({
|
||||
'date_from': date_from,
|
||||
'date_to': date_to,
|
||||
'v1': {
|
||||
'source': 'PharmIT3000',
|
||||
'total': v1_result.get('total', {}),
|
||||
'error': v1_result.get('error')
|
||||
},
|
||||
'v2': {
|
||||
'source': 'PMPLUS20',
|
||||
'total': v2_result.get('total', {}),
|
||||
'error': v2_result.get('error')
|
||||
},
|
||||
'diff': diff
|
||||
})
|
||||
|
||||
|
||||
def _default_from():
|
||||
"""기본 시작일: 이번 달 1일"""
|
||||
today = date.today()
|
||||
return today.replace(day=1).strftime('%Y%m%d')
|
||||
|
||||
|
||||
def _default_to():
|
||||
"""기본 종료일: 오늘"""
|
||||
return date.today().strftime('%Y%m%d')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("🏥 Pharmacy Stats API")
|
||||
print("http://0.0.0.0:5060")
|
||||
print("")
|
||||
print("Endpoints:")
|
||||
print(" /v1/api/stats - PharmIT3000 전체 통계")
|
||||
print(" /v1/api/stats/insurance - PharmIT3000 보험별")
|
||||
print(" /v1/api/stats/time - PharmIT3000 시간가산별")
|
||||
print(" /v1/api/stats/payment - PharmIT3000 결제수단별")
|
||||
print(" /v1/api/stats/hospital - PharmIT3000 병원별")
|
||||
print("")
|
||||
print(" /v2/api/stats/... - PMPLUS20 (동일 구조)")
|
||||
print("")
|
||||
print(" /api/compare - v1 vs v2 비교")
|
||||
app.run(host='0.0.0.0', port=5060, debug=True)
|
||||
Reference in New Issue
Block a user