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.

290 lines
9.9KB

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