fix: [생산지시] 공정 진행 현황 WO 필터링 + BOM 파싱 수정

- 공정 진행 현황: process_id=null인 구매품/서비스 WO 제외 (withCount, 목록/상세 모두)
- extractBomProcessGroups: bom_result.items[] 구조에 맞게 파싱 수정
  - process_name → process_group 키 사용
  - 품목 필드 매핑 수정 (item_id, specification, unit, quantity, unit_price, total_price, node_name)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-05 19:26:52 +09:00
parent 59d13eeb9f
commit 38c2402771

View File

@@ -29,7 +29,10 @@ public function index(array $params): LengthAwarePaginator
->where('tenant_id', $tenantId)
->whereIn('status_code', self::PRODUCTION_STATUSES)
->with(['client', 'workOrders.process', 'workOrders.assignees.user'])
->withCount(['workOrders', 'nodes']);
->withCount([
'workOrders' => fn ($q) => $q->whereNotNull('process_id'),
'nodes',
]);
// 검색어 필터
if (! empty($params['search'])) {
@@ -79,12 +82,13 @@ public function index(array $params): LengthAwarePaginator
// 개소수 (order_nodes 수)
$order->node_count = $order->nodes_count ?? 0;
$workOrders = $order->workOrders;
// 생산 공정이 있는 WO만 (구매품/서비스 제외)
$productionWOs = $order->workOrders->filter(fn ($wo) => ! empty($wo->process_id));
$order->work_order_progress = [
'total' => $workOrders->count(),
'completed' => $workOrders->where('status', 'completed')->count()
+ $workOrders->where('status', 'shipped')->count(),
'in_progress' => $workOrders->where('status', 'in_progress')->count(),
'total' => $productionWOs->count(),
'completed' => $productionWOs->where('status', 'completed')->count()
+ $productionWOs->where('status', 'shipped')->count(),
'in_progress' => $productionWOs->where('status', 'in_progress')->count(),
];
// 프론트 탭용 production_status 매핑
@@ -154,16 +158,19 @@ public function show(int $orderId): array
: null;
$order->production_status = $this->mapProductionStatus($order->status_code);
// WorkOrder 진행 현황
// 생산 공정이 있는 WorkOrder만 필터 (process_id가 null인 구매품/서비스 제외)
$productionWorkOrders = $order->workOrders->filter(fn ($wo) => ! empty($wo->process_id));
// WorkOrder 진행 현황 (생산 공정 기준)
$workOrderProgress = [
'total' => $order->workOrders->count(),
'completed' => $order->workOrders->where('status', 'completed')->count()
+ $order->workOrders->where('status', 'shipped')->count(),
'in_progress' => $order->workOrders->where('status', 'in_progress')->count(),
'total' => $productionWorkOrders->count(),
'completed' => $productionWorkOrders->where('status', 'completed')->count()
+ $productionWorkOrders->where('status', 'shipped')->count(),
'in_progress' => $productionWorkOrders->where('status', 'in_progress')->count(),
];
// WorkOrder 목록 가공
$workOrders = $order->workOrders->map(function ($wo) {
// WorkOrder 목록 가공 (생산 공정만)
$workOrders = $productionWorkOrders->values()->map(function ($wo) {
return [
'id' => $wo->id,
'work_order_no' => $wo->work_order_no,
@@ -202,6 +209,9 @@ private function mapProductionStatus(string $statusCode): string
/**
* order_nodes에서 BOM 공정 분류 추출
*
* bom_result 구조: { items: [...], success, subtotals, ... }
* 각 item: { item_id, item_code, item_name, process_group, specification, quantity, unit, ... }
*/
private function extractBomProcessGroups($nodes): array
{
@@ -209,30 +219,42 @@ private function extractBomProcessGroups($nodes): array
foreach ($nodes as $node) {
$bomResult = $node->options['bom_result'] ?? null;
if (! $bomResult) {
if (! $bomResult || ! is_array($bomResult)) {
continue;
}
// bom_result 구조에 따라 공정별 그룹화
foreach ($bomResult as $item) {
$processName = $item['process_name'] ?? '기타';
// bom_result.items 배열에서 추출
$items = $bomResult['items'] ?? [];
if (! is_array($items)) {
continue;
}
if (! isset($groups[$processName])) {
$groups[$processName] = [
'process_name' => $processName,
'size_spec' => $item['size_spec'] ?? null,
$nodeName = $node->name ?? '';
foreach ($items as $item) {
if (! is_array($item)) {
continue;
}
$processGroup = $item['process_group'] ?? $item['category_group'] ?? '기타';
if (! isset($groups[$processGroup])) {
$groups[$processGroup] = [
'process_name' => $processGroup,
'items' => [],
];
}
$groups[$processName]['items'][] = [
'id' => $item['id'] ?? null,
$groups[$processGroup]['items'][] = [
'id' => $item['item_id'] ?? null,
'item_code' => $item['item_code'] ?? '',
'item_name' => $item['item_name'] ?? '',
'spec' => $item['spec'] ?? '',
'lot_no' => $item['lot_no'] ?? '',
'required_qty' => $item['required_qty'] ?? 0,
'qty' => $item['qty'] ?? 0,
'spec' => $item['specification'] ?? '',
'unit' => $item['unit'] ?? '',
'quantity' => $item['quantity'] ?? 0,
'unit_price' => $item['unit_price'] ?? 0,
'total_price' => $item['total_price'] ?? 0,
'node_name' => $nodeName,
];
}
}