Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

327 lines
11KB

  1. <?php
  2. namespace Lc\CaracoleBundle\Resolver;
  3. use Lc\CaracoleBundle\Definition\SectionSettingDefinition;
  4. use Lc\CaracoleBundle\Model\Section\OpeningInterface;
  5. use Lc\CaracoleBundle\Model\Section\SectionInterface;
  6. use Lc\CaracoleBundle\Repository\Order\OrderShopStore;
  7. use Lc\CaracoleBundle\Repository\Section\OpeningStore;
  8. use Lc\CaracoleBundle\Solver\Section\OpeningSolver;
  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. protected OpeningStore $openingStore;
  22. protected OpeningSolver $openingSolver;
  23. public function __construct(
  24. SectionResolver $sectionResolver,
  25. Security $security,
  26. OrderShopStore $orderShopStore,
  27. SettingSolver $settingSolver,
  28. OpeningStore $openingStore,
  29. OpeningSolver $openingSolver
  30. ) {
  31. $this->sectionResolver = $sectionResolver;
  32. $this->security = $security;
  33. $this->orderShopStore = $orderShopStore;
  34. $this->settingSolver = $settingSolver;
  35. $this->openingStore = $openingStore;
  36. $this->openingSolver = $openingSolver;
  37. }
  38. public function isOpenSale(
  39. SectionInterface $section = null,
  40. UserInterface $user = null,
  41. string $context = null
  42. ): bool {
  43. // Initialisation
  44. $this->messages = [];
  45. if (is_null($section)) {
  46. $section = $this->sectionResolver->getCurrent(true);
  47. }
  48. if (is_null($user)) {
  49. $user = $this->security->getUser();
  50. }
  51. $date = new \DateTime();
  52. // État des prise de commande (voir configuration de section)
  53. $orderState = $this->settingSolver->getSettingValue($section, SectionSettingDefinition::SETTING_ORDER_STATE);
  54. if ($orderState == SectionSettingDefinition::VALUE_ORDER_STATE_OPEN) {
  55. $this->addMessage('Les commandes sont ouvertes (configuration de la section).');
  56. return true;
  57. }
  58. if ($orderState == SectionSettingDefinition::VALUE_ORDER_STATE_CLOSED) {
  59. $this->addMessage('Les commandes sont fermées (configuration de la section).');
  60. return false;
  61. }
  62. // Nombre maximum de commandes par cycle (voir configuration de section)
  63. if ($this->isMaximumOrderDistributionAchieved($section)) {
  64. $this->addMessage('Le nombre maximum de commande a été atteint.');
  65. return false;
  66. }
  67. // Période de fermeture des commandes issue de la configuration de la section (congés)
  68. if ($this->isClosingPeriod($section, $date)) {
  69. $this->addMessage(
  70. 'Les commandes sont fermées (période de fermeture des commandes dans la configuration de la section).'
  71. );
  72. return false;
  73. }
  74. // Période d'ouverture des commandes
  75. $openings = $section->getOpenings();
  76. foreach ($openings as $opening) {
  77. if (!$opening->getGroupUser() || ($opening->getGroupUser() && $user && $user->getGroupUsers()->contains(
  78. $opening->getGroupUser()
  79. ))) {
  80. if ($this->isDateMatchWithOpening($date, $opening)) {
  81. $this->addMessage('Les commandes sont ouvertes (périodes d\'ouverture classique des commandes).');
  82. return true;
  83. }
  84. }
  85. }
  86. $this->addMessage('Les commandes sont fermées (périodes d\'ouverture classique des commandes).');
  87. return false;
  88. }
  89. public function isOpenFullTime(SectionInterface $section = null)
  90. {
  91. if (is_null($section)) {
  92. $section = $this->sectionResolver->getCurrent();
  93. }
  94. $orderState = $this->settingSolver->getSettingValue($section, SectionSettingDefinition::SETTING_ORDER_STATE);
  95. if ($orderState == SectionSettingDefinition::VALUE_ORDER_STATE_OPEN) {
  96. return true;
  97. }
  98. return false;
  99. }
  100. // isHolidays
  101. public function isClosingPeriod(SectionInterface $section = null, \DateTime $date = null)
  102. {
  103. if (is_null($section)) {
  104. $section = $this->sectionResolver->getCurrent();
  105. }
  106. if(is_null($date)) {
  107. $date = new \DateTime();
  108. }
  109. $orderClosedStart = $this->settingSolver->getSettingValue(
  110. $section,
  111. SectionSettingDefinition::SETTING_ORDER_CLOSED_START
  112. );
  113. $orderClosedEnd = $this->settingSolver->getSettingValue(
  114. $section,
  115. SectionSettingDefinition::SETTING_ORDER_CLOSED_END
  116. );
  117. if ($orderClosedStart && $orderClosedEnd && $date >= $orderClosedStart && $date <= $orderClosedEnd) {
  118. return true;
  119. }
  120. return false;
  121. }
  122. // isMaximumOrderWeekAchieved
  123. //isMaximumOrderCycleAchieved
  124. public function isMaximumOrderDistributionAchieved(SectionInterface $section)
  125. {
  126. $countOrderShopCycle = $this->orderShopStore
  127. ->setSection($section)
  128. ->countValidByCurrentDistribution();
  129. $orderMaximumPerCycle = $this->settingSolver->getSettingValue(
  130. $section,
  131. SectionSettingDefinition::SETTING_ORDER_MAXIMUM_PER_CYCLE
  132. );
  133. if ($orderMaximumPerCycle && $countOrderShopCycle >= $orderMaximumPerCycle) {
  134. return true;
  135. }
  136. return false;
  137. }
  138. public function isDateMatchWithOpening(\DateTime $date, OpeningInterface $opening): bool
  139. {
  140. $day = $date->format('N');
  141. $dayOpening = $opening->getDay();
  142. if ($opening->getTimeStart()) {
  143. $dateOpeningStart = clone $date;
  144. $dateOpeningStart->setTime(
  145. $opening->getTimeStart()->format('H'),
  146. $opening->getTimeStart()->format('i')
  147. );
  148. }
  149. if ($opening->getTimeEnd()) {
  150. $dateOpeningEnd = clone $date;
  151. $dateOpeningEnd->setTime(
  152. $opening->getTimeEnd()->format('H'),
  153. $opening->getTimeEnd()->format('i')
  154. );
  155. }
  156. if ($day == $dayOpening) {
  157. // Commandes ouvertes toute la journée
  158. if (!$opening->getTimeStart() && !$opening->getTimeEnd()) {
  159. return true;
  160. } // Commandes ouvertes à partir de timeStart
  161. elseif ($opening->getTimeStart() && !$opening->getTimeEnd() && $date >= $dateOpeningStart) {
  162. return true;
  163. } // Commandes ouvertes jusqu'à timeEnd
  164. elseif (!$opening->getTimeStart() && $opening->getTimeEnd() && $date < $dateOpeningEnd) {
  165. return true;
  166. } // Commandes ouvertes de timeStart à timeEnd
  167. elseif ($opening->getTimeStart() && $opening->getTimeEnd()
  168. && $date >= $dateOpeningStart && $date < $dateOpeningEnd) {
  169. return true;
  170. }
  171. }
  172. return false;
  173. }
  174. // getDateEndCurrentSale
  175. public function getFormatedDateClosingCurrentSale(
  176. SectionInterface $section = null,
  177. $formatDate = '',
  178. $delimiterDayTime = 'à'
  179. ) {
  180. if (is_null($section)) {
  181. $section = $this->sectionResolver->getCurrent();
  182. }
  183. $date = new \DateTime();
  184. $openingArray = $this->openingStore
  185. ->setSection($section)
  186. ->get();
  187. if ($this->isOpenSale($section)) {
  188. $openingClosing = $this->openingSolver->getNextOpeningOfClosing($date, $openingArray);
  189. if ($openingClosing) {
  190. return $this->openingSolver->getFormatedDateByFormatAndDelimiterDayTime(
  191. $date,
  192. $openingClosing->getTimeEnd(),
  193. $formatDate,
  194. $delimiterDayTime
  195. );
  196. }
  197. }
  198. return '';
  199. }
  200. // getDateBeginNextSale
  201. public function getFormatedDateOpeningNextSale(
  202. SectionInterface $section = null,
  203. $formatDate = '',
  204. $delimiterDayTime = 'à'
  205. ) {
  206. if (is_null($section)) {
  207. $section = $this->sectionResolver->getCurrent();
  208. }
  209. $date = new \DateTime();
  210. if($this->isClosingPeriod($section)) {
  211. $date = $this->settingSolver->getSettingValue(
  212. $section,
  213. SectionSettingDefinition::SETTING_ORDER_CLOSED_END
  214. );
  215. }
  216. $openingArray = $this->openingStore
  217. ->setSection($section)
  218. ->get();
  219. if (!$this->isOpenSale($section)) {
  220. $opening = $this->openingSolver->getNextOpeningOfOpening($date, $openingArray);
  221. if ($opening) {
  222. return $this->openingSolver->getFormatedDateByFormatAndDelimiterDayTime(
  223. $date,
  224. $opening->getTimeStart() ?: (new \DateTime())->setTime(0, 0),
  225. $formatDate,
  226. $delimiterDayTime
  227. );
  228. }
  229. }
  230. return '';
  231. }
  232. public function isOpenSaleOnlyComplementaryOrders(SectionInterface $section = null, UserInterface $user = null)
  233. {
  234. if (is_null($section)) {
  235. $section = $this->sectionResolver->getCurrent();
  236. }
  237. if (is_null($user)) {
  238. $user = $this->security->getUser();
  239. }
  240. // @TODO : ajouter une option dans les sections (permettre les commandes complémentaires ou non)
  241. $orderShopsUser = $this->orderShopStore->setSection($section)->getByCurrentDistributionAndUser($user);
  242. return $this->isOpenSale($section, $user)
  243. && $this->isMaximumOrderDistributionAchieved($section)
  244. && count($orderShopsUser) > 0;
  245. }
  246. public function getMessageOpeningNextSale(SectionInterface $section): ?string
  247. {
  248. $openingTextClosed = $this->settingSolver->getSettingValue(
  249. $section,
  250. SectionSettingDefinition::SETTING_OPENING_TEXT_CLOSED
  251. );
  252. if ($openingTextClosed && strlen($openingTextClosed) > 0) {
  253. return $openingTextClosed ;
  254. }
  255. $dateOpeningNextSale = $this->getFormatedDateOpeningNextSale($section);
  256. if ($dateOpeningNextSale && strlen($dateOpeningNextSale) > 0) {
  257. return 'Réouverture aux commandes le <span class="underline">'.$dateOpeningNextSale.'</span>' ;
  258. }
  259. return null;
  260. }
  261. public function getMessages(): array
  262. {
  263. return $this->messages;
  264. }
  265. public function addMessage(string $message): void
  266. {
  267. $this->messages[] = $message;
  268. }
  269. }