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.

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