|
|
@@ -0,0 +1,285 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace App\Service\OnlineRegistration;
|
|
|
+
|
|
|
+use App\Entity\Access\Access;
|
|
|
+use App\Entity\Organization\Organization;
|
|
|
+use App\Enum\OnlineRegistration\ValidationStateEnum;
|
|
|
+use App\Service\Access\Utils as AccessUtils;
|
|
|
+use App\Service\Utils\ArrayUtils;
|
|
|
+use App\Service\Utils\DatesUtils;
|
|
|
+use Doctrine\Common\Collections\ArrayCollection;
|
|
|
+use Doctrine\Common\Collections\Collection;
|
|
|
+
|
|
|
+/**
|
|
|
+ * --- SERVICE INUTILISE POUR LE MOMENT ---
|
|
|
+ * Service de lancement de l'inscription en ligne
|
|
|
+ */
|
|
|
+class RegistrationStartingService
|
|
|
+{
|
|
|
+ const EDUCATION_REREGISTER_RIGHT = "canReregisterEducations";
|
|
|
+ const EDUCATION_ADD_RIGHT = "canAddEducations";
|
|
|
+ const STUDENT_ADD_RIGHT = "canAddStudents";
|
|
|
+ const ONLY_EDUCATION_ADD_RIGHT = "lockAllExeptAddNewEducation";
|
|
|
+
|
|
|
+
|
|
|
+ public function __construct(
|
|
|
+ private OnlineRegistrationService $onlineRegistrationService,
|
|
|
+ private AccessUtils $accessUtils
|
|
|
+ ) {}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Teste si un Access peut accéder à l'IEL
|
|
|
+ * Sinon, lève une RuntimeException
|
|
|
+ *
|
|
|
+ * @param Access $access
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public function canStartOnlineRegistration(Access $access): bool {
|
|
|
+
|
|
|
+ if ($this->accessAndFamilyWishAlreadyValidateCanAddEducation($access)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ $functions = $this->accessUtils->getActiveFunctions($access);
|
|
|
+
|
|
|
+ $hasNoFunction = $functions === ["OTHER_FUNCTION"] && !$access->getAdminAccess();
|
|
|
+
|
|
|
+ $isStudent = in_array('STUDENT', $functions);
|
|
|
+
|
|
|
+ if (!$isStudent && $access->getAccessFamily()) {
|
|
|
+ // On regarde si un membre de la famille est un élève actif
|
|
|
+ $isStudent = ArrayUtils::any(
|
|
|
+ $access->getAccessFamily()->getAccesses()->toArray(),
|
|
|
+ function ($access) { return $this->accessUtils->hasActiveFunction($access, 'STUDENT'); }
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ $reregistration = $isStudent && !$access->isNewAccess();
|
|
|
+
|
|
|
+ // La structure dois posséder des periodes d'ouvertures
|
|
|
+ if (!$this->hasOpeningHours($access->getOrganization(), $reregistration)) {
|
|
|
+ throw new \RuntimeException('no_opening_hours_users');
|
|
|
+ }
|
|
|
+
|
|
|
+ // Aujourd'hui doit faire partie des périodes d'ouvertures
|
|
|
+ if(!$this->isInOpeningPeriod($access->getOrganization(), $reregistration)) {
|
|
|
+ throw new \RuntimeException('not_inside_period');
|
|
|
+ }
|
|
|
+
|
|
|
+ // Si l'Access a déjà répondu une fois cette année à l'IEL (ou un membre de la famille)
|
|
|
+ if($this->checkIelValidationDateTimeFamily($access)) {
|
|
|
+ throw new \RuntimeException('iel_allready_done');
|
|
|
+ }
|
|
|
+ else if (!$hasNoFunction && !$access->isIelEnabled()) {
|
|
|
+ throw new \RuntimeException('no_access_granted');
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * TODO: compléter la doc et trouver un nom plus court
|
|
|
+ *
|
|
|
+ * @param Access $access
|
|
|
+ * @return bool
|
|
|
+ * @throws \Exception
|
|
|
+ */
|
|
|
+ private function accessAndFamilyWishAlreadyValidateCanAddEducation(Access $access): bool {
|
|
|
+ $currentAccessWish = $this->onlineRegistrationService->getCurrentAccessWish($access);
|
|
|
+
|
|
|
+ if (!$currentAccessWish) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ $accessWishAlreadyValidateCanAddEducation =
|
|
|
+ $this->accessWishAlreadyValidateCanAddEducation($access) ||
|
|
|
+ (
|
|
|
+ $access->getAccessFamily() &&
|
|
|
+ !$access->getAccessFamily()->getAccesses()->isEmpty() &&
|
|
|
+ ArrayUtils::any(
|
|
|
+ $access->getAccessFamily()->getAccesses()->toArray(),
|
|
|
+ function ($familyAccess) { return $this->accessWishAlreadyValidateCanAddEducation($familyAccess); }
|
|
|
+ )
|
|
|
+ );
|
|
|
+
|
|
|
+ if ($accessWishAlreadyValidateCanAddEducation) {
|
|
|
+ // La structure dois posséder des periodes d'ouvertures
|
|
|
+ if (!$this->hasOpeningHours($access->getOrganization(),false)){
|
|
|
+ throw new \Exception('no_opening_hours_users');
|
|
|
+ }
|
|
|
+
|
|
|
+ // Aujourd'hui doit faire partit des périodes d'ouvertures
|
|
|
+ if (!$this->isInsidePeriod($access->getOrganization(),false)){
|
|
|
+ throw new \Exception('not_inside_period');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $accessWishAlreadyValidateCanAddEducation;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * TODO: compléter la doc et trouver un nom plus court
|
|
|
+ *
|
|
|
+ * @param Access $access
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ private function accessWishAlreadyValidateCanAddEducation(Access $access): bool
|
|
|
+ {
|
|
|
+ $currentAccessWish = $this->onlineRegistrationService->getCurrentAccessWish($access);
|
|
|
+
|
|
|
+ if (!$currentAccessWish) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ $accessFamilyWish = $currentAccessWish->getAccessFamilyWish();
|
|
|
+
|
|
|
+ if ($accessFamilyWish?->isCloseRegistration()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($currentAccessWish->getValidationState() !== ValidationStateEnum::OPEN_FOR_EDUCATIONS) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ $studentsAndEducationsAuthorization = $this->buildStudentAuthorizations($access);
|
|
|
+
|
|
|
+ return $studentsAndEducationsAuthorization[self::EDUCATION_ADD_RIGHT] === true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Détermine les autorisations d'un étudiant
|
|
|
+ *
|
|
|
+ * @param Access $access
|
|
|
+ * @return array<string, bool>
|
|
|
+ */
|
|
|
+ private function buildStudentAuthorizations(Access $access): array {
|
|
|
+
|
|
|
+ $rights = [
|
|
|
+ self::EDUCATION_REREGISTER_RIGHT => false,
|
|
|
+ self::EDUCATION_ADD_RIGHT => true,
|
|
|
+ self::STUDENT_ADD_RIGHT => true,
|
|
|
+ self::ONLY_EDUCATION_ADD_RIGHT => false
|
|
|
+ ];
|
|
|
+
|
|
|
+ $isNewStudent = $access->isNewAccess();
|
|
|
+ if ($isNewStudent) {
|
|
|
+ return $rights;
|
|
|
+ }
|
|
|
+
|
|
|
+ $organization = $access->getOrganization();
|
|
|
+ if ($organization === null) {
|
|
|
+ throw new \RuntimeException('Missing organization');
|
|
|
+ }
|
|
|
+
|
|
|
+ $organizationSettings = $organization->getOnlineRegistrationSettings();
|
|
|
+ $addNewStudentsSetting = $organizationSettings->canAddNewStudents();
|
|
|
+ $addNewEducationsSetting = $organizationSettings->canAddNewEducations();
|
|
|
+
|
|
|
+ $reRegistrationIsOpen = $this->isRegistrationOpen($organization, true);
|
|
|
+ // TODO: je comprend pas bien cette condition?
|
|
|
+ $rights[self::EDUCATION_REREGISTER_RIGHT] = $reRegistrationIsOpen || (!$addNewStudentsSetting && !$addNewEducationsSetting);
|
|
|
+
|
|
|
+ $newRegistrationIsOpen = $this->isRegistrationOpen($organization, false);
|
|
|
+ $rights[self::EDUCATION_ADD_RIGHT] = $newRegistrationIsOpen || $addNewEducationsSetting;
|
|
|
+ $rights[self::STUDENT_ADD_RIGHT] = $newRegistrationIsOpen || $addNewStudentsSetting;
|
|
|
+
|
|
|
+ $currentAccessWish = $this->onlineRegistrationService->getCurrentAccessWish($access);
|
|
|
+
|
|
|
+ $rights[self::STUDENT_ADD_RIGHT] = $currentAccessWish &&
|
|
|
+ $currentAccessWish->getValidationState() === ValidationStateEnum::OPEN_FOR_EDUCATIONS ||
|
|
|
+ (
|
|
|
+ $currentAccessWish->getAccessFamilyWish() &&
|
|
|
+ ArrayUtils::any(
|
|
|
+ $currentAccessWish->getAccessFamilyWish()->getAccessWishes()->toArray(),
|
|
|
+ function ($wish) { return $wish->getValidationState() === ValidationStateEnum::OPEN_FOR_EDUCATIONS; }
|
|
|
+ )
|
|
|
+ );
|
|
|
+
|
|
|
+ return $rights;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Retourne true si l'IEL est ouvert pour l'organisation donnée
|
|
|
+ *
|
|
|
+ * @param Organization $organization
|
|
|
+ * @param bool $reregistration
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ private function isRegistrationOpen(Organization $organization, bool $reregistration = true) {
|
|
|
+ return $this->hasOpeningHours($organization, $reregistration) &&
|
|
|
+ $this->isInOpeningPeriod($organization, $reregistration);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Retourne les périodes d'ouverture de l'IEL d'une organization, selon qu'il s'agisse de réinscription ou non
|
|
|
+ *
|
|
|
+ * @param Organization $organization
|
|
|
+ * @param bool $reregistration
|
|
|
+ * @return Collection
|
|
|
+ */
|
|
|
+ private function getOrganizationPeriods(Organization $organization, bool $reregistration = true): Collection {
|
|
|
+ $organizationSettings = $organization->getOnlineRegistrationSettings();
|
|
|
+ return $reregistration ?
|
|
|
+ $organizationSettings->getOpeningPeriods() :
|
|
|
+ $organizationSettings->getOpeningPeriodsNewEnrolments();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * TODO: completer doc
|
|
|
+ *
|
|
|
+ * @param Organization $organization
|
|
|
+ * @param bool $reregistration
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ private function hasOpeningHours(Organization $organization, bool $reregistration = true): bool {
|
|
|
+ $openingPeriods = $this->getOrganizationPeriods($organization, $reregistration);
|
|
|
+ return count($openingPeriods) > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Vérifie que nous sommes actuellement dans au moins une des périodes d'ouverture de l'IEL de l'organisation
|
|
|
+ *
|
|
|
+ * @param Organization $organization
|
|
|
+ * @param $reregistration
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public function isInOpeningPeriod(Organization $organization, bool $reregistration = true): bool {
|
|
|
+ return ArrayUtils::any(
|
|
|
+ $this->getOrganizationPeriods($organization, $reregistration)->toArray(),
|
|
|
+ function ($period) { return DatesUtils::isNowInInterval($period->getStartDate(), $period->getEndDate()); }
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * TODO: completer doc et revoir le nom
|
|
|
+ *
|
|
|
+ * @param Access $access
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ private function checkIelValidationDateTimeFamily(Access $access): bool {
|
|
|
+ $today = DatesUtils::new();
|
|
|
+
|
|
|
+ if(
|
|
|
+ $access->getIelValidationDatetime() &&
|
|
|
+ ($access->getIelValidationDatetime()->format('Y') === $today->format('Y'))
|
|
|
+ ) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (
|
|
|
+ $access->getAccessFamily() &&
|
|
|
+ !$access->getAccessFamily()->getAccesses()->isEmpty()
|
|
|
+ ) {
|
|
|
+ return ArrayUtils::any(
|
|
|
+ $access->getAccessFamily()->getAccesses()->toArray(),
|
|
|
+ function ($access) use ($today) {
|
|
|
+ return $access->getIelValidationDatetime() && $access->getIelValidationDatetime()->format('Y') === $today->format('Y');
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+}
|