src/Entity/Cart.php line 20

Open in your IDE?
  1. <?php
  2. namespace App\Entity;
  3. use App\Interfaces\ProductInterface;
  4. use App\Model\CartInfo;
  5. use App\Model\Product;
  6. use App\Repository\CartRepository;
  7. use App\Traits\DateTrait;
  8. use Doctrine\Common\Collections\ArrayCollection;
  9. use Doctrine\Common\Collections\Collection;
  10. use Doctrine\ORM\Mapping as ORM;
  11. /**
  12. * @ORM\Table(indexes={
  13. * @ORM\Index(columns={"serial_cookie"})
  14. * })
  15. * @ORM\Entity(repositoryClass=CartRepository::class)
  16. */
  17. class Cart
  18. {
  19. // option Choix point/cb
  20. public const CHOICE_CURRENCY = 'currency';
  21. public const CHOICE_CURRENCY_ONLINE_PAYMENT = 'currency_online_payment';
  22. public const ONLINE_PAYMENT_ONLY = 'online_payment_only';
  23. // option avantage dans le panier (produit gratuit, remise, etc)
  24. public const TYPE_QUOTA_PRODUCT_FREE = 'quota_product_free';
  25. public const TYPE_DISCOUNT = 'discount';
  26. public const TYPE_ADVANTAGE_OPTIONS = [
  27. self::TYPE_QUOTA_PRODUCT_FREE,
  28. self::TYPE_DISCOUNT,
  29. ];
  30. /**
  31. * @ORM\Id
  32. * @ORM\GeneratedValue
  33. * @ORM\Column(type="integer")
  34. */
  35. private ?int $id = null;
  36. /**
  37. * @ORM\Column(type="string", length=64, nullable=true)
  38. */
  39. private ?string $shippingMethod = null;
  40. /**
  41. * @ORM\Column(type="string", length=64)
  42. */
  43. private ?string $serialCookie = null;
  44. /**
  45. * @ORM\Column(type="boolean", options={"default": true})
  46. */
  47. private bool $sameAddressBilling = true;
  48. /**
  49. * @ORM\Column(type="integer", nullable=true)
  50. */
  51. private ?int $shippingDelay = null;
  52. /**
  53. * @ORM\ManyToOne(targetEntity=User::class, inversedBy="carts", cascade={"persist"})
  54. * @ORM\JoinColumn(nullable=true)
  55. */
  56. private ?User $user = null;
  57. /**
  58. * @ORM\Column(type="boolean", options={"default": false})
  59. */
  60. private bool $multiShipping = false;
  61. /**
  62. * @ORM\Column(type="decimal", precision=12, scale=4, nullable=true)
  63. */
  64. private ?string $bonusTotalUsed = null;
  65. /**
  66. * @ORM\OneToOne(targetEntity=CartAddress::class, cascade={"persist", "remove"}, orphanRemoval=true)
  67. */
  68. private ?CartAddress $shippingAddress = null;
  69. /**
  70. * @ORM\OneToOne(targetEntity=CartAddress::class, cascade={"persist", "remove"}, orphanRemoval=true)
  71. */
  72. private ?CartAddress $billingAddress = null;
  73. /**
  74. * @ORM\OneToMany(targetEntity=CartItem::class, mappedBy="cart", cascade={"remove"})
  75. */
  76. private Collection $items;
  77. /**
  78. * @ORM\OneToOne(targetEntity=SaleOrder::class, mappedBy="cart", cascade={"persist", "remove"})
  79. */
  80. private ?SaleOrder $saleOrder = null;
  81. /**
  82. * @ORM\OneToMany(targetEntity=PointTransaction::class, mappedBy="paidCart")
  83. */
  84. private Collection $paidPointTransactions;
  85. /**
  86. * @ORM\OneToMany(targetEntity=PointTransaction::class, mappedBy="cart")
  87. */
  88. private Collection $pointTransactions;
  89. public ?CartInfo $cartInfo = null;
  90. /**
  91. * @ORM\Column(type="boolean", options={"default": false})
  92. */
  93. private bool $isExpressDelivery = false;
  94. /**
  95. * Donnée du formulaire rempli par l'utilisateur
  96. *
  97. * @ORM\Column(type="json", nullable=true)
  98. *
  99. */
  100. private ?array $orderExtraData = null;
  101. /**
  102. * @ORM\Column(type="json", nullable=true)
  103. */
  104. private ?array $choiceCurrencyPayment = null;
  105. /**
  106. * @ORM\Column(type="json", nullable=true)
  107. */
  108. private ?array $advantageOptions = null;
  109. use DateTrait;
  110. public function __construct()
  111. {
  112. $this->items = new ArrayCollection();
  113. $this->paidPointTransactions = new ArrayCollection();
  114. $this->pointTransactions = new ArrayCollection();
  115. }
  116. public function __toString()
  117. {
  118. return 'Panier ' . $this->getId();
  119. }
  120. /*
  121. * ============================================================================================
  122. * =============================== FONCTIONS CUSTOM ===========================================
  123. * ============================================================================================
  124. */
  125. public function getReference(): string
  126. {
  127. $id = strval($this->getId());
  128. return str_pad($id, 8, '0', STR_PAD_LEFT);
  129. }
  130. // ITEMS
  131. public function getId(): ?int
  132. {
  133. return $this->id;
  134. }
  135. // @TODO check product, dans la 2.8 ca ne fct pas non plus
  136. // public function getTotalHt()
  137. // {
  138. // $total = NULL;
  139. // /* @var $item CartItem */
  140. // foreach ( $this->items as $item ) {
  141. // $total += $item->getProduct()->getPriceHT() * $item->getQuantity();
  142. // }
  143. // return $total;
  144. // }
  145. //
  146. //
  147. // public function getTotalTTC()
  148. // {
  149. // $total = NULL;
  150. // /** @var CartItem $item */
  151. // foreach ( $this->items as $item ) {
  152. // $total += $item->getProduct()->getPriceTTC() * $item->getQuantity();
  153. // }
  154. // return $total;
  155. // }
  156. public function getItemsCount(): int
  157. {
  158. return count($this->items);
  159. }
  160. /**
  161. * @param ProductInterface $product
  162. *
  163. * @return CartItem|false
  164. */
  165. public function getCartItemByProduct(ProductInterface $product)
  166. {
  167. foreach ($this->getItems() as $item) {
  168. if ($item->getSku() == $product->getSku()) {
  169. return $item;
  170. }
  171. }
  172. return false;
  173. }
  174. /**
  175. * @return Collection|CartItem[]
  176. */
  177. public function getItems(): Collection
  178. {
  179. return $this->items;
  180. }
  181. public function getAddressType(Address $address): string
  182. {
  183. if ($this->billingAddress == $address) {
  184. return Address::TYPE_BILLING_ADDRESS;
  185. } elseif ($this->shippingAddress == $address) {
  186. return Address::TYPE_SHIPPING_ADDRESS;
  187. }
  188. return Address::TYPE_BILLING_ADDRESS;
  189. }
  190. /*
  191. * ============================================================================================
  192. * ============================== FIN FONCTIONS CUSTOM ========================================
  193. * ============================================================================================
  194. */
  195. public function getCartItemById($id)
  196. {
  197. foreach ($this->getItems() as $item) {
  198. if ($item->getId() == $id) {
  199. return $item;
  200. }
  201. }
  202. return false;
  203. }
  204. public function totalQuantity()
  205. {
  206. $totalQuantity = 0;
  207. foreach ($this->getItems() as $item) {
  208. $totalQuantity += $item->getQuantity();
  209. }
  210. return $totalQuantity;
  211. }
  212. public function getShippingMethod(): ?string
  213. {
  214. return $this->shippingMethod;
  215. }
  216. public function setShippingMethod(?string $shippingMethod): self
  217. {
  218. $this->shippingMethod = $shippingMethod;
  219. return $this;
  220. }
  221. public function getSerialCookie(): ?string
  222. {
  223. return $this->serialCookie;
  224. }
  225. public function setSerialCookie(string $serialCookie): self
  226. {
  227. $this->serialCookie = $serialCookie;
  228. return $this;
  229. }
  230. public function getSameAddressBilling(): ?bool
  231. {
  232. return $this->sameAddressBilling;
  233. }
  234. public function setSameAddressBilling(bool $sameAddressBilling): self
  235. {
  236. $this->sameAddressBilling = $sameAddressBilling;
  237. return $this;
  238. }
  239. public function getShippingDelay(): ?int
  240. {
  241. return $this->shippingDelay;
  242. }
  243. public function setShippingDelay(?int $shippingDelay): self
  244. {
  245. $this->shippingDelay = $shippingDelay;
  246. return $this;
  247. }
  248. public function getUser(): ?User
  249. {
  250. return $this->user;
  251. }
  252. public function setUser(?User $user): self
  253. {
  254. $this->user = $user;
  255. return $this;
  256. }
  257. public function getMultiShipping(): ?bool
  258. {
  259. return $this->multiShipping;
  260. }
  261. public function setMultiShipping(bool $multiShipping): self
  262. {
  263. $this->multiShipping = $multiShipping;
  264. return $this;
  265. }
  266. public function getBonusTotalUsed(): ?string
  267. {
  268. return $this->bonusTotalUsed;
  269. }
  270. public function setBonusTotalUsed(?string $bonusTotalUsed): self
  271. {
  272. $this->bonusTotalUsed = $bonusTotalUsed;
  273. return $this;
  274. }
  275. public function getShippingAddress(): ?CartAddress
  276. {
  277. return $this->shippingAddress;
  278. }
  279. public function setShippingAddress(?CartAddress $shippingAddress): self
  280. {
  281. $this->shippingAddress = $shippingAddress;
  282. return $this;
  283. }
  284. public function getBillingAddress(): ?CartAddress
  285. {
  286. return $this->billingAddress;
  287. }
  288. public function setBillingAddress(?CartAddress $billingAddress): self
  289. {
  290. $this->billingAddress = $billingAddress;
  291. return $this;
  292. }
  293. public function addItem(CartItem $item): self
  294. {
  295. if (!$this->items->contains($item)) {
  296. $this->items[] = $item;
  297. $item->setCart($this);
  298. }
  299. return $this;
  300. }
  301. public function removeItem(CartItem $item): self
  302. {
  303. if ($this->items->removeElement($item)) {
  304. // set the owning side to null (unless already changed)
  305. if ($item->getCart() === $this) {
  306. $item->setCart(null);
  307. }
  308. }
  309. return $this;
  310. }
  311. public function getSaleOrder(): ?SaleOrder
  312. {
  313. return $this->saleOrder;
  314. }
  315. public function setSaleOrder(?SaleOrder $saleOrder): self
  316. {
  317. // unset the owning side of the relation if necessary
  318. if ($saleOrder === null && $this->saleOrder !== null) {
  319. $this->saleOrder->setCart(null);
  320. }
  321. // set the owning side of the relation if necessary
  322. if ($saleOrder !== null && $saleOrder->getCart() !== $this) {
  323. $saleOrder->setCart($this);
  324. }
  325. $this->saleOrder = $saleOrder;
  326. return $this;
  327. }
  328. /**
  329. * @return Collection|PointTransaction[]
  330. */
  331. public function getAllPointTransactions(): Collection
  332. {
  333. $all = $this->pointTransactions;
  334. foreach ($this->paidPointTransactions as $transaction) {
  335. if ($all->contains($transaction)) {
  336. continue;
  337. }
  338. $all->add($transaction);
  339. }
  340. return $all;
  341. }
  342. /**
  343. * @return Collection|PointTransaction[]
  344. */
  345. public function getPaidPointTransactions(): Collection
  346. {
  347. return $this->paidPointTransactions;
  348. }
  349. /**
  350. * @param PointTransaction $transaction
  351. *
  352. * @return $this
  353. */
  354. public function addPaidPointTransaction(PointTransaction $transaction): self
  355. {
  356. if (!$this->paidPointTransactions->contains($transaction)) {
  357. $this->paidPointTransactions[] = $transaction;
  358. if ($transaction->getPaidCart() !== $this) {
  359. $transaction->setPaidCart($this);
  360. }
  361. }
  362. return $this;
  363. }
  364. /**
  365. * @param PointTransaction $transaction
  366. *
  367. * @return $this
  368. */
  369. public function removePaidPointTransaction(PointTransaction $transaction): self
  370. {
  371. if ($this->paidPointTransactions->removeElement($transaction) && $transaction->getPaidCart() === $this) {
  372. $transaction->setPaidCart();
  373. }
  374. return $this;
  375. }
  376. /**
  377. * @param iterable|PointTransaction[] $transactions
  378. *
  379. * @return $this
  380. */
  381. public function setPaidPointTransactions(iterable $transactions): self
  382. {
  383. foreach ($this->paidPointTransactions as $transaction) {
  384. $this->removePaidPointTransaction($transaction);
  385. }
  386. foreach ($transactions as $transaction) {
  387. $this->addPaidPointTransaction($transaction);
  388. }
  389. return $this;
  390. }
  391. /**
  392. * @param bool $excludeValids
  393. * @param bool $onlyValids
  394. * @param string|null $onlyValids
  395. *
  396. * @return float
  397. */
  398. public function getTotalPaidPointTransactions(
  399. bool $excludeValids = false,
  400. bool $onlyValids = false,
  401. ?string $pointCategory = null
  402. ): float {
  403. $points = 0;
  404. foreach ($this->getPaidPointTransactions() as $transaction) {
  405. if ($excludeValids && $transaction->getValue() != 0) {
  406. continue;
  407. }
  408. if ($onlyValids && $transaction->getValue() == 0) {
  409. continue;
  410. }
  411. if ($pointCategory !== null && $transaction->getCategory() !== $pointCategory) {
  412. continue;
  413. }
  414. $points += $transaction->getPaymentValue();
  415. }
  416. return round($points, 2);
  417. }
  418. /**
  419. * @return Collection|PointTransaction[]
  420. */
  421. public function getPointTransactions(): Collection
  422. {
  423. return $this->pointTransactions;
  424. }
  425. /**
  426. * @param PointTransaction $transaction
  427. *
  428. * @return $this
  429. */
  430. public function addPointTransaction(PointTransaction $transaction): self
  431. {
  432. if (!$this->pointTransactions->contains($transaction)) {
  433. $this->pointTransactions[] = $transaction;
  434. if ($transaction->getCart() !== $this) {
  435. $transaction->setCart($this);
  436. }
  437. }
  438. return $this;
  439. }
  440. /**
  441. * @param PointTransaction $transaction
  442. *
  443. * @return $this
  444. */
  445. public function removePointTransaction(PointTransaction $transaction): self
  446. {
  447. if ($this->pointTransactions->removeElement($transaction) && $transaction->getCart() === $this) {
  448. $transaction->setCart(null);
  449. }
  450. return $this;
  451. }
  452. /**
  453. * @param iterable|PointTransaction[] $transactions
  454. *
  455. * @return $this
  456. */
  457. public function setPointTransactions(iterable $transactions): self
  458. {
  459. foreach ($this->pointTransactions as $transaction) {
  460. $this->removePointTransaction($transaction);
  461. }
  462. foreach ($transactions as $transaction) {
  463. $this->addPointTransaction($transaction);
  464. }
  465. return $this;
  466. }
  467. public function isExpressDelivery(): ?bool
  468. {
  469. return $this->isExpressDelivery;
  470. }
  471. public function setExpressDelivery(bool $isExpressDelivery): self
  472. {
  473. $this->isExpressDelivery = $isExpressDelivery;
  474. return $this;
  475. }
  476. public function getOrderExtraData(): ?array
  477. {
  478. return $this->orderExtraData;
  479. }
  480. public function setOrderExtraData(?array $orderExtraData): self
  481. {
  482. $this->orderExtraData = $orderExtraData;
  483. return $this;
  484. }
  485. public function hasOnlyEstimate(): bool
  486. {
  487. foreach ($this->items as $item) {
  488. if (!$item->getType() || $item->getType() !== Product::TYPE_ESTIMATE) {
  489. return false;
  490. }
  491. }
  492. return true;
  493. }
  494. public function getChoiceCurrencyPayment(): ?array
  495. {
  496. return $this->choiceCurrencyPayment;
  497. }
  498. public function setChoiceCurrencyPayment(?array $choiceCurrencyPayment): self
  499. {
  500. $this->choiceCurrencyPayment = $choiceCurrencyPayment;
  501. return $this;
  502. }
  503. public function getAdvantageOptions(): ?array
  504. {
  505. return $this->advantageOptions;
  506. }
  507. public function getAdvantageOption(string $typeAdvantage): ?array
  508. {
  509. if (!in_array($typeAdvantage, self::TYPE_ADVANTAGE_OPTIONS, true)) {
  510. throw new \InvalidArgumentException(sprintf('Type d’avantage non autorisé : %s.', $typeAdvantage));
  511. }
  512. return $this->advantageOptions[$typeAdvantage] ?? null;
  513. }
  514. public function setAdvantageOptions(?array $advantageOptions): self
  515. {
  516. $this->advantageOptions = $advantageOptions;
  517. return $this;
  518. }
  519. public function addAdvantageOption(string $typeAdvantage, array $advantageOption): self
  520. {
  521. if (!in_array($typeAdvantage, self::TYPE_ADVANTAGE_OPTIONS, true)) {
  522. throw new \InvalidArgumentException(sprintf('Type d’avantage non autorisé : %s.', $typeAdvantage));
  523. }
  524. $advantageOptions = $this->getAdvantageOptions() ?? [];
  525. $advantageOptions[$typeAdvantage] = $advantageOption;
  526. return $this->setAdvantageOptions($advantageOptions);
  527. }
  528. }