- erp-api-list.md: Phase 5 섹션 추가 (12개 API) - erp-api-detail.md: Phase 5 상세 스펙 추가 - 13. 사용자 초대 (5개): 목록, 발송, 수락, 취소, 재발송 - 14. 알림 설정 (3개): 조회, 수정, 일괄수정 - 15. 계정 관리 (4개): 탈퇴, 사용중지, 약관조회, 약관수정
471 lines
13 KiB
Markdown
471 lines
13 KiB
Markdown
# 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) - 슬랫 계산 |