Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

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