# 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) - 슬랫 계산