DateTimeConstraint.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Service\Constraint;
  4. use App\Entity\Access\Access;
  5. use App\Service\Organization\Utils as OrganizationUtils;
  6. use App\Tests\Service\Constraint\DateTimeConstraintTest;
  7. use Doctrine\ORM\EntityManagerInterface;
  8. /**
  9. * Classe DateTimeConstraint qui définie les dates de débuts et fin de périodes
  10. * par rapport au contraintes temporelles choisies par un utilisateur.
  11. */
  12. class DateTimeConstraint extends AbstractTimeConstraintUtils implements TimeConstraintInterface
  13. {
  14. public function __construct(
  15. private readonly EntityManagerInterface $entityManager,
  16. private readonly OrganizationUtils $organizationUtils,
  17. ) {
  18. }
  19. /**
  20. * Main méthod.
  21. *
  22. * @return array<string, array<string, list<int>>>
  23. *
  24. * @throws \Exception
  25. */
  26. public function invoke(int $accessID): array
  27. {
  28. $access = $this->entityManager->getRepository(Access::class)->find($accessID);
  29. $historical = $access->getHistorical();
  30. $contraints = [
  31. self::START_KEY => [],
  32. self::END_KEY => [],
  33. ];
  34. if ($this->hasCustomPeriods($historical)) {
  35. $periods = $this->getCustomPeriods($historical['dateStart'], $historical['dateEnd']);
  36. // Une période "Custom" reviens à savoir quels sont les éléments actif durant le "présent" de la période custom, donc
  37. // on peut utiliser le presentConstraint avec les periods custom
  38. $contraints = $this->addConstraint($contraints, $this->presentConstraint($periods));
  39. } else {
  40. $periods = $this->getPeriods($access);
  41. if ($historical['present'] ?? false) {
  42. $contraints = $this->addConstraint($contraints, $this->presentConstraint($periods));
  43. }
  44. if ($historical['past'] ?? false) {
  45. $contraints = $this->addConstraint($contraints, $this->pastConstraint($periods));
  46. }
  47. if ($historical['future'] ?? false) {
  48. $contraints = $this->addConstraint($contraints, $this->futureConstraint($periods));
  49. }
  50. }
  51. return $this->cleanConstraints($contraints);
  52. }
  53. /**
  54. * Retourne le tableau des périodes custom.
  55. *
  56. * @return string[]
  57. */
  58. protected function getCustomPeriods(string $dateStart, string $dateEnd): array
  59. {
  60. return [
  61. OrganizationUtils::START_DATE_KEY => $dateStart,
  62. OrganizationUtils::END_DATE_KEY => $dateEnd,
  63. ];
  64. }
  65. /**
  66. * Fonction permettant de récupérer les périodes de début et de fin d'affichage.
  67. *
  68. * @return string[]
  69. *
  70. * @throws \Exception
  71. *
  72. * @see DateTimeConstraintTest::testGetPeriodsToday()
  73. */
  74. protected function getPeriods(Access $access): array
  75. {
  76. $organization = $access->getOrganization();
  77. $activityYear = $access->getActivityYear();
  78. $currentActivityYear = $this->organizationUtils->getOrganizationCurrentActivityYear($organization);
  79. $periods = $this->organizationUtils->getActivityPeriodsSwitchYear($organization, $activityYear);
  80. // Si l'année courante est l'année d'affichage choisie par l'utilisateur, alors la date de début est aujourd'hui
  81. if ($activityYear === $currentActivityYear) {
  82. $today = new \DateTime('now');
  83. $periods[OrganizationUtils::START_DATE_KEY] = $today->format('Y-m-d');
  84. }
  85. return $periods;
  86. }
  87. /**
  88. * Une période est dans le présent si :
  89. * - la date de début est plus petite ou égale (<=) à la date de fin de période à afficher
  90. * ET
  91. * - la date de fin est plus grande ou égale (>=) à la date de fin de période à afficher OU que la date de fin n'est pas remplie (NULL)
  92. *
  93. * @param string[] $periods
  94. *
  95. * @return array<string, int[]>
  96. *
  97. * @see DateTimeConstraintTest::testPresentConstrain()
  98. */
  99. protected function presentConstraint(array $periods): array
  100. {
  101. return [
  102. self::START_KEY => [
  103. $periods[OrganizationUtils::END_DATE_KEY] => self::INF + self::EQUAL,
  104. ],
  105. self::END_KEY => [
  106. $periods[OrganizationUtils::START_DATE_KEY] => self::SUP + self::EQUAL,
  107. self::NULL_VALUE => self::NULL,
  108. ],
  109. ];
  110. }
  111. /**
  112. * Une période est dans le passé si :
  113. * - la date de fin est plus petite (<) que la date de début de période à afficher
  114. *
  115. * @param string[] $periods
  116. *
  117. * @return array<string, int[]>
  118. *
  119. * @see DateTimeConstraintTest::testPastConstrain()
  120. */
  121. protected function pastConstraint(array $periods): array
  122. {
  123. return [
  124. self::END_KEY => [
  125. $periods[OrganizationUtils::START_DATE_KEY] => self::INF,
  126. ],
  127. ];
  128. }
  129. /**
  130. * Une période est dans le futur si :
  131. * - la date de début est plus grande (>) que la date de fin de période à afficher
  132. *
  133. * @param string[] $periods
  134. *
  135. * @return array<string, int[]>
  136. *
  137. * @see DateTimeConstraintTest::testFuturConstrain()
  138. */
  139. protected function futureConstraint(array $periods): array
  140. {
  141. return [
  142. self::START_KEY => [
  143. $periods[OrganizationUtils::END_DATE_KEY] => self::SUP,
  144. ],
  145. ];
  146. }
  147. }