src/Entity/SaleOrderItem.php line 23

Open in your IDE?
  1. <?php
  2. namespace App\Entity;
  3. use App\Repository\SaleOrderItemRepository;
  4. use App\Traits\DateTrait;
  5. use Doctrine\Common\Collections\ArrayCollection;
  6. use Doctrine\Common\Collections\Collection;
  7. use Doctrine\ORM\Mapping as ORM;
  8. use JMS\Serializer\Annotation as Serializer;
  9. use JMS\Serializer\Annotation\Expose;
  10. use JMS\Serializer\Annotation\Groups;
  11. use JMS\Serializer\Annotation\SerializedName;
  12. /**
  13. * @ORM\Table(indexes={
  14. * @ORM\Index(columns={"status"})
  15. * })
  16. * @ORM\Entity(repositoryClass=SaleOrderItemRepository::class)
  17. *
  18. * @Serializer\ExclusionPolicy("ALL")
  19. */
  20. class SaleOrderItem
  21. {
  22. use DateTrait;
  23. public const TYPE_EVASION = 'evasion';
  24. public const TYPE_SHOPPING = 'shopping';
  25. public const TYPE_COFFRET = 'coffret';
  26. public const STATUS_PROCESSING = 'processing';
  27. public const STATUS_NOT_CONFIRMED = 'not_confirmed';
  28. public const STATUS_CANCELED = 'canceled';
  29. public const STATUS_SHIPPED = 'shipped';
  30. // Liste des statuts des commandes que l'on envoie au BO pour la synchronisation
  31. public const ALL_STATUS = [
  32. self::STATUS_PROCESSING,
  33. self::STATUS_NOT_CONFIRMED,
  34. self::STATUS_CANCELED,
  35. self::STATUS_SHIPPED,
  36. ];
  37. /**
  38. * @ORM\Id
  39. * @ORM\GeneratedValue
  40. * @ORM\Column(type="integer")
  41. *
  42. * @Expose
  43. * @Groups({"get:read", "sale_oder_item:list"})
  44. */
  45. private ?int $id = null;
  46. /**
  47. * Identifiant unique
  48. *
  49. * @ORM\Column(type="string", length=255)
  50. *
  51. * @Expose
  52. * @Groups({"sale_order:item", "sale_oder_item:list", "sale_order:post", "get:read"})
  53. */
  54. private ?string $sku = null;
  55. /**
  56. * Anciennement '$order' mais c'est un mot reservé (mysql) on ne peut plus l'utiliser
  57. *
  58. * @ORM\ManyToOne(targetEntity=SaleOrder::class, inversedBy="items")
  59. * @ORM\JoinColumn(nullable=false, name="order_id")
  60. */
  61. private ?SaleOrder $saleOrder = null;
  62. /**
  63. * Quantité
  64. *
  65. * @ORM\Column(type="integer")
  66. *
  67. * @Expose
  68. * @Groups({"sale_order:item", "sale_oder_item:list", "sale_order:post", "get:read","export_order_datatable"})
  69. */
  70. private ?int $quantity = null;
  71. /**
  72. * @ORM\Column(type="integer", nullable=true)
  73. *
  74. * @Expose
  75. * @Groups({"sale_order:item", "sale_oder_item:list","get:read"})
  76. */
  77. private ?int $quantityNoBatch = null;
  78. /**
  79. * @ORM\Column(type="string", length=100, options={"default":self::STATUS_PROCESSING})
  80. *
  81. * @Expose
  82. * @Groups({"get:read", "sale_oder_item:list"})
  83. */
  84. private string $status = self::STATUS_PROCESSING;
  85. /**
  86. * @ORM\Column(type="string", length=255)
  87. *
  88. * @Expose
  89. * @Groups({"get:read"})
  90. */
  91. private ?string $reference = null;
  92. /**
  93. * @ORM\Column(type="string", length=255)
  94. *
  95. * @Expose
  96. * @Groups({"sale_order:item", "sale_oder_item:list", "get:read","export_order_datatable"})
  97. */
  98. private ?string $name = null;
  99. /**
  100. * @ORM\Column(type="text", nullable=true)
  101. *
  102. * @Expose
  103. * @Groups({"get:read"})
  104. */
  105. private ?string $description = null;
  106. /**
  107. * @ORM\Column(type="string", length=255)
  108. *
  109. * @Expose
  110. * @Groups({"get:read", "sale_oder_item:list"})
  111. */
  112. private ?string $gamme = null;
  113. /**
  114. * @ORM\Column(type="decimal", precision=12, scale=4, nullable=true)
  115. *
  116. * @Expose
  117. * @Groups({"get:read", "sale_oder_item:list"})
  118. * @SerializedName ("price_h_t")
  119. */
  120. private ?string $priceHT = null;
  121. /**
  122. * @ORM\Column(type="decimal", precision=12, scale=4, nullable=true)
  123. */
  124. private ?string $priceTTC = null;
  125. /**
  126. * @ORM\Column(type="decimal", precision=12, scale=4, nullable=true)
  127. */
  128. private ?string $unitPoint = null;
  129. /**
  130. * @ORM\Column(type="string", length=255, nullable=true)
  131. *
  132. * @Expose
  133. * @Groups({"get:read"})
  134. */
  135. private ?string $imageUrl = null;
  136. /**
  137. * @ORM\Column(type="string", length=255, nullable=true)
  138. */
  139. private ?string $imageThumbnailUrl = null;
  140. /**
  141. * @ORM\Column(type="decimal", precision=12, scale=4, nullable=true)
  142. *
  143. * @Expose
  144. * @Groups({"get:read"})
  145. */
  146. private ?string $taxableAmount = null;
  147. /**
  148. * @ORM\OneToMany(targetEntity=SaleOrderParticipant::class, mappedBy="saleOrderItem", cascade={"persist","remove"}, orphanRemoval=true)
  149. * @Expose
  150. * @Groups({"sale_order:item", "sale_order:post", "get:read", "export_order_datatable"})
  151. */
  152. private ?Collection $participants = null;
  153. /**
  154. * @ORM\OneToMany(targetEntity=SaleOrderItemOption::class, mappedBy="item")
  155. */
  156. private ?Collection $options = null;
  157. /**
  158. * @ORM\Column(type="text", nullable=true)
  159. */
  160. private ?string $categoryValues = null;
  161. /**
  162. * @ORM\Column(type="text", nullable=true)
  163. */
  164. private ?string $totalChosenCategoryValues = null;
  165. /**
  166. * @ORM\Column(type="datetime", nullable=true)
  167. * @Expose
  168. * @Groups({"get:read"})
  169. */
  170. private $wishDateEvasion;
  171. /**
  172. * @ORM\Column(type="float", nullable=true)
  173. */
  174. private $weight;
  175. /**
  176. * @ORM\Column(type="boolean", options={"default":true}) nullable=false)
  177. *
  178. * @Expose
  179. * @Groups({"get:read", "sale_oder_item:list"})
  180. */
  181. private ?bool $isRefundable = true;
  182. /**
  183. *
  184. * @ORM\Column(type="boolean", options={"default":false}) nullable=true)
  185. *
  186. * @Expose
  187. * @Groups({"get:read", "sale_oder_item:list"})
  188. */
  189. private ?bool $isReplaced = false;
  190. /**
  191. * @ORM\OneToMany(targetEntity=PointTransaction::class, mappedBy="saleOrderItem", cascade={"persist"})
  192. */
  193. //On lie un SaleOrderItem a une transaction seulement à l'annulation, pour pouvoir lier un remboursement a un produit
  194. private Collection $pointTransactions;
  195. /**
  196. * @ORM\OneToOne(targetEntity=SaleOrderShipmentItem::class, mappedBy="saleOrderItem", cascade={"persist", "remove"})
  197. */
  198. private $saleOrderShipmentItem;
  199. /**
  200. * @ORM\OneToOne(targetEntity=SaleOrderItem::class, cascade={"persist", "remove"})
  201. */
  202. private $replaceItem;
  203. /**
  204. * @ORM\Column(type="integer", nullable=true)
  205. */
  206. private $boId;
  207. public function __construct()
  208. {
  209. $this->categoryValues = '';
  210. $this->totalChosenCategoryValues = '';
  211. $this->participants = new ArrayCollection();
  212. $this->options = new ArrayCollection();
  213. $this->pointTransactions = new ArrayCollection();
  214. }
  215. public function __clone()
  216. {
  217. if ($this->id) {
  218. $this->setId(null);
  219. $this->setSaleOrder(null);
  220. }
  221. }
  222. public function __toString()
  223. {
  224. return $this->getSku();
  225. }
  226. /*
  227. * ============================================================================================
  228. * =============================== FONCTIONS CUSTOM ===========================================
  229. * ============================================================================================
  230. */
  231. public function getSku(): ?string
  232. {
  233. return $this->sku;
  234. }
  235. public function setSku(?string $sku): self
  236. {
  237. $this->sku = $sku;
  238. return $this;
  239. }
  240. /**
  241. * @Serializer\VirtualProperty()
  242. * @Serializer\SerializedName("array_category_values")
  243. */
  244. public function getArrayCategoryValues()
  245. {
  246. return json_decode($this->categoryValues, true) ?? [];
  247. }
  248. /**
  249. * @Serializer\VirtualProperty()
  250. * @Serializer\SerializedName("array_total_chosen_category_values")
  251. */
  252. public function getArrayTotalChosenCategoryValues()
  253. {
  254. return json_decode($this->totalChosenCategoryValues, true) ?? [];
  255. }
  256. /**
  257. * @param string $slug
  258. * @param int $value
  259. *
  260. * @return $this
  261. */
  262. public function modifyValueToCategory(string $slug, int $value): self
  263. {
  264. $newArray = $this->getArrayCategoryValues();
  265. $newArray[$slug] = $value;
  266. $this->categoryValues = json_encode($newArray);
  267. return $this;
  268. }
  269. /**
  270. * @param float $multiplication
  271. *
  272. * @return $this
  273. */
  274. public function multiplicationCategoryValues(float $multiplication): self
  275. {
  276. $newArray = $this->getArrayCategoryValues();
  277. foreach ($newArray as $cat => $val) {
  278. $newArray[$cat] = $val * $multiplication;
  279. }
  280. $this->categoryValues = json_encode($newArray);
  281. return $this;
  282. }
  283. /*
  284. * ============================================================================================
  285. * ============================== FIN FONCTIONS CUSTOM ========================================
  286. * ============================================================================================
  287. */
  288. public function getTotalPrice()
  289. {
  290. $quantity = $this->getQuantity() ?? 1;
  291. $price = $this->getPriceHT() ?? 0;
  292. return $price * $quantity;
  293. }
  294. public function getQuantity(): ?int
  295. {
  296. return $this->quantity;
  297. }
  298. public function setQuantity(int $quantity): self
  299. {
  300. $this->quantity = $quantity;
  301. return $this;
  302. }
  303. public function getPriceHT(): ?string
  304. {
  305. return $this->priceHT;
  306. }
  307. public function setPriceHT(?string $priceHT): self
  308. {
  309. $this->priceHT = $priceHT;
  310. return $this;
  311. }
  312. public function getTotalPoint()
  313. {
  314. $unitPoint = $this->getUnitPoint() ?? 0;
  315. $quantity = $this->getQuantity() ?? 1;
  316. return $unitPoint * $quantity;
  317. }
  318. public function setId($id)
  319. {
  320. $this->id = $id;
  321. }
  322. public function getId(): ?int
  323. {
  324. return $this->id;
  325. }
  326. public function getQuantityNoBatch(): ?int
  327. {
  328. return $this->quantityNoBatch;
  329. }
  330. public function setQuantityNoBatch(?int $quantityNoBatch): self
  331. {
  332. $this->quantityNoBatch = $quantityNoBatch;
  333. return $this;
  334. }
  335. public function getStatus(): string
  336. {
  337. return $this->status;
  338. }
  339. public function setStatus(string $status): self
  340. {
  341. $this->status = $status;
  342. return $this;
  343. }
  344. public function getReference(): ?string
  345. {
  346. return $this->reference;
  347. }
  348. public function setReference(?string $reference): self
  349. {
  350. $this->reference = $reference;
  351. return $this;
  352. }
  353. public function getName(): ?string
  354. {
  355. return $this->name;
  356. }
  357. public function setName(?string $name): self
  358. {
  359. $this->name = $name;
  360. return $this;
  361. }
  362. public function getDescription(): ?string
  363. {
  364. return $this->description;
  365. }
  366. public function setDescription(?string $description): self
  367. {
  368. $this->description = $description;
  369. return $this;
  370. }
  371. public function getGamme(): ?string
  372. {
  373. return $this->gamme;
  374. }
  375. public function setGamme(?string $gamme): self
  376. {
  377. $this->gamme = $gamme;
  378. return $this;
  379. }
  380. public function getPriceTTC(): ?string
  381. {
  382. return $this->priceTTC;
  383. }
  384. public function setPriceTTC(?string $priceTTC): self
  385. {
  386. $this->priceTTC = $priceTTC;
  387. return $this;
  388. }
  389. public function getUnitPoint(): ?string
  390. {
  391. return $this->unitPoint;
  392. }
  393. public function setUnitPoint(?string $unitPoint): self
  394. {
  395. $this->unitPoint = $unitPoint;
  396. return $this;
  397. }
  398. public function getImageUrl(): ?string
  399. {
  400. return $this->imageUrl;
  401. }
  402. public function setImageUrl(?string $imageUrl): self
  403. {
  404. $this->imageUrl = $imageUrl;
  405. return $this;
  406. }
  407. public function getImageThumbnailUrl(): ?string
  408. {
  409. return $this->imageThumbnailUrl;
  410. }
  411. public function setImageThumbnailUrl(?string $imageThumbnailUrl): self
  412. {
  413. $this->imageThumbnailUrl = $imageThumbnailUrl;
  414. return $this;
  415. }
  416. public function getTaxableAmount(): ?string
  417. {
  418. return $this->taxableAmount;
  419. }
  420. public function setTaxableAmount(?string $taxableAmount): self
  421. {
  422. $this->taxableAmount = $taxableAmount;
  423. return $this;
  424. }
  425. public function getSaleOrder(): ?SaleOrder
  426. {
  427. return $this->saleOrder;
  428. }
  429. public function setSaleOrder(?SaleOrder $saleOrder): self
  430. {
  431. $this->saleOrder = $saleOrder;
  432. return $this;
  433. }
  434. /**
  435. * @return Collection|SaleOrderParticipant[]
  436. */
  437. public function getParticipants(): Collection
  438. {
  439. if (!$this->participants) {
  440. $this->participants = new ArrayCollection();
  441. }
  442. return $this->participants;
  443. }
  444. public function addParticipant(SaleOrderParticipant $participant): self
  445. {
  446. if (!$this->participants->contains($participant)) {
  447. $this->participants[] = $participant;
  448. $participant->setSaleOrderItem($this);
  449. }
  450. return $this;
  451. }
  452. public function removeParticipant(SaleOrderParticipant $participant): self
  453. {
  454. if ($this->participants->removeElement($participant)) {
  455. // set the owning side to null (unless already changed)
  456. if ($participant->getSaleOrderItem() === $this) {
  457. $participant->setSaleOrderItem(null);
  458. }
  459. }
  460. return $this;
  461. }
  462. /**
  463. * @return Collection|SaleOrderItemOption[]
  464. */
  465. public function getOptions(): Collection
  466. {
  467. if (!$this->options) {
  468. $this->options = new ArrayCollection();
  469. }
  470. return $this->options;
  471. }
  472. public function addOption(SaleOrderItemOption $option): self
  473. {
  474. if (!$this->options->contains($option)) {
  475. $this->options[] = $option;
  476. $option->setItem($this);
  477. }
  478. return $this;
  479. }
  480. public function removeOption(SaleOrderItemOption $option): self
  481. {
  482. if ($this->options->removeElement($option)) {
  483. // set the owning side to null (unless already changed)
  484. if ($option->getItem() === $this) {
  485. $option->setItem(null);
  486. }
  487. }
  488. return $this;
  489. }
  490. public function getCategoryValues(): ?string
  491. {
  492. return $this->categoryValues;
  493. }
  494. public function setCategoryValues(?string $categoryValues): self
  495. {
  496. $this->categoryValues = $categoryValues;
  497. return $this;
  498. }
  499. public function getTotalChosenCategoryValues(): ?string
  500. {
  501. return $this->totalChosenCategoryValues;
  502. }
  503. public function setTotalChosenCategoryValues(?string $totalChosenCategoryValues): self
  504. {
  505. $this->totalChosenCategoryValues = $totalChosenCategoryValues;
  506. return $this;
  507. }
  508. public function getWishDateEvasion()
  509. {
  510. return $this->wishDateEvasion;
  511. }
  512. public function setWishDateEvasion($wishDateEvasion)
  513. {
  514. $this->wishDateEvasion = $wishDateEvasion;
  515. }
  516. public function getWeight(): ?float
  517. {
  518. return $this->weight;
  519. }
  520. public function setWeight(?float $weight): self
  521. {
  522. $this->weight = $weight;
  523. return $this;
  524. }
  525. public function getIsRefundable(): ?bool
  526. {
  527. return $this->isRefundable;
  528. }
  529. public function setIsRefundable(?bool $isRefundable): self
  530. {
  531. $this->isRefundable = $isRefundable;
  532. return $this;
  533. }
  534. public function getisReplaced(): ?bool
  535. {
  536. return $this->isReplaced;
  537. }
  538. public function setisReplaced(?bool $isReplaced): self
  539. {
  540. $this->isReplaced = $isReplaced;
  541. return $this;
  542. }
  543. public function getPointTransactions(): Collection
  544. {
  545. return $this->pointTransactions;
  546. }
  547. public function addPointTransaction(?PointTransaction $pointTransaction): self
  548. {
  549. if (!$this->pointTransactions->contains($pointTransaction)) {
  550. $this->pointTransactions[] = $pointTransaction;
  551. if ($pointTransaction !== null && $pointTransaction->getSaleOrderItem() !== $this) {
  552. $pointTransaction->setSaleOrderItem($this);
  553. }
  554. }
  555. return $this;
  556. }
  557. public function removePointTransaction(?PointTransaction $pointTransaction): self
  558. {
  559. if ($this->pointTransactions->removeElement(
  560. $pointTransaction
  561. ) && $pointTransaction !== null && $pointTransaction->getSaleOrderItem() === $this) {
  562. $pointTransaction->setSaleOrderItem(null);
  563. }
  564. return $this;
  565. }
  566. public function getSaleOrderShipmentItem(): ?SaleOrderShipmentItem
  567. {
  568. return $this->saleOrderShipmentItem;
  569. }
  570. public function setSaleOrderShipmentItem(SaleOrderShipmentItem $saleOrderShipmentItem): self
  571. {
  572. // set the owning side of the relation if necessary
  573. if ($saleOrderShipmentItem->getSaleOrderItem() !== $this) {
  574. $saleOrderShipmentItem->setSaleOrderItem($this);
  575. }
  576. $this->saleOrderShipmentItem = $saleOrderShipmentItem;
  577. return $this;
  578. }
  579. public function getReplacedItem(): ?self
  580. {
  581. return $this->replaceItem;
  582. }
  583. public function setReplacedItem(?self $replaceItem): self
  584. {
  585. $this->replaceItem = $replaceItem;
  586. return $this;
  587. }
  588. public function getOriginalRefundableItem(): ?self
  589. {
  590. $current = $this;
  591. $visited = [$this->getId()]; // On marque le départ
  592. while ($replaced = $current->getReplacedItem()) {
  593. $replacedId = $replaced->getId();
  594. // Protection anti-boucle : si on retombe sur un ID déjà vu, ABORT
  595. if (in_array($replacedId, $visited, true)) {
  596. return null; // Boucle circulaire détectée
  597. }
  598. $visited[] = $replacedId; // On marque comme traité
  599. // Trouvé un item remboursable
  600. if ($replaced->getIsRefundable()) {
  601. return $replaced;
  602. }
  603. $current = $replaced; // On continue la remontée
  604. }
  605. // Bout de chaîne sans item remboursable
  606. return null;
  607. }
  608. public function getBoId(): ?int
  609. {
  610. return $this->boId;
  611. }
  612. public function setBoId(?int $boId): self
  613. {
  614. $this->boId = $boId;
  615. return $this;
  616. }
  617. }