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.

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