where('tenant_id', $tenantId) ->pluck('user_id') ->toArray(); if (empty($userIds)) { $this->command->warn(' ⚠ leaves: 사용자가 없습니다'); return; } // 휴가 유형 (가중치) $leaveTypes = [ 'annual' => 50, // 연차 50% 'half_am' => 15, // 오전 반차 15% 'half_pm' => 15, // 오후 반차 15% 'sick' => 10, // 병가 10% 'family' => 5, // 경조사 5% 'other' => 5, // 기타 5% ]; // 상태 (가중치) $statuses = [ 'approved' => 60, // 승인 60% 'pending' => 25, // 대기 25% 'rejected' => 10, // 반려 10% 'cancelled' => 5, // 취소 5% ]; $count = 0; $year = 2025; // 사용자별로 1~4건의 휴가 생성 foreach ($userIds as $uId) { $leaveCount = rand(1, 4); for ($i = 0; $i < $leaveCount; $i++) { $month = rand(1, 12); $day = rand(1, 28); $startDate = sprintf('%04d-%02d-%02d', $year, $month, $day); $leaveType = $this->getRandomWeighted($leaveTypes); $status = $this->getRandomWeighted($statuses); // 휴가 일수 결정 if (in_array($leaveType, ['half_am', 'half_pm'])) { $days = 0.5; $endDate = $startDate; } else { $days = rand(1, 3); $endDate = date('Y-m-d', strtotime($startDate.' + '.($days - 1).' days')); } // 승인자 정보 $approvedBy = null; $approvedAt = null; $rejectReason = null; if ($status === 'approved') { $approvedBy = $userId; $approvedAt = date('Y-m-d H:i:s', strtotime($startDate.' - 2 days')); } elseif ($status === 'rejected') { $approvedBy = $userId; $approvedAt = date('Y-m-d H:i:s', strtotime($startDate.' - 2 days')); $rejectReason = '업무 일정 상 불가'; } Leave::create([ 'tenant_id' => $tenantId, 'user_id' => $uId, 'leave_type' => $leaveType, 'start_date' => $startDate, 'end_date' => $endDate, 'days' => $days, 'reason' => $this->getLeaveReason($leaveType), 'status' => $status, 'approved_by' => $approvedBy, 'approved_at' => $approvedAt, 'reject_reason' => $rejectReason, 'created_by' => $uId, ]); $count++; } } $this->command->info(' ✓ leaves: '.$count.'건 생성'); } private function getRandomWeighted(array $weights): string { $total = array_sum($weights); $rand = rand(1, $total); $cumulative = 0; foreach ($weights as $key => $weight) { $cumulative += $weight; if ($rand <= $cumulative) { return $key; } } return array_key_first($weights); } private function getLeaveReason(string $type): string { return match ($type) { 'annual' => '개인 휴가', 'half_am' => '오전 병원 방문', 'half_pm' => '오후 개인 일정', 'sick' => '건강 사유', 'family' => '가족 행사', 'maternity' => '출산 휴가', 'parental' => '육아 휴직', default => '개인 사유', }; } }