fix: FormulaEvaluatorService 슬랫 통합 및 면적/중량 공식 수정
- FormulaEvaluatorService: 슬랫 면적 공식 분리 (W0×(H0+50) vs W1×(H1+550)) - FormulaEvaluatorService: MOTOR_CAPACITY/BRACKET_SIZE 입력값 우선 처리 - KyungdongFormulaHandler: calculateDynamicItems 면적/중량 제품타입별 분기 - KyungdongFormulaHandler: normalizeGuideType() 추가 (벽면↔벽면형 호환) - KyungdongFormulaHandler: guide_rail_spec 파라미터 별칭 지원 - 검증: 스크린/슬랫 5치수×3수량 전체 5130 정합성 확인 (±1원 이내) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1627,27 +1627,45 @@ private function calculateKyungdongBom(
|
||||
// KyungdongFormulaHandler 인스턴스 생성
|
||||
$handler = new KyungdongFormulaHandler;
|
||||
|
||||
// Step 3: 경동 전용 변수 계산
|
||||
// Step 3: 경동 전용 변수 계산 (제품타입별 면적/중량 공식)
|
||||
$W1 = $W0 + 160;
|
||||
$H1 = $H0 + 350;
|
||||
$area = ($W1 * ($H1 + 550)) / 1000000;
|
||||
|
||||
// 중량 계산 (제품타입별)
|
||||
if ($productType === 'steel') {
|
||||
if ($productType === 'slat') {
|
||||
// 슬랫: W0 × (H0 + 50) / 1M
|
||||
$area = ($W0 * ($H0 + 50)) / 1000000;
|
||||
$weight = $area * 25;
|
||||
$weightFormula = "AREA × 25";
|
||||
$areaFormula = '(W0 × (H0 + 50)) / 1,000,000';
|
||||
$areaCalc = "({$W0} × ({$H0} + 50)) / 1,000,000";
|
||||
$weightFormula = 'AREA × 25';
|
||||
$weightCalc = "{$area} × 25";
|
||||
} elseif ($productType === 'steel') {
|
||||
// 철재: W1 × (H1 + 550) / 1M, 중량 = 면적 × 25
|
||||
$area = ($W1 * ($H1 + 550)) / 1000000;
|
||||
$weight = $area * 25;
|
||||
$areaFormula = '(W1 × (H1 + 550)) / 1,000,000';
|
||||
$areaCalc = "({$W1} × ({$H1} + 550)) / 1,000,000";
|
||||
$weightFormula = 'AREA × 25';
|
||||
$weightCalc = "{$area} × 25";
|
||||
} else {
|
||||
// 스크린: W1 × (H1 + 550) / 1M
|
||||
$area = ($W1 * ($H1 + 550)) / 1000000;
|
||||
$weight = $area * 2 + ($W0 / 1000) * 14.17;
|
||||
$weightFormula = "AREA × 2 + (W0 / 1000) × 14.17";
|
||||
$areaFormula = '(W1 × (H1 + 550)) / 1,000,000';
|
||||
$areaCalc = "({$W1} × ({$H1} + 550)) / 1,000,000";
|
||||
$weightFormula = 'AREA × 2 + (W0 / 1000) × 14.17';
|
||||
$weightCalc = "{$area} × 2 + ({$W0} / 1000) × 14.17";
|
||||
}
|
||||
|
||||
// 모터 용량 결정
|
||||
$motorCapacity = $handler->calculateMotorCapacity($productType, $weight, $bracketInch);
|
||||
// 모터 용량 결정 (입력값 우선, 없으면 자동계산)
|
||||
$motorCapacity = $inputVariables['MOTOR_CAPACITY']
|
||||
?? $inputVariables['motor_capacity']
|
||||
?? $handler->calculateMotorCapacity($productType, $weight, $bracketInch);
|
||||
|
||||
// 브라켓 크기 결정
|
||||
$bracketSize = $handler->calculateBracketSize($weight, $bracketInch);
|
||||
// 브라켓 크기 결정 (입력값 우선, 없으면 자동계산)
|
||||
$bracketSize = $inputVariables['BRACKET_SIZE']
|
||||
?? $inputVariables['bracket_size']
|
||||
?? $handler->calculateBracketSize($weight, $bracketInch);
|
||||
|
||||
// 핸들러가 필요한 키 보장 (inputVariables에서 전달되지 않으면 기본값)
|
||||
$productModel = $inputVariables['product_model'] ?? 'KSS01';
|
||||
@@ -1692,8 +1710,8 @@ private function calculateKyungdongBom(
|
||||
[
|
||||
'var' => 'AREA',
|
||||
'desc' => '면적',
|
||||
'formula' => '(W1 × (H1 + 550)) / 1,000,000',
|
||||
'calculation' => "({$W1} × ({$H1} + 550)) / 1,000,000",
|
||||
'formula' => $areaFormula,
|
||||
'calculation' => $areaCalc,
|
||||
'result' => round($area, 4),
|
||||
'unit' => '㎡',
|
||||
],
|
||||
|
||||
@@ -392,8 +392,8 @@ public function calculateSteelItems(array $params): array
|
||||
// 절곡품 관련 파라미터
|
||||
$caseSpec = $params['case_spec'] ?? '500*380';
|
||||
$caseLength = (float) ($params['case_length'] ?? ($width + 220)); // mm 단위 (레거시: W0+220)
|
||||
$guideType = $params['guide_type'] ?? '벽면형'; // 벽면형, 측면형, 혼합형
|
||||
$guideSpec = $params['guide_spec'] ?? '120*70'; // 120*70, 120*100
|
||||
$guideType = $this->normalizeGuideType($params['guide_type'] ?? '벽면형');
|
||||
$guideSpec = $params['guide_spec'] ?? $params['guide_rail_spec'] ?? '120*70';
|
||||
$guideLength = (float) ($params['guide_length'] ?? ($height + 250)) / 1000; // m 단위 (레거시: H0+250)
|
||||
$bottomBarLength = (float) ($params['bottombar_length'] ?? $width) / 1000; // m 단위 (레거시: W0)
|
||||
$lbarLength = (float) ($params['lbar_length'] ?? ($width + 220)) / 1000; // m 단위 (레거시: W0+220)
|
||||
@@ -669,6 +669,22 @@ private function calculateGuideRails(
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* 가이드타입 정규화 (5130 ↔ SAM 호환)
|
||||
*
|
||||
* 5130: '벽면', '측면', '혼합' (col6 필드)
|
||||
* SAM: '벽면형', '측면형', '혼합형' (switch case)
|
||||
*/
|
||||
private function normalizeGuideType(string $type): string
|
||||
{
|
||||
return match ($type) {
|
||||
'벽면', '벽면형' => '벽면형',
|
||||
'측면', '측면형' => '측면형',
|
||||
'혼합', '혼합형' => '혼합형',
|
||||
default => $type,
|
||||
};
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// 부자재 계산 (3종)
|
||||
// =========================================================================
|
||||
@@ -863,11 +879,22 @@ public function calculateDynamicItems(array $inputs): array
|
||||
$bracketInch = $inputs['bracket_inch'] ?? '5';
|
||||
$productType = $inputs['product_type'] ?? 'screen';
|
||||
|
||||
// 중량 계산 (5130 로직) - W1, H1 기반
|
||||
$W1 = $width + 160;
|
||||
$H1 = $height + 350;
|
||||
$area = ($W1 * ($H1 + 550)) / 1000000;
|
||||
$weight = $area * ($productType === 'steel' ? 25 : 2) + ($width / 1000) * 14.17;
|
||||
// 중량 계산 (5130 로직) - 제품타입별 면적/중량 공식
|
||||
if ($productType === 'slat') {
|
||||
// 슬랫: W0 × (H0 + 50) / 1M, 중량 = 면적 × 25
|
||||
$area = ($width * ($height + 50)) / 1000000;
|
||||
$weight = $area * 25;
|
||||
} else {
|
||||
// 스크린/철재: W1 × (H1 + 550) / 1M
|
||||
$W1 = $width + 160;
|
||||
$H1 = $height + 350;
|
||||
$area = ($W1 * ($H1 + 550)) / 1000000;
|
||||
if ($productType === 'steel') {
|
||||
$weight = $area * 25;
|
||||
} else {
|
||||
$weight = $area * 2 + ($width / 1000) * 14.17;
|
||||
}
|
||||
}
|
||||
|
||||
// 모터 용량/브라켓 크기 계산 (입력값 우선, 없으면 자동계산)
|
||||
$motorCapacity = $inputs['MOTOR_CAPACITY'] ?? $this->calculateMotorCapacity($productType, $weight, $bracketInch);
|
||||
@@ -967,7 +994,7 @@ public function calculateDynamicItems(array $inputs): array
|
||||
// 4. 절곡품
|
||||
// installation_type → guide_type 매핑 (calculateSteelItems는 guide_type 사용)
|
||||
if (isset($inputs['installation_type']) && ! isset($inputs['guide_type'])) {
|
||||
$inputs['guide_type'] = $inputs['installation_type'];
|
||||
$inputs['guide_type'] = $this->normalizeGuideType($inputs['installation_type']);
|
||||
}
|
||||
$steelItems = $this->calculateSteelItems($inputs);
|
||||
$items = array_merge($items, $steelItems);
|
||||
|
||||
Reference in New Issue
Block a user