# PIT3000 판매/조제/수납 데이터 구조

## 핵심 테이블 관계

```
CD_SUNAB (수납/결제) ─── 모든 거래의 결제 기록 (130건/일 기준)
  │
  ├── PS_main (처방접수) ─── 조제 건만 (89건/일 기준)
  │     │  조인: PS_main.PreSerial = CD_SUNAB.PRESERIAL
  │     │  조인: PS_main.Indate = CD_SUNAB.INDATE
  │     │
  │     ├── PS_sub_hosp (처방 의약품 상세)
  │     └── PS_sub_pharm (조제 의약품 상세)
  │
  └── SALE_MAIN (OTC 판매) ─── OTC 직접 판매만 (39건/일 기준)
        │  조인: SALE_MAIN.SL_NO_order = CD_SUNAB.PRESERIAL
        │
        └── SALE_SUB (판매 품목 상세) ─── SL_NO_order로 조인
```

## 테이블별 역할

### 1. CD_SUNAB — 수납/결제 (모든 거래 포함)
- **역할**: 조제 + OTC 모든 거래의 결제/수납 기록
- **1주문 = 1행** (복수행 없음)
- **키**: `PRESERIAL` (주문번호), `INDATE` (수납일)
- **건수**: 하루 약 130건 (조제 91 + OTC 39)

| 컬럼 | 설명 |
|------|------|
| `PRESERIAL` | 주문번호 (PS_main.PreSerial 또는 SALE_MAIN.SL_NO_order와 매칭) |
| `INDATE` | 수납일 (YYYYMMDD) |
| `DAY_SERIAL` | 일련번호 |
| `CUSCODE` | 고객코드 |
| `ETC_CARD` | 조제 카드결제 금액 |
| `ETC_CASH` | 조제 현금결제 금액 |
| `ETC_PAPER` | 조제 외상 금액 |
| `OTC_CARD` | 일반약 카드결제 금액 |
| `OTC_CASH` | 일반약 현금결제 금액 |
| `OTC_PAPER` | 일반약 외상 금액 |
| `pAPPROVAL_NUM` | 카드 승인번호 |
| `pMCHDATA` | 카드사 이름 |
| `pCARDINMODE` | 카드 입력방식 (1=IC칩) |
| `pTRDTYPE` | 거래유형 (D1=일반승인) |
| `nCASHINMODE` | 현금영수증 모드 (1=발행, 2=카드거래 자동세팅) |
| `nAPPROVAL_NUM` | 현금영수증 승인번호 |
| `Appr_Gubun` | 승인구분 (1, 2, 9 등) |
| `APPR_DATE` | 승인일시 (YYYYMMDDHHmmss) |
| `DaeRiSunab` | 대리수납 여부 |
| `YOHUDATE` | 요후일 |
| 총 **54개 컬럼** | |

### 2. PS_main — 처방전 접수 (조제 전용)
- **역할**: 처방전 기반 조제 접수 기록
- **키**: `PreSerial` (처방번호 = CD_SUNAB.PRESERIAL)
- **건수**: 하루 약 89건
- **SALE_MAIN에는 없음** — 조제건은 SALE_MAIN을 거치지 않음

| 컬럼 | 설명 |
|------|------|
| `PreSerial` | 처방번호 (= CD_SUNAB.PRESERIAL) |
| `Day_Serial` | 일일 접수 순번 (1~89) |
| `Indate` | 접수일 (YYYYMMDD) |
| `CusCode` | 환자 코드 |
| `Paname` | 환자명 |
| `PaNum` | 주민번호 |
| `InsName` | 보험구분 (건강보험, 의료급여 등) |
| `OrderName` | 의료기관명 |
| `Drname` | 처방의사명 |
| `PresTime` | 접수 시간 |
| `PRICE_T` | 총금액 |
| `PRICE_P` | 본인부담금 |
| `PRICE_C` | 보험자부담금 |
| `Pre_State` | 처방 상태 |
| `InsertTime` | 입력 시간 |
| 총 **58개 컬럼** | |

### 3. SALE_MAIN — OTC 직접 판매
- **역할**: 일반의약품(OTC) 직접 판매 기록
- **키**: `SL_NO_order` (주문번호 = CD_SUNAB.PRESERIAL)
- **건수**: 하루 약 39건
- **조제건은 포함되지 않음**

