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

399 lines
14KB

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