diff --git a/app/Services/Quote/Handlers/KyungdongFormulaHandler.php b/app/Services/Quote/Handlers/KyungdongFormulaHandler.php index 83727ae..af90462 100644 --- a/app/Services/Quote/Handlers/KyungdongFormulaHandler.php +++ b/app/Services/Quote/Handlers/KyungdongFormulaHandler.php @@ -247,6 +247,29 @@ public function calculateScreenPrice(float $width, float $height): array ]; } + /** + * 슬랫(철재) 주자재 가격 계산 + * 5130 공식: W0 × (H0 + 50) / 1,000,000 × 단가 + * + * @return array [unit_price, area, total_price] + */ + public function calculateSlatPrice(float $width, float $height): array + { + $calculateHeight = $height + 50; + $area = ($width * $calculateHeight) / 1000000; + + // 원자재 단가 조회 (방화/슬랫) + $unitPrice = $this->getRawMaterialPrice('방화'); + + $roundedArea = round($area, 2); + + return [ + 'unit_price' => $unitPrice, + 'area' => $roundedArea, + 'total_price' => round($unitPrice * $roundedArea), + ]; + } + // ========================================================================= // 단가 조회 메서드 (EstimatePriceService 사용) // ========================================================================= @@ -360,6 +383,7 @@ public function calculateSteelItems(array $params): array $width = (float) ($params['W0'] ?? 0); $height = (float) ($params['H0'] ?? 0); $quantity = (int) ($params['QTY'] ?? 1); + $productType = $params['product_type'] ?? 'screen'; $modelName = $params['model_name'] ?? $params['product_model'] ?? 'KSS01'; $rawFinish = $params['finishing_type'] ?? 'SUS'; // DB에는 'SUS', 'EGI'로 저장 → 'SUS마감' → 'SUS' 변환 @@ -443,14 +467,17 @@ public function calculateSteelItems(array $params): array $guideItems = $this->calculateGuideRails($modelName, $finishingType, $guideType, $guideSpec, $guideLength, $quantity); $items = array_merge($items, $guideItems); - // 5. 레일용 연기차단재 (단가 × 길이m × 2 × 수량) + // 5. 레일용 연기차단재 + // 스크린: 단가 × 길이m × 2 × 수량 (좌우) + // 슬랫: 단가 × 길이m × 수량 (×2 없음) $railSmokePrice = $this->priceService->getRailSmokeBlockPrice(); if ($railSmokePrice > 0 && $guideLength > 0) { - $railSmokeQty = 2 * $quantity; // 좌우 2개 + $railSmokeMultiplier = ($productType === 'slat') ? 1 : 2; + $railSmokeQty = $railSmokeMultiplier * $quantity; $items[] = [ 'category' => 'steel', 'item_name' => '레일용 연기차단재', - 'specification' => "{$guideLength}m × 2", + 'specification' => ($railSmokeMultiplier > 1) ? "{$guideLength}m × 2" : "{$guideLength}m", 'unit' => 'm', 'quantity' => $guideLength * $railSmokeQty, 'unit_price' => $railSmokePrice, @@ -472,8 +499,8 @@ public function calculateSteelItems(array $params): array ]; } - // 7. L바 (단가 × 길이m × 수량) - $lbarPrice = $this->priceService->getLBarPrice($modelName); + // 7. L바 (단가 × 길이m × 수량) - 스크린 전용, 슬랫 미사용 + $lbarPrice = ($productType !== 'slat') ? $this->priceService->getLBarPrice($modelName) : 0; if ($lbarPrice > 0 && $lbarLength > 0) { $items[] = [ 'category' => 'steel', @@ -486,8 +513,8 @@ public function calculateSteelItems(array $params): array ]; } - // 8. 보강평철 (단가 × 길이m × 수량) - $flatBarPrice = $this->priceService->getFlatBarPrice(); + // 8. 보강평철 (단가 × 길이m × 수량) - 스크린 전용, 슬랫 미사용 + $flatBarPrice = ($productType !== 'slat') ? $this->priceService->getFlatBarPrice() : 0; if ($flatBarPrice > 0 && $flatBarLength > 0) { $items[] = [ 'category' => 'steel', @@ -514,8 +541,8 @@ public function calculateSteelItems(array $params): array ]; } - // 10. 환봉 (고정 2,000원 × 수량) - if ($roundBarQty > 0) { + // 10. 환봉 (고정 2,000원 × 수량) - 스크린 전용, 슬랫 미사용 + if ($roundBarQty > 0 && $productType !== 'slat') { $roundBarPrice = 2000; $items[] = [ 'category' => 'steel', @@ -747,11 +774,13 @@ public function calculatePartItems(array $params): array // 3. 모터 받침용 앵글 (bracket angle) // 5130: calculateAngle(qty, itemList, '스크린용') → col2 검색, qty × $su × 4 + // 5130 슬랫: col23(앵글사이즈) 비어있으면 생략 $motorCapacity = $params['MOTOR_CAPACITY'] ?? '300K'; + $bracketAngleEnabled = (bool) ($params['bracket_angle_enabled'] ?? ($productType !== 'slat')); if ($productType === 'screen') { $angleSearchOption = '스크린용'; } else { - // 철재: bracketSize로 매핑 (530*320→철제300K, 600*350→철제400K, 690*390→철제800K) + // 철재/슬랫: bracketSize로 매핑 $angleSearchOption = match ($bracketSize) { '530*320' => '철제300K', '600*350' => '철제400K', @@ -759,7 +788,7 @@ public function calculatePartItems(array $params): array default => '철제300K', }; } - $anglePrice = $this->getAnglePrice($angleSearchOption); + $anglePrice = $bracketAngleEnabled ? $this->getAnglePrice($angleSearchOption) : 0; if ($anglePrice > 0) { $angleQty = 4 * $quantity; // 5130: $su * 4 $items[] = [ @@ -774,10 +803,11 @@ public function calculatePartItems(array $params): array } // 4. 부자재 앵글 (main angle) - // 5130: calculateMainAngle(1, $itemList, '앵글3T', '2.5') × col71 - $mainAngleType = $bracketSize === '690*390' ? '앵글4T' : '앵글3T'; + // 스크린 5130: calculateMainAngle(1, $itemList, '앵글3T', '2.5') × col71 + // 슬랫 5130: calculateMainAngle(1, $itemList, '앵글4T', '2.5') × col77 + $mainAngleType = ($productType === 'slat') ? '앵글4T' : ($bracketSize === '690*390' ? '앵글4T' : '앵글3T'); $mainAngleSize = '2.5'; - $mainAngleQty = (int) ($params['main_angle_qty'] ?? 2); // col71, default 2 (좌우) + $mainAngleQty = (int) ($params['main_angle_qty'] ?? 2); // col71/col77, default 2 (좌우) $mainAnglePrice = $this->getMainAnglePrice($mainAngleType, $mainAngleSize); if ($mainAnglePrice > 0 && $mainAngleQty > 0) { $items[] = [ @@ -791,6 +821,25 @@ public function calculatePartItems(array $params): array ]; } + // 5. 조인트바 (슬랫 전용, 5130: price × col76, QTY 미적용) + if ($productType === 'slat') { + $jointBarQty = (int) ($params['joint_bar_qty'] ?? 0); + if ($jointBarQty > 0) { + $jointBarPrice = $this->getRawMaterialPrice('조인트바'); + if ($jointBarPrice > 0) { + $items[] = [ + 'category' => 'parts', + 'item_name' => '조인트바', + 'specification' => '', + 'unit' => 'EA', + 'quantity' => $jointBarQty, + 'unit_price' => $jointBarPrice, + 'total_price' => round($jointBarPrice * $jointBarQty), + ]; + } + } + } + return $items; } @@ -844,17 +893,25 @@ public function calculateDynamicItems(array $inputs): array ]; } - // 1. 주자재 (스크린) - $screenResult = $this->calculateScreenPrice($width, $height); + // 1. 주자재 (스크린 또는 슬랫) + if ($productType === 'slat') { + $materialResult = $this->calculateSlatPrice($width, $height); + $materialName = '주자재(슬랫)'; + $materialCode = 'KD-SLAT'; + } else { + $materialResult = $this->calculateScreenPrice($width, $height); + $materialName = '주자재(스크린)'; + $materialCode = 'KD-SCREEN'; + } $items[] = [ 'category' => 'material', - 'item_code' => 'KD-SCREEN', - 'item_name' => '주자재(스크린)', - 'specification' => "면적 {$screenResult['area']}㎡", + 'item_code' => $materialCode, + 'item_name' => $materialName, + 'specification' => "면적 {$materialResult['area']}㎡", 'unit' => '㎡', - 'quantity' => $screenResult['area'] * $quantity, - 'unit_price' => $screenResult['unit_price'], - 'total_price' => $screenResult['total_price'] * $quantity, + 'quantity' => $materialResult['area'] * $quantity, + 'unit_price' => $materialResult['unit_price'], + 'total_price' => $materialResult['total_price'] * $quantity, ]; // 2. 모터