Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

234 lines
8.0KB

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