pharmacy-pos-qr-system/backend/gui/check_cash.py
thug0bin 9bd2174501 feat: 제품 검색 페이지 및 QR 라벨 인쇄 기능
- /admin/products: 전체 제품 검색 페이지 (OTC)
- /api/products: 제품 검색 API (세트상품 바코드 포함)
- qr_printer.py: Brother QL-710W 프린터 연동
- /api/qr-print, /api/qr-preview: QR 라벨 인쇄/미리보기 API
- 판매상세 페이지에 QR 인쇄 버튼 추가
- 수량 선택 UI (+/- 버튼, 최대 10장)
- 세트상품 제조사 표시 개선
- 대시보드 헤더에 제품검색/판매조회 탭 추가
2026-02-27 13:56:26 +09:00

122 lines
4.5 KiB
Python

import pyodbc, sys
sys.stdout.reconfigure(encoding='utf-8')
conn = pyodbc.connect(
r'DRIVER={ODBC Driver 17 for SQL Server};SERVER=192.168.0.4\PM2014;DATABASE=PM_PRES;UID=sa;PWD=tmddls214!%(;Encrypt=no;TrustServerCertificate=yes;'
)
cur = conn.cursor()
# 조제 주문(180)이 SALE_MAIN에 있는지 확인
cur.execute("""
SELECT SL_NO_order, SL_DT_appl, SL_NM_custom, SL_MY_sale, InsertTime, PRESERIAL
FROM SALE_MAIN
WHERE SL_NO_order = '20260225000180'
""")
r = cur.fetchone()
print(f'=== 조제 주문 180 in SALE_MAIN: {"있음" if r else "없음"} ===')
if r:
print(f' 주문={r[0]} 날짜={r[1]} 고객={r[2]} 금액={r[3]} 시간={r[4]} PRESERIAL={r[5]}')
# SALE_MAIN 총 건수 vs CD_SUNAB 총 건수
cur.execute("SELECT COUNT(*) FROM SALE_MAIN WHERE SL_DT_appl = '20260225'")
sale_cnt = cur.fetchone()[0]
cur.execute("SELECT COUNT(*) FROM CD_SUNAB WHERE INDATE = '20260225'")
sunab_cnt = cur.fetchone()[0]
print(f'\n=== 오늘 건수 비교 ===')
print(f' SALE_MAIN: {sale_cnt}')
print(f' CD_SUNAB: {sunab_cnt}')
# CD_SUNAB 컬럼 구조 확인
cur.execute("SELECT TOP 1 * FROM CD_SUNAB WHERE INDATE = '20260225'")
cols = [d[0] for d in cur.description]
print(f'\n=== CD_SUNAB 컬럼 ({len(cols)}개) ===')
for i, c in enumerate(cols):
print(f' {i}: {c}')
# CD_SUNAB 조제건(SALE_MAIN 없는 91건)의 PRESERIAL vs PS_main.PreSerial 매칭
cur.execute("""
SELECT S.PRESERIAL
FROM CD_SUNAB S
WHERE S.INDATE = '20260225'
AND NOT EXISTS (SELECT 1 FROM SALE_MAIN M WHERE M.SL_NO_order = S.PRESERIAL)
""")
sunab_only = [r[0] for r in cur.fetchall()]
print(f'\n=== CD_SUNAB만 있는 91건 vs PS_main 매칭 ===')
# PS_main의 PreSerial 패턴 확인
cur.execute("SELECT TOP 5 PreSerial, Day_Serial, Indate, Paname FROM PS_main WHERE Indate = '20260225' ORDER BY PreSerial DESC")
print('PS_main 샘플:')
for r in cur.fetchall():
print(f' PreSerial={r[0]} | Day_Serial={r[1]} | Indate={r[2]} | 환자={r[3]}')
# CD_SUNAB PRESERIAL vs PS_main PreSerial 직접 비교
# CD_SUNAB.PRESERIAL = '20260225000180' 형태
# PS_main.PreSerial = ? 형태 확인
cur.execute("""
SELECT COUNT(*)
FROM CD_SUNAB S
WHERE S.INDATE = '20260225'
AND NOT EXISTS (SELECT 1 FROM SALE_MAIN M WHERE M.SL_NO_order = S.PRESERIAL)
AND EXISTS (SELECT 1 FROM PS_main P WHERE P.PreSerial = S.PRESERIAL AND P.Indate = '20260225')
""")
matched = cur.fetchone()[0]
cur.execute("""
SELECT S.PRESERIAL
FROM CD_SUNAB S
WHERE S.INDATE = '20260225'
AND NOT EXISTS (SELECT 1 FROM SALE_MAIN M WHERE M.SL_NO_order = S.PRESERIAL)
AND NOT EXISTS (SELECT 1 FROM PS_main P WHERE P.PreSerial = S.PRESERIAL AND P.Indate = '20260225')
""")
unmatched = cur.fetchall()
print(f'\nCD_SUNAB 91건 중 PS_main 매칭: {matched}')
print(f'CD_SUNAB 91건 중 PS_main 미매칭: {len(unmatched)}')
for r in unmatched:
serial = r[0]
print(f'\n=== 미매칭 {serial} ===')
# CD_SUNAB에서 금액, 승인일시
cur.execute("""
SELECT ISNULL(ETC_CARD,0)+ISNULL(ETC_CASH,0) as etc,
ISNULL(OTC_CARD,0)+ISNULL(OTC_CASH,0) as otc,
APPR_DATE, CUSCODE, DaeRiSunab, YOHUDATE
FROM CD_SUNAB WHERE PRESERIAL = ? AND INDATE = '20260225'
""", serial)
d = cur.fetchone()
print(f' ETC={d[0]:,.0f} OTC={d[1]:,.0f} | 승인일시={d[2]} | CUSCODE={d[3]} | 대리수납={d[4]} | 요후일={d[5]}')
# 다른 날짜의 PS_main에서 같은 PRESERIAL 검색 (날짜 무관)
cur.execute("SELECT PreSerial, Indate, Paname, Day_Serial FROM PS_main WHERE PreSerial = ?", serial)
ps = cur.fetchone()
if ps:
print(f' → PS_main 발견! 날짜={ps[1]} 환자={ps[2]} Day_Serial={ps[3]}')
else:
print(f' → PS_main 전체에서도 없음')
# PRESERIAL 번호 앞 8자리가 다른 날짜인 CD_SUNAB 검색
cur.execute("""
SELECT INDATE, PRESERIAL, ISNULL(ETC_CARD,0)+ISNULL(ETC_CASH,0) as etc
FROM CD_SUNAB WHERE PRESERIAL = ? AND INDATE != '20260225'
""", serial)
other = cur.fetchall()
if other:
for o in other:
print(f' → 다른 날짜 CD_SUNAB 발견! INDATE={o[0]} ETC={o[2]:,.0f}')
# CUSCODE로 PS_main 검색 (같은 환자의 이전 처방?)
if d[3] and d[3].strip():
cur.execute("""
SELECT TOP 3 PreSerial, Indate, Paname, Day_Serial
FROM PS_main WHERE CusCode = ?
ORDER BY Indate DESC, Day_Serial DESC
""", d[3].strip())
ps_list = cur.fetchall()
if ps_list:
print(f' → 같은 CUSCODE({d[3]})의 최근 PS_main:')
for p in ps_list:
print(f' PreSerial={p[0]} 날짜={p[1]} 환자={p[2]}')
conn.close()