Files
GSB-Construction/Modules/TimelineScheduling/app/Http/Controllers/MilestoneController.php

106 lines
3.9 KiB
PHP

<?php
namespace Modules\TimelineScheduling\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Modules\ProjectManagement\Enums\WeatherCondition;
use Modules\ProjectManagement\Models\Project;
use Modules\ProjectManagement\Models\ProjectMilestone;
class MilestoneController extends Controller
{
public function index(Request $request)
{
$projectUlid = $request->query('project');
$project = null;
if ($projectUlid) {
$project = Project::where('ulid', $projectUlid)->firstOrFail();
$project->load([
'tasks' => fn ($q) => $q->select('id', 'project_id')->with('delays'),
'milestones',
]);
}
return \Inertia\Inertia::render('TimelineScheduling::Timeline/Index', [
'project' => $project,
'projects' => Project::select('id', 'ulid', 'name')->get(),
'milestones' => $project ? $project->milestones->map(fn ($m) => array_merge($m->toArray(), [
'is_completed' => $m->is_completed,
'is_overdue' => $m->is_overdue,
'status' => $m->status,
'status_color' => $m->status_color,
'days_delayed' => $m->days_delayed,
])) : [],
'milestoneStats' => $project ? [
'total' => $project->milestones->count(),
'completed' => $project->milestones->where('actual_date', '!=', null)->count(),
'completion_percentage' => $project->milestone_completion,
'weather_delay_days' => $project->weather_delay_days,
] : null,
'weatherConditions' => collect(WeatherCondition::cases())->map(fn ($c) => [
'value' => $c->value,
'label' => $c->label(),
'icon' => $c->icon(),
]),
'allowedTransitions' => $project ? collect($project->status->allowedTransitions())->map(fn ($s) => [
'value' => $s->value,
'label' => $s->label(),
]) : [],
]);
}
public function store(Request $request)
{
$validated = $request->validate([
'project_id' => 'required|exists:projects,id',
'name' => 'required|string|max:255',
'description' => 'nullable|string',
'planned_date' => 'nullable|date',
'weight_percentage' => 'required|numeric|min:0|max:100',
]);
$project = Project::findOrFail($validated['project_id']);
$validated['sort_order'] = $project->milestones()->count();
$validated['is_default'] = false;
ProjectMilestone::create($validated);
return back()->with('success', 'Milestone added.');
}
public function update(Request $request, ProjectMilestone $milestone)
{
$validated = $request->validate([
'name' => 'sometimes|required|string|max:255',
'description' => 'nullable|string',
'planned_date' => 'nullable|date',
'actual_date' => 'nullable|date',
'weight_percentage' => 'sometimes|numeric|min:0|max:100',
'weather_impacted' => 'sometimes|boolean',
'weather_condition' => 'nullable|string',
'weather_delay_days' => 'sometimes|integer|min:0',
'weather_notes' => 'nullable|string|max:2000',
]);
// Clear weather fields if not impacted
if (isset($validated['weather_impacted']) && !$validated['weather_impacted']) {
$validated['weather_condition'] = null;
$validated['weather_delay_days'] = 0;
$validated['weather_notes'] = null;
}
$milestone->update($validated);
return back()->with('success', 'Milestone updated.');
}
public function destroy(ProjectMilestone $milestone)
{
$milestone->delete();
return back()->with('success', 'Milestone removed.');
}
}