You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

366 lines
13KB

  1. <?php
  2. namespace Lc\CaracoleBundle\Solver\Order;
  3. use App\Entity\Order\OrderShop;
  4. use Doctrine\Common\Collections\ArrayCollection;
  5. use Doctrine\Common\Collections\Collection;
  6. use Doctrine\ORM\EntityManagerInterface;
  7. use Lc\CaracoleBundle\Model\File\DocumentInterface;
  8. use Lc\CaracoleBundle\Model\File\DocumentModel;
  9. use Lc\CaracoleBundle\Model\Order\OrderProductInterface;
  10. use Lc\CaracoleBundle\Model\Order\OrderShopInterface;
  11. use Lc\CaracoleBundle\Model\Order\OrderShopModel;
  12. use Lc\CaracoleBundle\Model\Order\OrderStatusInterface;
  13. use Lc\CaracoleBundle\Model\Order\OrderStatusModel;
  14. use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface;
  15. use Lc\CaracoleBundle\Model\Product\ProductFamilyModel;
  16. use Lc\CaracoleBundle\Model\Product\ProductInterface;
  17. use Lc\CaracoleBundle\Model\Reduction\ReductionCreditInterface;
  18. use Lc\CaracoleBundle\Solver\Product\ProductFamilySectionPropertySolver;
  19. use Lc\CaracoleBundle\Solver\Product\ProductSolver;
  20. class OrderShopSolver
  21. {
  22. protected EntityManagerInterface $entityManager;
  23. protected ProductSolver $productSolver;
  24. public function __construct(
  25. EntityManagerInterface $entityManager,
  26. ProductSolver $productSolver
  27. )
  28. {
  29. $this->entityManager = $entityManager;
  30. $this->productSolver = $productSolver;
  31. }
  32. public function countQuantities(OrderShopInterface $orderShop): int
  33. {
  34. return $this->countQuantitiesByOrderProducts($orderShop->getOrderProducts());
  35. }
  36. public function countQuantitiesByOrderProducts($orderProducts = []): int
  37. {
  38. $count = 0;
  39. foreach ($orderProducts as $orderProduct) {
  40. $count += $orderProduct->getQuantityOrder();
  41. }
  42. return $count;
  43. }
  44. public function getOrderProductsByParentCategory(OrderShopInterface $orderShop): array
  45. {
  46. $categoriesArray = [];
  47. foreach ($orderShop->getOrderProducts() as $orderProduct) {
  48. $productCategories = $orderProduct->getProduct()->getProductFamily()->getProductCategories();
  49. $category = $productCategories[0]->getParentCategory();
  50. $labelCategory = $category->getTitle();
  51. if (!isset($categoriesArray[$labelCategory])) {
  52. $categoriesArray[$labelCategory] = [];
  53. }
  54. $categoriesArray[$labelCategory][] = $orderProduct;
  55. }
  56. return $categoriesArray;
  57. }
  58. // getOrderProductsByProductFamily
  59. public function getOrderProductsByProductFamily(
  60. OrderShopInterface $orderShop,
  61. ProductFamilyInterface $productFamily
  62. ): array
  63. {
  64. $arrayOrderProducts = [];
  65. foreach ($orderShop->getOrderProducts() as $orderProduct) {
  66. if ($orderProduct->getProduct()->getProductFamily() == $productFamily) {
  67. $arrayOrderProducts[] = $orderProduct;
  68. }
  69. }
  70. return $arrayOrderProducts;
  71. }
  72. public function getQuantityOrderByProduct(
  73. OrderShopInterface $orderShop,
  74. ProductInterface $product,
  75. $byWeight = false
  76. ): int
  77. {
  78. $quantity = 0;
  79. $productFamily = $product->getProductFamily();
  80. $behaviorCountStock = $productFamily->getBehaviorCountStock();
  81. foreach ($orderShop->getOrderProducts() as $orderProduct) {
  82. if ($orderProduct->getProduct()->getId() == $product->getId()
  83. || (($behaviorCountStock == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY || $behaviorCountStock == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE)
  84. && $orderProduct->getProduct()->getProductFamily()->getId() == $productFamily->getId())) {
  85. if ($byWeight) {
  86. $quantity += $orderProduct->getQuantityOrder() * ($orderProduct->getQuantityProduct() / $orderProduct->getProduct()->getUnitInherited()->getCoefficient());
  87. } else {
  88. $quantity += $orderProduct->getQuantityOrder();
  89. }
  90. }
  91. }
  92. return $quantity;
  93. }
  94. // isProductAvailable
  95. public function isProductAvailable(
  96. ProductInterface $product,
  97. $quantityOrder = 0,
  98. $checkCart = false,
  99. $orderShop
  100. )
  101. {
  102. if ($product->getStatus() != 1 || $product->getProductFamily()->getStatus() != 1 || !$this->productSolver->isProductSaleStatusOn($product)) {
  103. return false;
  104. }
  105. if ($checkCart && !$orderShop) {
  106. throw new \Exception("Attention : définir le orderShop à l'endroit où est appelé isAvailable");
  107. }
  108. $productFamily = $product->getProductFamily();
  109. $quantityAsked = $quantityOrder;
  110. if ($productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE) {
  111. if (!$quantityOrder) {
  112. $quantityAsked = $this->getQuantityOrderByProduct($orderShop, $product, true);
  113. } else {
  114. $quantityAsked = ($this->productSolver->getQuantityInherited(
  115. $product
  116. ) / $this->productSolver->getUnitInherited($product)->getCoefficient()) * $quantityOrder;
  117. }
  118. if ($checkCart) {
  119. $quantityAsked += $this->getQuantityOrderByProduct($orderShop, $product, true);
  120. }
  121. }
  122. if (($productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY
  123. || $productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT)) {
  124. if (!$quantityOrder) {
  125. $quantityAsked = $this->getQuantityOrderByProduct($orderShop, $product);
  126. }
  127. if ($checkCart) {
  128. $quantityAsked += $this->getQuantityOrderByProduct($orderShop, $product);
  129. }
  130. }
  131. if ($this->productSolver->getAvailableQuantityInherited($product) >= $quantityAsked) {
  132. return true;
  133. } else {
  134. return false;
  135. }
  136. }
  137. public function isOneProductAvailableAddCart(OrderShopInterface $orderShop, $products): bool
  138. {
  139. foreach ($products as $product) {
  140. if ($this->isProductAvailable($product, 1, true, $orderShop)) {
  141. return true;
  142. }
  143. }
  144. return false;
  145. }
  146. public function isOrderProductAvailableAddCart(OrderProductInterface $orderProduct, OrderShopInterface $orderShop)
  147. {
  148. return $this->isProductAvailable(
  149. $orderProduct->getProduct(),
  150. $orderProduct->getQuantityOrder(),
  151. true,
  152. $orderShop
  153. );
  154. }
  155. public function getTotalOrderPayments(OrderShopInterface $orderShop, $mergeComplementaryOrderShop = false): float
  156. {
  157. $totalAmount = floatval(0);
  158. foreach ($orderShop->getOrderPayments() as $orderPayment) {
  159. $totalAmount = $orderPayment->getAmount() + $totalAmount;
  160. }
  161. if ($mergeComplementaryOrderShop) {
  162. foreach ($this->getValidComplementaryOrderShops($orderShop) as $complementaryOrderShop) {
  163. foreach ($complementaryOrderShop->getOrderPayments() as $orderPayment) {
  164. $totalAmount = $orderPayment->getAmount() + $totalAmount;
  165. }
  166. }
  167. }
  168. return $totalAmount;
  169. }
  170. public function getValidComplementaryOrderShops(OrderShopInterface $orderShop): Collection
  171. {
  172. $arrayComplementaryOrderShops = new ArrayCollection();
  173. foreach ($orderShop->getComplementaryOrderShops() as $complementaryOrderShop) {
  174. if ($this->isValid($complementaryOrderShop)) {
  175. $arrayComplementaryOrderShops[] = $complementaryOrderShop;
  176. }
  177. }
  178. return $arrayComplementaryOrderShops;
  179. }
  180. public function getOrderStatusHistory(OrderShopInterface $orderShop, OrderStatusInterface $status)
  181. {
  182. $orderStatusHistories = $orderShop->getOrderStatusHistories();
  183. if (count($orderStatusHistories) > 0) {
  184. foreach ($orderStatusHistories as $orderStatusHistory) {
  185. if ($orderStatusHistory->getOrderStatus() === $status) {
  186. return $orderStatusHistory;
  187. }
  188. }
  189. }
  190. return null;
  191. }
  192. public function getDocumentInvoice(OrderShopInterface $orderShop): ?DocumentInterface
  193. {
  194. foreach ($orderShop->getDocuments() as $document) {
  195. if ($document->getType() == DocumentModel::TYPE_INVOICE) {
  196. return $document;
  197. }
  198. }
  199. return null;
  200. }
  201. public function isDeliveryHome(OrderShopInterface $orderShop): bool
  202. {
  203. return $orderShop->getDeliveryType() == OrderShopModel::DELIVERY_TYPE_HOME;
  204. }
  205. public function isDeliveryPointSale(OrderShopInterface $orderShop): bool
  206. {
  207. return $orderShop->getDeliveryType() == OrderShopModel::DELIVERY_TYPE_POINTSALE;
  208. }
  209. public function isComplementaryOrderShop(OrderShopInterface $orderShop): bool
  210. {
  211. return (bool)$orderShop->getMainOrderShop();
  212. }
  213. public function mergeComplentaryOrderShops(
  214. OrderShopInterface $orderShop,
  215. bool $combineProducts = true
  216. ): OrderShopInterface
  217. {
  218. $this->entityManager->refresh($orderShop);
  219. if ($this->getValidComplementaryOrderShops($orderShop)) {
  220. foreach ($this->getValidComplementaryOrderShops($orderShop) as $complementaryOrderShop) {
  221. foreach ($complementaryOrderShop->getOrderProducts() as $orderProductAdd) {
  222. $updated = false;
  223. foreach ($orderShop->getOrderProducts() as $orderProduct) {
  224. if ($combineProducts && $orderProduct->getProduct()->getId() == $orderProductAdd->getProduct()->getId()
  225. && (string)$orderProduct->getPrice() == (string)$orderProductAdd->getPrice()
  226. ) {
  227. $orderProduct->setUpdatedOnMergeComplementaryOrderShop(true);
  228. $orderProduct->setQuantityOrder(
  229. $orderProduct->getQuantityOrder() + $orderProductAdd->getQuantityOrder()
  230. );
  231. $updated = true;
  232. }
  233. }
  234. if (!$updated) {
  235. $orderProductAdd->setOnMergeComplementaryOrderShop($complementaryOrderShop);
  236. $orderProductAdd->setCreatedOnMergeComplementaryOrderShop(true);
  237. $orderShop->addOrderProduct($orderProductAdd);
  238. }
  239. }
  240. }
  241. }
  242. return $orderShop;
  243. }
  244. public function isReductionCreditAddedToOrder(
  245. OrderShopInterface $orderShop,
  246. ReductionCreditInterface $reductionCredit
  247. )
  248. {
  249. foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) {
  250. if ($orderReductionCredit->getReductionCredit() == $reductionCredit) {
  251. return true;
  252. }
  253. }
  254. return false;
  255. }
  256. public function hasOrderProductAlreadyInCart(
  257. OrderShopInterface $orderShop,
  258. OrderProductInterface $orderProductTest
  259. ): ?OrderProductInterface
  260. {
  261. foreach ($orderShop->getOrderProducts() as $orderProduct) {
  262. if ($orderProduct->getProduct() == $orderProductTest->getProduct()) {
  263. return $orderProduct;
  264. }
  265. }
  266. return null;
  267. }
  268. public function isValid(OrderShopInterface $orderShop): bool
  269. {
  270. if ($orderShop->getOrderStatus() && in_array(
  271. $orderShop->getOrderStatus()->getAlias(),
  272. OrderStatusModel::$statusAliasAsValid
  273. ) > 0) {
  274. return true;
  275. }
  276. return false;
  277. }
  278. public function isCart(OrderShopInterface $orderShop): bool
  279. {
  280. if ($orderShop->getOrderStatus() && in_array(
  281. $orderShop->getOrderStatus()->getAlias(),
  282. OrderStatusModel::$statusAliasAsCart
  283. ) > 0) {
  284. return true;
  285. }
  286. return false;
  287. }
  288. // getProductQuantityMaxAddCart
  289. public function getProductQuantityMaxAddCart(OrderShopInterface $orderShop, ProductInterface $product)
  290. {
  291. $productFamily = $product->getProductFamily();
  292. $byWeight = false;
  293. if ($productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE) {
  294. $byWeight = true;
  295. }
  296. return $this->productSolver->getAvailableQuantityInherited($product) - $this->getQuantityOrderByProduct(
  297. $orderShop,
  298. $product,
  299. $byWeight
  300. );
  301. }
  302. public function hasMakeAChoiceAboutComplementaryOrder(OrderShop $orderShop): bool
  303. {
  304. return $orderShop->getMainOrderShop() || $orderShop->getDeclineComplementaryOrderShop();
  305. }
  306. }