From 3bae303447aa4a2db3dfb9d5eeed49b94052c7ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B6=8C=ED=98=81=EC=84=B1?= Date: Wed, 11 Mar 2026 17:35:24 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20[=EC=9E=91=EC=97=85=EC=A7=80=EC=8B=9C]?= =?UTF-8?q?=20syncOrderStatus=20=EC=A7=91=EA=B3=84=20=EB=B0=A9=EC=8B=9D?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기존: 단일 작업지시 상태만 보고 수주 상태 매핑 (첫 WO 완료 시 즉시 PRODUCED) - 변경: 수주의 모든 비보조 작업지시 상태를 집계하여 결정 - 전부 shipped → SHIPPED - 전부 completed/shipped → PRODUCED - 하나라도 진행중/완료/출하 → IN_PRODUCTION - 감사 로그에 집계 내역(work_order_counts) 포함 --- app/Services/WorkOrderService.php | 47 +++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/app/Services/WorkOrderService.php b/app/Services/WorkOrderService.php index ba39c09..bbb5ed0 100644 --- a/app/Services/WorkOrderService.php +++ b/app/Services/WorkOrderService.php @@ -836,14 +836,38 @@ private function syncOrderStatus(WorkOrder $workOrder, int $tenantId): void return; } - // 작업지시 상태 → 수주 상태 매핑 - $statusMap = [ - WorkOrder::STATUS_IN_PROGRESS => Order::STATUS_IN_PRODUCTION, - WorkOrder::STATUS_COMPLETED => Order::STATUS_PRODUCED, - WorkOrder::STATUS_SHIPPED => Order::STATUS_SHIPPED, - ]; + // 해당 수주의 모든 비보조 작업지시 상태 집계 + $allWorkOrders = WorkOrder::where('tenant_id', $tenantId) + ->where('sales_order_id', $workOrder->sales_order_id) + ->where('status', '!=', WorkOrder::STATUS_CANCELLED) + ->get(); - $newOrderStatus = $statusMap[$workOrder->status] ?? null; + // 보조 공정 제외 + $mainWorkOrders = $allWorkOrders->filter(fn ($wo) => ! $this->isAuxiliaryWorkOrder($wo)); + + if ($mainWorkOrders->isEmpty()) { + return; + } + + $totalCount = $mainWorkOrders->count(); + $statusCounts = $mainWorkOrders->groupBy('status')->map->count(); + + $shippedCount = $statusCounts->get(WorkOrder::STATUS_SHIPPED, 0); + $completedCount = $statusCounts->get(WorkOrder::STATUS_COMPLETED, 0); + $inProgressCount = $statusCounts->get(WorkOrder::STATUS_IN_PROGRESS, 0); + + // 집계 기반 수주 상태 결정 + // 전부 출하 → SHIPPED + // 전부 완료(또는 완료+출하) → PRODUCED + // 하나라도 진행중/완료/출하 → IN_PRODUCTION + $newOrderStatus = null; + if ($shippedCount === $totalCount) { + $newOrderStatus = Order::STATUS_SHIPPED; + } elseif (($completedCount + $shippedCount) === $totalCount) { + $newOrderStatus = Order::STATUS_PRODUCED; + } elseif ($inProgressCount > 0 || $completedCount > 0 || $shippedCount > 0) { + $newOrderStatus = Order::STATUS_IN_PRODUCTION; + } // 매핑되는 상태가 없거나 이미 동일한 상태면 스킵 if (! $newOrderStatus || $order->status_code === $newOrderStatus) { @@ -861,8 +885,13 @@ private function syncOrderStatus(WorkOrder $workOrder, int $tenantId): void 'order', $order->id, 'status_synced_from_work_order', - ['status_code' => $oldOrderStatus, 'work_order_id' => $workOrder->id], - ['status_code' => $newOrderStatus, 'work_order_id' => $workOrder->id] + ['status_code' => $oldOrderStatus, 'work_order_id' => $workOrder->id, 'aggregated' => true], + ['status_code' => $newOrderStatus, 'work_order_counts' => [ + 'total' => $totalCount, + 'shipped' => $shippedCount, + 'completed' => $completedCount, + 'in_progress' => $inProgressCount, + ]] ); }