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.

249 line
8.8KB

  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\SectionStoreTrait;
  7. use Lc\CaracoleBundle\Solver\Price\PriceSolver;
  8. use Lc\SovBundle\Model\User\UserInterface;
  9. use Lc\SovBundle\Repository\AbstractStore;
  10. use Lc\SovBundle\Repository\RepositoryQueryInterface;
  11. class ProductFamilyStore extends AbstractStore
  12. {
  13. use SectionStoreTrait;
  14. protected ProductFamilyRepositoryQuery $query;
  15. protected PriceSolver $priceSolver;
  16. public function __construct(ProductFamilyRepositoryQuery $query, PriceSolver $priceSolver)
  17. {
  18. $this->query = $query;
  19. $this->priceSolver = $priceSolver;
  20. }
  21. public function orderByDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
  22. {
  23. $query->orderBy('position');
  24. return $query;
  25. }
  26. public function filtersDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
  27. {
  28. $query->filterBySection($this->section);
  29. return $query;
  30. }
  31. public function relationsDefault($query): RepositoryQueryInterface
  32. {
  33. $query->joinProductCategories();
  34. $query->joinProducts();
  35. return $query;
  36. }
  37. // getProductFamiliesByCategory
  38. public function getByCategory(ProductCategoryInterface $productCategory, $query = null)
  39. {
  40. $query = $this->createDefaultQuery($query);
  41. $query
  42. ->filterIsOnline()
  43. ->filterByProductCategory($productCategory);
  44. return $query->find();
  45. }
  46. // getProductFamiliesNovelties
  47. public function getNovelty($user = null, $organizeByParentCategory = true, $query = null)
  48. {
  49. $query = $this->createDefaultQuery($query);
  50. $query
  51. ->filterByPropertyNoveltyExpirationDate()
  52. ->filterIsOnline();
  53. $results = $query->find();
  54. return $this->getWithReductions($results, $user, false, $organizeByParentCategory);
  55. }
  56. // getProductFamiliesOrganics
  57. public function getOrganic($user = null, $organizeByParentCategory = true, $query = null)
  58. {
  59. $query = $this->createDefaultQuery($query);
  60. $query
  61. ->filterIsOrganicLabel()
  62. ->filterIsOnline();
  63. $results = $query->find();
  64. return $this->getWithReductions($results, $user, false, $organizeByParentCategory);
  65. }
  66. // getProductFamiliesOnDiscount
  67. public function getDiscount($user = null, $organizeByParentCategory = true, $query = null)
  68. {
  69. return $this->getWithReductions($this->getOnline($query), $user, false, $organizeByParentCategory);
  70. }
  71. // getProductFamiliesFavorites
  72. public function getFavorite($user = null, $organizeByParentCategory = true, $query = null)
  73. {
  74. if ($user) {
  75. return $this->getWithReductions($user->getFavoriteProductFamilies(), $user, false, $organizeByParentCategory);
  76. }
  77. return [];
  78. }
  79. // findByTerms
  80. public function getByTerms($terms, $maxResults = false, $query = null)
  81. {
  82. $query = $this->createDefaultQuery($query);
  83. $query->filterIsOnline();
  84. $query->groupBy('id');
  85. if($maxResults) {
  86. $query->limit($maxResults);
  87. }
  88. return $query->find();
  89. }
  90. public function getBestReductionCatalog(
  91. ProductFamilyInterface $productFamily,
  92. ReductionCatalogInterface $reductionCatalog1,
  93. ReductionCatalogInterface $reductionCatalog2
  94. ) {
  95. $price1 = $this->priceSolver->applyReductionCatalog(
  96. $productFamily,
  97. $this->priceSolver->getPrice($productFamily),
  98. $this->priceSolver->getPriceWithTax($productFamily),
  99. 1,
  100. $reductionCatalog1
  101. );
  102. $price2 = $this->priceSolver->applyReductionCatalog(
  103. $productFamily,
  104. $this->priceSolver->getPrice($productFamily),
  105. $this->priceSolver->getPriceWithTax($productFamily),
  106. 1,
  107. $reductionCatalog2
  108. );
  109. if ($price1 > $price2) {
  110. return $reductionCatalog2;
  111. } else {
  112. return $reductionCatalog1;
  113. }
  114. }
  115. // setReductionForProductFamilies
  116. public function getWithReductions(
  117. $productFamilies,
  118. UserInterface $user = null,
  119. $organizeByCategory = false,
  120. $organizeByParentCategory = false,
  121. $onlyOnDiscount = false
  122. ) {
  123. $conditions = [
  124. 'ids' => [],
  125. 'categories' => [],
  126. ];
  127. foreach ($productFamilies as $productFamily) {
  128. $conditions['ids'][] = $productFamily->getId();
  129. $conditions['categories'] = array_merge(
  130. $conditions['categories'],
  131. $productFamily->getProductCategories()->toArray()
  132. );
  133. }
  134. if ($productFamilies) {
  135. $reductionCatalogs = $this->reductionCatalogStore->getByProductFamiliesConditions(
  136. $conditions,
  137. $user
  138. );
  139. }
  140. $productFamiliesToReturn = array();
  141. foreach ($productFamilies as $productFamily) {
  142. foreach ($reductionCatalogs as $reductionCatalog) {
  143. $conditionProductFamilies = $conditionProductFamily = $conditionProductCategory = false;
  144. if ($reductionCatalog->getProductFamilies()->contains(
  145. $productFamily
  146. ) || $reductionCatalog->getProductFamilies()->isEmpty()) {
  147. $conditionProductFamilies = true;
  148. }
  149. if ($reductionCatalog->getProductFamily() == $productFamily || $reductionCatalog->getProductFamily(
  150. ) === null) {
  151. $conditionProductFamily = true;
  152. }
  153. foreach ($productFamily->getProductCategories() as $productCategory) {
  154. if ($reductionCatalog->getProductCategories()->contains(
  155. $productCategory
  156. ) || $reductionCatalog->getProductCategories()->isEmpty()) {
  157. $conditionProductCategory = true;
  158. }
  159. }
  160. if ($conditionProductFamilies && $conditionProductFamily && $conditionProductCategory) {
  161. if ($productFamily->getReductionCatalog()) {
  162. $productFamily->setReductionCatalog(
  163. $this->getBestReductionCatalog(
  164. $productFamily,
  165. $reductionCatalog,
  166. $productFamily->getReductionCatalog()
  167. )
  168. );
  169. } else {
  170. $productFamily->setReductionCatalog($reductionCatalog);
  171. }
  172. }
  173. }
  174. if (($onlyOnDiscount && $productFamily->getReductionCatalog()) || !$onlyOnDiscount) {
  175. if ($organizeByParentCategory) {
  176. $productCategories = $productFamily->getProductCategories();
  177. if ($productCategories && count($productCategories) > 0) {
  178. $parentCategory = $productCategories[0]->getParentCategory();
  179. if ($this->productCategorySolver->isDisplay($parentCategory, $user)) {
  180. if (!isset($productFamiliesToReturn[$parentCategory->getId()])) {
  181. $productFamiliesToReturn[$parentCategory->getId()] = [
  182. 'category' => $parentCategory,
  183. 'products' => []
  184. ];
  185. }
  186. $productFamiliesToReturn[$parentCategory->getId()]['products'][] = $productFamily;
  187. }
  188. }
  189. } elseif ($organizeByCategory) {
  190. foreach ($productFamily->getProductCategories() as $productCategory) {
  191. if ($this->isDisplay($productFamily)) {
  192. $productFamiliesToReturn[$productCategory->getId()][] = $productFamily;
  193. }
  194. }
  195. } else {
  196. if ($this->isDisplay($productFamily)) {
  197. $productFamiliesToReturn[] = $productFamily;
  198. }
  199. }
  200. }
  201. }
  202. if ($organizeByParentCategory) {
  203. uasort($productFamiliesToReturn, array($this, 'compMethodSortProductFamiliesByParentCategory'));
  204. }
  205. return $productFamiliesToReturn;
  206. }
  207. }