# DB 구조 분석

> **분석 대상:** 5130 레거시 견적 시스템 데이터베이스
> **데이터베이스:** chandj
> **분석 일자:** 2025-12-19

---

## 테이블 목록

### 핵심 테이블
| 테이블명 | 용도 | 비고 |
|----------|------|------|
| `estimate` | 견적서 마스터 | 견적 헤더 + JSON 상세 |
| `BDmodels` | 모델별 단가 | 케이스, 레일, 부자재 단가 |
| `BDparts` | 부품 단가 | 부품별 가격 계수 |

### 단가 테이블
| 테이블명 | 용도 | 비고 |
|----------|------|------|
| `price_raw_materials` | 주자재 단가 | 스크린, 슬랫 소재 |
| `price_motor` | 모터 단가 | 용량별 모터 가격 |
| `price_shaft` | 샤프트 단가 | 길이별 샤프트 가격 |
| `price_pipe` | 각파이프 단가 | 규격별 파이프 가격 |
| `price_angle` | 앵글 단가 | 규격별 앵글 가격 |
| `price_bend` | 절곡비 단가 | 절곡 가공비 |
| `price_smokeban` | 연기차단재 단가 | 연기차단재 가격 |
| `price_etc` | 기타 단가 | 기타 부자재 |
| `price_pole` | 폴 단가 | 폴 관련 가격 |

### 참조 테이블
| 테이블명 | 용도 |
|----------|------|
| `item_list` | 품목 마스터 |
| `output` | 발주서 (수주→발주 연계) |

---

## 1. estimate 테이블 (견적 마스터)

### 스키마
```sql
CREATE TABLE estimate (
    num INT AUTO_INCREMENT PRIMARY KEY,

    -- 기본 정보
    pjnum VARCHAR(50),                 -- 프로젝트 번호 (KD-PR-YYMMDD-NN)
    indate DATE,                       -- 등록일
    orderman VARCHAR(50),              -- 담당자
    outworkplace VARCHAR(200),         -- 현장명/거래처

    -- 분류 정보
    major_category VARCHAR(50),        -- 대분류 (스크린/철재)
    model_name VARCHAR(100),           -- 모델명 (KSS01, KFS01 등)
    position VARCHAR(50),              -- 위치

    -- 규격 정보
    makeWidth INT DEFAULT 160,         -- 제작 폭 (스크린:160, 슬랫:110)
    makeHeight INT DEFAULT 350,        -- 제작 높이
    maguriWing VARCHAR(20) DEFAULT '50', -- 마구리 윙

    -- 발주처 정보
    con_num VARCHAR(50),               -- 계약번호
    secondord VARCHAR(100),            -- 2차 발주처
    secondordman VARCHAR(50),          -- 2차 담당자
    secondordmantel VARCHAR(20),       -- 2차 담당자 연락처
    secondordnum VARCHAR(50),          -- 2차 발주번호

    -- 견적 상세 (JSON)
    estimateList TEXT,                 -- 스크린 견적 리스트 (JSON)
    estimateList_auto TEXT,            -- 스크린 자동계산 리스트 (JSON)
    estimateSlatList TEXT,             -- 슬랫 견적 리스트 (JSON)
    estimateSlatList_auto TEXT,        -- 슬랫 자동계산 리스트 (JSON)

    -- 금액 정보
    estimateTotal INT DEFAULT 0,       -- 견적 총액
    EstimateFirstSum INT DEFAULT 0,    -- 최초 견적 합계
    EstimateUpdatetSum INT DEFAULT 0,  -- 수정 견적 합계
    EstimateDiffer INT DEFAULT 0,      -- 차액
    estimateSurang INT DEFAULT 0,      -- 수량

    -- 할인 정보
    EstimateDiscountRate INT DEFAULT 0,-- 할인율 (%)
    EstimateDiscount INT DEFAULT 0,    -- 할인금액
    EstimateFinalSum INT DEFAULT 0,    -- 최종 금액

    -- 검사비/옵션
    inspectionFee INT DEFAULT 50000,   -- 인정검사비
    steel VARCHAR(50),                 -- 절곡 옵션 (1/0)
    motor VARCHAR(100),                -- 모터 옵션 (1/0)
    warranty VARCHAR(100),             -- 보증 (인정/빈값)
    slatcheck VARCHAR(10),             -- 슬랫 체크 (1/0)
    partscheck VARCHAR(10),            -- 부자재 체크 (1/0)

    -- 시스템 필드
    comment TEXT,                      -- 비고
    update_log TEXT,                   -- 수정이력
    is_deleted TINYINT DEFAULT 0,      -- 삭제플래그

    INDEX idx_pjnum (pjnum),
    INDEX idx_outworkplace (outworkplace),
    INDEX idx_indate (indate)
);
```

