feat: [inspection] 절곡 검사 마감유형(S1/S2/S3) 프로파일 분리 — 5130 레거시 기준

- BENDING_GAP_PROFILES를 S1/S2/S3 + common 계층 구조로 재구성
  - S1(KSS01): 벽면 4pt, 측면 6pt, 하단 1pt
  - S2(KSS02): 벽면 3pt, 측면 5pt, 하단 1pt
  - S3(KWE01/KSE01+SUS): 벽면 5pt, 측면 7pt, 하단 2pt
- resolveFinishingType() 신규: product_code → 마감유형 자동 판별
- buildBendingInspectionItems()에 마감유형별 프로파일 적용
- getInspectionConfig() 응답에 finishing_type 필드 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-27 17:36:28 +09:00
parent f970b6bf4b
commit afc1aa72a8

View File

@@ -1955,57 +1955,124 @@ public function getInspectionData(int $workOrderId, array $params = []): array
// ──────────────────────────────────────────────────────────────
/**
* 절곡 검사 기준 간격 프로파일 (단면 치수 공학 사양)
* 절곡 검사 기준 간격 프로파일 (5130 레거시 기준 S1/S2/S3 마감유형별)
*
* S1: KSS01 계열 (KQTS01 포함)
* S2: KSS02 계열 (EGI 마감 포함)
* S3: KWE01/KSE01 + SUS 별도마감
*
* 향후 DB 테이블 또는 테넌트 설정으로 이관 가능
*/
private const BENDING_GAP_PROFILES = [
'guide_rail_wall' => [
'name' => '가이드레일 벽면',
'gap_points' => [
['point' => '(1)', 'design_value' => '30'],
['point' => '(2)', 'design_value' => '78'],
['point' => '(3)', 'design_value' => '25'],
['point' => '(4)', 'design_value' => '45'],
'S1' => [
'guide_rail_wall' => [
'name' => '가이드레일(벽면형)',
'gap_points' => [
['point' => '(1)', 'design_value' => '30'],
['point' => '(2)', 'design_value' => '80'],
['point' => '(3)', 'design_value' => '45'],
['point' => '(4)', 'design_value' => '40'],
],
],
'guide_rail_side' => [
'name' => '가이드레일(측면형)',
'gap_points' => [
['point' => '(1)', 'design_value' => '30'],
['point' => '(2)', 'design_value' => '70'],
['point' => '(3)', 'design_value' => '45'],
['point' => '(4)', 'design_value' => '35'],
['point' => '(5)', 'design_value' => '95'],
['point' => '(6)', 'design_value' => '90'],
],
],
'bottom_bar' => [
'name' => '하단마감재',
'gap_points' => [
['point' => '(1)', 'design_value' => '60'],
],
],
],
'guide_rail_side' => [
'name' => '가이드레일 측면',
'gap_points' => [
['point' => '(1)', 'design_value' => '28'],
['point' => '(2)', 'design_value' => '75'],
['point' => '(3)', 'design_value' => '42'],
['point' => '(4)', 'design_value' => '38'],
['point' => '(5)', 'design_value' => '32'],
'S2' => [
'guide_rail_wall' => [
'name' => '가이드레일(벽면형)',
'gap_points' => [
['point' => '(1)', 'design_value' => '30'],
['point' => '(2)', 'design_value' => '80'],
['point' => '(3)', 'design_value' => '45'],
],
],
'guide_rail_side' => [
'name' => '가이드레일(측면형)',
'gap_points' => [
['point' => '(1)', 'design_value' => '30'],
['point' => '(2)', 'design_value' => '70'],
['point' => '(3)', 'design_value' => '45'],
['point' => '(4)', 'design_value' => '35'],
['point' => '(5)', 'design_value' => '95'],
],
],
'bottom_bar' => [
'name' => '하단마감재',
'gap_points' => [
['point' => '(1)', 'design_value' => '60'],
],
],
],
'bottom_bar' => [
'name' => '하단마감재',
'gap_points' => [
['point' => '(1)', 'design_value' => '60'],
'S3' => [
'guide_rail_wall' => [
'name' => '가이드레일(벽면형·별도마감)',
'gap_points' => [
['point' => '(1)', 'design_value' => '30'],
['point' => '(2)', 'design_value' => '80'],
['point' => '(3)', 'design_value' => '45'],
['point' => '(4)', 'design_value' => '40'],
['point' => '(5)', 'design_value' => '34'],
],
],
'guide_rail_side' => [
'name' => '가이드레일(측면형·별도마감)',
'gap_points' => [
['point' => '(1)', 'design_value' => '30'],
['point' => '(2)', 'design_value' => '70'],
['point' => '(3)', 'design_value' => '80'],
['point' => '(4)', 'design_value' => '45'],
['point' => '(5)', 'design_value' => '40'],
['point' => '(6)', 'design_value' => '34'],
['point' => '(7)', 'design_value' => '74'],
],
],
'bottom_bar' => [
'name' => '하단마감재(별도마감)',
'gap_points' => [
['point' => '(1)', 'design_value' => '60'],
['point' => '(2)', 'design_value' => '64'],
],
],
],
'case_box' => [
'name' => '케이스',
'gap_points' => [
['point' => '(1)', 'design_value' => '550'],
['point' => '(2)', 'design_value' => '50'],
['point' => '(3)', 'design_value' => '385'],
['point' => '(4)', 'design_value' => '50'],
['point' => '(5)', 'design_value' => '410'],
'common' => [
'case_box' => [
'name' => '케이스',
'gap_points' => [
['point' => '(1)', 'design_value' => '550'],
['point' => '(2)', 'design_value' => '50'],
['point' => '(3)', 'design_value' => '385'],
['point' => '(4)', 'design_value' => '50'],
['point' => '(5)', 'design_value' => '410'],
],
],
],
'smoke_w50' => [
'name' => '연기차단재 W50',
'gap_points' => [
['point' => '(1)', 'design_value' => '50'],
['point' => '(2)', 'design_value' => '12'],
'smoke_w50' => [
'name' => '연기차단재 W50',
'gap_points' => [
['point' => '(1)', 'design_value' => '50'],
['point' => '(2)', 'design_value' => '12'],
],
],
],
'smoke_w80' => [
'name' => '연기차단재 W80',
'gap_points' => [
['point' => '(1)', 'design_value' => '80'],
['point' => '(2)', 'design_value' => '12'],
'smoke_w80' => [
'name' => '연기차단재 W80',
'gap_points' => [
['point' => '(1)', 'design_value' => '80'],
['point' => '(2)', 'design_value' => '12'],
],
],
],
];
@@ -2030,7 +2097,9 @@ public function getInspectionConfig(int $workOrderId): array
$templateId = $process?->document_template_id;
$items = [];
$finishingType = null;
if ($processType === 'bending') {
$finishingType = $this->resolveFinishingType($productCode);
$items = $this->buildBendingInspectionItems($firstItem);
}
@@ -2038,6 +2107,7 @@ public function getInspectionConfig(int $workOrderId): array
'work_order_id' => $workOrder->id,
'process_type' => $processType,
'product_code' => $productCode,
'finishing_type' => $finishingType,
'template_id' => $templateId,
'items' => $items,
];
@@ -2060,8 +2130,40 @@ private function resolveInspectionProcessType(?Process $process): string
};
}
/**
* 제품코드에서 마감유형(S1/S2/S3) 결정 (5130 레거시 기준)
*
* KSS01, KQTS01 → S1
* KSS02 (및 EGI 마감) → S2
* KWE01/KSE01 + SUS → S3
*/
private function resolveFinishingType(?string $productCode): string
{
if (! $productCode) {
return 'S1';
}
// FG-{model}-{type}-{material} 형식에서 모델코드와 재질 추출
$parts = explode('-', $productCode);
$modelCode = $parts[1] ?? '';
$material = $parts[3] ?? '';
// SUS 재질 + KWE/KSE 모델 → S3 (별도마감)
if (stripos($material, 'SUS') !== false && (str_starts_with($modelCode, 'KWE') || str_starts_with($modelCode, 'KSE'))) {
return 'S3';
}
return match (true) {
str_starts_with($modelCode, 'KSS01'), str_starts_with($modelCode, 'KQTS') => 'S1',
str_starts_with($modelCode, 'KSS02') => 'S2',
str_starts_with($modelCode, 'KWE'), str_starts_with($modelCode, 'KSE') => 'S2', // EGI마감 = S2
default => 'S2', // 기본값: S2 (5130 기준 EGI와 동일)
};
}
/**
* 절곡 bending_info에서 검사 대상 구성품 + 간격 기준치 빌드
* 마감유형(S1/S2/S3)에 따라 gap_points가 달라짐
*/
private function buildBendingInspectionItems(?WorkOrderItem $firstItem): array
{
@@ -2069,6 +2171,11 @@ private function buildBendingInspectionItems(?WorkOrderItem $firstItem): array
return [];
}
$productCode = $firstItem->options['product_code'] ?? null;
$finishingType = $this->resolveFinishingType($productCode);
$typeProfiles = self::BENDING_GAP_PROFILES[$finishingType] ?? self::BENDING_GAP_PROFILES['S1'];
$commonProfiles = self::BENDING_GAP_PROFILES['common'];
$bendingInfo = $firstItem->options['bending_info'] ?? null;
$items = [];
@@ -2078,7 +2185,7 @@ private function buildBendingInspectionItems(?WorkOrderItem $firstItem): array
$hasSide = $guideRail && ($guideRail['side'] ?? false);
if ($hasWall) {
$profile = self::BENDING_GAP_PROFILES['guide_rail_wall'];
$profile = $typeProfiles['guide_rail_wall'];
$items[] = [
'id' => 'guide_rail_wall',
'name' => $profile['name'],
@@ -2087,7 +2194,7 @@ private function buildBendingInspectionItems(?WorkOrderItem $firstItem): array
}
if ($hasSide) {
$profile = self::BENDING_GAP_PROFILES['guide_rail_side'];
$profile = $typeProfiles['guide_rail_side'];
$items[] = [
'id' => 'guide_rail_side',
'name' => $profile['name'],
@@ -2095,32 +2202,32 @@ private function buildBendingInspectionItems(?WorkOrderItem $firstItem): array
];
}
// 하단마감재 (항상 포함)
$profile = self::BENDING_GAP_PROFILES['bottom_bar'];
// 하단마감재 (항상 포함, 마감유형별 gap_points 다름)
$profile = $typeProfiles['bottom_bar'];
$items[] = [
'id' => 'bottom_bar',
'name' => $profile['name'],
'gap_points' => $profile['gap_points'],
];
// 케이스 (항상 포함)
$profile = self::BENDING_GAP_PROFILES['case_box'];
// 케이스 (항상 포함, 공통)
$profile = $commonProfiles['case_box'];
$items[] = [
'id' => 'case_box',
'name' => $profile['name'],
'gap_points' => $profile['gap_points'],
];
// 연기차단재 W50 (항상 포함)
$profile = self::BENDING_GAP_PROFILES['smoke_w50'];
// 연기차단재 W50 (항상 포함, 공통)
$profile = $commonProfiles['smoke_w50'];
$items[] = [
'id' => 'smoke_w50',
'name' => $profile['name'],
'gap_points' => $profile['gap_points'],
];
// 연기차단재 W80 (항상 포함)
$profile = self::BENDING_GAP_PROFILES['smoke_w80'];
// 연기차단재 W80 (항상 포함, 공통)
$profile = $commonProfiles['smoke_w80'];
$items[] = [
'id' => 'smoke_w80',
'name' => $profile['name'],