src/Entity/Product.php line 763

Open in your IDE?
  1. <?php
  2. namespace App\Entity;
  3. use App\Entity\ProductDescription;
  4. use App\Entity\ProductModel;
  5. use Doctrine\ORM\Mapping as ORM;
  6. use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
  7. use App\Helpers\Encoder;
  8. /**
  9. * Products
  10. *
  11. * @ORM\Table(name="products", indexes={
  12. * @ORM\Index(name="IDX_PRODUCTS_MODEL_SAP", columns={"products_model_sap"}),
  13. * @ORM\Index(name="IDX_PRODUCTS_MODEL", columns={"products_model"}, options={"lengths": {191}})
  14. * })
  15. * @ORM\Entity(repositoryClass="App\Repository\ProductRepository")
  16. * @ORM\HasLifecycleCallbacks()
  17. */
  18. class Product extends TranslatedEntity
  19. {
  20. public const VAT_RATE = 0.2;
  21. public const SEARCH_INDICES = [
  22. 'fr' => 'fr-products',
  23. 'en' => 'en-products',
  24. ];
  25. public const TYPE_PRODUCT = 'product';
  26. public const TYPE_SAV = 'sav';
  27. protected $tranlatedEntity = 'ProductDescription';
  28. /**
  29. * @var int
  30. *
  31. * @ORM\Column(name="products_id", type="integer", nullable=false)
  32. * @ORM\Id
  33. * @ORM\GeneratedValue(strategy="IDENTITY")
  34. */
  35. private $id;
  36. /**
  37. * @ORM\OneToMany(targetEntity="App\Entity\ProductAttribute", mappedBy="product")
  38. */
  39. private $attributes;
  40. /**
  41. * @ORM\OneToMany(targetEntity="App\Entity\Product", mappedBy="parent")
  42. */
  43. private $children = [];
  44. /**
  45. * @ORM\ManyToOne(targetEntity="App\Entity\Product", inversedBy="children")
  46. * @ORM\JoinColumn(name="products_parent_id", referencedColumnName="products_id", nullable=true)
  47. */
  48. private $parent;
  49. /**
  50. * @var ?ProductModel
  51. *
  52. * @ORM\ManyToOne(targetEntity="App\Entity\ProductModel", inversedBy="products")
  53. * @ORM\JoinColumn(name="products_model_id", referencedColumnName="id", nullable=true)
  54. */
  55. private $productModel;
  56. /**
  57. * @ORM\OneToMany(targetEntity="App\Entity\ProductDescription", mappedBy="product")
  58. */
  59. private $descriptions = [];
  60. /**
  61. * @ORM\OneToMany(targetEntity="App\Entity\PictureProduct", mappedBy="product")
  62. * @ORM\OrderBy({"rank" = "ASC", "id" = "ASC"})
  63. */
  64. private $pictures = [];
  65. /**
  66. * @var App\Entity\Manufacturer|null
  67. *
  68. * @ORM\ManyToOne(targetEntity="App\Entity\Manufacturer")
  69. * @ORM\JoinColumn(name="manufacturers_id", referencedColumnName="manufacturers_id", nullable=true)
  70. */
  71. private $manufacturer;
  72. /**
  73. * @ORM\OneToMany(targetEntity="App\Entity\ProductCountryRestriction", mappedBy="product")
  74. */
  75. private $countryRestrictions;
  76. /**
  77. * @ORM\OneToMany(targetEntity="App\Entity\ProductToProductExtraField", mappedBy="product")
  78. */
  79. private $extraFields = [];
  80. /**
  81. * @ORM\OneToMany(targetEntity="App\Entity\ProductPrice", mappedBy="product", cascade={"persist", "remove"}, orphanRemoval=true)
  82. */
  83. private $prices = [];
  84. /**
  85. * @var int
  86. *
  87. * @ORM\Column(name="products_quantity", type="integer", nullable=false)
  88. */
  89. private $quantity = '0';
  90. /**
  91. * @var string|null
  92. *
  93. * @ORM\Column(name="products_model", type="string", length=256, nullable=true)
  94. */
  95. private $model;
  96. /**
  97. * @var string|null
  98. *
  99. * @ORM\Column(name="products_model_sap", type="string", length=50, nullable=true)
  100. */
  101. private $modelSAP;
  102. /**
  103. * @var string|null
  104. *
  105. * @ORM\Column(name="products_ean", type="string", length=50, nullable=true)
  106. */
  107. private $ean;
  108. /**
  109. * @var string|null
  110. *
  111. * @ORM\Column(name="products_image", type="string", length=140, nullable=true)
  112. */
  113. private $image;
  114. /**
  115. * @var string|null
  116. *
  117. * @ORM\Column(name="products_image_med", type="string", length=140, nullable=true)
  118. */
  119. private $imageMed;
  120. /**
  121. * @var string|null
  122. *
  123. * @ORM\Column(name="products_image_lrg", type="string", length=140, nullable=true)
  124. */
  125. private $imageLrg;
  126. /**
  127. * @var string|null
  128. *
  129. * @ORM\Column(name="products_image_sm_1", type="string", length=140, nullable=true)
  130. */
  131. private $imageSm1;
  132. /**
  133. * @var string|null
  134. *
  135. * @ORM\Column(name="products_image_xl_1", type="string", length=140, nullable=true)
  136. */
  137. private $imageXl1;
  138. /**
  139. * @var string|null
  140. *
  141. * @ORM\Column(name="products_image_sm_2", type="string", length=140, nullable=true)
  142. */
  143. private $imageSm2;
  144. /**
  145. * @var string|null
  146. *
  147. * @ORM\Column(name="products_image_xl_2", type="string", length=140, nullable=true)
  148. */
  149. private $imageXl2;
  150. /**
  151. * @var string|null
  152. *
  153. * @ORM\Column(name="products_image_sm_3", type="string", length=140, nullable=true)
  154. */
  155. private $imageSm3;
  156. /**
  157. * @var string|null
  158. *
  159. * @ORM\Column(name="products_image_xl_3", type="string", length=140, nullable=true)
  160. */
  161. private $imageXl3;
  162. /**
  163. * @var string|null
  164. *
  165. * @ORM\Column(name="products_image_sm_4", type="string", length=140, nullable=true)
  166. */
  167. private $imageSm4;
  168. /**
  169. * @var string|null
  170. *
  171. * @ORM\Column(name="products_image_xl_4", type="string", length=140, nullable=true)
  172. */
  173. private $imageXl4;
  174. /**
  175. * @var string|null
  176. *
  177. * @ORM\Column(name="products_image_sm_5", type="string", length=140, nullable=true)
  178. */
  179. private $imageSm5;
  180. /**
  181. * @var string|null
  182. *
  183. * @ORM\Column(name="products_image_xl_5", type="string", length=140, nullable=true)
  184. */
  185. private $imageXl5;
  186. /**
  187. * @var string|null
  188. *
  189. * @ORM\Column(name="products_image_sm_6", type="string", length=140, nullable=true)
  190. */
  191. private $imageSm6;
  192. /**
  193. * @var string|null
  194. *
  195. * @ORM\Column(name="products_image_xl_6", type="string", length=140, nullable=true)
  196. */
  197. private $imageXl6;
  198. /**
  199. * @var float
  200. *
  201. * @ORM\Column(name="products_price", type="decimal", precision=15, scale=4, nullable=false, options={"default"="0.0000"})
  202. */
  203. private $price = '0.0000';
  204. /**
  205. * @var float
  206. * @ORM\Column(name="products_ecotax", type="decimal", precision=15, scale=4, nullable=false, options={"default"="0.0000"})
  207. */
  208. private $ecotax = '0.0000';
  209. /**
  210. * @var \DateTime
  211. *
  212. * @ORM\Column(name="products_date_added", type="datetime", nullable=false)
  213. */
  214. private $dateAdded;
  215. /**
  216. * @var \DateTime|null
  217. *
  218. * @ORM\Column(name="products_last_modified", type="datetime", nullable=true)
  219. */
  220. private $lastModified;
  221. /**
  222. * @var \DateTime|null
  223. *
  224. * @ORM\Column(name="products_date_available", type="datetime", nullable=true)
  225. */
  226. private $dateAvailable;
  227. /**
  228. * @var string
  229. *
  230. * @ORM\Column(name="products_weight", type="decimal", precision=5, scale=2, nullable=false, options={"default"="0.00"})
  231. */
  232. private $weight = '0.00';
  233. /**
  234. * @var bool
  235. *
  236. * @ORM\Column(name="products_status", type="boolean", nullable=false)
  237. */
  238. private $status = '0';
  239. /** *
  240. * @ORM\ManyToOne(targetEntity="App\Entity\TaxClass", inversedBy="rates")
  241. * @ORM\JoinColumn(name="products_tax_class_id", referencedColumnName="tax_class_id")
  242. */
  243. private $taxClass;
  244. /**
  245. * @var int
  246. *
  247. * @ORM\Column(name="products_ordered", type="integer", nullable=false)
  248. */
  249. private $ordered = '0';
  250. /**
  251. * @var string
  252. *
  253. * @ORM\Column(name="products_price1", type="decimal", precision=15, scale=4, nullable=false, options={"default"="0.0000"})
  254. */
  255. private $price1 = '0.0000';
  256. /**
  257. * @var string
  258. *
  259. * @ORM\Column(name="products_price2", type="decimal", precision=15, scale=4, nullable=false, options={"default"="0.0000"})
  260. */
  261. private $price2 = '0.0000';
  262. /**
  263. * @var string
  264. *
  265. * @ORM\Column(name="products_price3", type="decimal", precision=15, scale=4, nullable=false, options={"default"="0.0000"})
  266. */
  267. private $price3 = '0.0000';
  268. /**
  269. * @var string
  270. *
  271. * @ORM\Column(name="products_price4", type="decimal", precision=15, scale=4, nullable=false, options={"default"="0.0000"})
  272. */
  273. private $price4 = '0.0000';
  274. /**
  275. * @var string
  276. *
  277. * @ORM\Column(name="products_price5", type="decimal", precision=15, scale=4, nullable=false, options={"default"="0.0000"})
  278. */
  279. private $price5 = '0.0000';
  280. /**
  281. * @var string
  282. *
  283. * @ORM\Column(name="products_price6", type="decimal", precision=15, scale=4, nullable=false, options={"default"="0.0000"})
  284. */
  285. private $price6 = '0.0000';
  286. /**
  287. * @var string
  288. *
  289. * @ORM\Column(name="products_price7", type="decimal", precision=15, scale=4, nullable=false, options={"default"="0.0000"})
  290. */
  291. private $price7 = '0.0000';
  292. /**
  293. * @var string
  294. *
  295. * @ORM\Column(name="products_price8", type="decimal", precision=15, scale=4, nullable=false, options={"default"="0.0000"})
  296. */
  297. private $price8 = '0.0000';
  298. /**
  299. * @var string
  300. *
  301. * @ORM\Column(name="products_price9", type="decimal", precision=15, scale=4, nullable=false, options={"default"="0.0000"})
  302. */
  303. private $price9 = '0.0000';
  304. /**
  305. * @var string
  306. *
  307. * @ORM\Column(name="products_price10", type="decimal", precision=15, scale=4, nullable=false, options={"default"="0.0000"})
  308. */
  309. private $price10 = '0.0000';
  310. /**
  311. * @var string
  312. *
  313. * @ORM\Column(name="products_price11", type="decimal", precision=15, scale=4, nullable=false, options={"default"="0.0000"})
  314. */
  315. private $price11 = '0.0000';
  316. /**
  317. * @var int
  318. *
  319. * @ORM\Column(name="products_price1_qty", type="integer", nullable=false)
  320. */
  321. private $price1Qty = '0';
  322. /**
  323. * @var int
  324. *
  325. * @ORM\Column(name="products_price2_qty", type="integer", nullable=false)
  326. */
  327. private $price2Qty = '0';
  328. /**
  329. * @var int
  330. *
  331. * @ORM\Column(name="products_price3_qty", type="integer", nullable=false)
  332. */
  333. private $price3Qty = '0';
  334. /**
  335. * @var int
  336. *
  337. * @ORM\Column(name="products_price4_qty", type="integer", nullable=false)
  338. */
  339. private $price4Qty = '0';
  340. /**
  341. * @var int
  342. *
  343. * @ORM\Column(name="products_price5_qty", type="integer", nullable=false)
  344. */
  345. private $price5Qty = '0';
  346. /**
  347. * @var int
  348. *
  349. * @ORM\Column(name="products_price6_qty", type="integer", nullable=false)
  350. */
  351. private $price6Qty = '0';
  352. /**
  353. * @var int
  354. *
  355. * @ORM\Column(name="products_price7_qty", type="integer", nullable=false)
  356. */
  357. private $price7Qty = '0';
  358. /**
  359. * @var int
  360. *
  361. * @ORM\Column(name="products_price8_qty", type="integer", nullable=false)
  362. */
  363. private $price8Qty = '0';
  364. /**
  365. * @var int
  366. *
  367. * @ORM\Column(name="products_price9_qty", type="integer", nullable=false)
  368. */
  369. private $price9Qty = '0';
  370. /**
  371. * @var int
  372. *
  373. * @ORM\Column(name="products_price10_qty", type="integer", nullable=false)
  374. */
  375. private $price10Qty = '0';
  376. /**
  377. * @var int
  378. *
  379. * @ORM\Column(name="products_price11_qty", type="integer", nullable=false)
  380. */
  381. private $price11Qty = '0';
  382. /**
  383. * @var int
  384. *
  385. * @ORM\Column(name="products_qty_blocks", type="integer", nullable=false, options={"default"="1"})
  386. */
  387. private $productsQtyBlocks = '1';
  388. /**
  389. * @var bool
  390. *
  391. * @ORM\Column(name="products_soleil", type="integer", nullable=false)
  392. */
  393. private $soleil = '0';
  394. /**
  395. * @var int
  396. *
  397. * @ORM\Column(name="products_limite_panier", type="integer", nullable=false)
  398. */
  399. private $limitePanier = '0';
  400. /**
  401. * @var int|null
  402. *
  403. * @ORM\Column(name="products_page", type="integer", nullable=true)
  404. */
  405. private $page;
  406. /**
  407. * @var bool
  408. *
  409. * @ORM\Column(name="products_garantie", type="integer", nullable=false)
  410. */
  411. private $guaranty = '0';
  412. /**
  413. * @var int
  414. *
  415. * @ORM\Column(name="products_cat", type="integer", nullable=true)
  416. */
  417. private $defaultCategoryId = 0;
  418. private $defaultCategory;
  419. /**
  420. * @var int
  421. *
  422. * @ORM\Column(name="products_index", type="integer", nullable=false, options={"default"="1"})
  423. */
  424. private $index = '1';
  425. /**
  426. * @var int
  427. *
  428. * @ORM\Column(name="products_mvente", type="integer", nullable=false, options={"default"="1"})
  429. */
  430. private $mvente = '1';
  431. /**
  432. * @var int
  433. *
  434. * @ORM\Column(name="products_strategique", type="integer", nullable=false)
  435. */
  436. private $strategique = '0';
  437. /**
  438. * @var int
  439. *
  440. * @ORM\Column(name="products_reappro_non", type="integer", nullable=false)
  441. */
  442. private $reapproNon = '0';
  443. /**
  444. * @var int|null
  445. *
  446. * @ORM\Column(name="products_multiple", type="integer", nullable=true)
  447. */
  448. private $multiple = 1;
  449. /**
  450. * @var string|null
  451. *
  452. * @ORM\Column(name="products_origin", type="string", length=3, nullable=true)
  453. */
  454. private $origin = 1;
  455. /**
  456. * @var bool
  457. *
  458. * @ORM\Column(name="products_gift", type="boolean", nullable=true)
  459. */
  460. private $gift = '0';
  461. /**
  462. * @var ?string
  463. *
  464. * @ORM\Column(name="products_type", type="string", length=20, nullable=true)
  465. */
  466. private $type;
  467. /**
  468. * @var int
  469. *
  470. * @ORM\Column(name="products_welcome", type="boolean", nullable=false, options={"default"="1"})
  471. */
  472. private $welcome = '1';
  473. /**
  474. * @var boolean
  475. *
  476. * @ORM\Column(name="is_default_variant", type="boolean", nullable=false, options={"default"="0"})
  477. */
  478. private $isDefaultVariant = false;
  479. public function __construct()
  480. {
  481. $this->children = new \Doctrine\Common\Collections\ArrayCollection();
  482. $this->prices = new \Doctrine\Common\Collections\ArrayCollection();
  483. $this->descriptions = new \Doctrine\Common\Collections\ArrayCollection();
  484. }
  485. public function getId() {
  486. return $this->id;
  487. }
  488. public function getChildren() {
  489. return $this->children;
  490. }
  491. public function getParent() {
  492. if(!empty($this->parent) && !empty($this->languageId)){
  493. $this->parent->setLanguageId($this->languageId);
  494. }
  495. return $this->parent;
  496. }
  497. public function getProductModel(): ?ProductModel {
  498. return $this->productModel;
  499. }
  500. public function getTopProductModel(): ?ProductModel {
  501. $tmp = $this->productModel;
  502. while(!empty($tmp)) {
  503. if($tmp->hasParent()) {
  504. $tmp = $tmp->getParent();
  505. }else{
  506. return $tmp;
  507. }
  508. }
  509. return $tmp;
  510. }
  511. public function hasProductModel() {
  512. return !empty($this->productModel);
  513. }
  514. /**
  515. * Valeur(s) affichée(s) du produit sur l'axe de listing de son ProductModel racine
  516. * (ex. "Rouge", ou "XS / Rouge" pour un axe composite). Null si aucun axe n'est configuré.
  517. */
  518. public function getListingAxisLabel(): ?string {
  519. $model = $this->getTopProductModel();
  520. if (!$model) {
  521. return null;
  522. }
  523. $values = [];
  524. foreach ($model->getListingAxisCodes() as $code) {
  525. $attr = $this->getAttribute($code);
  526. if ($attr && $attr->getDisplayedValue() !== null && $attr->getDisplayedValue() !== '') {
  527. $values[] = $attr->getDisplayedValue();
  528. }
  529. }
  530. return empty($values) ? null : implode(' / ', $values);
  531. }
  532. /**
  533. * Clé du produit sur l'axe de listing de son ProductModel racine (valeurs brutes, ex. "RED"
  534. * ou "XS|RED"), identique au regroupement de CategoryProductRepository. Null si aucun axe.
  535. */
  536. public function getListingAxisKey(): ?string {
  537. $model = $this->getTopProductModel();
  538. if (!$model) {
  539. return null;
  540. }
  541. $parts = [];
  542. foreach ($model->getListingAxisCodes() as $code) {
  543. $attr = $this->getAttribute($code);
  544. $parts[] = $attr ? (string) $attr->getValue() : '';
  545. }
  546. return implode('', $parts) === '' ? null : implode('|', $parts);
  547. }
  548. public function getDescriptions() {
  549. return $this->descriptions;
  550. }
  551. public function getAttributes() {
  552. return $this->attributes;
  553. }
  554. public function getAttribute($key) {
  555. if (strpos($key, ',') !== false) {
  556. $codes = array_values(array_filter(array_map('trim', explode(',', $key))));
  557. return array_map(fn($code) => $this->getAttribute($code), $codes);
  558. }
  559. if($this->attributes) {
  560. foreach($this->getAttributes() as $attr) {
  561. if($attr->getAttribute()->getCode() == $key)
  562. return $attr;
  563. }
  564. }
  565. return null;
  566. }
  567. public function getAttributeValue($key) {
  568. $attr = $this->getAttribute($key);
  569. if (is_array($attr)) {
  570. return implode(' / ', array_map(fn($a) => $a ? $a->getDisplayedValue() : '', $attr));
  571. }
  572. return $attr ? $attr->getDisplayedValue() : null;
  573. }
  574. public function getQuantity() {
  575. return $this->quantity;
  576. }
  577. public function getModel() {
  578. return $this->model;
  579. }
  580. public function getModelSAP(): ?string {
  581. return $this->modelSAP;
  582. }
  583. public function getEan(): ?string {
  584. return $this->ean;
  585. }
  586. public function getName() {
  587. if(!empty($this->languageId)){
  588. $description = null;
  589. foreach($this->descriptions as $d){
  590. if($d->getLanguage()->getId()==$this->languageId){
  591. $description = $d;
  592. break;
  593. }
  594. }
  595. }
  596. if(empty($description) && count($this->descriptions)){
  597. $description = $this->descriptions[0];
  598. }
  599. return empty($description)?'':$description->getName();
  600. }
  601. public function getHeadingTitle() {
  602. if(!empty($this->languageId)){
  603. $description = null;
  604. foreach($this->descriptions as $d){
  605. if($d->getLanguage()->getId()==$this->languageId){
  606. $description = $d;
  607. break;
  608. }
  609. }
  610. }
  611. if(empty($description) && count($this->descriptions)){
  612. $description = $this->descriptions[0];
  613. }
  614. return empty($description)?'':$description->getHeadingTitle();
  615. }
  616. public function getDeclinaison() {
  617. $output = '';
  618. if($this->parent){
  619. $name = $this->getName();
  620. $output = substr($name, strlen($this->getParent()->getName())+2, strlen($name));
  621. }
  622. return $output;
  623. }
  624. public function getUrl() {
  625. if(!empty($this->languageId)){
  626. $description = null;
  627. foreach($this->descriptions as $d){
  628. if($d->getLanguage()->getId()==$this->languageId){
  629. $description = $d;
  630. break;
  631. }
  632. }
  633. }
  634. if(empty($description) && count($this->descriptions)){
  635. $description = $this->descriptions[0];
  636. }
  637. return empty($description)?'':$description->getUrl();
  638. }
  639. public function getDescription() {
  640. if(!empty($this->languageId)){
  641. $description = null;
  642. foreach($this->descriptions as $d){
  643. if($d->getLanguage()->getId()==$this->languageId){
  644. $description = $d;
  645. break;
  646. }
  647. }
  648. }
  649. if(empty($description) && count($this->descriptions)){
  650. $description = $this->descriptions[0];
  651. }
  652. return empty($description)?'':$description->getDescription();
  653. }
  654. public function getExtraFields() {
  655. return $this->extraFields;
  656. }
  657. public function getProductDescription($lang='fr') : ?ProductDescription {
  658. foreach($this->getDescriptions() as $desc){
  659. if($desc->getLanguage()->getCode() == $lang)
  660. return $desc;
  661. }
  662. return null;
  663. }
  664. /**
  665. * Première image (ordre rank, id), quelles que soient les clés de la collection
  666. */
  667. public function getPicture() {
  668. foreach($this->pictures ?? [] as $picture) {
  669. return $picture;
  670. }
  671. return null;
  672. }
  673. public function getPictures() {
  674. return $this->pictures;
  675. }
  676. public function getPicturesUrl() {
  677. $output = [];
  678. foreach($this->pictures as $picture){
  679. $output[] = $picture->getUrl();
  680. }
  681. return $output;
  682. }
  683. public function getImage($absolute=false) {
  684. if($absolute)
  685. return 'https://www.dogcat.com/professionnel/images/'.$this->image;
  686. return $this->image;
  687. }
  688. public function getImageMed($absolute=false) {
  689. if($absolute)
  690. return 'https://www.dogcat.com/professionnel/images/'.$this->imageMed;
  691. return $this->imageMed;
  692. }
  693. public function getImageLrg($absolute=false) {
  694. if($absolute)
  695. return 'https://www.dogcat.com/professionnel/images/'.$this->imageLrg;
  696. return $this->imageLrg;
  697. }
  698. public function getImageSm1() {
  699. return $this->imageSm1;
  700. }
  701. public function getImageXl1() {
  702. return $this->imageXl1;
  703. }
  704. public function getImageSm2() {
  705. return $this->imageSm2;
  706. }
  707. public function getImageXl2() {
  708. return $this->imageXl2;
  709. }
  710. public function getImageSm3() {
  711. return $this->imageSm3;
  712. }
  713. public function getImageXl3() {
  714. return $this->imageXl3;
  715. }
  716. public function getImageSm4() {
  717. return $this->imageSm4;
  718. }
  719. public function getImageXl4() {
  720. return $this->imageXl4;
  721. }
  722. public function getImageSm5() {
  723. return $this->imageSm5;
  724. }
  725. public function getImageXl5() {
  726. return $this->imageXl5;
  727. }
  728. public function getImageSm6() {
  729. return $this->imageSm6;
  730. }
  731. public function getImageXl6() {
  732. return $this->imageXl6;
  733. }
  734. public function getPrice($withEcotax = false, ?PriceGroup $priceGroup = null, $withVat = false) {
  735. $price = $this->price;
  736. $tax = 0;
  737. if($this->isGift()) {
  738. return 0;
  739. }
  740. if($priceGroup) {
  741. $price = $this->getPriceByGroup($priceGroup);
  742. }
  743. if($withVat) {
  744. $tax = Encoder::roundPrice($price*self::VAT_RATE);
  745. }
  746. if($withEcotax === true){
  747. return Encoder::roundPrice($price) + Encoder::roundPrice($this->getEcotax()) + $tax;
  748. }
  749. return Encoder::roundPrice($price) + $tax;
  750. }
  751. public function getPrices() {
  752. return $this->prices;
  753. }
  754. public function getPriceByGroup(PriceGroup $priceGroup) {
  755. foreach($this->prices as $price) {
  756. if($price->getGroup() == $priceGroup) {
  757. return $price->getPrice();
  758. }
  759. }
  760. // throw new \App\Exception\PriceGroupException();
  761. }
  762. public function hasPrice(PriceGroup $priceGroup) {
  763. if($this->hasChildren()) {
  764. foreach($this->getChildren() as $child) {
  765. if($child->hasPrice($priceGroup))
  766. return true;
  767. }
  768. }else{
  769. foreach($this->prices as $price) {
  770. if($price->getGroup() == $priceGroup)
  771. return true;
  772. }
  773. }
  774. return false;
  775. }
  776. public function getEcotax() {
  777. return $this->ecotax;
  778. }
  779. public function getFromProduct(?PriceGroup $priceGroup = null) {
  780. $tmp = null;
  781. $from = null;
  782. foreach($this->children as $product){
  783. if(!$product->isStopped() && $product->isActive()){
  784. if(!empty($priceGroup) && !$product->hasPrice($priceGroup)) {
  785. continue;
  786. }
  787. if(is_null($tmp) || ($tmp>$product->getPrice(false, $priceGroup, false))){
  788. $tmp = $product->getPrice(false, $priceGroup, false);
  789. $from = $product;
  790. }
  791. }
  792. }
  793. return $from;
  794. }
  795. public function getFromPrice($withEcotax = true, ?PriceGroup $priceGroup = null, $withVat = false) {
  796. $tmp = null;
  797. foreach($this->children as $product){
  798. if(!$product->isStopped() && $product->isActive()){
  799. if(!empty($priceGroup) && !$product->hasPrice($priceGroup)) {
  800. continue;
  801. }
  802. if(is_null($tmp) || ($tmp>$product->getPrice($withEcotax, $priceGroup, $withVat))){
  803. $tmp = $product->getPrice($withEcotax, $priceGroup, $withVat);
  804. }
  805. }
  806. }
  807. return is_null($tmp)?0:$tmp;
  808. }
  809. public function getSoleilPrice($withEcotax = true) {
  810. if($this->isNonSoleil()){
  811. return Encoder::roundPrice($this->price * 0.9)+($withEcotax?$this->getEcotax():0);
  812. }else if($this->isSoleil()){
  813. return Encoder::roundPrice($this->price * 0.75)+($withEcotax?$this->getEcotax():0);
  814. }
  815. return Encoder::roundPrice($this->price)+($withEcotax?$this->getEcotax():0);
  816. }
  817. public function getDateAdded() {
  818. return $this->dateAdded;
  819. }
  820. public function getLastModified() {
  821. return $this->lastModified;
  822. }
  823. public function getDateAvailable() {
  824. return $this->dateAvailable;
  825. }
  826. public function getWeight() {
  827. return $this->weight;
  828. }
  829. public function getStatus() {
  830. return $this->status;
  831. }
  832. public function getTaxClass() {
  833. return $this->taxClass;
  834. }
  835. public function getManufacturer() {
  836. return $this->manufacturer;
  837. }
  838. public function getOrdered() {
  839. return $this->ordered;
  840. }
  841. public function getPrice1() {
  842. return $this->price1;
  843. }
  844. public function getPrice2() {
  845. return $this->price2;
  846. }
  847. public function getPrice3() {
  848. return $this->price3;
  849. }
  850. public function getPrice4() {
  851. return $this->price4;
  852. }
  853. public function getPrice5() {
  854. return $this->price5;
  855. }
  856. public function getPrice6() {
  857. return $this->price6;
  858. }
  859. public function getPrice7() {
  860. return $this->price7;
  861. }
  862. public function getPrice8() {
  863. return $this->price8;
  864. }
  865. public function getPrice9() {
  866. return $this->price9;
  867. }
  868. public function getPrice10() {
  869. return $this->price10;
  870. }
  871. public function getPrice11() {
  872. return $this->price11;
  873. }
  874. public function getPrice1Qty() {
  875. return $this->price1Qty;
  876. }
  877. public function getPrice2Qty() {
  878. return $this->price2Qty;
  879. }
  880. public function getPrice3Qty() {
  881. return $this->price3Qty;
  882. }
  883. public function getPrice4Qty() {
  884. return $this->price4Qty;
  885. }
  886. public function getPrice5Qty() {
  887. return $this->price5Qty;
  888. }
  889. public function getPrice6Qty() {
  890. return $this->price6Qty;
  891. }
  892. public function getPrice7Qty() {
  893. return $this->price7Qty;
  894. }
  895. public function getPrice8Qty() {
  896. return $this->price8Qty;
  897. }
  898. public function getPrice9Qty() {
  899. return $this->price9Qty;
  900. }
  901. public function getPrice10Qty() {
  902. return $this->price10Qty;
  903. }
  904. public function getPrice11Qty() {
  905. return $this->price11Qty;
  906. }
  907. public function getProductsQtyBlocks() {
  908. return $this->productsQtyBlocks;
  909. }
  910. public function getSoleil() {
  911. return $this->soleil;
  912. }
  913. public function getLimitePanier() {
  914. return $this->limitePanier;
  915. }
  916. public function getPage() {
  917. return $this->page;
  918. }
  919. public function getGuaranty() {
  920. return $this->guaranty;
  921. }
  922. public function getDefaultCategoryId() {
  923. return $this->defaultCategoryId;
  924. }
  925. public function getDefaultCategory() {
  926. return $this->defaultCategory;
  927. }
  928. public function getIndex() {
  929. if(empty($this->index))
  930. return 0;
  931. return $this->index > 0 ? 1 : 0;
  932. }
  933. public function getMvente() {
  934. return $this->mvente;
  935. }
  936. public function getStrategique() {
  937. return $this->strategique;
  938. }
  939. public function getReapproNon() {
  940. return $this->reapproNon;
  941. }
  942. public function getMultiple() {
  943. return empty($this->multiple)?1:$this->multiple;
  944. }
  945. public function getOrigin() {
  946. return $this->origin;
  947. }
  948. public function getReference() {
  949. return $this->getModel();
  950. }
  951. public function getGift() {
  952. return is_null($this->gift) ? 0 : $this->gift;
  953. }
  954. public function getType(): ?string {
  955. return empty($this->type) ? self::TYPE_PRODUCT : $this->type;
  956. }
  957. public function getCountryRestrictions() {
  958. return $this->countryRestrictions;
  959. }
  960. public function getRestrictedCountries() {
  961. $output = [];
  962. foreach($this->getCountryRestrictions() as $rc) {
  963. $output[] = $rc->getCountry();
  964. }
  965. return $output;
  966. }
  967. public function getWelcome(): int {
  968. return $this->welcome;
  969. }
  970. public function getIsDefaultVariant() {
  971. return $this->isDefaultVariant;
  972. }
  973. // public function getUrl($absolute=false) {
  974. // if(!empty($this->parent))
  975. // return $this->getParent()->getUrl($absolute);
  976. // if(!empty($this->languageId)){
  977. // $language = $this->languageId==4?'fr':'en';
  978. // }
  979. // if(empty($language)){
  980. // $language = 'fr';
  981. // }
  982. //// $url = '/professionnel/product_info.php?products_id='.$this->getId().'&language='.$language;
  983. //// if($absolute)
  984. //// return 'https://www.dogcat.com'.$url;
  985. // return $this->getUrl();
  986. // }
  987. public function setId($id) {
  988. $this->id = $id;
  989. }
  990. public function setAttributes($attributes) {
  991. $this->attributes = $attributes;
  992. }
  993. public function setChildren($children) {
  994. $this->children = $children;
  995. }
  996. public function setProductModel(?ProductModel $productModel): void {
  997. $this->productModel = $productModel;
  998. }
  999. public function setParent($parent) {
  1000. $this->parent = $parent;
  1001. }
  1002. public function setDescriptions($descriptions) {
  1003. $this->descriptions = $descriptions;
  1004. }
  1005. public function setExtraFields($extraFields): void {
  1006. $this->extraFields = $extraFields;
  1007. }
  1008. public function setQuantity($quantity) {
  1009. $this->quantity = $quantity;
  1010. }
  1011. public function setModel($model) {
  1012. $this->model = $model;
  1013. }
  1014. public function setModelSAP(?string $modelSAP): void {
  1015. $this->modelSAP = $modelSAP;
  1016. }
  1017. public function setEan(?string $ean): void {
  1018. $this->ean = $ean;
  1019. }
  1020. public function setImage($image) {
  1021. $this->image = $image;
  1022. }
  1023. public function setImageMed($imageMed) {
  1024. $this->imageMed = $imageMed;
  1025. }
  1026. public function setImageLrg($imageLrg) {
  1027. $this->imageLrg = $imageLrg;
  1028. }
  1029. public function setImageSm1($imageSm1) {
  1030. $this->imageSm1 = $imageSm1;
  1031. }
  1032. public function setImageXl1($imageXl1) {
  1033. $this->imageXl1 = $imageXl1;
  1034. }
  1035. public function setImageSm2($imageSm2) {
  1036. $this->imageSm2 = $imageSm2;
  1037. }
  1038. public function setImageXl2($imageXl2) {
  1039. $this->imageXl2 = $imageXl2;
  1040. }
  1041. public function setImageSm3($imageSm3) {
  1042. $this->imageSm3 = $imageSm3;
  1043. }
  1044. public function setImageXl3($imageXl3) {
  1045. $this->imageXl3 = $imageXl3;
  1046. }
  1047. public function setImageSm4($imageSm4) {
  1048. $this->imageSm4 = $imageSm4;
  1049. }
  1050. public function setImageXl4($imageXl4) {
  1051. $this->imageXl4 = $imageXl4;
  1052. }
  1053. public function setImageSm5($imageSm5) {
  1054. $this->imageSm5 = $imageSm5;
  1055. }
  1056. public function setImageXl5($imageXl5) {
  1057. $this->imageXl5 = $imageXl5;
  1058. }
  1059. public function setImageSm6($imageSm6) {
  1060. $this->imageSm6 = $imageSm6;
  1061. }
  1062. public function setImageXl6($imageXl6) {
  1063. $this->imageXl6 = $imageXl6;
  1064. }
  1065. public function setPrice($price) {
  1066. $this->price = $price;
  1067. }
  1068. public function setEcotax( $ecotax) {
  1069. $this->ecotax = $ecotax;
  1070. }
  1071. public function setDateAdded(\DateTime $dateAdded) {
  1072. $this->dateAdded = $dateAdded;
  1073. }
  1074. public function setLastModified(\DateTime $lastModified) {
  1075. $this->lastModified = $lastModified;
  1076. }
  1077. public function setDateAvailable(\DateTime $dateAvailable) {
  1078. $this->dateAvailable = $dateAvailable;
  1079. }
  1080. public function setWeight($weight) {
  1081. $this->weight = $weight;
  1082. }
  1083. public function setStatus($status) {
  1084. $this->status = $status;
  1085. }
  1086. public function setTaxClass($taxClass) {
  1087. $this->taxClass = $taxClass;
  1088. }
  1089. public function setManufacturer($manufacturer) {
  1090. $this->manufacturer = $manufacturer;
  1091. }
  1092. public function setOrdered($ordered) {
  1093. $this->ordered = $ordered;
  1094. }
  1095. public function setParentId($parentId) {
  1096. $this->parentId = $parentId;
  1097. }
  1098. public function setPrice1($price1) {
  1099. $this->price1 = $price1;
  1100. }
  1101. public function setPrice2($price2) {
  1102. $this->price2 = $price2;
  1103. }
  1104. public function setPrice3($price3) {
  1105. $this->price3 = $price3;
  1106. }
  1107. public function setPrice4($price4) {
  1108. $this->price4 = $price4;
  1109. }
  1110. public function setPrice5($price5) {
  1111. $this->price5 = $price5;
  1112. }
  1113. public function setPrice6($price6) {
  1114. $this->price6 = $price6;
  1115. }
  1116. public function setPrice7($price7) {
  1117. $this->price7 = $price7;
  1118. }
  1119. public function setPrice8($price8) {
  1120. $this->price8 = $price8;
  1121. }
  1122. public function setPrice9($price9) {
  1123. $this->price9 = $price9;
  1124. }
  1125. public function setPrice10($price10) {
  1126. $this->price10 = $price10;
  1127. }
  1128. public function setPrice11($price11) {
  1129. $this->price11 = $price11;
  1130. }
  1131. public function setPrice1Qty($price1Qty) {
  1132. $this->price1Qty = $price1Qty;
  1133. }
  1134. public function setPrice2Qty($price2Qty) {
  1135. $this->price2Qty = $price2Qty;
  1136. }
  1137. public function setPrice3Qty($price3Qty) {
  1138. $this->price3Qty = $price3Qty;
  1139. }
  1140. public function setPrice4Qty($price4Qty) {
  1141. $this->price4Qty = $price4Qty;
  1142. }
  1143. public function setPrice5Qty($price5Qty) {
  1144. $this->price5Qty = $price5Qty;
  1145. }
  1146. public function setPrice6Qty($price6Qty) {
  1147. $this->price6Qty = $price6Qty;
  1148. }
  1149. public function setPrice7Qty($price7Qty) {
  1150. $this->price7Qty = $price7Qty;
  1151. }
  1152. public function setPrice8Qty($price8Qty) {
  1153. $this->price8Qty = $price8Qty;
  1154. }
  1155. public function setPrice9Qty($price9Qty) {
  1156. $this->price9Qty = $price9Qty;
  1157. }
  1158. public function setPrice10Qty($price10Qty) {
  1159. $this->price10Qty = $price10Qty;
  1160. }
  1161. public function setPrice11Qty($price11Qty) {
  1162. $this->price11Qty = $price11Qty;
  1163. }
  1164. public function setProductsQtyBlocks($productsQtyBlocks) {
  1165. $this->productsQtyBlocks = $productsQtyBlocks;
  1166. }
  1167. public function setSoleil($soleil) {
  1168. $this->soleil = $soleil;
  1169. }
  1170. public function setLimitePanier($limitePanier) {
  1171. $this->limitePanier = $limitePanier;
  1172. }
  1173. public function setPage($page) {
  1174. $this->page = $page;
  1175. }
  1176. public function setGuaranty($guaranty) {
  1177. $this->guaranty = $guaranty;
  1178. }
  1179. public function setDefaultCategoryId($defaultCategoryId) {
  1180. $this->defaultCategoryId = $defaultCategoryId;
  1181. }
  1182. public function setIndex($index) {
  1183. $this->index = $index;
  1184. }
  1185. public function setMvente($mvente) {
  1186. $this->mvente = $mvente;
  1187. }
  1188. public function setStrategique($strategique) {
  1189. $this->strategique = $strategique;
  1190. }
  1191. public function setReapproNon($reapproNon) {
  1192. $this->reapproNon = $reapproNon;
  1193. }
  1194. public function setMultiple($multiple) {
  1195. return $this->multiple = $multiple;
  1196. }
  1197. public function setOrigin($origin) {
  1198. $this->origin = $origin;
  1199. }
  1200. public function setPrices($prices) {
  1201. $this->prices = $prices;
  1202. }
  1203. public function setGift($gift) {
  1204. $this->gift = $gift;
  1205. }
  1206. public function setType(?string $type): void {
  1207. $this->type = $type;
  1208. }
  1209. public function setCountryRestrictions($countryRestrictions): void {
  1210. $this->countryRestrictions = $countryRestrictions;
  1211. }
  1212. public function setWelcome(int $welcome): void {
  1213. $this->welcome = $welcome;
  1214. }
  1215. public function setIsDefaultVariant($isDefaultVariant): void {
  1216. $this->isDefaultVariant = $isDefaultVariant;
  1217. }
  1218. public function getCaracteristics() {
  1219. $output = [];
  1220. foreach($this->getAttributes() as $attr) {
  1221. if($attr->getAttribute()->getShowInCaracteristic())
  1222. $output[] = $attr;
  1223. }
  1224. // même ordre que les filtres (attributes_order), usort est stable : l'ordre d'origine départage les égalités
  1225. usort($output, fn($a, $b) => $a->getAttribute()->getSortOrder() <=> $b->getAttribute()->getSortOrder());
  1226. return $output;
  1227. }
  1228. public function hasWelcomeDiscount() {
  1229. return !empty($this->welcome);
  1230. }
  1231. public function isMadeInFrance() {
  1232. if(!empty($this->origin))
  1233. return strtoupper($this->origin) == 'FR';
  1234. if($this->hasChildren()){
  1235. foreach($this->children as $child){
  1236. if(!$child->isMadeInFrance()){
  1237. return false;
  1238. }
  1239. }
  1240. return true;
  1241. }
  1242. return false;
  1243. }
  1244. public function isAvailable() {
  1245. return $this->quantity > 0;
  1246. }
  1247. public function isDefaultVariant() {
  1248. return !empty($this->isDefaultVariant);
  1249. }
  1250. public function hasRestrictionForCountry($country) {
  1251. if($country){
  1252. if($this->countryRestrictions){
  1253. foreach($this->getCountryRestrictions() as $restriction){
  1254. if($restriction->getCountry() == $country){
  1255. return true;
  1256. }
  1257. }
  1258. }
  1259. }
  1260. return false;
  1261. }
  1262. public function isAvailableForCountry($country) {
  1263. if($country && $this->countryRestrictions){
  1264. foreach($this->getCountryRestrictions() as $restriction) {
  1265. if($restriction->getCountry() == $country){
  1266. return false;
  1267. }
  1268. }
  1269. }
  1270. if($country && $this->getManufacturer()){
  1271. return $this->getManufacturer()->isAvailableForCountry($country);
  1272. }
  1273. return true;
  1274. }
  1275. public function isStopped() {
  1276. return $this->quantity == -800;
  1277. }
  1278. public function isActive() {
  1279. return $this->getStatus() == 1;
  1280. }
  1281. public function isGift() {
  1282. return $this->getGift() == 1;
  1283. }
  1284. public function isSoleil() {
  1285. if($this->manufacturer?->isNoSoleil())
  1286. return false;
  1287. return $this->soleil == 1;
  1288. }
  1289. public function isNonSoleil() {
  1290. if($this->manufacturer?->isNoSoleil())
  1291. return false;
  1292. return $this->soleil == 0;
  1293. }
  1294. public function isVivog() {
  1295. return $this->isSoleil() || $this->isNonSoleil();
  1296. }
  1297. public function isParent() {
  1298. return empty($this->parent);
  1299. }
  1300. public function isProduct() {
  1301. return $this->getType() == self::TYPE_PRODUCT;
  1302. }
  1303. public function hasChildren() {
  1304. return count($this->children)>0;
  1305. }
  1306. public function hasSoleilPrice() {
  1307. return $this->isSoleil() || $this->isNonSoleil();
  1308. }
  1309. public function hasParent() {
  1310. return !empty($this->parent);
  1311. }
  1312. public function hasSoleil() {
  1313. return $this->isSoleil();
  1314. }
  1315. public function hasNonSoleil() {
  1316. return $this->isNonSoleil();
  1317. }
  1318. public function addPrice(ProductPrice $productPrice): self
  1319. {
  1320. if (!$this->prices->contains($productPrice)) {
  1321. $this->prices->add($productPrice);
  1322. $productPrice->setProduct($this);
  1323. }
  1324. return $this;
  1325. }
  1326. public function removePrice(ProductPrice $productPrice): self
  1327. {
  1328. if ($this->prices->removeElement($productPrice)) {
  1329. if ($productPrice->getProduct() === $this) {
  1330. $productPrice->setProduct(null);
  1331. }
  1332. }
  1333. return $this;
  1334. }
  1335. public function toArray() : array{
  1336. $parent = $this->getParent();
  1337. $manufacturer = $this->getManufacturer();
  1338. $output = [
  1339. 'id' => $this->getId(),
  1340. 'model' => $this->getModel(),
  1341. 'name' => $this->getName(),
  1342. 'description' => $this->getDescription(),
  1343. 'quantity' => $this->getQuantity(),
  1344. 'image' => $this->getImage(),
  1345. 'price' => $this->getPrice(),
  1346. 'dateAdded' => $this->getDateAdded(),
  1347. 'lastModified' => $this->getLastModified(),
  1348. 'dateAvailable' => $this->getDateAvailable(),
  1349. 'weight' => $this->getWeight(),
  1350. 'status' => $this->getStatus()?1:0,
  1351. 'taxClass ' => $this->getTaxClass()?$this->getTaxClass()->toArray():0,
  1352. 'ordered' => $this->getOrdered(),
  1353. 'parent' => empty($parent)?null:$parent->toArray(),
  1354. 'manufacturer' => empty($manufacturer)?null:$manufacturer->toArray(),
  1355. 'productsQtyBlocks' => $this->getProductsQtyBlocks(),
  1356. 'soleil' => $this->getSoleil(),
  1357. 'nbChildren' => count($this->getChildren()),
  1358. 'limitePanier' => $this->getLimitePanier(),
  1359. 'page' => $this->getPage(),
  1360. 'garantie' => $this->getGuaranty(),
  1361. 'defaultCategoryId' => $this->getDefaultCategoryId(),
  1362. 'index' => $this->getIndex(),
  1363. 'mvente' => $this->getMvente(),
  1364. 'strategique' => $this->getStrategique(),
  1365. 'reapproNon' => $this->getReapproNon(),
  1366. 'multiple' => $this->getMultiple(),
  1367. ];
  1368. return $output;
  1369. }
  1370. public function toJson() {
  1371. return json_encode($this->toArray());
  1372. }
  1373. /**
  1374. * @todo Remove once 0 values in the table are converted to NULL.
  1375. */
  1376. public function loadDescriptions(\Doctrine\ORM\EntityManager $em)
  1377. {
  1378. $conn = $em->getConnection();
  1379. $sql = $conn->prepare('select * from products_description where products_id = '.$this->getId());
  1380. $sql->execute();
  1381. $rows = $sql->fetchAll();
  1382. $descriptions = [];
  1383. foreach($rows as $desc){
  1384. $description = new ProductDescription();
  1385. $description->setName($desc['products_name']);
  1386. $description->setDescription($desc['products_description']);
  1387. $description->setLanguage($em->getRepository('App:Language')->find($desc['language_id']==1?1:4));
  1388. $descriptions[] = $description;
  1389. }
  1390. $this->setDescriptions($descriptions);
  1391. }
  1392. public static function getSearchIndex($lang = 'fr')
  1393. {
  1394. return self::SEARCH_INDICES[$lang];
  1395. }
  1396. /**
  1397. * @ORM\PrePersist
  1398. */
  1399. public function prePersit(\Doctrine\ORM\Event\LifecycleEventArgs $args) {
  1400. $this->setDateAdded(new \DateTime);
  1401. }
  1402. /**
  1403. * @ORM\PrePersist
  1404. * @ORM\PreUpdate
  1405. */
  1406. public function preUpdate(\Doctrine\ORM\Event\LifecycleEventArgs $args) {
  1407. if(is_null($this->weight))
  1408. $this->setWeight(0);
  1409. }
  1410. }