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.

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