From 3ab4f24bb4c43e4002ae3e2f95ed35c66d7783a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B6=8C=ED=98=81=EC=84=B1?= Date: Sat, 21 Feb 2026 00:34:01 +0900 Subject: [PATCH] =?UTF-8?q?fix(WEB):=20=EC=B2=A0=EC=9E=AC=20=EB=AA=A8?= =?UTF-8?q?=ED=84=B0=EC=9A=A9=EB=9F=89/=EC=85=94=ED=84=B0=EB=B0=95?= =?UTF-8?q?=EC=8A=A4=20=EA=B3=84=EC=82=B0=20=EB=A0=88=EA=B1=B0=EC=8B=9C=20?= =?UTF-8?q?=EC=9D=BC=EC=B9=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - FormulaHandler: 철재 면적 공식 W1×(H1+550) → W1×H1 (레거시 Slat_updateCol12and13 동일) - FormulaHandler: 샤프트 인치 자동계산 추가 (레거시 Slat_updateCol22 동일) - BendingInfoBuilder: 셔터박스 크기를 모터용량→브라켓→박스 매핑으로 결정 (BOM 원자재 코드 BD-케이스-500*380 대신 조립 크기 650*550 등 사용) Co-Authored-By: Claude Opus 4.6 --- .../Production/BendingInfoBuilder.php | 62 ++++++++++++++++--- .../Handlers/Tenant287/FormulaHandler.php | 42 +++++++++++-- 2 files changed, 89 insertions(+), 15 deletions(-) diff --git a/app/Services/Production/BendingInfoBuilder.php b/app/Services/Production/BendingInfoBuilder.php index d1f7ac3..799d75d 100644 --- a/app/Services/Production/BendingInfoBuilder.php +++ b/app/Services/Production/BendingInfoBuilder.php @@ -122,6 +122,9 @@ private function categorizeBomItem(array $bomItem): ?string if (str_starts_with($code, 'BD-보강평철')) { return 'detail_reinforce'; } + if (str_starts_with($code, 'EST-MOTOR-')) { + return 'motor'; + } return null; } @@ -180,6 +183,7 @@ private function assembleBendingInfo(array $productInfo, array $materials, array $caseBom = $agg['bomCategories']['shutterBox_case'] ?? null; $finCoverBom = $agg['bomCategories']['shutterBox_finCover'] ?? null; $lbarBom = $agg['bomCategories']['detail_lbar'] ?? null; + $motorBom = $agg['bomCategories']['motor'] ?? null; $dimGroups = $agg['dimensionGroups']; // 가이드레일 baseSize 추출: BD-가이드레일-KSS01-SUS-120*70 → "120*70" @@ -192,7 +196,7 @@ private function assembleBendingInfo(array $productInfo, array $materials, array 'detailParts' => $this->buildDetailParts($guideRailBom, $lbarBom, $materials), 'guideRail' => $this->buildGuideRail($productInfo['guideType'], $baseSize, $materials, $dimGroups, $productInfo['productCode']), 'bottomBar' => $this->buildBottomBar($materials, $dimGroups), - 'shutterBox' => $this->buildShutterBox($caseBom, $finCoverBom, $baseSize, $dimGroups), + 'shutterBox' => $this->buildShutterBox($caseBom, $finCoverBom, $motorBom, $baseSize, $dimGroups), 'smokeBarrier' => $this->buildSmokeBarrier($dimGroups), ]; } @@ -325,17 +329,24 @@ private function buildBottomBar(array $materials, array $dimGroups): array // shutterBox 섹션 // ───────────────────────────────────────────────── - private function buildShutterBox(?array $caseBom, ?array $finCoverBom, string $guideBaseSize, array $dimGroups): array + private function buildShutterBox(?array $caseBom, ?array $finCoverBom, ?array $motorBom, string $guideBaseSize, array $dimGroups): array { if (! $caseBom) { return []; } - // BD-케이스-500*380 → "500*380" - $caseSize = str_replace('BD-케이스-', '', $caseBom['item_code'] ?? ''); - $caseParts = explode('*', $caseSize); - $caseWidth = (int) ($caseParts[0] ?? 0); - $caseHeight = (int) ($caseParts[1] ?? 0); + // 셔터박스 크기: 모터용량 → 브라켓 → 박스 매핑 (레거시 Slat_updateCol37) + $motorCapacity = $this->extractMotorCapacity($motorBom); + $boxSize = $motorCapacity ? $this->getShutterBoxSize($motorCapacity) : null; + + if (! $boxSize) { + // fallback: BOM 케이스 item_code에서 추출 (BD-케이스-500*380 → "500*380") + $boxSize = str_replace('BD-케이스-', '', $caseBom['item_code'] ?? ''); + } + + $boxParts = explode('*', $boxSize); + $boxWidth = (int) ($boxParts[0] ?? 0); + $boxHeight = (int) ($boxParts[1] ?? 0); // railWidth: 가이드레일 baseSize에서 첫 번째 숫자 (120*70 → 120) $guideParts = explode('*', $guideBaseSize); @@ -355,10 +366,10 @@ private function buildShutterBox(?array $caseBom, ?array $finCoverBom, string $g return [ [ - 'size' => $caseSize, + 'size' => $boxSize, 'direction' => '양면', 'railWidth' => $railWidth, - 'frontBottom' => $caseHeight, + 'frontBottom' => $boxHeight, 'coverQty' => $coverQty, 'finCoverQty' => $finCoverQty, 'lengthData' => $widthData, @@ -647,6 +658,39 @@ private function getMaterialMapping(string $productCode, string $finishMaterial) // 유틸리티 메서드 // ───────────────────────────────────────────────── + /** + * 모터 BOM item_code에서 용량 추출 + * EST-MOTOR-220V-500K → "500K" + */ + private function extractMotorCapacity(?array $motorBom): ?string + { + if (! $motorBom) { + return null; + } + $code = $motorBom['item_code'] ?? ''; + if (preg_match('/(\d+K)$/', $code, $matches)) { + return $matches[1]; + } + + return null; + } + + /** + * 모터용량 → 셔터박스 조립 크기 매핑 + * 레거시 체인: 모터용량(col20) → 브라켓(col21) → 박스크기(col37) + * + * @see 5130/estimate/common/common_addrowJS.php Slat_updateCol21(), Slat_updateCol37() + */ + private function getShutterBoxSize(string $motorCapacity): string + { + return match ($motorCapacity) { + '300K', '400K' => '650*550', + '500K', '600K' => '700*600', + '800K', '1000K' => '780*650', + default => '650*550', + }; + } + /** * 가이드레일 item_code에서 baseSize 추출 * BD-가이드레일-KSS01-SUS-120*70 → "120*70" diff --git a/app/Services/Quote/Handlers/Tenant287/FormulaHandler.php b/app/Services/Quote/Handlers/Tenant287/FormulaHandler.php index c981433..f282856 100644 --- a/app/Services/Quote/Handlers/Tenant287/FormulaHandler.php +++ b/app/Services/Quote/Handlers/Tenant287/FormulaHandler.php @@ -303,6 +303,29 @@ private function getMotorCapacityByWeight(float $weight, ?string $bracketInch = return '1000K'; } + /** + * 샤프트(브라켓) 인치 자동 계산 + * 레거시 5130 Slat_updateCol22() 동일: W1(셔터기장)과 중량으로 결정 + * + * @param float $W1 제조폭 (mm) + * @param float $weight 중량 (kg) + * @return int 샤프트 인치 (4, 5, 6, 8) + */ + private function calculateShaftInch(float $W1, float $weight): int + { + if ($W1 <= 4500) { + return $weight <= 400 ? 4 : 5; + } + if ($W1 <= 5600) { + return $weight <= 600 ? 5 : 6; + } + if ($W1 <= 7800) { + return $weight <= 800 ? 6 : 8; + } + + return 8; + } + // ========================================================================= // 주자재(스크린) 계산 // ========================================================================= @@ -983,16 +1006,23 @@ public function calculateDynamicItems(array $inputs): array // 슬랫: W0 × (H0 + 50) / 1M, 중량 = 면적 × 25 $area = ($width * ($height + 50)) / 1000000; $weight = $area * 25; + } elseif ($productType === 'steel') { + // 철재: W1 × H1 / 1M (레거시 Slat_updateCol12and13 동일) + $W1 = $width + 110; + $H1 = $height + 350; + $area = ($W1 * $H1) / 1000000; + $weight = $area * 25; } else { - // 스크린/철재: W1 × (H1 + 550) / 1M + // 스크린: 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; - } + $weight = $area * 2 + ($width / 1000) * 14.17; + } + + // 샤프트 인치: 철재는 W1/중량 기반 자동계산 (레거시 Slat_updateCol22 동일) + if ($productType === 'steel' && ! isset($inputs['bracket_inch'])) { + $bracketInch = (string) $this->calculateShaftInch($W1 ?? ($width + 110), $weight); } // 모터 용량/브라켓 크기 계산 (입력값 우선, 없으면 자동계산)