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.

324 line
11KB

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