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
10.0KB

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