From 760efe656f96340f6eb6028ce482eaf90f6b8f7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Sat, 21 Mar 2026 17:15:32 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20[=EC=9E=AC=EA=B3=A0=EC=83=9D=EC=82=B0]?= =?UTF-8?q?=20STOCK=20=EC=9E=91=EC=97=85=EC=A7=80=EC=8B=9C=EC=97=90=20bend?= =?UTF-8?q?ing=5Finfo=20=EB=88=84=EB=9D=BD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 재고생산(STOCK) 주문은 order_nodes가 없어 BendingInfoBuilder가 null 반환 → work_order.options=NULL → 절곡 작업일지 데이터 미표시. order.options.bending_lot에서 간이 bending_info를 생성하여 주입. --- app/Services/OrderService.php | 122 ++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/app/Services/OrderService.php b/app/Services/OrderService.php index 59870222..ccf7bd4b 100644 --- a/app/Services/OrderService.php +++ b/app/Services/OrderService.php @@ -1602,6 +1602,22 @@ public function createProductionOrder(int $orderId, array $data) if ($buildResult) { $workOrderOptions = array_merge($workOrderOptions ?? [], ['bending_info' => $buildResult['bending_info']]); } + + // STOCK(재고생산): BendingInfoBuilder가 null 반환 시 (rootNodes 없음) + // order.options.bending_lot에서 간이 bending_info 생성 + if (! $buildResult && $isStock) { + $orderOptions = $order->options ?? []; + $bendingLot = $orderOptions['bending_lot'] ?? null; + if ($bendingLot) { + $stockBendingInfo = $this->buildStockBendingInfo( + $bendingLot, + $orderOptions['target_stock_qty'] ?? $order->quantity ?? 1 + ); + if ($stockBendingInfo) { + $workOrderOptions = array_merge($workOrderOptions ?? [], ['bending_info' => $stockBendingInfo]); + } + } + } } // team_id 결정: 명시적 전달값 > 공정 담당부서 자동 매핑 @@ -2185,4 +2201,110 @@ public function checkBendingStockForOrder(int $orderId): array return $result; } + + /** + * STOCK(재고생산) 주문의 bending_lot → 간이 bending_info 변환 + * + * order.options.bending_lot 코드를 work_order.options.bending_info 구조로 매핑하여 + * 절곡 작업일지에서 데이터를 정상 표시할 수 있도록 한다. + */ + private function buildStockBendingInfo(array $bendingLot, int $quantity): ?array + { + $prodCode = $bendingLot['prod_code'] ?? ''; + $specCode = $bendingLot['spec_code'] ?? ''; + $lengthCode = $bendingLot['length_code'] ?? ''; + + if (! $prodCode || ! $specCode || ! $lengthCode) { + return null; + } + + // length_code → mm 변환 + $lengthMm = $this->stockLengthCodeToMm($prodCode, $lengthCode); + if ($lengthMm <= 0) { + return null; + } + + // productCode 결정 (spec_code 기반) + $productCode = match (true) { + in_array($specCode, ['S', 'U', 'F']) => 'KSS01', // SUS 마감 + $specCode === 'T' => 'KTE01', // 철재 + default => 'KSE01', // EGI 일반 + }; + + // finishMaterial 결정 + $finishMaterial = match ($productCode) { + 'KSS01' => 'SUS마감', + 'KTE01' => in_array($specCode, ['S', 'U', 'F']) ? 'SUS마감' : '', + default => '', + }; + + // guideType 결정 (벽면/측면) + $guideType = $prodCode === 'S' ? 'side' : 'wall'; + + $bendingInfo = [ + 'productCode' => $productCode, + 'finishMaterial' => $finishMaterial, + 'common' => ['type' => $guideType], + ]; + + // 가이드레일 (R=벽면, S=측면) + if (in_array($prodCode, ['R', 'S'])) { + $baseDim = $guideType === 'wall' ? '135*80' : '135*130'; + $bendingInfo['guideRail'][$guideType] = [ + 'baseDimension' => $baseDim, + 'lengthData' => [['length' => $lengthMm, 'quantity' => $quantity]], + ]; + } + + // 하단마감재 (B=스크린, T=철재) + if (in_array($prodCode, ['B', 'T'])) { + $bendingInfo['bottomBar'] = ["length{$lengthMm}Qty" => $quantity]; + } + + // 연기차단재 (G) + if ($prodCode === 'G') { + $width = str_starts_with($lengthCode, '5') ? 50 : 80; + $bendingInfo['smokeBarrier'] = [ + 'width' => $width, + 'lengthData' => [['length' => $lengthMm, 'quantity' => $quantity]], + ]; + } + + // 케이스 (C) + if ($prodCode === 'C') { + $bendingInfo['shutterBox'] = [[ + 'size' => '500*380', + 'direction' => '양면', + 'lengthData' => [['length' => $lengthMm, 'quantity' => $quantity]], + 'coverQty' => 0, + 'finCoverQty' => 0, + ]]; + } + + return $bendingInfo; + } + + /** + * STOCK 재고생산 length_code → mm 변환 + */ + private function stockLengthCodeToMm(string $prodCode, string $lengthCode): int + { + // 연기차단재 전용 길이 + if ($prodCode === 'G') { + return match ($lengthCode) { + '53', '83' => 3000, + '54', '84' => 4000, + default => 0, + }; + } + + // 일반 길이 + $map = [ + '06' => 610, '12' => 1219, '17' => 1750, '20' => 2000, + '24' => 2438, '30' => 3000, '35' => 3500, '40' => 4000, + '41' => 4150, '42' => 4200, '43' => 4300, '45' => 4500, + ]; + + return $map[$lengthCode] ?? 0; + } }