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.

653 lines
18KB

  1. <?php
  2. namespace Lc\ShopBundle\Model;
  3. use Doctrine\Common\Collections\ArrayCollection;
  4. use Doctrine\Common\Collections\Collection;
  5. use Doctrine\ORM\Mapping as ORM;
  6. use Lc\ShopBundle\Context\FilterMerchantInterface;
  7. use Lc\ShopBundle\Context\PriceInterface;
  8. use Lc\ShopBundle\Context\ProductInterface;
  9. use Lc\ShopBundle\Context\ProductPropertyInterface;
  10. /**
  11. * @ORM\MappedSuperclass()
  12. */
  13. abstract class ProductFamily extends AbstractDocumentEntity implements ProductPropertyInterface, PriceInterface, FilterMerchantInterface
  14. {
  15. use ProductPropertyTrait;
  16. //Champ hydraté par ProductFamilyUtils
  17. protected $reductionCatalog;
  18. /**
  19. * @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\MerchantInterface", inversedBy="productFamilies")
  20. * @ORM\JoinColumn(nullable=false)
  21. */
  22. protected $merchant;
  23. /**
  24. * @ORM\ManyToMany(targetEntity="Lc\ShopBundle\Context\ProductCategoryInterface", inversedBy="productFamilies")
  25. */
  26. protected $productCategories;
  27. /**
  28. * @ORM\Column(type="boolean")
  29. */
  30. protected $activeProducts;
  31. /**
  32. * @ORM\Column(type="string", length=255, nullable=true)
  33. */
  34. protected $productsType;
  35. /**
  36. * @ORM\OneToMany(targetEntity="Lc\ShopBundle\Context\ProductInterface", mappedBy="productFamily", orphanRemoval=true, cascade={"persist"}, fetch="EAGER")
  37. */
  38. protected $products;
  39. /**
  40. * @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\TaxRateInterface")
  41. */
  42. protected $supplierTaxRate;
  43. /**
  44. * @ORM\Column(type="string", length=255, nullable=true)
  45. */
  46. protected $subtitle;
  47. /**
  48. * @ORM\Column(type="text", nullable=true)
  49. */
  50. protected $warningMessage;
  51. /**
  52. * @ORM\Column(type="string", length=255, nullable=true)
  53. */
  54. private $warningMessageType;
  55. /**
  56. * @ORM\Column(type="text", nullable=true)
  57. */
  58. protected $note;
  59. /**
  60. * @ORM\Column(type="string", length=31, nullable=true)
  61. */
  62. protected $behaviorOutOfStock;
  63. /**
  64. * @ORM\Column(type="string", length=31)
  65. */
  66. protected $behaviorCountStock;
  67. /**
  68. * @ORM\Column(type="date", nullable=true)
  69. */
  70. protected $propertyNoveltyExpirationDate;
  71. /**
  72. * @ORM\Column(type="string", length=255, nullable=true)
  73. */
  74. protected $propertyOrganicLabel;
  75. /**
  76. * @ORM\Column(type="text", nullable=true)
  77. */
  78. protected $propertyAllergens;
  79. /**
  80. * @ORM\Column(type="text", nullable=true)
  81. */
  82. protected $propertyComposition;
  83. /**
  84. * @ORM\Column(type="text", nullable=true)
  85. */
  86. protected $propertyFragrances;
  87. /**
  88. * @ORM\Column(type="text", nullable=true)
  89. */
  90. protected $propertyWeightQuantity;
  91. /**
  92. * @ORM\Column(type="text", nullable=true)
  93. */
  94. protected $propertyPackaging;
  95. /**
  96. * @ORM\Column(type="text", nullable=true)
  97. */
  98. protected $propertyCharacteristics;
  99. /**
  100. * @ORM\Column(type="string", length=255, nullable=true)
  101. */
  102. protected $behaviorExpirationDate;
  103. /**
  104. * @ORM\Column(type="string", length=255, nullable=true)
  105. */
  106. protected $typeExpirationDate;
  107. /**
  108. * @ORM\Column(type="string", length=32, nullable=true)
  109. */
  110. protected $behaviorAddToCart;
  111. /**
  112. * @ORM\Column(type="string", length=31)
  113. */
  114. protected $behaviorBuyingPrice;
  115. /**
  116. * @ORM\Column(type="boolean")
  117. */
  118. protected $displayPriceByRefUnit;
  119. public function __construct()
  120. {
  121. $this->productCategories = new ArrayCollection();
  122. $this->products = new ArrayCollection();
  123. }
  124. public function __toString()
  125. {
  126. return $this->getTitle();
  127. }
  128. public function getTaxRateInherited()
  129. {
  130. if ($this->getTaxRate()) {
  131. return $this->getTaxRate();
  132. } else {
  133. return $this->getMerchant()->getTaxRate();
  134. }
  135. }
  136. public function getMerchant(): ?Merchant
  137. {
  138. return $this->merchant;
  139. }
  140. public function setMerchant(?Merchant $merchant): self
  141. {
  142. $this->merchant = $merchant;
  143. return $this;
  144. }
  145. public function getActiveProducts(): ?bool
  146. {
  147. return $this->activeProducts;
  148. }
  149. public function setActiveProducts(bool $activeProducts): self
  150. {
  151. $this->activeProducts = $activeProducts;
  152. return $this;
  153. }
  154. public function getProductsType(): ?string
  155. {
  156. return $this->productsType;
  157. }
  158. public function setProductsType(?string $productsType): self
  159. {
  160. $this->productsType = $productsType;
  161. return $this;
  162. }
  163. /**
  164. * @return Collection|ProductInterface[]
  165. */
  166. public function getProducts(): Collection
  167. {
  168. return $this->products;
  169. }
  170. public function addProduct(ProductInterface $product): self
  171. {
  172. if (!$this->products->contains($product)) {
  173. $this->products[] = $product;
  174. $product->setProductFamily($this);
  175. }
  176. return $this;
  177. }
  178. public function removeProduct(ProductInterface $product): self
  179. {
  180. if ($this->products->contains($product)) {
  181. $this->products->removeElement($product);
  182. // set the owning side to null (unless already changed)
  183. if ($product->getProductFamily() === $this) {
  184. $product->setProductFamily(null);
  185. }
  186. }
  187. return $this;
  188. }
  189. public function getReductionCatalog(): ?ReductionCatalog
  190. {
  191. return $this->reductionCatalog;
  192. }
  193. public function setReductionCatalog(?ReductionCatalog $reductionCatalog): self
  194. {
  195. $this->reductionCatalog = $reductionCatalog;
  196. return $this;
  197. }
  198. /**
  199. * @return Collection|ProductCategory[]
  200. */
  201. public function getProductCategories(): Collection
  202. {
  203. return $this->productCategories;
  204. }
  205. public function initProductCategories()
  206. {
  207. $this->productCategories = new ArrayCollection();
  208. }
  209. public function addProductCategory(ProductCategory $productCategory): self
  210. {
  211. if (!$this->productCategories->contains($productCategory)) {
  212. $this->productCategories[] = $productCategory;
  213. }
  214. return $this;
  215. }
  216. public function removeProductCategory(ProductCategory $productCategory): self
  217. {
  218. if ($this->productCategories->contains($productCategory)) {
  219. $this->productCategories->removeElement($productCategory);
  220. }
  221. return $this;
  222. }
  223. public function getProductCategoryParent()
  224. {
  225. $productCategories = $this->getProductCategories();
  226. if (count($productCategories) > 0) {
  227. return $productCategories[0]->getParent();
  228. }
  229. return false;
  230. }
  231. public function getProductCategoryChild()
  232. {
  233. $productCategories = $this->getProductCategories();
  234. foreach ($productCategories as $productCategory) {
  235. if ($productCategory->getParent()) {
  236. return $productCategory;
  237. }
  238. }
  239. return false;
  240. }
  241. public function getSupplierTaxRate(): ?TaxRate
  242. {
  243. return $this->supplierTaxRate;
  244. }
  245. public function setSupplierTaxRate(?TaxRate $supplierTaxRate): self
  246. {
  247. $this->supplierTaxRate = $supplierTaxRate;
  248. return $this;
  249. }
  250. public function getSubtitle(): ?string
  251. {
  252. return $this->subtitle;
  253. }
  254. public function setSubtitle(?string $subtitle): self
  255. {
  256. $this->subtitle = $subtitle;
  257. return $this;
  258. }
  259. public function getWarningMessage(): ?string
  260. {
  261. return $this->warningMessage;
  262. }
  263. public function setWarningMessage(?string $warningMessage): self
  264. {
  265. $this->warningMessage = $warningMessage;
  266. return $this;
  267. }
  268. public function getWarningMessageType(): ?string
  269. {
  270. return $this->warningMessageType;
  271. }
  272. public function setWarningMessageType(?string $warningMessageType): self
  273. {
  274. $this->warningMessageType = $warningMessageType;
  275. return $this;
  276. }
  277. public function getNote(): ?string
  278. {
  279. return $this->note;
  280. }
  281. public function setNote(?string $note): self
  282. {
  283. $this->note = $note;
  284. return $this;
  285. }
  286. public function getBehaviorOutOfStock(): ?string
  287. {
  288. return $this->behaviorOutOfStock;
  289. }
  290. public function setBehaviorOutOfStock(?string $behaviorOutOfStock): self
  291. {
  292. $this->behaviorOutOfStock = $behaviorOutOfStock;
  293. return $this;
  294. }
  295. public function getBehaviorCountStock(): ?string
  296. {
  297. return $this->behaviorCountStock;
  298. }
  299. public function setBehaviorCountStock(string $behaviorCountStock): self
  300. {
  301. $this->behaviorCountStock = $behaviorCountStock;
  302. return $this;
  303. }
  304. private function getCheapestOrMostExpensiveProduct($comparisonFunction, $returnSelfIfNotActiveProducts)
  305. {
  306. $products = $this->getProducts()->getValues();
  307. if (count($products) > 0) {
  308. usort($products, $comparisonFunction);
  309. return $products[0];
  310. }
  311. if ($returnSelfIfNotActiveProducts) {
  312. return $this;
  313. } else {
  314. return false;
  315. }
  316. }
  317. public function getCheapestProduct()
  318. {
  319. return $this->getCheapestOrMostExpensiveProduct(function ($a, $b) {
  320. return $a->getPriceInherited() > $b->getPriceInherited();
  321. }, true);
  322. }
  323. public function getCheapestProductByUnitRef()
  324. {
  325. return $this->getCheapestOrMostExpensiveProduct(function ($a, $b) {
  326. return $a->getPriceByUnitRef() > $b->getPriceByUnitRef();
  327. }, false);
  328. }
  329. public function getMostExpensiveProductByUnitRef()
  330. {
  331. return $this->getCheapestOrMostExpensiveProduct(function ($a, $b) {
  332. return $a->getPriceByUnitRef() < $b->getPriceByUnitRef();
  333. }, false);
  334. }
  335. public function isPropertyNoveltyOnline(): ?bool
  336. {
  337. if ($this->getPropertyNoveltyExpirationDate()) {
  338. $now = new \DateTime();
  339. if ($now <= $this->getPropertyNoveltyExpirationDate()) {
  340. return true;
  341. }
  342. }
  343. return false;
  344. }
  345. public function getPropertyNoveltyExpirationDate(): ?\DateTimeInterface
  346. {
  347. return $this->propertyNoveltyExpirationDate;
  348. }
  349. public function setPropertyNoveltyExpirationDate(?\DateTimeInterface $propertyNoveltyExpirationDate): self
  350. {
  351. $this->propertyNoveltyExpirationDate = $propertyNoveltyExpirationDate;
  352. return $this;
  353. }
  354. public function getPropertyOrganicLabel(): ?string
  355. {
  356. return $this->propertyOrganicLabel;
  357. }
  358. public function setPropertyOrganicLabel(?string $propertyOrganicLabel): self
  359. {
  360. $this->propertyOrganicLabel = $propertyOrganicLabel;
  361. return $this;
  362. }
  363. public function getPropertyAllergens(): ?string
  364. {
  365. return $this->propertyAllergens;
  366. }
  367. public function setPropertyAllergens(?string $propertyAllergens): self
  368. {
  369. $this->propertyAllergens = $propertyAllergens;
  370. return $this;
  371. }
  372. public function getPropertyComposition(): ?string
  373. {
  374. return $this->propertyComposition;
  375. }
  376. public function setPropertyComposition(?string $propertyComposition): self
  377. {
  378. $this->propertyComposition = $propertyComposition;
  379. return $this;
  380. }
  381. public function getPropertyFragrances(): ?string
  382. {
  383. return $this->propertyFragrances;
  384. }
  385. public function setPropertyFragrances(?string $propertyFragrances): self
  386. {
  387. $this->propertyFragrances = $propertyFragrances;
  388. return $this;
  389. }
  390. public function countProperties(): bool
  391. {
  392. $count = 0;
  393. $count += (int)strlen($this->getPropertyAllergens()) > 0;
  394. $count += (int)strlen($this->getPropertyComposition()) > 0;
  395. $count += (int)strlen($this->getPropertyFragrances()) > 0;
  396. $count += (int)strlen($this->getPropertyOrganicLabel()) > 0;
  397. $count += (int)($this->getPropertyExpirationDate() != null);
  398. return $count;
  399. }
  400. public function getBehaviorExpirationDate(): ?string
  401. {
  402. return $this->behaviorExpirationDate;
  403. }
  404. public function setBehaviorExpirationDate(?string $behaviorExpirationDate): self
  405. {
  406. $this->behaviorExpirationDate = $behaviorExpirationDate;
  407. return $this;
  408. }
  409. public function getTypeExpirationDate(): ?string
  410. {
  411. return $this->typeExpirationDate;
  412. }
  413. public function setTypeExpirationDate(?string $typeExpirationDate): self
  414. {
  415. $this->typeExpirationDate = $typeExpirationDate;
  416. return $this;
  417. }
  418. public function getPropertyWeightQuantity(): ?string
  419. {
  420. return $this->propertyWeightQuantity;
  421. }
  422. public function setPropertyWeightQuantity(?string $propertyWeightQuantity): self
  423. {
  424. $this->propertyWeightQuantity = $propertyWeightQuantity;
  425. return $this;
  426. }
  427. public function getPropertyPackaging(): ?string
  428. {
  429. return $this->propertyPackaging;
  430. }
  431. public function setPropertyPackaging(?string $propertyPackaging): self
  432. {
  433. $this->propertyPackaging = $propertyPackaging;
  434. return $this;
  435. }
  436. public function getPropertyCharacteristics(): ?string
  437. {
  438. return $this->propertyCharacteristics;
  439. }
  440. public function setPropertyCharacteristics(?string $propertyCharacteristics): self
  441. {
  442. $this->propertyCharacteristics = $propertyCharacteristics;
  443. return $this;
  444. }
  445. public function getBehaviorAddToCart(): ?string
  446. {
  447. return $this->behaviorAddToCart;
  448. }
  449. public function setBehaviorAddToCart(?string $behaviorAddToCart): self
  450. {
  451. $this->behaviorAddToCart = $behaviorAddToCart;
  452. return $this;
  453. }
  454. public function getBehaviorBuyingPrice(): ?string
  455. {
  456. return $this->behaviorBuyingPrice;
  457. }
  458. public function setBehaviorBuyingPrice(?string $behaviorBuyingPrice): self
  459. {
  460. $this->behaviorBuyingPrice = $behaviorBuyingPrice;
  461. return $this;
  462. }
  463. public function getDisplayPriceByRefUnit(): ?bool
  464. {
  465. return $this->displayPriceByRefUnit;
  466. }
  467. public function setDisplayPriceByRefUnit(?bool $displayPriceByRefUnit): self
  468. {
  469. $this->displayPriceByRefUnit = $displayPriceByRefUnit;
  470. return $this;
  471. }
  472. public function hasProductsWithVariousWeight()
  473. {
  474. if ($this->getActiveProducts()) {
  475. $arrayCountProducts = [];
  476. $products = $this->getProducts();
  477. foreach ($products as $product) {
  478. $titleProduct = $product->getTitleInherited();
  479. if (!isset($arrayCountProducts[$titleProduct])) {
  480. $arrayCountProducts[$titleProduct] = [];
  481. }
  482. if (!in_array($product->getQuantityLabelInherited(), $arrayCountProducts[$titleProduct])) {
  483. $arrayCountProducts[$titleProduct][] = $product->getQuantityLabelInherited();
  484. }
  485. if (count($arrayCountProducts[$titleProduct]) > 1) {
  486. return true;
  487. }
  488. }
  489. }
  490. return false;
  491. }
  492. public function getProductsGroupByTitle()
  493. {
  494. $arrayProductsGroupByTitle = [];
  495. $products = $this->getProducts();
  496. foreach ($products as $product) {
  497. $titleProduct = $product->getTitleInherited();
  498. if (!isset($arrayProductsGroupByTitle[$titleProduct])) {
  499. $arrayProductsGroupByTitle[$titleProduct] = [];
  500. }
  501. $arrayProductsGroupByTitle[$titleProduct][] = $product;
  502. }
  503. return $arrayProductsGroupByTitle;
  504. }
  505. }