fix: [production-orders,order] 생산지시 목록 최적화 + 진행률 컬럼 수정 + 중복체크 취소 건 제외
This commit is contained in:
@@ -28,13 +28,14 @@ public function index(array $params): LengthAwarePaginator
|
||||
$query = Order::query()
|
||||
->where('tenant_id', $tenantId)
|
||||
->whereIn('status_code', self::PRODUCTION_STATUSES)
|
||||
->with(['client', 'workOrders.process', 'workOrders.assignees.user'])
|
||||
->with(['client'])
|
||||
->withCount([
|
||||
'workOrders' => fn ($q) => $q->whereNotNull('process_id')
|
||||
->where(fn ($q2) => $q2->whereNull('options->is_auxiliary')
|
||||
->orWhere('options->is_auxiliary', false)),
|
||||
'nodes',
|
||||
]);
|
||||
])
|
||||
->withMin('workOrders', 'created_at');
|
||||
|
||||
// 검색어 필터
|
||||
if (! empty($params['search'])) {
|
||||
@@ -74,24 +75,23 @@ public function index(array $params): LengthAwarePaginator
|
||||
$perPage = $params['per_page'] ?? 20;
|
||||
$result = $query->paginate($perPage);
|
||||
|
||||
// 작업지시 진행률을 일괄 서브쿼리로 조회 (N+1 방지)
|
||||
$orderIds = $result->getCollection()->pluck('id')->toArray();
|
||||
$woProgress = $this->getWorkOrderProgressBatch($orderIds);
|
||||
|
||||
// 가공 필드 추가
|
||||
$result->getCollection()->transform(function (Order $order) {
|
||||
$minCreatedAt = $order->workOrders->min('created_at');
|
||||
$result->getCollection()->transform(function (Order $order) use ($woProgress) {
|
||||
$minCreatedAt = $order->work_orders_min_created_at;
|
||||
$order->production_ordered_at = $minCreatedAt
|
||||
? $minCreatedAt->format('Y-m-d')
|
||||
? \Carbon\Carbon::parse($minCreatedAt)->format('Y-m-d')
|
||||
: null;
|
||||
|
||||
// 개소수 (order_nodes 수)
|
||||
$order->node_count = $order->nodes_count ?? 0;
|
||||
|
||||
// 주요 생산 공정 WO만 (구매품 + 보조 공정 제외)
|
||||
$productionWOs = $this->filterMainProductionWOs($order->workOrders);
|
||||
$order->work_order_progress = [
|
||||
'total' => $productionWOs->count(),
|
||||
'completed' => $productionWOs->where('status', 'completed')->count()
|
||||
+ $productionWOs->where('status', 'shipped')->count(),
|
||||
'in_progress' => $productionWOs->where('status', 'in_progress')->count(),
|
||||
];
|
||||
// 주요 생산 공정 WO 진행률 (서브쿼리 결과 사용)
|
||||
$progress = $woProgress[$order->id] ?? ['total' => 0, 'completed' => 0, 'in_progress' => 0];
|
||||
$order->work_order_progress = $progress;
|
||||
|
||||
// 프론트 탭용 production_status 매핑
|
||||
$order->production_status = $this->mapProductionStatus($order->status_code);
|
||||
@@ -109,21 +109,17 @@ public function stats(): array
|
||||
{
|
||||
$tenantId = $this->tenantId();
|
||||
|
||||
$waiting = Order::where('tenant_id', $tenantId)
|
||||
->where('status_code', Order::STATUS_IN_PROGRESS)
|
||||
->count();
|
||||
$counts = Order::where('tenant_id', $tenantId)
|
||||
->whereIn('status_code', self::PRODUCTION_STATUSES)
|
||||
->selectRaw('status_code, COUNT(*) as cnt')
|
||||
->groupBy('status_code')
|
||||
->pluck('cnt', 'status_code');
|
||||
|
||||
$inProduction = Order::where('tenant_id', $tenantId)
|
||||
->where('status_code', Order::STATUS_IN_PRODUCTION)
|
||||
->count();
|
||||
|
||||
$completed = Order::where('tenant_id', $tenantId)
|
||||
->whereIn('status_code', [
|
||||
Order::STATUS_PRODUCED,
|
||||
Order::STATUS_SHIPPING,
|
||||
Order::STATUS_SHIPPED,
|
||||
])
|
||||
->count();
|
||||
$waiting = $counts->get(Order::STATUS_IN_PROGRESS, 0);
|
||||
$inProduction = $counts->get(Order::STATUS_IN_PRODUCTION, 0);
|
||||
$completed = $counts->get(Order::STATUS_PRODUCED, 0)
|
||||
+ $counts->get(Order::STATUS_SHIPPING, 0)
|
||||
+ $counts->get(Order::STATUS_SHIPPED, 0);
|
||||
|
||||
return [
|
||||
'total' => $waiting + $inProduction + $completed,
|
||||
@@ -264,6 +260,43 @@ private function extractBomProcessGroups($nodes): array
|
||||
return array_values($groups);
|
||||
}
|
||||
|
||||
/**
|
||||
* 주문 ID 목록에 대해 작업지시 진행률을 일괄 조회 (단일 쿼리)
|
||||
*/
|
||||
private function getWorkOrderProgressBatch(array $orderIds): array
|
||||
{
|
||||
if (empty($orderIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$rows = \DB::table('work_orders')
|
||||
->selectRaw('sales_order_id, status, COUNT(*) as cnt')
|
||||
->whereIn('sales_order_id', $orderIds)
|
||||
->whereNotNull('process_id')
|
||||
->where(function ($q) {
|
||||
$q->whereNull('options->is_auxiliary')
|
||||
->orWhere('options->is_auxiliary', false);
|
||||
})
|
||||
->whereNull('deleted_at')
|
||||
->groupBy('sales_order_id', 'status')
|
||||
->get();
|
||||
|
||||
$result = [];
|
||||
foreach ($rows as $row) {
|
||||
if (! isset($result[$row->sales_order_id])) {
|
||||
$result[$row->sales_order_id] = ['total' => 0, 'completed' => 0, 'in_progress' => 0];
|
||||
}
|
||||
$result[$row->sales_order_id]['total'] += $row->cnt;
|
||||
if (in_array($row->status, ['completed', 'shipped'])) {
|
||||
$result[$row->sales_order_id]['completed'] += $row->cnt;
|
||||
} elseif ($row->status === 'in_progress') {
|
||||
$result[$row->sales_order_id]['in_progress'] += $row->cnt;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 주요 생산 공정 WO만 필터 (구매품/서비스 + 보조 공정 제외)
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user