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.

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