app/app/Livewire/Schedule/ScheduleGenerator.php

202 lines
No EOL
7 KiB
PHP

<?php
namespace App\Livewire\Schedule;
use App\Models\User;
use App\Models\Dish;
use App\Models\Schedule;
use App\Models\ScheduledUserDish;
use Carbon\Carbon;
use Livewire\Component;
class ScheduleGenerator extends Component
{
public $selectedMonth;
public $selectedYear;
public $selectedUsers = [];
public $clearExisting = true;
public $showAdvancedOptions = false;
public $isGenerating = false;
public function mount()
{
$this->selectedMonth = now()->month;
$this->selectedYear = now()->year;
// Select all users by default
$this->selectedUsers = User::where('planner_id', auth()->user()->planner_id)
->pluck('id')
->toArray();
}
public function render()
{
$users = User::where('planner_id', auth()->user()->planner_id)
->orderBy('name')
->get();
$months = [
1 => 'January', 2 => 'February', 3 => 'March', 4 => 'April',
5 => 'May', 6 => 'June', 7 => 'July', 8 => 'August',
9 => 'September', 10 => 'October', 11 => 'November', 12 => 'December'
];
$years = range(now()->year - 1, now()->year + 2);
return view('livewire.schedule.schedule-generator', [
'users' => $users,
'months' => $months,
'years' => $years
]);
}
public function generate()
{
$this->validate([
'selectedUsers' => 'required|array|min:1',
'selectedMonth' => 'required|integer|min:1|max:12',
'selectedYear' => 'required|integer|min:2020|max:2030',
]);
$this->isGenerating = true;
try {
$startDate = Carbon::createFromDate($this->selectedYear, $this->selectedMonth, 1);
$endDate = $startDate->copy()->endOfMonth();
// Clear existing schedule if requested
if ($this->clearExisting) {
ScheduledUserDish::whereBetween('date', [$startDate, $endDate])
->whereIn('user_id', $this->selectedUsers)
->delete();
}
// Get all dishes assigned to selected users
$userDishes = [];
foreach ($this->selectedUsers as $userId) {
$user = User::find($userId);
$dishes = $user->dishes()->get();
if ($dishes->isNotEmpty()) {
$userDishes[$userId] = $dishes->toArray();
}
}
// Generate schedule for each day
$currentDate = $startDate->copy();
while ($currentDate <= $endDate) {
foreach ($this->selectedUsers as $userId) {
// Skip if user already has a dish for this day
if (ScheduledUserDish::where('date', $currentDate->format('Y-m-d'))
->where('user_id', $userId)
->exists()) {
continue;
}
// Get available dishes for this user
if (!isset($userDishes[$userId]) || empty($userDishes[$userId])) {
continue;
}
$availableDishes = $userDishes[$userId];
// Simple random assignment (you can implement more complex logic here)
if (!empty($availableDishes)) {
$randomDish = $availableDishes[array_rand($availableDishes)];
ScheduledUserDish::create([
'user_id' => $userId,
'dish_id' => $randomDish['id'],
'date' => $currentDate->format('Y-m-d'),
'planner_id' => auth()->user()->planner_id,
]);
}
}
$currentDate->addDay();
}
$this->isGenerating = false;
// Emit event to refresh calendar
$this->dispatch('schedule-generated');
session()->flash('success', 'Schedule generated successfully for ' .
$this->getSelectedMonthName() . ' ' . $this->selectedYear);
} catch (\Exception $e) {
$this->isGenerating = false;
session()->flash('error', 'Error generating schedule: ' . $e->getMessage());
}
}
public function regenerateForDate($date)
{
try {
// Clear existing assignments for this date
ScheduledUserDish::whereDate('date', $date)
->whereIn('user_id', $this->selectedUsers)
->delete();
// Regenerate for this specific date
$currentDate = Carbon::parse($date);
foreach ($this->selectedUsers as $userId) {
$user = User::find($userId);
$dishes = $user->dishes()->get();
if ($dishes->isNotEmpty()) {
$randomDish = $dishes->random();
ScheduledUserDish::create([
'user_id' => $userId,
'dish_id' => $randomDish->id,
'date' => $currentDate->format('Y-m-d'),
'planner_id' => auth()->user()->planner_id,
]);
}
}
$this->dispatch('schedule-generated');
session()->flash('success', 'Schedule regenerated for ' . $currentDate->format('M d, Y'));
} catch (\Exception $e) {
session()->flash('error', 'Error regenerating schedule: ' . $e->getMessage());
}
}
public function clearMonth()
{
try {
$startDate = Carbon::createFromDate($this->selectedYear, $this->selectedMonth, 1);
$endDate = $startDate->copy()->endOfMonth();
ScheduledUserDish::whereBetween('date', [$startDate, $endDate])
->whereIn('user_id', $this->selectedUsers)
->delete();
$this->dispatch('schedule-generated');
session()->flash('success', 'Schedule cleared for ' .
$this->getSelectedMonthName() . ' ' . $this->selectedYear);
} catch (\Exception $e) {
session()->flash('error', 'Error clearing schedule: ' . $e->getMessage());
}
}
public function toggleAdvancedOptions()
{
$this->showAdvancedOptions = !$this->showAdvancedOptions;
}
private function getSelectedMonthName()
{
$months = [
1 => 'January', 2 => 'February', 3 => 'March', 4 => 'April',
5 => 'May', 6 => 'June', 7 => 'July', 8 => 'August',
9 => 'September', 10 => 'October', 11 => 'November', 12 => 'December'
];
return $months[$this->selectedMonth];
}
}