Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

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