fix: [재고생산] STOCK 작업지시에 bending_info 누락 수정

재고생산(STOCK) 주문은 order_nodes가 없어 BendingInfoBuilder가
null 반환 → work_order.options=NULL → 절곡 작업일지 데이터 미표시.
order.options.bending_lot에서 간이 bending_info를 생성하여 주입.
This commit is contained in:
김보곤
2026-03-21 17:15:32 +09:00
parent 192610e7fa
commit 760efe656f

View File

@@ -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;
}
}