### 주요 컬럼 설명

#### 프로젝트 번호 (pjnum)
```
형식: KD-PR-YYMMDD-NN
- KD: 경동
- PR: 프로젝트
- YYMMDD: 날짜 (6자리)
- NN: 일련번호 (01~99)

예시: KD-PR-251219-01
```

#### 대분류 (major_category)
| 값 | 설명 |
|----|------|
| 스크린 | 스크린 방화셔터 |
| 철재 | 철재 슬랫 방화셔터 |

#### 체크박스 옵션
| 컬럼 | 값 | 의미 |
|------|-----|------|
| steel | '1' / '0' | 절곡 포함/미포함 |
| motor | '1' / '0' | 모터 포함/미포함 |
| warranty | '인정' / '' | 보증 포함/미포함 |
| slatcheck | '1' / '0' | 슬랫 포함/미포함 |
| partscheck | '1' / '0' | 부자재 포함/미포함 |

---

## 2. estimateList JSON 구조

### 수동 입력 항목 (estimateList, estimateSlatList)
```json
[
    {
        "item_name": "가이드레일",
        "specification": "A형 65×80",
        "unit": "EA",
        "quantity": 2,
        "unit_price": 150000,
        "amount": 300000,
        "remark": ""
    },
    {
        "item_name": "스크린 판넬",
        "specification": "1.0T × 1200W",
        "unit": "m²",
        "quantity": 24.5,
        "unit_price": 45000,
        "amount": 1102500,
        "remark": "SUS304"
    }
]
```

### 자동 계산 항목 (estimateList_auto, estimateSlatList_auto)
```json
[
    {
        "item_code": "AUTO001",
        "item_name": "벤딩 가공비",
        "calc_type": "per_meter",
        "base_value": 120.5,
        "unit_price": 2500,
        "amount": 301250
    }
]
```

---

## 3. BDmodels 테이블 (모델별 단가)

### 스키마
```sql
CREATE TABLE IF NOT EXISTS BDmodels (
    id INT AUTO_INCREMENT PRIMARY KEY,
    modelname VARCHAR(50),              -- 모델명
    itemname VARCHAR(100),              -- 품목명
    itemsecond VARCHAR(100),            -- 품목 세부
    itemList TEXT,                      -- 상세 가격 JSON
    is_deleted TINYINT DEFAULT 0,
    INDEX idx_modelname (modelname),
    INDEX idx_itemname (itemname)
);
```

### itemList JSON 구조
```json
{
    "prices": [
        {"size": "530*320", "price": 150000},
        {"size": "600*350", "price": 180000},
        {"size": "690*390", "price": 210000}
    ],
    "unit": "EA",
    "description": "모터 브라켓"
}
```

### 주요 품목
| modelname | itemname | 용도 |
|-----------|----------|------|
| 공통 | 케이스 | 케이스 단가 |
| 공통 | 가이드레일 | 레일 단가 |
| 공통 | 연기차단재 | 연기차단재 단가 |
| 공통 | 하장바 | 하장바 단가 |
| 공통 | 마구리 | 마구리 단가 |
| 스크린 | L바 | L바 단가 (스크린 전용) |
| 스크린 | 보강평철 | 보강평철 단가 (스크린 전용) |
| 슬랫 | 조인트바 | 조인트바 단가 (슬랫 전용) |

---

## 4. 단가 테이블

### price_raw_materials (주자재)
```sql
CREATE TABLE price_raw_materials (
    id INT AUTO_INCREMENT PRIMARY KEY,
    material_type VARCHAR(50),          -- 소재 유형 (실리카, 와이어, 방화슬랫)
    specification VARCHAR(100),         -- 규격
    unit VARCHAR(20),                   -- 단위 (m², kg)
    unit_price DECIMAL(10,0),           -- 단가
    itemList TEXT,                      -- 상세 JSON
    is_deleted TINYINT DEFAULT 0
);
```

