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.

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