Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

195 linhas
6.9KB

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