| 컬럼 | 설명 |
|------|------|
| `SL_NO_order` | 주문번호 (= CD_SUNAB.PRESERIAL) |
| `SL_DT_appl` | 판매일 (YYYYMMDD) |
| `SL_NM_custom` | 고객명 (대부분 빈값 → `[비고객]`) |
| `SL_MY_total` | 원가 (할인 전) |
| `SL_MY_discount` | 할인 금액 |
| `SL_MY_sale` | 실판매가 (= total - discount) |
| `InsertTime` | 입력 시간 |
| `PRESERIAL` | 처방번호 (OTC는 'V' 고정, 의미 없음) |
| 총 **30개 컬럼** | |

---

## 데이터 흐름 정리

### 조제 (처방전 기반)
```
처방전 접수 → PS_main 생성 → 조제 → CD_SUNAB 수납 기록
                                    (ETC_CARD/ETC_CASH에 금액)
```
- SALE_MAIN에는 **기록되지 않음**
- SALE_SUB에도 품목이 **들어가지 않음**
- 환자명은 PS_main.Paname에 있음

### OTC 판매 (직접 판매)
```
POS에서 품목 선택 → SALE_MAIN + SALE_SUB 생성 → CD_SUNAB 수납 기록
                                                (OTC_CARD/OTC_CASH에 금액)
```
- PS_main에는 **기록되지 않음**
- 고객명은 보통 빈값 (`[비고객]`)

### 조제 + OTC 동시 (하루 약 10건)
```
처방전 조제 + 일반약 동시 구매
→ PS_main (조제 부분)
→ SALE_MAIN + SALE_SUB (OTC 부분)
→ CD_SUNAB 1행에 ETC + OTC 금액 모두 기록
```

---

## 조인 키 관계

```
CD_SUNAB.PRESERIAL = PS_main.PreSerial     (조제건)
CD_SUNAB.PRESERIAL = SALE_MAIN.SL_NO_order (OTC건)
```

**주의**: `SALE_MAIN.PRESERIAL`은 OTC에서 항상 `'V'`로, 조인키가 아님.
실제 조인키는 `SALE_MAIN.SL_NO_order`임.

---

## 건수 관계 (2025-02-25 기준)

| 구분 | 건수 | 설명 |
|------|------|------|
| CD_SUNAB | 130 | 모든 수납 기록 |
| PS_main | 89 | 처방전 접수 (= 조제) |
| SALE_MAIN | 39 | OTC 직접 판매 |
| CD_SUNAB에만 존재 | 91 | 조제건 (SALE_MAIN 없음) |
| PS_main 매칭 | 89 | 91건 중 PS_main과 매칭 |
| 미매칭 | 2 | PS_main 없이 수납만 존재 (미수금 수납 등 특수 케이스) |

### 130건 = 39 (OTC) + 89 (조제) + 2 (특수)

---

## 조제/OTC 구분 방법

CD_SUNAB의 ETC/OTC 금액으로 판별:

```python
etc_total = ETC_CARD + ETC_CASH  # 조제 금액
otc_total = OTC_CARD + OTC_CASH  # 일반약 금액

if etc_total > 0 and otc_total > 0:
    구분 = "조제+판매"
elif etc_total > 0:
    구분 = "조제"
elif otc_total > 0:
    구분 = "판매(OTC)"
else:
    구분 = "본인부담금 없음"  # 건강보험 전액 부담
```

---

## 결제수단 판별

```python
card_total = ETC_CARD + OTC_CARD
cash_total = ETC_CASH + OTC_CASH

# 현금영수증 판별 (nCASHINMODE=2는 카드거래 자동세팅이므로 제외)
has_cash_receipt = (nCASHINMODE == '1' and nAPPROVAL_NUM != '')

if card_total > 0 and cash_total > 0:
    결제 = "카드+현금"
elif card_total > 0:
    결제 = "카드"
elif cash_total > 0:
    결제 = "현영" if has_cash_receipt else "현금"
else:
    결제 = "-"
```

---

## GUI 표시 색상

