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.

275 lines
11KB

  1. <?php
  2. namespace Lc\CaracoleBundle\Builder\Order;
  3. use Doctrine\ORM\EntityManagerInterface;
  4. use Lc\CaracoleBundle\Builder\File\DocumentBuilder;
  5. use Lc\CaracoleBundle\Event\Order\OrderShopChangeStatusEvent;
  6. use Lc\CaracoleBundle\Factory\File\DocumentFactory;
  7. use Lc\CaracoleBundle\Factory\Order\OrderPaymentFactory;
  8. use Lc\CaracoleBundle\Factory\Order\OrderProductReductionCatalogFactory;
  9. use Lc\CaracoleBundle\Factory\Order\OrderShopFactory;
  10. use Lc\CaracoleBundle\Factory\Order\OrderStatusHistoryFactory;
  11. use Lc\CaracoleBundle\Model\File\DocumentModel;
  12. use Lc\CaracoleBundle\Model\Order\OrderProductInterface;
  13. use Lc\CaracoleBundle\Model\Order\OrderShopInterface;
  14. use Lc\CaracoleBundle\Model\Order\OrderStatusModel;
  15. use Lc\CaracoleBundle\Model\Section\SectionInterface;
  16. use Lc\CaracoleBundle\Model\User\VisitorInterface;
  17. use Lc\CaracoleBundle\Repository\Order\OrderProductStore;
  18. use Lc\CaracoleBundle\Repository\Order\OrderShopStore;
  19. use Lc\CaracoleBundle\Repository\Order\OrderStatusStore;
  20. use Lc\CaracoleBundle\Repository\Product\ProductFamilyStore;
  21. use Lc\CaracoleBundle\Resolver\Price\PriceResolver;
  22. use Lc\SovBundle\Model\User\UserInterface;
  23. class OrderShopBuilder
  24. {
  25. protected EntityManagerInterface $entityManager;
  26. protected OrderStatusStore $orderStatusStore;
  27. protected OrderProductStore $orderProductStore;
  28. protected ProductFamilyStore $productFamilyStore;
  29. protected PriceResolver $priceResolver;
  30. protected OrderProductBuilder $orderProductBuilder;
  31. protected DocumentBuilder $documentBuilder;
  32. public function __construct(
  33. EntityManagerInterface $entityManager,
  34. OrderShopStore $orderShopStore,
  35. OrderStatusStore $orderStatusStore,
  36. OrderProductStore $orderProductStore,
  37. ProductFamilyStore $productFamilyStore,
  38. OrderProductBuilder $orderProductBuilder,
  39. DocumentBuilder $documentBuilder,
  40. PriceResolver $priceResolver
  41. ) {
  42. $this->entityManager = $entityManager;
  43. $this->orderShopStore = $orderShopStore;
  44. $this->orderStatusStore = $orderStatusStore;
  45. $this->orderProductStore = $orderProductStore;
  46. $this->productFamilyStore = $productFamilyStore;
  47. $this->orderProductBuilder = $orderProductBuilder;
  48. $this->documentBuilder = $documentBuilder;
  49. $this->priceResolver = $priceResolver;
  50. }
  51. public function create(
  52. SectionInterface $section,
  53. UserInterface $user = null,
  54. VisitorInterface $visitor = null
  55. ) {
  56. $orderShopFactory = new OrderShopFactory();
  57. $orderShop = $orderShopFactory->create($section, $user, $visitor);
  58. $this->changeOrderStatus($orderShop, OrderStatusModel::ALIAS_CART);
  59. return $orderShop;
  60. }
  61. public function createIfNotExist(
  62. SectionInterface $section,
  63. UserInterface $user = null,
  64. VisitorInterface $visitor = null
  65. ) {
  66. $cart = $this->orderShopStore->getCartBy(
  67. [
  68. 'section' => $section,
  69. 'user' => $user,
  70. 'visitor' => $visitor
  71. ]
  72. );
  73. if (!$cart) {
  74. $cart = $this->create($section, $user, $visitor);
  75. }
  76. return $cart;
  77. }
  78. public function changeOrderStatus(OrderShopInterface $orderShop, string $alias)
  79. {
  80. $orderStatus = $this->orderStatusStore->getRepositoryQuery()->findOneByAlias($alias);
  81. if ($orderShop->getOrderStatus() === null
  82. || $orderShop->getOrderStatus()->getNextStatusAllowed()->contains($orderStatus)) {
  83. $this->eventDispatcher->dispatch(
  84. new OrderShopChangeStatusEvent($orderShop, $orderStatus),
  85. OrderShopChangeStatusEvent::PRE_CHANGE_STATUS
  86. );
  87. $orderShop->setOrderStatusProtected($orderStatus);
  88. $orderStatusHistoryFactory = new OrderStatusHistoryFactory();
  89. $orderStatusHistory = $orderStatusHistoryFactory->create($orderShop, $orderStatus);
  90. $orderShop->addOrderStatusHistory($orderStatusHistory);
  91. }
  92. return $orderShop;
  93. }
  94. public function addOrderProduct(
  95. OrderShopInterface $orderShop,
  96. OrderProductInterface $orderProductAdd,
  97. bool $persist = true
  98. ) {
  99. $return = false;
  100. if ($this->orderProductStore->isOrderProductAvailableAddCart($orderProductAdd, $orderShop)) {
  101. if ($orderProductAdd->getQuantityOrder() > 0) {
  102. $updated = false;
  103. $this->orderProductBuilder->init($orderProductAdd);
  104. $productFamily = $this->productFamilyStore->getOneBySlug(
  105. $orderProductAdd->getProduct()->getProductFamily()->getSlug()
  106. );
  107. if ($productFamily) {
  108. $reductionCatalog = $productFamily->getReductionCatalog();
  109. if ($reductionCatalog) {
  110. $orderProductReductionCatalogFactory = new OrderProductReductionCatalogFactory();
  111. $orderProductReductionCatalog = $orderProductReductionCatalogFactory->create(
  112. $reductionCatalog->getTitle(),
  113. $reductionCatalog->getValue(),
  114. $reductionCatalog->getUnit(),
  115. $reductionCatalog->getBehaviorTaxRate()
  116. );
  117. $orderProductAdd->setOrderProductReductionCatalog($orderProductReductionCatalog);
  118. }
  119. }
  120. foreach ($orderShop->getOrderProducts() as $orderProduct) {
  121. if ($orderProduct->getProduct()->getId() == $orderProductAdd->getProduct()->getId()
  122. && $orderProduct->getRedelivery() == $orderProductAdd->getRedelivery()
  123. && (string)$this->priceResolver->getPrice($orderProduct)
  124. == (string)$this->priceResolver->getPrice($orderProductAdd)
  125. && $orderProduct->getOrderProductReductionCatalog()->compare(
  126. $orderProductAdd->getOrderProductReductionCatalog()
  127. )) {
  128. $orderProduct->setQuantityOrder(
  129. $orderProduct->getQuantityOrder() + $orderProductAdd->getQuantityOrder()
  130. );
  131. if ($persist) {
  132. $this->entityManager->persist($orderProduct);
  133. }
  134. $updated = true;
  135. $return = true;
  136. break;
  137. }
  138. }
  139. if (!$updated) {
  140. $orderShop->addOrderProduct($orderProductAdd);
  141. if ($persist) {
  142. if (isset($orderProductReductionCatalog)) {
  143. $this->entityManager->persist($orderProductReductionCatalog);
  144. }
  145. $this->entityManager->persist($orderProductAdd);
  146. $this->entityManager->persist($orderShop);
  147. }
  148. $return = true;
  149. }
  150. if ($persist) {
  151. $this->entityManager->flush();
  152. }
  153. // @TODO : dispatch event cart change
  154. //$this->eventCartChange($orderShop);
  155. }
  156. } else {
  157. // @TODO : retourner le message d'erreur et faire le addFlash dans le contrôleur
  158. /*$availableQuantity = $orderProductAdd->getProduct()->getAvailableQuantityInherited();
  159. $textError = "Le produit <strong>" . $orderProductAdd->getTitleOrderShop(
  160. ) . "</strong> n'est pas disponible";
  161. if ($availableQuantity !== false && $availableQuantity > 0) {
  162. $unit = '';
  163. if ($orderProductAdd->getProduct()->getProductFamily()->getBehaviorCountStock(
  164. ) == ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE) {
  165. $unit = $orderProductAdd->getProduct()->getUnitInherited()->getUnitReference()->getUnit();
  166. }
  167. $textError .= ' dans cette quantité ';
  168. $user = $this->security->getUser();
  169. if ($user && $user->hasRole('ROLE_USER')) {
  170. $textError .= '<br />' . $availableQuantity . $unit . ' disponible(s) dont ' . $this->getQuantityOrderByProduct(
  171. $orderShop,
  172. $orderProductAdd->getProduct()
  173. ) . $unit . ' déjà dans votre panier.';
  174. }
  175. }
  176. $this->utils->addFlash('error', $textError);*/
  177. }
  178. return $return;
  179. }
  180. public function merge(OrderShopInterface $orderShop1, OrderShopInterface $orderShop2, $persist = true)
  181. {
  182. if ($orderShop1 && $orderShop2) {
  183. foreach ($orderShop2->getOrderProducts() as $orderProduct) {
  184. $orderProductAlreadyInCart = $orderShop1->hasOrderProductAlreadyInCart($orderProduct);
  185. if ($orderProductAlreadyInCart) {
  186. if ($orderProduct->getQuantityOrder() > $orderProductAlreadyInCart->getQuantityOrder()) {
  187. $orderShop1->removeOrderProduct($orderProductAlreadyInCart);
  188. $this->addOrderProduct($orderShop1, $orderProduct);
  189. }
  190. } else {
  191. $this->addOrderProduct($orderShop1, $orderProduct);
  192. }
  193. if ($persist) {
  194. $this->entityManager->remove($orderProduct);
  195. }
  196. }
  197. if ($persist) {
  198. $this->entityManager->remove($orderShop2);
  199. $this->entityManager->persist($orderShop1);
  200. $this->entityManager->flush();
  201. }
  202. return $orderShop1;
  203. }
  204. }
  205. public function addPayment(OrderShopInterface $orderShop, $meanPayment, $amount)
  206. {
  207. $orderPaymentFactory = new OrderPaymentFactory();
  208. $orderPayment = $orderPaymentFactory->create($orderShop, $meanPayment, $amount);
  209. $orderShop->addOrderPayment($orderPayment);
  210. if ($this->isOrderPaid($orderShop)) {
  211. $nextStatus = OrderStatusModel::ALIAS_PAID;
  212. } else {
  213. $nextStatus = OrderStatusModel::ALIAS_PARTIAL_PAYMENT;
  214. }
  215. if ($orderShop->getOrderStatus()->getAlias() != $nextStatus) {
  216. $orderShop = $this->changeOrderStatus($orderShop, $nextStatus);
  217. }
  218. $this->entityManager->persist($orderPayment);
  219. $this->entityManager->update($orderShop);
  220. $this->entityManager->flush();
  221. return $orderShop;
  222. }
  223. public function createDocumentInvoice(OrderShopInterface $orderShop)
  224. {
  225. $documentFactory = new DocumentFactory();
  226. $document = $documentFactory->create(DocumentModel::TYPE_INVOICE);
  227. $this->documentBuilder->initFromOrderShop($orderShop);
  228. return $document;
  229. }
  230. }