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.

492 lines
17KB

  1. <?php
  2. namespace Lc\CaracoleBundle\Solver\Product;
  3. use Doctrine\Common\Collections\ArrayCollection;
  4. use Doctrine\Common\Collections\Collection;
  5. use Lc\CaracoleBundle\Doctrine\Extension\ProductPropertyInterface;
  6. use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface;
  7. use Lc\CaracoleBundle\Model\Product\ProductFamilyModel;
  8. use Lc\CaracoleBundle\Model\Product\ProductFamilySectionPropertyInterface;
  9. use Lc\CaracoleBundle\Model\Product\ProductInterface;
  10. use Lc\CaracoleBundle\Model\Reduction\ReductionCatalogInterface;
  11. use Lc\CaracoleBundle\Model\Section\SectionInterface;
  12. class ProductFamilySolver
  13. {
  14. protected ProductSolver $productSolver;
  15. protected ProductFamilySectionPropertySolver $productFamilySectionPropertySolver;
  16. protected ProductCategorySolver $productCategorySolver;
  17. public function __construct(ProductSolver $productSolver, ProductFamilySectionPropertySolver $productFamilySectionPropertySolver, ProductCategorySolver $productCategorySolver)
  18. {
  19. $this->productSolver = $productSolver;
  20. $this->productFamilySectionPropertySolver = $productFamilySectionPropertySolver;
  21. $this->productCategorySolver = $productCategorySolver;
  22. }
  23. public static function getBehaviorCountStockChoices(): array
  24. {
  25. return [
  26. ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE,
  27. ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT,
  28. ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY,
  29. ];
  30. }
  31. public static function getWaringMessageTypeChoices(): array
  32. {
  33. return [
  34. ProductFamilyModel::WARNING_MESSAGE_TYPE_ERROR,
  35. ProductFamilyModel::WARNING_MESSAGE_TYPE_INFO,
  36. ProductFamilyModel::WARNING_MESSAGE_TYPE_SUCCESS,
  37. ProductFamilyModel::WARNING_MESSAGE_TYPE_WARNING,
  38. ];
  39. }
  40. public static function getBehaviorAddToCartChoices(): array
  41. {
  42. return [
  43. ProductFamilyModel::BEHAVIOR_ADD_TO_CART_MULTIPLE,
  44. ProductFamilyModel::BEHAVIOR_ADD_TO_CART_SIMPLE,
  45. ];
  46. }
  47. public static function getBehaviorPriceChoices(): array
  48. {
  49. return [
  50. ProductFamilyModel::BEHAVIOR_PRICE_BY_PIECE,
  51. ProductFamilyModel::BEHAVIOR_PRICE_BY_REFERENCE_UNIT,
  52. ];
  53. }
  54. public static function getTypeExpirationDateChoices(): array
  55. {
  56. return [
  57. ProductFamilyModel::TYPE_EXPIRATION_DATE_DLC,
  58. ProductFamilyModel::TYPE_EXPIRATION_DATE_DDM,
  59. ProductFamilyModel::TYPE_EXPIRATION_DATE_DLUO,
  60. ];
  61. }
  62. public static function getBehaviorExpirationDateChoices(): array
  63. {
  64. return [
  65. ProductFamilyModel::BEHAVIOR_EXPIRATION_DATE_BY_PRODUCT_FAMILY,
  66. ProductFamilyModel::BEHAVIOR_EXPIRATION_DATE_BY_PRODUCT,
  67. ];
  68. }
  69. public static function getBehaviorDisplaySaleChoices(): array
  70. {
  71. return [
  72. ProductFamilyModel::BEHAVIOR_DISPLAY_SALE_BY_MEASURE,
  73. ProductFamilyModel::BEHAVIOR_DISPLAY_SALE_BY_QUANTITY,
  74. ];
  75. }
  76. public function countProductFamiliesOrganizedByParentCategory(array $categories): int
  77. {
  78. $count = 0;
  79. foreach ($categories as $category) {
  80. $count += count($category['products']);
  81. }
  82. return $count;
  83. }
  84. public function getAvailableQuantityInherited(ProductFamilyInterface $productFamily)
  85. {
  86. $availableQuantity = 0;
  87. switch ($productFamily->getBehaviorCountStock()) {
  88. case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE :
  89. case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY :
  90. $availableQuantity = $productFamily->getAvailableQuantity();
  91. break;
  92. case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT :
  93. foreach ($this->getProductsOnline($productFamily) as $product) {
  94. $availableQuantity += $this->productSolver->getAvailableQuantityInherited($product);
  95. }
  96. break;
  97. }
  98. return $availableQuantity;
  99. }
  100. public function getAvailableQuantitySupplierInherited(ProductFamilyInterface $productFamily)
  101. {
  102. $availableQuantity = 0;
  103. switch ($productFamily->getBehaviorCountStock()) {
  104. case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE :
  105. case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY :
  106. $availableQuantity = $productFamily->getAvailableQuantitySupplier();
  107. break;
  108. case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT :
  109. foreach ($this->getProductsOnline($productFamily) as $product) {
  110. $availableQuantity += $this->productSolver->getAvailableQuantitySupplierInherited($product);
  111. }
  112. break;
  113. }
  114. return $availableQuantity;
  115. }
  116. public function getTaxRateInherited(ProductPropertyInterface $productFamily)
  117. {
  118. if ($productFamily instanceof ProductInterface) {
  119. $productFamily = $productFamily->getProductFamily();
  120. }
  121. if ($productFamily->getTaxRate()) {
  122. return $productFamily->getTaxRate();
  123. } else {
  124. return $productFamily->getProductFamilySectionProperties()[0]->getSection()->getMerchant()->getTaxRate();
  125. }
  126. }
  127. public function getProductsOnline(ProductFamilyInterface $productFamily): Collection
  128. {
  129. $products = $productFamily->getProducts();
  130. $productsOnlineArray = new ArrayCollection();
  131. foreach ($products as $product) {
  132. if ($product->getStatus() == 1 && $product->getOriginProduct() != true) {
  133. $productsOnlineArray[] = $product;
  134. }
  135. }
  136. return $productsOnlineArray;
  137. }
  138. public function getReductionCatalogInherited(ProductFamilyInterface $productFamily): ?ReductionCatalogInterface
  139. {
  140. return $productFamily->getReductionCatalog();
  141. }
  142. public function getProductCategoryParent(ProductFamilyInterface $productFamily, SectionInterface $section)
  143. {
  144. $productCategories = $productFamily->getProductCategories();
  145. if (count($productCategories) > 0) {
  146. foreach ($productCategories as $productCategory) {
  147. if($productCategory->getSection()->getId() == $section->getId()
  148. && $productCategory->getParent() !== null) {
  149. return $productCategory->getParent();
  150. }
  151. }
  152. }
  153. return false;
  154. }
  155. public function getProductCategoryChild(ProductFamilyInterface $productFamily)
  156. {
  157. $productCategories = $productFamily->getProductCategories();
  158. foreach ($productCategories as $productCategory) {
  159. if ($productCategory->getParent()) {
  160. return $productCategory;
  161. }
  162. }
  163. return false;
  164. }
  165. public function isPropertyNoveltyOnline(ProductFamilyInterface $productFamily): ?bool
  166. {
  167. if ($productFamily->getPropertyNoveltyExpirationDate()) {
  168. $now = new \DateTime();
  169. if ($now <= $productFamily->getPropertyNoveltyExpirationDate()) {
  170. return true;
  171. }
  172. }
  173. return false;
  174. }
  175. public function countProperties(ProductFamilyInterface $productFamily): bool
  176. {
  177. $count = 0;
  178. $count += (int)strlen($productFamily->getPropertyOrganicLabel()) > 0;
  179. $count += (int)strlen($productFamily->getPropertyWeight()) > 0;
  180. $count += (int)strlen($productFamily->getPropertyFragrances()) > 0;
  181. $count += (int)strlen($productFamily->getPropertyComposition()) > 0;
  182. $count += (int)strlen($productFamily->getPropertyAllergens()) > 0;
  183. $count += (int)strlen($productFamily->getPropertyAlcoholLevel()) > 0;
  184. $count += (int)strlen($productFamily->getPropertyCharacteristics()) > 0;
  185. $count += (int)strlen($productFamily->getPropertyFeature()) > 0;
  186. $count += (int)strlen($productFamily->getPropertyPackaging()) > 0;
  187. $count += (int)strlen($productFamily->getPropertyQuantity()) > 0;
  188. $count += (int)strlen($productFamily->getPropertyVariety()) > 0;
  189. $count += (int)($productFamily->getPropertyExpirationDate() != null);
  190. return $count;
  191. }
  192. public function hasProductsWithVariousWeight(ProductFamilyInterface $productFamily)
  193. {
  194. if ($productFamily->getActiveProducts()) {
  195. $arrayCountProducts = [];
  196. $products = $this->getProductsOnline($productFamily);
  197. foreach ($products as $product) {
  198. $titleProduct = $this->productSolver->getTitleInherited($product);
  199. if (!isset($arrayCountProducts[$titleProduct])) {
  200. $arrayCountProducts[$titleProduct] = [];
  201. }
  202. if (!in_array(
  203. $this->productSolver->getQuantityLabelInherited($product),
  204. $arrayCountProducts[$titleProduct]
  205. )) {
  206. $arrayCountProducts[$titleProduct][] = $this->productSolver->getQuantityLabelInherited($product);
  207. }
  208. if (count($arrayCountProducts[$titleProduct]) > 1) {
  209. return true;
  210. }
  211. }
  212. }
  213. return false;
  214. }
  215. public function getProductsGroupByTitle(ProductFamilyInterface $productFamily): array
  216. {
  217. $arrayProductsGroupByTitle = [];
  218. $products = $this->getProductsOnline($productFamily);
  219. foreach ($products as $product) {
  220. if ($product->getStatus() == 1) {
  221. $titleProduct = $this->productSolver->getTitleInherited($product);
  222. if (!isset($arrayProductsGroupByTitle[$titleProduct])) {
  223. $arrayProductsGroupByTitle[$titleProduct] = [];
  224. }
  225. $arrayProductsGroupByTitle[$titleProduct][] = $product;
  226. }
  227. }
  228. return $arrayProductsGroupByTitle;
  229. }
  230. public function getQuantityTitle(ProductFamilyInterface $productFamily, ProductInterface $product)
  231. {
  232. $title = $this->productSolver->getQuantityLabelInherited($product);
  233. if ($this->hasProductsWithVariousWeight($productFamily)) {
  234. $title .= ', ' . $this->productSolver->getTitleInherited($product);
  235. }
  236. return $title;
  237. }
  238. public function getOriginProduct(ProductFamilyInterface $productFamily): ?ProductInterface
  239. {
  240. $products = $productFamily->getProducts();
  241. foreach ($products as $product) {
  242. if ($product->getOriginProduct()) {
  243. return $product;
  244. }
  245. }
  246. return null;
  247. }
  248. public function getOriginProductOnline(ProductFamilyInterface $productFamily): ?ProductInterface
  249. {
  250. $originProduct = $this->getOriginProduct($productFamily);
  251. if ($originProduct->getStatus() == 1) {
  252. return $originProduct;
  253. } else {
  254. return null;
  255. }
  256. }
  257. public function hasOneProductOnline(ProductFamilyInterface $productFamily)
  258. {
  259. if (($productFamily->getActiveProducts() && count($this->getProductsOnline($productFamily)) > 0)
  260. || (!$productFamily->getActiveProducts() && $this->getOriginProduct($productFamily))) {
  261. return true;
  262. }
  263. return false;
  264. }
  265. public function getFieldBuyingPrice(ProductFamilyInterface $productFamily): string
  266. {
  267. if ($productFamily->getBehaviorPrice() === ProductFamilyModel::BEHAVIOR_PRICE_BY_PIECE) {
  268. return 'buyingPrice';
  269. } elseif ($productFamily->getBehaviorPrice() === ProductFamilyModel::BEHAVIOR_PRICE_BY_REFERENCE_UNIT) {
  270. return 'buyingPriceByRefUnit';
  271. }
  272. }
  273. public function getFieldPrice(ProductFamilyInterface $productFamily): string
  274. {
  275. if ($productFamily->getBehaviorPrice() === ProductFamilyModel::BEHAVIOR_PRICE_BY_PIECE) {
  276. return 'price';
  277. } elseif ($productFamily->getBehaviorPrice() === ProductFamilyModel::BEHAVIOR_PRICE_BY_REFERENCE_UNIT) {
  278. return 'priceByRefUnit';
  279. }
  280. }
  281. public function getBehaviorPriceInherited(ProductFamilyInterface $productFamily): string
  282. {
  283. return $productFamily->getBehaviorPrice();
  284. }
  285. public function getBuyingPriceByRefUnitInherited(ProductFamilyInterface $productFamily): ?float
  286. {
  287. return $productFamily->getBuyingPriceByRefUnit();
  288. }
  289. public function getBuyingPriceInherited(ProductFamilyInterface $productFamily): ?float
  290. {
  291. return $productFamily->getBuyingPrice();
  292. }
  293. public function getPriceByRefUnitInherited(ProductFamilyInterface $productFamily): ?float
  294. {
  295. return $productFamily->getPriceByRefUnit();
  296. }
  297. public function getQuantityInherited(ProductFamilyInterface $productFamily): ?float
  298. {
  299. return $productFamily->getQuantity();
  300. }
  301. public function getUnitInherited(ProductFamilyInterface $productFamily)
  302. {
  303. return $productFamily->getUnit();
  304. }
  305. public function getPriceInherited(ProductFamilyInterface $productFamily)
  306. {
  307. return $productFamily->getPrice();
  308. }
  309. public function getSummaryQualityLabels(ProductFamilyInterface $productFamily): string
  310. {
  311. $strLabels = '';
  312. $qualityLabelArray = $productFamily->getQualityLabels()->toArray();
  313. foreach($qualityLabelArray as $index => $qualityLabel) {
  314. $strLabels .= $qualityLabel->getTitle();
  315. if ($index !== array_key_last($qualityLabelArray)) {
  316. $strLabels .= ', ';
  317. }
  318. }
  319. return $strLabels;
  320. }
  321. public function hasQualityLabel(ProductFamilyInterface $productFamily): bool
  322. {
  323. $qualityLabels = $productFamily->getQualityLabels();
  324. return $qualityLabels && count($qualityLabels) > 0;
  325. }
  326. public function getOrganicLabel(ProductFamilyInterface $productFamily)
  327. {
  328. return $this->getQualityLabelByArray($productFamily, ProductFamilyModel::$organicLabels);
  329. }
  330. public function getGeographicLabel(ProductFamilyInterface $productFamily)
  331. {
  332. return $this->getQualityLabelByArray($productFamily, ProductFamilyModel::$geographicLabels);
  333. }
  334. public function getQualityLabelByArray(ProductFamilyInterface $productFamily, array $labelArray)
  335. {
  336. $qualityLabelArray = $productFamily->getQualityLabels();
  337. foreach ($qualityLabelArray as $qualityLabel) {
  338. if (in_array($qualityLabel->getDevAlias(), $labelArray)) {
  339. return $qualityLabel;
  340. }
  341. }
  342. return false;
  343. }
  344. public function hasOrganicLabel(ProductFamilyInterface $productFamily)
  345. {
  346. return $this->hasQualityLabelByArray($productFamily, ProductFamilyModel::$organicLabels);
  347. }
  348. public function hasGeographicLabel(ProductFamilyInterface $productFamily)
  349. {
  350. return $this->hasQualityLabelByArray($productFamily, ProductFamilyModel::$geographicLabels);
  351. }
  352. public function hasQualityLabelByArray(ProductFamilyInterface $productFamily, array $labelArray)
  353. {
  354. $qualityLabelArray = $productFamily->getQualityLabels();
  355. foreach ($qualityLabelArray as $qualityLabel) {
  356. if (in_array($qualityLabel->getDevAlias(), $labelArray)) {
  357. return true;
  358. }
  359. }
  360. return false;
  361. }
  362. public function getSection(ProductFamilyInterface $productFamily): ?SectionInterface
  363. {
  364. foreach ($productFamily->getProductFamilySectionProperties() as $productFamilySectionProperty) {
  365. if ($productFamilySectionProperty->getStatus()) {
  366. return $productFamilySectionProperty->getSection();
  367. }
  368. }
  369. return null;
  370. }
  371. public function isInSection(ProductFamilyInterface $productFamily, SectionInterface $section): bool
  372. {
  373. foreach ($productFamily->getProductFamilySectionProperties() as $productFamilySectionProperty) {
  374. if ($productFamilySectionProperty->getSection()->getId() == $section->getId(
  375. ) && $productFamilySectionProperty->getStatus()) {
  376. return true;
  377. }
  378. }
  379. return false;
  380. }
  381. public function isCategoriesOnlineInSection(ProductFamilyInterface $productFamily, SectionInterface $section):bool
  382. {
  383. $isCategoriesOnlineInSection =false;
  384. foreach ($productFamily->getProductCategories() as $productCatgory){
  385. if($productCatgory->getSection() === $section && $this->productCategorySolver->isOnline($productCatgory)){
  386. $isCategoriesOnlineInSection = true;
  387. }
  388. }
  389. return $isCategoriesOnlineInSection;
  390. }
  391. }