### price_motor (모터)
```sql
CREATE TABLE price_motor (
    id INT AUTO_INCREMENT PRIMARY KEY,
    capacity VARCHAR(20),               -- 용량 (150K, 300K, 500K, 800K, 1000K)
    type VARCHAR(50),                   -- 유형
    unit_price DECIMAL(10,0),           -- 단가
    is_deleted TINYINT DEFAULT 0
);
```

### price_shaft (샤프트)
```sql
CREATE TABLE price_shaft (
    id INT AUTO_INCREMENT PRIMARY KEY,
    length_range VARCHAR(50),           -- 길이 범위
    unit_price DECIMAL(10,0),           -- 단가
    weight_per_meter DECIMAL(5,2),      -- m당 중량
    is_deleted TINYINT DEFAULT 0
);
```

### price_pipe (각파이프)
```sql
CREATE TABLE price_pipe (
    id INT AUTO_INCREMENT PRIMARY KEY,
    specification VARCHAR(50),          -- 규격 (50×50, 75×75 등)
    unit_price DECIMAL(10,0),           -- m당 단가
    weight_per_meter DECIMAL(5,2),      -- m당 중량
    is_deleted TINYINT DEFAULT 0
);
```

### price_angle (앵글)
```sql
CREATE TABLE price_angle (
    id INT AUTO_INCREMENT PRIMARY KEY,
    specification VARCHAR(50),          -- 규격 (50×50×5 등)
    unit_price DECIMAL(10,0),           -- m당 단가
    weight_per_meter DECIMAL(5,2),      -- m당 중량
    is_deleted TINYINT DEFAULT 0
);
```

---

## 5. 컬럼 매핑 (스크린 vs 슬랫)

### get_screen_amount.php 컬럼
| 항목 | 컬럼 | 설명 |
|------|------|------|
| 위치 | col1 | 설치 위치 |
| 폭 | col2 | 오픈사이즈 폭 (mm) |
| 높이 | col3 | 오픈사이즈 높이 (mm) |
| 수량 | col4 | 수량 |
| 소재 | col5 | 실리카/와이어 |
| 케이스 타입 | col6 | 절곡/롤 |
| 레일 타입 | col7 | A형/B형 |
| 설치방식 | col8 | 매립/노출 |
| 면적 | col9 | 계산된 면적 (m²) |
| 케이스 길이 | col10 | mm |
| 레일 길이 | col11 | mm |
| 하장바 길이 | col12 | mm |
| 중량 | col13 | kg |
| 검사비 | col14 | 원 |
| 주자재 | col15 | 원 |
| 모터 | col16 | 원 |
| 제어기 | col17 | 원 |
| 케이스 | col18 | 원 |
| 레일 | col19 | 원 |
| 앵글 | col20 | 원 |
| 샤프트 | col21 | 원 |
| 인치 | col22 | 샤프트 인치 |

### get_slat_amount.php 컬럼
| 항목 | 컬럼 | 설명 |
|------|------|------|
| 위치 | col1 | 설치 위치 |
| 폭 | col2 | 오픈사이즈 폭 (mm) |
| 높이 | col3 | 오픈사이즈 높이 (mm) |
| 수량 | col4 | 수량 |
| 소재 | col5 | 방화슬랫 |
| 케이스 타입 | col6 | 절곡/롤 |
| 레일 타입 | col7 | A형/B형 |
| 설치방식 | col8 | 매립/노출 |
| 면적 | col9 | 계산된 면적 (m²) |
| 케이스 길이 | col10 | mm |
| 레일 길이 | col11 | mm |
| 하장바 길이 | col12 | mm |
| 중량 | col13 | kg |
| 검사비 | col14 | 원 |
| 주자재 (슬랫) | col15 | 원 |
| 조인트바 | col16 | 원 (슬랫 전용) |
| 모터 | col17 | 원 |
| 제어기 | col18 | 원 |
| 케이스 | col19 | 원 |
| 레일 | col20 | 원 |
| 앵글 | col21 | 원 |
| 샤프트 | col22 | 원 |
| 인치 | col23 | 샤프트 인치 |

---

## 6. 데이터 관계도

