<?php /** * DocumentTypeController.php. * * Created By: jonathan * Date: 15/10/2020 * Time: 12:59 */ namespace App\Http\Controllers\Api; use App\Exceptions\MissingMaturityAnswerException; use App\Http\Controllers\Controller; use App\Http\Requests\EvaluationRequest; use App\Models\Danger; use App\Models\DangerLevelEvaluation; use App\Models\Evaluation; use App\Models\EvaluationMaturityAnswer; use App\Models\Measure; use App\Models\MeasureLevel; use App\Models\User; use App\Repository\EvaluationRepository; use App\Repository\GraphDataRepository; use Illuminate\Support\Facades\Auth; class EvaluationsController extends Controller { public function __construct(GraphDataRepository $repository) { $this->repository = $repository; } public function all() { $user = Auth::user(); if (User::ROLE_ADMIN === $user->role) { return Evaluation::with('dangerLevels') ->with('measureLevels') ->with('maturityLevels') ->with('organization') ->get(); } return Evaluation::where('organization_id', $user->organization_id) ->with('dangerLevels') ->with('measureLevels') ->with('maturityLevels') ->with('organization') ->get(); } public function get(int $id) { $user = Auth::user(); $evaluation = Evaluation::find($id); // if user is admin or if user->organization = $id if ((User::ROLE_ADMIN === $user->role) || (($user->role > User::ROLE_ADMIN) && ($user->organization_id === $evaluation->organization_id))) { return Evaluation::where('id', $id) ->with('dangerLevels') ->with('measureLevels') ->with('maturityLevels') ->with('organization') ->get(); } abort(403); } /** * Enregistre l'évaluation en tant que terminée (validation sur l'étape en cours). * * @return Evaluation|null */ public function save(EvaluationRepository $repository, EvaluationRequest $request, $id = null) { $user = Auth::user(); $data = $request->validated(); if ($user->role <= User::ROLE_MANAGER) { if ((User::ROLE_MANAGER === $user->role) && ($data['organization_id'] !== $user->organization_id)) { abort(403); } if (!isset($id)) { $evaluation = new Evaluation(); $evaluation->author = $user->firstname . ' ' . $user->lastname; $evaluation->current_step = 1; } else { $evaluation = Evaluation::find($id); if ($evaluation->reference !== env('REFERENTIEL_VERSION')) { abort(422, 'Le référentiel de cette évaluation ne correspond pas au référentiel actuel'); } } $evaluation->status = $data['status']; $evaluation->updated_by = $user->firstname . ' ' . $user->lastname; $evaluation->organization_id = $data['organization_id']; $evaluation->reference = env('REFERENTIEL_VERSION'); $evaluation->save(); // Evaluer les dangers if (Evaluation::STEP_DANGERS === intval($evaluation->current_step) && isset($data['danger_levels'])) { $dangerLevelArray = []; $dangers = Danger::all(); $levels = collect($data['danger_levels']); foreach ($dangers as $danger) { $level = $levels->filter(function ($l) use ($danger) { return isset($l['danger_id']) && $l['danger_id'] === $danger->id; })->first(); if ((!$level || !isset($level['danger_level_id'])) && 0 === $data['draft']) { abort(422, 'Un ou plusieurs niveaux de dangers sont manquants'); } if ($level && isset($level['danger_level_id'])) { $dl = new DangerLevelEvaluation(); $dl->danger_id = $danger->id; $dl->danger_level_id = $level['danger_level_id']; $dangerLevelArray[] = $dl; } } $evaluation->dangerLevels()->delete(); $evaluation->dangerLevels()->saveMany($dangerLevelArray); } // Evaluer les mesures d'évaluation if ((Evaluation::STEP_MEASURES === intval($evaluation->current_step)) || (Evaluation::STEP_ACTIONS === intval($evaluation->current_step))) { // get list of actuals measures $previous_measures_array = MeasureLevel::where('evaluation_id', $evaluation['id'])->pluck('id')->toArray(); foreach ($data['measure_levels'] as $put_measure_level) { $measure = Measure::find($put_measure_level['measure_id']); if (isset($put_measure_level['id'])) { $measure_level = MeasureLevel::find($put_measure_level['id']); } else { $measure_level = new MeasureLevel(); } $measure_level->measure_id = $put_measure_level['measure_id']; $measure_level->evaluation_id = $evaluation['id']; $measure_level->actual_level = $put_measure_level['actual_level'] ?? null; $measure_level->expected_level = $put_measure_level['expected_level'] ?? null; $measure_level->manager = $put_measure_level['manager'] ?? null; $measure_level->end_date = $put_measure_level['end_date'] ?? null; $measure_level->save(); if (in_array($measure_level['id'], $previous_measures_array)) { $previous_measures_array = array_diff($previous_measures_array, [$measure_level['id']]); } } foreach ($previous_measures_array as $previous_measure) { MeasureLevel::where('id', $previous_measure) ->delete(); } } // Evaluer la maturité cyber if (Evaluation::STEP_MATURITY === intval($data['current_step'])) { if (!isset($data['maturity_levels'])) { abort(422, 'Les réponses aux questions de maturité sont obligatoires.'); } $answers = collect($data['maturity_levels']); try { $repository->saveMaturity($evaluation, $answers, $data['draft']); } catch (MissingMaturityAnswerException $e) { abort(422, 'Certaines réponses aux questions de maturité sont manquantes.'); } } if (!isset($data['draft']) || !$data['draft']) { // Change step if this is not a draft evaluation ++$evaluation->current_step; } else { // Get step from front end if it is a draft evaluation $evaluation->current_step = $data['current_step']; } // Make sure step does not go above 6 if ($evaluation->current_step >= 6) { $evaluation->current_step = 6; } // Set status done if step is 6 if ($evaluation->current_step >= 6) { $evaluation->status = Evaluation::STATUS_DONE; } else { $evaluation->status = Evaluation::STATUS_ONGOING; } $evaluation->save(); // Ajout du niveau supérieur pour les mesures preconisées $preconizedMeasure = array_slice($this->repository->getBestMeasuresForEvaluation($evaluation),0,4); foreach ($evaluation->measureLevels as $measureLevel) { $measureLevelpreconized = MeasureLevel::whereId($measureLevel->id) ->first(); if ($measureLevelpreconized && in_array($measureLevelpreconized['measure_id'], $preconizedMeasure, true)) { $measureLevelpreconized->expected_level = $measureLevelpreconized['actual_level'] < 3 ? $measureLevelpreconized['actual_level'] + 1 : null; } $measureLevelpreconized->save(); } // si mofification d'un step, reinitialisation des steps suivants if (isset($data['draft']) && $data['draft']) { if (1 === $evaluation->current_step) { $this->deleteMeasureOrActionPlanStep($evaluation, 1); } if (2 === $evaluation->current_step) { $this->deleteMeasureOrActionPlanStep($evaluation, 2); } if (4 === $evaluation->current_step) { $this->deleteMaturityStep($evaluation); } } return Evaluation::where('id', $evaluation->id) ->with('dangerLevels') ->with('measureLevels') ->with('organization') ->with('maturityLevels') ->first(); } abort(403); } private function deleteMeasureOrActionPlanStep($evaluation, $step) { $measureLevels = MeasureLevel::where('evaluation_id', $evaluation->id) ->get(); foreach ($measureLevels as $mesureLevel) { $measure = Measure::find($mesureLevel->measure_id); if (1 === $step) { $mesureLevel->actual_level = null; $mesureLevel->expected_level = null; } if (2 === $step) { $mesureLevel->expected_level = null; } $mesureLevel->end_date = null; $mesureLevel->manager = null; $mesureLevel->save(); } $this->deleteMaturityStep($evaluation); } private function deleteMaturityStep($evaluation) { EvaluationMaturityAnswer::where('evaluation_id', $evaluation->id) ->delete(); } public function delete(int $id = null) { $user = Auth::user(); $evaluation = Evaluation::find($id); if ((User::ROLE_ADMIN === $user->role) || ((User::ROLE_MANAGER === $user->role) && ($user->organization_id === $evaluation->organization_id))) { $evaluation->delete(); return abort(204); } abort(403); } }