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.

233 lines
9.6KB

  1. <?php
  2. namespace domain\Distribution\Distribution;
  3. use domain\Distribution\Distribution\Event\DistributionActiveEvent;
  4. use domain\Distribution\PointSaleDistribution\PointSaleDistribution;
  5. use domain\Distribution\PointSaleDistribution\PointSaleDistributionBuilder;
  6. use domain\Distribution\PointSaleDistribution\PointSaleDistributionRepository;
  7. use domain\Distribution\ProductDistribution\ProductDistribution;
  8. use domain\Distribution\ProductDistribution\ProductDistributionBuilder;
  9. use domain\Distribution\ProductDistribution\ProductDistributionRepository;
  10. use domain\Order\Order\OrderRepository;
  11. use domain\Order\ProductOrder\ProductOrderBuilder;
  12. use domain\PointSale\PointSale\PointSale;
  13. use domain\PointSale\PointSale\PointSaleRepository;
  14. use domain\Product\Product\Product;
  15. use domain\Product\Product\ProductRepository;
  16. use domain\Product\Product\ProductSolver;
  17. use domain\User\UserProducer\UserProducerRepository;
  18. use domain\_\AbstractBuilder;
  19. class DistributionBuilder extends AbstractBuilder
  20. {
  21. protected DistributionRepository $distributionRepository;
  22. protected DistributionSolver $distributionSolver;
  23. protected PointSaleDistributionRepository $pointSaleDistributionRepository;
  24. protected PointSaleDistributionBuilder $pointSaleDistributionBuilder;
  25. protected ProductRepository $productRepository;
  26. protected ProductDistributionRepository $productDistributionRepository;
  27. protected ProductDistributionBuilder $productDistributionBuilder;
  28. protected OrderRepository $orderRepository;
  29. protected UserProducerRepository $userProducerRepository;
  30. protected ProductOrderBuilder $productOrderBuilder;
  31. protected ProductSolver $productSolver;
  32. protected PointSaleRepository $pointSaleRepository;
  33. public function loadDependencies(): void
  34. {
  35. $this->distributionRepository = $this->loadService(DistributionRepository::class);
  36. $this->distributionSolver = $this->loadService(DistributionSolver::class);
  37. $this->pointSaleDistributionRepository = $this->loadService(PointSaleDistributionRepository::class);
  38. $this->pointSaleDistributionBuilder = $this->loadService(PointSaleDistributionBuilder::class);
  39. $this->productRepository = $this->loadService(ProductRepository::class);
  40. $this->productDistributionRepository = $this->loadService(ProductDistributionRepository::class);
  41. $this->productDistributionBuilder = $this->loadService(ProductDistributionBuilder::class);
  42. $this->orderRepository = $this->loadService(OrderRepository::class);
  43. $this->userProducerRepository = $this->loadService(UserProducerRepository::class);
  44. $this->productOrderBuilder = $this->loadService(ProductOrderBuilder::class);
  45. $this->productSolver = $this->loadService(ProductSolver::class);
  46. $this->pointSaleRepository = $this->loadService(PointSaleRepository::class);
  47. }
  48. public function instanciateDistribution(string $date, bool $delivery = true): Distribution
  49. {
  50. $distribution = new Distribution();
  51. $distribution->populateProducer($this->getProducerContext());
  52. $distribution->date = $date;
  53. $distribution->delivery = (int) $delivery;
  54. return $distribution;
  55. }
  56. public function createDistribution(string $date, bool $delivery = true): Distribution
  57. {
  58. $distribution = $this->instanciateDistribution($date, $delivery);
  59. $this->create($distribution);
  60. $this->createPointSaleDistributions($distribution);
  61. $this->createProductDistributions($distribution);
  62. return $distribution;
  63. }
  64. public function createDistributionIfNotExist(string $date, int $delivery = 1)
  65. {
  66. return $this->distributionRepository->findOneDistribution($date)
  67. ?? $this->createDistribution($date, $delivery);
  68. }
  69. public function createPointSaleDistributions(Distribution $distribution): void
  70. {
  71. $countPointSaleDistribution = $this->pointSaleDistributionRepository->countPointSaleDistributionsByDistribution($distribution);
  72. if (!$countPointSaleDistribution) {
  73. $this->pointSaleDistributionBuilder->createAllPointSaleDistributions($distribution, true);
  74. }
  75. }
  76. public function createProductDistributions(Distribution $distribution): void
  77. {
  78. $productArray = $this->productRepository->findProducts();
  79. $countProductDistribution = $this->productDistributionRepository->countProductDistributionsByDistribution($distribution);
  80. if (!$countProductDistribution) {
  81. foreach ($productArray as $product) {
  82. $this->addProduct($distribution, $product);
  83. }
  84. }
  85. }
  86. /**
  87. * Ajoute un produit à une distribution.
  88. */
  89. public function addProduct(Distribution $distribution, Product $product): ?ProductDistribution
  90. {
  91. if($this->productSolver->isStatusOnlineOrOffline($product)) {
  92. $productDistribution = $this->productDistributionBuilder->createProductDistributionIfNotExist($distribution, $product);
  93. $this->productDistributionBuilder->updateProductDistribution($productDistribution);
  94. $this->updateOrderProductPrices($distribution, $product);
  95. return $productDistribution;
  96. }
  97. return null;
  98. }
  99. /**
  100. * Lie un produit aux distributions futures.
  101. */
  102. public function addProductIncomingDistributions(Product $product): void
  103. {
  104. $distributionArray = $this->distributionRepository->findDistributionsIncoming(true);
  105. foreach ($distributionArray as $distribution) {
  106. $this->addProduct($distribution, $product);
  107. }
  108. }
  109. /**
  110. * Ajoute un point de vente à une distribution
  111. */
  112. public function addPointSale(Distribution $distribution, PointSale $pointSale): PointSaleDistribution
  113. {
  114. $pointSaleDistribution = $this->pointSaleDistributionBuilder->createPointSaleDistributionIfNotExist($distribution, $pointSale);
  115. $dayString = $this->distributionSolver->getDistributionDayAsString($distribution);
  116. $pointSaleDistribution->delivery = 0;
  117. $deliveryDay = 'delivery_' . $dayString;
  118. if ($pointSale->$deliveryDay) {
  119. $pointSaleDistribution->delivery = 1;
  120. }
  121. $this->saveUpdate($pointSaleDistribution);
  122. return $pointSaleDistribution;
  123. }
  124. /**
  125. * Ajoute un point de vente aux distributions futures.
  126. */
  127. public function addPointSaleIncomingDistributions(PointSale $pointSale): void
  128. {
  129. $distributionArray = $this->distributionRepository->findDistributionsIncoming(true);
  130. foreach ($distributionArray as $distribution) {
  131. $this->addPointSale($distribution, $pointSale);
  132. }
  133. }
  134. public function updateOrderProductPrices(Distribution $distribution, Product $product): void
  135. {
  136. $ordersArray = $this->orderRepository->findOrdersByDistribution($distribution, false, 'origin != "user"');
  137. if ($ordersArray) {
  138. foreach ($ordersArray as $order) {
  139. foreach ($order->productOrder as $productOrder) {
  140. if ($productOrder->id_product == $product->id) {
  141. $user = null;
  142. $userProducer = null;
  143. if (isset($order->user) && $order->user) {
  144. $user = $order->user;
  145. $userProducer = $this->userProducerRepository->findOneUserProducer($user);
  146. }
  147. $this->productOrderBuilder->updateProductOrderPrice(
  148. $productOrder,
  149. $user,
  150. $userProducer,
  151. $order->pointSale,
  152. $productOrder->quantity
  153. );
  154. }
  155. }
  156. }
  157. }
  158. }
  159. /**
  160. * Active ou désactive la distribution.
  161. */
  162. public function activeDistribution(Distribution $distribution, bool $active = true): void
  163. {
  164. $distribution->active = (int) $active;
  165. $this->update($distribution);
  166. $this->pointSaleDistributionBuilder->createAllPointSaleDistributions($distribution, true);
  167. if ($active) {
  168. $distributionActiveEvent = new DistributionActiveEvent();
  169. $distributionActiveEvent->distribution = $distribution;
  170. $distribution->trigger(Distribution::EVENT_ACTIVE, $distributionActiveEvent);
  171. }
  172. }
  173. public function activeDistributionByDate(\DateTime $date, bool $active = true): void
  174. {
  175. $distribution = $this->createDistributionIfNotExist($date->format('Y-m-d'));
  176. $this->activeDistribution($distribution, $active);
  177. }
  178. public function activeDistributionByDateIfDelivery(\DateTime $date, bool $active = true): void
  179. {
  180. $activeDay = $this->pointSaleRepository->isDayOfWeekWithDelivery($date->format('l'));
  181. if($activeDay || !$active) {
  182. $this->activeDistributionByDate($date, $active);
  183. }
  184. }
  185. public function activeDistributionByDayWeek(string $date, string $dayWeek, bool $active = true): void
  186. {
  187. $week = sprintf('%02d', date('W', strtotime($date)));
  188. $start = strtotime(date('Y', strtotime($date)) . 'W' . $week);
  189. $dateDay = new \DateTime(date('Y-m-d', strtotime($dayWeek, $start)));
  190. $this->activeDistributionByDateIfDelivery($dateDay, $active);
  191. }
  192. public function activeDistributionsOfWeek(string $date, bool $active = true): void
  193. {
  194. $daysWeekArray = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
  195. foreach($daysWeekArray as $dayWeek) {
  196. $this->activeDistributionByDayWeek($date, $dayWeek, $active);
  197. }
  198. }
  199. }