Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

OrderShopBuilder.php 27KB

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 лет назад
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 лет назад
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 лет назад
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 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  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. 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. ) {
  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->openingResolver = $openingResolver;
  106. $this->productSolver = $productSolver;
  107. $this->orderShopResolver = $orderShopResolver;
  108. $this->orderProductReductionCatalogSolver = $orderProductReductionCatalogSolver;
  109. $this->distributionBuilder = $distributionBuilder;
  110. $this->merchantResolver = $merchantResolver;
  111. $this->creditHistoryBuilder = $creditHistoryBuilder;
  112. }
  113. public function create(
  114. SectionInterface $section,
  115. UserInterface $user = null,
  116. VisitorInterface $visitor = null
  117. ): OrderShopInterface {
  118. $orderShopFactory = new OrderShopFactory();
  119. $orderShop = $orderShopFactory->create($section, $user, $visitor);
  120. $this->setOrderStatus($orderShop, OrderStatusModel::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 && isset($this->cacheCartCurrentBySection[$cacheIdCartCurrent])) {
  136. return $this->cacheCartCurrentBySection[$cacheIdCartCurrent];
  137. }
  138. $this->orderShopStore->setSection($section);
  139. $cartUser = $this->orderShopStore->getOneCartCurrent($user);
  140. $cartVisitor = $this->orderShopStore->getOneCartCurrent(null, $visitor);
  141. if ($cartUser && $cartVisitor && $cartUser->getId() != $cartVisitor->getId()) {
  142. $cart = $this->merge($cartUser, $cartVisitor);
  143. } else {
  144. if($cartUser) {
  145. $cart = $cartUser;
  146. }
  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. ): bool {
  204. $return = false;
  205. if ($this->orderShopSolver->isOrderProductAvailableAddCart($orderProductAdd, $orderShop)) {
  206. if ($orderProductAdd->getQuantityOrder() > 0) {
  207. $updated = false;
  208. $this->orderProductBuilder->init($orderProductAdd);
  209. $productFamily = $this->productFamilyStore->getOneBySlug(
  210. $orderProductAdd->getProduct()->getProductFamily()->getSlug()
  211. );
  212. if ($productFamily) {
  213. $reductionCatalog = $productFamily->getReductionCatalog();
  214. if ($reductionCatalog) {
  215. $orderProductReductionCatalogFactory = new OrderProductReductionCatalogFactory();
  216. $orderProductReductionCatalog = $orderProductReductionCatalogFactory->create(
  217. $reductionCatalog->getTitle(),
  218. $reductionCatalog->getValue(),
  219. $reductionCatalog->getUnit(),
  220. $reductionCatalog->getBehaviorTaxRate()
  221. );
  222. $orderProductAdd->setOrderProductReductionCatalog($orderProductReductionCatalog);
  223. }
  224. }
  225. foreach ($orderShop->getOrderProducts() as $orderProduct) {
  226. if ($orderProduct->getProduct()->getId() == $orderProductAdd->getProduct()->getId()
  227. && $orderProduct->getRedelivery() == $orderProductAdd->getRedelivery()
  228. && (string)$this->priceSolver->getPrice($orderProduct)
  229. == (string)$this->priceSolver->getPrice($orderProductAdd)
  230. && $this->orderProductReductionCatalogSolver->compare(
  231. $orderProduct->getOrderProductReductionCatalog(),
  232. $orderProductAdd->getOrderProductReductionCatalog()
  233. )) {
  234. $orderProduct->setQuantityOrder(
  235. $orderProduct->getQuantityOrder() + $orderProductAdd->getQuantityOrder()
  236. );
  237. if ($persist) {
  238. $this->entityManager->update($orderProduct);
  239. }
  240. $updated = true;
  241. $return = true;
  242. break;
  243. }
  244. }
  245. if (!$updated) {
  246. $orderShop->addOrderProduct($orderProductAdd);
  247. if ($persist) {
  248. if (isset($orderProductReductionCatalog)) {
  249. $this->entityManager->create($orderProductReductionCatalog);
  250. }
  251. //TODO est-ce un update ou un create ???
  252. $this->entityManager->persist($orderProductAdd);
  253. $this->entityManager->update($orderShop);
  254. }
  255. $return = true;
  256. }
  257. if ($persist) {
  258. $this->entityManager->flush();
  259. }
  260. // @TODO : dispatch event cart change
  261. //$this->eventCartChange($orderShop);
  262. }
  263. } else {
  264. // @TODO : retourner le message d'erreur et faire le addFlash dans le contrôleur
  265. /*$availableQuantity = $orderProductAdd->getProduct()->getAvailableQuantityInherited();
  266. $textError = "Le produit <strong>" . $orderProductAdd->getTitleOrderShop(
  267. ) . "</strong> n'est pas disponible";
  268. if ($availableQuantity !== false && $availableQuantity > 0) {
  269. $unit = '';
  270. if ($orderProductAdd->getProduct()->getProductFamily()->getBehaviorCountStock(
  271. ) == ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE) {
  272. $unit = $orderProductAdd->getProduct()->getUnitInherited()->getUnitReference()->getUnit();
  273. }
  274. $textError .= ' dans cette quantité ';
  275. $user = $this->security->getUser();
  276. if ($user && $user->hasRole('ROLE_USER')) {
  277. $textError .= '<br />' . $availableQuantity . $unit . ' disponible(s) dont ' . $this->getQuantityOrderByProduct(
  278. $orderShop,
  279. $orderProductAdd->getProduct()
  280. ) . $unit . ' déjà dans votre panier.';
  281. }
  282. }
  283. $this->utils->addFlash('error', $textError);*/
  284. }
  285. return $return;
  286. }
  287. public function merge(
  288. OrderShopInterface $orderShop1,
  289. OrderShopInterface $orderShop2,
  290. $persist = true
  291. ): OrderShopInterface {
  292. if ($orderShop1 && $orderShop2) {
  293. foreach ($orderShop2->getOrderProducts() as $orderProduct) {
  294. $orderProductAlreadyInCart = $this->orderShopSolver->hasOrderProductAlreadyInCart($orderShop1, $orderProduct);
  295. if ($orderProductAlreadyInCart) {
  296. if ($orderProduct->getQuantityOrder() > $orderProductAlreadyInCart->getQuantityOrder()) {
  297. $orderShop1->removeOrderProduct($orderProductAlreadyInCart);
  298. $this->addOrderProduct($orderShop1, $orderProduct);
  299. }
  300. } else {
  301. $this->addOrderProduct($orderShop1, $orderProduct);
  302. }
  303. if ($persist) {
  304. $this->entityManager->delete($orderProduct);
  305. }
  306. }
  307. if ($persist) {
  308. $this->entityManager->delete($orderShop2);
  309. $this->entityManager->update($orderShop1);
  310. $this->entityManager->flush();
  311. }
  312. return $orderShop1;
  313. }
  314. }
  315. public function addPayment(OrderShopInterface $orderShop, string $meanPayment, float $amount): OrderShopInterface
  316. {
  317. $orderPaymentFactory = new OrderPaymentFactory();
  318. $orderPayment = $orderPaymentFactory->create($orderShop, $meanPayment, $amount);
  319. $orderShop->addOrderPayment($orderPayment);
  320. if($meanPayment == OrderPaymentModel::MEAN_PAYMENT_CREDIT) {
  321. $this->creditHistoryBuilder->create(CreditHistoryModel::TYPE_DEBIT, $this->merchantResolver->getUserMerchant(), [
  322. 'orderPayment' => $orderPayment
  323. ]);
  324. }
  325. if ($this->orderShopResolver->isPaid($orderShop)) {
  326. $nextStatus = OrderStatusModel::ALIAS_PAID;
  327. } else {
  328. $nextStatus = OrderStatusModel::ALIAS_PARTIAL_PAYMENT;
  329. }
  330. if ($orderShop->getOrderStatus()->getAlias() != $nextStatus) {
  331. $this->changeOrderStatus($orderShop, $nextStatus);
  332. }
  333. $this->entityManager->create($orderPayment);
  334. $this->entityManager->update($orderShop);
  335. $this->entityManager->flush();
  336. return $orderShop;
  337. }
  338. public function initStatsInfo(OrderShopInterface $orderShop, $flush = true)
  339. {
  340. $orderShop->setStatTotal($this->priceSolver->getTotal($orderShop));
  341. $orderShop->setStatTotalWithTax($this->priceSolver->getTotalWithTax($orderShop));
  342. $orderShop->setStatTotalOrderProductsWithReductions(
  343. $this->priceSolver->getTotalOrderProductsWithReductions($orderShop)
  344. );
  345. $orderShop->setStatTotalOrderProductsWithTaxAndReductions(
  346. $this->priceSolver->getTotalOrderProductsWithTaxAndReductions($orderShop)
  347. );
  348. $orderShop->setStatMarginOrderProductsWithReductions(
  349. $this->priceSolver->getMarginOrderProductsWithReductions($orderShop)
  350. );
  351. $orderShop->setStatDeliveryPriceWithReduction($this->priceSolver->getDeliveryPriceWithReduction($orderShop));
  352. $orderShop->setStatDeliveryPriceWithTaxAndReduction(
  353. $this->priceSolver->getDeliveryPriceWithTaxAndReduction($orderShop)
  354. );
  355. $this->entityManager->persist($orderShop);
  356. if ($flush) {
  357. $this->entityManager->flush();
  358. }
  359. }
  360. //initCycleNumber
  361. public function initDistribution(OrderShopInterface $orderShop): void
  362. {
  363. $distribution = $this->distributionBuilder->guessDistributionByDeliveryDate(
  364. $orderShop->getDeliveryDate(),
  365. $orderShop->getSection()
  366. );
  367. $orderShop->setDistribution($distribution);
  368. }
  369. public function createDocumentInvoice(OrderShopInterface $orderShop): DocumentInterface
  370. {
  371. $documentFactory = new DocumentFactory();
  372. $document = $documentFactory->create($orderShop->getSection(), DocumentModel::TYPE_INVOICE);
  373. $this->documentBuilder->initFromOrderShop($document, $orderShop);
  374. return $document;
  375. }
  376. public function addReductionCart(
  377. OrderShopInterface $orderShop,
  378. ReductionCartInterface $reductionCart
  379. ): ?OrderReductionCartInterface {
  380. $orderReductionCartFactory = new OrderReductionCartFactory();
  381. $orderReductionCart = $orderReductionCartFactory->create($orderShop, $reductionCart);
  382. $orderShop->addOrderReductionCart($orderReductionCart);
  383. if ($this->orderShopResolver->isPositiveAmount($orderShop)
  384. && $this->orderShopResolver->isPositiveAmountRemainingToBePaid($orderShop)) {
  385. $this->entityManager->create($orderReductionCart);
  386. $this->entityManager->flush();
  387. return $orderReductionCart;
  388. } else {
  389. //TODO vérifier ce case ! Avec le null en valeur de retour
  390. $orderShop->removeOrderReductionCart($orderReductionCart);
  391. return null;
  392. }
  393. }
  394. // createOrderReductionCredit
  395. public function addReductionCredit(
  396. OrderShopInterface $orderShop,
  397. ReductionCreditInterface $reductionCredit
  398. ): ?OrderReductionCreditInterface {
  399. $orderReductionCreditFactory = new OrderReductionCreditFactory();
  400. $orderReductionCredit = $orderReductionCreditFactory->create($orderShop, $reductionCredit);
  401. $orderShop->addOrderReductionCredit($orderReductionCredit);
  402. if ($this->isOrderShopPositiveAmount($orderShop)
  403. && $this->isOrderShopPositiveAmountRemainingToBePaid($orderShop)) {
  404. $this->entityManager->create($orderReductionCredit);
  405. $this->entityManager->flush();
  406. return $orderReductionCredit;
  407. } else {
  408. $orderShop->removeOrderReductionCredit($orderReductionCredit);
  409. return null;
  410. }
  411. }
  412. public function deductAvailabilityProduct(OrderShopInterface $orderShop): void
  413. {
  414. foreach ($orderShop->getOrderProducts() as $orderProduct) {
  415. $this->applyDeductAvailabilityProduct($orderShop, $orderProduct);
  416. }
  417. }
  418. public function applyDeductAvailabilityProduct(
  419. OrderShopInterface $orderShop,
  420. OrderProductInterface $orderProduct
  421. ): void {
  422. switch ($orderProduct->getProduct()->getProductFamily()->getBehaviorCountStock()) {
  423. case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE :
  424. //Disponibilité par unité de référence
  425. $oldAvailability = $this->productSolver->getAvailableQuantityInherited($orderProduct->getProduct());
  426. $newAvailability = $oldAvailability - ($orderProduct->getQuantityOrder(
  427. ) * ($orderProduct->getQuantityProduct() / $orderProduct->getUnit()->getCoefficient()));
  428. $productFamily = $orderProduct->getProduct()->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($orderProduct->getProduct());
  435. $newAvailability = $oldAvailability - $orderProduct->getQuantityOrder();
  436. $productFamily = $orderProduct->getProduct()->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($orderProduct->getProduct());
  443. $newAvailability = $oldAvailability - $orderProduct->getQuantityOrder();
  444. $product = $orderProduct->getProduct();
  445. $product->setAvailableQuantity($newAvailability);
  446. $product->setUpdatedBy($orderShop->getUser());
  447. $this->entityManager->update($product);
  448. break;
  449. }
  450. $this->entityManager->flush();
  451. }
  452. public function updatePriceByProductFamily(ProductFamilyInterface $productFamily)
  453. {
  454. // @TODO : faire la vérification isOpenSale depuis la méthode appelante
  455. if (!$this->openingResolver->isOpenSale(
  456. $productFamily->getSection(),
  457. null,
  458. OpeningResolver::OPENING_CONTEXT_BACKEND
  459. )) {
  460. $countOrderProductUpdated = 0;
  461. foreach ($productFamily->getProducts() as $product) {
  462. $orderProducts = $this->orderProductStore->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. // @TODO : faire le add flash dans le controller
  478. /*$this->utils->addFlash(
  479. 'success',
  480. 'success.OrderShop.orderProductUpdated',
  481. array(),
  482. array('%count%' => $countOrderProductUpdated)
  483. );*/
  484. $this->entityManager->flush();
  485. }
  486. return $countOrderProductUpdated;
  487. }
  488. }
  489. public function setStatsInfo(OrderShopInterface $orderShop, $flush = true)
  490. {
  491. $orderShop->setStatTotal($this->priceSolver->getTotal($orderShop));
  492. $orderShop->setStatTotalWithTax($this->priceSolver->getTotalWithTax($orderShop));
  493. $orderShop->setStatTotalOrderProductsWithReductions(
  494. $this->priceSolver->getTotalOrderProductsWithReductions($orderShop)
  495. );
  496. $orderShop->setStatTotalOrderProductsWithTaxAndReductions(
  497. $this->priceSolver->getTotalOrderProductsWithTaxAndReductions($orderShop)
  498. );
  499. $orderShop->setStatMarginOrderProductsWithReductions(
  500. $this->priceSolver->getMarginOrderProductsWithReductions($orderShop)
  501. );
  502. $orderShop->setStatDeliveryPriceWithReduction($this->priceSolver->getDeliveryPriceWithReduction($orderShop));
  503. $orderShop->setStatDeliveryPriceWithTaxAndReduction(
  504. $this->priceSolver->getDeliveryPriceWithTaxAndReduction($orderShop)
  505. );
  506. $this->entityManager->update($orderShop);
  507. if ($flush) {
  508. $this->entityManager->flush();
  509. }
  510. }
  511. public function setHasReach(int $reachStep, OrderShopInterface $orderShop)
  512. {
  513. if ($orderShop->getHasReach() === null || $orderShop->getHasReach() < $reachStep) {
  514. $orderShop->setHasReach($reachStep);
  515. $this->entityManager->persist($orderShop);
  516. $this->entityManager->flush($orderShop);
  517. }
  518. }
  519. public function initComplementaryOrderShop(OrderShopInterface $orderShop, OrderShopInterface $mainOrderShop): void
  520. {
  521. $orderShop->setMainOrderShop($mainOrderShop);
  522. $orderShop->setDeliveryPrice(0);
  523. if ($mainOrderShop->getDeliveryAddress()) {
  524. $this->initDeliveryAddress($orderShop, $mainOrderShop->getDeliveryAddress());
  525. }
  526. $orderShop->setInvoiceAddress($mainOrderShop->getInvoiceAddress());
  527. }
  528. // setDeliveryAddress
  529. public function initDeliveryAddress(OrderShopInterface $orderShop, AddressInterface $address = null): void
  530. {
  531. $orderShop->setDeliveryAddress($address);
  532. $orderShop->setDeliveryInfos($address ? $address->getDeliveryInfos() : null);
  533. }
  534. // resetOrderShopInfos
  535. public function reset(OrderShopInterface $orderShop)
  536. {
  537. $this->initDeliveryAddress($orderShop, null);
  538. $orderShop->setMainOrderShop(null);
  539. $orderShop->setDeliveryPrice(null);
  540. $orderShop->setInvoiceAddress(null);
  541. $orderShop->setDeclineComplementaryOrderShop(false);
  542. }
  543. public function getProductsSalesStatistic(SectionInterface $section, $entity, $nbWeek = 2)
  544. {
  545. $productsSalesStatistic = new ProductsSalesStatistic(
  546. $this->entityManager,
  547. $entity,
  548. $nbWeek,
  549. $this->productSolver
  550. );
  551. $productsSalesStatistic->init($section, $this->distributionBuilder, $this->openingResolver);
  552. $productsSalesStatistic->populateProperties($this->orderShopStore);
  553. return $productsSalesStatistic->getAsArray();
  554. }
  555. }