### 결제 컬럼
- **카드**: 파란색 (#1976D2)
- **현영**: 청록색 볼드 (#00897B) — 현금영수증 발행
- **현금**: 주황색 (#E65100) — 현금영수증 미발행
- **카드+현금**: 보라색 (#7B1FA2)
- **-**: 회색 (수납 없음)

### 수납 컬럼
- **✓**: 녹색 (#4CAF50)
- **-**: 회색 (미수납)

### 할인 표시
- 할인 없음: `12,000원`
- 할인 있음: `54,000원 (-6,000)` 주황색 볼드 + 툴팁

---

## SALE_MAIN 금액 컬럼 상세

| 컬럼 | 설명 | 예시 |
|------|------|------|
| `SL_MY_total` | 원가 (할인 전) | 60,000 |
| `SL_MY_discount` | 할인 금액 | 6,000 |
| `SL_MY_sale` | **실판매가** (= total - discount) | 54,000 |
| `SL_MY_recive` | 수납금액 (부가세 제외 추정) | 49,091 |
| `SL_MY_credit` | 외상 금액 | 0 |
| `SL_MY_dis_ratio` | 할인율 | 0 (미사용) |

### 금액 관계
```
SL_MY_sale = SL_MY_total - SL_MY_discount
SL_MY_recive ≈ SL_MY_sale / 1.1  (부가세 제외 금액 추정)
```

### 할인 빈도
- 대부분의 거래: discount = 0 (할인 없음)
- 할인 적용 건: 하루 2~5건 정도 (직원 할인, 대량 구매 등)
- 할인 규모: 1,000원 ~ 수십만원까지 다양

---

## CD_SUNAB 카드/현금 상세 컬럼

### 카드 상세 정보
| 컬럼 | 설명 | 예시 |
|------|------|------|
| `pMCHDATA` | 카드사 이름 | 비씨카드사, NH농협카드 |
| `PCardName` | 카드사 이름 (별도) | KB국민카드 |
| `pAPPROVAL_NUM` | 카드 승인번호 | 72139919 |
| `pCARDINMODE` | 카드 입력 방식 | 1 (IC칩) |
| `pTRDTYPE` | 거래 유형 | D1 (일반승인) |
| `Appr_Gubun` | 승인 구분 | 9 (정상승인) |
| `pCANCEL_NUM` | 취소 승인번호 | (취소 시) |

### 현금 상세 정보
| 컬럼 | 설명 | 예시 |
|------|------|------|
| `nCASHINMODE` | 현금영수증 입력 방식 | 1=실제발행, 2=카드거래 자동세팅 |
| `nAPPROVAL_NUM` | 현금영수증 승인번호 | 116624870 |
| `nCHK_GUBUN` | 현금 체크 구분 | KOV, TASA |

---

## SQL 쿼리 (현재 GUI에서 사용)

```sql
SELECT
    M.SL_NO_order,
    M.InsertTime,
    M.SL_MY_sale,
    ISNULL(M.SL_NM_custom, '[비고객]') AS customer_name,
    ISNULL(S.card_total, 0) AS card_total,
    ISNULL(S.cash_total, 0) AS cash_total,
    ISNULL(M.SL_MY_total, 0) AS total_amount,
    ISNULL(M.SL_MY_discount, 0) AS discount,
    S.cash_receipt_mode,
    S.cash_receipt_num
FROM SALE_MAIN M
OUTER APPLY (
    SELECT TOP 1
        ISNULL(ETC_CARD, 0) + ISNULL(OTC_CARD, 0) AS card_total,
        ISNULL(ETC_CASH, 0) + ISNULL(OTC_CASH, 0) AS cash_total,
        nCASHINMODE AS cash_receipt_mode,
        nAPPROVAL_NUM AS cash_receipt_num
    FROM CD_SUNAB
    WHERE PRESERIAL = M.SL_NO_order
) S
WHERE M.SL_DT_appl = ?
ORDER BY M.InsertTime DESC
```

**한계**: SALE_MAIN 기준이므로 OTC 판매(39건)만 표시됨.
조제건(~89건)은 표시되지 않음. 조제건까지 보려면 CD_SUNAB을
기본 테이블로 사용하거나 PS_main과 조인하는 쿼리 재설계 필요.

---

## 카드사 분포 (전체 데이터 기준)

| 카드사 | 건수 |
|--------|------|
| KB국민카드 | 6,106 |
| NH농협카드 | 5,172 |
| 비씨카드사 | 4,900 |
| 하나카드 | 4,880 |
| 신한카드 | 3,210 |
| 삼성카드사 | 2,100 |
| 현대카드사 | 1,960 |
| 우리카드 | 1,285 |
| 롯데카드사 | 837 |
| 카카오페이 | 57 |
| 모바일상품권 | 11 |
