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.

538 lines
18KB

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