Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

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