copy()->endOfMonth(); if ($clearExisting) { $this->clearExistingSchedules($planner, $startDate, $endDate, $userIds); } $userDishesMap = $this->loadUserDishes($planner, $userIds); $this->generateSchedulesForPeriod($planner, $startDate, $endDate, $userIds, $userDishesMap); }); } private function clearExistingSchedules( Planner $planner, Carbon $startDate, Carbon $endDate, array $userIds ): void { $scheduleIds = Schedule::withoutGlobalScopes() ->where('planner_id', $planner->id) ->whereBetween('date', [$startDate, $endDate]) ->pluck('id'); ScheduledUserDish::whereIn('schedule_id', $scheduleIds) ->whereIn('user_id', $userIds) ->delete(); } private function loadUserDishes(Planner $planner, array $userIds): array { $users = User::query() ->with('userDishes.dish') ->whereIn('id', $userIds) ->where('planner_id', $planner->id) ->get() ->keyBy('id'); $userDishesMap = []; foreach ($users as $userId => $user) { if ($user->userDishes->isNotEmpty()) { $userDishesMap[$userId] = $user->userDishes; } } return $userDishesMap; } private function generateSchedulesForPeriod( Planner $planner, Carbon $startDate, Carbon $endDate, array $userIds, array $userDishesMap ): void { $currentDate = $startDate->copy(); while ($currentDate <= $endDate) { $schedule = Schedule::firstOrCreate( ['planner_id' => $planner->id, 'date' => $currentDate->format('Y-m-d')], ['is_skipped' => false] ); foreach ($userIds as $userId) { if (!isset($userDishesMap[$userId]) || $userDishesMap[$userId]->isEmpty()) { continue; } $randomUserDish = $userDishesMap[$userId]->random(); ScheduledUserDish::firstOrCreate( ['schedule_id' => $schedule->id, 'user_id' => $userId], ['user_dish_id' => $randomUserDish->id, 'is_skipped' => false] ); } $currentDate->addDay(); } } }