Files
sam-docs/projects/quotation/phase-1-5130-analysis/js-formulas.md
hskwon 1066ea25b2 docs: Phase 5 API 문서 추가 (사용자 초대, 알림설정, 계정관리)
- erp-api-list.md: Phase 5 섹션 추가 (12개 API)
- erp-api-detail.md: Phase 5 상세 스펙 추가
  - 13. 사용자 초대 (5개): 목록, 발송, 수락, 취소, 재발송
  - 14. 알림 설정 (3개): 조회, 수정, 일괄수정
  - 15. 계정 관리 (4개): 탈퇴, 사용중지, 약관조회, 약관수정
2025-12-19 15:35:41 +09:00

13 KiB
Raw Blame History

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)

// 기본 수식
totalPrice = 수량(su) × 단가(unitPrice)

// 면적 기반 수식
if (면적단가 > 0) {
    단가 = 면적(areaLength) × 면적단가(areaPrice)
    totalPrice = 수량 × 단가
}

2. 면적 계산

// 스크린 면적 (m²)
// 기본 높이 350에 +550 추가 = 900 기준
$calculateHeight = $height + 550;
$area = $width * $calculateHeight / 1000000;

// 슬랫 면적 (m²)
// 기본 높이 350에 +50 추가 = 400 기준
$calculateHeight = $height + 50;
$area = $width * $calculateHeight / 1000000;

💰 항목별 수식 상세

1. 검사비 (인정검사비)

$inspectionFee = 기본값(50000);
$검사비 = $inspectionFee × $수량;
입력 출력 단위
검사비 단가 검사비 총액

2. 주자재 (스크린/슬랫)

// 스크린 (실리카/와이어)
$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. 조인트바 (슬랫 전용)

$jointbar_price = $price_jointbar × $item['col76'];
입력 출력
조인트바 개수(col76) × 단가 조인트바 금액

조건: slatcheck == '1' 일 때만 계산


4. 모터

// 모터 용량 추출 (숫자만)
$motorSpec = preg_replace('/[a-zA-Z]/', '', $item['col19']);
$motorUnit_price = getPriceForMotor($motorSpec, $itemList);
$모터 = $motorUnit_price × $수량;
입력 조건 출력
모터 용량, 수량 모터공급처='경동(견적가포함)' AND motor='1' 모터 금액

모터 용량 판별 로직:

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. 연동제어기

$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. 케이스

// 규격별 단가 조회 (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. 케이스용 연기차단재

$boxSmokeBanPrices = BDmodels에서 '케이스용 연기차단재' 단가 조회;
$total_length = $item['col37'] / 1000;  // mm → m 변환
$케이스용_연기차단재 = round($boxSmokeBanPrices × $total_length) × $수량;
조건 계산
steel='1' AND 케이스규격 있음 단가 × 길이(m) × 수량

8. 케이스 마구리

$maguriCol = $item['col45'];  // 마구리 규격
$maguriPrices = BDmodels에서 seconditem='마구리' AND spec=$maguriCol 조회;
$케이스_마구리 = round($maguriPrices × $수량);
조건 계산
steel='1' 단가 × 수량

9. 모터 받침용 앵글

// 스크린
$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개 세트

브라켓 사이즈 결정 로직:

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. 가이드레일

// 레일 유형에 따른 가격 계산
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. 레일용 연기차단재

$guiderailSmokeBanPrices = BDmodels에서 '가이드레일용 연기차단재' 조회;
$total_length = $item['col23'] / 1000;
$레일용_연기차단재 = round($guiderailSmokeBanPrices × $total_length) × 2 × $수량;
조건 계산
steel='1' AND 연기차단재 옵션 있음 단가 × 길이 × 2(양쪽) × 수량

12. 하장바

$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바 (스크린 전용)

$LBarPrices = BDmodels에서 seconditem='L-BAR' 조회;
$total_length = $item['col51'] / 1000 × $수량;
$L바 = round($LBarPrices × $total_length);
조건 계산
steel='1' AND L바 옵션 있음 단가 × 길이 × 수량

14. 보강평철 (스크린 전용)

$bottomPlatePrices = BDmodels에서 seconditem='보강평철' 조회;
$total_length = $item['col54'] / 1000 × $수량;
$보강평철 = round($bottomPlatePrices × $total_length);
조건 계산
steel='1' AND 보강평철 옵션 있음 단가 × 길이 × 수량

15. 감기샤프트

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 (스크린 전용)

$baseWeightPlatePrice = 12000;  // 고정 단가
$무게평철 = $baseWeightPlatePrice × $item['col57'];
조건 계산
steel='1' 12,000원 × 개수

17. 환봉 (스크린 전용)

$round_bar_price = 2000;  // 고정 단가
$round_bar_surang = $item['col70'];
$환봉 = round($round_bar_price × $round_bar_surang);
조건 계산
steel='1' 2,000원 × 개수

18. 각파이프

$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. 앵글

$mainangle_price = calculateMainAngle(1, $itemList, '앵글3T', '2.5');  // 스크린
// 또는 '앵글4T' (슬랫)
$mainangle_surang = $item['col71'];  // 스크린
// 또는 col77 (슬랫)
$앵글 = round($mainangle_price × $mainangle_surang);
조건 계산
partscheck='1' 단가 × 수량

📊 전체 금액 계산

$totalRowAmount = 0;
foreach ($rowItemDetails as $key => $value) {
    if (!in_array($key, ['TotalAmount', 'slatcheck', 'partscheck', 'steel', 'motor', 'warranty'])) {
        $totalRowAmount += $value;
    }
}
$rowItemDetails['TotalAmount'] = round($totalRowAmount);

반환 데이터 구조:

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 형식

📚 참조