docs: Phase 5 API 문서 추가 (사용자 초대, 알림설정, 계정관리)
- erp-api-list.md: Phase 5 섹션 추가 (12개 API) - erp-api-detail.md: Phase 5 상세 스펙 추가 - 13. 사용자 초대 (5개): 목록, 발송, 수락, 취소, 재발송 - 14. 알림 설정 (3개): 조회, 수정, 일괄수정 - 15. 계정 관리 (4개): 탈퇴, 사용중지, 약관조회, 약관수정
@@ -35,6 +35,7 @@ Phase 4: 견적 API 개발
|
||||
docs/projects/quotation/
|
||||
├── MASTER_PLAN.md # 이 문서
|
||||
├── PROGRESS.md # 진행 현황
|
||||
├── screenshots/ # MES 프로토타입 화면 캡쳐
|
||||
├── phase-1-5130-analysis/ # 1단계: 5130 분석
|
||||
│ ├── README.md
|
||||
│ ├── ui-analysis.md
|
||||
@@ -128,6 +129,25 @@ docs/projects/quotation/
|
||||
- Phase 1 분석 결과 (js-formulas.md)
|
||||
- Phase 2 분석 결과
|
||||
|
||||
**UI 참조 (MES 프로토타입 화면 캡쳐):**
|
||||
> 📁 경로: `docs/projects/quotation/screenshots/`
|
||||
|
||||
| 파일명 | 설명 |
|
||||
|--------|------|
|
||||
| `01-formula-list-main.png` | 견적수식 목록 메인 (기본정보 카테고리, 10개 수식) |
|
||||
| `02-product-dropdown.png` | 제품 선택 드롭다운 (공통/스크린/철재/슬랫) |
|
||||
| `03-category-management.png` | 분류 관리 (스크린/철재/전기부품/기타부자재) |
|
||||
| `04-price-formula-management.png` | 단가 수식 관리 (그룹별 품목, 적용수식 설정) |
|
||||
| `05-auto-quotation-input.png` | 자동 견적 산출 입력 (오픈사이즈, 옵션 선택) |
|
||||
| `06-category-guiderail.png` | 가이드레일 카테고리 수식 (조회/계산식 타입) |
|
||||
| `07-formula-add-modal.png` | 수식 추가 모달 (변수, 타입, 결과출력 설정) |
|
||||
|
||||
**캡쳐 화면 핵심 기능:**
|
||||
- 13개 카테고리 (기본정보~장수산출)
|
||||
- 44개 수식 (공통)
|
||||
- 수식 타입: 입력값, 계산식, 조회
|
||||
- 결과 타입: 변수저장, 품목/수량 출력
|
||||
|
||||
**산출물:**
|
||||
| 파일 | 설명 |
|
||||
|------|------|
|
||||
@@ -189,5 +209,6 @@ MCP: Sequential Thinking 적용
|
||||
|
||||
| 날짜 | 변경 내용 | 작성자 |
|
||||
|------|----------|--------|
|
||||
| 2025-12-19 | Phase 3에 MES 프로토타입 화면 캡쳐 참조 추가 | Claude |
|
||||
| 2025-12-19 | 공통 정책 분리, 견적 특화 내용만 유지 | Claude |
|
||||
| 2025-12-19 | 초기 마스터 플랜 작성 | Claude |
|
||||
@@ -6,11 +6,11 @@
|
||||
|
||||
---
|
||||
|
||||
## 📊 전체 진행률
|
||||
## 전체 진행률
|
||||
|
||||
| Phase | 상태 | 진행률 | 시작일 | 완료일 |
|
||||
|-------|------|--------|--------|--------|
|
||||
| Phase 1: 5130 분석 | ⏳ 대기 | 0% | - | - |
|
||||
| Phase 1: 5130 분석 | ✅ 완료 | 100% | 2025-12-19 | 2025-12-19 |
|
||||
| Phase 2: mng 분석 | ⏳ 대기 | 0% | - | - |
|
||||
| Phase 3: 구현 | ⏳ 대기 | 0% | - | - |
|
||||
| Phase 4: API 개발 | ⏳ 대기 | 0% | - | - |
|
||||
@@ -19,36 +19,54 @@
|
||||
|
||||
## 🔄 현재 작업
|
||||
|
||||
**현재 Phase:** 시작 전
|
||||
**현재 작업:** 마스터 플랜 작성 완료
|
||||
**현재 Phase:** Phase 1 완료, Phase 2 대기
|
||||
**다음 작업:** mng 견적 수식 관리 현황 분석
|
||||
|
||||
---
|
||||
|
||||
## 📋 Phase 1: 5130 견적 기능 분석
|
||||
## ✅ Phase 1: 5130 견적 기능 분석 (완료)
|
||||
|
||||
### 체크리스트
|
||||
- [ ] UI/화면 분석 (list.php, form.php 등)
|
||||
- [ ] JS 수식 분석 (모든 JS 파일)
|
||||
- [ ] DB 구조 분석
|
||||
- [ ] 비즈니스 로직 문서화
|
||||
- [ ] README.md 작성
|
||||
- [x] UI/화면 분석 (list.php, write_form.php 등)
|
||||
- [x] JS 수식 분석 (calculation.js, fetch_unitprice.php)
|
||||
- [x] PHP 계산 로직 분석 (get_screen_amount.php, get_slat_amount.php)
|
||||
- [x] DB 구조 분석 (estimate, BDmodels, price_* 테이블)
|
||||
- [x] 비즈니스 로직 문서화
|
||||
- [x] README.md 작성
|
||||
|
||||
### 산출물
|
||||
- [ ] phase-1-5130-analysis/README.md
|
||||
- [ ] phase-1-5130-analysis/ui-analysis.md
|
||||
- [ ] phase-1-5130-analysis/js-formulas.md
|
||||
- [ ] phase-1-5130-analysis/db-structure.md
|
||||
- [ ] phase-1-5130-analysis/business-logic.md
|
||||
- [x] [README.md](./phase-1-5130-analysis/README.md) - 분석 체크리스트 및 요약
|
||||
- [x] [js-formulas.md](./phase-1-5130-analysis/js-formulas.md) - **핵심** 수식 분석 (19개 항목)
|
||||
- [x] [ui-analysis.md](./phase-1-5130-analysis/ui-analysis.md) - 화면별 기능 분석
|
||||
- [x] [db-structure.md](./phase-1-5130-analysis/db-structure.md) - 테이블/컬럼 구조
|
||||
- [x] [business-logic.md](./phase-1-5130-analysis/business-logic.md) - 비즈니스 로직 정리
|
||||
|
||||
### 메모
|
||||
_Phase 1 진행 시 메모 기록_
|
||||
### 핵심 발견 사항
|
||||
|
||||
#### 견적 유형 (2가지)
|
||||
| 유형 | 주요 특징 |
|
||||
|------|----------|
|
||||
| 스크린 | 면적 기반 (높이+550), 실리카/와이어 소재 |
|
||||
| 슬랫(철재) | 면적 기반 (높이+50), 방화슬랫 소재 |
|
||||
|
||||
#### 계산 항목 (18개)
|
||||
검사비, 주자재, 조인트바, 모터, 제어기, 케이스, 케이스연기차단재, 마구리, 앵글, 가이드레일, 레일연기차단재, 하장바, L바, 보강평철, 샤프트, 무게평철, 환봉, 각파이프
|
||||
|
||||
#### 옵션 체크박스 (5개)
|
||||
| 옵션 | 영향 항목 |
|
||||
|------|----------|
|
||||
| 절곡 | 케이스, 레일, 연기차단재, 하장바, L바, 보강평철 |
|
||||
| 모터 | 모터 가격 |
|
||||
| 보증 | 보증기간 |
|
||||
| 슬랫 | 주자재(슬랫), 조인트바 |
|
||||
| 부자재 | 샤프트, 각파이프, 앵글 |
|
||||
|
||||
---
|
||||
|
||||
## 📋 Phase 2: mng 견적 수식 관리 분석
|
||||
|
||||
### 체크리스트
|
||||
- [ ] 현재 구현 상태 분석
|
||||
- [ ] 현재 구현 상태 분석 (quote-formulas)
|
||||
- [ ] 오류/문제점 목록화
|
||||
- [ ] 개선 방향 도출
|
||||
- [ ] README.md 작성
|
||||
@@ -114,6 +132,8 @@ _Phase 4 진행 시 메모 기록_
|
||||
|------|------|----------|------|
|
||||
| 2025-12-19 | DB 작업 위치 | api 프로젝트에서만 | mng 마이그레이션 방지 |
|
||||
| 2025-12-19 | 신규 테이블 정책 | options JSON 적용 | Hybrid EAV 전략 |
|
||||
| 2025-12-19 | 견적 유형 | 스크린/슬랫 2가지 | 5130 기존 구조 유지 |
|
||||
| 2025-12-19 | 체크박스 옵션 | JSON으로 통합 저장 | 확장성 고려 |
|
||||
|
||||
---
|
||||
|
||||
@@ -126,4 +146,6 @@ _현재 이슈 없음_
|
||||
## 📚 참조 문서
|
||||
|
||||
- [MASTER_PLAN.md](./MASTER_PLAN.md) - 마스터 플랜
|
||||
- [docs/projects/mes/v1-analysis/quotation-analysis.md](../mes/v1-analysis/quotation-analysis.md) - MES 견적 분석
|
||||
- [phase-1-5130-analysis/](./phase-1-5130-analysis/) - Phase 1 분석 결과
|
||||
- [docs/projects/mes/v1-analysis/quotation-analysis.md](../mes/v1-analysis/quotation-analysis.md) - MES 견적 분석
|
||||
- [docs/projects/legacy-5130/03_ESTIMATE.md](../legacy-5130/03_ESTIMATE.md) - 5130 레거시 분석
|
||||
|
||||
148
projects/quotation/phase-1-5130-analysis/README.md
Normal file
@@ -0,0 +1,148 @@
|
||||
# Phase 1: 5130 견적 기능 분석
|
||||
|
||||
> **목표:** 5130 레거시 견적 시스템 완전 분석 및 문서화
|
||||
> **분석 일자:** 2025-12-19
|
||||
> **상태:** 🔄 진행 중
|
||||
|
||||
---
|
||||
|
||||
## 📋 분석 체크리스트
|
||||
|
||||
### 핵심 분석 (필수)
|
||||
- [x] JS 수식 분석 (`common/calculation.js`)
|
||||
- [x] PHP 단가 계산 로직 (`fetch_unitprice.php`)
|
||||
- [x] 스크린 금액 계산 (`get_screen_amount.php`)
|
||||
- [x] 슬랫 금액 계산 (`get_slat_amount.php`)
|
||||
- [x] DB 스키마 분석 (`estimate` 테이블)
|
||||
|
||||
### 문서 작성
|
||||
- [x] js-formulas.md - 수식 분석 (핵심!)
|
||||
- [x] ui-analysis.md - 화면별 기능 분석
|
||||
- [x] db-structure.md - 테이블/컬럼 구조
|
||||
- [x] business-logic.md - 비즈니스 로직 정리
|
||||
|
||||
---
|
||||
|
||||
## 📁 분석 대상 파일
|
||||
|
||||
### 핵심 파일
|
||||
| 파일 | 크기 | 설명 |
|
||||
|------|------|------|
|
||||
| `common/calculation.js` | 182줄 | 프론트엔드 행 계산 로직 |
|
||||
| `fetch_unitprice.php` | 875줄 | **핵심** - 단가 조회 및 수식 함수 |
|
||||
| `get_screen_amount.php` | 583줄 | 스크린 견적 계산 |
|
||||
| `get_slat_amount.php` | 541줄 | 슬랫(철재) 견적 계산 |
|
||||
| `write_form.php` | 103KB | 견적서 작성 UI |
|
||||
|
||||
### 디렉토리 구조
|
||||
```
|
||||
5130/estimate/
|
||||
├── common/
|
||||
│ ├── calculation.js # 행 계산 JS
|
||||
│ ├── lastJS.php # 페이지 공통 JS
|
||||
│ ├── common_screen.php # 스크린 공통
|
||||
│ └── common_slat.php # 슬랫 공통
|
||||
├── list.php # 견적 목록
|
||||
├── write_form.php # 견적서 작성
|
||||
├── estimate.php # 견적서 메인
|
||||
├── estimateSlat.php # 슬랫 견적
|
||||
├── estimateUnit.php # 단가 견적
|
||||
├── fetch_unitprice.php # 단가 조회 API
|
||||
├── get_estimate_amount.php # 견적 금액 라우터
|
||||
├── get_screen_amount.php # 스크린 금액 계산
|
||||
├── get_slat_amount.php # 슬랫 금액 계산
|
||||
├── insert.php # 견적 저장
|
||||
└── generate_serial_pjnum.php # 번호 생성
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 핵심 발견 사항
|
||||
|
||||
### 1. 견적 유형 (2가지)
|
||||
| 유형 | 파일 | 주요 특징 |
|
||||
|------|------|----------|
|
||||
| **스크린** | `get_screen_amount.php` | 면적(m²) 기반, 실리카/와이어 소재 |
|
||||
| **슬랫(철재)** | `get_slat_amount.php` | 면적 기반, 방화 슬랫 소재 |
|
||||
|
||||
### 2. 계산 항목 (18개 항목)
|
||||
1. 검사비 (인정검사비)
|
||||
2. 주자재 (스크린/슬랫)
|
||||
3. 조인트바 (슬랫 전용)
|
||||
4. 모터
|
||||
5. 연동제어기 (매립형/노출형/뒷박스)
|
||||
6. 케이스
|
||||
7. 케이스용 연기차단재
|
||||
8. 케이스 마구리
|
||||
9. 모터 받침용 앵글
|
||||
10. 가이드레일
|
||||
11. 레일용 연기차단재
|
||||
12. 하장바
|
||||
13. L바 (스크린 전용)
|
||||
14. 보강평철 (스크린 전용)
|
||||
15. 감기샤프트
|
||||
16. 무게평철 (스크린 전용)
|
||||
17. 환봉 (스크린 전용)
|
||||
18. 각파이프
|
||||
19. 앵글
|
||||
|
||||
### 3. 체크박스 옵션 (5개)
|
||||
| 옵션 | 변수명 | 영향 항목 |
|
||||
|------|--------|----------|
|
||||
| 절곡 | `steel` | 케이스, 가이드레일, 연기차단재, 하장바, L바, 보강평철 |
|
||||
| 모터 | `motor` | 모터 가격 포함 여부 |
|
||||
| 보증 | `warranty` | 보증기간 |
|
||||
| 슬랫 | `slatcheck` | 주자재(슬랫), 조인트바 |
|
||||
| 부자재 | `partscheck` | 샤프트, 각파이프, 앵글 |
|
||||
|
||||
### 4. 단가 테이블 (7개)
|
||||
| 테이블 | 용도 |
|
||||
|--------|------|
|
||||
| `price_raw_materials` | 주자재 단가 (스크린, 슬랫) |
|
||||
| `price_motor` | 모터/제어기 단가 |
|
||||
| `price_shaft` | 샤프트 단가 |
|
||||
| `price_pipe` | 각파이프 단가 |
|
||||
| `price_angle` | 앵글 단가 |
|
||||
| `BDmodels` | 케이스, 가이드레일, 부자재 단가 |
|
||||
| `item_list` | 품목 마스터 |
|
||||
|
||||
---
|
||||
|
||||
## 📊 상세 문서
|
||||
|
||||
| 문서 | 설명 |
|
||||
|------|------|
|
||||
| [js-formulas.md](./js-formulas.md) | **핵심** - 모든 수식 상세 분석 |
|
||||
| [ui-analysis.md](./ui-analysis.md) | 화면별 기능 분석 |
|
||||
| [db-structure.md](./db-structure.md) | DB 테이블 구조 |
|
||||
| [business-logic.md](./business-logic.md) | 비즈니스 로직 정리 |
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 주의 사항
|
||||
|
||||
### 코드 특성
|
||||
1. **레거시 PHP + jQuery** - ES6 문법 없음
|
||||
2. **동적 테이블명** - 일부 쿼리에서 테이블명 동적 설정
|
||||
3. **JSON 기반 데이터** - `itemList` 컬럼에 JSON으로 상세 데이터 저장
|
||||
4. **컬럼명 규칙** - `col1`, `col2`, ... 형태의 범용 컬럼
|
||||
|
||||
### SAM 이관 시 고려사항
|
||||
1. 단가 테이블 구조 재설계 필요
|
||||
2. `BDmodels` 테이블 → SAM 품목기준관리 연동
|
||||
3. 체크박스 옵션 → 견적 옵션 테이블 설계
|
||||
4. 수식 로직 → Service 클래스로 분리
|
||||
|
||||
---
|
||||
|
||||
## 📝 다음 단계
|
||||
|
||||
Phase 2로 이동하여 현재 mng 견적 수식 관리 상태 분석 예정
|
||||
|
||||
---
|
||||
|
||||
## 📚 참조
|
||||
|
||||
- [MASTER_PLAN.md](../MASTER_PLAN.md)
|
||||
- [PROGRESS.md](../PROGRESS.md)
|
||||
- [docs/projects/legacy-5130/03_ESTIMATE.md](../../legacy-5130/03_ESTIMATE.md)
|
||||
472
projects/quotation/phase-1-5130-analysis/business-logic.md
Normal file
@@ -0,0 +1,472 @@
|
||||
# 비즈니스 로직 분석
|
||||
|
||||
> **분석 대상:** 5130 레거시 견적 시스템 비즈니스 로직
|
||||
> **분석 일자:** 2025-12-19
|
||||
|
||||
---
|
||||
|
||||
## 비즈니스 프로세스 개요
|
||||
|
||||
### 견적 생성 플로우
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 1. 견적 시작 │
|
||||
│ └─ 신규 / 복사 / 수주연계 │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 2. 기본 정보 입력 │
|
||||
│ └─ 현장명, 발주처, 담당자 │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 3. 제품 선택 │
|
||||
│ ├─ 대분류: 스크린 / 철재 │
|
||||
│ ├─ 모델: KSS01, KFS01 등 │
|
||||
│ └─ 규격: 폭, 높이, 마구리윙 │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 4. 옵션 선택 │
|
||||
│ └─ 절곡, 모터, 보증, 슬랫, 부자재 │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 5. 상세 항목 입력 │
|
||||
│ ├─ 각 행별 위치, 폭, 높이, 수량 입력 │
|
||||
│ └─ 자동 계산 트리거 │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 6. 금액 계산 (자동) │
|
||||
│ ├─ AJAX → get_screen_amount / get_slat_amount │
|
||||
│ ├─ 18개 항목별 단가 조회 및 계산 │
|
||||
│ └─ 합계 산출 │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 7. 할인 적용 │
|
||||
│ └─ 할인율 / 할인액 입력 → 최종금액 계산 │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 8. 저장 │
|
||||
│ ├─ 견적번호 생성 (KD-PR-YYMMDD-NN) │
|
||||
│ └─ DB 저장 (estimate 테이블) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1. 견적 유형별 처리
|
||||
|
||||
### 스크린 견적 (Screen)
|
||||
| 특성 | 값 |
|
||||
|------|-----|
|
||||
| 대분류 | 스크린 |
|
||||
| 주자재 소재 | 실리카, 와이어 |
|
||||
| 면적 계산 | (높이 + 550) × 폭 / 1,000,000 m² |
|
||||
| 기본 제작폭 | 160mm |
|
||||
| 전용 항목 | L바, 보강평철, 무게평철, 환봉 |
|
||||
|
||||
### 슬랫 견적 (Slat/철재)
|
||||
| 특성 | 값 |
|
||||
|------|-----|
|
||||
| 대분류 | 철재 |
|
||||
| 주자재 소재 | 방화슬랫 |
|
||||
| 면적 계산 | (높이 + 50) × 폭 / 1,000,000 m² |
|
||||
| 기본 제작폭 | 110mm |
|
||||
| 전용 항목 | 조인트바 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 옵션 체크박스 로직
|
||||
|
||||
### 옵션별 영향 항목
|
||||
|
||||
| 옵션 | 변수 | 영향받는 항목 |
|
||||
|------|------|---------------|
|
||||
| 절곡 | `steel` | 케이스, 케이스용 연기차단재, 마구리, 가이드레일, 레일용 연기차단재, 하장바, L바(스크린), 보강평철(스크린) |
|
||||
| 모터 | `motor` | 모터 가격 포함/미포함 |
|
||||
| 보증 | `warranty` | 보증기간 표시 (인정) |
|
||||
| 슬랫 | `slatcheck` | 주자재(슬랫), 조인트바 |
|
||||
| 부자재 | `partscheck` | 감기샤프트, 각파이프, 앵글 |
|
||||
|
||||
### 조건부 계산 로직
|
||||
```php
|
||||
// 절곡 옵션 체크 시
|
||||
if ($steel == '1') {
|
||||
// 케이스, 연기차단재, 레일, 하장바 등 계산
|
||||
$caseAmount = calculateCase($width, $caseType, $itemList);
|
||||
$smokebanAmount = calculateSmokeban($width, $itemList);
|
||||
// ...
|
||||
} else {
|
||||
// 해당 항목 0원 처리
|
||||
$caseAmount = 0;
|
||||
$smokebanAmount = 0;
|
||||
}
|
||||
|
||||
// 모터 옵션 체크 시
|
||||
if ($motor == '1') {
|
||||
$motorAmount = getMotorPrice($motorCapacity);
|
||||
} else {
|
||||
$motorAmount = 0;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 단가 조회 로직
|
||||
|
||||
### 조회 우선순위
|
||||
1. **BDmodels 테이블**: 모델별 품목 단가
|
||||
2. **price_* 테이블**: 품목별 세부 단가
|
||||
3. **기본값**: 조회 실패 시 기본 단가 적용
|
||||
|
||||
### 단가 조회 함수
|
||||
```php
|
||||
// fetch_unitprice.php
|
||||
|
||||
// 1. 모터 단가 조회
|
||||
function getMotorPrice($capacity) {
|
||||
// price_motor 테이블에서 용량별 단가 조회
|
||||
$sql = "SELECT unit_price FROM price_motor WHERE capacity = ?";
|
||||
// ...
|
||||
}
|
||||
|
||||
// 2. 샤프트 단가 조회
|
||||
function getShaftPrice($length) {
|
||||
// price_shaft 테이블에서 길이별 단가 조회
|
||||
$sql = "SELECT unit_price FROM price_shaft WHERE ? BETWEEN min_length AND max_length";
|
||||
// ...
|
||||
}
|
||||
|
||||
// 3. BDmodels에서 품목 단가 조회
|
||||
function getBDModelPrice($modelname, $itemname, $size) {
|
||||
$sql = "SELECT itemList FROM BDmodels WHERE modelname = ? AND itemname = ?";
|
||||
// JSON 파싱 후 사이즈에 맞는 가격 반환
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 금액 계산 플로우
|
||||
|
||||
### 스크린 금액 계산 (get_screen_amount.php)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 입력값 │
|
||||
│ - 폭(col2), 높이(col3), 수량(col4), 소재(col5) │
|
||||
│ - 케이스타입(col6), 레일타입(col7), 설치방식(col8) │
|
||||
│ - 체크박스옵션 (steel, motor, warranty, slatcheck, partscheck)│
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 1. 면적 계산 │
|
||||
│ area = (height + 550) × width / 1,000,000 │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 2. 중량 계산 (모터 용량 결정용) │
|
||||
│ weight = area × 소재별_단위중량 │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 3. 모터 용량 결정 │
|
||||
│ motorCapacity = searchBracketSize(weight, inch) │
|
||||
│ → 150K / 300K / 500K / 800K / 1000K │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 4. 18개 항목별 금액 계산 │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ 1. 검사비: inspectionFee (고정) │ │
|
||||
│ │ 2. 주자재: area × 소재단가 │ │
|
||||
│ │ 3. 모터: getMotorPrice(capacity) × motor체크 │ │
|
||||
│ │ 4. 제어기: getControllerPrice(type) × motor체크 │ │
|
||||
│ │ 5. 케이스: (width+제작폭) × m당단가 × steel체크 │ │
|
||||
│ │ 6. 케이스연기차단재: width × m당단가 × steel체크 │ │
|
||||
│ │ 7. 마구리: 2개 × 개당단가 × steel체크 │ │
|
||||
│ │ 8. 앵글: 규격별단가 × steel체크 │ │
|
||||
│ │ 9. 가이드레일: (height+레일여유) × m당단가 × steel │ │
|
||||
│ │ 10. 레일연기차단재: height × m당단가 × steel │ │
|
||||
│ │ 11. 하장바: width × m당단가 × steel체크 │ │
|
||||
│ │ 12. L바: width × m당단가 × steel체크 │ │
|
||||
│ │ 13. 보강평철: width × m당단가 × steel체크 │ │
|
||||
│ │ 14. 샤프트: getShaftPrice(width) × partscheck │ │
|
||||
│ │ 15. 무게평철: weight계산 × 단가 │ │
|
||||
│ │ 16. 환봉: 길이계산 × m당단가 │ │
|
||||
│ │ 17. 각파이프: 길이계산 × m당단가 × partscheck │ │
|
||||
│ │ 18. 앵글: 길이계산 × m당단가 × partscheck │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 5. 행 합계 │
|
||||
│ rowTotal = Σ(항목별금액) × 수량 │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 6. 전체 합계 │
|
||||
│ estimateTotal = Σ(모든행 rowTotal) │
|
||||
│ EstimateFinalSum = estimateTotal - 할인액 │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 모터 용량 결정 로직
|
||||
|
||||
### 중량 + 인치 기반 판단
|
||||
|
||||
```php
|
||||
function searchBracketSize($motorWeight, $bracketInch = null) {
|
||||
$weight = floatval($motorWeight);
|
||||
$inch = intval($bracketInch);
|
||||
|
||||
// 인치별 중량 기준
|
||||
if ($inch > 0) {
|
||||
// 4인치 기준
|
||||
if ($inch == 4 && $weight <= 300) → 300K
|
||||
if ($inch == 4 && $weight <= 400) → 400K
|
||||
|
||||
// 5인치 기준
|
||||
if ($inch == 5 && $weight <= 246) → 300K
|
||||
if ($inch == 5 && $weight <= 327) → 400K
|
||||
if ($inch == 5 && $weight <= 500) → 500K
|
||||
if ($inch == 5 && $weight <= 600) → 600K
|
||||
|
||||
// 6인치 기준
|
||||
if ($inch == 6 && $weight <= 208) → 300K
|
||||
if ($inch == 6 && $weight <= 277) → 400K
|
||||
if ($inch == 6 && $weight <= 424) → 500K
|
||||
if ($inch == 6 && $weight <= 508) → 600K
|
||||
if ($inch == 6 && $weight <= 800) → 800K
|
||||
if ($inch == 6 && $weight <= 1000) → 1000K
|
||||
|
||||
// 8인치 기준
|
||||
if ($inch == 8 && $weight <= 324) → 500K
|
||||
if ($inch == 8 && $weight <= 388) → 600K
|
||||
if ($inch == 8 && $weight <= 611) → 800K
|
||||
if ($inch == 8 && $weight <= 1000) → 1000K
|
||||
} else {
|
||||
// 인치 없이 중량만으로 판단
|
||||
if ($weight <= 300) → 300K
|
||||
if ($weight <= 400) → 400K
|
||||
if ($weight <= 500) → 500K
|
||||
if ($weight <= 600) → 600K
|
||||
if ($weight <= 800) → 800K
|
||||
if ($weight <= 1000) → 1000K
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 브라켓 사이즈 매핑
|
||||
|
||||
| 모터 용량 | 브라켓 사이즈 |
|
||||
|-----------|---------------|
|
||||
| 300K, 400K | 530×320 |
|
||||
| 500K, 600K | 600×350 |
|
||||
| 800K, 1000K | 690×390 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 견적번호 생성
|
||||
|
||||
### 형식
|
||||
```
|
||||
KD-PR-YYMMDD-NN
|
||||
|
||||
KD: 경동 (회사코드)
|
||||
PR: 프로젝트
|
||||
YYMMDD: 날짜 (년월일 6자리)
|
||||
NN: 일련번호 (01~99, 당일 기준)
|
||||
```
|
||||
|
||||
### 생성 로직
|
||||
```php
|
||||
// generate_serial_pjnum.php
|
||||
function generatePjnum($pdo) {
|
||||
$today = date('ymd');
|
||||
$prefix = "KD-PR-{$today}-";
|
||||
|
||||
// 오늘 날짜의 마지막 번호 조회
|
||||
$sql = "SELECT pjnum FROM estimate
|
||||
WHERE pjnum LIKE ?
|
||||
ORDER BY pjnum DESC LIMIT 1";
|
||||
$stmh = $pdo->prepare($sql);
|
||||
$stmh->execute([$prefix . '%']);
|
||||
$row = $stmh->fetch();
|
||||
|
||||
if ($row) {
|
||||
// 마지막 번호 추출 후 +1
|
||||
$lastNum = intval(substr($row['pjnum'], -2));
|
||||
$nextNum = str_pad($lastNum + 1, 2, '0', STR_PAD_LEFT);
|
||||
} else {
|
||||
$nextNum = '01';
|
||||
}
|
||||
|
||||
return $prefix . $nextNum;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 금액 처리 규칙
|
||||
|
||||
### 단위 변환
|
||||
| 항목 | 입력 단위 | 계산 단위 | 비고 |
|
||||
|------|----------|----------|------|
|
||||
| 폭/높이 | mm | m | /1000 변환 |
|
||||
| 면적 | - | m² | 폭×높이/1,000,000 |
|
||||
| 중량 | - | kg | 면적×단위중량 |
|
||||
| 금액 | - | 원 | 천원 단위 반올림 |
|
||||
|
||||
### 반올림 규칙
|
||||
```javascript
|
||||
// calculation.js
|
||||
// 금액은 천원 단위에서 반올림
|
||||
roundedAreaPrice = Math.round(areaPrice / 1000) * 1000;
|
||||
|
||||
// 면적은 소수점 2자리
|
||||
area = Math.round(area * 100) / 100;
|
||||
```
|
||||
|
||||
### 수동 편집 처리
|
||||
```javascript
|
||||
// 수동 편집된 셀은 배경색 변경
|
||||
$('.manually-edited').css('background-color', '#f8d7da');
|
||||
|
||||
// 자동 계산 시 수동 편집 값 유지 옵션
|
||||
if (!isManuallyEdited) {
|
||||
cell.val(calculatedValue);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 데이터 저장 규칙
|
||||
|
||||
### 저장 전 검증
|
||||
1. 필수값 확인: 현장명, 발주처, 담당자
|
||||
2. 수치 변환: 콤마 제거, 정수 변환
|
||||
3. 권한 확인: 레벨 5 이하
|
||||
|
||||
### 저장 데이터
|
||||
```php
|
||||
// insert.php
|
||||
$data = [
|
||||
'pjnum' => generatePjnum(),
|
||||
'indate' => date('Y-m-d'),
|
||||
'orderman' => $_SESSION['name'],
|
||||
'outworkplace' => $outworkplace,
|
||||
'major_category' => $major_category,
|
||||
'model_name' => $model_name,
|
||||
'makeWidth' => intval(str_replace(',', '', $makeWidth)),
|
||||
'makeHeight' => intval(str_replace(',', '', $makeHeight)),
|
||||
'maguriWing' => $maguriWing,
|
||||
'inspectionFee' => intval(str_replace(',', '', $inspectionFee)),
|
||||
'estimateList' => json_encode($estimateList),
|
||||
'estimateList_auto' => json_encode($estimateList_auto),
|
||||
'estimateSlatList' => json_encode($estimateSlatList),
|
||||
'estimateSlatList_auto' => json_encode($estimateSlatList_auto),
|
||||
'estimateTotal' => intval(str_replace(',', '', $estimateTotal)),
|
||||
'steel' => $steel,
|
||||
'motor' => $motor,
|
||||
'warranty' => $warranty,
|
||||
'slatcheck' => $slatcheck,
|
||||
'partscheck' => $partscheck
|
||||
];
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. SAM 이관 시 로직 변경
|
||||
|
||||
### Service 클래스 분리
|
||||
```php
|
||||
// app/Services/QuotationService.php
|
||||
class QuotationService
|
||||
{
|
||||
// 1. 견적 생성
|
||||
public function createQuote(array $data): Quote { }
|
||||
|
||||
// 2. 금액 계산
|
||||
public function calculateAmount(Quote $quote): array { }
|
||||
|
||||
// 3. 스크린 계산
|
||||
protected function calculateScreenAmount(array $details): array { }
|
||||
|
||||
// 4. 슬랫 계산
|
||||
protected function calculateSlatAmount(array $details): array { }
|
||||
|
||||
// 5. 모터 용량 결정
|
||||
protected function determineMotorCapacity(float $weight, ?int $inch): int { }
|
||||
|
||||
// 6. 단가 조회
|
||||
protected function getUnitPrice(string $itemCode, array $params): float { }
|
||||
}
|
||||
```
|
||||
|
||||
### 계산 로직 캡슐화
|
||||
```php
|
||||
// app/ValueObjects/QuoteDimension.php
|
||||
class QuoteDimension
|
||||
{
|
||||
public function __construct(
|
||||
public readonly int $width,
|
||||
public readonly int $height,
|
||||
public readonly int $wing = 50
|
||||
) {}
|
||||
|
||||
public function getAreaForScreen(): float
|
||||
{
|
||||
return ($this->height + 550) * $this->width / 1000000;
|
||||
}
|
||||
|
||||
public function getAreaForSlat(): float
|
||||
{
|
||||
return ($this->height + 50) * $this->width / 1000000;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 옵션 처리
|
||||
```php
|
||||
// app/ValueObjects/QuoteOptions.php
|
||||
class QuoteOptions
|
||||
{
|
||||
public function __construct(
|
||||
public readonly bool $steel = false,
|
||||
public readonly bool $motor = false,
|
||||
public readonly bool $warranty = false,
|
||||
public readonly bool $slat = false,
|
||||
public readonly bool $parts = false
|
||||
) {}
|
||||
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
return new self(
|
||||
steel: $data['steel'] ?? false,
|
||||
motor: $data['motor'] ?? false,
|
||||
warranty: $data['warranty'] ?? false,
|
||||
slat: $data['slat'] ?? false,
|
||||
parts: $data['parts'] ?? false
|
||||
);
|
||||
}
|
||||
|
||||
public function toJson(): string
|
||||
{
|
||||
return json_encode([
|
||||
'steel' => $this->steel,
|
||||
'motor' => $this->motor,
|
||||
'warranty' => $this->warranty,
|
||||
'slat' => $this->slat,
|
||||
'parts' => $this->parts
|
||||
]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 참조 파일
|
||||
|
||||
- `5130/estimate/get_screen_amount.php` - 스크린 계산 로직
|
||||
- `5130/estimate/get_slat_amount.php` - 슬랫 계산 로직
|
||||
- `5130/estimate/fetch_unitprice.php` - 단가 조회 함수
|
||||
- `5130/estimate/insert.php` - 저장 로직
|
||||
- `5130/estimate/generate_serial_pjnum.php` - 번호 생성
|
||||
448
projects/quotation/phase-1-5130-analysis/db-structure.md
Normal file
@@ -0,0 +1,448 @@
|
||||
# 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` - 이전 분석
|
||||
471
projects/quotation/phase-1-5130-analysis/js-formulas.md
Normal file
@@ -0,0 +1,471 @@
|
||||
# 5130 견적 수식 분석
|
||||
|
||||
> **핵심 문서** - 모든 견적 계산 수식 상세 분석
|
||||
> **분석 일자:** 2025-12-19
|
||||
|
||||
---
|
||||
|
||||
## 📋 수식 개요
|
||||
|
||||
### 수식 파일 위치
|
||||
| 파일 | 용도 | 핵심 함수 |
|
||||
|------|------|----------|
|
||||
| `common/calculation.js` | 프론트엔드 행 계산 | `calculateRowTotal()` |
|
||||
| `fetch_unitprice.php` | 단가 조회/계산 헬퍼 | 30+ 함수 |
|
||||
| `get_screen_amount.php` | 스크린 견적 계산 | `calculateScreenAmount()` |
|
||||
| `get_slat_amount.php` | 슬랫 견적 계산 | `calculateSlatAmount()` |
|
||||
|
||||
---
|
||||
|
||||
## 🔢 기본 계산 수식
|
||||
|
||||
### 1. 행별 합계 계산 (calculation.js)
|
||||
```javascript
|
||||
// 기본 수식
|
||||
totalPrice = 수량(su) × 단가(unitPrice)
|
||||
|
||||
// 면적 기반 수식
|
||||
if (면적단가 > 0) {
|
||||
단가 = 면적(areaLength) × 면적단가(areaPrice)
|
||||
totalPrice = 수량 × 단가
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 면적 계산
|
||||
```php
|
||||
// 스크린 면적 (m²)
|
||||
// 기본 높이 350에 +550 추가 = 900 기준
|
||||
$calculateHeight = $height + 550;
|
||||
$area = $width * $calculateHeight / 1000000;
|
||||
|
||||
// 슬랫 면적 (m²)
|
||||
// 기본 높이 350에 +50 추가 = 400 기준
|
||||
$calculateHeight = $height + 50;
|
||||
$area = $width * $calculateHeight / 1000000;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💰 항목별 수식 상세
|
||||
|
||||
### 1. 검사비 (인정검사비)
|
||||
```php
|
||||
$inspectionFee = 기본값(50000);
|
||||
$검사비 = $inspectionFee × $수량;
|
||||
```
|
||||
| 입력 | 출력 | 단위 |
|
||||
|------|------|------|
|
||||
| 검사비 단가 | 검사비 총액 | 원 |
|
||||
|
||||
---
|
||||
|
||||
### 2. 주자재 (스크린/슬랫)
|
||||
```php
|
||||
// 스크린 (실리카/와이어)
|
||||
$screen_price = $price_raw_materials × round($area, 2);
|
||||
$주자재_스크린 = $screen_price × $수량;
|
||||
|
||||
// 슬랫 (방화)
|
||||
$slat_price = $price_raw_materials × round($area, 2);
|
||||
$주자재_슬랫 = $slat_price × $수량;
|
||||
```
|
||||
| 입력 | 계산 | 출력 |
|
||||
|------|------|------|
|
||||
| 폭(W), 높이(H), 단가 | 면적 × 단가 × 수량 | 주자재 금액 |
|
||||
|
||||
**조건:** `slatcheck == '1'` 일 때만 슬랫 주자재 계산
|
||||
|
||||
---
|
||||
|
||||
### 3. 조인트바 (슬랫 전용)
|
||||
```php
|
||||
$jointbar_price = $price_jointbar × $item['col76'];
|
||||
```
|
||||
| 입력 | 출력 |
|
||||
|------|------|
|
||||
| 조인트바 개수(col76) × 단가 | 조인트바 금액 |
|
||||
|
||||
**조건:** `slatcheck == '1'` 일 때만 계산
|
||||
|
||||
---
|
||||
|
||||
### 4. 모터
|
||||
```php
|
||||
// 모터 용량 추출 (숫자만)
|
||||
$motorSpec = preg_replace('/[a-zA-Z]/', '', $item['col19']);
|
||||
$motorUnit_price = getPriceForMotor($motorSpec, $itemList);
|
||||
$모터 = $motorUnit_price × $수량;
|
||||
```
|
||||
| 입력 | 조건 | 출력 |
|
||||
|------|------|------|
|
||||
| 모터 용량, 수량 | 모터공급처='경동(견적가포함)' AND motor='1' | 모터 금액 |
|
||||
|
||||
**모터 용량 판별 로직:**
|
||||
```php
|
||||
function calculateMotorSpec($item, $weight, $BracketInch) {
|
||||
// 스크린/철재 구분
|
||||
$ItemSel = (substr($item['col4'], 0, 2) === 'KS') ? '스크린' : '철재';
|
||||
|
||||
// 중량 + 인치 조합으로 용량 결정
|
||||
// 스크린: 150K, 300K, 400K, 500K, 600K
|
||||
// 철재: 300K, 400K, 500K, 600K, 800K, 1000K
|
||||
|
||||
// 예시 조건 (스크린 150K)
|
||||
if ($ItemSel === '스크린' && $BracketInch == 4 && $weight <= 150) {
|
||||
return 150;
|
||||
}
|
||||
// ... 기타 조건들
|
||||
}
|
||||
```
|
||||
|
||||
**모터 용량 매핑표:**
|
||||
| 인치 | 중량 범위 | 스크린 용량 | 철재 용량 |
|
||||
|------|----------|------------|----------|
|
||||
| 4" | ≤150kg | 150K | - |
|
||||
| 4" | ≤300kg | 300K | 300K |
|
||||
| 4" | ≤400kg | 400K | 400K |
|
||||
| 5" | ≤500kg | 500K | 500K |
|
||||
| 5" | ≤600kg | 600K | 600K |
|
||||
| 6" | ≤800kg | - | 800K |
|
||||
| 8" | ≤1000kg | - | 1000K |
|
||||
|
||||
---
|
||||
|
||||
### 5. 연동제어기
|
||||
```php
|
||||
$price1 = calculateControllerSpec($item['col15'], $itemList, '매립형');
|
||||
$price2 = calculateControllerSpec($item['col16'], $itemList, '노출형');
|
||||
$price3 = calculateControllerSpec($item['col17'], $itemList, '뒷박스');
|
||||
|
||||
$controller_price =
|
||||
$price1 × $매립형_수량 +
|
||||
$price2 × $노출형_수량 +
|
||||
$price3 × $뒷박스_수량;
|
||||
```
|
||||
| 유형 | 입력 컬럼 | 설명 |
|
||||
|------|----------|------|
|
||||
| 매립형 | col15 (스크린) / col16 (슬랫) | 벽 매립 타입 |
|
||||
| 노출형 | col16 (스크린) / col17 (슬랫) | 외부 노출 타입 |
|
||||
| 뒷박스 | col17 (스크린) / col18 (슬랫) | 뒷면 박스 타입 |
|
||||
|
||||
---
|
||||
|
||||
### 6. 케이스
|
||||
```php
|
||||
// 규격별 단가 조회 (BDmodels 테이블)
|
||||
if ($item['col36'] === 'custom') {
|
||||
$dimension = $item['col36_custom']; // 커스텀 규격
|
||||
} else {
|
||||
$dimension = $item['col36']; // 표준 규격
|
||||
}
|
||||
|
||||
// 표준 규격이면 단가표에서 조회
|
||||
if (array_key_exists($dimension, $shutterBoxprices)) {
|
||||
$shutter_price = $shutterBoxprices[$dimension] / 1000;
|
||||
} else {
|
||||
// 비표준 규격은 기본 단가 기준 면적비로 계산
|
||||
$basicbox_price = $shutterBoxprices['500*380']; // 스크린 기본
|
||||
// 또는 '650*550' (슬랫 기본)
|
||||
$basicbox_pricePermeter = $basicbox_price / (500 * 380 / 1000);
|
||||
$shutter_price = $basicbox_pricePermeter × $boxwidth × $boxheight / 1000;
|
||||
}
|
||||
|
||||
$케이스 = round($shutter_price × $total_length × 1000) × $수량;
|
||||
```
|
||||
| 조건 | 계산 |
|
||||
|------|------|
|
||||
| steel='1' (절곡 체크) | 단가 × 길이(m) × 수량 |
|
||||
|
||||
---
|
||||
|
||||
### 7. 케이스용 연기차단재
|
||||
```php
|
||||
$boxSmokeBanPrices = BDmodels에서 '케이스용 연기차단재' 단가 조회;
|
||||
$total_length = $item['col37'] / 1000; // mm → m 변환
|
||||
$케이스용_연기차단재 = round($boxSmokeBanPrices × $total_length) × $수량;
|
||||
```
|
||||
| 조건 | 계산 |
|
||||
|------|------|
|
||||
| steel='1' AND 케이스규격 있음 | 단가 × 길이(m) × 수량 |
|
||||
|
||||
---
|
||||
|
||||
### 8. 케이스 마구리
|
||||
```php
|
||||
$maguriCol = $item['col45']; // 마구리 규격
|
||||
$maguriPrices = BDmodels에서 seconditem='마구리' AND spec=$maguriCol 조회;
|
||||
$케이스_마구리 = round($maguriPrices × $수량);
|
||||
```
|
||||
| 조건 | 계산 |
|
||||
|------|------|
|
||||
| steel='1' | 단가 × 수량 |
|
||||
|
||||
---
|
||||
|
||||
### 9. 모터 받침용 앵글
|
||||
```php
|
||||
// 스크린
|
||||
$price_angle = calculateAngle($item['col14'], $itemList, '스크린용');
|
||||
|
||||
// 슬랫 (브라켓 크기 기반)
|
||||
if (empty($item['col21'])) {
|
||||
$bracket_size = searchBracketSize($item['col13'], $item['col22']);
|
||||
} else {
|
||||
$bracket_size = $item['col21'];
|
||||
}
|
||||
$price_angle = calculateAngleBracket_slat($item['col15'], $itemList, $bracket_size);
|
||||
|
||||
$모터받침용_앵글 = round($price_angle × $수량 × 4); // 4개 세트
|
||||
```
|
||||
|
||||
**브라켓 사이즈 결정 로직:**
|
||||
```php
|
||||
function searchBracketSize($motorWeight, $bracketInch) {
|
||||
// 모터 용량 판별
|
||||
$motorCapacity = calculateMotorKG($weight, $inch);
|
||||
|
||||
// 용량별 브라켓 사이즈 매핑
|
||||
if (in_array($motorCapacity, [300, 400])) return '530*320';
|
||||
if (in_array($motorCapacity, [500, 600])) return '600*350';
|
||||
if (in_array($motorCapacity, [800, 1000])) return '690*390';
|
||||
return '530*320'; // 기본값
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 10. 가이드레일
|
||||
```php
|
||||
// 레일 유형에 따른 가격 계산
|
||||
if (strpos($guideType, '혼합') !== false) {
|
||||
// 혼합형: 벽면 + 측면 각각 다른 규격
|
||||
$wallPrice = $guidrailPrices[$wallKey];
|
||||
$sidePrice = $guidrailPrices[$sideKey];
|
||||
$guidrail_price = $wallPrice + $sidePrice; // 1개 세트
|
||||
} else {
|
||||
// 단일형: 벽면 또는 측면
|
||||
$guidrail_price = $guidrailPrices[$guideKey] × 2; // 2개 세트
|
||||
}
|
||||
|
||||
$total_length = $item['col23'] / 1000; // mm → m
|
||||
$가이드레일 = round($guidrail_price × $total_length) × $수량;
|
||||
```
|
||||
|
||||
**가이드레일 키 구성:**
|
||||
```
|
||||
$key = $modelCode|$finishingType|$spec
|
||||
예: KS-100|도장|65*80
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 11. 레일용 연기차단재
|
||||
```php
|
||||
$guiderailSmokeBanPrices = BDmodels에서 '가이드레일용 연기차단재' 조회;
|
||||
$total_length = $item['col23'] / 1000;
|
||||
$레일용_연기차단재 = round($guiderailSmokeBanPrices × $total_length) × 2 × $수량;
|
||||
```
|
||||
| 조건 | 계산 |
|
||||
|------|------|
|
||||
| steel='1' AND 연기차단재 옵션 있음 | 단가 × 길이 × 2(양쪽) × 수량 |
|
||||
|
||||
---
|
||||
|
||||
### 12. 하장바
|
||||
```php
|
||||
$bottomBarPrices = BDmodels에서
|
||||
model_name=$modelCode AND
|
||||
seconditem='하단마감재' AND
|
||||
finishing_type=$finishingType 조회;
|
||||
|
||||
$total_length = $item['col48'] / 1000 × $수량; // 스크린
|
||||
// 또는 $item['col49'] (슬랫)
|
||||
$하장바 = round($bottomBarPrices × $total_length);
|
||||
```
|
||||
| 조건 | 계산 |
|
||||
|------|------|
|
||||
| steel='1' AND 하장바 옵션 있음 | 단가 × 길이 × 수량 |
|
||||
|
||||
---
|
||||
|
||||
### 13. L바 (스크린 전용)
|
||||
```php
|
||||
$LBarPrices = BDmodels에서 seconditem='L-BAR' 조회;
|
||||
$total_length = $item['col51'] / 1000 × $수량;
|
||||
$L바 = round($LBarPrices × $total_length);
|
||||
```
|
||||
| 조건 | 계산 |
|
||||
|------|------|
|
||||
| steel='1' AND L바 옵션 있음 | 단가 × 길이 × 수량 |
|
||||
|
||||
---
|
||||
|
||||
### 14. 보강평철 (스크린 전용)
|
||||
```php
|
||||
$bottomPlatePrices = BDmodels에서 seconditem='보강평철' 조회;
|
||||
$total_length = $item['col54'] / 1000 × $수량;
|
||||
$보강평철 = round($bottomPlatePrices × $total_length);
|
||||
```
|
||||
| 조건 | 계산 |
|
||||
|------|------|
|
||||
| steel='1' AND 보강평철 옵션 있음 | 단가 × 길이 × 수량 |
|
||||
|
||||
---
|
||||
|
||||
### 15. 감기샤프트
|
||||
```php
|
||||
function calculateShaftPrice($item, $pdo) {
|
||||
// 샤프트 규격별 가격 합산
|
||||
// 컬럼: col59~col65 (스크린), col61~col71 (슬랫)
|
||||
|
||||
addShaftPrice($item['col59'], $itemList, '3', '300', $sum); // 3인치 300mm
|
||||
addShaftPrice($item['col60'], $itemList, '4', '3000', $sum); // 4인치 3000mm
|
||||
addShaftPrice($item['col61'], $itemList, '4', '4500', $sum); // 4인치 4500mm
|
||||
// ... 기타 규격
|
||||
|
||||
return $sum_shaft_price;
|
||||
}
|
||||
|
||||
function addShaftPrice($column, $itemList, $size, $length, &$sum) {
|
||||
$shaft_price = calculateShaft($column, $itemList, $size, $length);
|
||||
if ($shaft_price > 0) {
|
||||
$sum += $shaft_price;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**샤프트 규격표:**
|
||||
| 인치 | 길이 | 스크린 컬럼 | 슬랫 컬럼 |
|
||||
|------|------|------------|----------|
|
||||
| 3" | 300mm | col59 | - |
|
||||
| 4" | 3000mm | col60 | col61 |
|
||||
| 4" | 4500mm | col61 | col62 |
|
||||
| 4" | 6000mm | col62 | col63 |
|
||||
| 5" | 6000mm | col63 | col64 |
|
||||
| 5" | 7000mm | col64 | col65 |
|
||||
| 5" | 8200mm | col65 | col66 |
|
||||
| 6" | 3000mm | - | col67 |
|
||||
| 6" | 6000mm | - | col68 |
|
||||
| 6" | 7000mm | - | col69 |
|
||||
| 6" | 8000mm | - | col70 |
|
||||
| 8" | 8200mm | - | col71 |
|
||||
|
||||
---
|
||||
|
||||
### 16. 무게평철 12T (스크린 전용)
|
||||
```php
|
||||
$baseWeightPlatePrice = 12000; // 고정 단가
|
||||
$무게평철 = $baseWeightPlatePrice × $item['col57'];
|
||||
```
|
||||
| 조건 | 계산 |
|
||||
|------|------|
|
||||
| steel='1' | 12,000원 × 개수 |
|
||||
|
||||
---
|
||||
|
||||
### 17. 환봉 (스크린 전용)
|
||||
```php
|
||||
$round_bar_price = 2000; // 고정 단가
|
||||
$round_bar_surang = $item['col70'];
|
||||
$환봉 = round($round_bar_price × $round_bar_surang);
|
||||
```
|
||||
| 조건 | 계산 |
|
||||
|------|------|
|
||||
| steel='1' | 2,000원 × 개수 |
|
||||
|
||||
---
|
||||
|
||||
### 18. 각파이프
|
||||
```php
|
||||
$pipe_price_3000 = calculatePipe($itemList, '1.4', '3000'); // 1.4T 3000mm
|
||||
$pipe_price_6000 = calculatePipe($itemList, '1.4', '6000'); // 1.4T 6000mm
|
||||
|
||||
$pipe_surang_3000 = $item['col68']; // 스크린
|
||||
$pipe_surang_6000 = $item['col69'];
|
||||
// 또는 col74, col75 (슬랫)
|
||||
|
||||
$각파이프_총액 =
|
||||
($pipe_price_3000 × $pipe_surang_3000) +
|
||||
($pipe_price_6000 × $pipe_surang_6000);
|
||||
```
|
||||
| 조건 | 계산 |
|
||||
|------|------|
|
||||
| partscheck='1' | (3000mm 단가 × 수량) + (6000mm 단가 × 수량) |
|
||||
|
||||
---
|
||||
|
||||
### 19. 앵글
|
||||
```php
|
||||
$mainangle_price = calculateMainAngle(1, $itemList, '앵글3T', '2.5'); // 스크린
|
||||
// 또는 '앵글4T' (슬랫)
|
||||
$mainangle_surang = $item['col71']; // 스크린
|
||||
// 또는 col77 (슬랫)
|
||||
$앵글 = round($mainangle_price × $mainangle_surang);
|
||||
```
|
||||
| 조건 | 계산 |
|
||||
|------|------|
|
||||
| partscheck='1' | 단가 × 수량 |
|
||||
|
||||
---
|
||||
|
||||
## 📊 전체 금액 계산
|
||||
|
||||
```php
|
||||
$totalRowAmount = 0;
|
||||
foreach ($rowItemDetails as $key => $value) {
|
||||
if (!in_array($key, ['TotalAmount', 'slatcheck', 'partscheck', 'steel', 'motor', 'warranty'])) {
|
||||
$totalRowAmount += $value;
|
||||
}
|
||||
}
|
||||
$rowItemDetails['TotalAmount'] = round($totalRowAmount);
|
||||
```
|
||||
|
||||
**반환 데이터 구조:**
|
||||
```php
|
||||
return [
|
||||
'total_amount' => $total_amount, // 전체 합계
|
||||
'details' => $sums, // 행별 소계 배열
|
||||
'itemDetails' => $itemDetails, // 항목별 상세 금액
|
||||
'surangSum' => $surangSum // 총 수량
|
||||
];
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🏷️ 테스트 케이스
|
||||
|
||||
### 스크린 견적 예시
|
||||
| 입력 | 값 |
|
||||
|------|-----|
|
||||
| 폭(W) | 3,000mm |
|
||||
| 높이(H) | 2,500mm |
|
||||
| 수량 | 2 |
|
||||
| 모터공급 | 경동(견적가포함) |
|
||||
| 모터용량 | 300K |
|
||||
| 케이스 | 500*380 |
|
||||
| 검사비 | 50,000원 |
|
||||
|
||||
| 항목 | 계산식 | 금액 |
|
||||
|------|--------|------|
|
||||
| 검사비 | 50,000 × 2 | 100,000 |
|
||||
| 주자재 | 면적 × 단가 × 2 | (계산 필요) |
|
||||
| 모터 | 300K 단가 × 2 | (단가표 참조) |
|
||||
| ... | ... | ... |
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 주의사항
|
||||
|
||||
1. **컬럼 번호 차이**: 스크린과 슬랫에서 같은 항목이 다른 컬럼 사용
|
||||
2. **단위 변환**: mm → m 변환 필수 (/ 1000)
|
||||
3. **반올림 처리**: 대부분 `round()` 사용
|
||||
4. **조건부 계산**: 체크박스 옵션에 따라 계산 여부 결정
|
||||
5. **JSON 데이터**: 단가 테이블의 `itemList` 컬럼은 JSON 형식
|
||||
|
||||
---
|
||||
|
||||
## 📚 참조
|
||||
|
||||
- [fetch_unitprice.php](../../../../5130/estimate/fetch_unitprice.php) - 헬퍼 함수
|
||||
- [get_screen_amount.php](../../../../5130/estimate/get_screen_amount.php) - 스크린 계산
|
||||
- [get_slat_amount.php](../../../../5130/estimate/get_slat_amount.php) - 슬랫 계산
|
||||
382
projects/quotation/phase-1-5130-analysis/ui-analysis.md
Normal file
@@ -0,0 +1,382 @@
|
||||
# UI/화면 분석
|
||||
|
||||
> **분석 대상:** 5130 레거시 견적 시스템 화면
|
||||
> **분석 일자:** 2025-12-19
|
||||
|
||||
---
|
||||
|
||||
## 화면 목록
|
||||
|
||||
### 메인 화면
|
||||
| 파일 | 화면명 | 설명 |
|
||||
|------|--------|------|
|
||||
| `list.php` | 견적 목록 | 견적서 리스트, 검색, 필터링 |
|
||||
| `write_form.php` | 견적 작성 | 견적서 작성/수정 폼 (103KB, 핵심 파일) |
|
||||
| `viewEstimate.php` | 견적서 보기 | 견적서 조회/출력 |
|
||||
| `statistics.php` | 견적 통계 | 통계 대시보드 |
|
||||
|
||||
### 견적 유형별 화면
|
||||
| 파일 | 화면명 | 설명 |
|
||||
|------|--------|------|
|
||||
| `estimate.php` | 스크린 견적 | 스크린 견적서 메인 |
|
||||
| `estimateSlat.php` | 슬랫 견적 | 슬랫(철재) 견적서 메인 |
|
||||
| `estimateUnit.php` | 단가 견적 | 단가 기반 견적서 |
|
||||
| `screen_view_original.php` | 스크린 상세 | 스크린 견적 상세 뷰 |
|
||||
| `slat_view_original.php` | 슬랫 상세 | 슬랫 견적 상세 뷰 |
|
||||
|
||||
### 상세/수정 화면
|
||||
| 파일 | 화면명 | 설명 |
|
||||
|------|--------|------|
|
||||
| `edit.php` | 견적 수정 | 스크린 견적 수정 |
|
||||
| `edit_slat.php` | 슬랫 수정 | 슬랫 견적 수정 |
|
||||
| `viewEstimateDetail.php` | 상세 보기 | 견적 상세 정보 |
|
||||
| `EsDetail_screen.php` | 스크린 상세 | 스크린 항목 상세 |
|
||||
| `EsDetail_slat.php` | 슬랫 상세 | 슬랫 항목 상세 |
|
||||
| `compare.php` | 견적 비교 | 견적 버전 비교 |
|
||||
|
||||
### 출력/다운로드
|
||||
| 파일 | 화면명 | 설명 |
|
||||
|------|--------|------|
|
||||
| `print_list.php` | 목록 인쇄 | 견적 목록 인쇄용 |
|
||||
| `downloadExcel.php` | 엑셀 다운로드 | 견적서 엑셀 내보내기 |
|
||||
| `saveExcel.php` | 엑셀 저장 | 엑셀 파일 저장 |
|
||||
|
||||
---
|
||||
|
||||
## 1. 견적 목록 (list.php)
|
||||
|
||||
### 화면 구조
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 견적 List [새로고침] │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ ▷ 123건 접수일 [2025-02-19] ~ [2025-12-19] │
|
||||
│ [전체] [스크린] [철재] 제품모델▼ 검색[______] [검색] │
|
||||
│ [신규] │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 번호│접수일 │견적번호 │구분 │제품│수량│금액 │발주처...│
|
||||
│─────│────────│────────────│──────│────│────│──────│─────────│
|
||||
│ 123 │25-12-19│KD-PR-251219│스크린│KSS01│ 5 │5,000K│(주)ABC │
|
||||
│ 122 │25-12-18│KD-PR-251218│철재 │KFS01│ 3 │3,200K│(주)DEF │
|
||||
│ ... │ │ │ │ │ │ │ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 필터/검색 조건
|
||||
| 항목 | 타입 | 설명 |
|
||||
|------|------|------|
|
||||
| `fromdate` | date | 시작일 (기본: -10개월) |
|
||||
| `todate` | date | 종료일 (기본: +1개월) |
|
||||
| `major_category` | radio | 전체/스크린/철재 |
|
||||
| `model_name` | select | 제품 모델 선택 |
|
||||
| `search` | text | 전체 컬럼 검색 |
|
||||
|
||||
### 테이블 컬럼
|
||||
| 컬럼 | 폭 | 설명 |
|
||||
|------|-----|------|
|
||||
| 번호 | 30px | 일련번호 (역순) |
|
||||
| 접수일 | 100px | indate |
|
||||
| 견적번호 | 100px | pjnum |
|
||||
| 구분 | 80px | major_category (스크린/철재) |
|
||||
| 제품코드 | 80px | model_name |
|
||||
| 수량 | 80px | estimateSurang |
|
||||
| 금액 | 80px | estimateTotal |
|
||||
| 발주처 | 150px | secondord |
|
||||
| 담당자 | 80px | secondordman |
|
||||
| 연락처 | 120px | secondordmantel |
|
||||
| 현장명 | 200px | outworkplace |
|
||||
| 작성자 | 80px | orderman |
|
||||
| 비고 | 300px | comment |
|
||||
|
||||
### 기능 버튼
|
||||
- **새로고침**: `location.reload()`
|
||||
- **검색**: 필터 조건으로 목록 갱신
|
||||
- **신규**: `write_form.php` 이동
|
||||
|
||||
---
|
||||
|
||||
## 2. 견적 작성 폼 (write_form.php)
|
||||
|
||||
### 화면 모드
|
||||
| 모드 | 설명 |
|
||||
|------|------|
|
||||
| 신규 (`mode=''`) | 새 견적 작성 |
|
||||
| 수정 (`mode=modify`) | 기존 견적 수정 |
|
||||
| 복사 (`mode=copy`) | 기존 견적 복사하여 신규 생성 |
|
||||
| 발주 (`header=header`) | 수주에서 발주 산출 |
|
||||
| 스크린 수정 (`itemoption=screen`) | 스크린 발주서 수정 |
|
||||
| 슬랫 수정 (`itemoption=slat`) | 철재스라트 발주서 수정 |
|
||||
|
||||
### 화면 구조 (추정)
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 견적 산출 │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ ┌──────────── 기본 정보 ────────────┐ │
|
||||
│ │ 접수일: [2025-12-19] │ │
|
||||
│ │ 견적번호: KD-PR-251219-01 │ │
|
||||
│ │ 담당자: 홍길동 │ │
|
||||
│ │ 현장명: (주)ABC 빌딩 │ │
|
||||
│ └───────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────── 발주처 정보 ──────────┐ │
|
||||
│ │ 발주처: ____________ │ │
|
||||
│ │ 담당자: ____________ 연락처: ____│ │
|
||||
│ └───────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────── 제품 정보 ────────────┐ │
|
||||
│ │ 대분류: (●)스크린 (○)철재 │ │
|
||||
│ │ 모델명: [KSS01 ▼] │ │
|
||||
│ │ 제작폭: [160] 제작높이: [350] │ │
|
||||
│ │ 마구리윙: [50] │ │
|
||||
│ └───────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────── 옵션 체크 ────────────┐ │
|
||||
│ │ [✓] 절곡 [✓] 모터 [✓] 보증 │ │
|
||||
│ │ [✓] 슬랫 [✓] 부자재 │ │
|
||||
│ └───────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────── 견적 항목 ────────────┐ │
|
||||
│ │ 검사비: [50,000] │ │
|
||||
│ │ │ │
|
||||
│ │ [스크린 견적 테이블] │ │
|
||||
│ │ [슬랫 견적 테이블] │ │
|
||||
│ └───────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────── 금액 합계 ────────────┐ │
|
||||
│ │ 수량: 5 합계: 5,000,000 │ │
|
||||
│ │ 할인율: 10% 할인액: 500,000 │ │
|
||||
│ │ 최종금액: 4,500,000 │ │
|
||||
│ └───────────────────────────────────┘ │
|
||||
│ │
|
||||
│ [저장] [취소] [삭제] │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 주요 입력 필드
|
||||
|
||||
#### 기본 정보
|
||||
| 필드 | 변수명 | 타입 | 기본값 |
|
||||
|------|--------|------|--------|
|
||||
| 접수일 | `indate` | date | 오늘 |
|
||||
| 견적번호 | `pjnum` | text | 자동생성 |
|
||||
| 담당자 | `orderman` | text | 로그인 사용자 |
|
||||
| 현장명 | `outworkplace` | text | - |
|
||||
|
||||
#### 발주처 정보
|
||||
| 필드 | 변수명 | 타입 |
|
||||
|------|--------|------|
|
||||
| 발주처 | `secondord` | text |
|
||||
| 담당자 | `secondordman` | text |
|
||||
| 연락처 | `secondordmantel` | text |
|
||||
|
||||
#### 제품 정보
|
||||
| 필드 | 변수명 | 타입 | 기본값 |
|
||||
|------|--------|------|--------|
|
||||
| 대분류 | `major_category` | radio | 스크린 |
|
||||
| 모델명 | `model_name` | select | - |
|
||||
| 제작폭 | `makeWidth` | number | 160 (스크린), 110 (슬랫) |
|
||||
| 제작높이 | `makeHeight` | number | 350 |
|
||||
| 마구리윙 | `maguriWing` | number | 50 |
|
||||
|
||||
#### 옵션 체크박스
|
||||
| 필드 | 변수명 | 영향 |
|
||||
|------|--------|------|
|
||||
| 절곡 | `steel` | 케이스, 레일, 연기차단재, 하장바, L바, 보강평철 |
|
||||
| 모터 | `motor` | 모터 가격 포함 |
|
||||
| 보증 | `warranty` | 보증기간 표시 |
|
||||
| 슬랫 | `slatcheck` | 주자재(슬랫), 조인트바 |
|
||||
| 부자재 | `partscheck` | 샤프트, 각파이프, 앵글 |
|
||||
|
||||
#### 금액 정보
|
||||
| 필드 | 변수명 | 설명 |
|
||||
|------|--------|------|
|
||||
| 검사비 | `inspectionFee` | 인정검사비 (기본: 50,000) |
|
||||
| 수량 | `estimateSurang` | 총 수량 |
|
||||
| 합계 | `estimateTotal` | 견적 총액 |
|
||||
| 최초합계 | `EstimateFirstSum` | 최초 견적 합계 |
|
||||
| 수정합계 | `EstimateUpdatetSum` | 수정 견적 합계 |
|
||||
| 차액 | `EstimateDiffer` | 최초-수정 차액 |
|
||||
| 할인율 | `EstimateDiscountRate` | % |
|
||||
| 할인액 | `EstimateDiscount` | 원 |
|
||||
| 최종금액 | `EstimateFinalSum` | 최종 결정 금액 |
|
||||
|
||||
### CSS 클래스
|
||||
```css
|
||||
/* 수동 편집된 셀 강조 */
|
||||
.manually-edited {
|
||||
background-color: #f8d7da !important;
|
||||
}
|
||||
|
||||
/* readonly 체크박스 */
|
||||
.readonly-checkbox,
|
||||
.readonly-radio {
|
||||
pointer-events: none;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* 커스텀 너비 */
|
||||
.w-40, .w-50, .w-60, .w-85 { ... }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 견적 항목 테이블
|
||||
|
||||
### 스크린 견적 테이블 (estimateList)
|
||||
| 열 | 필드명 | 설명 |
|
||||
|----|--------|------|
|
||||
| 항목명 | `item_name` | 품목 이름 |
|
||||
| 규격 | `specification` | 규격/사양 |
|
||||
| 단위 | `unit` | EA, m², m, kg |
|
||||
| 수량 | `quantity` | 수량 |
|
||||
| 단가 | `unit_price` | 단가 |
|
||||
| 금액 | `amount` | quantity × unit_price |
|
||||
| 비고 | `remark` | 메모 |
|
||||
|
||||
### 슬랫 견적 테이블 (estimateSlatList)
|
||||
스크린과 동일 구조
|
||||
|
||||
### 자동계산 테이블 (estimateList_auto, estimateSlatList_auto)
|
||||
| 열 | 필드명 | 설명 |
|
||||
|----|--------|------|
|
||||
| 항목코드 | `item_code` | 자동계산 항목 코드 |
|
||||
| 항목명 | `item_name` | 품목 이름 |
|
||||
| 계산타입 | `calc_type` | per_meter, per_area 등 |
|
||||
| 기준값 | `base_value` | 계산 기준 수치 |
|
||||
| 단가 | `unit_price` | 단가 |
|
||||
| 금액 | `amount` | 계산 결과 |
|
||||
|
||||
---
|
||||
|
||||
## 4. API 엔드포인트 (AJAX 호출)
|
||||
|
||||
### 데이터 조회
|
||||
| 엔드포인트 | 용도 |
|
||||
|------------|------|
|
||||
| `fetch_unitprice.php` | 단가 조회 |
|
||||
| `fetch_date.php` | 날짜 정보 |
|
||||
| `fetch_receiver.php` | 수신자 정보 |
|
||||
| `fetch_outworkplace.php` | 현장 목록 |
|
||||
| `fetch_length_data.php` | 길이 데이터 |
|
||||
| `fetch_price.php` | 가격 정보 |
|
||||
|
||||
### 금액 계산
|
||||
| 엔드포인트 | 용도 |
|
||||
|------------|------|
|
||||
| `get_estimate_amount.php` | 견적 금액 라우터 |
|
||||
| `get_screen_amount.php` | 스크린 금액 계산 |
|
||||
| `get_slat_amount.php` | 슬랫 금액 계산 |
|
||||
| `recalc_row.php` | 행 재계산 |
|
||||
|
||||
### 데이터 저장
|
||||
| 엔드포인트 | 용도 |
|
||||
|------------|------|
|
||||
| `insert.php` | 견적 저장 (신규) |
|
||||
| `update.php` | 견적 수정 |
|
||||
| `delete.php` | 견적 삭제 |
|
||||
| `insert_estimate.php` | 견적 등록 |
|
||||
| `insert_detail.php` | 상세 저장 |
|
||||
|
||||
### 기타
|
||||
| 엔드포인트 | 용도 |
|
||||
|------------|------|
|
||||
| `generate_serial_pjnum.php` | 견적번호 생성 |
|
||||
| `get_initial_pjnum.php` | 초기 견적번호 |
|
||||
| `insert_logmenu.php` | 로그 기록 |
|
||||
|
||||
---
|
||||
|
||||
## 5. JavaScript 처리
|
||||
|
||||
### 공통 스크립트 (common/)
|
||||
| 파일 | 용도 |
|
||||
|------|------|
|
||||
| `calculation.js` | 행 계산 로직 |
|
||||
| `lastJS.php` | 페이지 공통 JS |
|
||||
| `common_screen.php` | 스크린 공통 |
|
||||
| `common_slat.php` | 슬랫 공통 |
|
||||
|
||||
### 주요 이벤트 처리
|
||||
```javascript
|
||||
// 수량/단가 변경 시 금액 재계산
|
||||
function calculateRowTotal(row) { ... }
|
||||
|
||||
// 옵션 체크박스 변경 시 항목 재계산
|
||||
$('input[name="steel"]').change(function() { ... });
|
||||
|
||||
// 모델 변경 시 단가 조회
|
||||
$('#model_name').change(function() {
|
||||
// AJAX: fetch_unitprice.php
|
||||
});
|
||||
|
||||
// 크기 변경 시 전체 재계산
|
||||
$('#makeWidth, #makeHeight').change(function() {
|
||||
// AJAX: get_estimate_amount.php
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 사용자 권한
|
||||
|
||||
### 접근 레벨
|
||||
```php
|
||||
// 레벨 5 이하만 접근 가능
|
||||
if(!isset($_SESSION["level"]) || $_SESSION["level"]>5) {
|
||||
header("Location:" . $WebSite . "login/login_form.php");
|
||||
exit;
|
||||
}
|
||||
```
|
||||
|
||||
### 작성 권한자
|
||||
```php
|
||||
$authorities = [
|
||||
"개발자", "전진", "노완호", "이세희",
|
||||
"함신옥", "손금주", "이은진", "이경호"
|
||||
];
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## SAM 이관 시 UI 고려사항
|
||||
|
||||
### 1. Livewire + Blade 전환
|
||||
| 5130 | SAM |
|
||||
|------|-----|
|
||||
| jQuery AJAX | Livewire wire:click |
|
||||
| PHP 직접 렌더링 | Blade 컴포넌트 |
|
||||
| 전역 변수 | Livewire 프로퍼티 |
|
||||
| form submit | wire:submit |
|
||||
|
||||
### 2. 컴포넌트 분리
|
||||
```
|
||||
resources/views/livewire/quotation/
|
||||
├── quote-list.blade.php # 목록
|
||||
├── quote-form.blade.php # 작성/수정
|
||||
├── quote-detail.blade.php # 상세
|
||||
├── components/
|
||||
│ ├── quote-table.blade.php # 견적 테이블
|
||||
│ ├── option-checkboxes.blade.php # 옵션 체크박스
|
||||
│ └── amount-summary.blade.php # 금액 요약
|
||||
```
|
||||
|
||||
### 3. 반응형 개선
|
||||
- 현재: 고정 너비 테이블
|
||||
- 개선: Tailwind 반응형 그리드
|
||||
|
||||
### 4. UX 개선점
|
||||
- 실시간 금액 계산 (debounce 적용)
|
||||
- 자동저장 (draft 기능)
|
||||
- 견적 버전 비교 UI
|
||||
- 모바일 최적화
|
||||
|
||||
---
|
||||
|
||||
## 참조 파일
|
||||
|
||||
- `list.php:111-192` - 목록 테이블 구조
|
||||
- `write_form.php:1-300` - 폼 초기화 로직
|
||||
- `common/calculation.js` - 행 계산 로직
|
||||
- `_row.php` - 행 렌더링 공통
|
||||
- `_request.php` - 요청 파라미터 처리
|
||||
BIN
projects/quotation/screenshots/01-formula-list-main.png
Normal file
|
After Width: | Height: | Size: 359 KiB |
BIN
projects/quotation/screenshots/02-product-dropdown.png
Normal file
|
After Width: | Height: | Size: 368 KiB |
BIN
projects/quotation/screenshots/03-category-management.png
Normal file
|
After Width: | Height: | Size: 245 KiB |
BIN
projects/quotation/screenshots/04-price-formula-management.png
Normal file
|
After Width: | Height: | Size: 213 KiB |
BIN
projects/quotation/screenshots/05-auto-quotation-input.png
Normal file
|
After Width: | Height: | Size: 290 KiB |
BIN
projects/quotation/screenshots/06-category-guiderail.png
Normal file
|
After Width: | Height: | Size: 384 KiB |
BIN
projects/quotation/screenshots/07-formula-add-modal.png
Normal file
|
After Width: | Height: | Size: 373 KiB |