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 line
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. $productFamiliesArray = [];
  48. foreach ($parentCategory->getChildrens() as $i => $category) {
  49. $productFamiliesCategory = $this->getByCategory($category);
  50. foreach ($productFamiliesCategory as $productFamily) {
  51. $productFamiliesArray[$productFamily->getId()] = $productFamily;
  52. }
  53. uasort($productFamiliesArray, array($this, 'compMethodSortProductFamiliesByPosition'));
  54. }
  55. return $this->getWithReductions($productFamiliesArray, $user, true);
  56. }
  57. private function compMethodSortProductFamiliesByPosition($a, $b)
  58. {
  59. return $a->getPosition() > $b->getPosition();
  60. }
  61. // getProductFamiliesByCategory
  62. public function getByCategory(
  63. ProductCategoryInterface $productCategory,
  64. $query = null
  65. ) {
  66. $query = $this->createDefaultQuery($query);
  67. $query
  68. ->filterIsOnline()
  69. ->filterByProductCategory($productCategory);
  70. return $query->find();
  71. }
  72. //TODO ajouter status en donné de contexte pour éviter ce truc
  73. public function getByCategoryOnlineAndOffline(
  74. ProductCategoryInterface $productCategory,
  75. $query = null
  76. ) {
  77. $query = $this->createDefaultQuery($query);
  78. $query
  79. ->filterByProductCategory($productCategory);
  80. return $query->find();
  81. }
  82. // getProductFamiliesNovelties
  83. public function getNovelty($user = null, $organizeByParentCategory = true, $query = null)
  84. {
  85. $query = $this->createDefaultQuery($query);
  86. $query
  87. ->filterByPropertyNoveltyExpirationDate()
  88. ->filterIsOnline();
  89. $results = $query->find();
  90. return $this->getWithReductions($results, $user, false, $organizeByParentCategory);
  91. }
  92. // getProductFamiliesOrganics
  93. public function getOrganic($user = null, $organizeByParentCategory = true, $query = null)
  94. {
  95. $query = $this->createDefaultQuery($query);
  96. $query
  97. ->filterIsOrganicLabel()
  98. ->filterIsOnline();
  99. $results = $query->find();
  100. return $this->getWithReductions($results, $user, false, $organizeByParentCategory);
  101. }
  102. // getProductFamiliesOnDiscount
  103. public function getDiscount($user = null, $organizeByParentCategory = true, $query = null)
  104. {
  105. return $this->getWithReductions($this->getOnline($query), $user, false, $organizeByParentCategory, true);
  106. }
  107. // getProductFamiliesFavorites
  108. public function getFavorite($user = null, $organizeByParentCategory = true, $query = null)
  109. {
  110. if ($user) {
  111. return $this->getWithReductions(
  112. $user->getFavoriteProductFamilies(),
  113. $user,
  114. false,
  115. $organizeByParentCategory
  116. );
  117. }
  118. return [];
  119. }
  120. // findByTerms
  121. public function getByTerms(
  122. $terms,
  123. $maxResults = false,
  124. $organizeByParentCategory = false,
  125. $user = null,
  126. $query = null
  127. ) {
  128. $query = $this->createDefaultQuery($query);
  129. $query->filterIsOnline();
  130. $query->filterByTerms($terms);
  131. $query->groupBy('id');
  132. if ($maxResults) {
  133. $query->limit($maxResults);
  134. }
  135. $results = $query->find();
  136. return $this->getWithReductions($results, $user, false, $organizeByParentCategory);
  137. }
  138. public function getBestReductionCatalog(
  139. ProductFamilyInterface $productFamily,
  140. ReductionCatalogInterface $reductionCatalog1,
  141. ReductionCatalogInterface $reductionCatalog2
  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. $conditions = [
  166. 'productFamiliesIds' => [],
  167. 'categories' => [],
  168. 'productFamilies' => [],
  169. ];
  170. foreach ($productFamilies as $productFamily) {
  171. $conditions['productFamiliesIds'][] = $productFamily->getId();
  172. $conditions['productFamilies'][] = $productFamily;
  173. $conditions['categories'] = array_merge(
  174. $conditions['categories'],
  175. $productFamily->getProductCategories()->toArray()
  176. );
  177. }
  178. if ($productFamilies) {
  179. $reductionCatalogs = $this->reductionCatalogStore->getByProductFamiliesConditions(
  180. $conditions,
  181. $user
  182. );
  183. }
  184. $productFamiliesToReturn = array();
  185. foreach ($productFamilies as $productFamily) {
  186. foreach ($reductionCatalogs as $reductionCatalog) {
  187. $conditionProductFamilies = $conditionProductFamily = $conditionProductCategory = false;
  188. if ($reductionCatalog->getProductFamilies()->contains(
  189. $productFamily
  190. ) || $reductionCatalog->getProductFamilies()->isEmpty()) {
  191. $conditionProductFamilies = true;
  192. }
  193. if ($reductionCatalog->getProductFamily() == $productFamily || $reductionCatalog->getProductFamily(
  194. ) === 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. }