120 lines
4.5 KiB
PHP
120 lines
4.5 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Enums\ProjectStatus;
|
|
use App\Http\Requests\MacroSchedule\PostActivityRequest;
|
|
use App\Http\Requests\MacroSchedule\ShowMacroScheduleRequest;
|
|
use App\Models\MacroSchedule\Activity;
|
|
use App\Models\Project;
|
|
use Illuminate\Support\Carbon;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class ScheduleMacroController extends Controller
|
|
{
|
|
/**
|
|
* View Macro planning
|
|
*
|
|
* @param \App\Http\Requests\MacroSchedule\ShowMacroScheduleRequest $request
|
|
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
|
*/
|
|
public function show(ShowMacroScheduleRequest $request)
|
|
{
|
|
$numberOfWeeksToShow = \config('macroschedule.numberOfWeeksToShow');
|
|
|
|
$date = Carbon::now();
|
|
if ($request->date) {
|
|
$date = Carbon::createFromFormat('d/m/Y', $request->date);
|
|
}
|
|
|
|
/** @var \Illuminate\Support\Carbon $date The date from which to take activities */
|
|
$date->startOfWeek();
|
|
|
|
/** @var \Illuminate\Support\Collection $projects */
|
|
$projects = Project::where('status', '>', ProjectStatus::new())
|
|
->where('status', '<', ProjectStatus::finished())
|
|
->with(['activities' => function ($q) use ($date, $numberOfWeeksToShow) {
|
|
$q->whereDate('start', '>=', $date->toDateString())
|
|
->OrWhereDate('end', '<=', $date->clone()->addWeeks($numberOfWeeksToShow)->toDateString());
|
|
}])->with('markers')->orderBy('status')->orderBy('name')->get()->keyBy('id');
|
|
|
|
// * Key by date activities relation
|
|
$projects->map(function (Project $project) {
|
|
$project->setRelation('activities', $project->activities->keyBy('id'));
|
|
});
|
|
|
|
// * Map activities by datetime
|
|
$activities = collect();
|
|
$projects->pluck('activities')->map(function (Collection $projectActivities) use (&$activities) {
|
|
$projectActivities->map(function (Activity $activity) use (&$activities) {
|
|
$activities->push($activity);
|
|
});
|
|
});
|
|
|
|
// * Disponibility calculation
|
|
$loadCollection = collect();
|
|
|
|
/** @var array<\Illuminate\Support\Carbon> */
|
|
$period = $date->toPeriod($date->clone()->addWeeks($numberOfWeeksToShow), 12, 'hour')->toArray();
|
|
|
|
foreach ($period as $day) {
|
|
/** @var \Illuminate\Support\Collection */
|
|
$dayActivities = $activities->filter(function (Activity $activity) use ($day) {
|
|
return $day->betweenIncluded($activity->start, $activity->end);
|
|
});
|
|
/** @var integer total activités / hommes / demi journées */
|
|
$totalLoad = $dayActivities->sum('load');
|
|
$loadCollection->put($day->format('Y-m-d H:i:s'), $totalLoad / config('macroschedule.totalAvailableDevs'));
|
|
}
|
|
|
|
return view('macroplanning.view', compact(
|
|
'date',
|
|
'projects',
|
|
'date',
|
|
'numberOfWeeksToShow',
|
|
'loadCollection'
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Save activity.
|
|
*
|
|
* @param PostActivityRequest $request
|
|
* @return \Illuminate\Http\JsonResponse
|
|
*/
|
|
public function postActivity(PostActivityRequest $request)
|
|
{
|
|
return DB::transaction(function () use ($request) {
|
|
$hasOverLap = false;
|
|
|
|
/** @var \App\Models\Project */
|
|
$project = Project::whereId($request->project_id)
|
|
->with('activities')->firstOrFail();
|
|
|
|
/** @var \App\Models\MacroSchedule\Activity */
|
|
$activity = Activity::whereId($request->id)->firstOrNew();
|
|
$activity->fill($request->validated());
|
|
$activity->project()->associate($project);
|
|
if (!$activity->saveOrFail()) {
|
|
response()->json('Une erreur est survenue lors de \'enregistrement');
|
|
}
|
|
|
|
// * Overload activities if necessary
|
|
$project->activities->map(function (Activity $periodActivity) use ($activity, &$hasOverLap) {
|
|
if (
|
|
$activity->id !== $periodActivity->id and
|
|
$activity->doesPeriodCoverActivity($periodActivity->start, $periodActivity->end)
|
|
) {
|
|
$hasOverLap = true;
|
|
$periodActivity->overlapUsingActivity($activity);
|
|
}
|
|
});
|
|
|
|
return response()->json([
|
|
'id' => $activity->id,
|
|
'hasOverlap' => $hasOverLap
|
|
]);
|
|
});
|
|
}
|
|
}
|