```
┌─────────────────────────────────────────────────────────┐
│                      estimate                            │
│  (견적 마스터)                                           │
├─────────────────────────────────────────────────────────┤
│  num (PK)                                                │
│  pjnum (견적번호)                                        │
│  major_category → '스크린' / '철재'                      │
│  model_name → item_list.model_name                       │
│  estimateList (JSON) ────┐                               │
│  estimateSlatList (JSON) │                               │
└──────────────────────────┼───────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────┐
│              JSON 상세 항목                              │
├─────────────────────────────────────────────────────────┤
│  item_name → BDmodels.itemname                           │
│  unit_price ← price_* 테이블 조회                        │
└──────────────────────────────────────────────────────────┘
                           │
         ┌─────────────────┼─────────────────┐
         ▼                 ▼                 ▼
┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│  BDmodels    │  │ price_motor  │  │ price_shaft  │
│  (모델 단가) │  │ (모터 단가)  │  │ (샤프트 단가)│
└──────────────┘  └──────────────┘  └──────────────┘
         ▼                 ▼                 ▼
┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│price_raw_mat │  │ price_pipe   │  │ price_angle  │
│  (주자재)    │  │ (각파이프)   │  │ (앵글)       │
└──────────────┘  └──────────────┘  └──────────────┘
```

---

## 7. SAM 이관 매핑

### 테이블 매핑
| 5130 테이블 | SAM 테이블 | 비고 |
|-------------|------------|------|
| estimate | quotes + quote_items | 헤더/상세 분리 |
| BDmodels | products + prices | 품목기준관리 연동 |
| price_* | prices | 통합 단가 테이블 |

### 주요 변환 포인트
1. **JSON → 정규화**: estimateList JSON을 quote_items 테이블로 분리
2. **동적 컬럼 → 고정 컬럼**: col1~col23을 명시적 컬럼명으로 변경
3. **체크박스 → options JSON**: steel, motor 등을 options JSON으로 통합
4. **단가 테이블 통합**: 7개 단가 테이블을 prices 테이블로 통합

### SAM 스키마 (제안)
```sql
-- 견적 헤더
CREATE TABLE quotes (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    tenant_id BIGINT UNSIGNED NOT NULL,
    quote_number VARCHAR(50) NOT NULL,
    quote_date DATE NOT NULL,
    customer_id BIGINT UNSIGNED,
    project_name VARCHAR(200),
    category ENUM('screen', 'slat') NOT NULL,
    model_id BIGINT UNSIGNED,
    options JSON,  -- {steel: true, motor: true, warranty: true, ...}
    dimensions JSON,  -- {width: 160, height: 350, wing: 50}
    inspection_fee DECIMAL(10,0) DEFAULT 50000,
    subtotal DECIMAL(12,0) DEFAULT 0,
    discount_rate DECIMAL(5,2) DEFAULT 0,
    discount_amount DECIMAL(12,0) DEFAULT 0,
    total_amount DECIMAL(12,0) DEFAULT 0,
    status ENUM('draft', 'sent', 'accepted', 'rejected') DEFAULT 'draft',
    created_by BIGINT UNSIGNED,
    created_at TIMESTAMP,
    updated_at TIMESTAMP,
    deleted_at TIMESTAMP NULL,

    INDEX idx_tenant_quote (tenant_id, quote_number),
    INDEX idx_tenant_date (tenant_id, quote_date)
);

-- 견적 상세
CREATE TABLE quote_items (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    quote_id BIGINT UNSIGNED NOT NULL,
    item_type ENUM('manual', 'auto') DEFAULT 'manual',
    item_code VARCHAR(50),
    item_name VARCHAR(100) NOT NULL,
    specification VARCHAR(200),
    unit VARCHAR(20),
    quantity DECIMAL(10,2) DEFAULT 1,
    unit_price DECIMAL(12,0) DEFAULT 0,
    amount DECIMAL(12,0) DEFAULT 0,
    sort_order INT DEFAULT 0,
    remark TEXT,

    FOREIGN KEY (quote_id) REFERENCES quotes(id) ON DELETE CASCADE,
    INDEX idx_quote (quote_id)
);
```

---

## 참조 파일

- `5130/estimate/insert.php` - 견적 저장 로직
- `5130/estimate/fetch_unitprice.php` - 단가 조회
- `5130/bendingfee_backup/sql.php` - BDmodels 스키마
- `docs/projects/legacy-5130/03_ESTIMATE.md` - 이전 분석