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

382 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\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. ): OrderShopInterface {
  223. $this->entityManager->refresh($orderShop);
  224. if ($this->getValidComplementaryOrderShops($orderShop)) {
  225. foreach ($this->getValidComplementaryOrderShops($orderShop) as $complementaryOrderShop) {
  226. foreach ($complementaryOrderShop->getOrderProducts() as $orderProductAdd) {
  227. $updated = false;
  228. foreach ($orderShop->getOrderProducts() as $orderProduct) {
  229. if ($combineProducts && $orderProduct->getProduct()->getId() == $orderProductAdd->getProduct(
  230. )->getId()
  231. && (string)$orderProduct->getPrice() == (string)$orderProductAdd->getPrice()
  232. ) {
  233. $orderProduct->setUpdatedOnMergeComplementaryOrderShop(true);
  234. $orderProduct->setQuantityOrder(
  235. $orderProduct->getQuantityOrder() + $orderProductAdd->getQuantityOrder()
  236. );
  237. $updated = true;
  238. }
  239. }
  240. if (!$updated) {
  241. $orderProductAdd->setOnMergeComplementaryOrderShop($complementaryOrderShop);
  242. $orderProductAdd->setCreatedOnMergeComplementaryOrderShop(true);
  243. $orderShop->addOrderProduct($orderProductAdd);
  244. }
  245. }
  246. }
  247. }
  248. return $orderShop;
  249. }
  250. public function isReductionCreditAddedToOrder(
  251. OrderShopInterface $orderShop,
  252. ReductionCreditInterface $reductionCredit
  253. ) {
  254. foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) {
  255. if ($orderReductionCredit->getReductionCredit() == $reductionCredit) {
  256. return true;
  257. }
  258. }
  259. return false;
  260. }
  261. public function hasOrderProductAlreadyInCart(
  262. OrderShopInterface $orderShop,
  263. OrderProductInterface $orderProductTest
  264. ): ?OrderProductInterface {
  265. foreach ($orderShop->getOrderProducts() as $orderProduct) {
  266. if ($orderProduct->getProduct() == $orderProductTest->getProduct()) {
  267. return $orderProduct;
  268. }
  269. }
  270. return null;
  271. }
  272. public function isValid(OrderShopInterface $orderShop): bool
  273. {
  274. if ($orderShop->getOrderStatus() && in_array(
  275. $orderShop->getOrderStatus()->getAlias(),
  276. OrderStatusModel::$statusAliasAsValid
  277. ) > 0) {
  278. return true;
  279. }
  280. return false;
  281. }
  282. public function isCart(OrderShopInterface $orderShop): bool
  283. {
  284. if ($orderShop->getOrderStatus() && in_array(
  285. $orderShop->getOrderStatus()->getAlias(),
  286. OrderStatusModel::$statusAliasAsCart
  287. ) > 0) {
  288. return true;
  289. }
  290. return false;
  291. }
  292. public function isDone(OrderShopInterface $orderShop): bool
  293. {
  294. if ($orderShop->getOrderStatus() && $orderShop->getOrderStatus()->getAlias() == OrderStatusModel::ALIAS_DONE) {
  295. return true;
  296. }
  297. return false;
  298. }
  299. // getProductQuantityMaxAddCart
  300. public function getProductQuantityMaxAddCart(OrderShopInterface $orderShop, ProductInterface $product)
  301. {
  302. $productFamily = $product->getProductFamily();
  303. $byWeight = false;
  304. if ($productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE) {
  305. $byWeight = true;
  306. }
  307. return max(
  308. $this->productSolver->getAvailableQuantityInherited($product) - $this->getQuantityOrderByProduct(
  309. $orderShop,
  310. $product,
  311. $byWeight
  312. ),
  313. 0
  314. );
  315. }
  316. public function hasMakeAChoiceAboutComplementaryOrder(OrderShop $orderShop): bool
  317. {
  318. return $orderShop->getMainOrderShop() || $orderShop->getDeclineComplementaryOrderShop();
  319. }
  320. }