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.

414 lines
15KB

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