You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 line
6.5KB

  1. <?php
  2. namespace Lc\CaracoleBundle\Resolver;
  3. use App\Entity\Section\Section;
  4. use Lc\CaracoleBundle\Definition\SectionSettingDefinition;
  5. use Lc\CaracoleBundle\Model\Section\OpeningInterface;
  6. use Lc\CaracoleBundle\Model\Section\SectionInterface;
  7. use Lc\CaracoleBundle\Repository\Order\OrderShopStore;
  8. use Lc\SovBundle\Model\User\UserInterface;
  9. use Symfony\Component\Security\Core\Security;
  10. class OpeningResolver
  11. {
  12. const OPENING_CONTEXT_FRONTEND = 'frontend' ;
  13. const OPENING_CONTEXT_BACKEND = 'backend' ;
  14. protected array $messages = [];
  15. protected SectionResolver $sectionResolver;
  16. protected Security $security;
  17. protected OrderShopStore $orderShopStore;
  18. public function __construct(SectionResolver $sectionResolver, Security $security, OrderShopStore $orderShopStore)
  19. {
  20. $this->sectionResolver = $sectionResolver;
  21. $this->security = $security;
  22. $this->orderShopStore = $orderShopStore;
  23. }
  24. public function isOpenSale(
  25. SectionInterface $section,
  26. UserInterface $user = null,
  27. \DateTime $date = null,
  28. string $context = null
  29. ): bool {
  30. // Initialisation
  31. $this->messages = [];
  32. if (is_null($date)) {
  33. $date = new \DateTime();
  34. }
  35. // État des prise de commande (voir configuration de section)
  36. $orderState = $section->getSettingValue(SectionSettingDefinition::SETTING_ORDER_STATE);
  37. if ($orderState == SectionSettingDefinition::VALUE_ORDER_STATE_OPEN) {
  38. $this->addMessage('Les commandes sont ouvertes (configuration de la section).');
  39. return true;
  40. }
  41. if ($orderState == SectionSettingDefinition::VALUE_ORDER_STATE_CLOSED) {
  42. $this->addMessage('Les commandes sont fermées (configuration de la section).');
  43. return false;
  44. }
  45. // Nombre maximum de commandes par cycle (voir configuration de section)
  46. if($this->isMaximumOrderCycleAchieved($section)) {
  47. $this->addMessage('Le nombre maximum de commande a été atteint.');
  48. return false;
  49. }
  50. // Période de fermeture des commandes issue de la configuration de la section (congés)
  51. if($this->isClosingPeriod($section, $date)) {
  52. $this->addMessage(
  53. 'Les commandes sont fermées (période de fermeture des commandes dans la configuration de la section).'
  54. );
  55. return false;
  56. }
  57. // Période d'ouverture des commandes
  58. $openings = $section->getOpenings();
  59. foreach ($openings as $opening) {
  60. if(!$opening->getGroupUser() || ($opening->getGroupUser() && $user && $user->getGroupUsers()->contains($opening->getGroupUser()))) {
  61. if ($this->isDateMatchWithOpening($date, $opening)) {
  62. $this->addMessage('Les commandes sont ouvertes (périodes d\'ouverture classique des commandes).');
  63. return true;
  64. }
  65. }
  66. }
  67. $this->addMessage('Les commandes sont fermées (périodes d\'ouverture classique des commandes).');
  68. return false;
  69. }
  70. // isHolidays
  71. public function isClosingPeriod(SectionInterface $section, \DateTime $date)
  72. {
  73. $orderClosedStart = $section->getSettingValue(SectionSettingDefinition::SETTING_ORDER_CLOSED_START);
  74. $orderClosedEnd = $section->getSettingValue(SectionSettingDefinition::SETTING_ORDER_CLOSED_END);
  75. if ($orderClosedStart && $orderClosedEnd && $date >= $orderClosedStart && $date <= $orderClosedEnd) {
  76. return true;
  77. }
  78. return false;
  79. }
  80. // isMaximumOrderWeekAchieved
  81. public function isMaximumOrderCycleAchieved(SectionInterface $section)
  82. {
  83. $countOrderShopCycle = $this->orderShopStore->countValidByCurrentCycle();
  84. $orderMaximumPerCycle = $section->getSettingValue(SectionSettingDefinition::SETTING_ORDER_MAXIMUM_PER_CYCLE);
  85. if ($orderMaximumPerCycle && $countOrderShopCycle >= $orderMaximumPerCycle) {
  86. return true;
  87. }
  88. return false;
  89. }
  90. public function isDateMatchWithOpening(\DateTime $date, OpeningInterface $opening): bool
  91. {
  92. $day = $date->format('N');
  93. $dayOpening = $opening->getDay();
  94. if ($opening->getTimeStart()) {
  95. $dateOpeningStart = clone $date;
  96. $dateOpeningStart->setTime(
  97. $opening->getTimeStart()->format('H'),
  98. $opening->getTimeStart()->format('i')
  99. );
  100. }
  101. if ($opening->getTimeEnd()) {
  102. $dateOpeningEnd = clone $date;
  103. $dateOpeningEnd->setTime(
  104. $opening->getTimeEnd()->format('H'),
  105. $opening->getTimeEnd()->format('i')
  106. );
  107. }
  108. if ($day == $dayOpening) {
  109. // Commandes ouvertes toute la journée
  110. if (!$opening->getTimeStart() && !$opening->getTimeEnd()) {
  111. return true;
  112. } // Commandes ouvertes à partir de timeStart
  113. elseif ($opening->getTimeStart() && !$opening->getTimeEnd() && $date >= $dateOpeningStart) {
  114. return true;
  115. } // Commandes ouvertes jusqu'à timeEnd
  116. elseif (!$opening->getTimeStart() && $opening->getTimeEnd() && $date < $dateOpeningEnd) {
  117. return true;
  118. } // Commandes ouvertes de timeStart à timeEnd
  119. elseif ($opening->getTimeStart() && $opening->getTimeEnd()
  120. && $date >= $dateOpeningStart && $date < $dateOpeningEnd) {
  121. return true;
  122. }
  123. }
  124. return false;
  125. }
  126. public function getDateEndCurrentSale(SectionInterface $section, $formatDate = '', $delimiterDayTime = 'à')
  127. {
  128. // @TODO : à réécrire
  129. }
  130. public function getDateBeginNextSale(SectionInterface $section, $formatDate = '', $delimiterDayTime = 'à')
  131. {
  132. // @TODO : à réécrire
  133. }
  134. public function getMessages(): array
  135. {
  136. return $this->messages;
  137. }
  138. public function addMessage(string $message): void
  139. {
  140. $this->messages[] = $message;
  141. }
  142. public function isOpenSaleOnlyComplementaryOrders(Section $section, UserInterface $user)
  143. {
  144. // @TODO : ajouter une option dans les sections (permettre les commandes complémentaires ou non)
  145. $orderShopsUser = $this->orderShopStore->setSection($section)->getByCurrentCycleAndUser($user);
  146. return $this->isOpenSale($section, $user)
  147. && $this->isMaximumOrderCycleAchieved($section)
  148. && count($orderShopsUser) > 0;
  149. }
  150. }