Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

690 lines
28KB

  1. <?php
  2. namespace Lc\CaracoleBundle\Builder\Order;
  3. use App\Builder\Distribution\DistributionBuilder;
  4. use Doctrine\ORM\EntityManagerInterface;
  5. use Lc\CaracoleBundle\Builder\Credit\CreditHistoryBuilder;
  6. use Lc\CaracoleBundle\Builder\File\DocumentBuilder;
  7. use Lc\CaracoleBundle\Event\Order\CartChangeEvent;
  8. use Lc\CaracoleBundle\Event\Order\OrderShopChangeStatusEvent;
  9. use Lc\CaracoleBundle\Factory\File\DocumentFactory;
  10. use Lc\CaracoleBundle\Factory\Order\OrderPaymentFactory;
  11. use Lc\CaracoleBundle\Factory\Order\OrderProductFactory;
  12. use Lc\CaracoleBundle\Factory\Order\OrderProductReductionCatalogFactory;
  13. use Lc\CaracoleBundle\Factory\Order\OrderReductionCartFactory;
  14. use Lc\CaracoleBundle\Factory\Order\OrderReductionCreditFactory;
  15. use Lc\CaracoleBundle\Factory\Order\OrderShopFactory;
  16. use Lc\CaracoleBundle\Factory\Order\OrderStatusHistoryFactory;
  17. use Lc\CaracoleBundle\Model\Address\AddressInterface;
  18. use Lc\CaracoleBundle\Model\Credit\CreditHistoryModel;
  19. use Lc\CaracoleBundle\Model\File\DocumentInterface;
  20. use Lc\CaracoleBundle\Model\File\DocumentModel;
  21. use Lc\CaracoleBundle\Model\Order\OrderPaymentModel;
  22. use Lc\CaracoleBundle\Model\Order\OrderProductInterface;
  23. use Lc\CaracoleBundle\Model\Order\OrderReductionCartInterface;
  24. use Lc\CaracoleBundle\Model\Order\OrderReductionCreditInterface;
  25. use Lc\CaracoleBundle\Model\Order\OrderShopInterface;
  26. use Lc\CaracoleBundle\Model\Order\OrderStatusInterface;
  27. use Lc\CaracoleBundle\Model\Order\OrderStatusModel;
  28. use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface;
  29. use Lc\CaracoleBundle\Model\Product\ProductFamilyModel;
  30. use Lc\CaracoleBundle\Model\Product\ProductInterface;
  31. use Lc\CaracoleBundle\Model\Reduction\ReductionCartInterface;
  32. use Lc\CaracoleBundle\Model\Reduction\ReductionCreditInterface;
  33. use Lc\CaracoleBundle\Model\Section\SectionInterface;
  34. use Lc\CaracoleBundle\Model\User\VisitorInterface;
  35. use Lc\CaracoleBundle\Repository\Order\OrderProductStore;
  36. use Lc\CaracoleBundle\Repository\Order\OrderShopStore;
  37. use Lc\CaracoleBundle\Repository\Order\OrderStatusStore;
  38. use Lc\CaracoleBundle\Repository\Product\ProductFamilyStore;
  39. use Lc\CaracoleBundle\Resolver\MerchantResolver;
  40. use Lc\CaracoleBundle\Resolver\OrderShopResolver;
  41. use Lc\CaracoleBundle\Solver\Order\OrderProductReductionCatalogSolver;
  42. use Lc\CaracoleBundle\Solver\Order\OrderProductSolver;
  43. use Lc\CaracoleBundle\Solver\Order\OrderShopSolver;
  44. use Lc\CaracoleBundle\Solver\Price\PriceSolver;
  45. use Lc\CaracoleBundle\Solver\Product\ProductSolver;
  46. use Lc\CaracoleBundle\Statistic\Product\ProductsSalesStatistic;
  47. use Lc\SovBundle\Model\User\UserInterface;
  48. use Lc\SovBundle\Translation\FlashBagTranslator;
  49. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  50. use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
  51. class OrderShopBuilder
  52. {
  53. protected EntityManagerInterface $entityManager;
  54. protected OrderStatusStore $orderStatusStore;
  55. protected OrderProductStore $orderProductStore;
  56. protected OrderShopStore $orderShopStore;
  57. protected OrderShopSolver $orderShopSolver;
  58. protected ProductFamilyStore $productFamilyStore;
  59. protected PriceSolver $priceSolver;
  60. protected OrderProductBuilder $orderProductBuilder;
  61. protected DocumentBuilder $documentBuilder;
  62. protected EventDispatcherInterface $eventDispatcher;
  63. protected FlashBagTranslator $flashBag;
  64. protected ProductSolver $productSolver;
  65. protected OrderShopResolver $orderShopResolver;
  66. protected OrderProductReductionCatalogSolver $orderProductReductionCatalogSolver;
  67. protected DistributionBuilder $distributionBuilder;
  68. protected MerchantResolver $merchantResolver;
  69. protected CreditHistoryBuilder $creditHistoryBuilder;
  70. protected OrderShopFactory $orderShopFactory;
  71. protected OrderProductSolver $orderProductSolver;
  72. public function __construct(
  73. EntityManagerInterface $entityManager,
  74. OrderShopStore $orderShopStore,
  75. OrderShopSolver $orderShopSolver,
  76. OrderStatusStore $orderStatusStore,
  77. OrderProductStore $orderProductStore,
  78. ProductFamilyStore $productFamilyStore,
  79. OrderProductBuilder $orderProductBuilder,
  80. DocumentBuilder $documentBuilder,
  81. PriceSolver $priceSolver,
  82. EventDispatcherInterface $eventDispatcher,
  83. FlashBagTranslator $flashBag,
  84. ProductSolver $productSolver,
  85. OrderShopResolver $orderShopResolver,
  86. OrderProductReductionCatalogSolver $orderProductReductionCatalogSolver,
  87. DistributionBuilder $distributionBuilder,
  88. MerchantResolver $merchantResolver,
  89. CreditHistoryBuilder $creditHistoryBuilder,
  90. OrderShopFactory $orderShopFactory,
  91. OrderProductSolver $orderProductSolver
  92. ) {
  93. $this->entityManager = $entityManager;
  94. $this->orderShopStore = $orderShopStore;
  95. $this->orderShopSolver = $orderShopSolver;
  96. $this->orderStatusStore = $orderStatusStore;
  97. $this->orderProductStore = $orderProductStore;
  98. $this->productFamilyStore = $productFamilyStore;
  99. $this->orderProductBuilder = $orderProductBuilder;
  100. $this->documentBuilder = $documentBuilder;
  101. $this->priceSolver = $priceSolver;
  102. $this->eventDispatcher = $eventDispatcher;
  103. $this->flashBag = $flashBag;
  104. $this->productSolver = $productSolver;
  105. $this->orderShopResolver = $orderShopResolver;
  106. $this->orderProductReductionCatalogSolver = $orderProductReductionCatalogSolver;
  107. $this->distributionBuilder = $distributionBuilder;
  108. $this->merchantResolver = $merchantResolver;
  109. $this->creditHistoryBuilder = $creditHistoryBuilder;
  110. $this->orderShopFactory = $orderShopFactory;
  111. $this->orderProductSolver = $orderProductSolver;
  112. }
  113. public function create(
  114. SectionInterface $section,
  115. UserInterface $user = null,
  116. VisitorInterface $visitor = null
  117. ): OrderShopInterface {
  118. $orderShop = $this->orderShopFactory->create($section, $user, $visitor);
  119. $this->setOrderStatus($orderShop, OrderStatusModel::ALIAS_CART);
  120. $this->entityManager->create($orderShop);
  121. $this->entityManager->flush();
  122. return $orderShop;
  123. }
  124. protected array $cacheCartCurrentBySection = [];
  125. public function createIfNotExist(
  126. SectionInterface $section,
  127. UserInterface $user = null,
  128. VisitorInterface $visitor = null,
  129. bool $cache = false
  130. ): OrderShopInterface {
  131. $cart = null;
  132. // cache
  133. $cacheIdCartCurrent = 'cart_current_' . $section->getId();
  134. if ($cache
  135. && isset($this->cacheCartCurrentBySection[$cacheIdCartCurrent])
  136. && $this->cacheCartCurrentBySection[$cacheIdCartCurrent]) {
  137. return $this->cacheCartCurrentBySection[$cacheIdCartCurrent];
  138. }
  139. $this->orderShopStore->setSection($section);
  140. $cartUser = $this->orderShopStore->getOneCartCurrent($user);
  141. $cartVisitor = $this->orderShopStore->getOneCartCurrent(null, $visitor);
  142. if ($cartUser && $cartVisitor && $cartUser->getId() != $cartVisitor->getId()) {
  143. $cart = $this->merge($cartUser, $cartVisitor);
  144. } else {
  145. if ($cartUser) {
  146. $cart = $cartUser;
  147. } elseif ($cartVisitor) {
  148. if ($user && $cartVisitor && !$cartVisitor->getUser()) {
  149. $cartVisitor->setUser($user);
  150. $this->entityManager->update($cartVisitor);
  151. $this->entityManager->flush();
  152. }
  153. $cart = $cartVisitor;
  154. }
  155. }
  156. if (!$cart) {
  157. $cart = $this->create($section, $user, $visitor);
  158. }
  159. // @TODO : obligé de faire ça sinon le panier ne se met pas à jour quand on ajoute des produits. Pourquoi ?
  160. $this->entityManager->refresh($cart);
  161. // cache
  162. $this->cacheCartCurrentBySection[$cacheIdCartCurrent] = $cart;
  163. return $cart;
  164. }
  165. public function setOrderStatus(
  166. OrderShopInterface $orderShop,
  167. string $alias,
  168. bool $forceByAdmin = false
  169. ): OrderShopInterface {
  170. $orderStatus = $this->orderStatusStore->getOneByAlias($alias);
  171. if ($orderStatus) {
  172. if ($orderShop->getOrderStatus() === null
  173. || $orderShop->getOrderStatus()->getNextStatusAllowed()->contains($orderStatus)) {
  174. $this->applyChangeOrderStatus($orderShop, $orderStatus, $forceByAdmin);
  175. }
  176. } else {
  177. throw new \ErrorException('La statut demandé n\'existe pas.');
  178. }
  179. return $orderShop;
  180. }
  181. public function applyChangeOrderStatus(
  182. OrderShopInterface $orderShop,
  183. OrderStatusInterface $orderStatus,
  184. bool $forceByAdmin = false
  185. ): void {
  186. $this->eventDispatcher->dispatch(
  187. new OrderShopChangeStatusEvent($orderShop, $orderStatus, $forceByAdmin),
  188. OrderShopChangeStatusEvent::PRE_CHANGE_STATUS
  189. );
  190. $orderShop->setOrderStatusProtected($orderStatus);
  191. $orderStatusHistoryFactory = new OrderStatusHistoryFactory();
  192. $orderStatusHistory = $orderStatusHistoryFactory->create($orderShop, $orderStatus);
  193. $orderShop->addOrderStatusHistory($orderStatusHistory);
  194. $this->eventDispatcher->dispatch(
  195. new OrderShopChangeStatusEvent($orderShop, $orderStatus, $forceByAdmin),
  196. OrderShopChangeStatusEvent::POST_CHANGE_STATUS
  197. );
  198. }
  199. public function addOrderProduct(
  200. OrderShopInterface $orderShop,
  201. OrderProductInterface $orderProductAdd,
  202. bool $persist = true
  203. ): ?array {
  204. $orderProductAddedArray = [];
  205. $orderProductAdd->setOrderShop($orderShop);
  206. if ($this->orderShopSolver->isOrderProductAvailableAddCart($orderProductAdd, $orderShop)) {
  207. if ($orderProductAdd->getQuantityOrder() > 0) {
  208. $orderProductAddedArray[] = $orderProductAdd;
  209. $updated = false;
  210. $this->orderProductBuilder->init($orderProductAdd);
  211. if(is_null($orderProductAdd->getOrderProductReductionCatalog())) {
  212. // on hydrate $productFamily avec réduction
  213. $productFamily = $this->productFamilyStore->setSection($orderShop->getSection())->getOneBySlug(
  214. $orderProductAdd->getProduct()->getProductFamily()->getSlug()
  215. );
  216. if($productFamily) {
  217. $this->orderProductBuilder->initReductionCatalog($orderShop->getSection(), $orderProductAdd, $productFamily);
  218. }
  219. }
  220. foreach ($orderShop->getOrderProducts() as $orderProduct) {
  221. if ($this->orderProductSolver->compare($orderProduct, $orderProductAdd)) {
  222. $orderProduct->setQuantityOrder(
  223. $orderProduct->getQuantityOrder() + $orderProductAdd->getQuantityOrder()
  224. );
  225. if ($persist) {
  226. $this->entityManager->update($orderProduct);
  227. }
  228. $updated = true;
  229. break;
  230. }
  231. }
  232. if (!$updated) {
  233. $orderShop->addOrderProduct($orderProductAdd);
  234. if ($persist) {
  235. if (isset($orderProductReductionCatalog)) {
  236. $this->entityManager->create($orderProductReductionCatalog);
  237. }
  238. // @TODO : update ou create ?
  239. $this->entityManager->persist($orderProductAdd);
  240. $this->entityManager->update($orderShop);
  241. }
  242. }
  243. if ($persist) {
  244. $this->entityManager->flush();
  245. $this->eventDispatcher->dispatch(new CartChangeEvent($orderShop), CartChangeEvent::POST_UPDATE);
  246. }
  247. }
  248. } else {
  249. // @TODO : retourner le message d'erreur et faire le addFlash dans le contrôleur
  250. /*$availableQuantity = $orderProductAdd->getProduct()->getAvailableQuantityInherited();
  251. $textError = "Le produit <strong>" . $orderProductAdd->getTitleOrderShop(
  252. ) . "</strong> n'est pas disponible";
  253. if ($availableQuantity !== false && $availableQuantity > 0) {
  254. $unit = '';
  255. if ($orderProductAdd->getProduct()->getProductFamily()->getBehaviorCountStock(
  256. ) == ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE) {
  257. $unit = $orderProductAdd->getProduct()->getUnitInherited()->getUnitReference()->getUnit();
  258. }
  259. $textError .= ' dans cette quantité ';
  260. $user = $this->security->getUser();
  261. if ($user && $user->hasRole('ROLE_USER')) {
  262. $textError .= '<br />' . $availableQuantity . $unit . ' disponible(s) dont ' . $this->getQuantityOrderByProduct(
  263. $orderShop,
  264. $orderProductAdd->getProduct()
  265. ) . $unit . ' déjà dans votre panier.';
  266. }
  267. }
  268. $this->utils->addFlash('error', $textError);*/
  269. }
  270. if(count($orderProductAddedArray) == 0) {
  271. return null;
  272. }
  273. return $orderProductAddedArray;
  274. }
  275. public function merge(
  276. OrderShopInterface $orderShop1,
  277. OrderShopInterface $orderShop2,
  278. $persist = true
  279. ): OrderShopInterface {
  280. // @TODO : intégrer la gestion des OrderPackProduct dans cette méthode
  281. // TODO essayer de comprendre pourquoi on doit faire un refresh ici
  282. $this->entityManager->refresh($orderShop1);
  283. $this->entityManager->refresh($orderShop2);
  284. foreach ($orderShop2->getOrderProducts() as $orderProduct) {
  285. $orderProductAlreadyInCart = $this->orderShopSolver->hasOrderProductAlreadyInCart(
  286. $orderShop1,
  287. $orderProduct
  288. );
  289. if ($orderProductAlreadyInCart) {
  290. if ($orderProduct->getQuantityOrder() > $orderProductAlreadyInCart->getQuantityOrder()) {
  291. $orderShop1->removeOrderProduct($orderProductAlreadyInCart);
  292. $this->addOrderProduct($orderShop1, $orderProduct);
  293. }
  294. } else {
  295. $this->addOrderProduct($orderShop1, $orderProduct);
  296. }
  297. if ($persist) {
  298. $this->entityManager->delete($orderProduct);
  299. }
  300. }
  301. if ($persist) {
  302. $this->entityManager->delete($orderShop2);
  303. $this->entityManager->update($orderShop1);
  304. $this->entityManager->flush();
  305. }
  306. return $orderShop1;
  307. }
  308. public function addPayment(OrderShopInterface $orderShop, string $meanPayment, float $amount, bool $editable = false): OrderShopInterface
  309. {
  310. $orderPaymentFactory = new OrderPaymentFactory();
  311. $orderPayment = $orderPaymentFactory->create($orderShop, $meanPayment, $amount, $editable);
  312. $orderShop->addOrderPayment($orderPayment);
  313. if ($meanPayment == OrderPaymentModel::MEAN_PAYMENT_CREDIT) {
  314. $this->creditHistoryBuilder->create(
  315. CreditHistoryModel::TYPE_DEBIT,
  316. $this->merchantResolver->getUserMerchant(),
  317. [
  318. 'orderPayment' => $orderPayment
  319. ]
  320. );
  321. }
  322. if ($this->orderShopResolver->isPaid($orderShop)) {
  323. $nextStatus = OrderStatusModel::ALIAS_PAID;
  324. } else {
  325. $nextStatus = OrderStatusModel::ALIAS_PARTIAL_PAYMENT;
  326. }
  327. if ($orderShop->getOrderStatus()->getAlias() != $nextStatus) {
  328. $this->changeOrderStatus($orderShop, $nextStatus);
  329. }
  330. $this->entityManager->create($orderPayment);
  331. $this->entityManager->update($orderShop);
  332. $this->entityManager->flush();
  333. return $orderShop;
  334. }
  335. public function initStatsInfo(OrderShopInterface $orderShop, $flush = true)
  336. {
  337. $orderShop->setStatTotal($this->priceSolver->getTotal($orderShop));
  338. $orderShop->setStatTotalWithTax($this->priceSolver->getTotalWithTax($orderShop));
  339. $orderShop->setStatTotalOrderProductsWithReductions(
  340. $this->priceSolver->getTotalOrderProductsWithReductions($orderShop)
  341. );
  342. $orderShop->setStatTotalOrderProductsWithTaxAndReductions(
  343. $this->priceSolver->getTotalOrderProductsWithTaxAndReductions($orderShop)
  344. );
  345. $orderShop->setStatMarginOrderProductsWithReductions(
  346. $this->priceSolver->getMarginOrderProductsWithReductions($orderShop)
  347. );
  348. $orderShop->setStatDeliveryPriceWithReduction($this->priceSolver->getDeliveryPriceWithReduction($orderShop));
  349. $orderShop->setStatDeliveryPriceWithTaxAndReduction(
  350. $this->priceSolver->getDeliveryPriceWithTaxAndReduction($orderShop)
  351. );
  352. $this->entityManager->persist($orderShop);
  353. if ($flush) {
  354. $this->entityManager->flush();
  355. }
  356. }
  357. //initCycleNumber
  358. public function initDistribution(OrderShopInterface $orderShop): void
  359. {
  360. $distribution = $this->distributionBuilder->guessDistributionByDeliveryDate(
  361. $orderShop->getDeliveryDate(),
  362. $orderShop->getSection()
  363. );
  364. $orderShop->setDistribution($distribution);
  365. }
  366. public function createDocumentInvoice(OrderShopInterface $orderShop): DocumentInterface
  367. {
  368. $documentFactory = new DocumentFactory();
  369. $document = $documentFactory->create($orderShop->getSection()->getMerchant(), DocumentModel::TYPE_INVOICE);
  370. $this->documentBuilder->initFromOrderShop($document, $orderShop);
  371. return $document;
  372. }
  373. public function addReductionCart(
  374. OrderShopInterface $orderShop,
  375. ReductionCartInterface $reductionCart
  376. ): ?OrderReductionCartInterface {
  377. $orderReductionCartFactory = new OrderReductionCartFactory();
  378. $orderReductionCart = $orderReductionCartFactory->create($orderShop, $reductionCart);
  379. $orderShop->addOrderReductionCart($orderReductionCart);
  380. if ($this->orderShopResolver->isPositiveAmount($orderShop)
  381. && $this->orderShopResolver->isPositiveAmountRemainingToBePaid($orderShop)) {
  382. $this->entityManager->create($orderReductionCart);
  383. $this->entityManager->flush();
  384. return $orderReductionCart;
  385. } else {
  386. //TODO vérifier ce case ! Avec le null en valeur de retour
  387. $orderShop->removeOrderReductionCart($orderReductionCart);
  388. return null;
  389. }
  390. }
  391. // createOrderReductionCredit
  392. public function addReductionCredit(
  393. OrderShopInterface $orderShop,
  394. ReductionCreditInterface $reductionCredit
  395. ): ?OrderReductionCreditInterface {
  396. $orderReductionCreditFactory = new OrderReductionCreditFactory();
  397. $orderReductionCredit = $orderReductionCreditFactory->create($orderShop, $reductionCredit);
  398. $orderShop->addOrderReductionCredit($orderReductionCredit);
  399. if ($this->orderShopResolver->isPositiveAmount($orderShop)
  400. && $this->orderShopResolver->isPositiveAmountRemainingToBePaid($orderShop)) {
  401. $this->entityManager->create($orderReductionCredit);
  402. $this->entityManager->flush();
  403. return $orderReductionCredit;
  404. } else {
  405. $orderShop->removeOrderReductionCredit($orderReductionCredit);
  406. return null;
  407. }
  408. }
  409. public function deductAvailabilityProduct(OrderShopInterface $orderShop): void
  410. {
  411. foreach ($orderShop->getOrderProducts() as $orderProduct) {
  412. $this->applyDeductAvailabilityProduct($orderShop, $orderProduct->getProduct(), $orderProduct->getQuantityOrder());
  413. }
  414. }
  415. public function applyDeductAvailabilityProduct(
  416. OrderShopInterface $orderShop,
  417. ProductInterface $product,
  418. float $quantityOrder,
  419. float $quantityProduct = null
  420. ): void {
  421. switch ($product->getProductFamily()->getBehaviorCountStock()) {
  422. case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE :
  423. //Disponibilité par unité de référence
  424. $oldAvailability = $this->productSolver->getAvailableQuantityInherited($product);
  425. $newAvailability = $oldAvailability - ($quantityOrder * ($this->productSolver->getQuantityInherited(
  426. $product
  427. ) / $this->productSolver->getUnitInherited($product)->getCoefficient()));
  428. $productFamily = $product->getProductFamily();
  429. $productFamily->setAvailableQuantity($newAvailability);
  430. $productFamily->setUpdatedBy($orderShop->getUser());
  431. $this->entityManager->update($productFamily);
  432. break;
  433. case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY :
  434. $oldAvailability = $this->productSolver->getAvailableQuantityInherited($product);
  435. $newAvailability = $oldAvailability - $quantityOrder;
  436. $productFamily = $product->getProductFamily();
  437. $productFamily->setAvailableQuantity($newAvailability);
  438. $productFamily->setUpdatedBy($orderShop->getUser());
  439. $this->entityManager->update($productFamily);
  440. break;
  441. case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT :
  442. $oldAvailability = $this->productSolver->getAvailableQuantityInherited($product);
  443. $newAvailability = $oldAvailability - $quantityOrder;
  444. $product->setAvailableQuantity($newAvailability);
  445. $product->setUpdatedBy($orderShop->getUser());
  446. $this->entityManager->update($product);
  447. break;
  448. }
  449. $this->entityManager->flush();
  450. }
  451. public function updatePriceByProductFamily(ProductFamilyInterface $productFamily, SectionInterface $section)
  452. {
  453. $countOrderProductUpdated = 0;
  454. foreach ($productFamily->getProducts() as $product) {
  455. $orderProducts = $this->orderProductStore->resetContext()->setSection(
  456. $section
  457. )->getInCartsByProduct($product);
  458. foreach ($orderProducts as $orderProduct) {
  459. $quantityOrder = $orderProduct->getQuantityOrder();
  460. $orderShop = $orderProduct->getOrderShop();
  461. $orderShop->removeOrderProduct($orderProduct);
  462. $this->entityManager->delete($orderProduct);
  463. $this->entityManager->flush();
  464. $this->entityManager->refresh($orderShop);
  465. $orderProductFactory = new OrderProductFactory();
  466. $addOrderProduct = $orderProductFactory->create($product, $quantityOrder);
  467. $this->addOrderProduct($orderShop, $addOrderProduct);
  468. $countOrderProductUpdated++;
  469. }
  470. }
  471. if ($countOrderProductUpdated) {
  472. $this->entityManager->flush();
  473. }
  474. return $countOrderProductUpdated;
  475. }
  476. public function setStatsInfo(OrderShopInterface $orderShop, $flush = true)
  477. {
  478. $orderShop->setStatTotal($this->priceSolver->getTotal($orderShop));
  479. $orderShop->setStatTotalWithTax($this->priceSolver->getTotalWithTax($orderShop));
  480. $orderShop->setStatTotalOrderProductsWithReductions(
  481. $this->priceSolver->getTotalOrderProductsWithReductions($orderShop)
  482. );
  483. $orderShop->setStatTotalOrderProductsWithTaxAndReductions(
  484. $this->priceSolver->getTotalOrderProductsWithTaxAndReductions($orderShop)
  485. );
  486. $orderShop->setStatMarginOrderProductsWithReductions(
  487. $this->priceSolver->getMarginOrderProductsWithReductions($orderShop)
  488. );
  489. $orderShop->setStatDeliveryPriceWithReduction($this->priceSolver->getDeliveryPriceWithReduction($orderShop));
  490. $orderShop->setStatDeliveryPriceWithTaxAndReduction(
  491. $this->priceSolver->getDeliveryPriceWithTaxAndReduction($orderShop)
  492. );
  493. $this->entityManager->update($orderShop);
  494. if ($flush) {
  495. $this->entityManager->flush();
  496. }
  497. }
  498. public function setHasReach(int $reachStep, OrderShopInterface $orderShop)
  499. {
  500. if ($orderShop->getHasReach() === null || $orderShop->getHasReach() < $reachStep) {
  501. $orderShop->setHasReach($reachStep);
  502. $this->entityManager->persist($orderShop);
  503. $this->entityManager->flush($orderShop);
  504. }
  505. }
  506. public function initComplementaryOrderShop(OrderShopInterface $orderShop, OrderShopInterface $mainOrderShop): void
  507. {
  508. $orderShop->setMainOrderShop($mainOrderShop);
  509. $orderShop->setDeliveryPrice(0);
  510. if ($mainOrderShop->getDeliveryAddress()) {
  511. $this->initDeliveryAddress($orderShop, $mainOrderShop->getDeliveryAddress());
  512. }
  513. $orderShop->setInvoiceAddress($mainOrderShop->getInvoiceAddress());
  514. }
  515. // setDeliveryAddress
  516. public function initDeliveryAddress(OrderShopInterface $orderShop, AddressInterface $address = null): void
  517. {
  518. $orderShop->setDeliveryAddress($address);
  519. $orderShop->setDeliveryInfos($address ? $address->getDeliveryInfos() : null);
  520. }
  521. // resetOrderShopInfos
  522. public function reset(OrderShopInterface $orderShop)
  523. {
  524. $this->initDeliveryAddress($orderShop, null);
  525. $orderShop->setMainOrderShop(null);
  526. $orderShop->setDeliveryPrice(null);
  527. $orderShop->setInvoiceAddress(null);
  528. $orderShop->setDeclineComplementaryOrderShop(false);
  529. }
  530. public function getProductsSalesStatistic(SectionInterface $section, $entity, $nbWeek = 2)
  531. {
  532. $productsSalesStatistic = new ProductsSalesStatistic(
  533. $this->entityManager,
  534. $entity,
  535. $nbWeek,
  536. $this->productSolver
  537. );
  538. $productsSalesStatistic->init($section, $this->distributionBuilder);
  539. $productsSalesStatistic->populateProperties($this->orderShopStore->resetContext()->setSection($section));
  540. return $productsSalesStatistic->getAsArray();
  541. }
  542. public function delete(OrderShopInterface $orderShop)
  543. {
  544. // delete OrderProduct
  545. foreach($orderShop->getOrderProducts() as $orderProduct) {
  546. $this->entityManager->delete($orderProduct);
  547. }
  548. // delete OrderPackProduct
  549. foreach($orderShop->getOrderPackProducts() as $orderPackProduct) {
  550. $this->entityManager->delete($orderPackProduct);
  551. }
  552. // delete OrderPayment
  553. foreach($orderShop->getOrderPayments() as $orderPayment) {
  554. $this->entityManager->delete($orderPayment);
  555. }
  556. // delete OrderReductionCarts
  557. foreach($orderShop->getOrderReductionCarts() as $orderReductionCart) {
  558. $this->entityManager->delete($orderReductionCart);
  559. }
  560. // delete OrderReductionCredits
  561. foreach($orderShop->getOrderReductionCredits() as $orderReductionCredit) {
  562. $this->entityManager->delete($orderReductionCredit);
  563. }
  564. // delete OrderStatusHistory
  565. foreach($orderShop->getOrderStatusHistories() as $orderStatusHistory) {
  566. $this->entityManager->delete($orderStatusHistory);
  567. }
  568. // delete OrderShop
  569. $this->entityManager->delete($orderShop);
  570. $this->entityManager->flush();
  571. }
  572. }