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.

306 lines
10KB

  1. <?php
  2. namespace Lc\CaracoleBundle\Repository\Product;
  3. use Lc\CaracoleBundle\Model\Product\ProductCategoryInterface;
  4. use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface;
  5. use Lc\CaracoleBundle\Model\Reduction\ReductionCatalogInterface;
  6. use Lc\CaracoleBundle\Repository\MerchantStoreTrait;
  7. use Lc\CaracoleBundle\Repository\SectionStoreTrait;
  8. use Lc\CaracoleBundle\Solver\Price\PriceSolver;
  9. use Lc\SovBundle\Model\User\UserInterface;
  10. use Lc\CaracoleBundle\Repository\AbstractStore;
  11. use Lc\SovBundle\Repository\RepositoryQueryInterface;
  12. class ProductFamilyStore extends AbstractStore
  13. {
  14. use SectionStoreTrait;
  15. use MerchantStoreTrait;
  16. protected ProductFamilyRepositoryQuery $query;
  17. protected PriceSolver $priceSolver;
  18. public function __construct(ProductFamilyRepositoryQuery $query, PriceSolver $priceSolver)
  19. {
  20. $this->query = $query;
  21. $this->priceSolver = $priceSolver;
  22. }
  23. public function orderByDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
  24. {
  25. $query->orderBy('position');
  26. return $query;
  27. }
  28. public function filtersDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
  29. {
  30. $query->filterIsOnlineAndOffline();
  31. $this->addFilterBySectionOptionnal($query);
  32. $this->addFilterByMerchantViaSectionOptionnal($query);
  33. return $query;
  34. }
  35. public function relationsDefault($query): RepositoryQueryInterface
  36. {
  37. $query->joinProductCategories();
  38. $query->joinProducts();
  39. $query->joinQualityLabels();
  40. return $query;
  41. }
  42. public function getByParentCategory(
  43. ProductCategoryInterface $parentCategory,
  44. $user = null,
  45. $query = null
  46. )
  47. {
  48. $productFamiliesArray = [];
  49. foreach ($parentCategory->getChildrens() as $i => $category) {
  50. $productFamiliesCategory = $this->getByCategory($category, $query);
  51. foreach ($productFamiliesCategory as $productFamily) {
  52. $productFamiliesArray[$productFamily->getId()] = $productFamily;
  53. }
  54. }
  55. return $this->getWithReductions($productFamiliesArray, $user, true);
  56. }
  57. // getProductFamiliesByCategory
  58. public function getByCategory(
  59. ProductCategoryInterface $productCategory,
  60. $query = null
  61. )
  62. {
  63. $query = $this->createDefaultQuery($query);
  64. $query
  65. ->filterIsOnline()
  66. ->filterByProductCategory($productCategory);
  67. return $query->find();
  68. }
  69. //TODO ajouter status en donné de contexte pour éviter ce truc
  70. public function getByCategoryOnlineAndOffline(
  71. ProductCategoryInterface $productCategory,
  72. $query = null
  73. )
  74. {
  75. $query = $this->createDefaultQuery($query);
  76. $query
  77. ->filterByProductCategory($productCategory);
  78. return $query->find();
  79. }
  80. // getProductFamiliesNovelties
  81. public function getNovelty($user = null, $organizeByParentCategory = true, $query = null)
  82. {
  83. $query = $this->createDefaultQuery($query);
  84. $query
  85. ->filterByPropertyNoveltyExpirationDate()
  86. ->filterIsOnline();
  87. $results = $query->find();
  88. return $this->getWithReductions($results, $user, false, $organizeByParentCategory);
  89. }
  90. // getProductFamiliesOrganics
  91. public function getOrganic($user = null, $organizeByParentCategory = true, $query = null)
  92. {
  93. $query = $this->createDefaultQuery($query);
  94. $query
  95. ->filterIsOrganicLabel()
  96. ->filterIsOnline();
  97. $results = $query->find();
  98. return $this->getWithReductions($results, $user, false, $organizeByParentCategory);
  99. }
  100. // getProductFamiliesOnDiscount
  101. public function getDiscount($user = null, $organizeByParentCategory = true, $query = null)
  102. {
  103. return $this->getWithReductions($this->getOnline($query), $user, false, $organizeByParentCategory, true);
  104. }
  105. // getProductFamiliesFavorites
  106. public function getFavorite($user = null, $organizeByParentCategory = true, $query = null)
  107. {
  108. if ($user) {
  109. return $this->getWithReductions(
  110. $user->getFavoriteProductFamilies(),
  111. $user,
  112. false,
  113. $organizeByParentCategory
  114. );
  115. }
  116. return [];
  117. }
  118. // findByTerms
  119. public function getByTerms(
  120. $terms,
  121. $maxResults = false,
  122. $organizeByParentCategory = false,
  123. $user = null,
  124. $query = null
  125. )
  126. {
  127. $query = $this->createDefaultQuery($query);
  128. $query->filterIsOnline();
  129. $query->filterByTerms($terms);
  130. $query->groupBy('id');
  131. if ($maxResults) {
  132. $query->limit($maxResults);
  133. }
  134. $results = $query->find();
  135. return $this->getWithReductions($results, $user, false, $organizeByParentCategory);
  136. }
  137. public function getBestReductionCatalog(
  138. ProductFamilyInterface $productFamily,
  139. ReductionCatalogInterface $reductionCatalog1,
  140. ReductionCatalogInterface $reductionCatalog2
  141. )
  142. {
  143. $price1 = $this->priceSolver->getPriceWithTaxByReduction(
  144. $productFamily,
  145. $reductionCatalog1
  146. );
  147. $price2 = $this->priceSolver->getPriceWithTaxByReduction(
  148. $productFamily,
  149. $reductionCatalog2
  150. );
  151. if ($price1 > $price2) {
  152. return $reductionCatalog2;
  153. } else {
  154. return $reductionCatalog1;
  155. }
  156. }
  157. // setReductionForProductFamilies
  158. public function getWithReductions(
  159. $productFamilies,
  160. UserInterface $user = null,
  161. $organizeByCategory = false,
  162. $organizeByParentCategory = false,
  163. $onlyOnDiscount = false
  164. )
  165. {
  166. $conditions = [
  167. 'productFamiliesIds' => [],
  168. 'categories' => [],
  169. 'productFamilies' => [],
  170. ];
  171. foreach ($productFamilies as $productFamily) {
  172. $conditions['productFamiliesIds'][] = $productFamily->getId();
  173. $conditions['productFamilies'][] = $productFamily;
  174. $conditions['categories'] = array_merge(
  175. $conditions['categories'],
  176. $productFamily->getProductCategories()->toArray()
  177. );
  178. }
  179. if ($productFamilies) {
  180. $reductionCatalogs = $this->reductionCatalogStore->getByProductFamiliesConditions(
  181. $conditions,
  182. $user
  183. );
  184. }
  185. $productFamiliesToReturn = array();
  186. foreach ($productFamilies as $productFamily) {
  187. foreach ($reductionCatalogs as $reductionCatalog) {
  188. $conditionProductFamilies = $conditionProductFamily = $conditionProductCategory = false;
  189. if ($reductionCatalog->getProductFamilies()->contains(
  190. $productFamily
  191. ) || $reductionCatalog->getProductFamilies()->isEmpty()) {
  192. $conditionProductFamilies = true;
  193. }
  194. if ($reductionCatalog->getProductFamily() == $productFamily || $reductionCatalog->getProductFamily() === null) {
  195. $conditionProductFamily = true;
  196. }
  197. foreach ($productFamily->getProductCategories() as $productCategory) {
  198. if ($reductionCatalog->getProductCategories()->contains(
  199. $productCategory
  200. ) || $reductionCatalog->getProductCategories()->isEmpty()) {
  201. $conditionProductCategory = true;
  202. }
  203. }
  204. if ($conditionProductFamilies && $conditionProductFamily && $conditionProductCategory) {
  205. if ($productFamily->getReductionCatalog()) {
  206. $productFamily->setReductionCatalog(
  207. $this->getBestReductionCatalog(
  208. $productFamily,
  209. $reductionCatalog,
  210. $productFamily->getReductionCatalog()
  211. )
  212. );
  213. } else {
  214. $productFamily->setReductionCatalog($reductionCatalog);
  215. }
  216. }
  217. }
  218. if (($onlyOnDiscount && $productFamily->getReductionCatalog()) || !$onlyOnDiscount) {
  219. if ($organizeByParentCategory) {
  220. $productCategories = $productFamily->getProductCategories();
  221. if ($productCategories && count($productCategories) > 0) {
  222. $parentCategory = $productCategories[0]->getParentCategory();
  223. if ($this->productCategorySolver->isDisplay($parentCategory, $user)) {
  224. if (!isset($productFamiliesToReturn[$parentCategory->getId()])) {
  225. $productFamiliesToReturn[$parentCategory->getId()] = [
  226. 'category' => $parentCategory,
  227. 'products' => []
  228. ];
  229. }
  230. $productFamiliesToReturn[$parentCategory->getId()]['products'][] = $productFamily;
  231. }
  232. }
  233. } elseif ($organizeByCategory) {
  234. foreach ($productFamily->getProductCategories() as $productCategory) {
  235. if ($this->isDisplay($productFamily)) {
  236. $productFamiliesToReturn[$productCategory->getId()][] = $productFamily;
  237. }
  238. }
  239. } else {
  240. if ($this->isDisplay($productFamily)) {
  241. $productFamiliesToReturn[] = $productFamily;
  242. }
  243. }
  244. }
  245. }
  246. if ($organizeByParentCategory) {
  247. uasort($productFamiliesToReturn, array($this, 'compMethodSortProductFamiliesByParentCategory'));
  248. }
  249. return $productFamiliesToReturn;
  250. }
  251. }