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

OrderShopBuilder.php 28KB

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