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.

374 lines
16KB

  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\OrderReductionCartFactory;
  10. use Lc\CaracoleBundle\Factory\Order\OrderReductionCreditFactory;
  11. use Lc\CaracoleBundle\Factory\Order\OrderShopFactory;
  12. use Lc\CaracoleBundle\Factory\Order\OrderStatusHistoryFactory;
  13. use Lc\CaracoleBundle\Model\File\DocumentModel;
  14. use Lc\CaracoleBundle\Model\Order\OrderProductInterface;
  15. use Lc\CaracoleBundle\Model\Order\OrderShopInterface;
  16. use Lc\CaracoleBundle\Model\Order\OrderStatusModel;
  17. use Lc\CaracoleBundle\Model\Product\ProductFamilyModel;
  18. use Lc\CaracoleBundle\Model\Reduction\ReductionCartInterface;
  19. use Lc\CaracoleBundle\Model\Reduction\ReductionCreditInterface;
  20. use Lc\CaracoleBundle\Model\Section\SectionInterface;
  21. use Lc\CaracoleBundle\Model\User\VisitorInterface;
  22. use Lc\CaracoleBundle\Repository\Order\OrderProductStore;
  23. use Lc\CaracoleBundle\Repository\Order\OrderShopStore;
  24. use Lc\CaracoleBundle\Repository\Order\OrderStatusStore;
  25. use Lc\CaracoleBundle\Repository\Product\ProductFamilyStore;
  26. use Lc\CaracoleBundle\Resolver\Price\PriceResolver;
  27. use Lc\SovBundle\Model\User\UserInterface;
  28. class OrderShopBuilder
  29. {
  30. protected EntityManagerInterface $entityManager;
  31. protected OrderStatusStore $orderStatusStore;
  32. protected OrderProductStore $orderProductStore;
  33. protected ProductFamilyStore $productFamilyStore;
  34. protected PriceResolver $priceResolver;
  35. protected OrderProductBuilder $orderProductBuilder;
  36. protected DocumentBuilder $documentBuilder;
  37. public function __construct(
  38. EntityManagerInterface $entityManager,
  39. OrderShopStore $orderShopStore,
  40. OrderStatusStore $orderStatusStore,
  41. OrderProductStore $orderProductStore,
  42. ProductFamilyStore $productFamilyStore,
  43. OrderProductBuilder $orderProductBuilder,
  44. DocumentBuilder $documentBuilder,
  45. PriceResolver $priceResolver
  46. ) {
  47. $this->entityManager = $entityManager;
  48. $this->orderShopStore = $orderShopStore;
  49. $this->orderStatusStore = $orderStatusStore;
  50. $this->orderProductStore = $orderProductStore;
  51. $this->productFamilyStore = $productFamilyStore;
  52. $this->orderProductBuilder = $orderProductBuilder;
  53. $this->documentBuilder = $documentBuilder;
  54. $this->priceResolver = $priceResolver;
  55. }
  56. public function create(
  57. SectionInterface $section,
  58. UserInterface $user = null,
  59. VisitorInterface $visitor = null
  60. ) {
  61. $orderShopFactory = new OrderShopFactory();
  62. $orderShop = $orderShopFactory->create($section, $user, $visitor);
  63. $this->changeOrderStatus($orderShop, OrderStatusModel::ALIAS_CART);
  64. return $orderShop;
  65. }
  66. public function createIfNotExist(
  67. SectionInterface $section,
  68. UserInterface $user = null,
  69. VisitorInterface $visitor = null
  70. ) {
  71. $cart = $this->orderShopStore->getCartBy(
  72. [
  73. 'section' => $section,
  74. 'user' => $user,
  75. 'visitor' => $visitor
  76. ]
  77. );
  78. if (!$cart) {
  79. $cart = $this->create($section, $user, $visitor);
  80. }
  81. return $cart;
  82. }
  83. public function changeOrderStatus(OrderShopInterface $orderShop, string $alias)
  84. {
  85. $orderStatus = $this->orderStatusStore->getRepositoryQuery()->findOneByAlias($alias);
  86. if ($orderShop->getOrderStatus() === null
  87. || $orderShop->getOrderStatus()->getNextStatusAllowed()->contains($orderStatus)) {
  88. $this->eventDispatcher->dispatch(
  89. new OrderShopChangeStatusEvent($orderShop, $orderStatus),
  90. OrderShopChangeStatusEvent::PRE_CHANGE_STATUS
  91. );
  92. $orderShop->setOrderStatusProtected($orderStatus);
  93. $orderStatusHistoryFactory = new OrderStatusHistoryFactory();
  94. $orderStatusHistory = $orderStatusHistoryFactory->create($orderShop, $orderStatus);
  95. $orderShop->addOrderStatusHistory($orderStatusHistory);
  96. }
  97. return $orderShop;
  98. }
  99. public function addOrderProduct(
  100. OrderShopInterface $orderShop,
  101. OrderProductInterface $orderProductAdd,
  102. bool $persist = true
  103. ) {
  104. $return = false;
  105. if ($this->orderProductStore->isOrderProductAvailableAddCart($orderProductAdd, $orderShop)) {
  106. if ($orderProductAdd->getQuantityOrder() > 0) {
  107. $updated = false;
  108. $this->orderProductBuilder->init($orderProductAdd);
  109. $productFamily = $this->productFamilyStore->getOneBySlug(
  110. $orderProductAdd->getProduct()->getProductFamily()->getSlug()
  111. );
  112. if ($productFamily) {
  113. $reductionCatalog = $productFamily->getReductionCatalog();
  114. if ($reductionCatalog) {
  115. $orderProductReductionCatalogFactory = new OrderProductReductionCatalogFactory();
  116. $orderProductReductionCatalog = $orderProductReductionCatalogFactory->create(
  117. $reductionCatalog->getTitle(),
  118. $reductionCatalog->getValue(),
  119. $reductionCatalog->getUnit(),
  120. $reductionCatalog->getBehaviorTaxRate()
  121. );
  122. $orderProductAdd->setOrderProductReductionCatalog($orderProductReductionCatalog);
  123. }
  124. }
  125. foreach ($orderShop->getOrderProducts() as $orderProduct) {
  126. if ($orderProduct->getProduct()->getId() == $orderProductAdd->getProduct()->getId()
  127. && $orderProduct->getRedelivery() == $orderProductAdd->getRedelivery()
  128. && (string)$this->priceResolver->getPrice($orderProduct)
  129. == (string)$this->priceResolver->getPrice($orderProductAdd)
  130. && $orderProduct->getOrderProductReductionCatalog()->compare(
  131. $orderProductAdd->getOrderProductReductionCatalog()
  132. )) {
  133. $orderProduct->setQuantityOrder(
  134. $orderProduct->getQuantityOrder() + $orderProductAdd->getQuantityOrder()
  135. );
  136. if ($persist) {
  137. $this->entityManager->persist($orderProduct);
  138. }
  139. $updated = true;
  140. $return = true;
  141. break;
  142. }
  143. }
  144. if (!$updated) {
  145. $orderShop->addOrderProduct($orderProductAdd);
  146. if ($persist) {
  147. if (isset($orderProductReductionCatalog)) {
  148. $this->entityManager->persist($orderProductReductionCatalog);
  149. }
  150. $this->entityManager->persist($orderProductAdd);
  151. $this->entityManager->persist($orderShop);
  152. }
  153. $return = true;
  154. }
  155. if ($persist) {
  156. $this->entityManager->flush();
  157. }
  158. // @TODO : dispatch event cart change
  159. //$this->eventCartChange($orderShop);
  160. }
  161. } else {
  162. // @TODO : retourner le message d'erreur et faire le addFlash dans le contrôleur
  163. /*$availableQuantity = $orderProductAdd->getProduct()->getAvailableQuantityInherited();
  164. $textError = "Le produit <strong>" . $orderProductAdd->getTitleOrderShop(
  165. ) . "</strong> n'est pas disponible";
  166. if ($availableQuantity !== false && $availableQuantity > 0) {
  167. $unit = '';
  168. if ($orderProductAdd->getProduct()->getProductFamily()->getBehaviorCountStock(
  169. ) == ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE) {
  170. $unit = $orderProductAdd->getProduct()->getUnitInherited()->getUnitReference()->getUnit();
  171. }
  172. $textError .= ' dans cette quantité ';
  173. $user = $this->security->getUser();
  174. if ($user && $user->hasRole('ROLE_USER')) {
  175. $textError .= '<br />' . $availableQuantity . $unit . ' disponible(s) dont ' . $this->getQuantityOrderByProduct(
  176. $orderShop,
  177. $orderProductAdd->getProduct()
  178. ) . $unit . ' déjà dans votre panier.';
  179. }
  180. }
  181. $this->utils->addFlash('error', $textError);*/
  182. }
  183. return $return;
  184. }
  185. public function merge(OrderShopInterface $orderShop1, OrderShopInterface $orderShop2, $persist = true)
  186. {
  187. if ($orderShop1 && $orderShop2) {
  188. foreach ($orderShop2->getOrderProducts() as $orderProduct) {
  189. $orderProductAlreadyInCart = $orderShop1->hasOrderProductAlreadyInCart($orderProduct);
  190. if ($orderProductAlreadyInCart) {
  191. if ($orderProduct->getQuantityOrder() > $orderProductAlreadyInCart->getQuantityOrder()) {
  192. $orderShop1->removeOrderProduct($orderProductAlreadyInCart);
  193. $this->addOrderProduct($orderShop1, $orderProduct);
  194. }
  195. } else {
  196. $this->addOrderProduct($orderShop1, $orderProduct);
  197. }
  198. if ($persist) {
  199. $this->entityManager->remove($orderProduct);
  200. }
  201. }
  202. if ($persist) {
  203. $this->entityManager->remove($orderShop2);
  204. $this->entityManager->persist($orderShop1);
  205. $this->entityManager->flush();
  206. }
  207. return $orderShop1;
  208. }
  209. }
  210. public function addPayment(OrderShopInterface $orderShop, $meanPayment, $amount)
  211. {
  212. $orderPaymentFactory = new OrderPaymentFactory();
  213. $orderPayment = $orderPaymentFactory->create($orderShop, $meanPayment, $amount);
  214. $orderShop->addOrderPayment($orderPayment);
  215. if ($this->isOrderPaid($orderShop)) {
  216. $nextStatus = OrderStatusModel::ALIAS_PAID;
  217. } else {
  218. $nextStatus = OrderStatusModel::ALIAS_PARTIAL_PAYMENT;
  219. }
  220. if ($orderShop->getOrderStatus()->getAlias() != $nextStatus) {
  221. $orderShop = $this->changeOrderStatus($orderShop, $nextStatus);
  222. }
  223. $this->entityManager->persist($orderPayment);
  224. $this->entityManager->update($orderShop);
  225. $this->entityManager->flush();
  226. return $orderShop;
  227. }
  228. public function createDocumentInvoice(OrderShopInterface $orderShop)
  229. {
  230. $documentFactory = new DocumentFactory();
  231. $document = $documentFactory->create(DocumentModel::TYPE_INVOICE);
  232. $this->documentBuilder->initFromOrderShop($orderShop);
  233. return $document;
  234. }
  235. public function addReductionCart(OrderShopInterface $orderShop, ReductionCartInterface $reductionCart)
  236. {
  237. $orderReductionCartFactory = new OrderReductionCartFactory();
  238. $orderReductionCart = $orderReductionCartFactory->create($orderShop, $reductionCart);
  239. $orderShop->addOrderReductionCart($orderReductionCart) ;
  240. if($this->orderShopStore->isPositiveAmount($orderShop)
  241. && $this->isPositiveAmountRemainingToBePaid($orderShop)) {
  242. $this->entityManager->persist($orderReductionCart);
  243. $this->entityManager->flush();
  244. return $orderReductionCart ;
  245. }
  246. else {
  247. $orderShop->removeOrderReductionCart($orderReductionCart) ;
  248. return false;
  249. }
  250. }
  251. // createOrderReductionCredit
  252. public function addReductionCredit(OrderShopInterface $orderShop, ReductionCreditInterface $reductionCredit)
  253. {
  254. $orderReductionCreditFactory = new OrderReductionCreditFactory();
  255. $orderReductionCredit = $orderReductionCreditFactory->create($orderShop, $reductionCredit);
  256. $orderShop->addOrderReductionCredit($orderReductionCredit) ;
  257. if($this->isOrderShopPositiveAmount($orderShop)
  258. && $this->isOrderShopPositiveAmountRemainingToBePaid($orderShop)) {
  259. $this->entityManager->persist($orderReductionCredit);
  260. $this->entityManager->flush();
  261. return $orderReductionCredit;
  262. }
  263. else {
  264. $orderShop->removeOrderReductionCredit($orderReductionCredit) ;
  265. return false;
  266. }
  267. }
  268. public function deductAvailabilityProduct(OrderShopInterface $orderShop)
  269. {
  270. // @TODO : à refactorer en plaçant dans src tout ce qui est spécifique à PDL
  271. foreach ($orderShop->getOrderProducts() as $orderProduct) {
  272. //Si ce n'esrt pas une relivraison OU si c'est une relivraison + relivraison + ce n'est pas une erruer producteur
  273. if (!$orderProduct->isRedelivery() || ($orderProduct->isRedelivery() && $orderProduct->isRedeliverySupplierOrder() && !$orderProduct->isRedeliverySupplierMistake())) {
  274. switch ($orderProduct->getProduct()->getProductFamily()->getBehaviorCountStock()) {
  275. case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE :
  276. //Disponibilité par unité de référence
  277. $oldAvailability = $orderProduct->getProduct()->getAvailableQuantityInherited();
  278. $newAvailability = $oldAvailability - ($orderProduct->getQuantityOrder() * ($orderProduct->getQuantityProduct() / $orderProduct->getUnit()->getCoefficient()));
  279. $productFamily = $orderProduct->getProduct()->getProductFamily();
  280. $productFamily->setAvailableQuantity($newAvailability);
  281. $productFamily->setUpdatedBy($orderShop->getUser());
  282. $this->entityManager->persist($productFamily);
  283. break;
  284. case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY :
  285. $oldAvailability = $orderProduct->getProduct()->getAvailableQuantityInherited();
  286. $newAvailability = $oldAvailability - $orderProduct->getQuantityOrder();
  287. $productFamily = $orderProduct->getProduct()->getProductFamily();
  288. $productFamily->setAvailableQuantity($newAvailability);
  289. $productFamily->setUpdatedBy($orderShop->getUser());
  290. $this->entityManager->persist($productFamily);
  291. break;
  292. case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT :
  293. $oldAvailability = $orderProduct->getProduct()->getAvailableQuantityInherited();
  294. $newAvailability = $oldAvailability - $orderProduct->getQuantityOrder();
  295. $product = $orderProduct->getProduct();
  296. $product->setAvailableQuantity($newAvailability);
  297. $product->setUpdatedBy($orderShop->getUser());
  298. $this->entityManager->persist($product);
  299. break;
  300. }
  301. $this->entityManager->flush();
  302. }
  303. }
  304. }
  305. }