fix: 5130 견적 금액 정합성 수정 (5항목)
- guide_type 매핑: installation_type → guide_type 파라미터 전달 추가 (측면형/혼합형 가이드레일 가격 반영) - 제어기/뒷박스 수량: QTY 곱셈 제거 (5130 동일: col15/col16/col17은 고정 수량) - 샤프트 규격 매핑: W0 기반 임의 길이 → 5130 고정 제품(5인치: 6/7/8.2m)으로 매핑 - 환봉/앵글 이중 곱셈 수정: 자동계산에 이미 QTY 포함, 추가 곱셈 제거 - 모터/브라켓 입력값 우선: MOTOR_CAPACITY/BRACKET_SIZE 입력 시 자동계산 대신 사용 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -283,6 +283,33 @@ public function getShaftPrice(string $size, float $length): float
|
||||
return $this->priceService->getShaftPrice($size, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* 5130 고정 샤프트 제품 규격 매핑
|
||||
* col59~65: 3인치 300, 4인치 3000/4500/6000, 5인치 6000/7000/8200
|
||||
*
|
||||
* @param string $size 인치 (3, 4, 5)
|
||||
* @param float $lengthMm W0 올림값 (mm)
|
||||
* @return float 매핑된 길이 (m 단위), 0이면 매핑 불가
|
||||
*/
|
||||
private function mapShaftToFixedProduct(string $size, float $lengthMm): float
|
||||
{
|
||||
$products = match ($size) {
|
||||
'3' => [300],
|
||||
'4' => [3000, 4500, 6000],
|
||||
'5' => [6000, 7000, 8200],
|
||||
default => [6000, 7000, 8200], // 기본 5인치
|
||||
};
|
||||
|
||||
// 올림값 이상인 제품 중 가장 작은 것 선택
|
||||
foreach ($products as $productMm) {
|
||||
if ($lengthMm <= $productMm) {
|
||||
return $productMm / 1000; // mm → m
|
||||
}
|
||||
}
|
||||
|
||||
return 0; // 매핑 불가 (초과)
|
||||
}
|
||||
|
||||
/**
|
||||
* 파이프 단가 조회
|
||||
*/
|
||||
@@ -495,9 +522,9 @@ public function calculateSteelItems(array $params): array
|
||||
'item_name' => '환봉',
|
||||
'specification' => '',
|
||||
'unit' => 'EA',
|
||||
'quantity' => $roundBarQty * $quantity,
|
||||
'quantity' => $roundBarQty,
|
||||
'unit_price' => $roundBarPrice,
|
||||
'total_price' => $roundBarPrice * $roundBarQty * $quantity,
|
||||
'total_price' => $roundBarPrice * $roundBarQty,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -635,10 +662,12 @@ public function calculatePartItems(array $params): array
|
||||
$productType = $params['product_type'] ?? 'screen';
|
||||
$quantity = (int) ($params['QTY'] ?? 1);
|
||||
|
||||
// 1. 감기샤프트
|
||||
// 1. 감기샤프트 (5130: col59~65 고정 제품)
|
||||
// 5130 고정 규격: 3인치→0.3m, 4인치→3/4.5/6m, 5인치→6/7/8.2m
|
||||
$shaftSize = $bracketInch;
|
||||
$shaftLength = ceil($width / 1000); // mm → m 변환 후 올림
|
||||
$shaftPrice = $this->getShaftPrice($shaftSize, $shaftLength);
|
||||
$shaftLengthMm = ceil($width / 1000) * 1000; // W0 → 올림 (mm)
|
||||
$shaftLength = $this->mapShaftToFixedProduct($shaftSize, $shaftLengthMm);
|
||||
$shaftPrice = $shaftLength > 0 ? $this->getShaftPrice($shaftSize, $shaftLength) : 0;
|
||||
if ($shaftPrice > 0) {
|
||||
$items[] = [
|
||||
'category' => 'parts',
|
||||
@@ -756,9 +785,9 @@ public function calculatePartItems(array $params): array
|
||||
'item_name' => "앵글 {$mainAngleType}",
|
||||
'specification' => "{$mainAngleSize}m",
|
||||
'unit' => 'EA',
|
||||
'quantity' => $mainAngleQty * $quantity,
|
||||
'quantity' => $mainAngleQty,
|
||||
'unit_price' => $mainAnglePrice,
|
||||
'total_price' => $mainAnglePrice * $mainAngleQty * $quantity,
|
||||
'total_price' => $mainAnglePrice * $mainAngleQty,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -791,9 +820,9 @@ public function calculateDynamicItems(array $inputs): array
|
||||
$area = ($W1 * ($H1 + 550)) / 1000000;
|
||||
$weight = $area * ($productType === 'steel' ? 25 : 2) + ($width / 1000) * 14.17;
|
||||
|
||||
// 모터 용량/브라켓 크기 계산
|
||||
$motorCapacity = $this->calculateMotorCapacity($productType, $weight, $bracketInch);
|
||||
$bracketSize = $this->calculateBracketSize($weight, $bracketInch);
|
||||
// 모터 용량/브라켓 크기 계산 (입력값 우선, 없으면 자동계산)
|
||||
$motorCapacity = $inputs['MOTOR_CAPACITY'] ?? $this->calculateMotorCapacity($productType, $weight, $bracketInch);
|
||||
$bracketSize = $inputs['BRACKET_SIZE'] ?? $this->calculateBracketSize($weight, $bracketInch);
|
||||
|
||||
// 입력값에 계산된 값 추가 (부자재 계산용)
|
||||
$inputs['WEIGHT'] = $weight;
|
||||
@@ -842,6 +871,8 @@ public function calculateDynamicItems(array $inputs): array
|
||||
];
|
||||
|
||||
// 3. 제어기 (5130: 매립형×col15 + 노출형×col16 + 뒷박스×col17)
|
||||
// 5130: 제어기 = price_매립 × col15 + price_노출 × col16 + price_뒷박스 × col17
|
||||
// col15/col16/col17은 고정 수량 (QTY와 무관, $su를 곱하지 않음)
|
||||
$controllerType = $inputs['controller_type'] ?? '매립형';
|
||||
$controllerQty = (int) ($inputs['controller_qty'] ?? 1);
|
||||
$controllerPrice = $this->getControllerPrice($controllerType);
|
||||
@@ -852,13 +883,13 @@ public function calculateDynamicItems(array $inputs): array
|
||||
'item_name' => "제어기 {$controllerType}",
|
||||
'specification' => $controllerType,
|
||||
'unit' => 'EA',
|
||||
'quantity' => $controllerQty * $quantity,
|
||||
'quantity' => $controllerQty,
|
||||
'unit_price' => $controllerPrice,
|
||||
'total_price' => $controllerPrice * $controllerQty * $quantity,
|
||||
'total_price' => $controllerPrice * $controllerQty,
|
||||
];
|
||||
}
|
||||
|
||||
// 뒷박스 (5130: col17 수량)
|
||||
// 뒷박스 (5130: col17 수량, QTY와 무관)
|
||||
$backboxQty = (int) ($inputs['backbox_qty'] ?? 1);
|
||||
if ($backboxQty > 0) {
|
||||
$backboxPrice = $this->getControllerPrice('뒷박스');
|
||||
@@ -869,14 +900,18 @@ public function calculateDynamicItems(array $inputs): array
|
||||
'item_name' => '뒷박스',
|
||||
'specification' => '',
|
||||
'unit' => 'EA',
|
||||
'quantity' => $backboxQty * $quantity,
|
||||
'quantity' => $backboxQty,
|
||||
'unit_price' => $backboxPrice,
|
||||
'total_price' => $backboxPrice * $backboxQty * $quantity,
|
||||
'total_price' => $backboxPrice * $backboxQty,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 절곡품
|
||||
// installation_type → guide_type 매핑 (calculateSteelItems는 guide_type 사용)
|
||||
if (isset($inputs['installation_type']) && ! isset($inputs['guide_type'])) {
|
||||
$inputs['guide_type'] = $inputs['installation_type'];
|
||||
}
|
||||
$steelItems = $this->calculateSteelItems($inputs);
|
||||
$items = array_merge($items, $steelItems);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user