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.

512 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. if($productFamily->getQuantity()){
  300. return $productFamily->getQuantity();
  301. }else{
  302. return 1;
  303. }
  304. }
  305. public function getUnitInherited(ProductFamilyInterface $productFamily)
  306. {
  307. return $productFamily->getUnit();
  308. }
  309. public function getPriceInherited(ProductFamilyInterface $productFamily)
  310. {
  311. return $productFamily->getPrice();
  312. }
  313. public function getSummaryQualityLabels(ProductFamilyInterface $productFamily): string
  314. {
  315. $strLabels = '';
  316. $qualityLabelArray = $productFamily->getQualityLabels()->toArray();
  317. foreach($qualityLabelArray as $index => $qualityLabel) {
  318. $strLabels .= $qualityLabel->getTitle();
  319. if ($index !== array_key_last($qualityLabelArray)) {
  320. $strLabels .= ', ';
  321. }
  322. }
  323. return $strLabels;
  324. }
  325. public function hasQualityLabel(ProductFamilyInterface $productFamily): bool
  326. {
  327. $qualityLabels = $productFamily->getQualityLabels();
  328. return $qualityLabels && count($qualityLabels) > 0;
  329. }
  330. public function getOrganicLabel(ProductFamilyInterface $productFamily)
  331. {
  332. return $this->getQualityLabelByArray($productFamily, ProductFamilyModel::$organicLabels);
  333. }
  334. public function getGeographicLabel(ProductFamilyInterface $productFamily)
  335. {
  336. return $this->getQualityLabelByArray($productFamily, ProductFamilyModel::$geographicLabels);
  337. }
  338. public function getQualityLabelByArray(ProductFamilyInterface $productFamily, array $labelArray)
  339. {
  340. $qualityLabelArray = $productFamily->getQualityLabels();
  341. foreach ($qualityLabelArray as $qualityLabel) {
  342. if (in_array($qualityLabel->getDevAlias(), $labelArray)) {
  343. return $qualityLabel;
  344. }
  345. }
  346. return false;
  347. }
  348. public function hasOrganicLabel(ProductFamilyInterface $productFamily)
  349. {
  350. return $this->hasQualityLabelByArray($productFamily, ProductFamilyModel::$organicLabels);
  351. }
  352. public function hasGeographicLabel(ProductFamilyInterface $productFamily)
  353. {
  354. return $this->hasQualityLabelByArray($productFamily, ProductFamilyModel::$geographicLabels);
  355. }
  356. public function hasQualityLabelByArray(ProductFamilyInterface $productFamily, array $labelArray)
  357. {
  358. $qualityLabelArray = $productFamily->getQualityLabels();
  359. foreach ($qualityLabelArray as $qualityLabel) {
  360. if (in_array($qualityLabel->getDevAlias(), $labelArray)) {
  361. return true;
  362. }
  363. }
  364. return false;
  365. }
  366. public function getSection(ProductFamilyInterface $productFamily): ?SectionInterface
  367. {
  368. foreach ($productFamily->getProductFamilySectionProperties() as $productFamilySectionProperty) {
  369. if ($productFamilySectionProperty->getStatus()) {
  370. return $productFamilySectionProperty->getSection();
  371. }
  372. }
  373. return null;
  374. }
  375. public function isInSection(ProductFamilyInterface $productFamily, SectionInterface $section): bool
  376. {
  377. foreach ($productFamily->getProductFamilySectionProperties() as $productFamilySectionProperty) {
  378. if ($productFamilySectionProperty->getSection()->getId() == $section->getId(
  379. ) && $productFamilySectionProperty->getStatus()) {
  380. return true;
  381. }
  382. }
  383. return false;
  384. }
  385. public function isCategoriesOnlineInSection(ProductFamilyInterface $productFamily, SectionInterface $section):bool
  386. {
  387. $isCategoriesOnlineInSection =false;
  388. foreach ($productFamily->getProductCategories() as $productCatgory){
  389. if($productCatgory->getSection() === $section && $this->productCategorySolver->isOnline($productCatgory)){
  390. $isCategoriesOnlineInSection = true;
  391. }
  392. }
  393. return $isCategoriesOnlineInSection;
  394. }
  395. public function getTitleProduct(ProductInterface $product)
  396. {
  397. $productFamily = $product->getProductFamily();
  398. $title = $product->getProductFamily()->getTitle();
  399. if ($product->getTitle() && strlen($product->getTitle())) {
  400. $title .= ' - ' . $product->getTitle();
  401. }
  402. if ($this->hasProductsWithVariousWeight($productFamily)) {
  403. $title .= ' - ' . $this->productSolver->getQuantityLabelInherited($product);
  404. }
  405. return $title;
  406. }
  407. }