fix: [production] 자재투입 모달 개선 — lot_managed 필터링, BOM 그룹키, 셔터박스 순서

- getMaterialsForItem: lot_managed===false 품목 자재투입 목록에서 제외 (L-Bar, 보강평철)
- getMaterialsForItem: bom_group_key 필드 추가 (category+partType 기반 고유키)
- BendingInfoBuilder: shutterPartTypes에서 top_cover/fin_cover 제거 (별도 생성과 중복)
- BendingInfoBuilder: 셔터박스 루프 순서 파트→길이로 변경 (작업일지 순서 일치)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-03 20:57:44 +09:00
parent fefd129795
commit fc537898fc
2 changed files with 30 additions and 8 deletions

View File

@@ -220,14 +220,17 @@ public function buildDynamicBomForItem(array $context, int $width, int $height,
if ($boxSize) {
$isStandard = $boxSize === '500*380';
$dist = $this->shutterBoxDistribution($width);
$shutterPartTypes = ['front', 'lintel', 'inspection', 'rear_corner', 'top_cover', 'fin_cover'];
// 상부덮개(top_cover), 마구리(fin_cover)는 1219mm 기준으로 별도 생성 (아래 256행~)
$shutterPartTypes = ['front', 'lintel', 'inspection', 'rear_corner'];
// 작업일지와 동일한 순서: 파트 → 길이
foreach ($shutterPartTypes as $partType) {
foreach ($dist as $length => $count) {
$totalCount = $count * $qty;
if ($totalCount <= 0) {
continue;
}
foreach ($dist as $length => $count) {
$totalCount = $count * $qty;
if ($totalCount <= 0) {
continue;
}
foreach ($shutterPartTypes as $partType) {
$prefix = $resolver->resolveShutterBoxPrefix($partType, $isStandard);
$itemCode = $resolver->buildItemCode($prefix, $length);
if (! $itemCode) {

View File

@@ -3165,6 +3165,12 @@ public function getMaterialsForItem(int $workOrderId, int $itemId): array
continue;
}
// LOT 관리 대상이 아닌 품목은 자재투입 목록에서 제외
$childOptions = $childItems[$childItemId]->options ?? [];
if (isset($childOptions['lot_managed']) && $childOptions['lot_managed'] === false) {
continue;
}
// dynamic_bom.qty는 아이템 수량이 곱해져 있으므로 나눠서 개소당 수량 산출
// (작업일지 bendingInfo와 동일한 수량)
$bomQty = (float) ($bomEntry['qty'] ?? 1);
@@ -3202,6 +3208,12 @@ public function getMaterialsForItem(int $workOrderId, int $itemId): array
continue;
}
// LOT 관리 대상이 아닌 품목은 자재투입 목록에서 제외
$childOptions = $childItem->options ?? [];
if (isset($childOptions['lot_managed']) && $childOptions['lot_managed'] === false) {
continue;
}
$materialItems[] = [
'item' => $childItem,
'bom_qty' => $bomQty,
@@ -3232,11 +3244,16 @@ public function getMaterialsForItem(int $workOrderId, int $itemId): array
$materials = [];
$rank = 1;
foreach ($materialItems as $matInfo) {
foreach ($materialItems as $bomIdx => $matInfo) {
$materialItem = $matInfo['item'];
$alreadyInputted = (float) ($inputtedQties[$materialItem->id] ?? 0);
$remainingRequired = max(0, $matInfo['required_qty'] - $alreadyInputted);
// BOM 엔트리별 고유 그룹키 (같은 item_id라도 category+partType이 다르면 별도 그룹)
$bomGroupKey = $materialItem->id
.'_'.($matInfo['category'] ?? '')
.'_'.($matInfo['part_type'] ?? '');
$stock = \App\Models\Tenants\Stock::where('tenant_id', $tenantId)
->where('item_id', $materialItem->id)
->first();
@@ -3256,6 +3273,7 @@ public function getMaterialsForItem(int $workOrderId, int $itemId): array
$materials[] = [
'stock_lot_id' => $lot->id,
'item_id' => $materialItem->id,
'bom_group_key' => $bomGroupKey,
'lot_no' => $lot->lot_no,
'material_code' => $materialItem->code,
'material_name' => $materialItem->name,
@@ -3282,6 +3300,7 @@ public function getMaterialsForItem(int $workOrderId, int $itemId): array
$materials[] = [
'stock_lot_id' => null,
'item_id' => $materialItem->id,
'bom_group_key' => $bomGroupKey,
'lot_no' => null,
'material_code' => $materialItem->code,
'material_name' => $materialItem->name,