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.

ProductFamilySolver.php 17KB

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