選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

OrderShopBuilder.php 28KB

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